@super_studio/ecforce-ai-agent-react 0.1.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,104 @@
1
+ @import "./tooltip.css";
2
+
3
+ /* Chatbot Trigger Button */
4
+ .chatbot-trigger {
5
+ position: fixed;
6
+ bottom: 1rem;
7
+ right: 1rem;
8
+ z-index: 50;
9
+ border-radius: 9999px;
10
+ border: 1px solid #f0f2f7;
11
+ background-color: #ffffff;
12
+ color: #0061ff;
13
+ box-shadow:
14
+ 0 1px 3px 0 rgba(0, 0, 0, 0.1),
15
+ 0 1px 2px 0 rgba(0, 0, 0, 0.06);
16
+ transition: colors 200ms ease-in-out;
17
+ cursor: pointer;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ height: 40px;
22
+ width: 40px;
23
+ }
24
+
25
+ .chatbot-trigger:hover {
26
+ background-color: #f0f2f7;
27
+ }
28
+
29
+ /* Sheet Content */
30
+ .chatbot-sheet-content {
31
+ position: fixed;
32
+ top: 0;
33
+ right: 0;
34
+ bottom: 0;
35
+ z-index: 50;
36
+ background-color: #ffffff;
37
+ box-shadow:
38
+ 0 10px 15px -3px rgba(0, 0, 0, 0.1),
39
+ 0 4px 6px -2px rgba(0, 0, 0, 0.05);
40
+ border-left: 1px solid #e5e7eb;
41
+ width: var(--sheet-width, 400px);
42
+ height: 100vh;
43
+ transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
44
+ }
45
+
46
+ .chatbot-sheet-content.chatbot-sheet-expanded {
47
+ --sheet-width: 848px;
48
+ }
49
+
50
+ /* Sheet Header */
51
+ .chatbot-sheet-header {
52
+ display: flex;
53
+ flex-direction: column;
54
+ gap: 0.375rem;
55
+ padding: 1rem;
56
+ }
57
+
58
+ /* Sheet Footer */
59
+ .chatbot-sheet-footer {
60
+ margin-top: auto;
61
+ display: flex;
62
+ flex-direction: column;
63
+ gap: 0.5rem;
64
+ padding: 1rem;
65
+ }
66
+
67
+ /* Invisible Title and Description (For radix accessibility) */
68
+ .chatbot-sheet-title,
69
+ .chatbot-sheet-description {
70
+ position: absolute;
71
+ width: 1px;
72
+ height: 1px;
73
+ padding: 0;
74
+ margin: -1px;
75
+ overflow: hidden;
76
+ clip: rect(0, 0, 0, 0);
77
+ white-space: nowrap;
78
+ border: 0;
79
+ }
80
+
81
+ /* Sheet Description */
82
+ .chatbot-sheet-description {
83
+ color: #6b7280;
84
+ font-size: 0.875rem;
85
+ }
86
+
87
+ /* Sheet Close */
88
+ .chatbot-sheet-close {
89
+ cursor: pointer;
90
+ }
91
+
92
+ /* Initial mount animation */
93
+ @keyframes chatbot-sheet-enter {
94
+ from {
95
+ transform: translateX(100%);
96
+ }
97
+ to {
98
+ transform: translateX(0);
99
+ }
100
+ }
101
+
102
+ .chatbot-sheet-content[data-state="open"] {
103
+ animation: chatbot-sheet-enter 300ms cubic-bezier(0.4, 0, 0.2, 1);
104
+ }
@@ -1,36 +1,42 @@
1
- import { forwardRef, useState } from "react";
1
+ import { forwardRef, type CSSProperties } from "react";
2
2
  import {
3
3
  AgentFrame,
4
4
  type AgentElement,
5
5
  type AgentFrameProps,
6
6
  } from "./agent-frame";
