@liveblocks/react-ui 2.25.0-aiprivatebeta7 → 2.25.0-aiprivatebeta9
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/_private/index.cjs +14 -10
- package/dist/_private/index.cjs.map +1 -1
- package/dist/_private/index.d.cts +200 -105
- package/dist/_private/index.d.ts +200 -105
- package/dist/_private/index.js +10 -5
- package/dist/_private/index.js.map +1 -1
- package/dist/components/AiChat.cjs +85 -120
- package/dist/components/AiChat.cjs.map +1 -1
- package/dist/components/AiChat.js +87 -122
- package/dist/components/AiChat.js.map +1 -1
- package/dist/components/AiTool.cjs +164 -0
- package/dist/components/AiTool.cjs.map +1 -0
- package/dist/components/AiTool.js +162 -0
- package/dist/components/AiTool.js.map +1 -0
- package/dist/components/Comment.cjs +5 -3
- package/dist/components/Comment.cjs.map +1 -1
- package/dist/components/Comment.js +6 -4
- package/dist/components/Comment.js.map +1 -1
- package/dist/components/InboxNotificationList.cjs +11 -3
- package/dist/components/InboxNotificationList.cjs.map +1 -1
- package/dist/components/InboxNotificationList.js +12 -4
- package/dist/components/InboxNotificationList.js.map +1 -1
- package/dist/components/Thread.cjs +3 -3
- package/dist/components/Thread.cjs.map +1 -1
- package/dist/components/Thread.js +3 -3
- package/dist/components/Thread.js.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.cjs +53 -229
- package/dist/components/internal/AiChatAssistantMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatAssistantMessage.js +55 -231
- package/dist/components/internal/AiChatAssistantMessage.js.map +1 -1
- package/dist/components/internal/AiChatComposer.cjs +29 -17
- package/dist/components/internal/AiChatComposer.cjs.map +1 -1
- package/dist/components/internal/AiChatComposer.js +29 -17
- package/dist/components/internal/AiChatComposer.js.map +1 -1
- package/dist/components/internal/AiChatUserMessage.cjs +17 -10
- package/dist/components/internal/AiChatUserMessage.cjs.map +1 -1
- package/dist/components/internal/AiChatUserMessage.js +17 -10
- package/dist/components/internal/AiChatUserMessage.js.map +1 -1
- package/dist/components/internal/Button.cjs.map +1 -1
- package/dist/components/internal/Button.js.map +1 -1
- package/dist/components/internal/CodeBlock.cjs +72 -0
- package/dist/components/internal/CodeBlock.cjs.map +1 -0
- package/dist/components/internal/CodeBlock.js +70 -0
- package/dist/components/internal/CodeBlock.js.map +1 -0
- package/dist/components/internal/Emoji.cjs +12 -4
- package/dist/components/internal/Emoji.cjs.map +1 -1
- package/dist/components/internal/Emoji.js +12 -4
- package/dist/components/internal/Emoji.js.map +1 -1
- package/dist/components/internal/Prose.cjs +37 -0
- package/dist/components/internal/Prose.cjs.map +1 -0
- package/dist/components/internal/Prose.js +35 -0
- package/dist/components/internal/Prose.js.map +1 -0
- package/dist/icon.cjs +2 -0
- package/dist/icon.cjs.map +1 -1
- package/dist/icon.js +1 -0
- package/dist/icon.js.map +1 -1
- package/dist/icons/{Resolve.cjs → CheckCircle.cjs} +3 -3
- package/dist/icons/CheckCircle.cjs.map +1 -0
- package/dist/icons/{Resolve.js → CheckCircle.js} +3 -3
- package/dist/icons/CheckCircle.js.map +1 -0
- package/dist/icons/{Resolved.cjs → CheckCircleFill.cjs} +3 -3
- package/dist/icons/CheckCircleFill.cjs.map +1 -0
- package/dist/icons/{Resolved.js → CheckCircleFill.js} +3 -3
- package/dist/icons/CheckCircleFill.js.map +1 -0
- package/dist/icons/index.cjs +4 -4
- package/dist/icons/index.js +2 -2
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -14
- package/dist/index.d.ts +68 -14
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/overrides.cjs +2 -8
- package/dist/overrides.cjs.map +1 -1
- package/dist/overrides.js +2 -8
- package/dist/overrides.js.map +1 -1
- package/dist/primitives/AiChatComposer/index.cjs +1 -2
- package/dist/primitives/AiChatComposer/index.cjs.map +1 -1
- package/dist/primitives/AiChatComposer/index.js +1 -2
- package/dist/primitives/AiChatComposer/index.js.map +1 -1
- package/dist/primitives/AiMessage/contexts.cjs +18 -0
- package/dist/primitives/AiMessage/contexts.cjs.map +1 -0
- package/dist/primitives/AiMessage/contexts.js +15 -0
- package/dist/primitives/AiMessage/contexts.js.map +1 -0
- package/dist/primitives/AiMessage/index.cjs +133 -0
- package/dist/primitives/AiMessage/index.cjs.map +1 -0
- package/dist/primitives/AiMessage/index.js +131 -0
- package/dist/primitives/AiMessage/index.js.map +1 -0
- package/dist/primitives/{internal/Collapsible → Collapsible}/index.cjs +39 -17
- package/dist/primitives/Collapsible/index.cjs.map +1 -0
- package/dist/primitives/{internal/Collapsible → Collapsible}/index.js +37 -15
- package/dist/primitives/Collapsible/index.js.map +1 -0
- package/dist/primitives/{internal/Markdown.cjs → Markdown.cjs} +150 -83
- package/dist/primitives/Markdown.cjs.map +1 -0
- package/dist/primitives/{internal/Markdown.js → Markdown.js} +151 -83
- package/dist/primitives/Markdown.js.map +1 -0
- package/dist/primitives/index.cjs +4 -6
- package/dist/primitives/index.cjs.map +1 -1
- package/dist/primitives/index.d.cts +2 -79
- package/dist/primitives/index.d.ts +2 -79
- package/dist/primitives/index.js +4 -6
- package/dist/primitives/index.js.map +1 -1
- package/dist/utils/ErrorBoundary.cjs +48 -0
- package/dist/utils/ErrorBoundary.cjs.map +1 -0
- package/dist/utils/ErrorBoundary.js +45 -0
- package/dist/utils/ErrorBoundary.js.map +1 -0
- package/dist/utils/use-visible.cjs +63 -45
- package/dist/utils/use-visible.cjs.map +1 -1
- package/dist/utils/use-visible.js +64 -46
- package/dist/utils/use-visible.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -5
- package/src/styles/constants.css +1 -1
- package/src/styles/dark/index.css +7 -3
- package/src/styles/index.css +584 -238
- package/src/styles/utils.css +1 -1
- package/styles/dark/attributes.css +1 -1
- package/styles/dark/attributes.css.map +1 -1
- package/styles/dark/media-query.css +1 -1
- package/styles/dark/media-query.css.map +1 -1
- package/styles.css +1 -1
- package/styles.css.map +1 -1
- package/dist/icons/Resolve.cjs.map +0 -1
- package/dist/icons/Resolve.js.map +0 -1
- package/dist/icons/Resolved.cjs.map +0 -1
- package/dist/icons/Resolved.js.map +0 -1
- package/dist/primitives/internal/Collapsible/index.cjs.map +0 -1
- package/dist/primitives/internal/Collapsible/index.js.map +0 -1
- package/dist/primitives/internal/Emoji.cjs +0 -32
- package/dist/primitives/internal/Emoji.cjs.map +0 -1
- package/dist/primitives/internal/Emoji.js +0 -30
- package/dist/primitives/internal/Emoji.js.map +0 -1
- package/dist/primitives/internal/Markdown.cjs.map +0 -1
- package/dist/primitives/internal/Markdown.js.map +0 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { kInternal } from '@liveblocks/core';
|
|
3
|
+
import { useClient } from '@liveblocks/react';
|
|
4
|
+
import { useSignal } from '@liveblocks/react/_private';
|
|
5
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
6
|
+
import { Fragment, useCallback, forwardRef, useMemo } from 'react';
|
|
7
|
+
import { ErrorBoundary } from '../../utils/ErrorBoundary.js';
|
|
8
|
+
import { Markdown } from '../Markdown.js';
|
|
9
|
+
import { AiToolInvocationContext } from './contexts.js';
|
|
10
|
+
|
|
11
|
+
const AI_MESSAGE_CONTENT_NAME = "AiMessageContent";
|
|
12
|
+
const defaultMessageContentComponents = {
|
|
13
|
+
TextPart: ({ part }) => {
|
|
14
|
+
return /* @__PURE__ */ jsx(Markdown, {
|
|
15
|
+
content: part.text
|
|
16
|
+
});
|
|
17
|
+
},
|
|
18
|
+
ReasoningPart: ({ part }) => {
|
|
19
|
+
return /* @__PURE__ */ jsx(Markdown, {
|
|
20
|
+
content: part.text
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
ToolInvocationPart: Fragment
|
|
24
|
+
};
|
|
25
|
+
function ToolInvocation({
|
|
26
|
+
chatId,
|
|
27
|
+
messageId,
|
|
28
|
+
part
|
|
29
|
+
}) {
|
|
30
|
+
const client = useClient();
|
|
31
|
+
const ai = client[kInternal].ai;
|
|
32
|
+
const tool = useSignal(ai.signals.getToolDefinition\u03A3(chatId, part.toolName));
|
|
33
|
+
const respond = useCallback(
|
|
34
|
+
(result) => {
|
|
35
|
+
if (part.status === "receiving") {
|
|
36
|
+
console.log(
|
|
37
|
+
`Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) is still receiving`
|
|
38
|
+
);
|
|
39
|
+
} else if (part.status === "executed") {
|
|
40
|
+
console.log(
|
|
41
|
+
`Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) has already executed`
|
|
42
|
+
);
|
|
43
|
+
} else {
|
|
44
|
+
ai.setToolResult(
|
|
45
|
+
chatId,
|
|
46
|
+
messageId,
|
|
47
|
+
part.toolCallId,
|
|
48
|
+
result
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
[ai, chatId, messageId, part.status, part.toolName, part.toolCallId]
|
|
53
|
+
);
|
|
54
|
+
if (tool === void 0 || tool.render === void 0)
|
|
55
|
+
return null;
|
|
56
|
+
const { type: _, ...rest } = part;
|
|
57
|
+
const props = {
|
|
58
|
+
...rest,
|
|
59
|
+
respond,
|
|
60
|
+
$types: void 0,
|
|
61
|
+
[kInternal]: {
|
|
62
|
+
execute: tool.execute
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
66
|
+
fallback: /* @__PURE__ */ jsxs("p", {
|
|
67
|
+
style: { color: "red" },
|
|
68
|
+
children: [
|
|
69
|
+
"Failed to render tool call result for '",
|
|
70
|
+
part.toolName,
|
|
71
|
+
"'. See console for details."
|
|
72
|
+
]
|
|
73
|
+
}),
|
|
74
|
+
children: /* @__PURE__ */ jsx(AiToolInvocationContext.Provider, {
|
|
75
|
+
value: props,
|
|
76
|
+
children: /* @__PURE__ */ jsx(tool.render, {
|
|
77
|
+
...props
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const AiMessageContent = forwardRef(
|
|
83
|
+
({ message, components, asChild, ...props }, forwardedRef) => {
|
|
84
|
+
const Component = asChild ? Slot : "div";
|
|
85
|
+
const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(
|
|
86
|
+
() => ({ ...defaultMessageContentComponents, ...components }),
|
|
87
|
+
[components]
|
|
88
|
+
);
|
|
89
|
+
const content = message.content ?? message.contentSoFar;
|
|
90
|
+
const numParts = content.length;
|
|
91
|
+
const isGenerating = message.role === "assistant" && message.status === "generating";
|
|
92
|
+
return /* @__PURE__ */ jsx(Component, {
|
|
93
|
+
...props,
|
|
94
|
+
ref: forwardedRef,
|
|
95
|
+
children: content.map((part, index) => {
|
|
96
|
+
const isStreaming = isGenerating && index === numParts - 1;
|
|
97
|
+
const extra = { index, isStreaming };
|
|
98
|
+
switch (part.type) {
|
|
99
|
+
case "text":
|
|
100
|
+
return /* @__PURE__ */ jsx(TextPart, {
|
|
101
|
+
part,
|
|
102
|
+
...extra
|
|
103
|
+
}, index);
|
|
104
|
+
case "reasoning":
|
|
105
|
+
return /* @__PURE__ */ jsx(ReasoningPart, {
|
|
106
|
+
part,
|
|
107
|
+
...extra
|
|
108
|
+
}, index);
|
|
109
|
+
case "tool-invocation":
|
|
110
|
+
return /* @__PURE__ */ jsx(ToolInvocationPart, {
|
|
111
|
+
part,
|
|
112
|
+
...extra,
|
|
113
|
+
children: /* @__PURE__ */ jsx(ToolInvocation, {
|
|
114
|
+
part,
|
|
115
|
+
chatId: message.chatId,
|
|
116
|
+
messageId: message.id
|
|
117
|
+
}, index)
|
|
118
|
+
}, index);
|
|
119
|
+
default:
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
if (process.env.NODE_ENV !== "production") {
|
|
127
|
+
AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { AiMessageContent as Content };
|
|
131
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import type {\n AiToolInvocationPart,\n MessageId,\n ToolResultData,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, Fragment, useCallback, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiToolInvocationContext } from \"./contexts\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ToolInvocationPart: Fragment,\n};\n\n/* -------------------------------------------------------------------------------------------------\n * ToolInvocationPart\n * -----------------------------------------------------------------------------------------------*/\n\nfunction ToolInvocation({\n chatId,\n messageId,\n part,\n}: {\n chatId: string;\n messageId: MessageId;\n part: AiToolInvocationPart;\n}) {\n const client = useClient();\n const ai = client[kInternal].ai;\n const tool = useSignal(ai.signals.getToolDefinitionΣ(chatId, part.toolName));\n\n const respond = useCallback(\n (result: ToolResultData) => {\n if (part.status === \"receiving\") {\n console.log(\n `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) is still receiving`\n );\n } else if (part.status === \"executed\") {\n console.log(\n `Ignoring respond(): tool '${part.toolName}' (${part.toolCallId}) has already executed`\n );\n } else {\n ai.setToolResult(\n chatId,\n messageId,\n part.toolCallId,\n result\n // TODO Pass in AiGenerationOptions here?\n );\n }\n },\n [ai, chatId, messageId, part.status, part.toolName, part.toolCallId]\n );\n\n if (tool === undefined || tool.render === undefined) return null;\n\n const { type: _, ...rest } = part;\n const props = {\n ...rest,\n respond,\n $types: undefined as never,\n [kInternal]: {\n execute: tool.execute,\n },\n };\n return (\n <ErrorBoundary\n fallback={\n <p style={{ color: \"red\" }}>\n Failed to render tool call result for '{part.toolName}'. See console\n for details.\n </p>\n }\n >\n <AiToolInvocationContext.Provider value={props}>\n <tool.render {...props} />\n </AiToolInvocationContext.Provider>\n </ErrorBoundary>\n );\n}\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(\n () => ({ ...defaultMessageContentComponents, ...components }),\n [components]\n );\n\n const content = message.content ?? message.contentSoFar;\n const numParts = content.length;\n const isGenerating =\n message.role === \"assistant\" && message.status === \"generating\";\n return (\n <Component {...props} ref={forwardedRef}>\n {content.map((part, index) => {\n // A part is considered to be still \"streaming in\" if it's the last\n // part in the content array, and the message is in \"generating\"\n // state.\n const isStreaming = isGenerating && index === numParts - 1;\n const extra = { index, isStreaming };\n switch (part.type) {\n case \"text\":\n return <TextPart key={index} part={part} {...extra} />;\n case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n case \"tool-invocation\":\n // TODO: If the render() method doesn't exist, we should not render the ToolInvocationPart\n // or pass it no children so that it can decide to not render?\n return (\n <ToolInvocationPart key={index} part={part} {...extra}>\n <ToolInvocation\n key={index}\n part={part}\n chatId={message.chatId}\n messageId={message.id}\n />\n </ToolInvocationPart>\n );\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiMessage.*\nexport { AiMessageContent as Content };\n"],"names":[],"mappings":"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"}
|
|
@@ -3,29 +3,45 @@
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var reactSlot = require('@radix-ui/react-slot');
|
|
5
5
|
var react = require('react');
|
|
6
|
+
var useControllableState = require('../../utils/use-controllable-state.cjs');
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const COLLAPSIBLE_ROOT_NAME = "CollapsibleRoot";
|
|
9
|
+
const COLLAPSIBLE_TRIGGER_NAME = "CollapsibleTrigger";
|
|
10
|
+
const COLLAPSIBLE_CONTENT_NAME = "CollapsibleContent";
|
|
11
|
+
const CollapsibleContext = react.createContext(null);
|
|
12
|
+
const CollapsibleRoot = react.forwardRef(
|
|
13
|
+
({
|
|
14
|
+
open: controlledOpen,
|
|
15
|
+
onOpenChange: controlledOnOpenChange,
|
|
16
|
+
defaultOpen,
|
|
17
|
+
disabled = false,
|
|
18
|
+
asChild,
|
|
19
|
+
...props
|
|
20
|
+
}, forwardedRef) => {
|
|
21
|
+
const [isOpen, onOpenChange] = useControllableState.useControllableState(
|
|
22
|
+
controlledOpen === void 0 && defaultOpen === void 0 ? true : controlledOpen,
|
|
23
|
+
controlledOnOpenChange,
|
|
24
|
+
defaultOpen
|
|
25
|
+
);
|
|
10
26
|
const Component = asChild ? reactSlot.Slot : "div";
|
|
11
27
|
const id = react.useId();
|
|
12
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
13
|
-
value: { open, onOpenChange, disabled, contentId: id },
|
|
28
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContext.Provider, {
|
|
29
|
+
value: { open: isOpen, onOpenChange, disabled, contentId: id },
|
|
14
30
|
children: /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
15
31
|
...props,
|
|
16
32
|
ref: forwardedRef,
|
|
17
|
-
"data-state":
|
|
33
|
+
"data-state": isOpen ? "open" : "closed",
|
|
18
34
|
"data-disabled": disabled ? "" : void 0
|
|
19
35
|
})
|
|
20
36
|
});
|
|
21
37
|
}
|
|
22
38
|
);
|
|
23
|
-
const
|
|
39
|
+
const CollapsibleTrigger = react.forwardRef(
|
|
24
40
|
({ onClick, asChild, ...props }, forwardedRef) => {
|
|
25
41
|
const Component = asChild ? reactSlot.Slot : "button";
|
|
26
|
-
const context = react.useContext(
|
|
42
|
+
const context = react.useContext(CollapsibleContext);
|
|
27
43
|
if (!context) {
|
|
28
|
-
throw new Error("Collapsible.
|
|
44
|
+
throw new Error("Collapsible.Root is missing from the React tree.");
|
|
29
45
|
}
|
|
30
46
|
const { open, disabled, contentId, onOpenChange } = context;
|
|
31
47
|
return /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
@@ -48,14 +64,15 @@ const Trigger = react.forwardRef(
|
|
|
48
64
|
});
|
|
49
65
|
}
|
|
50
66
|
);
|
|
51
|
-
const
|
|
67
|
+
const CollapsibleContent = react.forwardRef(
|
|
52
68
|
({ asChild, ...props }, forwardedRef) => {
|
|
53
69
|
const Component = asChild ? reactSlot.Slot : "div";
|
|
54
|
-
const
|
|
70
|
+
const context = react.useContext(CollapsibleContext);
|
|
55
71
|
const divRef = react.useRef(null);
|
|
56
|
-
if (!
|
|
57
|
-
throw new Error("
|
|
58
|
-
|
|
72
|
+
if (!context) {
|
|
73
|
+
throw new Error("Collapsible.Root is missing from the React tree.");
|
|
74
|
+
}
|
|
75
|
+
const { open, onOpenChange, disabled, contentId } = context;
|
|
59
76
|
react.useEffect(() => {
|
|
60
77
|
const element = divRef.current;
|
|
61
78
|
if (element === null)
|
|
@@ -98,8 +115,13 @@ const Content = react.forwardRef(
|
|
|
98
115
|
});
|
|
99
116
|
}
|
|
100
117
|
);
|
|
118
|
+
if (process.env.NODE_ENV !== "production") {
|
|
119
|
+
CollapsibleContent.displayName = COLLAPSIBLE_CONTENT_NAME;
|
|
120
|
+
CollapsibleRoot.displayName = COLLAPSIBLE_ROOT_NAME;
|
|
121
|
+
CollapsibleTrigger.displayName = COLLAPSIBLE_TRIGGER_NAME;
|
|
122
|
+
}
|
|
101
123
|
|
|
102
|
-
exports.Content =
|
|
103
|
-
exports.Root =
|
|
104
|
-
exports.Trigger =
|
|
124
|
+
exports.Content = CollapsibleContent;
|
|
125
|
+
exports.Root = CollapsibleRoot;
|
|
126
|
+
exports.Trigger = CollapsibleTrigger;
|
|
105
127
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../src/primitives/Collapsible/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n} from \"react\";\n\nimport { useControllableState } from \"../../utils/use-controllable-state\";\nimport type { ContentProps, RootProps, TriggerProps } from \"./types\";\n\nconst COLLAPSIBLE_ROOT_NAME = \"CollapsibleRoot\";\nconst COLLAPSIBLE_TRIGGER_NAME = \"CollapsibleTrigger\";\nconst COLLAPSIBLE_CONTENT_NAME = \"CollapsibleContent\";\n\nconst CollapsibleContext = createContext<{\n open?: boolean;\n onOpenChange: (open: boolean) => void;\n disabled: boolean;\n contentId: string;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleRoot = forwardRef<HTMLDivElement, RootProps>(\n (\n {\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n defaultOpen,\n disabled = false,\n asChild,\n ...props\n },\n forwardedRef\n ) => {\n const [isOpen, onOpenChange] = useControllableState(\n // If the collapsible is neither controlled nor uncontrolled, it defaults to controlled as open.\n controlledOpen === undefined && defaultOpen === undefined\n ? true\n : controlledOpen,\n controlledOnOpenChange,\n defaultOpen\n );\n const Component = asChild ? Slot : \"div\";\n const id = useId();\n\n return (\n <CollapsibleContext.Provider\n value={{ open: isOpen, onOpenChange, disabled, contentId: id }}\n >\n <Component\n {...props}\n ref={forwardedRef}\n data-state={isOpen ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n />\n </CollapsibleContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleTrigger = forwardRef<HTMLButtonElement, TriggerProps>(\n ({ onClick, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(CollapsibleContext);\n\n if (!context) {\n throw new Error(\"Collapsible.Root is missing from the React tree.\");\n }\n\n const { open, disabled, contentId, onOpenChange } = context;\n\n return (\n <Component\n {...props}\n ref={forwardedRef}\n type=\"button\"\n aria-controls={contentId}\n aria-expanded={open || false}\n data-state={open ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n disabled={disabled}\n onClick={(event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n if (disabled) return;\n onOpenChange(!open);\n }}\n />\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Content\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleContent = forwardRef<HTMLDivElement, ContentProps>(\n ({ asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const context = useContext(CollapsibleContext);\n const divRef = useRef<HTMLDivElement>(null);\n\n if (!context) {\n throw new Error(\"Collapsible.Root is missing from the React tree.\");\n }\n\n const { open, onOpenChange, disabled, contentId } = context;\n\n useEffect(() => {\n const element = divRef.current;\n if (element === null) return;\n\n const isHiddenUntilFoundSupported = \"onbeforematch\" in document.body;\n if (!isHiddenUntilFoundSupported) return;\n\n function handleBeforeMatch() {\n onOpenChange(true);\n }\n\n // https://developer.chrome.com/articles/hidden-until-found/\n element.addEventListener(\"beforematch\", handleBeforeMatch);\n return () => {\n element.removeEventListener(\"beforematch\", handleBeforeMatch);\n };\n }, [onOpenChange]);\n\n // Passing `string` to `hidden` in JSX is not currently supported: https://github.com/facebook/react/issues/24740\n useEffect(() => {\n const element = divRef.current;\n if (element === null) return;\n\n if (open) return;\n\n const isHiddenUntilFoundSupported = \"onbeforematch\" in document.body;\n if (!isHiddenUntilFoundSupported) return;\n\n element.setAttribute(\"hidden\", \"until-found\");\n return () => {\n element.removeAttribute(\"hidden\");\n };\n }, [open]);\n\n useImperativeHandle<\n HTMLDivElement | null,\n HTMLDivElement | null\n >(forwardedRef, () => {\n return divRef.current;\n }, []);\n\n return (\n <Component\n {...props}\n ref={divRef}\n data-state={open ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n id={contentId}\n hidden={!open}\n />\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n CollapsibleContent.displayName = COLLAPSIBLE_CONTENT_NAME;\n CollapsibleRoot.displayName = COLLAPSIBLE_ROOT_NAME;\n CollapsibleTrigger.displayName = COLLAPSIBLE_TRIGGER_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as Collapsible.*\nexport {\n CollapsibleContent as Content,\n CollapsibleRoot as Root,\n CollapsibleTrigger as Trigger,\n};\n"],"names":["createContext","forwardRef","useControllableState","Slot","useId","jsx","useContext","useRef","useEffect","useImperativeHandle"],"mappings":"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"}
|
|
@@ -1,29 +1,45 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { Slot } from '@radix-ui/react-slot';
|
|
3
3
|
import { createContext, forwardRef, useId, useContext, useRef, useEffect, useImperativeHandle } from 'react';
|
|
4
|
+
import { useControllableState } from '../../utils/use-controllable-state.js';
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
6
|
+
const COLLAPSIBLE_ROOT_NAME = "CollapsibleRoot";
|
|
7
|
+
const COLLAPSIBLE_TRIGGER_NAME = "CollapsibleTrigger";
|
|
8
|
+
const COLLAPSIBLE_CONTENT_NAME = "CollapsibleContent";
|
|
9
|
+
const CollapsibleContext = createContext(null);
|
|
10
|
+
const CollapsibleRoot = forwardRef(
|
|
11
|
+
({
|
|
12
|
+
open: controlledOpen,
|
|
13
|
+
onOpenChange: controlledOnOpenChange,
|
|
14
|
+
defaultOpen,
|
|
15
|
+
disabled = false,
|
|
16
|
+
asChild,
|
|
17
|
+
...props
|
|
18
|
+
}, forwardedRef) => {
|
|
19
|
+
const [isOpen, onOpenChange] = useControllableState(
|
|
20
|
+
controlledOpen === void 0 && defaultOpen === void 0 ? true : controlledOpen,
|
|
21
|
+
controlledOnOpenChange,
|
|
22
|
+
defaultOpen
|
|
23
|
+
);
|
|
8
24
|
const Component = asChild ? Slot : "div";
|
|
9
25
|
const id = useId();
|
|
10
|
-
return /* @__PURE__ */ jsx(
|
|
11
|
-
value: { open, onOpenChange, disabled, contentId: id },
|
|
26
|
+
return /* @__PURE__ */ jsx(CollapsibleContext.Provider, {
|
|
27
|
+
value: { open: isOpen, onOpenChange, disabled, contentId: id },
|
|
12
28
|
children: /* @__PURE__ */ jsx(Component, {
|
|
13
29
|
...props,
|
|
14
30
|
ref: forwardedRef,
|
|
15
|
-
"data-state":
|
|
31
|
+
"data-state": isOpen ? "open" : "closed",
|
|
16
32
|
"data-disabled": disabled ? "" : void 0
|
|
17
33
|
})
|
|
18
34
|
});
|
|
19
35
|
}
|
|
20
36
|
);
|
|
21
|
-
const
|
|
37
|
+
const CollapsibleTrigger = forwardRef(
|
|
22
38
|
({ onClick, asChild, ...props }, forwardedRef) => {
|
|
23
39
|
const Component = asChild ? Slot : "button";
|
|
24
|
-
const context = useContext(
|
|
40
|
+
const context = useContext(CollapsibleContext);
|
|
25
41
|
if (!context) {
|
|
26
|
-
throw new Error("Collapsible.
|
|
42
|
+
throw new Error("Collapsible.Root is missing from the React tree.");
|
|
27
43
|
}
|
|
28
44
|
const { open, disabled, contentId, onOpenChange } = context;
|
|
29
45
|
return /* @__PURE__ */ jsx(Component, {
|
|
@@ -46,14 +62,15 @@ const Trigger = forwardRef(
|
|
|
46
62
|
});
|
|
47
63
|
}
|
|
48
64
|
);
|
|
49
|
-
const
|
|
65
|
+
const CollapsibleContent = forwardRef(
|
|
50
66
|
({ asChild, ...props }, forwardedRef) => {
|
|
51
67
|
const Component = asChild ? Slot : "div";
|
|
52
|
-
const
|
|
68
|
+
const context = useContext(CollapsibleContext);
|
|
53
69
|
const divRef = useRef(null);
|
|
54
|
-
if (!
|
|
55
|
-
throw new Error("
|
|
56
|
-
|
|
70
|
+
if (!context) {
|
|
71
|
+
throw new Error("Collapsible.Root is missing from the React tree.");
|
|
72
|
+
}
|
|
73
|
+
const { open, onOpenChange, disabled, contentId } = context;
|
|
57
74
|
useEffect(() => {
|
|
58
75
|
const element = divRef.current;
|
|
59
76
|
if (element === null)
|
|
@@ -96,6 +113,11 @@ const Content = forwardRef(
|
|
|
96
113
|
});
|
|
97
114
|
}
|
|
98
115
|
);
|
|
116
|
+
if (process.env.NODE_ENV !== "production") {
|
|
117
|
+
CollapsibleContent.displayName = COLLAPSIBLE_CONTENT_NAME;
|
|
118
|
+
CollapsibleRoot.displayName = COLLAPSIBLE_ROOT_NAME;
|
|
119
|
+
CollapsibleTrigger.displayName = COLLAPSIBLE_TRIGGER_NAME;
|
|
120
|
+
}
|
|
99
121
|
|
|
100
|
-
export { Content, Root, Trigger };
|
|
122
|
+
export { CollapsibleContent as Content, CollapsibleRoot as Root, CollapsibleTrigger as Trigger };
|
|
101
123
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/primitives/Collapsible/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n} from \"react\";\n\nimport { useControllableState } from \"../../utils/use-controllable-state\";\nimport type { ContentProps, RootProps, TriggerProps } from \"./types\";\n\nconst COLLAPSIBLE_ROOT_NAME = \"CollapsibleRoot\";\nconst COLLAPSIBLE_TRIGGER_NAME = \"CollapsibleTrigger\";\nconst COLLAPSIBLE_CONTENT_NAME = \"CollapsibleContent\";\n\nconst CollapsibleContext = createContext<{\n open?: boolean;\n onOpenChange: (open: boolean) => void;\n disabled: boolean;\n contentId: string;\n} | null>(null);\n\n/* -------------------------------------------------------------------------------------------------\n * Root\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleRoot = forwardRef<HTMLDivElement, RootProps>(\n (\n {\n open: controlledOpen,\n onOpenChange: controlledOnOpenChange,\n defaultOpen,\n disabled = false,\n asChild,\n ...props\n },\n forwardedRef\n ) => {\n const [isOpen, onOpenChange] = useControllableState(\n // If the collapsible is neither controlled nor uncontrolled, it defaults to controlled as open.\n controlledOpen === undefined && defaultOpen === undefined\n ? true\n : controlledOpen,\n controlledOnOpenChange,\n defaultOpen\n );\n const Component = asChild ? Slot : \"div\";\n const id = useId();\n\n return (\n <CollapsibleContext.Provider\n value={{ open: isOpen, onOpenChange, disabled, contentId: id }}\n >\n <Component\n {...props}\n ref={forwardedRef}\n data-state={isOpen ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n />\n </CollapsibleContext.Provider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Trigger\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleTrigger = forwardRef<HTMLButtonElement, TriggerProps>(\n ({ onClick, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"button\";\n const context = useContext(CollapsibleContext);\n\n if (!context) {\n throw new Error(\"Collapsible.Root is missing from the React tree.\");\n }\n\n const { open, disabled, contentId, onOpenChange } = context;\n\n return (\n <Component\n {...props}\n ref={forwardedRef}\n type=\"button\"\n aria-controls={contentId}\n aria-expanded={open || false}\n data-state={open ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n disabled={disabled}\n onClick={(event) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n if (disabled) return;\n onOpenChange(!open);\n }}\n />\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Content\n * -----------------------------------------------------------------------------------------------*/\n\nconst CollapsibleContent = forwardRef<HTMLDivElement, ContentProps>(\n ({ asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const context = useContext(CollapsibleContext);\n const divRef = useRef<HTMLDivElement>(null);\n\n if (!context) {\n throw new Error(\"Collapsible.Root is missing from the React tree.\");\n }\n\n const { open, onOpenChange, disabled, contentId } = context;\n\n useEffect(() => {\n const element = divRef.current;\n if (element === null) return;\n\n const isHiddenUntilFoundSupported = \"onbeforematch\" in document.body;\n if (!isHiddenUntilFoundSupported) return;\n\n function handleBeforeMatch() {\n onOpenChange(true);\n }\n\n // https://developer.chrome.com/articles/hidden-until-found/\n element.addEventListener(\"beforematch\", handleBeforeMatch);\n return () => {\n element.removeEventListener(\"beforematch\", handleBeforeMatch);\n };\n }, [onOpenChange]);\n\n // Passing `string` to `hidden` in JSX is not currently supported: https://github.com/facebook/react/issues/24740\n useEffect(() => {\n const element = divRef.current;\n if (element === null) return;\n\n if (open) return;\n\n const isHiddenUntilFoundSupported = \"onbeforematch\" in document.body;\n if (!isHiddenUntilFoundSupported) return;\n\n element.setAttribute(\"hidden\", \"until-found\");\n return () => {\n element.removeAttribute(\"hidden\");\n };\n }, [open]);\n\n useImperativeHandle<\n HTMLDivElement | null,\n HTMLDivElement | null\n >(forwardedRef, () => {\n return divRef.current;\n }, []);\n\n return (\n <Component\n {...props}\n ref={divRef}\n data-state={open ? \"open\" : \"closed\"}\n data-disabled={disabled ? \"\" : undefined}\n id={contentId}\n hidden={!open}\n />\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n CollapsibleContent.displayName = COLLAPSIBLE_CONTENT_NAME;\n CollapsibleRoot.displayName = COLLAPSIBLE_ROOT_NAME;\n CollapsibleTrigger.displayName = COLLAPSIBLE_TRIGGER_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as Collapsible.*\nexport {\n CollapsibleContent as Content,\n CollapsibleRoot as Root,\n CollapsibleTrigger as Trigger,\n};\n"],"names":[],"mappings":"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"}
|