@duskmoon-dev/components 0.3.1 → 0.4.0

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 (109) hide show
  1. package/README.md +61 -2
  2. package/dist/{chunk-r9wkv7xd.js → chunk-fwjzvsrx.js} +3 -3
  3. package/dist/classes/chat.d.ts +43 -0
  4. package/dist/classes/console-page.d.ts +16 -0
  5. package/dist/classes/dropdown.d.ts +5 -5
  6. package/dist/classes/fab.d.ts +11 -0
  7. package/dist/classes/index.d.ts +6 -0
  8. package/dist/classes/index.js +1443 -1210
  9. package/dist/classes/megamenu.d.ts +10 -0
  10. package/dist/classes/otp-input.d.ts +12 -0
  11. package/dist/classes/popover.d.ts +1 -3
  12. package/dist/classes/swap.d.ts +12 -0
  13. package/dist/classes/tree-select.d.ts +6 -6
  14. package/dist/components/anchor/index.js +2 -2
  15. package/dist/components/app/index.js +211 -151
  16. package/dist/components/avatar/Avatar.types.d.ts +1 -1
  17. package/dist/components/avatar/index.js +2 -1
  18. package/dist/components/badge/index.js +1 -1
  19. package/dist/components/button/Button.d.ts +1 -1
  20. package/dist/components/button/Button.types.d.ts +8 -0
  21. package/dist/components/button/index.js +253 -24
  22. package/dist/components/calendar/index.js +44 -19
  23. package/dist/components/cascader/index.js +2 -2
  24. package/dist/components/chat/Chat.d.ts +22 -0
  25. package/dist/components/chat/Chat.types.d.ts +73 -0
  26. package/dist/components/chat/index.d.ts +2 -0
  27. package/dist/components/chat/index.js +309 -0
  28. package/dist/components/color-picker/ColorPicker.types.d.ts +2 -1
  29. package/dist/components/color-picker/index.js +210 -13
  30. package/dist/components/config-provider/index.js +2 -2
  31. package/dist/components/console-page/ConsolePage.d.ts +2 -0
  32. package/dist/components/console-page/ConsolePage.types.d.ts +29 -0
  33. package/dist/components/console-page/index.d.ts +2 -0
  34. package/dist/components/console-page/index.js +205 -0
  35. package/dist/components/date-picker/DatePicker.types.d.ts +1 -0
  36. package/dist/components/date-picker/index.js +537 -35
  37. package/dist/components/date-picker/usePickerDropdown.d.ts +17 -0
  38. package/dist/components/dm-breadcrumb/index.js +18 -18
  39. package/dist/components/dm-date-picker/index.js +635 -133
  40. package/dist/components/dm-drawer/index.js +269 -40
  41. package/dist/components/dm-layout/index.js +575 -208
  42. package/dist/components/dm-menu/index.js +399 -32
  43. package/dist/components/dm-message/index.js +18 -18
  44. package/dist/components/dm-page-header/index.js +537 -247
  45. package/dist/components/dm-pagination/index.js +39 -39
  46. package/dist/components/dm-pro-table/index.js +2374 -1559
  47. package/dist/components/dm-provider/index.js +94 -94
  48. package/dist/components/dm-query/DmQuery.types.d.ts +1 -1
  49. package/dist/components/dm-query/index.js +955 -210
  50. package/dist/components/dm-search/DmSearch.types.d.ts +4 -0
  51. package/dist/components/dm-search/index.js +937 -183
  52. package/dist/components/dm-splitter/index.js +32 -32
  53. package/dist/components/dm-status/index.js +25 -25
  54. package/dist/components/dm-table/index.js +1430 -676
  55. package/dist/components/dm-tabs/index.js +34 -34
  56. package/dist/components/dm-toolbar/index.js +423 -133
  57. package/dist/components/dm-tree/index.js +92 -92
  58. package/dist/components/dm-truncate/index.js +145 -65
  59. package/dist/components/dropdown/Dropdown.types.d.ts +1 -1
  60. package/dist/components/dropdown/index.js +467 -177
  61. package/dist/components/fab/Fab.d.ts +4 -0
  62. package/dist/components/fab/Fab.types.d.ts +25 -0
  63. package/dist/components/fab/index.d.ts +2 -0
  64. package/dist/components/fab/index.js +480 -0
  65. package/dist/components/form/Form.types.d.ts +1 -0
  66. package/dist/components/form/index.js +16 -5
  67. package/dist/components/grid/index.js +2 -2
  68. package/dist/components/input/index.js +4 -4
  69. package/dist/components/markdown/index.js +1 -1
  70. package/dist/components/megamenu/Megamenu.d.ts +2 -0
  71. package/dist/components/megamenu/Megamenu.types.d.ts +32 -0
  72. package/dist/components/megamenu/index.d.ts +2 -0
  73. package/dist/components/megamenu/index.js +214 -0
  74. package/dist/components/message/index.js +5 -5
  75. package/dist/components/modal/index.js +128 -68
  76. package/dist/components/notification/index.js +2 -2
  77. package/dist/components/otp-input/OtpInput.d.ts +2 -0
  78. package/dist/components/otp-input/OtpInput.types.d.ts +16 -0
  79. package/dist/components/otp-input/index.d.ts +2 -0
  80. package/dist/components/otp-input/index.js +112 -0
  81. package/dist/components/popconfirm/index.js +297 -68
  82. package/dist/components/popover/index.js +24 -4
  83. package/dist/components/skeleton/index.js +5 -5
  84. package/dist/components/spin/index.js +2 -2
  85. package/dist/components/steps/index.js +2 -2
  86. package/dist/components/swap/Swap.d.ts +3 -0
  87. package/dist/components/swap/Swap.types.d.ts +22 -0
  88. package/dist/components/swap/index.d.ts +2 -0
  89. package/dist/components/swap/index.js +109 -0
  90. package/dist/components/table/index.js +2 -2
  91. package/dist/components/tabs/index.js +2 -2
  92. package/dist/components/tag/index.js +2 -2
  93. package/dist/components/time-picker/TimePicker.types.d.ts +1 -0
  94. package/dist/components/time-picker/index.js +167 -29
  95. package/dist/components/tooltip/Tooltip.types.d.ts +4 -0
  96. package/dist/components/tooltip/index.js +107 -27
  97. package/dist/components/tour/index.js +315 -86
  98. package/dist/components/tree-select/index.js +8 -8
  99. package/dist/components/typography/index.js +4 -4
  100. package/dist/components/upload/Upload.types.d.ts +1 -0
  101. package/dist/components/upload/index.js +7 -5
  102. package/dist/generated/version.d.ts +1 -1
  103. package/dist/index.d.ts +6 -0
  104. package/dist/index.js +4023 -2134
  105. package/dist/infrastructure.js +11 -11
  106. package/dist/styles.css +13677 -9811
  107. package/dist/theme/index.js +3 -3
  108. package/dist/utils/index.js +5 -5
  109. package/package.json +30 -6