7
- import { Popover, PopoverContent, PopoverTrigger } from "./popover";
8
-
9
- export const ChatbotPopover = forwardRef<AgentElement, AgentFrameProps>(
10
- (props, ref) => {
11
- const [isOpen, setIsOpen] = useState(false);
12
- const [hasOpened, setHasOpened] = useState(false);
7
+ import {
8
+ Sheet,
9
+ SheetContent,
10
+ SheetDescription,
11
+ SheetTitle,
12
+ SheetTrigger,
13
+ } from "./sheet";
14
+ import { Tooltip } from "./tooltip";
13
15
 
14
- const handleOpenChange = (open: boolean) => {
15
- setIsOpen(open);
16
- if (open && !hasOpened) {
17
- setHasOpened(true);
18
- }
19
- };
16
+ type ChatbotSheetProps = AgentFrameProps & {
17
+ sheetStyle?: CSSProperties;
18
+ };
20
19
 
20
+ export const ChatbotSheet = forwardRef<AgentElement, ChatbotSheetProps>(
21
+ ({ sheetStyle, ...props }, ref) => {
21
22
  return (
22
- <Popover open={isOpen} onOpenChange={handleOpenChange}>
23
- <PopoverTrigger>
24
- <EcforceAiIcon />
25
- </PopoverTrigger>
26
- <PopoverContent
23
+ <Sheet>
24
+ <Tooltip
25
+ side="top"
27
26
  align="end"
28
- backdrop={isOpen}
29
- forceMount={hasOpened || undefined} // チャットのStateを保持するために必要
30
- >
27
+ content="AIに質問してみましょう"
28
+ trigger={
29
+ <SheetTrigger>
30
+ <EcforceAiIcon />
31
+ </SheetTrigger>
32
+ }
33
+ />
34
+ <SheetContent style={sheetStyle}>
35
+ <SheetTitle>AIに質問してみましょう</SheetTitle>
36
+ <SheetDescription>AIに質問してみましょう</SheetDescription>
31
37
  <AgentFrame {...props} ref={ref} />
32
- </PopoverContent>
33
- </Popover>
38
+ </SheetContent>
39
+ </Sheet>
34
40
  );
35
41
  },
36
42
  );
@@ -38,8 +44,8 @@ export const ChatbotPopover = forwardRef<AgentElement, AgentFrameProps>(
38
44
  function EcforceAiIcon() {
39
45
  return (
40
46
  <svg
41
- width="24"
42
- height="24"
47
+ width="18"
48
+ height="18"
43
49
  viewBox="0 0 24 24"
44
50
  xmlns="http://www.w3.org/2000/svg"
45
51
  fill="currentColor"
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from "./chatbot-proivder";
1
2
  export * from "./agent-frame";
2
- export * from "./chatbot-popover";
3
- export * from "./popover";
3
+ export * from "./chatbot-sheet";
4
+ export * from "./sheet";
5
+ export * from "./tooltip";
package/src/sheet.tsx ADDED
@@ -0,0 +1,148 @@
1
+ "use client";
2
+
3
+ import * as SheetPrimitive from "@radix-ui/react-dialog";
4
+ import * as React from "react";
5
+ import { useChatbot } from "./chatbot-proivder";
6
+
7
+ function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
8
+ const { open, setOpen } = useChatbot();
9
+ return (
10
+ <SheetPrimitive.Root
11
+ data-slot="sheet"
12
+ modal={false}
13
+ open={open}
14
+ onOpenChange={setOpen}
15
+ {...props}
16
+ />
17
+ );
18
+ }
19
+
20
+ const SheetTrigger = React.forwardRef<
21
+ React.ElementRef<typeof SheetPrimitive.Trigger>,
22
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Trigger>
23
+ >(({ className, ...props }, ref) => (
24
+ <SheetPrimitive.Trigger
25
+ ref={ref}
26
+ data-slot="sheet-trigger"
27
+ className={`chatbot-trigger ${className || ""}`}
28
+ {...props}
29
+ />
30
+ ));
31
+ SheetTrigger.displayName = SheetPrimitive.Trigger.displayName;
32
+
33
+ const SheetClose = React.forwardRef<
34
+ React.ElementRef<typeof SheetPrimitive.Close>,
35
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Close>
36
+ >(({ className, ...props }, ref) => (
37
+ <SheetPrimitive.Close
38
+ ref={ref}
39
+ data-slot="sheet-close"
40
+ className={`chatbot-sheet-close ${className || ""}`}
41
+ {...props}
42
+ />
43
+ ));
44
+ SheetClose.displayName = SheetPrimitive.Close.displayName;
45
+
46
+ function SheetPortal({
47
+ ...props
48
+ }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
49
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
50
+ }
51
+
52
+ const SheetContent = React.forwardRef<
53
+ React.ElementRef<typeof SheetPrimitive.Content>,
54
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>
55
+ >(({ className, children, style, ...props }, ref) => {
56
+ const { isExpanded, open, hasOpened } = useChatbot();
57
+ const width = isExpanded ? "848px" : "400px";
58
+
59
+ // Use transform for better performance instead of right property
60
+ const translateX = open ? "0" : "100%";
61
+
62
+ // Create style object with CSS custom property for smoother animation
63
+ const contentStyle = {
64
+ "--sheet-width": width,
65
+ transform: `translateX(${translateX})`,
66
+ ...style,
67
+ } as React.CSSProperties & { "--sheet-width": string };
68
+
69
+ return (
70
+ <SheetPortal forceMount={hasOpened || undefined}>
71
+ <SheetPrimitive.Content
72
+ ref={ref}
73
+ data-slot="sheet-content"
74
+ forceMount={hasOpened || undefined}
75
+ onInteractOutside={(e) => e.preventDefault()}
76
+ className={`chatbot-sheet-content ${isExpanded ? "chatbot-sheet-expanded" : ""} ${className || ""}`}
77
+ style={contentStyle}
78
+ {...props}
79
+ >
80
+ {children}
81
+ </SheetPrimitive.Content>
82
+ </SheetPortal>
83
+ );
84
+ });
85
+ SheetContent.displayName = SheetPrimitive.Content.displayName;
86
+
87
+ const SheetHeader = React.forwardRef<
88
+ HTMLDivElement,
89
+ React.HTMLAttributes<HTMLDivElement>
90
+ >(({ className, ...props }, ref) => (
91
+ <div
92
+ ref={ref}
93
+ data-slot="sheet-header"
94
+ className={`chatbot-sheet-header ${className || ""}`}
95
+ {...props}
96
+ />
97
+ ));
98
+ SheetHeader.displayName = "SheetHeader";
99
+
100
+ const SheetFooter = React.forwardRef<
101
+ HTMLDivElement,
102
+ React.HTMLAttributes<HTMLDivElement>
103
+ >(({ className, ...props }, ref) => (
104
+ <div
105
+ ref={ref}
106
+ data-slot="sheet-footer"
107
+ className={`chatbot-sheet-footer ${className || ""}`}
108
+ {...props}
109
+ />
110
+ ));
111
+ SheetFooter.displayName = "SheetFooter";
112
+
113
+ const SheetTitle = React.forwardRef<
114
+ React.ElementRef<typeof SheetPrimitive.Title>,
115
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
116
+ >(({ className, ...props }, ref) => (
117
+ <SheetPrimitive.Title
118
+ ref={ref}
119
+ data-slot="sheet-title"
120
+ className={`chatbot-sheet-title ${className || ""}`}
121
+ {...props}
122
+ />
123
+ ));
124
+ SheetTitle.displayName = SheetPrimitive.Title.displayName;
125
+
126
+ const SheetDescription = React.forwardRef<
127
+ React.ElementRef<typeof SheetPrimitive.Description>,
128
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
129
+ >(({ className, ...props }, ref) => (
130
+ <SheetPrimitive.Description
131
+ ref={ref}
132
+ data-slot="sheet-description"
133
+ className={`chatbot-sheet-description ${className || ""}`}
134
+ {...props}
135
+ />
136
+ ));
137
+ SheetDescription.displayName = SheetPrimitive.Description.displayName;
138
+
139
+ export {
140
+ Sheet,
141
+ SheetTrigger,
142
+ SheetClose,
143
+ SheetContent,
144
+ SheetHeader,
145
+ SheetFooter,
146
+ SheetTitle,
147
+ SheetDescription,
148
+ };
@@ -0,0 +1,18 @@
1
+ /* Tooltip Content */
2
+ .tooltip-content {
3
+ background-color: #1f2937;
4
+ z-index: 50;
5
+ max-width: 320px;
6
+ border-radius: 0.125rem;
7
+ padding: 0.5rem;
8
+ font-size: 0.625rem;
9
+ font-weight: 400;
10
+ line-height: 1.25;
11
+ color: #ffffff;
12
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
13
+ }
14
+
15
+ /* Arrow styling can be customized via arrowClassName prop */
16
+ .tooltip-arrow {
17
+ fill: #1f2937;
18
+ }
@@ -0,0 +1,88 @@
1
+ "use client";
2
+
3
+ import {
4
+ Arrow,
5
+ Content,
6
+ Portal,
7
+ Provider,
8
+ Root,
9
+ Trigger,
10
+ } from "@radix-ui/react-tooltip";
11
+ import "./tooltip.css";
12
+
13
+ type Side = "top" | "right" | "bottom" | "left";
14
+ type Align = "start" | "center" | "end";
15
+
16
+ type TooltipProps = {
17
+ content: React.ReactNode;
18
+ side?: Side;
19
+ align?: Align;
20
+ trigger: React.ReactNode;
21
+ disabled?: boolean;
22
+ delayDuration?: number;
23
+ skipDelayDuration?: number;
24
+ className?: string;
25
+ open?: boolean;
26
+ alignOffset?: number;
27
+ sideOffset?: number;
28
+ arrowClassName?: string;
29
+ keepTooltipOpen?: boolean;
30
+ };
31
+
32
+ export function Tooltip({
33
+ content,
34
+ trigger,
35
+ side,
36
+ align,
37
+ disabled,
38
+ delayDuration,
39
+ skipDelayDuration,
40
+ className,
41
+ open,
42
+ alignOffset,
43
+ sideOffset,
44
+ arrowClassName,
45
+ keepTooltipOpen,
46
+ }: TooltipProps) {
47
+ return (
48
+ <Provider
49
+ delayDuration={delayDuration ?? 200}
50
+ skipDelayDuration={skipDelayDuration ?? 200}
51
+ >
52
+ <Root open={disabled ? false : open}>
53
+ <Trigger
54
+ onClick={
55
+ keepTooltipOpen
56
+ ? (event) => {
57
+ event.preventDefault();
58
+ }
59
+ : undefined
60
+ }
61
+ asChild
62
+ >
63
+ {trigger}
64
+ </Trigger>
65
+
66
+ <Portal>
67
+ <Content
68
+ className={`tooltip-content ${className || ""}`}
69
+ side={side}
70
+ align={align}
71
+ alignOffset={alignOffset}
72
+ sideOffset={sideOffset}
73
+ onPointerDownOutside={
74
+ keepTooltipOpen
75
+ ? (event) => {
76
+ event.preventDefault();
77
+ }
78
+ : undefined
79
+ }
80
+ >
81
+ <Arrow className={arrowClassName} />
82
+ {content}
83
+ </Content>
84
+ </Portal>
85
+ </Root>
86
+ </Provider>
87
+ );
88
+ }
@@ -1,3 +0,0 @@
1
- import { type AgentElement, type AgentFrameProps } from "./agent-frame";
2
- export declare const ChatbotPopover: import("react").ForwardRefExoticComponent<AgentFrameProps & import("react").RefAttributes<AgentElement>>;
3
- //# sourceMappingURL=chatbot-popover.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chatbot-popover.d.ts","sourceRoot":"","sources":["../src/chatbot-popover.tsx"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAGvB,eAAO,MAAM,cAAc,0GA2B1B,CAAC"}
package/dist/chatbot.css DELETED
@@ -1,166 +0,0 @@
1
- /* Chatbot Trigger Button */
2
- .chatbot-trigger {
3
- position: fixed;
4
- bottom: 1rem;
5
- right: 1rem;
6
- z-index: 50;
7
- border-radius: 9999px;
8
- border: 1px solid #f0f2f7;
9
- background-color: #ffffff;
10
- padding: 0.375rem;
11
- color: #0061ff;
12
- box-shadow:
13
- 0 1px 3px 0 rgba(0, 0, 0, 0.1),
14
- 0 1px 2px 0 rgba(0, 0, 0, 0.06);
15
- transition: colors 200ms ease-in-out;
16
- cursor: pointer;
17
- }
18
-
19
- .chatbot-trigger:hover {
20
- background-color: #f0f2f7;
21
- }
22
-
23
- /* Popover Backdrop */
24
- .chatbot-popover-backdrop {
25
- position: fixed;
26
- top: 0;
27
- right: 0;
28
- bottom: 0;
29
- left: 0;
30
- z-index: 30;
31
- background-color: rgba(0, 0, 0, 0.5);
32
- animation: fade-in 150ms ease-out;
33
- }
34
-
35
- /* Popover Content */
36
- .chatbot-popover-content {
37
- z-index: 50;
38
- border-radius: 2rem;
39
- background-color: #f7f9fa;
40
- box-shadow:
41
- 0 4px 6px -1px rgba(0, 0, 0, 0.1),
42
- 0 2px 4px -1px rgba(0, 0, 0, 0.06);
43
- outline: none;
44
- overflow: hidden;
45
- height: 80vh;
46
- width: 600px;
47
- }
48
-
49
- /* Animation states */
50
- .chatbot-popover-content[data-state="closed"] {
51
- display: none;
52
- }
53
-
54
- .chatbot-popover-content[data-state="open"] {
55
- animation:
56
- zoom-in 150ms ease-out,
57
- fade-in 150ms ease-out;
58
- }
59
-
60
- .chatbot-popover-content[data-state="closed"] {
61
- animation:
62
- zoom-out 150ms ease-in,
63
- fade-out 150ms ease-in;
64
- }
65
-
66
- /* Side-specific slide animations */
67
- .chatbot-popover-content[data-side="bottom"] {
68
- animation:
69
- zoom-in 150ms ease-out,
70
- fade-in 150ms ease-out,
71
- slide-in-from-top 150ms ease-out;
72
- }
73
-
74
- .chatbot-popover-content[data-side="top"] {
75
- animation:
76
- zoom-in 150ms ease-out,
77
- fade-in 150ms ease-out,
78
- slide-in-from-bottom 150ms ease-out;
79
- }
80
-
81
- .chatbot-popover-content[data-side="left"] {
82
- animation:
83
- zoom-in 150ms ease-out,
84
- fade-in 150ms ease-out,
85
- slide-in-from-right 150ms ease-out;
86
- }
87
-
88
- .chatbot-popover-content[data-side="right"] {
89
- animation:
90
- zoom-in 150ms ease-out,
91
- fade-in 150ms ease-out,
92
- slide-in-from-left 150ms ease-out;
93
- }
94
-
95
- /* Keyframe Animations */
96
- @keyframes fade-in {
97
- from {
98
- opacity: 0;
99
- }
100
- to {
101
- opacity: 1;
102
- }
103
- }
104
-
105
- @keyframes fade-out {
106
- from {
107
- opacity: 1;
108
- }
109
- to {
110
- opacity: 0;
111
- }
112
- }
113
-
114
- @keyframes zoom-in {
115
- from {
116
- transform: scale(0.95);
117
- }
118
- to {
119
- transform: scale(1);
120
- }
121
- }
122
-
123
- @keyframes zoom-out {
124
- from {
125
- transform: scale(1);
126
- }
127
- to {
128
- transform: scale(0.95);
129
- }
130
- }
131
-
132
- @keyframes slide-in-from-top {
133
- from {
134
- transform: translateY(-0.5rem);
135
- }
136
- to {
137
- transform: translateY(0);
138
- }
139
- }
140
-
141
- @keyframes slide-in-from-bottom {
142
- from {
143
- transform: translateY(0.5rem);
144
- }
145
- to {
146
- transform: translateY(0);
147
- }
148
- }
149
-
150
- @keyframes slide-in-from-left {
151
- from {
152
- transform: translateX(-0.5rem);
153
- }
154
- to {
155
- transform: translateX(0);
156
- }
157
- }
158
-
159
- @keyframes slide-in-from-right {
160
- from {
161
- transform: translateX(0.5rem);
162
- }
163
- to {
164
- transform: translateX(0);
165
- }
166
- }
package/dist/popover.d.ts DELETED
@@ -1,9 +0,0 @@
1
- import * as PopoverPrimitive from "@radix-ui/react-popover";
2
- import * as React from "react";
3
- declare const Popover: React.FC<PopoverPrimitive.PopoverProps>;
4
- declare const PopoverTrigger: React.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
5
- declare const PopoverContent: React.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
6
- backdrop?: boolean;
7
- } & React.RefAttributes<HTMLDivElement>>;
8
- export { Popover, PopoverTrigger, PopoverContent };
9
- //# sourceMappingURL=popover.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../src/popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,QAAA,MAAM,OAAO,yCAAwB,CAAC;AAEtC,QAAA,MAAM,cAAc,sKASlB,CAAC;AAGH,QAAA,MAAM,cAAc;eAGL,OAAO;wCA4BrB,CAAC;AAGF,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC"}