@duskmoon-dev/components 0.3.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/README.md +142 -2
  2. package/dist/classes/chat.d.ts +9 -1
  3. package/dist/classes/console-page.d.ts +16 -0
  4. package/dist/classes/dropdown.d.ts +5 -5
  5. package/dist/classes/fab.d.ts +11 -0
  6. package/dist/classes/index.d.ts +5 -0
  7. package/dist/classes/index.js +180 -34
  8. package/dist/classes/megamenu.d.ts +10 -0
  9. package/dist/classes/otp-input.d.ts +12 -0
  10. package/dist/classes/popover.d.ts +1 -3
  11. package/dist/classes/swap.d.ts +12 -0
  12. package/dist/classes/tree-select.d.ts +6 -6
  13. package/dist/components/app/index.js +128 -68
  14. package/dist/components/avatar/Avatar.types.d.ts +1 -1
  15. package/dist/components/avatar/index.js +2 -1
  16. package/dist/components/badge/index.js +1 -1
  17. package/dist/components/button/Button.d.ts +1 -1
  18. package/dist/components/button/Button.types.d.ts +8 -0
  19. package/dist/components/button/index.js +253 -24
  20. package/dist/components/calendar/index.js +44 -19
  21. package/dist/components/chat/Chat.d.ts +9 -1
  22. package/dist/components/chat/Chat.types.d.ts +26 -0
  23. package/dist/components/chat/index.js +92 -3
  24. package/dist/components/color-picker/ColorPicker.types.d.ts +2 -1
  25. package/dist/components/color-picker/index.js +206 -9
  26. package/dist/components/console-page/ConsolePage.d.ts +2 -0
  27. package/dist/components/console-page/ConsolePage.types.d.ts +29 -0
  28. package/dist/components/console-page/index.d.ts +2 -0
  29. package/dist/components/console-page/index.js +205 -0
  30. package/dist/components/date-picker/DatePicker.types.d.ts +1 -0
  31. package/dist/components/date-picker/index.js +537 -35
  32. package/dist/components/date-picker/usePickerDropdown.d.ts +17 -0
  33. package/dist/components/dm-date-picker/index.js +545 -43
  34. package/dist/components/dm-drawer/index.js +253 -24
  35. package/dist/components/dm-layout/index.js +391 -24
  36. package/dist/components/dm-menu/index.js +380 -13
  37. package/dist/components/dm-page-header/index.js +404 -114
  38. package/dist/components/dm-pro-table/index.js +1195 -368
  39. package/dist/components/dm-query/DmQuery.types.d.ts +1 -1
  40. package/dist/components/dm-query/index.js +943 -188
  41. package/dist/components/dm-search/DmSearch.types.d.ts +4 -0
  42. package/dist/components/dm-search/index.js +929 -163
  43. package/dist/components/dm-table/index.js +1013 -247
  44. package/dist/components/dm-toolbar/index.js +400 -110
  45. package/dist/components/dm-truncate/index.js +115 -35
  46. package/dist/components/dropdown/Dropdown.types.d.ts +1 -1
  47. package/dist/components/dropdown/index.js +400 -110
  48. package/dist/components/fab/Fab.d.ts +4 -0
  49. package/dist/components/fab/Fab.types.d.ts +25 -0
  50. package/dist/components/fab/index.d.ts +2 -0
  51. package/dist/components/fab/index.js +480 -0
  52. package/dist/components/form/Form.types.d.ts +1 -0
  53. package/dist/components/form/index.js +14 -3
  54. package/dist/components/json-schema-form/JsonSchemaForm.d.ts +19 -0
  55. package/dist/components/json-schema-form/JsonSchemaWidget.d.ts +14 -0
  56. package/dist/components/json-schema-form/index.d.ts +8 -0
  57. package/dist/components/json-schema-form/index.js +7661 -0
  58. package/dist/components/json-schema-form/json-form-widgets.d.ts +26 -0
  59. package/dist/components/json-schema-form/json-schema-form.d.ts +50 -0
  60. package/dist/components/megamenu/Megamenu.d.ts +2 -0
  61. package/dist/components/megamenu/Megamenu.types.d.ts +32 -0
  62. package/dist/components/megamenu/index.d.ts +2 -0
  63. package/dist/components/megamenu/index.js +214 -0
  64. package/dist/components/modal/index.js +128 -68
  65. package/dist/components/otp-input/OtpInput.d.ts +2 -0
  66. package/dist/components/otp-input/OtpInput.types.d.ts +16 -0
  67. package/dist/components/otp-input/index.d.ts +2 -0
  68. package/dist/components/otp-input/index.js +112 -0
  69. package/dist/components/popconfirm/index.js +255 -26
  70. package/dist/components/popover/index.js +24 -4
  71. package/dist/components/select/index.js +12 -0
  72. package/dist/components/swap/Swap.d.ts +3 -0
  73. package/dist/components/swap/Swap.types.d.ts +22 -0
  74. package/dist/components/swap/index.d.ts +2 -0
  75. package/dist/components/swap/index.js +109 -0
  76. package/dist/components/time-picker/TimePicker.types.d.ts +1 -0
  77. package/dist/components/time-picker/index.js +167 -29
  78. package/dist/components/tooltip/Tooltip.types.d.ts +4 -0
  79. package/dist/components/tooltip/index.js +107 -27
  80. package/dist/components/tour/index.js +253 -24
  81. package/dist/components/tree-select/index.js +8 -8
  82. package/dist/components/upload/Upload.types.d.ts +1 -0
  83. package/dist/components/upload/index.js +2 -0
  84. package/dist/generated/version.d.ts +1 -1
  85. package/dist/index.d.ts +5 -0
  86. package/dist/index.js +3343 -1633
  87. package/dist/infrastructure.js +1 -1
  88. package/dist/styles.css +1359 -865
  89. package/package.json +31 -5