@@ -1,5 +1,8 @@
1
1
  "use client";
2
2
 
3
+ // src/components/dm-toolbar/DmToolbar.tsx
4
+ import { useMemo } from "react";
5
+
3
6
  // ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
4
7
  function r(e) {
5
8
  var t, f, n = "";
@@ -25,6 +28,26 @@ function clsx() {
25
28
  function cn(...inputs) {
26
29
  return clsx(inputs);
27
30
  }
31
+ // src/classes/dm-toolbar.ts
32
+ var dmToolbarBaseClass = "dm-toolbar";
33
+ var dmToolbarItemClass = "dm-toolbar-item";
34
+ var dmToolbarPrimaryItemClass = "dm-toolbar-primary-item";
35
+ var dmToolbarSecondaryItemClass = "dm-toolbar-secondary-item";
36
+ var dmToolbarMoreClass = "dm-toolbar-more";
37
+ function getDmToolbarClasses({ className }) {
38
+ return cn(dmToolbarBaseClass, className);
39
+ }
40
+ function getDmToolbarItemClasses({
41
+ primary,
42
+ className
43
+ }) {
44
+ return cn(dmToolbarItemClass, primary ? dmToolbarPrimaryItemClass : dmToolbarSecondaryItemClass, className);
45
+ }
46
+
47
+ // src/components/button/Button.tsx
48
+ import React from "react";
49
+ import { createPortal } from "react-dom";
50
+
28
51
  // src/classes/button.ts
29
52
  var buttonBaseClass = "btn";
30
53
  var buttonColorClasses = {
@@ -48,7 +71,7 @@ var buttonAppearanceClasses = {
48
71
  };
49
72
  var buttonShapeClasses = {
50
73
  rect: "",
51
- circle: "btn-circle",
74
+ circle: "btn-circle btn-icon",
52
75
  square: "btn-square"
53
76
  };
54
77
  var buttonSizeClasses = {
@@ -68,11 +91,14 @@ function getButtonClasses({
68
91
  isLoading,
69
92
  className
70
93
  }) {
71
- return cn(buttonBaseClass, buttonColorClasses[color], buttonAppearanceClasses[appearance], buttonShapeClasses[shape], buttonSizeClasses[size], block && buttonBlockClass, isLoading && buttonIsLoadingClass, className);
94
+ return cn(buttonBaseClass, buttonColorClasses[color], buttonAppearanceClasses[appearance], buttonShapeClasses[shape], buttonSizeClasses[size], shape === "circle" && size === "xs" && "btn-icon-sm", shape === "circle" && size === "sm" && "btn-icon-sm", shape === "circle" && size === "lg" && "btn-icon-lg", block && buttonBlockClass, isLoading && buttonIsLoadingClass, className);
72
95
  }
73
96
 
74
97
  // src/components/button/Button.tsx
75
- import { jsx, jsxs } from "react/jsx-runtime";
98
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
99
+ function isPromiseLike(value) {
100
+ return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
101
+ }
76
102
  function Button({
77
103
  color = "primary",
78
104
  appearance = "filled",
@@ -86,8 +112,155 @@ function Button({
86
112
  children,
87
113
  disabled,
88
114
  ref,
115
+ confirm,
116
+ onClick,
89
117
  ...props
90
118
  }) {
119
+ const buttonRef = React.useRef(null);
120
+ const popoverRef = React.useRef(null);
121
+ const cancelRef = React.useRef(null);
122
+ const approvalRef = React.useRef("idle");
123
+ const pendingRef = React.useRef(false);
124
+ const actionRef = React.useRef(0);
125
+ const operationRef = React.useRef(0);
126
+ const mountedRef = React.useRef(false);
127
+ const [portalTarget, setPortalTarget] = React.useState(null);
128
+ const [confirmLoading, setConfirmLoading] = React.useState(false);
129
+ const [confirmError, setConfirmError] = React.useState(false);
130
+ const generatedId = React.useId().replace(/:/g, "");
131
+ const popoverId = `button-confirm-${generatedId}`;
132
+ const titleId = `${popoverId}-title`;
133
+ const descriptionId = `${popoverId}-description`;
134
+ const anchor = `--${popoverId}-anchor`;
135
+ const hasConfirm = Boolean(confirm);
136
+ const confirmation = confirm && typeof confirm === "object" ? confirm : undefined;
137
+ const title = confirmation ? confirmation.title : "Confirm action";
138
+ const hasTitle = title !== undefined && title !== null && title !== false && title !== "";
139
+ const content = confirmation?.component ?? confirmation?.message ?? confirmation?.description;
140
+ const hasContent = content !== undefined && content !== null && content !== false && content !== "";
141
+ const mergedRef = React.useCallback((node) => {
142
+ buttonRef.current = node;
143
+ if (!node) {
144
+ if (typeof ref === "function")
145
+ ref(null);
146
+ else if (ref)
147
+ ref.current = null;
148
+ return;
149
+ }
150
+ const cleanup = typeof ref === "function" ? ref(node) : undefined;
151
+ if (ref && typeof ref !== "function")
152
+ ref.current = node;
153
+ return () => {
154
+ buttonRef.current = null;
155
+ if (typeof cleanup === "function")
156
+ cleanup();
157
+ else if (typeof ref === "function")
158
+ ref(null);
159
+ else if (ref)
160
+ ref.current = null;
161
+ };
162
+ }, [ref]);
163
+ React.useEffect(() => {
164
+ mountedRef.current = true;
165
+ return () => {
166
+ mountedRef.current = false;
167
+ operationRef.current += 1;
168
+ };
169
+ }, []);
170
+ React.useEffect(() => {
171
+ operationRef.current += 1;
172
+ approvalRef.current = "idle";
173
+ setConfirmError(false);
174
+ setPortalTarget(hasConfirm ? document.body : null);
175
+ }, [hasConfirm]);
176
+ function closePopover() {
177
+ if (popoverRef.current?.matches(":popover-open")) {
178
+ popoverRef.current.hidePopover();
179
+ }
180
+ buttonRef.current?.focus();
181
+ }
182
+ function handleClick(event) {
183
+ if (!confirm) {
184
+ onClick?.(event);
185
+ return;
186
+ }
187
+ if (approvalRef.current === "native") {
188
+ approvalRef.current = "idle";
189
+ return;
190
+ }
191
+ if (approvalRef.current === "action") {
192
+ approvalRef.current = "idle";
193
+ let result;
194
+ try {
195
+ result = onClick?.(event);
196
+ } catch {
197
+ event.preventDefault();
198
+ pendingRef.current = false;
199
+ setConfirmError(true);
200
+ return;
201
+ }
202
+ if (!isPromiseLike(result)) {
203
+ pendingRef.current = false;
204
+ closePopover();
205
+ return;
206
+ }
207
+ const userPreventedDefault = event.defaultPrevented;
208
+ event.preventDefault();
209
+ setConfirmLoading(true);
210
+ const action = actionRef.current;
211
+ const operation = operationRef.current;
212
+ Promise.resolve(result).then(() => {
213
+ if (!mountedRef.current || action !== actionRef.current)
214
+ return;
215
+ pendingRef.current = false;
216
+ setConfirmLoading(false);
217
+ if (operation !== operationRef.current)
218
+ return;
219
+ closePopover();
220
+ if (!userPreventedDefault && !buttonRef.current?.disabled) {
221
+ approvalRef.current = "native";
222
+ buttonRef.current?.click();
223
+ approvalRef.current = "idle";
224
+ }
225
+ }, () => {
226
+ if (!mountedRef.current || action !== actionRef.current)
227
+ return;
228
+ pendingRef.current = false;
229
+ setConfirmLoading(false);
230
+ if (operation !== operationRef.current)
231
+ return;
232
+ setConfirmError(true);
233
+ cancelRef.current?.focus();
234
+ });
235
+ return;
236
+ }
237
+ event.preventDefault();
238
+ if (disabled || isLoading || pendingRef.current)
239
+ return;
240
+ if (popoverRef.current?.matches(":popover-open")) {
241
+ closePopover();
242
+ return;
243
+ }
244
+ setConfirmError(false);
245
+ popoverRef.current?.showPopover();
246
+ cancelRef.current?.focus();
247
+ }
248
+ function handleConfirm(event) {
249
+ event.preventDefault();
250
+ event.stopPropagation();
251
+ const trigger = buttonRef.current;
252
+ if (disabled || isLoading || pendingRef.current || !trigger || trigger.disabled || !event.currentTarget.matches(":popover-open"))
253
+ return;
254
+ setConfirmError(false);
255
+ pendingRef.current = true;
256
+ actionRef.current += 1;
257
+ approvalRef.current = "action";
258
+ trigger.click();
259
+ if (approvalRef.current === "action") {
260
+ approvalRef.current = "idle";
261
+ pendingRef.current = false;
262
+ }
263
+ }
91
264
  const classes = getButtonClasses({
92
265
  color,
93
266
  appearance,
@@ -97,29 +270,104 @@ function Button({
97
270
  isLoading,
98
271
  className
99
272
  });
100
- return /* @__PURE__ */ jsxs("button", {
101
- ref,
102
- className: classes,
103
- disabled: disabled || isLoading,
104
- "aria-busy": isLoading,
105
- "aria-disabled": disabled || isLoading,
106
- ...props,
273
+ const confirmClasses = getButtonClasses({
274
+ color,
275
+ size: "sm",
276
+ isLoading: confirmLoading
277
+ });
278
+ return /* @__PURE__ */ jsxs(Fragment, {
107
279
  children: [
108
- isLoading && /* @__PURE__ */ jsx("span", {
109
- className: "btn-spinner"
110
- }),
111
- !isLoading && leftIcon && /* @__PURE__ */ jsx("span", {
112
- className: "btn-icon-left",
113
- children: leftIcon
114
- }),
115
- /* @__PURE__ */ jsx("span", {
116
- className: "btn-content",
117
- children
280
+ /* @__PURE__ */ jsxs("button", {
281
+ ref: confirm ? mergedRef : ref,
282
+ className: classes,
283
+ disabled: disabled || isLoading,
284
+ "aria-busy": isLoading,
285
+ "aria-disabled": disabled || isLoading,
286
+ ...props,
287
+ style: confirm ? { ...props.style, anchorName: anchor } : props.style,
288
+ "aria-haspopup": confirm ? "dialog" : props["aria-haspopup"],
289
+ "aria-controls": confirm ? popoverId : props["aria-controls"],
290
+ onClick: confirm ? handleClick : onClick,
291
+ children: [
292
+ isLoading && /* @__PURE__ */ jsx("span", {
293
+ className: "btn-spinner"
294
+ }),
295
+ !isLoading && leftIcon && /* @__PURE__ */ jsx("span", {
296
+ className: "btn-icon-left",
297
+ children: leftIcon
298
+ }),
299
+ /* @__PURE__ */ jsx("span", {
300
+ className: "btn-content",
301
+ children
302
+ }),
303
+ !isLoading && rightIcon && /* @__PURE__ */ jsx("span", {
304
+ className: "btn-icon-right",
305
+ children: rightIcon
306
+ })
307
+ ]
118
308
  }),
119
- !isLoading && rightIcon && /* @__PURE__ */ jsx("span", {
120
- className: "btn-icon-right",
121
- children: rightIcon
122
- })
309
+ confirm && portalTarget && createPortal(/* @__PURE__ */ jsxs("form", {
310
+ id: popoverId,
311
+ ref: popoverRef,
312
+ popover: "auto",
313
+ role: "dialog",
314
+ "aria-labelledby": hasTitle ? titleId : undefined,
315
+ "aria-label": hasTitle ? undefined : "Confirm action",
316
+ "aria-describedby": hasContent ? descriptionId : undefined,
317
+ className: "popover popover-confirm popover-bottom",
318
+ style: { positionAnchor: anchor },
319
+ onSubmit: handleConfirm,
320
+ onClick: (event) => event.stopPropagation(),
321
+ onToggle: (event) => {
322
+ if (!event.currentTarget.matches(":popover-open")) {
323
+ operationRef.current += 1;
324
+ if (event.currentTarget.contains(document.activeElement) || document.activeElement === document.body) {
325
+ buttonRef.current?.focus();
326
+ }
327
+ }
328
+ },
329
+ children: [
330
+ hasTitle && /* @__PURE__ */ jsx("div", {
331
+ className: "popover-header",
332
+ children: /* @__PURE__ */ jsx("h3", {
333
+ id: titleId,
334
+ className: "popover-title",
335
+ children: title
336
+ })
337
+ }),
338
+ hasContent && /* @__PURE__ */ jsx("div", {
339
+ id: descriptionId,
340
+ className: "popover-body",
341
+ children: content
342
+ }),
343
+ confirmError && /* @__PURE__ */ jsx("div", {
344
+ role: "alert",
345
+ className: "popover-body",
346
+ children: "The action failed. Please try again."
347
+ }),
348
+ /* @__PURE__ */ jsxs("div", {
349
+ className: "popover-footer",
350
+ children: [
351
+ /* @__PURE__ */ jsx("button", {
352
+ ref: cancelRef,
353
+ type: "button",
354
+ className: "btn btn-text btn-sm",
355
+ popoverTarget: popoverId,
356
+ popoverTargetAction: "hide",
357
+ disabled: confirmLoading,
358
+ children: confirmation?.cancelText ?? "Cancel"
359
+ }),
360
+ /* @__PURE__ */ jsx("button", {
361
+ type: "submit",
362
+ className: confirmClasses,
363
+ disabled: disabled || isLoading || confirmLoading,
364
+ "aria-busy": confirmLoading,
365
+ children: confirmation?.confirmText ?? "Confirm"
366
+ })
367
+ ]
368
+ })
369
+ ]
370
+ }), portalTarget)
123
371
  ]
124
372
  });
125
373
  }
@@ -128,34 +376,32 @@ import {
128
376
  cloneElement,
129
377
  forwardRef,
130
378
  isValidElement,
379
+ useEffect,
131
380
  useId,
381
+ useRef,
132
382
  useState
133
383
  } from "react";
134
384
 
135
385
  // src/classes/dropdown.ts
136
- var dropdownWrapperClass = "dropdown-wrapper";
137
- var dropdownBaseClass = "popover dropdown";
138
- var dropdownOpenClass = "popover-show dropdown-open";
139
- var dropdownArrowClass = "popover-arrow dropdown-arrow";
386
+ var dropdownWrapperClass = "dropdown";
387
+ var dropdownBaseClass = "dropdown-content";
388
+ var dropdownArrowClass = "dropdown-arrow";
140
389
  var dropdownMenuClass = "menu dropdown-menu";
141
390
  var dropdownButtonClass = "dropdown-button";
142
391
  var dropdownPlacementClasses = {
143
- top: "popover-top dropdown-top",
144
- bottom: "popover-bottom dropdown-bottom",
145
- left: "popover-left dropdown-left",
146
- right: "popover-right dropdown-right",
147
- topLeft: "popover-top dropdown-top-left",
148
- topRight: "popover-top dropdown-top-right",
149
- bottomLeft: "popover-bottom dropdown-bottom-left",
150
- bottomRight: "popover-bottom dropdown-bottom-right"
392
+ top: "dropdown-block-start",
393
+ bottom: "dropdown-block-end",
394
+ left: "dropdown-inline-start",
395
+ right: "dropdown-inline-end",
396
+ topLeft: "dropdown-block-start",
397
+ topRight: "dropdown-block-start",
398
+ bottomLeft: "dropdown-block-end",
399
+ bottomRight: "dropdown-block-end"
151
400
  };
152
401
  function getDropdownClasses({
153
- placement = "bottomLeft",
154
- open,
155
- arrow,
156
402
  className
157
403
  }) {
158
- return cn(dropdownBaseClass, dropdownPlacementClasses[placement], open && dropdownOpenClass, !arrow && "popover-no-arrow dropdown-no-arrow", className);
404
+ return cn(dropdownBaseClass, className);
159
405
  }
160
406
 
161
407
  // src/classes/menu.ts
@@ -208,9 +454,6 @@ function getMenuItemClasses({
208
454
 
209
455
  // src/components/dropdown/Dropdown.tsx
210
456
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
211
- function hasTrigger(triggers, trigger) {
212
- return (triggers ?? ["hover"]).includes(trigger);
213
- }
214
457
  function callHandler(handler, event) {
215
458
  handler?.(event);
216
459
  }
@@ -262,85 +505,103 @@ var DropdownRoot = forwardRef(({
262
505
  ...props
263
506
  }, ref) => {
264
507
  const [internalOpen, setInternalOpen] = useState(Boolean(defaultOpen));
265
- const isControlled = open !== undefined;
266
- const visible = isControlled ? open : internalOpen;
267
- const overlayId = useId();
268
- function setVisible(nextOpen) {
269
- if (disabled)
508
+ const [nativeOpen, setNativeOpen] = useState(Boolean(open ?? defaultOpen));
509
+ const visible = open ?? internalOpen;
510
+ const popupRef = useRef(null);
511
+ const popupId = useId();
512
+ const anchorName = `--dm-dropdown-${popupId.replace(/[^a-zA-Z0-9_-]/g, "")}`;
513
+ const clickTrigger = trigger.includes("click") || trigger.includes("hover");
514
+ useEffect(() => {
515
+ const popup = popupRef.current;
516
+ if (!popup?.showPopover || !popup?.hidePopover)
270
517
  return;
271
- if (!isControlled) {
518
+ if (visible && !popup.matches(":popover-open"))
519
+ popup.showPopover();
520
+ if (!visible && popup.matches(":popover-open"))
521
+ popup.hidePopover();
522
+ }, [visible]);
523
+ function setVisible(nextOpen) {
524
+ if (open === undefined)
272
525
  setInternalOpen(nextOpen);
273
- }
274
526
  onOpenChange?.(nextOpen);
275
527
  }
276
- const close = () => setVisible(false);
277
- const toggleVisible = () => setVisible(!visible);
528
+ function close() {
529
+ const popup = popupRef.current;
530
+ if (popup?.matches(":popover-open"))
531
+ popup.hidePopover();
532
+ else
533
+ setVisible(false);
534
+ }
278
535
  const menuNode = overlay ?? (menu?.items ? /* @__PURE__ */ jsx2("ul", {
279
536
  className: dropdownMenuClass,
280
537
  children: menu.items.map((item) => renderMenuItem(item, menu.onClick, close))
281
538
  }) : null);
282
539
  const popup = dropdownRender ? dropdownRender(menuNode) : menuNode;
283
- const shouldRenderPopup = !destroyPopupOnHide || visible;
284
- const triggerProps = {
285
- "aria-controls": visible ? overlayId : undefined,
286
- "aria-expanded": visible || undefined,
287
- onMouseEnter: hasTrigger(trigger, "hover") ? () => setVisible(true) : undefined,
288
- onMouseLeave: hasTrigger(trigger, "hover") ? () => setVisible(false) : undefined,
289
- onClick: hasTrigger(trigger, "click") ? toggleVisible : undefined,
290
- onContextMenu: hasTrigger(trigger, "contextMenu") ? (event) => {
291
- event.preventDefault();
292
- toggleVisible();
293
- } : undefined
540
+ const show = () => !disabled && popupRef.current?.showPopover?.();
541
+ const hide = () => !disabled && popupRef.current?.hidePopover?.();
542
+ const toggle = () => {
543
+ if (disabled)
544
+ return;
545
+ if (popupRef.current?.matches(":popover-open"))
546
+ hide();
547
+ else
548
+ show();
294
549
  };
550
+ const childIsButton = isValidElement(children) && (children.type === "button" || children.type === Button);
295
551
  const triggerNode = isValidElement(children) ? cloneElement(children, {
296
- "aria-controls": triggerProps["aria-controls"] ?? children.props["aria-controls"],
297
- "aria-expanded": triggerProps["aria-expanded"] ?? children.props["aria-expanded"],
552
+ popoverTarget: childIsButton && clickTrigger && !disabled ? popupId : undefined,
553
+ style: {
554
+ ...children.props.style,
555
+ anchorName
556
+ },
557
+ "aria-controls": popupId,
558
+ "aria-expanded": nativeOpen,
559
+ disabled: disabled || children.props.disabled,
298
560
  onMouseEnter: (event) => {
299
561
  callHandler(children.props.onMouseEnter, event);
300
- triggerProps.onMouseEnter?.();
562
+ if (trigger.includes("hover"))
563
+ show();
301
564
  onMouseEnter?.(event);
302
565
  },
303
566
  onMouseLeave: (event) => {
304
567
  callHandler(children.props.onMouseLeave, event);
305
- triggerProps.onMouseLeave?.();
306
568
  onMouseLeave?.(event);
307
569
  },
308
570
  onClick: (event) => {
309
571
  callHandler(children.props.onClick, event);
310
- triggerProps.onClick?.();
311
572
  onClick?.(event);
573
+ if (!childIsButton && clickTrigger && !event.defaultPrevented)
574
+ toggle();
312
575
  },
313
576
  onContextMenu: (event) => {
314
577
  callHandler(children.props.onContextMenu, event);
315
- triggerProps.onContextMenu?.(event);
578
+ if (trigger.includes("contextMenu")) {
579
+ event.preventDefault();
580
+ toggle();
581
+ }
316
582
  onContextMenu?.(event);
317
583
  }
318
- }) : /* @__PURE__ */ jsx2("span", {
319
- role: "button",
320
- tabIndex: disabled ? -1 : 0,
321
- "aria-disabled": disabled || undefined,
322
- "aria-controls": triggerProps["aria-controls"],
323
- "aria-expanded": triggerProps["aria-expanded"],
584
+ }) : /* @__PURE__ */ jsx2("button", {
585
+ type: "button",
586
+ disabled,
587
+ popoverTarget: clickTrigger && !disabled ? popupId : undefined,
588
+ style: { anchorName },
589
+ "aria-controls": popupId,
590
+ "aria-expanded": nativeOpen,
324
591
  onMouseEnter: (event) => {
325
- triggerProps.onMouseEnter?.();
592
+ if (trigger.includes("hover"))
593
+ show();
326
594
  onMouseEnter?.(event);
327
595
  },
328
596
  onMouseLeave: (event) => {
329
- triggerProps.onMouseLeave?.();
330
597
  onMouseLeave?.(event);
331
598
  },
332
- onClick: (event) => {
333
- triggerProps.onClick?.();
334
- onClick?.(event);
335
- },
336
- onKeyDown: (event) => {
337
- if (event.key === "Enter" || event.key === " ") {
599
+ onClick,
600
+ onContextMenu: (event) => {
601
+ if (trigger.includes("contextMenu")) {
338
602
  event.preventDefault();
339
- triggerProps.onClick?.();
603
+ toggle();
340
604
  }
341
- },
342
- onContextMenu: (event) => {
343
- triggerProps.onContextMenu?.(event);
344
605
  onContextMenu?.(event);
345
606
  },
346
607
  children
@@ -348,25 +609,30 @@ var DropdownRoot = forwardRef(({
348
609
  return /* @__PURE__ */ jsxs2("span", {
349
610
  ...props,
350
611
  ref,
351
- className: dropdownWrapperClass,
612
+ className: cn(dropdownWrapperClass, dropdownPlacementClasses[placement]),
613
+ onMouseLeave: trigger.includes("hover") ? hide : undefined,
352
614
  children: [
353
615
  triggerNode,
354
- shouldRenderPopup ? /* @__PURE__ */ jsxs2("span", {
355
- id: overlayId,
356
- role: "menu",
357
- className: getDropdownClasses({
358
- placement,
359
- open: visible,
360
- arrow,
361
- className
362
- }),
616
+ /* @__PURE__ */ jsxs2("span", {
617
+ id: popupId,
618
+ ref: popupRef,
619
+ popover: "auto",
620
+ style: { positionAnchor: anchorName },
621
+ className: getDropdownClasses({ className, arrow }),
622
+ onToggle: (event) => {
623
+ if (event.target !== event.currentTarget)
624
+ return;
625
+ const nextOpen = event.nativeEvent.newState === "open";
626
+ setNativeOpen(nextOpen);
627
+ setVisible(nextOpen);
628
+ },
363
629
  children: [
364
- popup,
630
+ !destroyPopupOnHide || visible ? popup : null,
365
631
  arrow ? /* @__PURE__ */ jsx2("span", {
366
632
  className: dropdownArrowClass
367
633
  }) : null
368
634
  ]
369
- }) : null
635
+ })
370
636
  ]
371
637
  });
372
638
  });
@@ -378,56 +644,80 @@ var DropdownButton = forwardRef(({
378
644
  menu,
379
645
  onClick,
380
646
  trigger = ["click"],
647
+ color = "base",
648
+ appearance = "outline",
649
+ size,
650
+ shape,
651
+ block,
652
+ isLoading,
653
+ leftIcon,
654
+ rightIcon,
655
+ confirm,
381
656
  ...props
382
657
  }, ref) => {
658
+ const buttonStyle = { color, appearance, size, shape };
383
659
  const buttons = [
384
660
  /* @__PURE__ */ jsx2(Button, {
661
+ ...buttonStyle,
385
662
  disabled,
663
+ isLoading,
664
+ leftIcon,
665
+ rightIcon,
666
+ confirm,
386
667
  onClick,
387
668
  children
388
669
  }, "primary"),
389
670
  /* @__PURE__ */ jsx2(Button, {
671
+ ...buttonStyle,
672
+ type: "button",
390
673
  "aria-label": "Open dropdown",
391
- disabled,
392
- children: "v"
674
+ disabled: disabled || isLoading,
675
+ children: /* @__PURE__ */ jsxs2("svg", {
676
+ "aria-hidden": "true",
677
+ width: "18",
678
+ height: "18",
679
+ viewBox: "0 0 24 24",
680
+ fill: "currentColor",
681
+ children: [
682
+ /* @__PURE__ */ jsx2("circle", {
683
+ cx: "5",
684
+ cy: "12",
685
+ r: "1.75"
686
+ }),
687
+ /* @__PURE__ */ jsx2("circle", {
688
+ cx: "12",
689
+ cy: "12",
690
+ r: "1.75"
691
+ }),
692
+ /* @__PURE__ */ jsx2("circle", {
693
+ cx: "19",
694
+ cy: "12",
695
+ r: "1.75"
696
+ })
697
+ ]
698
+ })
393
699
  }, "trigger")
394
700
  ];
395
701
  const renderedButtons = buttonsRender ? buttonsRender(buttons) : buttons;
396
- return /* @__PURE__ */ jsx2(DropdownRoot, {
397
- ...props,
702
+ return /* @__PURE__ */ jsxs2("span", {
398
703
  ref,
399
- menu,
400
- trigger,
401
- disabled,
402
- children: /* @__PURE__ */ jsx2("span", {
403
- className: dropdownButtonClass,
404
- children: renderedButtons
405
- })
704
+ className: cn(dropdownButtonClass, block && "dropdown-button-block"),
705
+ children: [
706
+ renderedButtons[0],
707
+ /* @__PURE__ */ jsx2(DropdownRoot, {
708
+ ...props,
709
+ menu,
710
+ trigger,
711
+ disabled: disabled || isLoading,
712
+ children: renderedButtons[1]
713
+ })
714
+ ]
406
715
  });
407
716
  });
408
717
  DropdownButton.displayName = "Dropdown.Button";
409
718
  var Dropdown = Object.assign(DropdownRoot, {
410
719
  Button: DropdownButton
411
720
  });
412
- // src/components/dm-toolbar/DmToolbar.tsx
413
- import { useMemo } from "react";
414
-
415
- // src/classes/dm-toolbar.ts
416
- var dmToolbarBaseClass = "dm-toolbar";
417
- var dmToolbarItemClass = "dm-toolbar-item";
418
- var dmToolbarPrimaryItemClass = "dm-toolbar-primary-item";
419
- var dmToolbarSecondaryItemClass = "dm-toolbar-secondary-item";
420
- var dmToolbarMoreClass = "dm-toolbar-more";
421
- function getDmToolbarClasses({ className }) {
422
- return cn(dmToolbarBaseClass, className);
423
- }
424
- function getDmToolbarItemClasses({
425
- primary,
426
- className
427
- }) {
428
- return cn(dmToolbarItemClass, primary ? dmToolbarPrimaryItemClass : dmToolbarSecondaryItemClass, className);
429
- }
430
-
431
721
  // src/components/dm-toolbar/DmToolbar.tsx
432
722
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
433
723
  function isPrimary(item) {
@@ -481,12 +771,12 @@ function DmToolbar({
481
771
  maxVisibleSecondaryItems
482
772
  }) {
483
773
  const { visibleSecondaryItems, overflowSecondaryItems, primaryItems } = useMemo(() => {
484
- const primaryItems2 = items.filter(isPrimary);
774
+ const primaryItems = items.filter(isPrimary);
485
775
  const secondaryItems = items.filter((item) => !isPrimary(item));
486
776
  const visibleLimit = maxVisibleSecondaryItems === undefined ? secondaryItems.length : Math.max(0, maxVisibleSecondaryItems);
487
- const visibleSecondaryItems2 = visibleLimit === 0 ? [] : secondaryItems.slice(-visibleLimit);
488
- const overflowSecondaryItems2 = visibleLimit >= secondaryItems.length ? [] : secondaryItems.slice(0, secondaryItems.length - visibleLimit);
489
- return { visibleSecondaryItems: visibleSecondaryItems2, overflowSecondaryItems: overflowSecondaryItems2, primaryItems: primaryItems2 };
777
+ const visibleSecondaryItems = visibleLimit === 0 ? [] : secondaryItems.slice(-visibleLimit);
778
+ const overflowSecondaryItems = visibleLimit >= secondaryItems.length ? [] : secondaryItems.slice(0, secondaryItems.length - visibleLimit);
779
+ return { visibleSecondaryItems, overflowSecondaryItems, primaryItems };
490
780
  }, [items, maxVisibleSecondaryItems]);
491
781
  const showMore = overflowSecondaryItems.length > 0;
492
782
  return /* @__PURE__ */ jsxs3("div", {