@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
@@ -0,0 +1,309 @@
1
+ "use client";
2
+
3
+ // src/components/chat/Chat.tsx
4
+ import { forwardRef } from "react";
5
+
6
+ // ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
7
+ function r(e) {
8
+ var t, f, n = "";
9
+ if (typeof e == "string" || typeof e == "number")
10
+ n += e;
11
+ else if (typeof e == "object")
12
+ if (Array.isArray(e)) {
13
+ var o = e.length;
14
+ for (t = 0;t < o; t++)
15
+ e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
16
+ } else
17
+ for (f in e)
18
+ e[f] && (n && (n += " "), n += f);
19
+ return n;
20
+ }
21
+ function clsx() {
22
+ for (var e, t, f = 0, n = "", o = arguments.length;f < o; f++)
23
+ (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
24
+ return n;
25
+ }
26
+
27
+ // src/utils/cn.ts
28
+ function cn(...inputs) {
29
+ return clsx(inputs);
30
+ }
31
+ // src/classes/chat.ts
32
+ var chatBaseClass = "chat";
33
+ var chatAvatarClass = "chat-avatar";
34
+ var chatHeaderClass = "chat-header";
35
+ var chatBubbleBaseClass = "chat-bubble";
36
+ var chatFooterClass = "chat-footer";
37
+ var chatStatusClass = "chat-status";
38
+ var chatStatusItemClass = "chat-status-item";
39
+ var chatStatusValueClass = "chat-status-value";
40
+ var chatActionsClass = "chat-actions";
41
+ var chatActionsHoverClass = "chat-actions-hover";
42
+ var chatScrollClass = "chat-scroll";
43
+ var chatScrollBodyClass = "chat-scroll-body";
44
+ var chatScrollTrackClass = "chat-scroll-track";
45
+ var chatScrollIndicatorClass = "chat-scroll-indicator";
46
+ var chatReasoningClass = "chat-reasoning";
47
+ var chatToolBaseClass = "chat-tool";
48
+ var chatToolHeaderClass = "chat-tool-header";
49
+ var chatToolStatusClass = "chat-tool-status";
50
+ var chatToolCallClass = "chat-tool-call";
51
+ var chatToolResultClass = "chat-tool-result";
52
+ var chatTypingClass = "chat-typing";
53
+ var chatBubbleFilledClass = "chat-bubble-filled";
54
+ var chatBubbleStreamingClass = "chat-bubble-streaming";
55
+ var chatPlacementClasses = {
56
+ start: "chat-start",
57
+ end: "chat-end"
58
+ };
59
+ var chatBubbleColorClasses = {
60
+ primary: "chat-bubble-primary",
61
+ secondary: "chat-bubble-secondary",
62
+ tertiary: "chat-bubble-tertiary",
63
+ accent: "chat-bubble-accent",
64
+ neutral: "chat-bubble-neutral",
65
+ base: "chat-bubble-base",
66
+ info: "chat-bubble-info",
67
+ success: "chat-bubble-success",
68
+ warning: "chat-bubble-warning",
69
+ error: "chat-bubble-error"
70
+ };
71
+ var chatBubbleSizeClasses = {
72
+ xs: "chat-bubble-xs",
73
+ sm: "chat-bubble-sm",
74
+ md: "chat-bubble-md",
75
+ lg: "chat-bubble-lg"
76
+ };
77
+ var chatToolStateClasses = {
78
+ pending: "chat-tool-pending",
79
+ running: "chat-tool-running",
80
+ success: "chat-tool-success",
81
+ error: "chat-tool-error"
82
+ };
83
+ function getChatClasses({
84
+ placement = "start",
85
+ className
86
+ }) {
87
+ return cn(chatBaseClass, chatPlacementClasses[placement], className);
88
+ }
89
+ function getChatBubbleClasses({
90
+ color,
91
+ size = "md",
92
+ filled,
93
+ streaming,
94
+ className
95
+ }) {
96
+ return cn(chatBubbleBaseClass, color && chatBubbleColorClasses[color], chatBubbleSizeClasses[size], filled && chatBubbleFilledClass, streaming && chatBubbleStreamingClass, className);
97
+ }
98
+ function getChatToolClasses({
99
+ status,
100
+ className
101
+ }) {
102
+ return cn(chatToolBaseClass, status && chatToolStateClasses[status], className);
103
+ }
104
+
105
+ // src/components/chat/Chat.tsx
106
+ import { jsx, jsxs } from "react/jsx-runtime";
107
+ var ChatAvatar = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
108
+ ...props,
109
+ ref,
110
+ className: cn(chatAvatarClass, className)
111
+ }));
112
+ ChatAvatar.displayName = "Chat.Avatar";
113
+ var ChatHeader = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
114
+ ...props,
115
+ ref,
116
+ className: cn(chatHeaderClass, className)
117
+ }));
118
+ ChatHeader.displayName = "Chat.Header";
119
+ var ChatBubble = forwardRef(({ color, size = "md", filled, streaming, className, children, ...props }, ref) => /* @__PURE__ */ jsxs("div", {
120
+ ...props,
121
+ ref,
122
+ className: getChatBubbleClasses({
123
+ color,
124
+ size,
125
+ filled,
126
+ streaming,
127
+ className
128
+ }),
129
+ children: [
130
+ children,
131
+ streaming ? /* @__PURE__ */ jsx("span", {
132
+ className: "chat-bubble-content chat-bubble-streaming",
133
+ "aria-hidden": "true"
134
+ }) : null
135
+ ]
136
+ }));
137
+ ChatBubble.displayName = "Chat.Bubble";
138
+ var ChatFooter = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
139
+ ...props,
140
+ ref,
141
+ className: cn(chatFooterClass, className)
142
+ }));
143
+ ChatFooter.displayName = "Chat.Footer";
144
+ var ChatStatus = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
145
+ ...props,
146
+ ref,
147
+ className: cn(chatStatusClass, className)
148
+ }));
149
+ ChatStatus.displayName = "Chat.Status";
150
+ var ChatStatusItem = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("span", {
151
+ ...props,
152
+ ref,
153
+ className: cn(chatStatusItemClass, className)
154
+ }));
155
+ ChatStatusItem.displayName = "Chat.StatusItem";
156
+ var ChatStatusValue = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("span", {
157
+ ...props,
158
+ ref,
159
+ className: cn(chatStatusValueClass, className)
160
+ }));
161
+ ChatStatusValue.displayName = "Chat.StatusValue";
162
+ var ChatActions = forwardRef(({ hover, className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
163
+ ...props,
164
+ ref,
165
+ className: cn(chatActionsClass, hover && chatActionsHoverClass, className)
166
+ }));
167
+ ChatActions.displayName = "Chat.Actions";
168
+ var ChatScroll = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
169
+ ...props,
170
+ ref,
171
+ className: cn(chatScrollClass, className)
172
+ }));
173
+ ChatScroll.displayName = "Chat.Scroll";
174
+ var ChatScrollBody = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
175
+ ...props,
176
+ ref,
177
+ className: cn(chatScrollBodyClass, className)
178
+ }));
179
+ ChatScrollBody.displayName = "Chat.ScrollBody";
180
+ var ChatScrollTrack = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
181
+ ...props,
182
+ ref,
183
+ className: cn(chatScrollTrackClass, className)
184
+ }));
185
+ ChatScrollTrack.displayName = "Chat.ScrollTrack";
186
+ var ChatScrollIndicator = forwardRef(({ targetId, timeline, type = "button", className, onClick, ...props }, ref) => /* @__PURE__ */ jsx("button", {
187
+ ...props,
188
+ ref,
189
+ type,
190
+ "data-chat-target": targetId,
191
+ "data-chat-tl": timeline,
192
+ "aria-label": props["aria-label"] ?? (props["aria-labelledby"] ? undefined : `Jump to assistant reply ${timeline}`),
193
+ className: cn(chatScrollIndicatorClass, className),
194
+ onClick: (event) => {
195
+ onClick?.(event);
196
+ if (event.defaultPrevented)
197
+ return;
198
+ const scroller = event.currentTarget.closest(`.${chatScrollClass}`);
199
+ const target = Array.from(scroller?.querySelectorAll("[id]") ?? []).find((element) => element.id === targetId && element.closest(`.${chatScrollClass}`) === scroller);
200
+ if (!scroller || !target)
201
+ return;
202
+ const top = scroller.scrollTop + target.getBoundingClientRect().top - scroller.getBoundingClientRect().top;
203
+ const reducedMotion = scroller.ownerDocument.defaultView?.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
204
+ scroller.scrollTo({ top, behavior: reducedMotion ? "auto" : "smooth" });
205
+ }
206
+ }));
207
+ ChatScrollIndicator.displayName = "Chat.ScrollIndicator";
208
+ var ChatReasoning = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("details", {
209
+ ...props,
210
+ ref,
211
+ className: cn(chatReasoningClass, className)
212
+ }));
213
+ ChatReasoning.displayName = "Chat.Reasoning";
214
+ var ChatTool = forwardRef(({ status, className, ...props }, ref) => /* @__PURE__ */ jsx("details", {
215
+ ...props,
216
+ ref,
217
+ className: getChatToolClasses({ status, className })
218
+ }));
219
+ ChatTool.displayName = "Chat.Tool";
220
+ var ChatToolHeader = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("summary", {
221
+ ...props,
222
+ ref,
223
+ className: cn(chatToolHeaderClass, className)
224
+ }));
225
+ ChatToolHeader.displayName = "Chat.ToolHeader";
226
+ var ChatToolStatus = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("span", {
227
+ ...props,
228
+ ref,
229
+ className: cn(chatToolStatusClass, className)
230
+ }));
231
+ ChatToolStatus.displayName = "Chat.ToolStatus";
232
+ var ChatToolCall = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
233
+ ...props,
234
+ ref,
235
+ className: cn(chatToolCallClass, className)
236
+ }));
237
+ ChatToolCall.displayName = "Chat.ToolCall";
238
+ var ChatToolResult = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
239
+ ...props,
240
+ ref,
241
+ className: cn(chatToolResultClass, className)
242
+ }));
243
+ ChatToolResult.displayName = "Chat.ToolResult";
244
+ var ChatTyping = forwardRef(({
245
+ className,
246
+ role = "status",
247
+ "aria-label": ariaLabel = "Assistant is typing",
248
+ ...props
249
+ }, ref) => /* @__PURE__ */ jsx("span", {
250
+ ...props,
251
+ ref,
252
+ role,
253
+ "aria-label": ariaLabel,
254
+ className: cn(chatTypingClass, className),
255
+ children: /* @__PURE__ */ jsx("span", {
256
+ "aria-hidden": "true"
257
+ })
258
+ }));
259
+ ChatTyping.displayName = "Chat.Typing";
260
+ var ChatRoot = forwardRef(({ placement = "start", timeline, className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
261
+ ...props,
262
+ ref,
263
+ "data-chat-tl": timeline ?? props["data-chat-tl"],
264
+ className: getChatClasses({ placement, className })
265
+ }));
266
+ ChatRoot.displayName = "Chat";
267
+ var Chat = Object.assign(ChatRoot, {
268
+ Avatar: ChatAvatar,
269
+ Header: ChatHeader,
270
+ Bubble: ChatBubble,
271
+ Footer: ChatFooter,
272
+ Status: ChatStatus,
273
+ StatusItem: ChatStatusItem,
274
+ StatusValue: ChatStatusValue,
275
+ Actions: ChatActions,
276
+ Scroll: ChatScroll,
277
+ ScrollBody: ChatScrollBody,
278
+ ScrollTrack: ChatScrollTrack,
279
+ ScrollIndicator: ChatScrollIndicator,
280
+ Reasoning: ChatReasoning,
281
+ Tool: ChatTool,
282
+ ToolHeader: ChatToolHeader,
283
+ ToolStatus: ChatToolStatus,
284
+ ToolCall: ChatToolCall,
285
+ ToolResult: ChatToolResult,
286
+ Typing: ChatTyping
287
+ });
288
+ export {
289
+ Chat,
290
+ ChatActions,
291
+ ChatAvatar,
292
+ ChatBubble,
293
+ ChatFooter,
294
+ ChatHeader,
295
+ ChatReasoning,
296
+ ChatScroll,
297
+ ChatScrollBody,
298
+ ChatScrollIndicator,
299
+ ChatScrollTrack,
300
+ ChatStatus,
301
+ ChatStatusItem,
302
+ ChatStatusValue,
303
+ ChatTool,
304
+ ChatToolCall,
305
+ ChatToolHeader,
306
+ ChatToolResult,
307
+ ChatToolStatus,
308
+ ChatTyping
309
+ };
@@ -1,4 +1,4 @@
1
- import type { ComponentPropsWithoutRef, ForwardRefExoticComponent, ReactNode, RefAttributes } from "react";
1
+ import type { ComponentProps, ComponentPropsWithoutRef, ForwardRefExoticComponent, ReactNode, RefAttributes } from "react";
2
2
  export type ColorPickerFormat = "hex" | "rgb" | "hsb";