@@ -140,29 +140,33 @@ function Header({
140
140
  return /* @__PURE__ */ jsxs("div", {
141
141
  className: calendarHeaderClass,
142
142
  children: [
143
- /* @__PURE__ */ jsx("div", {
144
- className: calendarTitleClass,
145
- children: title
143
+ /* @__PURE__ */ jsx("button", {
144
+ type: "button",
145
+ className: calendarNavClass,
146
+ "aria-label": "Previous panel",
147
+ onClick: () => setPanelDate(mode === "year" ? addYears(panelDate, -1) : addMonths(panelDate, -1), mode),
148
+ children: /* @__PURE__ */ jsx("svg", {
149
+ "aria-hidden": "true",
150
+ focusable: "false",
151
+ width: "16",
152
+ height: "16",
153
+ viewBox: "0 0 24 24",
154
+ fill: "none",
155
+ stroke: "currentColor",
156
+ strokeWidth: "2",
157
+ strokeLinecap: "round",
158
+ strokeLinejoin: "round",
159
+ children: /* @__PURE__ */ jsx("path", {
160
+ d: "m15 18-6-6 6-6"
161
+ })
162
+ })
146
163
  }),
147
164
  /* @__PURE__ */ jsxs("div", {
148
165
  className: calendarControlsClass,
149
166
  children: [
150
- /* @__PURE__ */ jsxs("div", {
151
- className: calendarNavClass,
152
- children: [
153
- /* @__PURE__ */ jsx("button", {
154
- type: "button",
155
- "aria-label": "Previous panel",
156
- onClick: () => setPanelDate(mode === "year" ? addYears(panelDate, -1) : addMonths(panelDate, -1), mode),
157
- children: "Previous"
158
- }),
159
- /* @__PURE__ */ jsx("button", {
160
- type: "button",
161
- "aria-label": "Next panel",
162
- onClick: () => setPanelDate(mode === "year" ? addYears(panelDate, 1) : addMonths(panelDate, 1), mode),
163
- children: "Next"
164
- })
165
- ]
167
+ /* @__PURE__ */ jsx("div", {
168
+ className: calendarTitleClass,
169
+ children: title
166
170
  }),
167
171
  /* @__PURE__ */ jsxs("div", {
168
172
  className: calendarModeClass,
@@ -182,6 +186,27 @@ function Header({
182
186
  ]
183
187
  })
184
188
  ]
189
+ }),
190
+ /* @__PURE__ */ jsx("button", {
191
+ type: "button",
192
+ className: calendarNavClass,
193
+ "aria-label": "Next panel",
194
+ onClick: () => setPanelDate(mode === "year" ? addYears(panelDate, 1) : addMonths(panelDate, 1), mode),
195
+ children: /* @__PURE__ */ jsx("svg", {
196
+ "aria-hidden": "true",
197
+ focusable: "false",
198
+ width: "16",
199
+ height: "16",
200
+ viewBox: "0 0 24 24",
201
+ fill: "none",
202
+ stroke: "currentColor",
203
+ strokeWidth: "2",
204
+ strokeLinecap: "round",
205
+ strokeLinejoin: "round",
206
+ children: /* @__PURE__ */ jsx("path", {
207
+ d: "m9 18 6-6-6-6"
208
+ })
209
+ })
185
210
  })
186
211
  ]
187
212
  });
@@ -1,9 +1,17 @@
1
1
  import React from "react";
2
- import type { ChatBubbleProps, ChatComponent, ChatToolProps, ChatTypingProps } from "./Chat.types";
2
+ import type { ChatBubbleProps, ChatComponent, ChatActionsProps, ChatScrollIndicatorProps, ChatToolProps, ChatTypingProps } from "./Chat.types";
3
3
  export declare const ChatAvatar: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
4
4
  export declare const ChatHeader: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
5
5
  export declare const ChatBubble: React.ForwardRefExoticComponent<Omit<ChatBubbleProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
6
6
  export declare const ChatFooter: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
+ export declare const ChatStatus: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
8
+ export declare const ChatStatusItem: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
9
+ export declare const ChatStatusValue: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
10
+ export declare const ChatActions: React.ForwardRefExoticComponent<Omit<ChatActionsProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
11
+ export declare const ChatScroll: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
12
+ export declare const ChatScrollBody: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
13
+ export declare const ChatScrollTrack: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
14
+ export declare const ChatScrollIndicator: React.ForwardRefExoticComponent<Omit<ChatScrollIndicatorProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
7
15
  export declare const ChatReasoning: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.DetailsHTMLAttributes<HTMLDetailsElement>, HTMLDetailsElement>, "ref"> & React.RefAttributes<HTMLDetailsElement>>;
8
16
  export declare const ChatTool: React.ForwardRefExoticComponent<Omit<ChatToolProps, "ref"> & React.RefAttributes<HTMLDetailsElement>>;
9
17
  export declare const ChatToolHeader: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & React.RefAttributes<HTMLElement>>;
@@ -1,15 +1,33 @@
1
1
  import type { ComponentProps, ForwardRefExoticComponent, RefAttributes } from "react";
2
2
  export type ChatPlacement = "start" | "end";
3
+ export type ChatTimeline = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24;
3
4
  export type ChatBubbleColor = "primary" | "secondary" | "tertiary" | "accent" | "neutral" | "base" | "info" | "success" | "warning" | "error";
4
5
  export type ChatBubbleSize = "xs" | "sm" | "md" | "lg";
5
6
  export type ChatToolState = "pending" | "running" | "success" | "error";
6
7
  export interface ChatProps extends ComponentProps<"div"> {
7
8
  /** Position the turn at the start or end of the conversation row. */
8
9
  placement?: ChatPlacement;
10
+ /** Pair an assistant row with a scroll indicator (slots 1–24). */
11
+ timeline?: ChatTimeline;
12
+ "data-chat-tl"?: string | number;
9
13
  }
10
14
  export type ChatAvatarProps = ComponentProps<"div">;
11
15
  export type ChatHeaderProps = ComponentProps<"div">;
12
16
  export type ChatFooterProps = ComponentProps<"div">;
17
+ export type ChatStatusProps = ComponentProps<"div">;
18
+ export type ChatStatusItemProps = ComponentProps<"span">;
19
+ export type ChatStatusValueProps = ComponentProps<"span">;
20
+ export interface ChatActionsProps extends ComponentProps<"div"> {
21
+ /** Reveal actions on message hover or keyboard focus. */
22
+ hover?: boolean;
23
+ }
24
+ export type ChatScrollProps = ComponentProps<"div">;
25
+ export type ChatScrollBodyProps = ComponentProps<"div">;
26
+ export type ChatScrollTrackProps = ComponentProps<"div">;
27
+ export interface ChatScrollIndicatorProps extends ComponentProps<"button"> {
28
+ targetId: string;
29
+ timeline: ChatTimeline;
30
+ }
13
31
  export interface ChatBubbleProps extends ComponentProps<"div"> {
14
32
  /** Apply a semantic DuskMoon color to the bubble. */
15
33
  color?: ChatBubbleColor;
@@ -36,6 +54,14 @@ export type ChatComponent = ChatPartComponent<HTMLDivElement, ChatProps> & {
36
54
  Header: ChatPartComponent<HTMLDivElement, ChatHeaderProps>;
37
55
  Bubble: ChatPartComponent<HTMLDivElement, ChatBubbleProps>;
38
56
  Footer: ChatPartComponent<HTMLDivElement, ChatFooterProps>;
57
+ Status: ChatPartComponent<HTMLDivElement, ChatStatusProps>;
58
+ StatusItem: ChatPartComponent<HTMLSpanElement, ChatStatusItemProps>;
59
+ StatusValue: ChatPartComponent<HTMLSpanElement, ChatStatusValueProps>;
60
+ Actions: ChatPartComponent<HTMLDivElement, ChatActionsProps>;
61
+ Scroll: ChatPartComponent<HTMLDivElement, ChatScrollProps>;
62
+ ScrollBody: ChatPartComponent<HTMLDivElement, ChatScrollBodyProps>;
63
+ ScrollTrack: ChatPartComponent<HTMLDivElement, ChatScrollTrackProps>;
64
+ ScrollIndicator: ChatPartComponent<HTMLButtonElement, ChatScrollIndicatorProps>;
39
65
  Reasoning: ChatPartComponent<HTMLDetailsElement, ChatReasoningProps>;
40
66
  Tool: ChatPartComponent<HTMLDetailsElement, ChatToolProps>;
41
67
  ToolHeader: ChatPartComponent<HTMLElement, ChatToolHeaderProps>;
@@ -34,6 +34,15 @@ var chatAvatarClass = "chat-avatar";
34
34
  var chatHeaderClass = "chat-header";
35
35
  var chatBubbleBaseClass = "chat-bubble";
36
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";
37
46
  var chatReasoningClass = "chat-reasoning";
38
47
  var chatToolBaseClass = "chat-tool";
39
48
  var chatToolHeaderClass = "chat-tool-header";
@@ -41,7 +50,6 @@ var chatToolStatusClass = "chat-tool-status";
41
50
  var chatToolCallClass = "chat-tool-call";
42
51
  var chatToolResultClass = "chat-tool-result";
43
52
  var chatTypingClass = "chat-typing";
44
- var chatStreamingCaretClass = "chat-streaming-caret";
45
53
  var chatBubbleFilledClass = "chat-bubble-filled";
46
54
  var chatBubbleStreamingClass = "chat-bubble-streaming";
47
55
  var chatPlacementClasses = {
@@ -121,7 +129,7 @@ var ChatBubble = forwardRef(({ color, size = "md", filled, streaming, className,
121
129
  children: [
122
130
  children,
123
131
  streaming ? /* @__PURE__ */ jsx("span", {
124
- className: chatStreamingCaretClass,
132
+ className: "chat-bubble-content chat-bubble-streaming",
125
133
  "aria-hidden": "true"
126
134
  }) : null
127
135
  ]
@@ -133,6 +141,70 @@ var ChatFooter = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ js
133
141
  className: cn(chatFooterClass, className)
134
142
  }));
135
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";
136
208
  var ChatReasoning = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("details", {
137
209
  ...props,
138
210
  ref,
@@ -185,9 +257,10 @@ var ChatTyping = forwardRef(({
185
257
  })
186
258
  }));
187
259
  ChatTyping.displayName = "Chat.Typing";
188
- var ChatRoot = forwardRef(({ placement = "start", className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
260
+ var ChatRoot = forwardRef(({ placement = "start", timeline, className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
189
261
  ...props,
190
262
  ref,
263
+ "data-chat-tl": timeline ?? props["data-chat-tl"],
191
264
  className: getChatClasses({ placement, className })
192
265
  }));
193
266
  ChatRoot.displayName = "Chat";
@@ -196,6 +269,14 @@ var Chat = Object.assign(ChatRoot, {
196
269
  Header: ChatHeader,
197
270
  Bubble: ChatBubble,
198
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,
199
280
  Reasoning: ChatReasoning,
200
281
  Tool: ChatTool,
201
282
  ToolHeader: ChatToolHeader,
@@ -206,11 +287,19 @@ var Chat = Object.assign(ChatRoot, {
206
287
  });
207
288
  export {
208
289
  Chat,
290
+ ChatActions,
209
291
  ChatAvatar,
210
292
  ChatBubble,
211
293
  ChatFooter,
212
294
  ChatHeader,
213
295
  ChatReasoning,
296
+ ChatScroll,
297
+ ChatScrollBody,
298
+ ChatScrollIndicator,
299
+ ChatScrollTrack,
300
+ ChatStatus,
301
+ ChatStatusItem,
302
+ ChatStatusValue,
214
303
  ChatTool,
215
304
  ChatToolCall,
216
305
  ChatToolHeader,
@@ -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) {
@@ -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 {
@@ -118,17 +125,44 @@ function colorToRgb(value) {
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: () => {
@@ -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";