@ctrl-ui/react 0.8.7 → 0.8.8
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.
- package/dist/action-bar.d.ts +15 -7
- package/dist/action-bar.js +40 -20
- package/dist/activity.js +8 -16
- package/dist/audio-recorder.d.ts +14 -4
- package/dist/audio-recorder.js +82 -29
- package/dist/audio-visualizer.js +1 -1
- package/dist/blocks/coding-agent.js +39 -39
- package/dist/blocks/design-canvas-inspector.js +2 -2
- package/dist/blocks/design-canvas.d.ts +5 -1
- package/dist/blocks/design-canvas.js +200 -94
- package/dist/blocks/discussion.d.ts +28 -0
- package/dist/blocks/discussion.js +67 -0
- package/dist/blocks/file-explorer-data.d.ts +1 -0
- package/dist/blocks/file-explorer-data.js +4 -1
- package/dist/blocks/file-explorer.d.ts +9 -1
- package/dist/blocks/file-explorer.js +461 -192
- package/dist/blocks/settings.d.ts +2 -1
- package/dist/blocks/settings.js +102 -80
- package/dist/blocks/team-chat.d.ts +12 -0
- package/dist/blocks/team-chat.js +26 -0
- package/dist/blocks/theme-toggle.js +23 -31
- package/dist/chat-composer-attachment.d.ts +4 -1
- package/dist/chat-composer-attachment.js +35 -10
- package/dist/chat-composer-editor/extensions/mention.d.ts +5 -1
- package/dist/chat-composer-editor/extensions/mention.js +58 -27
- package/dist/chat-composer-editor/ghost.js +2 -4
- package/dist/chat-composer-editor/types.d.ts +5 -0
- package/dist/chat-composer-editor.d.ts +1 -1
- package/dist/chat-composer-editor.js +57 -30
- package/dist/chat-composer.d.ts +13 -32
- package/dist/chat-composer.js +53 -13
- package/dist/chat-layout.d.ts +19 -0
- package/dist/chat-layout.js +91 -40
- package/dist/chat-message/social.d.ts +26 -0
- package/dist/chat-message/social.js +122 -0
- package/dist/chat-message.d.ts +28 -29
- package/dist/chat-message.js +106 -25
- package/dist/context.d.ts +2 -2
- package/dist/context.js +39 -24
- package/dist/dynamic-notification-canvas-loop.d.ts +24 -0
- package/dist/dynamic-notification-canvas-loop.js +113 -0
- package/dist/dynamic-notification-glass.js +23 -114
- package/dist/dynamic-notification-liquid.js +14 -118
- package/dist/dynamic-notification.d.ts +16 -8
- package/dist/dynamic-notification.js +86 -23
- package/dist/email/email-brand.d.ts +7 -4
- package/dist/email/email-brand.js +9 -6
- package/dist/email/email-code.d.ts +3 -2
- package/dist/email/email-code.js +11 -9
- package/dist/email/email-footer.d.ts +5 -3
- package/dist/email/email-footer.js +11 -5
- package/dist/email/email.d.ts +31 -9
- package/dist/email/email.js +50 -26
- package/dist/email/templates.d.ts +10 -9
- package/dist/email/templates.js +102 -38
- package/dist/email/theme.js +1 -1
- package/dist/environment-variables.d.ts +4 -2
- package/dist/environment-variables.js +52 -32
- package/dist/filter-bar/editor.js +20 -8
- package/dist/filter-bar/model.d.ts +1 -0
- package/dist/filter-bar/model.js +10 -1
- package/dist/filter-bar/motion.js +4 -4
- package/dist/filter-bar/parts.js +20 -9
- package/dist/filter-bar/types.d.ts +1 -0
- package/dist/filter-bar.js +20 -14
- package/dist/hooks/use-audio-recorder.js +12 -6
- package/dist/hooks/use-chat-composer.d.ts +19 -7
- package/dist/hooks/use-chat-composer.js +32 -5
- package/dist/hooks/use-chat-message.d.ts +28 -2
- package/dist/hooks/use-chat-message.js +41 -10
- package/dist/hooks/use-chat-thread-scroll.js +43 -7
- package/dist/hooks/use-color-area.d.ts +3 -3
- package/dist/hooks/use-color-area.js +13 -12
- package/dist/hooks/use-copy-to-clipboard.d.ts +2 -1
- package/dist/hooks/use-copy-to-clipboard.js +20 -20
- package/dist/hooks/use-dynamic-notification.d.ts +6 -2
- package/dist/hooks/use-dynamic-notification.js +26 -10
- package/dist/hooks/use-mobile.d.ts +3 -2
- package/dist/hooks/use-mobile.js +8 -4
- package/dist/hooks/use-textarea-trigger-menu.js +2 -1
- package/dist/hooks/use-trigger-menu.d.ts +54 -0
- package/dist/hooks/use-trigger-menu.js +102 -47
- package/dist/hooks/use-user-ask.d.ts +2 -0
- package/dist/hooks/use-user-ask.js +35 -41
- package/dist/inline-attachment.d.ts +6 -2
- package/dist/inline-attachment.js +36 -15
- package/dist/inline-citation.d.ts +12 -5
- package/dist/inline-citation.js +26 -17
- package/dist/knob-contracts/audio-recorder-knobs.d.ts +1 -1
- package/dist/knob-contracts/audio-recorder-knobs.js +2 -1
- package/dist/knob-contracts/audio-visualizer-knobs.d.ts +1 -1
- package/dist/knob-contracts/audio-visualizer-knobs.js +2 -1
- package/dist/knob-contracts/avatar-knobs.d.ts +1 -1
- package/dist/knob-contracts/avatar-knobs.js +6 -1
- package/dist/knob-contracts/badge-knobs.d.ts +1 -1
- package/dist/knob-contracts/badge-knobs.js +2 -1
- package/dist/knob-contracts/breadcrumb-knobs.d.ts +4 -0
- package/dist/knob-contracts/breadcrumb-knobs.js +8 -0
- package/dist/knob-contracts/button-knobs.d.ts +1 -1
- package/dist/knob-contracts/button-knobs.js +1 -0
- package/dist/knob-contracts/chat-message-knobs.d.ts +1 -1
- package/dist/knob-contracts/chat-message-knobs.js +8 -1
- package/dist/knob-contracts/code-diff-knobs.d.ts +1 -1
- package/dist/knob-contracts/code-diff-knobs.js +2 -0
- package/dist/knob-contracts/code-knobs.d.ts +1 -1
- package/dist/knob-contracts/code-knobs.js +2 -1
- package/dist/knob-contracts/dynamic-notification-knobs.d.ts +1 -1
- package/dist/knob-contracts/dynamic-notification-knobs.js +2 -0
- package/dist/knob-contracts/emoji-picker-knobs.d.ts +4 -0
- package/dist/knob-contracts/emoji-picker-knobs.js +10 -0
- package/dist/knob-contracts/field-knobs.d.ts +1 -1
- package/dist/knob-contracts/field-knobs.js +5 -1
- package/dist/knob-contracts/filter-bar-knobs.d.ts +1 -1
- package/dist/knob-contracts/filter-bar-knobs.js +1 -2
- package/dist/knob-contracts/markdown-knobs.d.ts +1 -1
- package/dist/knob-contracts/markdown-knobs.js +3 -1
- package/dist/knob-contracts/page-layout-knobs.d.ts +1 -1
- package/dist/knob-contracts/page-layout-knobs.js +2 -1
- package/dist/knob-contracts/popup-knobs.d.ts +1 -1
- package/dist/knob-contracts/popup-knobs.js +27 -0
- package/dist/knob-contracts/range-knobs.d.ts +1 -1
- package/dist/knob-contracts/range-knobs.js +1 -0
- package/dist/knob-contracts/rich-tooltip-knobs.d.ts +1 -1
- package/dist/knob-contracts/rich-tooltip-knobs.js +2 -1
- package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
- package/dist/knob-contracts/sidebar-knobs.js +27 -2
- package/dist/knob-contracts/spinner-knobs.d.ts +1 -1
- package/dist/knob-contracts/spinner-knobs.js +1 -1
- package/dist/knob-contracts/stepper-knobs.d.ts +1 -1
- package/dist/knob-contracts/stepper-knobs.js +4 -1
- package/dist/knob-contracts/switch-knobs.d.ts +1 -1
- package/dist/knob-contracts/switch-knobs.js +5 -0
- package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
- package/dist/knob-contracts/table-of-contents-knobs.js +2 -1
- package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
- package/dist/knob-contracts/tabs-knobs.js +1 -0
- package/dist/knob-contracts/tree-knobs.d.ts +1 -1
- package/dist/knob-contracts/tree-knobs.js +2 -1
- package/dist/lib/cn.js +0 -4
- package/dist/lib/contrast.d.ts +1 -0
- package/dist/lib/contrast.js +17 -5
- package/dist/lib/dropzone-validation.js +41 -28
- package/dist/lib/env-file.d.ts +1 -1
- package/dist/lib/env-file.js +5 -5
- package/dist/lib/motion.d.ts +4 -0
- package/dist/lib/motion.js +15 -0
- package/dist/lib/phone-input-format.js +1 -1
- package/dist/lib/trigger-detect.js +6 -8
- package/dist/markdown-block.js +2 -1
- package/dist/popup-parts.d.ts +8 -0
- package/dist/popup-parts.js +43 -0
- package/dist/source-badge.js +3 -1
- package/dist/styles/code.css +0 -2
- package/dist/styles/effects.css +6 -32
- package/dist/styles/index.css +10 -5
- package/dist/styles/recipes/accordion.css +9 -6
- package/dist/styles/recipes/action-bar.css +0 -15
- package/dist/styles/recipes/activity.css +5 -11
- package/dist/styles/recipes/alert.css +4 -4
- package/dist/styles/recipes/audio-recorder.css +15 -3
- package/dist/styles/recipes/audio-visualizer.css +13 -2
- package/dist/styles/recipes/avatar.css +78 -1
- package/dist/styles/recipes/badge.css +14 -4
- package/dist/styles/recipes/breadcrumb.css +77 -0
- package/dist/styles/recipes/button-group.css +5 -7
- package/dist/styles/recipes/button-states.css +66 -0
- package/dist/styles/recipes/button.css +24 -83
- package/dist/styles/recipes/calendar.css +17 -23
- package/dist/styles/recipes/card.css +2 -2
- package/dist/styles/recipes/chat-composer-attachment.css +9 -3
- package/dist/styles/recipes/chat-composer.css +7 -10
- package/dist/styles/recipes/chat-layout.css +35 -0
- package/dist/styles/recipes/chat-message-social.css +123 -0
- package/dist/styles/recipes/chat-message.css +157 -37
- package/dist/styles/recipes/choice.css +18 -21
- package/dist/styles/recipes/code-diff.css +46 -33
- package/dist/styles/recipes/code.css +36 -16
- package/dist/styles/recipes/collapsible.css +7 -2
- package/dist/styles/recipes/color-picker-details.css +3 -4
- package/dist/styles/recipes/color-picker-values.css +9 -8
- package/dist/styles/recipes/color-picker.css +11 -2
- package/dist/styles/recipes/context.css +3 -3
- package/dist/styles/recipes/dockable-panel.css +7 -4
- package/dist/styles/recipes/dropzone.css +7 -8
- package/dist/styles/recipes/dynamic-notification-input.css +8 -5
- package/dist/styles/recipes/dynamic-notification-motion.css +12 -21
- package/dist/styles/recipes/dynamic-notification.css +40 -26
- package/dist/styles/recipes/emoji-picker.css +132 -0
- package/dist/styles/recipes/empty.css +5 -4
- package/dist/styles/recipes/environment-variables.css +4 -15
- package/dist/styles/recipes/field-parts.css +30 -24
- package/dist/styles/recipes/field.css +61 -26
- package/dist/styles/recipes/filter-bar.css +18 -31
- package/dist/styles/recipes/gradient-editor.css +18 -7
- package/dist/styles/recipes/infinite-canvas.css +0 -1
- package/dist/styles/recipes/inline-attachment.css +3 -3
- package/dist/styles/recipes/inline-citation.css +10 -4
- package/dist/styles/recipes/item.css +23 -9
- package/dist/styles/recipes/markdown-block.css +5 -4
- package/dist/styles/recipes/markdown.css +68 -26
- package/dist/styles/recipes/morphing-panel.css +8 -8
- package/dist/styles/recipes/page-layout.css +20 -12
- package/dist/styles/recipes/pagination.css +4 -5
- package/dist/styles/recipes/phone-input.css +12 -8
- package/dist/styles/recipes/popup-controls.css +166 -33
- package/dist/styles/recipes/popup-drawer.css +3 -14
- package/dist/styles/recipes/popup-lists.css +128 -27
- package/dist/styles/recipes/popup-motion.css +4 -45
- package/dist/styles/recipes/popup-toast.css +55 -26
- package/dist/styles/recipes/popup.css +139 -141
- package/dist/styles/recipes/range.css +54 -18
- package/dist/styles/recipes/resizable.css +2 -7
- package/dist/styles/recipes/rich-tooltip.css +24 -34
- package/dist/styles/recipes/scroll-area.css +8 -1
- package/dist/styles/recipes/sidebar-menu.css +149 -34
- package/dist/styles/recipes/sidebar-parts.css +154 -0
- package/dist/styles/recipes/sidebar.css +187 -128
- package/dist/styles/recipes/source-badge.css +1 -1
- package/dist/styles/recipes/spinner.css +8 -1
- package/dist/styles/recipes/stepper.css +31 -13
- package/dist/styles/recipes/switch.css +68 -23
- package/dist/styles/recipes/table-of-contents.css +9 -1
- package/dist/styles/recipes/table.css +14 -10
- package/dist/styles/recipes/tabs.css +17 -12
- package/dist/styles/recipes/task-list.css +7 -14
- package/dist/styles/recipes/thread-rail.css +42 -19
- package/dist/styles/recipes/timeline.css +2 -0
- package/dist/styles/recipes/toolbar.css +27 -25
- package/dist/styles/recipes/track-highlight.css +10 -7
- package/dist/styles/recipes/tree.css +31 -4
- package/dist/styles/recipes/user-ask-details.css +0 -1
- package/dist/styles/recipes/user-ask.css +4 -4
- package/dist/styles/theme.css +37 -16
- package/dist/task-list.d.ts +4 -1
- package/dist/task-list.js +24 -8
- package/dist/thread-rail.d.ts +1 -1
- package/dist/thread-rail.js +61 -19
- package/dist/transcript-divider.js +2 -1
- package/dist/ui/alert-dialog.js +1 -1
- package/dist/ui/alert.d.ts +3 -1
- package/dist/ui/alert.js +14 -8
- package/dist/ui/autocomplete.js +4 -2
- package/dist/ui/avatar.d.ts +8 -0
- package/dist/ui/avatar.js +23 -3
- package/dist/ui/badge.js +1 -1
- package/dist/ui/breadcrumb.d.ts +27 -0
- package/dist/ui/breadcrumb.js +88 -0
- package/dist/ui/button.d.ts +2 -1
- package/dist/ui/button.js +3 -3
- package/dist/ui/calendar.js +2 -2
- package/dist/ui/card.d.ts +3 -1
- package/dist/ui/card.js +12 -7
- package/dist/ui/checkbox.d.ts +2 -0
- package/dist/ui/code-diff.d.ts +1 -1
- package/dist/ui/code-diff.js +72 -28
- package/dist/ui/code.d.ts +5 -3
- package/dist/ui/code.js +28 -29
- package/dist/ui/collapsible.js +1 -1
- package/dist/ui/color-picker.d.ts +5 -2
- package/dist/ui/color-picker.js +85 -37
- package/dist/ui/combobox-disabled-selection.d.ts +1 -2
- package/dist/ui/combobox-disabled-selection.js +7 -9
- package/dist/ui/combobox.js +14 -6
- package/dist/ui/command.d.ts +8 -2
- package/dist/ui/command.js +30 -14
- package/dist/ui/context-menu.js +4 -1
- package/dist/ui/dialog.d.ts +2 -1
- package/dist/ui/dialog.js +4 -23
- package/dist/ui/dockable-panel-geometry.d.ts +1 -0
- package/dist/ui/dockable-panel-geometry.js +7 -1
- package/dist/ui/dockable-panel.d.ts +9 -6
- package/dist/ui/dockable-panel.js +63 -23
- package/dist/ui/drawer.js +1 -1
- package/dist/ui/dropdown-menu.js +5 -4
- package/dist/ui/dropzone.d.ts +2 -2
- package/dist/ui/dropzone.js +75 -16
- package/dist/ui/emoji-picker.d.ts +18 -0
- package/dist/ui/emoji-picker.js +136 -0
- package/dist/ui/empty.d.ts +3 -1
- package/dist/ui/empty.js +12 -7
- package/dist/ui/gradient-editor.d.ts +1 -1
- package/dist/ui/gradient-editor.js +37 -21
- package/dist/ui/hover-card.js +1 -1
- package/dist/ui/infinite-canvas.d.ts +3 -2
- package/dist/ui/infinite-canvas.js +63 -19
- package/dist/ui/input-group.d.ts +0 -3
- package/dist/ui/input-group.js +4 -14
- package/dist/ui/input-otp.d.ts +1 -1
- package/dist/ui/input-otp.js +32 -15
- package/dist/ui/input.js +4 -4
- package/dist/ui/item.d.ts +2 -1
- package/dist/ui/item.js +12 -8
- package/dist/ui/live-status.d.ts +7 -0
- package/dist/ui/live-status.js +17 -0
- package/dist/ui/markdown-elements.d.ts +6 -0
- package/dist/ui/markdown-elements.js +31 -1
- package/dist/ui/menubar.js +3 -3
- package/dist/ui/morphing-panel.js +3 -2
- package/dist/ui/native-select.d.ts +1 -1
- package/dist/ui/native-select.js +24 -11
- package/dist/ui/navigation-menu.js +1 -1
- package/dist/ui/page-layout.d.ts +2 -2
- package/dist/ui/page-layout.js +2 -4
- package/dist/ui/pagination.d.ts +7 -5
- package/dist/ui/pagination.js +19 -13
- package/dist/ui/phone-input.d.ts +1 -0
- package/dist/ui/phone-input.js +58 -60
- package/dist/ui/popover.js +1 -1
- package/dist/ui/radio-group.d.ts +2 -0
- package/dist/ui/resizable.d.ts +3 -2
- package/dist/ui/resizable.js +5 -3
- package/dist/ui/responsive-dialog.d.ts +1 -1
- package/dist/ui/responsive-dialog.js +4 -21
- package/dist/ui/rich-tooltip.d.ts +10 -4
- package/dist/ui/rich-tooltip.js +82 -34
- package/dist/ui/scroll-area.d.ts +1 -1
- package/dist/ui/scroll-area.js +43 -28
- package/dist/ui/select.js +1 -1
- package/dist/ui/sheet.js +1 -1
- package/dist/ui/sidebar-menu.d.ts +5 -1
- package/dist/ui/sidebar-menu.js +32 -34
- package/dist/ui/sidebar-provider.d.ts +10 -1
- package/dist/ui/sidebar-provider.js +39 -14
- package/dist/ui/sidebar-resize-rail.js +8 -4
- package/dist/ui/sidebar.d.ts +11 -6
- package/dist/ui/sidebar.js +47 -24
- package/dist/ui/slider.js +31 -22
- package/dist/ui/spinner.d.ts +3 -2
- package/dist/ui/spinner.js +3 -2
- package/dist/ui/stepper.d.ts +8 -1
- package/dist/ui/stepper.js +74 -25
- package/dist/ui/switch.d.ts +1 -0
- package/dist/ui/table-of-contents.d.ts +2 -2
- package/dist/ui/table-of-contents.js +20 -8
- package/dist/ui/table.js +4 -2
- package/dist/ui/textarea.d.ts +1 -1
- package/dist/ui/textarea.js +20 -9
- package/dist/ui/timeline.d.ts +3 -1
- package/dist/ui/timeline.js +17 -9
- package/dist/ui/toast.d.ts +11 -5
- package/dist/ui/toast.js +101 -55
- package/dist/ui/toolbar.d.ts +3 -2
- package/dist/ui/toolbar.js +4 -2
- package/dist/ui/tooltip.js +4 -21
- package/dist/ui/tree.js +121 -81
- package/dist/ui/trigger-menu.js +2 -1
- package/dist/user-ask.d.ts +10 -5
- package/dist/user-ask.js +32 -12
- package/package.json +5 -1
- package/dist/hooks/use-keyboard-navigation.d.ts +0 -3
- package/dist/hooks/use-keyboard-navigation.js +0 -22
package/dist/action-bar.d.ts
CHANGED
|
@@ -24,20 +24,28 @@ export type ActionBarProps = Omit<ComponentProps<"div">, "style"> & {
|
|
|
24
24
|
style?: CSSProperties & ActionBarKnobStyle;
|
|
25
25
|
};
|
|
26
26
|
export declare function ActionBar({ label, align, className, children, context, copyValue, editValue, onCopy, onCopyError, onEdit, onEditError, ...props }: ActionBarProps): import("react").JSX.Element;
|
|
27
|
-
|
|
27
|
+
type ActionBarItemBaseProps = Omit<ComponentProps<typeof Button>, "iconOnly" | "children"> & {
|
|
28
28
|
icon?: ReactNode;
|
|
29
29
|
};
|
|
30
|
-
export
|
|
31
|
-
|
|
30
|
+
export type ActionBarItemProps = ActionBarItemBaseProps & ({
|
|
31
|
+
children: NonNullable<ReactNode>;
|
|
32
|
+
} | {
|
|
33
|
+
children?: null;
|
|
34
|
+
"aria-label": string;
|
|
35
|
+
});
|
|
36
|
+
export declare function ActionBarItem({ icon, children, active, disabled, ...props }: ActionBarItemProps): import("react").JSX.Element;
|
|
37
|
+
export type ActionBarCopyProps = ActionBarItemBaseProps & {
|
|
32
38
|
value?: ActionBarCopyValue;
|
|
33
|
-
children?: ReactNode
|
|
39
|
+
children?: NonNullable<ReactNode>;
|
|
34
40
|
copiedChildren?: ReactNode;
|
|
41
|
+
copiedAriaLabel?: string;
|
|
42
|
+
copyFailedLabel?: string;
|
|
35
43
|
resetDelay?: number;
|
|
36
44
|
};
|
|
37
|
-
export declare function ActionBarCopy({ value, children, copiedChildren, resetDelay, disabled, onClick, ...props }: ActionBarCopyProps): import("react").JSX.Element;
|
|
38
|
-
export type ActionBarEditProps =
|
|
45
|
+
export declare function ActionBarCopy({ value, children, copiedChildren, copiedAriaLabel, copyFailedLabel, resetDelay, disabled, onClick, ...props }: ActionBarCopyProps): import("react").JSX.Element;
|
|
46
|
+
export type ActionBarEditProps = ActionBarItemBaseProps & {
|
|
39
47
|
value?: ActionBarCopyValue;
|
|
40
|
-
children?: ReactNode
|
|
48
|
+
children?: NonNullable<ReactNode>;
|
|
41
49
|
};
|
|
42
50
|
export declare function ActionBarEdit({ value, children, disabled, onClick, ...props }: ActionBarEditProps): import("react").JSX.Element;
|
|
43
51
|
//#endregion
|
package/dist/action-bar.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { useCopyToClipboard } from "./hooks/use-copy-to-clipboard.js";
|
|
2
3
|
import { cn } from "./lib/cn.js";
|
|
3
4
|
import { Button } from "./ui/button.js";
|
|
4
|
-
import {
|
|
5
|
+
import { LiveStatus } from "./ui/live-status.js";
|
|
6
|
+
import { Toolbar } from "@base-ui/react/toolbar";
|
|
5
7
|
import { createContext, useContext } from "react";
|
|
6
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
9
|
//#region src/action-bar.tsx
|
|
8
10
|
const ActionBarContext = createContext({});
|
|
9
11
|
async function resolveCopyValue(value) {
|
|
@@ -21,30 +23,35 @@ function ActionBar({ label = "Message actions", align = "start", className, chil
|
|
|
21
23
|
};
|
|
22
24
|
return /* @__PURE__ */ jsx(ActionBarContext.Provider, {
|
|
23
25
|
value: actionContext,
|
|
24
|
-
children: /* @__PURE__ */ jsx(
|
|
26
|
+
children: /* @__PURE__ */ jsx(Toolbar.Root, {
|
|
27
|
+
...props,
|
|
25
28
|
"data-control-ui": "action-bar",
|
|
26
29
|
"data-control-family": "action-bar",
|
|
27
30
|
"data-slot": "root",
|
|
28
|
-
role: "toolbar",
|
|
29
31
|
"aria-label": label,
|
|
30
32
|
className: cn("flex items-center", align === "end" ? "justify-end" : "justify-start", className),
|
|
31
|
-
...props,
|
|
32
33
|
children
|
|
33
34
|
})
|
|
34
35
|
});
|
|
35
36
|
}
|
|
36
|
-
function ActionBarItem({ icon, children,
|
|
37
|
-
return /* @__PURE__ */
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
function ActionBarItem({ icon, children, active, disabled, ...props }) {
|
|
38
|
+
return /* @__PURE__ */ jsx(Toolbar.Button, {
|
|
39
|
+
disabled,
|
|
40
|
+
focusableWhenDisabled: false,
|
|
41
|
+
render: /* @__PURE__ */ jsxs(Button, {
|
|
42
|
+
size: "xs",
|
|
43
|
+
active,
|
|
44
|
+
"aria-pressed": active,
|
|
45
|
+
iconOnly: children == null,
|
|
46
|
+
...props,
|
|
47
|
+
children: [icon, children]
|
|
48
|
+
})
|
|
42
49
|
});
|
|
43
50
|
}
|
|
44
|
-
function ActionBarCopy({ value, children = "Copy", copiedChildren = "Copied", resetDelay = 1200, disabled, onClick, ...props }) {
|
|
51
|
+
function ActionBarCopy({ value, children = "Copy", copiedChildren = "Copied", copiedAriaLabel = "Copied to clipboard", copyFailedLabel = "Couldn't copy. Select the text and copy it manually.", resetDelay = 1200, disabled, onClick, ...props }) {
|
|
45
52
|
const { copyValue: contextCopyValue, onCopy, onCopyError } = useContext(ActionBarContext);
|
|
46
53
|
const copyValue = value ?? contextCopyValue;
|
|
47
|
-
const {
|
|
54
|
+
const { status, copyToClipboard } = useCopyToClipboard({
|
|
48
55
|
copiedDuration: resetDelay,
|
|
49
56
|
onCopy,
|
|
50
57
|
onCopyError
|
|
@@ -52,17 +59,30 @@ function ActionBarCopy({ value, children = "Copy", copiedChildren = "Copied", re
|
|
|
52
59
|
async function handleClick(event) {
|
|
53
60
|
onClick?.(event);
|
|
54
61
|
if (event.defaultPrevented) return;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
try {
|
|
63
|
+
const nextValue = await resolveCopyValue(copyValue);
|
|
64
|
+
if (!nextValue) return;
|
|
65
|
+
await copyToClipboard(nextValue);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
onCopyError?.(error);
|
|
68
|
+
}
|
|
58
69
|
}
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
let copyStatus = "";
|
|
71
|
+
if (status === "copied") copyStatus = copiedAriaLabel;
|
|
72
|
+
else if (status === "failed") copyStatus = copyFailedLabel;
|
|
73
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ActionBarItem, {
|
|
61
74
|
disabled: disabled ?? !copyValue,
|
|
62
75
|
onClick: handleClick,
|
|
63
76
|
...props,
|
|
64
|
-
children:
|
|
65
|
-
|
|
77
|
+
children: status === "copied" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
|
|
78
|
+
"aria-hidden": "true",
|
|
79
|
+
className: "contents",
|
|
80
|
+
children: copiedChildren
|
|
81
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
82
|
+
className: "sr-only",
|
|
83
|
+
children
|
|
84
|
+
})] }) : children
|
|
85
|
+
}), /* @__PURE__ */ jsx(LiveStatus, { message: copyStatus })] });
|
|
66
86
|
}
|
|
67
87
|
function ActionBarEdit({ value, children = "Edit", disabled, onClick, ...props }) {
|
|
68
88
|
const { copyValue, editValue: contextEditValue, onEdit, onEditError } = useContext(ActionBarContext);
|
package/dist/activity.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "./lib/cn.js";
|
|
3
|
-
import {
|
|
3
|
+
import { LiveStatus } from "./ui/live-status.js";
|
|
4
4
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./ui/collapsible.js";
|
|
5
|
+
import { ScrollArea } from "./ui/scroll-area.js";
|
|
5
6
|
import { createContext, useContext } from "react";
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
import { Check, ChevronRight, CircleAlert, CircleDashed, LoaderCircle } from "lucide-react";
|
|
@@ -30,13 +31,13 @@ function formatActivityTitle(value) {
|
|
|
30
31
|
}
|
|
31
32
|
function Activity({ kind = "default", name, state = "pending", statusLabel, className, children, ...props }) {
|
|
32
33
|
const context = {
|
|
33
|
-
isError: state === "error",
|
|
34
34
|
isRunning: state === "running",
|
|
35
35
|
kind,
|
|
36
36
|
name,
|
|
37
37
|
state,
|
|
38
38
|
statusLabel: statusLabel ?? activityStatusLabels[state]
|
|
39
39
|
};
|
|
40
|
+
const statusText = typeof context.statusLabel === "string" ? context.statusLabel : activityStatusLabels[state];
|
|
40
41
|
return /* @__PURE__ */ jsx(ActivityContext.Provider, {
|
|
41
42
|
value: context,
|
|
42
43
|
children: /* @__PURE__ */ jsxs(Collapsible, {
|
|
@@ -46,20 +47,9 @@ function Activity({ kind = "default", name, state = "pending", statusLabel, clas
|
|
|
46
47
|
"data-activity-state": state,
|
|
47
48
|
"data-activity-kind": kind,
|
|
48
49
|
"data-activity-name": name,
|
|
49
|
-
"aria-busy": context.isRunning || void 0,
|
|
50
50
|
className: cn("group/activity min-w-0", className),
|
|
51
51
|
...props,
|
|
52
|
-
children: [/* @__PURE__ */ jsx(
|
|
53
|
-
role: context.isError ? "alert" : "status",
|
|
54
|
-
"aria-live": context.isError ? "assertive" : "polite",
|
|
55
|
-
"aria-atomic": "true",
|
|
56
|
-
"data-control-ui": "activity",
|
|
57
|
-
"data-control-family": "activity",
|
|
58
|
-
"data-slot": "announcement",
|
|
59
|
-
"data-status": state,
|
|
60
|
-
className: "sr-only",
|
|
61
|
-
children: context.statusLabel
|
|
62
|
-
}), children]
|
|
52
|
+
children: [/* @__PURE__ */ jsx(LiveStatus, { message: name ? `${formatActivityTitle(name)}: ${statusText}` : statusText }), children]
|
|
63
53
|
})
|
|
64
54
|
});
|
|
65
55
|
}
|
|
@@ -101,18 +91,20 @@ function ActivityIcon({ className, children, ...props }) {
|
|
|
101
91
|
"data-slot": "icon",
|
|
102
92
|
...props,
|
|
103
93
|
className: cn("flex shrink-0 items-center justify-center [&_svg]:size-4", className),
|
|
104
|
-
children: children ?? /* @__PURE__ */ jsx(Icon, {})
|
|
94
|
+
children: children ?? /* @__PURE__ */ jsx(Icon, { "data-motion-essential": activity.isRunning ? "" : void 0 })
|
|
105
95
|
});
|
|
106
96
|
}
|
|
107
97
|
function ActivityTitle({ className, children, ...props }) {
|
|
108
98
|
const activity = useActivityContext();
|
|
99
|
+
const text = children ?? (activity.name ? formatActivityTitle(activity.name) : void 0);
|
|
109
100
|
return /* @__PURE__ */ jsx("span", {
|
|
110
101
|
"data-control-ui": "activity",
|
|
111
102
|
"data-control-family": "activity",
|
|
112
103
|
"data-slot": "title",
|
|
104
|
+
title: typeof text === "string" ? text : void 0,
|
|
113
105
|
...props,
|
|
114
106
|
className: cn("min-w-0 flex-1 truncate", className),
|
|
115
|
-
children:
|
|
107
|
+
children: text
|
|
116
108
|
});
|
|
117
109
|
}
|
|
118
110
|
function ActivityStatus({ className, children, ...props }) {
|
package/dist/audio-recorder.d.ts
CHANGED
|
@@ -11,11 +11,16 @@ type AudioRecorderStyleProps<Props, Style> = Omit<Props, "style"> & {
|
|
|
11
11
|
export declare function useAudioRecorderContext(): UseAudioRecorderResult;
|
|
12
12
|
export type AudioRecorderProps = Omit<ComponentProps<"div">, "style"> & UseAudioRecorderOptions & {
|
|
13
13
|
label?: string;
|
|
14
|
+
recordingLabel?: string;
|
|
15
|
+
timeLimitLabel?: string;
|
|
16
|
+
sendingLabel?: string;
|
|
17
|
+
sentLabel?: string;
|
|
18
|
+
canceledLabel?: string;
|
|
14
19
|
style?: CSSProperties & AudioRecorderKnobStyle;
|
|
15
20
|
};
|
|
16
|
-
export declare function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled, barCount, barDurationMs, deviceId, label, className, children, ...props }: AudioRecorderProps): import("react").JSX.Element;
|
|
21
|
+
export declare function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled, barCount, barDurationMs, deviceId, label, recordingLabel, timeLimitLabel, sendingLabel, sentLabel, canceledLabel, className, children, ...props }: AudioRecorderProps): import("react").JSX.Element;
|
|
17
22
|
export type AudioRecorderTriggerProps = AudioRecorderStyleProps<ComponentProps<typeof Button>, ButtonKnobStyle & AudioRecorderKnobStyle>;
|
|
18
|
-
export declare function AudioRecorderTrigger({ className, children, disabled, onClick, ...props }: AudioRecorderTriggerProps): import("react").JSX.Element;
|
|
23
|
+
export declare function AudioRecorderTrigger({ className, children, disabled, onClick, ref, ...props }: AudioRecorderTriggerProps): import("react").JSX.Element;
|
|
19
24
|
export type AudioRecorderVisualizerProps = AudioRecorderStyleProps<Omit<ComponentProps<"div">, "children">, AudioVisualizerKnobStyle & AudioRecorderKnobStyle> & {
|
|
20
25
|
points?: number;
|
|
21
26
|
};
|
|
@@ -23,10 +28,15 @@ export declare function AudioRecorderVisualizer({ points, className, ...props }:
|
|
|
23
28
|
export type AudioRecorderStatusProps = AudioRecorderStyleProps<ComponentProps<"span">, AudioRecorderKnobStyle>;
|
|
24
29
|
export declare function AudioRecorderStatus({ className, children, ...props }: AudioRecorderStatusProps): import("react").JSX.Element;
|
|
25
30
|
export type AudioRecorderDurationProps = AudioRecorderStyleProps<ComponentProps<"span">, AudioRecorderKnobStyle>;
|
|
26
|
-
export declare function AudioRecorderDuration({ className, children, ...props }: AudioRecorderDurationProps
|
|
31
|
+
export declare function AudioRecorderDuration({ className, children, durationLabel, ...props }: AudioRecorderDurationProps & {
|
|
32
|
+
durationLabel?: string;
|
|
33
|
+
}): import("react").JSX.Element;
|
|
27
34
|
export type AudioRecorderCancelProps = AudioRecorderStyleProps<ComponentProps<typeof Button>, ButtonKnobStyle & AudioRecorderKnobStyle>;
|
|
28
35
|
export declare function AudioRecorderCancel({ className, children, disabled, onClick, tabIndex, ...props }: AudioRecorderCancelProps): import("react").JSX.Element;
|
|
29
36
|
export type AudioRecorderSubmitProps = AudioRecorderStyleProps<ComponentProps<typeof Button>, ButtonKnobStyle & AudioRecorderKnobStyle>;
|
|
30
|
-
export declare function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex, ...props }: AudioRecorderSubmitProps
|
|
37
|
+
export declare function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex, label, retryLabel, ...props }: AudioRecorderSubmitProps & {
|
|
38
|
+
label?: string;
|
|
39
|
+
retryLabel?: string;
|
|
40
|
+
}): import("react").JSX.Element;
|
|
31
41
|
//#endregion
|
|
32
42
|
export type { AudioRecording };
|
package/dist/audio-recorder.js
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "./lib/cn.js";
|
|
3
3
|
import { Button } from "./ui/button.js";
|
|
4
|
+
import { LiveStatus } from "./ui/live-status.js";
|
|
4
5
|
import { AudioVisualizer } from "./audio-visualizer.js";
|
|
5
6
|
import { useAudioRecorder } from "./hooks/use-audio-recorder.js";
|
|
6
7
|
import { formatAudioRecorderDuration } from "./lib/format-audio-recorder-duration.js";
|
|
7
|
-
import { createContext, use } from "react";
|
|
8
|
+
import { createContext, use, useRef, useState } from "react";
|
|
8
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
9
10
|
import { CheckIcon, MicIcon, XIcon } from "lucide-react";
|
|
10
11
|
//#region src/audio-recorder.tsx
|
|
11
12
|
const AudioRecorderContext = createContext(null);
|
|
13
|
+
const AudioRecorderTriggerRefContext = createContext(null);
|
|
14
|
+
function focusAudioRecorderTrigger(triggerRef) {
|
|
15
|
+
triggerRef?.current?.focus();
|
|
16
|
+
}
|
|
12
17
|
function useAudioRecorderContext() {
|
|
13
18
|
const context = use(AudioRecorderContext);
|
|
14
19
|
if (!context) throw new Error("AudioRecorder compound components must be rendered inside <AudioRecorder>.");
|
|
15
20
|
return context;
|
|
16
21
|
}
|
|
17
|
-
function
|
|
22
|
+
function audioRecorderAnnouncement(previous, next, maxDurationMs, labels) {
|
|
23
|
+
if (next.error && next.error !== previous.error) return next.error.message;
|
|
24
|
+
if (next.state === previous.state) return null;
|
|
25
|
+
if (next.state === "recording") return labels.recordingLabel;
|
|
26
|
+
if (next.state === "submitting") return labels.sendingLabel;
|
|
27
|
+
if (next.state === "recorded" && previous.state === "recording" && maxDurationMs && next.durationMs >= maxDurationMs) return labels.timeLimitLabel;
|
|
28
|
+
if (next.state === "idle" && previous.state === "submitting") return labels.sentLabel;
|
|
29
|
+
if (next.state === "idle" && (previous.state === "recording" || previous.state === "recorded")) return labels.canceledLabel;
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled, barCount, barDurationMs, deviceId, label = "Voice recorder", recordingLabel = "Recording", timeLimitLabel = "Stopped at time limit", sendingLabel = "Sending voice recording", sentLabel = "Voice recording sent", canceledLabel = "Voice recording canceled", className, children, ...props }) {
|
|
18
33
|
const recorder = useAudioRecorder({
|
|
19
34
|
onRecordingComplete,
|
|
20
35
|
onCancel,
|
|
@@ -24,21 +39,42 @@ function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled,
|
|
|
24
39
|
barDurationMs,
|
|
25
40
|
deviceId
|
|
26
41
|
});
|
|
42
|
+
const triggerRef = useRef(null);
|
|
43
|
+
const [previous, setPrevious] = useState(recorder);
|
|
44
|
+
const [announcement, setAnnouncement] = useState("");
|
|
45
|
+
if (previous.state !== recorder.state || previous.error !== recorder.error) {
|
|
46
|
+
const next = audioRecorderAnnouncement(previous, recorder, maxDurationMs, {
|
|
47
|
+
recordingLabel,
|
|
48
|
+
timeLimitLabel,
|
|
49
|
+
sendingLabel,
|
|
50
|
+
sentLabel,
|
|
51
|
+
canceledLabel
|
|
52
|
+
});
|
|
53
|
+
setPrevious({
|
|
54
|
+
state: recorder.state,
|
|
55
|
+
error: recorder.error,
|
|
56
|
+
durationMs: recorder.durationMs
|
|
57
|
+
});
|
|
58
|
+
if (next !== null) setAnnouncement(next);
|
|
59
|
+
}
|
|
27
60
|
return /* @__PURE__ */ jsx(AudioRecorderContext.Provider, {
|
|
28
61
|
value: recorder,
|
|
29
|
-
children: /* @__PURE__ */ jsx(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
children: /* @__PURE__ */ jsx(AudioRecorderTriggerRefContext.Provider, {
|
|
63
|
+
value: triggerRef,
|
|
64
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
65
|
+
"data-control-ui": "audio-recorder",
|
|
66
|
+
"data-control-family": "audio-recorder",
|
|
67
|
+
"data-slot": "root",
|
|
68
|
+
"data-state": recorder.state,
|
|
69
|
+
"data-disabled": recorder.isDisabled ? "true" : void 0,
|
|
70
|
+
"data-error": recorder.error ? "true" : void 0,
|
|
71
|
+
role: "group",
|
|
72
|
+
"aria-label": label,
|
|
73
|
+
"aria-disabled": recorder.isDisabled || void 0,
|
|
74
|
+
className: cn("flex w-full min-w-0 max-w-full items-center", className),
|
|
75
|
+
...props,
|
|
76
|
+
children: [children ?? /* @__PURE__ */ jsx(AudioRecorderDefaultLayout, { points: barCount }), /* @__PURE__ */ jsx(LiveStatus, { message: announcement })]
|
|
77
|
+
})
|
|
42
78
|
})
|
|
43
79
|
});
|
|
44
80
|
}
|
|
@@ -65,8 +101,14 @@ function AudioRecorderDefaultLayout({ points }) {
|
|
|
65
101
|
})
|
|
66
102
|
] });
|
|
67
103
|
}
|
|
68
|
-
function AudioRecorderTrigger({ className, children, disabled, onClick, ...props }) {
|
|
104
|
+
function AudioRecorderTrigger({ className, children, disabled, onClick, ref, ...props }) {
|
|
69
105
|
const recorder = useAudioRecorderContext();
|
|
106
|
+
const triggerRef = use(AudioRecorderTriggerRefContext);
|
|
107
|
+
function setRef(node) {
|
|
108
|
+
if (triggerRef) triggerRef.current = node;
|
|
109
|
+
if (typeof ref === "function") ref(node);
|
|
110
|
+
else if (ref) ref.current = node;
|
|
111
|
+
}
|
|
70
112
|
const isActive = recorder.state === "requesting" || recorder.state === "recording" || recorder.state === "recorded" || recorder.state === "submitting";
|
|
71
113
|
const isStatusOnly = !recorder.canStart && (recorder.state === "requesting" || recorder.state === "recording" || recorder.state === "recorded" || recorder.state === "submitting");
|
|
72
114
|
const triggerVariant = audioRecorderTriggerVariant(recorder, isActive);
|
|
@@ -91,6 +133,8 @@ function AudioRecorderTrigger({ className, children, disabled, onClick, ...props
|
|
|
91
133
|
"aria-label": ariaLabel,
|
|
92
134
|
title: recorder.error?.message,
|
|
93
135
|
disabled: disabled ?? (recorder.isDisabled || !recorder.canStart),
|
|
136
|
+
focusableWhenDisabled: true,
|
|
137
|
+
ref: setRef,
|
|
94
138
|
className: cn("data-[status-only=true]:cursor-default", className),
|
|
95
139
|
onClick: handleClick,
|
|
96
140
|
...props,
|
|
@@ -129,7 +173,6 @@ function AudioRecorderVisualizer({ points, className, ...props }) {
|
|
|
129
173
|
active: recorder.state === "recording",
|
|
130
174
|
levels: recorder.levels,
|
|
131
175
|
points,
|
|
132
|
-
"aria-hidden": !isVisible,
|
|
133
176
|
className,
|
|
134
177
|
...props
|
|
135
178
|
});
|
|
@@ -138,14 +181,15 @@ function AudioRecorderStatus({ className, children, ...props }) {
|
|
|
138
181
|
const recorder = useAudioRecorderContext();
|
|
139
182
|
const message = children ?? audioRecorderStatusMessage(recorder);
|
|
140
183
|
const isVisible = Boolean(message);
|
|
184
|
+
const title = typeof message === "string" ? message : void 0;
|
|
141
185
|
return /* @__PURE__ */ jsx("span", {
|
|
142
186
|
"data-control-ui": "audio-recorder",
|
|
143
187
|
"data-control-family": "audio-recorder",
|
|
144
188
|
"data-slot": "status",
|
|
145
189
|
"data-visible": isVisible ? "true" : void 0,
|
|
146
|
-
"data-tone": recorder.
|
|
147
|
-
"aria-hidden":
|
|
148
|
-
|
|
190
|
+
"data-tone": recorder.error ? "error" : "neutral",
|
|
191
|
+
"aria-hidden": "true",
|
|
192
|
+
title,
|
|
149
193
|
className: cn("min-w-0 flex-1 truncate", className),
|
|
150
194
|
...props,
|
|
151
195
|
children: message
|
|
@@ -154,29 +198,35 @@ function AudioRecorderStatus({ className, children, ...props }) {
|
|
|
154
198
|
function audioRecorderStatusMessage(recorder) {
|
|
155
199
|
if (recorder.state === "requesting") return "Allow microphone access";
|
|
156
200
|
if (recorder.state === "submitting") return "Sending voice recording";
|
|
157
|
-
if (recorder.
|
|
201
|
+
if (recorder.error) return recorder.error.message;
|
|
158
202
|
return null;
|
|
159
203
|
}
|
|
160
|
-
function AudioRecorderDuration({ className, children, ...props }) {
|
|
204
|
+
function AudioRecorderDuration({ className, children, durationLabel = "Recording length", ...props }) {
|
|
161
205
|
const recorder = useAudioRecorderContext();
|
|
162
206
|
const isVisible = recorder.state === "recording" || recorder.state === "recorded";
|
|
163
|
-
return /* @__PURE__ */
|
|
207
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
164
208
|
"data-control-ui": "audio-recorder",
|
|
165
209
|
"data-control-family": "audio-recorder",
|
|
166
210
|
"data-slot": "duration",
|
|
167
211
|
"data-visible": isVisible ? "true" : void 0,
|
|
168
212
|
"aria-hidden": !isVisible,
|
|
169
|
-
className: cn("shrink-0", className),
|
|
213
|
+
className: cn("shrink-0 tabular-nums", className),
|
|
170
214
|
...props,
|
|
171
|
-
children:
|
|
215
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
216
|
+
className: "sr-only",
|
|
217
|
+
children: [durationLabel, " "]
|
|
218
|
+
}), children ?? formatAudioRecorderDuration(recorder.durationMs)]
|
|
172
219
|
});
|
|
173
220
|
}
|
|
174
221
|
function AudioRecorderCancel({ className, children, disabled, onClick, tabIndex, ...props }) {
|
|
175
222
|
const recorder = useAudioRecorderContext();
|
|
223
|
+
const triggerRef = use(AudioRecorderTriggerRefContext);
|
|
176
224
|
const isVisible = recorder.canCancel;
|
|
177
225
|
function handleClick(event) {
|
|
178
226
|
onClick?.(event);
|
|
179
|
-
if (
|
|
227
|
+
if (event.defaultPrevented || !recorder.canCancel) return;
|
|
228
|
+
focusAudioRecorderTrigger(triggerRef);
|
|
229
|
+
recorder.cancel();
|
|
180
230
|
}
|
|
181
231
|
return /* @__PURE__ */ jsx(Button, {
|
|
182
232
|
"data-control-ui": "audio-recorder",
|
|
@@ -201,12 +251,15 @@ function AudioRecorderCancel({ className, children, disabled, onClick, tabIndex,
|
|
|
201
251
|
})
|
|
202
252
|
});
|
|
203
253
|
}
|
|
204
|
-
function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex, ...props }) {
|
|
254
|
+
function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex, label = "Send voice recording", retryLabel = "Retry sending voice recording", ...props }) {
|
|
205
255
|
const recorder = useAudioRecorderContext();
|
|
256
|
+
const triggerRef = use(AudioRecorderTriggerRefContext);
|
|
206
257
|
const isVisible = recorder.canSubmit;
|
|
207
258
|
async function handleClick(event) {
|
|
208
259
|
onClick?.(event);
|
|
209
|
-
if (
|
|
260
|
+
if (event.defaultPrevented || !recorder.canSubmit) return;
|
|
261
|
+
focusAudioRecorderTrigger(triggerRef);
|
|
262
|
+
await recorder.submit();
|
|
210
263
|
}
|
|
211
264
|
return /* @__PURE__ */ jsx(Button, {
|
|
212
265
|
"data-control-ui": "audio-recorder",
|
|
@@ -218,7 +271,7 @@ function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex,
|
|
|
218
271
|
size: "sm",
|
|
219
272
|
iconOnly: true,
|
|
220
273
|
shape: "circle",
|
|
221
|
-
"aria-label":
|
|
274
|
+
"aria-label": recorder.error ? retryLabel : label,
|
|
222
275
|
"aria-hidden": !isVisible,
|
|
223
276
|
tabIndex: isVisible ? tabIndex : -1,
|
|
224
277
|
disabled: disabled ?? (recorder.state === "submitting" || !isVisible),
|
package/dist/audio-visualizer.js
CHANGED
|
@@ -29,7 +29,7 @@ function AudioVisualizer({ levels, points, active = true, className, style, ...p
|
|
|
29
29
|
"data-control-family": "audio-visualizer",
|
|
30
30
|
"data-slot": "track",
|
|
31
31
|
"data-active": active ? "true" : void 0,
|
|
32
|
-
className: "flex size-full items-stretch justify-end mask-l-from-90%",
|
|
32
|
+
className: "flex size-full items-stretch justify-end mask-l-from-90% rtl:mask-l-from-100% rtl:mask-r-from-90%",
|
|
33
33
|
children: visible.map(({ key, level }) => {
|
|
34
34
|
const perceptualLevel = Math.sqrt(level);
|
|
35
35
|
const visibleLevel = MIN_VISIBLE_LEVEL + perceptualLevel * .88;
|
|
@@ -10,13 +10,14 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
import { BotIcon, ChevronRightIcon, CircleIcon, FolderIcon, PlusIcon, SearchIcon } from "lucide-react";
|
|
11
11
|
//#region src/blocks/coding-agent.tsx
|
|
12
12
|
function CodingAgentBlock({ appName = "Agent", brand, sidebarTop, navigation = [], projects, activeTaskId, activeTaskTitle = "New task", onNavigationSelect, onTaskSelect, onNewTask, onSearch, headerActions, sidebarFooter, children, layout = "viewport", className, style, ...props }) {
|
|
13
|
-
const
|
|
13
|
+
const Heading = layout === "contained" ? "h2" : "h1";
|
|
14
14
|
const providerStyle = {
|
|
15
15
|
"--sidebar-width": "17.5rem",
|
|
16
16
|
...style
|
|
17
17
|
};
|
|
18
18
|
return /* @__PURE__ */ jsxs(SidebarProvider, {
|
|
19
|
-
|
|
19
|
+
layout,
|
|
20
|
+
className: cn("bg-background text-foreground", layout === "viewport" && "h-svh overflow-hidden", className),
|
|
20
21
|
style: providerStyle,
|
|
21
22
|
...props,
|
|
22
23
|
children: [/* @__PURE__ */ jsx(CodingAgentSidebar, {
|
|
@@ -26,7 +27,6 @@ function CodingAgentBlock({ appName = "Agent", brand, sidebarTop, navigation = [
|
|
|
26
27
|
navigation,
|
|
27
28
|
projects,
|
|
28
29
|
activeTaskId,
|
|
29
|
-
contained,
|
|
30
30
|
sidebarFooter,
|
|
31
31
|
onNavigationSelect,
|
|
32
32
|
onTaskSelect,
|
|
@@ -39,14 +39,15 @@ function CodingAgentBlock({ appName = "Agent", brand, sidebarTop, navigation = [
|
|
|
39
39
|
children: [
|
|
40
40
|
/* @__PURE__ */ jsx(SidebarTrigger, {
|
|
41
41
|
size: "xs",
|
|
42
|
-
className: "
|
|
42
|
+
className: "lg:hidden"
|
|
43
43
|
}),
|
|
44
44
|
/* @__PURE__ */ jsx(FolderIcon, {
|
|
45
45
|
className: "size-4 shrink-0 text-muted-foreground",
|
|
46
46
|
"aria-hidden": "true"
|
|
47
47
|
}),
|
|
48
|
-
/* @__PURE__ */ jsx(
|
|
48
|
+
/* @__PURE__ */ jsx(Heading, {
|
|
49
49
|
className: "min-w-0 flex-1 truncate text-label font-medium",
|
|
50
|
+
title: activeTaskTitle,
|
|
50
51
|
children: activeTaskTitle
|
|
51
52
|
}),
|
|
52
53
|
headerActions ? /* @__PURE__ */ jsx("div", {
|
|
@@ -61,7 +62,7 @@ function CodingAgentBlock({ appName = "Agent", brand, sidebarTop, navigation = [
|
|
|
61
62
|
})]
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
|
-
function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects, activeTaskId,
|
|
65
|
+
function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects, activeTaskId, sidebarFooter, onNavigationSelect, onTaskSelect, onNewTask, onSearch }) {
|
|
65
66
|
const { setOpenMobile } = useSidebar();
|
|
66
67
|
function finishMobileNavigation() {
|
|
67
68
|
setOpenMobile(false);
|
|
@@ -72,7 +73,6 @@ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects,
|
|
|
72
73
|
}
|
|
73
74
|
return /* @__PURE__ */ jsxs(Sidebar, {
|
|
74
75
|
collapsible: "offcanvas",
|
|
75
|
-
className: contained ? "absolute! inset-y-0! h-full border-r border-sidebar-border" : void 0,
|
|
76
76
|
children: [
|
|
77
77
|
/* @__PURE__ */ jsxs(SidebarHeader, {
|
|
78
78
|
className: "gap-1.5 border-b border-sidebar-border px-2 pb-2 pt-3",
|
|
@@ -90,16 +90,20 @@ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects,
|
|
|
90
90
|
})
|
|
91
91
|
}), /* @__PURE__ */ jsx("span", {
|
|
92
92
|
className: "truncate text-label font-semibold",
|
|
93
|
+
title: appName,
|
|
93
94
|
children: appName
|
|
94
95
|
})]
|
|
95
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
96
|
+
}), onSearch ? /* @__PURE__ */ jsx(Button, {
|
|
96
97
|
variant: "ghost",
|
|
97
98
|
size: "sm",
|
|
98
99
|
iconOnly: true,
|
|
99
100
|
"aria-label": "Search tasks",
|
|
100
101
|
onClick: onSearch,
|
|
101
|
-
children: /* @__PURE__ */ jsx(SearchIcon, {
|
|
102
|
-
|
|
102
|
+
children: /* @__PURE__ */ jsx(SearchIcon, {
|
|
103
|
+
className: "size-3.5",
|
|
104
|
+
"aria-hidden": "true"
|
|
105
|
+
})
|
|
106
|
+
}) : null]
|
|
103
107
|
}),
|
|
104
108
|
/* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
|
|
105
109
|
size: "sm",
|
|
@@ -120,7 +124,7 @@ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects,
|
|
|
120
124
|
item.icon,
|
|
121
125
|
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
122
126
|
item.trailing ? /* @__PURE__ */ jsx("span", {
|
|
123
|
-
className: "
|
|
127
|
+
className: "ms-auto shrink-0",
|
|
124
128
|
children: item.trailing
|
|
125
129
|
}) : null
|
|
126
130
|
]
|
|
@@ -149,30 +153,26 @@ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects,
|
|
|
149
153
|
children: project.name
|
|
150
154
|
})
|
|
151
155
|
] }), /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx(SidebarMenu, {
|
|
152
|
-
className: "mt-1
|
|
153
|
-
children: project.tasks.map((task) => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}) : null
|
|
173
|
-
]
|
|
174
|
-
}) }, task.id);
|
|
175
|
-
})
|
|
156
|
+
className: "mt-1 ps-5",
|
|
157
|
+
children: project.tasks.map((task) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
|
|
158
|
+
size: "sm",
|
|
159
|
+
isActive: task.id === activeTaskId,
|
|
160
|
+
onClick: () => {
|
|
161
|
+
onTaskSelect?.(task, project);
|
|
162
|
+
finishMobileNavigation();
|
|
163
|
+
},
|
|
164
|
+
children: [
|
|
165
|
+
/* @__PURE__ */ jsx(CircleIcon, {
|
|
166
|
+
className: "size-1.5 fill-current opacity-35",
|
|
167
|
+
"aria-hidden": "true"
|
|
168
|
+
}),
|
|
169
|
+
/* @__PURE__ */ jsx("span", { children: task.title }),
|
|
170
|
+
task.trailing ? /* @__PURE__ */ jsx("span", {
|
|
171
|
+
className: "ms-auto shrink-0",
|
|
172
|
+
children: task.trailing
|
|
173
|
+
}) : null
|
|
174
|
+
]
|
|
175
|
+
}) }, task.id))
|
|
176
176
|
}) })]
|
|
177
177
|
}, project.id))
|
|
178
178
|
})]
|
|
@@ -215,11 +215,11 @@ function CodingAgentEmptyState({ title = "What should we build?", description, i
|
|
|
215
215
|
})
|
|
216
216
|
}),
|
|
217
217
|
/* @__PURE__ */ jsx("h2", {
|
|
218
|
-
className: "text-balance text-
|
|
218
|
+
className: "text-balance text-heading-3 sm:text-heading-2",
|
|
219
219
|
children: title
|
|
220
220
|
}),
|
|
221
221
|
description ? /* @__PURE__ */ jsx("p", {
|
|
222
|
-
className: "mt-2 max-w-xl text-
|
|
222
|
+
className: "mt-2 max-w-xl text-pretty text-body text-muted-foreground",
|
|
223
223
|
children: description
|
|
224
224
|
}) : null,
|
|
225
225
|
suggestions.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
@@ -227,7 +227,7 @@ function CodingAgentEmptyState({ title = "What should we build?", description, i
|
|
|
227
227
|
children: suggestions.map((suggestion) => /* @__PURE__ */ jsx(Button, {
|
|
228
228
|
variant: "surface",
|
|
229
229
|
size: "lg",
|
|
230
|
-
className: "h-auto min-h-28 w-full items-start justify-start whitespace-normal rounded-[var(--radius-panel)] px-4 py-4 text-
|
|
230
|
+
className: "h-auto min-h-28 w-full items-start justify-start whitespace-normal rounded-[var(--radius-panel)] px-4 py-4 text-start",
|
|
231
231
|
onClick: () => onSuggestionSelect?.(suggestion.prompt ?? suggestion.title, suggestion),
|
|
232
232
|
children: /* @__PURE__ */ jsxs("span", {
|
|
233
233
|
className: "flex min-w-0 flex-col items-start gap-3",
|
|
@@ -237,7 +237,7 @@ function CodingAgentEmptyState({ title = "What should we build?", description, i
|
|
|
237
237
|
children: suggestion.icon
|
|
238
238
|
}),
|
|
239
239
|
/* @__PURE__ */ jsx("span", {
|
|
240
|
-
className: "text-
|
|
240
|
+
className: "text-body font-medium text-foreground",
|
|
241
241
|
children: suggestion.title
|
|
242
242
|
}),
|
|
243
243
|
suggestion.description ? /* @__PURE__ */ jsx("span", {
|