3
3
  export type ColorPickerTrigger = "hover" | "click";
4
4
  export type ColorPickerSize = "small" | "middle" | "large" | "sm" | "md" | "lg";
@@ -20,6 +20,7 @@ export interface ColorPreset {
20
20
  colors: ColorValue[];
21
21
  }
22
22
  export interface ColorPickerProps extends Omit<ComponentPropsWithoutRef<"div">, "children" | "defaultValue" | "onChange"> {
23
+ triggerProps?: ComponentProps<"button">;
23
24
  value?: ColorValue;
24
25
  defaultValue?: ColorValue;
25
26
  format?: ColorPickerFormat;
@@ -1,7 +1,14 @@
1
1
  "use client";
2
2
 
3
3
  // src/components/color-picker/ColorPicker.tsx
4
- import { forwardRef, useState } from "react";
4
+ import {
5
+ forwardRef,
6
+ useEffect,
7
+ useId,
8
+ useImperativeHandle,
9
+ useRef,
10
+ useState
11
+ } from "react";
5
12
 
6
13
  // ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
7
14
  function r(e) {
@@ -88,9 +95,9 @@ function hsbToRgb(value) {
88
95
  const c = brightness * s;
89
96
  const x = c * (1 - Math.abs(h / 60 % 2 - 1));
90
97
  const m = brightness - c;
91
- const [r2, g, b] = h < 60 ? [c, x, 0] : h < 120 ? [x, c, 0] : h < 180 ? [0, c, x] : h < 240 ? [0, x, c] : h < 300 ? [x, 0, c] : [c, 0, x];
98
+ const [r, g, b] = h < 60 ? [c, x, 0] : h < 120 ? [x, c, 0] : h < 180 ? [0, c, x] : h < 240 ? [0, x, c] : h < 300 ? [x, 0, c] : [c, 0, x];
92
99
  return {
93
- r: (r2 + m) * 255,
100
+ r: (r + m) * 255,
94
101
  g: (g + m) * 255,
95
102
  b: (b + m) * 255,
96
103
  a: value.a
@@ -102,7 +109,7 @@ function colorToRgb(value) {
102
109
  if (isHsb(value))
103
110
  return hsbToRgb(value);
104
111
  const normalized = value.trim();
105
- if (normalized.startsWith("#")) {
112
+ if (/^#(?:[a-f\d]{3}|[a-f\d]{6})$/i.test(normalized)) {
106
113
  const hex = normalized.slice(1);
107
114
  const fullHex = hex.length === 3 ? hex.split("").map((item) => item + item).join("") : hex.padEnd(6, "0").slice(0, 6);
108
115
  return {
@@ -113,22 +120,49 @@ function colorToRgb(value) {
113
120
  }
114
121
  const match = normalized.match(/rgba?\(([^)]+)\)/i);
115
122
  if (match) {
116
- const [r2, g, b, a] = match[1].split(",").map((part) => Number(part.trim()));
117
- return { r: r2, g, b, a };
123
+ const [r, g, b, a] = match[1].split(",").map((part) => Number(part.trim()));
124
+ return { r, g, b, a };
118
125
  }
119
126
  return { r: 0, g: 0, b: 0 };
120
127
  }
128
+ function colorToHsb(value) {
129
+ if (isHsb(value))
130
+ return {
131
+ ...value,
132
+ h: (value.h % 360 + 360) % 360,
133
+ s: clamp(value.s, 0, 100),
134
+ b: clamp(value.b, 0, 100)
135
+ };
136
+ const rgb = colorToRgb(value);
137
+ const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((part) => Number.isFinite(part) ? clamp(part, 0, 255) / 255 : 0);
138
+ const max = Math.max(r, g, b);
139
+ const delta = max - Math.min(r, g, b);
140
+ const hue = delta === 0 ? 0 : max === r ? (g - b) / delta % 6 : max === g ? (b - r) / delta + 2 : (r - g) / delta + 4;
141
+ return {
142
+ h: (hue * 60 + 360) % 360,
143
+ s: max === 0 ? 0 : delta / max * 100,
144
+ b: max * 100,
145
+ a: rgb.a
146
+ };
147
+ }
121
148
  function colorToCss(value, format) {
122
149
  const rgb = colorToRgb(value);
123
150
  if (format === "rgb") {
124
151
  return rgb.a !== undefined ? `rgba(${Math.round(rgb.r)}, ${Math.round(rgb.g)}, ${Math.round(rgb.b)}, ${rgb.a})` : `rgb(${Math.round(rgb.r)}, ${Math.round(rgb.g)}, ${Math.round(rgb.b)})`;
125
152
  }
126
- if (format === "hsb" && isHsb(value)) {
127
- return `hsb(${Math.round(value.h)}, ${Math.round(value.s)}%, ${Math.round(value.b)}%)`;
153
+ if (format === "hsb") {
154
+ const hsb = colorToHsb(value);
155
+ return `hsb(${Math.round(hsb.h)}, ${Math.round(hsb.s)}%, ${Math.round(hsb.b)}%)`;
128
156
  }
129
157
  return `#${componentToHex(rgb.r)}${componentToHex(rgb.g)}${componentToHex(rgb.b)}`;
130
158
  }
131
159
  function parseInput(value, format) {
160
+ if (format === "hsb") {
161
+ const match = value.match(/^hsb\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i);
162
+ if (match)
163
+ return { h: Number(match[1]), s: Number(match[2]), b: Number(match[3]) };
164
+ return value;
165
+ }
132
166
  if (format === "rgb") {
133
167
  const rgb = colorToRgb(value);
134
168
  return {
@@ -156,9 +190,14 @@ var ColorPicker = forwardRef(({
156
190
  showText,
157
191
  size = "middle",
158
192
  trigger = "click",
193
+ triggerProps,
159
194
  value,
160
195
  ...props
161
196
  }, ref) => {
197
+ const rootRef = useRef(null);
198
+ const triggerRef = useRef(null);
199
+ const panelId = useId();
200
+ useImperativeHandle(ref, () => rootRef.current, []);
162
201
  const valueControlled = value !== undefined;
163
202
  const openControlled = open !== undefined;
164
203
  const [innerValue, setInnerValue] = useState(defaultValue);
@@ -166,6 +205,16 @@ var ColorPicker = forwardRef(({
166
205
  const currentValue = valueControlled ? value : innerValue;
167
206
  const visible = openControlled ? Boolean(open) : innerOpen;
168
207
  const cssValue = colorToCss(currentValue, format);
208
+ const [lastSelection, setLastSelection] = useState(() => colorToHsb(currentValue));
209
+ const selection = colorToHsb(currentValue);
210
+ if (selection.s === 0 || selection.b === 0)
211
+ selection.h = lastSelection.h;
212
+ if (selection.b === 0)
213
+ selection.s = lastSelection.s;
214
+ if (selection.h === 0 && lastSelection.h === 360)
215
+ selection.h = 360;
216
+ const pointerId = useRef(null);
217
+ const instructionsId = useId();
169
218
  function setVisible(nextOpen) {
170
219
  if (disabled)
171
220
  return;
@@ -174,21 +223,163 @@ var ColorPicker = forwardRef(({
174
223
  }
175
224
  onOpenChange?.(nextOpen);
176
225
  }
177
- function emitChange(nextValue) {
226
+ useEffect(() => {
227
+ if (!visible)
228
+ return;
229
+ function dismissOutside(event) {
230
+ if (!rootRef.current?.contains(event.target))
231
+ setVisible(false);
232
+ }
233
+ function dismissEscape(event) {
234
+ if (event.key === "Escape" && rootRef.current?.contains(event.target)) {
235
+ event.preventDefault();
236
+ setVisible(false);
237
+ triggerRef.current?.focus();
238
+ }
239
+ }
240
+ document.addEventListener("pointerdown", dismissOutside);
241
+ document.addEventListener("keydown", dismissEscape);
242
+ return () => {
243
+ document.removeEventListener("pointerdown", dismissOutside);
244
+ document.removeEventListener("keydown", dismissEscape);
245
+ };
246
+ });
247
+ function emitChange(nextValue, complete = true) {
248
+ if (disabled)
249
+ return;
178
250
  const css = colorToCss(nextValue, format);
179
251
  if (!valueControlled) {
180
252
  setInnerValue(nextValue);
181
253
  }
182
254
  onChange?.(nextValue, css);
183
- onChangeComplete?.(nextValue, css);
255
+ if (complete)
256
+ onChangeComplete?.(nextValue, css);
257
+ }
258
+ function selectColor(next, complete = true) {
259
+ if (disabled)
260
+ return;
261
+ setLastSelection(next);
262
+ emitChange(format === "hex" ? colorToCss(next, "hex") : format === "rgb" ? hsbToRgb(next) : next, complete);
263
+ }
264
+ function selectPosition(event, complete = false) {
265
+ const bounds = event.currentTarget.getBoundingClientRect();
266
+ if (disabled || bounds.width === 0 || bounds.height === 0)
267
+ return;
268
+ selectColor({
269
+ ...selection,
270
+ s: clamp((event.clientX - bounds.left) / bounds.width * 100, 0, 100),
271
+ b: clamp(100 - (event.clientY - bounds.top) / bounds.height * 100, 0, 100)
272
+ }, complete);
184
273
  }
185
274
  const panel = /* @__PURE__ */ jsxs("div", {
275
+ id: panelId,
186
276
  className: colorPickerPanelClass,
277
+ role: "dialog",
278
+ "aria-label": "Choose color",
187
279
  children: [
280
+ /* @__PURE__ */ jsx("div", {
281
+ className: "color-picker-area",
282
+ role: "slider",
283
+ "aria-label": "Saturation and brightness",
284
+ "aria-valuemin": 0,
285
+ "aria-valuemax": 100,
286
+ "aria-valuenow": Math.round(selection.s),
287
+ "aria-valuetext": `Saturation ${Math.round(selection.s)}%, brightness ${Math.round(selection.b)}%`,
288
+ "aria-describedby": instructionsId,
289
+ "aria-disabled": Boolean(disabled),
290
+ tabIndex: disabled ? -1 : 0,
291
+ style: { "--color-picker-hue": `${selection.h}` },
292
+ onPointerDown: (event) => {
293
+ if (disabled || event.button !== 0)
294
+ return;
295
+ event.preventDefault();
296
+ event.currentTarget.focus();
297
+ pointerId.current = event.pointerId;
298
+ event.currentTarget.setPointerCapture?.(event.pointerId);
299
+ selectPosition(event);
300
+ },
301
+ onPointerMove: (event) => {
302
+ if (pointerId.current === event.pointerId)
303
+ selectPosition(event);
304
+ },
305
+ onPointerUp: (event) => {
306
+ if (pointerId.current !== event.pointerId)
307
+ return;
308
+ selectPosition(event, true);
309
+ pointerId.current = null;
310
+ event.currentTarget.releasePointerCapture?.(event.pointerId);
311
+ },
312
+ onPointerCancel: () => {
313
+ pointerId.current = null;
314
+ },
315
+ onLostPointerCapture: () => {
316
+ pointerId.current = null;
317
+ },
318
+ onKeyDown: (event) => {
319
+ if (disabled)
320
+ return;
321
+ const step = event.shiftKey ? 10 : 1;
322
+ let { s, b } = selection;
323
+ switch (event.key) {
324
+ case "ArrowLeft":
325
+ s -= step;
326
+ break;
327
+ case "ArrowRight":
328
+ s += step;
329
+ break;
330
+ case "ArrowDown":
331
+ b -= step;
332
+ break;
333
+ case "ArrowUp":
334
+ b += step;
335
+ break;
336
+ case "Home":
337
+ s = 0;
338
+ break;
339
+ case "End":
340
+ s = 100;
341
+ break;
342
+ default:
343
+ return;
344
+ }
345
+ event.preventDefault();
346
+ selectColor({
347
+ ...selection,
348
+ s: clamp(s, 0, 100),
349
+ b: clamp(b, 0, 100)
350
+ });
351
+ },
352
+ children: /* @__PURE__ */ jsx("span", {
353
+ className: "color-picker-area-indicator",
354
+ "aria-hidden": "true",
355
+ style: {
356
+ left: `${selection.s}%`,
357
+ top: `${100 - selection.b}%`,
358
+ backgroundColor: colorToCss(currentValue, "hex")
359
+ }
360
+ })
361
+ }),
362
+ /* @__PURE__ */ jsx("span", {
363
+ id: instructionsId,
364
+ className: "color-picker-instructions",
365
+ children: "Left/right: saturation. Up/down: brightness. Shift: larger steps."
366
+ }),
367
+ /* @__PURE__ */ jsx("input", {
368
+ className: "color-picker-hue",
369
+ type: "range",
370
+ "aria-label": "Hue",
371
+ min: 0,
372
+ max: 360,
373
+ step: 1,
374
+ value: selection.h,
375
+ disabled,
376
+ onChange: (event) => selectColor({ ...selection, h: Number(event.currentTarget.value) })
377
+ }),
188
378
  /* @__PURE__ */ jsx("input", {
189
379
  className: colorPickerInputClass,
190
380
  "aria-label": "Color value",
191
- value: cssValue,
381
+ value: format === "hex" && typeof currentValue === "string" ? currentValue : cssValue,
382
+ disabled,
192
383
  onChange: (event) => emitChange(parseInput(event.currentTarget.value, format))
193
384
  }),
194
385
  presets?.length ? /* @__PURE__ */ jsx("div", {
@@ -206,6 +397,7 @@ var ColorPicker = forwardRef(({
206
397
  const presetCss = colorToCss(presetColor, format);
207
398
  return /* @__PURE__ */ jsx("button", {
208
399
  type: "button",
400
+ disabled,
209
401
  "aria-label": `Select color ${presetCss}`,
210
402
  className: colorPickerSwatchClass,
211
403
  style: {
@@ -222,7 +414,7 @@ var ColorPicker = forwardRef(({
222
414
  });
223
415
  return /* @__PURE__ */ jsxs("div", {
224
416
  ...props,
225
- ref,
417
+ ref: rootRef,
226
418
  className: getColorPickerClasses({
227
419
  size,
228
420
  trigger,
@@ -241,9 +433,14 @@ var ColorPicker = forwardRef(({
241
433
  },
242
434
  children: [
243
435
  /* @__PURE__ */ jsx("button", {
436
+ ...triggerProps,
437
+ ref: triggerRef,
244
438
  type: "button",
439
+ "aria-haspopup": "dialog",
440
+ "aria-expanded": visible,
441
+ "aria-controls": visible ? panelId : undefined,
245
442
  className: colorPickerSwatchClass,
246
- "aria-label": "Open color picker",
443
+ "aria-label": triggerProps?.["aria-label"] ?? "Open color picker",
247
444
  disabled,
248
445
  style: { backgroundColor: colorToCss(currentValue, "hex") },
249
446
  onClick: () => {
@@ -122,6 +122,6 @@ ConfigProvider.config = (config) => {
122
122
  globalConfig = { ...globalConfig, ...config };
123
123
  };
124
124
  export {
125
- ConfigProvider,
126
- ConfigContext
125
+ ConfigContext,
126
+ ConfigProvider
127
127
  };
@@ -0,0 +1,2 @@
1
+ import type { ConsolePageComponent } from "./ConsolePage.types";
2
+ export declare const ConsolePage: ConsolePageComponent;
@@ -0,0 +1,29 @@
1
+ import type { ComponentProps, ForwardRefExoticComponent, ReactNode, RefAttributes } from "react";
2
+ import type { ConsolePageSidebarState } from "../../classes/console-page";
3
+ export interface ConsolePageProps extends Omit<ComponentProps<"div">, "ref"> {
4
+ sidebarState?: ConsolePageSidebarState;
5
+ sidebarMode?: ConsolePageSidebarState;
6
+ appBar?: ReactNode;
7
+ sidebar?: ReactNode;
8
+ sidebarHeader?: ReactNode;
9
+ sidebarFooter?: ReactNode;
10
+ }
11
+ export type ConsolePageSidebarMode = ConsolePageSidebarState;
12
+ export type ConsolePageFrameProps = Omit<ComponentProps<"div">, "ref">;
13
+ export type ConsolePageAppbarProps = Omit<ComponentProps<"header">, "ref">;
14
+ export type ConsolePageSidebarProps = Omit<ComponentProps<"aside">, "ref">;
15
+ export type ConsolePageSidebarBodyProps = Omit<ComponentProps<"nav">, "ref">;
16
+ export type ConsolePageMainProps = Omit<ComponentProps<"main">, "ref">;
17
+ export type ConsolePageButtonProps = Omit<ComponentProps<"button">, "ref">;
18
+ export interface ConsolePageComponent extends ForwardRefExoticComponent<ConsolePageProps & RefAttributes<HTMLDivElement>> {
19
+ Frame: ForwardRefExoticComponent<ConsolePageFrameProps & RefAttributes<HTMLDivElement>>;
20
+ Appbar: ForwardRefExoticComponent<ConsolePageAppbarProps & RefAttributes<HTMLElement>>;
21
+ Sidebar: ForwardRefExoticComponent<ConsolePageSidebarProps & RefAttributes<HTMLElement>>;
22
+ SidebarHeader: ForwardRefExoticComponent<ConsolePageFrameProps & RefAttributes<HTMLDivElement>>;
23
+ SidebarBody: ForwardRefExoticComponent<ConsolePageSidebarBodyProps & RefAttributes<HTMLElement>>;
24
+ SidebarFooter: ForwardRefExoticComponent<ConsolePageFrameProps & RefAttributes<HTMLDivElement>>;
25
+ Main: ForwardRefExoticComponent<ConsolePageMainProps & RefAttributes<HTMLElement>>;
26
+ SidebarToggle: ForwardRefExoticComponent<ConsolePageButtonProps & RefAttributes<HTMLButtonElement>>;
27
+ MobileTrigger: ForwardRefExoticComponent<ConsolePageButtonProps & RefAttributes<HTMLButtonElement>>;
28
+ MobileMenu: ForwardRefExoticComponent<ConsolePageSidebarBodyProps & RefAttributes<HTMLElement>>;
29
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./ConsolePage";
2
+ export * from "./ConsolePage.types";