Skip to content

Commit 59b69e5

Browse files
committed
Merge pull request #3203 from contentful/PIC-694-forma36-create-aichatlayout-component-implementation
feat(f36-ai-components): add AIChatLayout component
2 parents f88f199 + 8e56100 commit 59b69e5

File tree

8 files changed

+751
-87
lines changed

8 files changed

+751
-87
lines changed

package-lock.json

Lines changed: 4 additions & 54 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/f36-ai-components/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
"build": "tsup"
1818
},
1919
"dependencies": {
20+
"@contentful/f36-components": "^5.6.0",
2021
"@contentful/f36-core": "^5.0.0",
22+
"@contentful/f36-header": "^5.6.0",
23+
"@contentful/f36-layout": "^5.6.0",
2124
"@contentful/f36-tokens": "^5.0.0",
25+
"@contentful/f36-utils": "^5.2.0",
2226
"emotion": "^10.0.17"
2327
},
2428
"peerDependencies": {
Lines changed: 127 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,134 @@
11
import tokens from '@contentful/f36-tokens';
2+
import { hexToRGBA } from '@contentful/f36-utils';
23
import { css } from 'emotion';
34

4-
export const getStyles = () => {
5+
import type { AIChatLayoutDisplay } from './AIChatLayout';
6+
7+
interface StyleProps {
8+
display?: AIChatLayoutDisplay;
9+
variant?: 'normal' | 'expanded';
10+
isAnimatingOut?: boolean;
11+
}
12+
13+
export const getStyles = (props: StyleProps = {}) => {
14+
const {
15+
display = 'open',
16+
variant = 'normal',
17+
isAnimatingOut = false,
18+
} = props;
19+
20+
const isOpen = display !== 'collapsed';
21+
522
return {
6-
aIChatLayout: css({
7-
color: tokens.red600,
23+
root: css({
24+
position: 'fixed',
25+
bottom: tokens.spacing2Xs,
26+
right: tokens.spacingXs,
27+
width: variant === 'expanded' && isOpen ? '985px' : '350px',
28+
transition: `width ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}, transform ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}, opacity ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,
29+
transform: isAnimatingOut ? 'translateX(50%)' : 'translateX(0)',
30+
opacity: isAnimatingOut ? 0 : 1,
31+
backgroundColor: tokens.colorWhite,
32+
display: 'flex',
33+
flexDirection: 'column',
34+
justifyContent: isOpen ? 'flex-start' : 'center',
35+
alignItems: 'flex-start',
36+
overflow: 'hidden',
37+
boxShadow: tokens.boxShadowHeavy,
38+
borderRadius: '16px',
39+
}),
40+
41+
header: css({
42+
width: '100%',
43+
height: '48px',
44+
padding: `0px ${tokens.spacingS}`,
45+
backgroundColor: 'transparent',
46+
flexShrink: 0,
47+
alignItems: 'center',
48+
gap: tokens.spacing2Xs,
49+
borderBottom: isOpen
50+
? `1px solid ${hexToRGBA(tokens.gray900, 0.05)}`
51+
: '0',
52+
cursor: display === 'collapsed' ? 'pointer' : 'auto',
53+
}),
54+
55+
icon: css({
56+
display: 'flex',
57+
alignItems: 'center',
58+
justifyContent: 'center',
59+
flexShrink: 0,
60+
paddingLeft: tokens.spacingXs,
61+
}),
62+
63+
title: css({
64+
flex: '1 1 auto',
65+
fontSize: tokens.fontSizeM,
66+
fontWeight: tokens.fontWeightMedium,
67+
color: tokens.gray900,
68+
overflow: 'hidden',
69+
textOverflow: 'ellipsis',
70+
whiteSpace: 'nowrap',
71+
}),
72+
73+
buttonGroup: css({
74+
display: 'flex',
75+
alignItems: 'center',
76+
flexShrink: 0,
77+
justifyContent: 'flex-end',
78+
position: 'relative',
79+
marginLeft: 'auto',
80+
}),
81+
82+
buttonIcon: css({
83+
filter: `drop-shadow(0px 1px 0px ${hexToRGBA(tokens.gray900, 0.05)})`,
84+
}),
85+
86+
buttonVisible: css({
87+
opacity: 1,
88+
transform: 'translateX(0) scale(1)',
89+
transition: `opacity ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}, transform ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,
90+
transitionDelay: 'var(--button-delay, 0ms)',
91+
pointerEvents: 'auto',
92+
marginLeft: tokens.spacing2Xs,
93+
outline: 'none',
94+
border: 'none',
95+
boxShadow: 'none',
96+
'&:first-child': {
97+
marginLeft: '0',
98+
},
99+
}),
100+
101+
buttonHidden: css({
102+
opacity: 0,
103+
transform: 'translateX(4px) scale(0.95)',
104+
transition: `opacity ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}, transform ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}, width ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,
105+
transitionDelay: 'var(--button-delay, 0ms)',
106+
pointerEvents: 'none',
107+
width: '0',
108+
minWidth: '0',
109+
maxWidth: '0',
110+
margin: '0',
111+
padding: '0',
112+
border: 'none',
113+
overflow: 'hidden',
114+
}),
115+
116+
content: css({
117+
flex: 1,
118+
height: '720px',
119+
padding: tokens.spacingM,
120+
overflow: 'auto',
121+
backgroundColor: tokens.colorWhite,
122+
}),
123+
124+
aiGradientIcon: css({
125+
width: '20px',
126+
height: '20px',
127+
transition: `transform ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,
128+
129+
'*': {
130+
fill: `url("#icon-gradient") rgba(140, 46, 234, 1)`,
131+
},
8132
}),
9133
};
10134
};

0 commit comments

Comments
 (0)