-
Notifications
You must be signed in to change notification settings - Fork 14
Khatchig - CEM2662 - Typing animation #440
base: master
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import React from 'react'; | ||
| import { Meta, Story } from '@storybook/react'; | ||
| import TextBubble, { ITextBubbleProps } from './TextBubble'; | ||
| import TypingDots from '../../Text/TypingDots/TypingDots'; | ||
|
|
||
| export default { | ||
| title: 'Components/Text Bubble', | ||
| component: TextBubble, | ||
| } as Meta; | ||
|
|
||
| const Template: Story<ITextBubbleProps> = (args) => ( | ||
| <TextBubble {...args} /> | ||
| ); | ||
|
|
||
| export const Basic = Template.bind({}); | ||
| Basic.args = { | ||
| content: <p>Basic text bubble (other generated)</p>, | ||
| fromBot: true | ||
| } | ||
|
|
||
| export const User = Template.bind({}); | ||
| User.args = { | ||
| content: <p>Basic text bubble (user generated)</p>, | ||
| fromBot: false | ||
| } | ||
|
|
||
| export const NoText = Template.bind({}); | ||
| NoText.args = { | ||
| content: <p> </p>, | ||
| fromBot: true | ||
| } | ||
|
|
||
| export const Typing = Template.bind({}); | ||
| Typing.args = { | ||
| content: <TypingDots num={3} delayStep={0.1} />, | ||
| fromBot: true | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| import React from 'react'; | ||
| import styled from 'styled-components'; | ||
| import { Mixins } from '../../Utils'; | ||
|
|
||
| export interface ITextBubbleProps { | ||
| content: React.ReactElement; | ||
| fromBot: boolean; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bubbleProps: React.HTMLAttrs(ReactDivElemet) |
||
| } | ||
|
|
||
| export const TextBubble = ({content, fromBot, ...props}: ITextBubbleProps): React.ReactElement => { | ||
| return ( | ||
| <BubbleContainer fromBot={ fromBot }> | ||
| <Bubble fromBot={ fromBot }> | ||
|
||
| <div style={{ | ||
|
||
| marginLeft: textMarginSize, | ||
| marginRight: textMarginSize, | ||
| display: "flex", | ||
| flexDirection: "row" | ||
| }}> | ||
|
||
| { content } | ||
| </div> | ||
| </Bubble> | ||
| </BubbleContainer> | ||
| ); | ||
| } | ||
|
|
||
| const textMarginSize = "10px"; | ||
|
|
||
| const container_margin = "10px"; | ||
|
||
| const BubbleContainer = styled.div<{ fromBot: boolean }>` | ||
| ${Mixins.flex("row")}; | ||
| ${Mixins.flex("center")}; | ||
| position: relative; | ||
|
|
||
| maxwidth: "80%"; | ||
| width: "fit-content"; | ||
| ${({ fromBot }): string => | ||
| fromBot | ||
| ? ` | ||
| justify-content: left; | ||
| margin-left: 0px; | ||
| margin-right: ${container_margin}; | ||
| ` | ||
| : ` | ||
| justify-content: right; | ||
| margin-left: ${container_margin}; | ||
| margin-right: 0px; | ||
| ` | ||
| } | ||
| marginTop: standardMarginSize; | ||
| margin-top: -20px; | ||
|
||
| margin-bottom: 20px; | ||
| ${({ theme }): string => ` | ||
| padding: ${theme.dimensions.padding.withBorder}; | ||
| `} | ||
|
|
||
| animation: appear 0.5s ease-in 1; | ||
| @keyframes appear { | ||
| from { | ||
| opacity: 0; | ||
| } | ||
| to { | ||
| opacity: 100; | ||
| } | ||
| } | ||
| ` | ||
|
|
||
| const bubble_margin = "50px"; | ||
| const Bubble = styled.div<{ fromBot: boolean }>` | ||
| ${({ fromBot }): string => | ||
| fromBot | ||
| ? ` | ||
| margin-left: ${bubble_margin}; | ||
| margin-right: 0px; | ||
| ` | ||
| : ` | ||
| margin-left: 0px; | ||
| margin-right: ${bubble_margin}; | ||
| ` | ||
| } | ||
| border: 1.5px solid rgba(0, 0, 0, 0.1); | ||
| ${({ theme, fromBot }): string => | ||
| fromBot | ||
| ? ` | ||
| border-radius: 20px 20px 20px 5px; | ||
| background-color: ${theme.colors["background"]}; | ||
| ` | ||
| : ` | ||
| border-radius: 20px 20px 5px 20px; | ||
| background-color: ${theme.colors["primary"]}; | ||
| ` | ||
| } | ||
| margin-bottom: 10px; | ||
| `; | ||
|
|
||
| export default TextBubble; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import React from 'react'; | ||
| import { Meta, Story } from '@storybook/react'; | ||
| import TypingDots, { ITypingDotsProps } from './TypingDots'; | ||
|
|
||
| export default { | ||
| title: 'Components/Typing Indicator Dots', | ||
| component: TypingDots | ||
| } as Meta; | ||
|
|
||
| export const Basic: Story<ITypingDotsProps> = () => ( | ||
| <TypingDots num={3} delayStep={0.1}/> | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import React from 'react'; | ||
| import styled from 'styled-components'; | ||
|
|
||
| export interface ITypingDotsProps { | ||
| num: number; | ||
| delayStep: number; | ||
| } | ||
|
|
||
| export const TypingDots = ({ num, delayStep, ...props }: ITypingDotsProps): React.ReactElement => { | ||
|
|
||
| let dots = []; | ||
|
|
||
| for (let i = 0; i < num; i ++) { | ||
| dots.push(<Dot delay={i * delayStep} />); | ||
| } | ||
|
Comment on lines
+11
to
+15
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Somethings wrong here |
||
|
|
||
| return ( | ||
| <DotContainer> | ||
| { dots } | ||
| </DotContainer> | ||
| ); | ||
| } | ||
|
|
||
| const DotContainer = styled.div` | ||
| margin: 10px; | ||
| display: flex; | ||
| flex-direction: row; | ||
| ` | ||
|
|
||
| const Dot = styled.div<{ delay: number }>` | ||
| width: 10px; | ||
| height: 10px; | ||
| border-radius: 50%; | ||
| margin: 10px 5px 10px 5px; | ||
| ${({ theme }): string => ` | ||
| background-color: ${theme.colors.border}; | ||
| `} | ||
| animation: bounce 0.5s ease-in-out infinite; | ||
| animation-delay: ${p => p.delay}s; | ||
|
|
||
| @keyframes bounce { | ||
| 10% { | ||
| transform: translateY(0); | ||
| } | ||
| 50% { | ||
| transform: translateY(-25%); | ||
| } | ||
| 90% { | ||
| transform: translateY(25%); | ||
| } | ||
| } | ||
| ` | ||
|
|
||
| export default TypingDots; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Frombot