@camunda/copilot-chat 0.0.0-alpha2

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/LICENSE ADDED
@@ -0,0 +1,65 @@
1
+ Camunda License 1.0
2
+
3
+ The Camunda License (the “License”) sets forth the terms and conditions
4
+ under which Camunda Services GmbH ("the Licensor") grants You a license
5
+ solely to the source code in this repository ("the Software").
6
+
7
+ Acceptance
8
+ By Using the Software, You agree to all the terms and conditions below.
9
+ If Your Use of the Software does not comply with the terms and conditions
10
+ described in this License, You must purchase a commercial license from the
11
+ Licensor, its affiliated entities, or authorized resellers, or You must
12
+ refrain from Using the Software. If You receive the Software in original or
13
+ modified form from a third party, the terms and conditions outlined in this
14
+ License apply to Your Use of that Software. You should have received a copy
15
+ of this License in this case.
16
+
17
+ Copyright License
18
+ Subject to the terms and conditions of this License, the Licensor hereby grants
19
+ You the non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable
20
+ right to Use the Software in any way or manner that would otherwise infringe the
21
+ Licensor’s copyright as long and insofar as You Use the Software only and limited
22
+ to the Use in or for the purpose of Using the Software in Non-Production Environment.
23
+ Each time you distribute or make otherwise publicly available the Software or
24
+ Derivative Works thereof, the recipient automatically receives a license from
25
+ the original Licensor to the respective Software or Derivative Works thereof
26
+ under the terms of this License.
27
+
28
+ Conditions and Restrictions
29
+ All Use of the Software is explicitly made subject to the following conditions:
30
+ * You may not move, change, disable, or circumvent the license key functionality
31
+ in the Software, and You may not remove or obscure any functionality in the
32
+ Software that is protected by the license key.
33
+ * If You distribute or make available the Software or any modification or Derivative
34
+ Works thereof (including compiled versions), You must conspicuously display and
35
+ attach this License on each original or modified copy of the Software and enable
36
+ the recipient to obtain the source code if You have distributed a compiled version
37
+
38
+
39
+ Patent License
40
+ Patent and trademark rights are not licensed under this Public License.
41
+
42
+
43
+ No Liability
44
+ EXCEPT FOR DAMAGES CAUSED BY INTENT OR FRAUDULENTLY CONCEALED DEFECTS, AND EXCEPT FOR
45
+ DAMAGES RESULTING FROM BREACH OF ANY WARRANTY OR GUARANTEE EXPRESSLY GIVEN BY LICENSOR
46
+ IN THIS LICENCE, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY
47
+ DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK. ANY MANDATORY STATUTORY
48
+ LIABILITY UNDER APPLICABLE LAW REMAINS UNAFFECTED.
49
+
50
+ No Warranty
51
+ EXCEPT AS EXPRESSLY STATED IN THIS LICENSE OR REQUIRED BY APPLICABLE LAW, THE WORKS ARE
52
+ PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND INCLUDING WITHOUT LIMITATION,
53
+ ANY WARRANTIES REGARDING THE CONTENTS, ACCURACY, OR FITNESS FOR A PARTICULAR PURPOSE.
54
+
55
+
56
+ Definitions
57
+ You refer to the individual or entity agreeing to these terms.
58
+ Use means any action concerning the Software that, without permission, would make Youliable
59
+ for infringement under applicable copyright law. Use within the meaning of this License
60
+ includes, but is not limited to, copying, distribution (with or without modification),
61
+ making available to the public, and modifying the Software.
62
+
63
+ Non-Production Environment means a setting in which the Software is used for development, staging,
64
+ testing, quality assurance, demonstration, or evaluation purposes, and not for any live or
65
+ production systems.
package/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # Camunda Copilot Client
2
+
3
+ React component library for embedding Camunda Copilot chat interface into web applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @camunda/copilot-chat
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { CopilotChat } from '@camunda/copilot-chat';
15
+
16
+ function App() {
17
+ const handleSendMessage = async (request, options, instance) => {
18
+ // Handle message sending logic
19
+ const response = {
20
+ output: {
21
+ generic: [
22
+ {
23
+ response_type: 'text',
24
+ text: `You said: "${request.input.text}"`,
25
+ },
26
+ ],
27
+ },
28
+ };
29
+
30
+ await instance.messaging.addMessage(response);
31
+ };
32
+
33
+ return <CopilotChat customSendMessage={handleSendMessage} workareaSelector="body" />;
34
+ }
35
+ ```
36
+
37
+ ### Props
38
+
39
+ - **`customSendMessage`** (required): Function to handle message sending and responses
40
+ - **`workareaSelector`** (optional): CSS selector for the workarea container (default: `"body"`)
41
+
42
+ ### Features
43
+
44
+ - Bottom-right floating launcher button
45
+ - Sidecar panel that slides in from the right
46
+ - Automatically injected styles (no separate CSS import needed)
47
+
48
+ ## Development
49
+
50
+ ### Prerequisites
51
+
52
+ - Node.js ≥18.0.0
53
+ - npm ≥9.0.0
54
+
55
+ ### Setup
56
+
57
+ ```bash
58
+ npm install
59
+ ```
60
+
61
+ ### Local Development
62
+
63
+ ```bash
64
+ # Run both library build (watch mode) and demo app together
65
+ npm run dev
66
+
67
+ # Or run individually:
68
+ # Build library in watch mode
69
+ npm run build:watch
70
+
71
+ # Run demo app (in another terminal)
72
+ npm run demo
73
+
74
+ # Run tests
75
+ npm test
76
+
77
+ # Lint
78
+ npm run lint
79
+ ```
80
+
81
+ The demo app runs at `http://localhost:4200`. The `dev` command automatically rebuilds the library when you make changes and hot-reloads the demo app.
82
+
83
+ ## Contributing
84
+
85
+ ```bash
86
+ # 1. Create a feature branch
87
+ git checkout -b '#ticketNumber/my-feature-description'
88
+
89
+ # 2. Make changes and test with dev mode
90
+ npm run dev
91
+
92
+ # 3. Run tests
93
+ npm test
94
+
95
+ # 4. Build to verify
96
+ npm run build
97
+
98
+ # 5. Commit and push
99
+ git commit -m "feat: my feature"
100
+ git push
101
+ ```
102
+
103
+ ## License
104
+
105
+ Camunda License 1.0 - See [LICENSE](LICENSE) file for details.
@@ -0,0 +1,8 @@
1
+ import { ChatCustomElementProps } from '@carbon/ai-chat';
2
+ export interface CopilotChatProps {
3
+ customSendMessage: NonNullable<ChatCustomElementProps['messaging']>['customSendMessage'];
4
+ workareaSelector?: string;
5
+ }
6
+ export declare const CopilotChat: ({ customSendMessage, workareaSelector, }: CopilotChatProps) => import("react/jsx-runtime").JSX.Element;
7
+ export default CopilotChat;
8
+ //# sourceMappingURL=CopilotChat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopilotChat.d.ts","sourceRoot":"","sources":["../src/CopilotChat.tsx"],"names":[],"mappings":"AAQA,OAAO,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAE,sBAAsB,EAAgB,MAAM,iBAAiB,CAAC;AAK5E,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,EAAE,WAAW,CAC5B,sBAAsB,CAAC,WAAW,CAAC,CACpC,CAAC,mBAAmB,CAAC,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAWD,eAAO,MAAM,WAAW,GAAI,0CAGzB,gBAAgB,4CAiDlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { ChatInstance } from '@carbon/ai-chat';
2
+ interface CopilotLauncherProps {
3
+ instance: ChatInstance | null;
4
+ isOpen: boolean;
5
+ }
6
+ export declare const CopilotLauncher: ({ instance, isOpen }: CopilotLauncherProps) => import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=CopilotLauncher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopilotLauncher.d.ts","sourceRoot":"","sources":["../../src/components/CopilotLauncher.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,eAAO,MAAM,eAAe,GAAI,sBAAsB,oBAAoB,4CA2BzE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { SidecarLayoutConfig } from '../layout/SidecarLayoutManager';
2
+ export interface UseCopilotSidecarOptions extends SidecarLayoutConfig {
3
+ enabled: boolean;
4
+ }
5
+ export declare const useCopilotSidecar: ({ enabled, width, zIndex, workareaSelector, responsiveBreakpoint, }: UseCopilotSidecarOptions) => void;
6
+ //# sourceMappingURL=useCopilotSidecar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCopilotSidecar.d.ts","sourceRoot":"","sources":["../../src/hooks/useCopilotSidecar.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,wBAAyB,SAAQ,mBAAmB;IACnE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,iBAAiB,GAAI,qEAM/B,wBAAwB,SAe1B,CAAC"}
package/dist/index.css ADDED
@@ -0,0 +1,135 @@
1
+ :root {
2
+ --copilot-chat-sidecar-width: 416px;
3
+ --copilot-chat-panel-z-index: 9999;
4
+ --copilot-chat-transition: 160ms cubic-bezier(0.2, 0, 0, 1);
5
+ }
6
+
7
+ body[data-copilot-chat-layout='sidecar'],
8
+ [data-copilot-chat-host] {
9
+ margin-inline-end: var(--copilot-chat-sidecar-width);
10
+ transition: margin-inline-end var(--copilot-chat-transition);
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body[data-copilot-chat-layout='bottom-sheet'] {
15
+ margin-inline-end: 0;
16
+ }
17
+
18
+ .copilot-chat-panel {
19
+ position: fixed;
20
+ inset-block: 0;
21
+ inset-inline-end: 0;
22
+ inline-size: var(--copilot-chat-sidecar-width);
23
+ max-inline-size: clamp(320px, var(--copilot-chat-sidecar-width), 512px);
24
+ block-size: 100vh;
25
+ z-index: var(--copilot-chat-panel-z-index);
26
+ opacity: 0;
27
+ pointer-events: none;
28
+ transform: translateX(100%);
29
+ transition: opacity 160ms cubic-bezier(0.2, 0, 0, 1),
30
+ transform 160ms cubic-bezier(0.2, 0, 0, 1);
31
+ --copilot-brand-color: #8a3ffc;
32
+ --copilot-brand-color-hover: #7a34e4;
33
+ --copilot-brand-color-active: #5c24aa;
34
+ --copilot-brand-color-ghost: rgba(138, 63, 252, 0.12);
35
+ --copilot-brand-color-ghost-strong: rgba(138, 63, 252, 0.2);
36
+ --copilot-brand-color-muted: #6c2ed8;
37
+ --cds-interactive: var(--copilot-brand-color);
38
+ --cds-button-primary: var(--copilot-brand-color);
39
+ --cds-button-primary-hover: var(--copilot-brand-color-hover);
40
+ --cds-button-primary-active: var(--copilot-brand-color-active);
41
+ --cds-button-tertiary: var(--copilot-brand-color);
42
+ --cds-button-tertiary-hover: var(--copilot-brand-color-hover);
43
+ --cds-button-tertiary-active: var(--copilot-brand-color-active);
44
+ --cds-link-primary: var(--copilot-brand-color);
45
+ --cds-link-primary-hover: var(--copilot-brand-color-hover);
46
+ --cds-link-secondary: var(--copilot-brand-color);
47
+ --cds-link-visited: var(--copilot-brand-color-muted);
48
+ --cds-chat-avatar-user: var(--copilot-brand-color);
49
+ --cds-chat-button: var(--copilot-brand-color);
50
+ --cds-chat-button-hover: var(--copilot-brand-color-ghost);
51
+ --cds-chat-button-selected: var(--copilot-brand-color-ghost-strong);
52
+ --cds-chat-button-text-hover: var(--copilot-brand-color-hover);
53
+ --cds-chat-button-text-selected: var(--copilot-brand-color);
54
+ --cds-aichat-launcher-color-background: var(--copilot-brand-color);
55
+ --cds-aichat-launcher-color-background-hover: var(
56
+ --copilot-brand-color-hover
57
+ );
58
+ --cds-aichat-launcher-color-background-active: var(
59
+ --copilot-brand-color-active
60
+ );
61
+ --cds-aichat-launcher-color-avatar: #fff;
62
+ --cds-aichat-launcher-expanded-message-color-background: var(
63
+ --copilot-brand-color
64
+ );
65
+ --cds-aichat-launcher-expanded-message-color-background-hover: var(
66
+ --copilot-brand-color-hover
67
+ );
68
+ --cds-aichat-launcher-expanded-message-color-background-active: var(
69
+ --copilot-brand-color-active
70
+ );
71
+ }
72
+
73
+ .copilot-chat-panel--open {
74
+ opacity: 1;
75
+ pointer-events: auto;
76
+ transform: translateX(0);
77
+ background-color: var(--cds-layer, #fff);
78
+ border-inline-start: 1px solid var(--cds-border-subtle, rgba(0, 0, 0, 0.12));
79
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.08);
80
+ }
81
+
82
+ body[data-copilot-chat-layout='bottom-sheet'] .copilot-chat-panel {
83
+ inset-inline: 0;
84
+ inset-block-start: auto;
85
+ inset-block-end: 0;
86
+ block-size: min(70vh, 520px);
87
+ inline-size: 100%;
88
+ border-inline-start: none;
89
+ border-block-start: 1px solid var(--cds-border-subtle, rgba(0, 0, 0, 0.12));
90
+ }
91
+ ._launcher_qra98_1 {
92
+ position: fixed;
93
+ bottom: 24px;
94
+ right: 24px;
95
+ z-index: 10000;
96
+ width: 56px;
97
+ height: 56px;
98
+ border-radius: 50%;
99
+ background-color: #8a3ffc;
100
+ border: none;
101
+ padding: 0;
102
+ display: flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ cursor: pointer;
106
+ transition: background-color 0.2s ease-in-out, opacity 0.2s ease-in-out;
107
+ }
108
+
109
+ ._launcher_qra98_1:hover {
110
+ background-color: #7a34e4;
111
+ }
112
+
113
+ ._launcher_qra98_1:active {
114
+ background-color: #5c24aa;
115
+ }
116
+
117
+ ._launcher_qra98_1:disabled {
118
+ opacity: 0.5;
119
+ cursor: not-allowed;
120
+ }
121
+
122
+ ._launcher--hidden_qra98_32 {
123
+ opacity: 0;
124
+ pointer-events: none;
125
+ }
126
+
127
+ ._icon_qra98_37 {
128
+ inline-size: 28px;
129
+ block-size: 28px;
130
+ }
131
+
132
+ body[data-copilot-chat-layout='bottom-sheet'] ._launcher_qra98_1 {
133
+ inset-inline-end: 16px;
134
+ inset-block-end: 16px;
135
+ }
@@ -0,0 +1,3 @@
1
+ export { default as CopilotChat } from './CopilotChat';
2
+ export type { CopilotChatProps } from './CopilotChat';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,0BAA0B,CAAC;AAElC,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,301 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useLayoutEffect, useCallback, useState, useEffect } from "react";
3
+ import { ViewType, ChatCustomElement, CornersType } from "@carbon/ai-chat";
4
+ const BODY_ATTRIBUTE = "data-copilot-chat-layout";
5
+ const HOST_ATTRIBUTE = "data-copilot-chat-host";
6
+ const WIDTH_VAR = "--copilot-chat-sidecar-width";
7
+ const Z_INDEX_VAR = "--copilot-chat-panel-z-index";
8
+ const layoutState = {
9
+ activeCount: 0,
10
+ rootSnapshot: null,
11
+ hostRegistry: /* @__PURE__ */ new Map(),
12
+ mediaWatcher: null,
13
+ mode: "sidecar",
14
+ activeWidth: 416
15
+ };
16
+ const isDomAvailable = () => typeof document !== "undefined" && typeof window !== "undefined";
17
+ const resolveHosts = (workareaSelector) => {
18
+ if (!isDomAvailable()) {
19
+ return [];
20
+ }
21
+ if (workareaSelector) {
22
+ const elements = document.querySelectorAll(workareaSelector);
23
+ const htmlElements = Array.from(elements).filter(
24
+ (element) => element instanceof HTMLElement
25
+ );
26
+ if (htmlElements.length > 0) {
27
+ return htmlElements;
28
+ }
29
+ return [document.body];
30
+ }
31
+ return [document.body];
32
+ };
33
+ const applyRootVariables = (width, zIndex) => {
34
+ if (!isDomAvailable()) {
35
+ return;
36
+ }
37
+ const root = document.documentElement;
38
+ if (!layoutState.rootSnapshot) {
39
+ layoutState.rootSnapshot = {
40
+ width: root.style.getPropertyValue(WIDTH_VAR),
41
+ zIndex: root.style.getPropertyValue(Z_INDEX_VAR)
42
+ };
43
+ }
44
+ layoutState.activeWidth = width;
45
+ root.style.setProperty(WIDTH_VAR, `${width}px`);
46
+ root.style.setProperty(Z_INDEX_VAR, `${zIndex}`);
47
+ syncHostAppearance(layoutState.mode);
48
+ };
49
+ const restoreRootVariables = () => {
50
+ if (!isDomAvailable() || !layoutState.rootSnapshot) {
51
+ return;
52
+ }
53
+ const root = document.documentElement;
54
+ const { width, zIndex } = layoutState.rootSnapshot;
55
+ if (width) {
56
+ root.style.setProperty(WIDTH_VAR, width);
57
+ } else {
58
+ root.style.removeProperty(WIDTH_VAR);
59
+ }
60
+ if (zIndex) {
61
+ root.style.setProperty(Z_INDEX_VAR, zIndex);
62
+ } else {
63
+ root.style.removeProperty(Z_INDEX_VAR);
64
+ }
65
+ layoutState.rootSnapshot = null;
66
+ layoutState.activeWidth = 416;
67
+ };
68
+ const updateHostAppearance = (host, mode) => {
69
+ host.setAttribute(HOST_ATTRIBUTE, mode);
70
+ };
71
+ const syncHostAppearance = (mode) => {
72
+ layoutState.hostRegistry.forEach(
73
+ (_entry, host) => updateHostAppearance(host, mode)
74
+ );
75
+ };
76
+ const attachHost = (host) => {
77
+ const entry = layoutState.hostRegistry.get(host) ?? {
78
+ count: 0
79
+ };
80
+ layoutState.hostRegistry.set(host, {
81
+ count: entry.count + 1
82
+ });
83
+ updateHostAppearance(host, layoutState.mode);
84
+ return () => {
85
+ const currentEntry = layoutState.hostRegistry.get(host);
86
+ if (!currentEntry) {
87
+ return;
88
+ }
89
+ const nextCount = currentEntry.count - 1;
90
+ if (nextCount <= 0) {
91
+ host.removeAttribute(HOST_ATTRIBUTE);
92
+ layoutState.hostRegistry.delete(host);
93
+ return;
94
+ }
95
+ layoutState.hostRegistry.set(host, {
96
+ count: nextCount
97
+ });
98
+ };
99
+ };
100
+ const setBodyMode = (mode) => {
101
+ if (!isDomAvailable()) {
102
+ return;
103
+ }
104
+ layoutState.mode = mode;
105
+ document.body.setAttribute(BODY_ATTRIBUTE, mode);
106
+ syncHostAppearance(mode);
107
+ };
108
+ const clearBodyMode = () => {
109
+ if (!isDomAvailable()) {
110
+ return;
111
+ }
112
+ document.body.removeAttribute(BODY_ATTRIBUTE);
113
+ layoutState.mode = "sidecar";
114
+ };
115
+ const watchBreakpoint = (breakpoint) => {
116
+ if (!isDomAvailable() || typeof window.matchMedia !== "function") {
117
+ setBodyMode("sidecar");
118
+ return () => void 0;
119
+ }
120
+ const query = window.matchMedia(`(max-width: ${breakpoint}px)`);
121
+ const applyMode = (matches) => {
122
+ setBodyMode(matches ? "bottom-sheet" : "sidecar");
123
+ };
124
+ applyMode(query.matches);
125
+ const listener = (event) => applyMode(event.matches);
126
+ query.addEventListener("change", listener);
127
+ return () => query.removeEventListener("change", listener);
128
+ };
129
+ const ensureMediaWatcher = (breakpoint) => {
130
+ if (!isDomAvailable()) {
131
+ return;
132
+ }
133
+ if (layoutState.mediaWatcher && layoutState.mediaWatcher.breakpoint === breakpoint) {
134
+ return;
135
+ }
136
+ layoutState.mediaWatcher?.dispose();
137
+ const dispose = watchBreakpoint(breakpoint);
138
+ layoutState.mediaWatcher = { breakpoint, dispose };
139
+ };
140
+ const teardownMediaWatcher = () => {
141
+ layoutState.mediaWatcher?.dispose();
142
+ layoutState.mediaWatcher = null;
143
+ clearBodyMode();
144
+ };
145
+ const attachSidecarLayout = ({
146
+ width,
147
+ zIndex,
148
+ workareaSelector,
149
+ responsiveBreakpoint
150
+ }) => {
151
+ if (!isDomAvailable()) {
152
+ return () => void 0;
153
+ }
154
+ const hosts = resolveHosts(workareaSelector);
155
+ applyRootVariables(width, zIndex);
156
+ ensureMediaWatcher(responsiveBreakpoint);
157
+ const detachHosts = hosts.map((host) => attachHost(host));
158
+ layoutState.activeCount += 1;
159
+ return () => {
160
+ detachHosts.forEach((detach) => detach());
161
+ layoutState.activeCount = Math.max(layoutState.activeCount - 1, 0);
162
+ if (layoutState.activeCount === 0) {
163
+ teardownMediaWatcher();
164
+ restoreRootVariables();
165
+ }
166
+ };
167
+ };
168
+ const useCopilotSidecar = ({
169
+ enabled,
170
+ width,
171
+ zIndex,
172
+ workareaSelector,
173
+ responsiveBreakpoint
174
+ }) => {
175
+ useLayoutEffect(() => {
176
+ if (!enabled) {
177
+ return;
178
+ }
179
+ const detach = attachSidecarLayout({
180
+ width,
181
+ zIndex,
182
+ workareaSelector,
183
+ responsiveBreakpoint
184
+ });
185
+ return () => detach();
186
+ }, [enabled, width, zIndex, workareaSelector, responsiveBreakpoint]);
187
+ };
188
+ const CopilotLauncherIcon = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='48'%20height='48'%20viewBox='0%200%2048%2048'%20fill='none'%3e%3ccircle%20cx='24'%20cy='24'%20r='24'%20fill='%238A3FFC'%20/%3e%3cg%20transform='translate(7%209)%20scale(2)'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M9.7219%205.2691C8.6668%204.2126%207.7435%202.4757%207.0638%201.00772C7.0445%201.00316%207.0206%201%206.9941%201C6.9675%201%206.9436%201.00316%206.9243%201.00773C6.2447%202.4757%205.322%204.2122%204.2662%205.2687C3.2106%206.325%201.47501%207.2485%200.00802994%207.9287C0.00328994%207.9483%200%207.9728%200%208C0%208.0271%200.00324982%208.0515%200.00793982%208.071C1.47467%208.751%203.2101%209.6743%204.2659%2010.7311C5.322%2011.7875%206.2448%2013.5244%206.9245%2014.9923C6.9437%2014.9969%206.9675%2015%206.994%2015C7.0205%2015%207.0444%2014.9968%207.0636%2014.9923C7.7433%2013.5244%208.666%2011.7877%209.7215%2010.7315M9.7215%2010.7315C10.773%209.6791%2012.4531%208.7468%2013.8721%208.0577C13.8756%208.0415%2013.878%208.0217%2013.878%207.9998C13.878%207.9779%2013.8756%207.9582%2013.8721%207.942C12.4537%207.2529%2010.7734%206.3207%209.7219%205.2691'%20fill='white'%20/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M15.4808%201.52468C15.104%201.14737%2014.7742%200.52704%2014.5315%200.00275993C14.5246%200.00112993%2014.5161%200%2014.5066%200C14.4971%200%2014.4885%200.00112993%2014.4817%200.00275993C14.2389%200.52705%2013.9094%201.14721%2013.5323%201.52455C13.1553%201.9018%2012.5355%202.2316%2012.0116%202.4745C12.0099%202.4815%2012.0087%202.4903%2012.0087%202.5C12.0087%202.5097%2012.0099%202.5184%2012.0115%202.5254C12.5354%202.7682%2013.1552%203.098%2013.5322%203.4754C13.9094%203.8527%2014.239%204.473%2014.4817%204.9972C14.4886%204.9989%2014.4971%205%2014.5066%205C14.516%205%2014.5246%204.9989%2014.5314%204.9972C14.7742%204.473%2015.1037%203.8528%2015.4806%203.4755M15.4806%203.4755C15.8562%203.0997%2016.4562%202.7667%2016.963%202.5206C16.9643%202.5148%2016.9651%202.5078%2016.9651%202.4999C16.9651%202.4921%2016.9643%202.4851%2016.963%202.4793C16.4565%202.2332%2015.8563%201.90026%2015.4808%201.52468'%20fill='white'%20/%3e%3c/g%3e%3c/svg%3e";
189
+ const launcher = "_launcher_qra98_1";
190
+ const icon = "_icon_qra98_37";
191
+ const styles = {
192
+ launcher,
193
+ "launcher--hidden": "_launcher--hidden_qra98_32",
194
+ icon
195
+ };
196
+ const CopilotLauncher = ({ instance, isOpen }) => {
197
+ const handleClick = useCallback(() => {
198
+ if (!instance) return;
199
+ const state = instance.getState();
200
+ instance.changeView(
201
+ state.viewState.mainWindow ? ViewType.LAUNCHER : ViewType.MAIN_WINDOW
202
+ );
203
+ }, [instance]);
204
+ return /* @__PURE__ */ jsx(
205
+ "button",
206
+ {
207
+ type: "button",
208
+ className: `${styles.launcher} ${isOpen ? styles["launcher--hidden"] : ""}`,
209
+ onClick: handleClick,
210
+ disabled: !instance,
211
+ "aria-label": "Toggle Copilot",
212
+ children: /* @__PURE__ */ jsx(
213
+ "img",
214
+ {
215
+ src: CopilotLauncherIcon,
216
+ alt: "",
217
+ "aria-hidden": "true",
218
+ className: styles.icon
219
+ }
220
+ )
221
+ }
222
+ );
223
+ };
224
+ const __vite_glob_0_0 = "._launcher_qra98_1 {\n position: fixed;\n bottom: 24px;\n right: 24px;\n z-index: 10000;\n width: 56px;\n height: 56px;\n border-radius: 50%;\n background-color: #8a3ffc;\n border: none;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: background-color 0.2s ease-in-out, opacity 0.2s ease-in-out;\n}\n\n._launcher_qra98_1:hover {\n background-color: #7a34e4;\n}\n\n._launcher_qra98_1:active {\n background-color: #5c24aa;\n}\n\n._launcher_qra98_1:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n._launcher--hidden_qra98_32 {\n opacity: 0;\n pointer-events: none;\n}\n\n._icon_qra98_37 {\n inline-size: 28px;\n block-size: 28px;\n}\n\nbody[data-copilot-chat-layout='bottom-sheet'] ._launcher_qra98_1 {\n inset-inline-end: 16px;\n inset-block-end: 16px;\n}\n";
225
+ const baseStyles = ":root {\n --copilot-chat-sidecar-width: 416px;\n --copilot-chat-panel-z-index: 9999;\n --copilot-chat-transition: 160ms cubic-bezier(0.2, 0, 0, 1);\n}\n\nbody[data-copilot-chat-layout='sidecar'],\n[data-copilot-chat-host] {\n margin-inline-end: var(--copilot-chat-sidecar-width);\n transition: margin-inline-end var(--copilot-chat-transition);\n box-sizing: border-box;\n}\n\nbody[data-copilot-chat-layout='bottom-sheet'] {\n margin-inline-end: 0;\n}\n\n.copilot-chat-panel {\n position: fixed;\n inset-block: 0;\n inset-inline-end: 0;\n inline-size: var(--copilot-chat-sidecar-width);\n max-inline-size: clamp(320px, var(--copilot-chat-sidecar-width), 512px);\n block-size: 100vh;\n z-index: var(--copilot-chat-panel-z-index);\n opacity: 0;\n pointer-events: none;\n transform: translateX(100%);\n transition: opacity 160ms cubic-bezier(0.2, 0, 0, 1),\n transform 160ms cubic-bezier(0.2, 0, 0, 1);\n --copilot-brand-color: #8a3ffc;\n --copilot-brand-color-hover: #7a34e4;\n --copilot-brand-color-active: #5c24aa;\n --copilot-brand-color-ghost: rgba(138, 63, 252, 0.12);\n --copilot-brand-color-ghost-strong: rgba(138, 63, 252, 0.2);\n --copilot-brand-color-muted: #6c2ed8;\n --cds-interactive: var(--copilot-brand-color);\n --cds-button-primary: var(--copilot-brand-color);\n --cds-button-primary-hover: var(--copilot-brand-color-hover);\n --cds-button-primary-active: var(--copilot-brand-color-active);\n --cds-button-tertiary: var(--copilot-brand-color);\n --cds-button-tertiary-hover: var(--copilot-brand-color-hover);\n --cds-button-tertiary-active: var(--copilot-brand-color-active);\n --cds-link-primary: var(--copilot-brand-color);\n --cds-link-primary-hover: var(--copilot-brand-color-hover);\n --cds-link-secondary: var(--copilot-brand-color);\n --cds-link-visited: var(--copilot-brand-color-muted);\n --cds-chat-avatar-user: var(--copilot-brand-color);\n --cds-chat-button: var(--copilot-brand-color);\n --cds-chat-button-hover: var(--copilot-brand-color-ghost);\n --cds-chat-button-selected: var(--copilot-brand-color-ghost-strong);\n --cds-chat-button-text-hover: var(--copilot-brand-color-hover);\n --cds-chat-button-text-selected: var(--copilot-brand-color);\n --cds-aichat-launcher-color-background: var(--copilot-brand-color);\n --cds-aichat-launcher-color-background-hover: var(\n --copilot-brand-color-hover\n );\n --cds-aichat-launcher-color-background-active: var(\n --copilot-brand-color-active\n );\n --cds-aichat-launcher-color-avatar: #fff;\n --cds-aichat-launcher-expanded-message-color-background: var(\n --copilot-brand-color\n );\n --cds-aichat-launcher-expanded-message-color-background-hover: var(\n --copilot-brand-color-hover\n );\n --cds-aichat-launcher-expanded-message-color-background-active: var(\n --copilot-brand-color-active\n );\n}\n\n.copilot-chat-panel--open {\n opacity: 1;\n pointer-events: auto;\n transform: translateX(0);\n background-color: var(--cds-layer, #fff);\n border-inline-start: 1px solid var(--cds-border-subtle, rgba(0, 0, 0, 0.12));\n box-shadow: 0 24px 64px rgba(0, 0, 0, 0.08);\n}\n\nbody[data-copilot-chat-layout='bottom-sheet'] .copilot-chat-panel {\n inset-inline: 0;\n inset-block-start: auto;\n inset-block-end: 0;\n block-size: min(70vh, 520px);\n inline-size: 100%;\n border-inline-start: none;\n border-block-start: 1px solid var(--cds-border-subtle, rgba(0, 0, 0, 0.12));\n}\n";
226
+ const STYLE_ID = "copilot-chat-sidecar-styles";
227
+ const cssModuleInlineMap = /* @__PURE__ */ Object.assign({
228
+ "../components/CopilotLauncher.module.css": __vite_glob_0_0
229
+ });
230
+ const combinedStyles = [baseStyles, ...Object.values(cssModuleInlineMap)].join(
231
+ "\n"
232
+ );
233
+ const ensureSidecarStyles = () => {
234
+ if (typeof document === "undefined") {
235
+ return;
236
+ }
237
+ const existingStyle = document.getElementById(STYLE_ID);
238
+ if (existingStyle) {
239
+ return;
240
+ }
241
+ const style = document.createElement("style");
242
+ style.id = STYLE_ID;
243
+ style.textContent = combinedStyles;
244
+ document.head.appendChild(style);
245
+ };
246
+ const headerConfig = {
247
+ name: "Copilot",
248
+ showAiLabel: false
249
+ };
250
+ const launcherConfig = {
251
+ isOn: false
252
+ };
253
+ const CopilotChat = ({
254
+ customSendMessage,
255
+ workareaSelector
256
+ }) => {
257
+ const [isOpen, setIsOpen] = useState(false);
258
+ const [instance, setInstance] = useState(null);
259
+ useEffect(() => {
260
+ ensureSidecarStyles();
261
+ }, []);
262
+ useCopilotSidecar({
263
+ enabled: isOpen,
264
+ width: 416,
265
+ zIndex: 12,
266
+ workareaSelector,
267
+ responsiveBreakpoint: 960
268
+ });
269
+ const handleViewChange = useCallback(
270
+ (event) => {
271
+ setIsOpen(event.newViewState.mainWindow);
272
+ },
273
+ []
274
+ );
275
+ const handleAfterRender = useCallback((instance2) => {
276
+ setInstance(instance2);
277
+ }, []);
278
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
279
+ /* @__PURE__ */ jsx(CopilotLauncher, { instance, isOpen }),
280
+ /* @__PURE__ */ jsx(
281
+ ChatCustomElement,
282
+ {
283
+ className: `copilot-chat-panel ${isOpen ? "copilot-chat-panel--open" : ""}`,
284
+ aiEnabled: false,
285
+ assistantName: "Copilot",
286
+ layout: {
287
+ corners: CornersType.SQUARE
288
+ },
289
+ openChatByDefault: false,
290
+ onViewChange: handleViewChange,
291
+ onAfterRender: handleAfterRender,
292
+ header: headerConfig,
293
+ launcher: launcherConfig,
294
+ messaging: { customSendMessage }
295
+ }
296
+ )
297
+ ] });
298
+ };
299
+ export {
300
+ CopilotChat
301
+ };
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ declare const jsx: (type: React.ElementType, props: Record<string, unknown> | null | undefined, key?: React.Key) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
3
+ declare const jsxs: (type: React.ElementType, props: Record<string, unknown> | null | undefined, key?: React.Key) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
4
+ declare const jsxDEV: (type: React.ElementType, props: Record<string, unknown> | null | undefined, key?: React.Key, _isStaticChildren?: boolean, _source?: unknown, _self?: unknown) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
5
+ declare const Fragment: React.ExoticComponent<React.FragmentProps>;
6
+ export { jsx, jsxs, jsxDEV, Fragment };
7
+ //# sourceMappingURL=jsx-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsx-runtime.d.ts","sourceRoot":"","sources":["../src/jsx-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAc1B,QAAA,MAAM,GAAG,GACP,MAAM,KAAK,CAAC,WAAW,EACvB,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACjD,MAAM,KAAK,CAAC,GAAG,uEACa,CAAC;AAE/B,QAAA,MAAM,IAAI,SALF,KAAK,CAAC,WAAW,SAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,QAC3C,KAAK,CAAC,GAAG,uEAGD,CAAC;AAEjB,QAAA,MAAM,MAAM,GACV,MAAM,KAAK,CAAC,WAAW,EACvB,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACjD,MAAM,KAAK,CAAC,GAAG,EACf,oBAAoB,OAAO,EAC3B,UAAU,OAAO,EACjB,QAAQ,OAAO,uEACa,CAAC;AAE/B,QAAA,MAAM,QAAQ,4CAAiB,CAAC;AAEhC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface SidecarLayoutConfig {
2
+ width: number;
3
+ zIndex: number;
4
+ workareaSelector?: string;
5
+ responsiveBreakpoint: number;
6
+ }
7
+ export declare const attachSidecarLayout: ({ width, zIndex, workareaSelector, responsiveBreakpoint, }: SidecarLayoutConfig) => () => void;
8
+ //# sourceMappingURL=SidecarLayoutManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SidecarLayoutManager.d.ts","sourceRoot":"","sources":["../../src/layout/SidecarLayoutManager.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AAInC,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAsMD,eAAO,MAAM,mBAAmB,GAAI,4DAKjC,mBAAmB,eAqBrB,CAAC"}
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@camunda/copilot-chat",
3
+ "version": "0.0.0-alpha1",
4
+ "description": "Camunda Copilot Client Library - React components and utilities for Camunda Platform 8",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "style": "./dist/index.css",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/camunda/camunda-copilot-client.git",
29
+ "directory": "packages/copilot-chat"
30
+ },
31
+ "keywords": [
32
+ "camunda",
33
+ "copilot",
34
+ "react",
35
+ "typescript",
36
+ "camunda-platform-8",
37
+ "workflow",
38
+ "automation"
39
+ ],
40
+ "author": "Camunda Services GmbH",
41
+ "license": "LicenseRef-Camunda-1.0",
42
+ "engines": {
43
+ "node": ">=18.0.0",
44
+ "npm": ">=9.0.0"
45
+ },
46
+ "dependencies": {
47
+ "@carbon/ai-chat": "^1.2.0",
48
+ "@carbon/react": "1.95.0"
49
+ },
50
+ "peerDependencies": {
51
+ "react": ">=18.0.0 <20.0.0",
52
+ "react-dom": ">=18.0.0 <20.0.0"
53
+ }
54
+ }
@@ -0,0 +1,2 @@
1
+ export declare const ensureSidecarStyles: () => void;
2
+ //# sourceMappingURL=ensureSidecarStyles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensureSidecarStyles.d.ts","sourceRoot":"","sources":["../../src/styles/ensureSidecarStyles.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,mBAAmB,YAc/B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@camunda/copilot-chat",
3
+ "version": "0.0.0-alpha2",
4
+ "description": "Camunda Copilot Client Library - React components and utilities for Camunda Platform 8",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "style": "./dist/index.css",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/camunda/camunda-copilot-client.git",
29
+ "directory": "packages/copilot-chat"
30
+ },
31
+ "keywords": [
32
+ "camunda",
33
+ "copilot",
34
+ "react",
35
+ "typescript",
36
+ "camunda-platform-8",
37
+ "workflow",
38
+ "automation"
39
+ ],
40
+ "author": "Camunda Services GmbH",
41
+ "license": "LicenseRef-Camunda-1.0",
42
+ "engines": {
43
+ "node": ">=18.0.0",
44
+ "npm": ">=9.0.0"
45
+ },
46
+ "dependencies": {
47
+ "@carbon/ai-chat": "^1.2.0",
48
+ "@carbon/react": "1.95.0"
49
+ },
50
+ "peerDependencies": {
51
+ "react": ">=18.0.0 <20.0.0",
52
+ "react-dom": ">=18.0.0 <20.0.0"
53
+ }
54
+ }