Skip to content

Commit 056ad12

Browse files
authored
Merge pull request #199 from GetStream/emoji-picker
Emoji picker
2 parents 3f359a8 + 06d2318 commit 056ad12

28 files changed

+501
-29
lines changed
1.91 MB
Loading
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
---
2+
id: emoji-picker
3+
title: Emoji picker
4+
---
5+
6+
import Screenshot from "../assets/emoji-picker-screenshot.png";
7+
8+
The SDK doesn't have a built-in emoji picker, but it has support for providing your own template. This guide shows you how to add an emoji picker to your chat application.
9+
10+
## Create the emoji picker template
11+
12+
1. Create a new component in your application
13+
14+
```
15+
ng g c emoji-picker
16+
```
17+
18+
2. Install `@ctrl/ngx-emoji-mart`
19+
20+
You can use any emoji picker but this example will use [`@ctrl/ngx-emoji-mart `](https://www.npmjs.com/package/@ctrl/ngx-emoji-mart)
21+
22+
```
23+
npm install @ctrl/ngx-emoji-mart
24+
```
25+
26+
Import the emoji-mart stylesheet into your root stylesheet (for example `styles.scss`):
27+
28+
```
29+
@import "~@ctrl/ngx-emoji-mart/picker";
30+
```
31+
32+
Import the `PickerModule` into your `AppModule`:
33+
34+
```typescript
35+
import { NgModule } from "@angular/core";
36+
import { BrowserModule } from "@angular/platform-browser";
37+
import { TranslateModule } from "@ngx-translate/core";
38+
39+
import { AppComponent } from "./app.component";
40+
import {
41+
StreamChatModule,
42+
StreamAutocompleteTextareaModule,
43+
} from "stream-chat-angular";
44+
import { EmojiPickerComponent } from "./emoji-picker/emoji-picker.component";
45+
import { PickerModule } from "@ctrl/ngx-emoji-mart";
46+
47+
@NgModule({
48+
declarations: [AppComponent, EmojiPickerComponent],
49+
imports: [
50+
BrowserModule,
51+
TranslateModule.forRoot(),
52+
StreamAutocompleteTextareaModule,
53+
StreamChatModule,
54+
PickerModule,
55+
],
56+
providers: [],
57+
bootstrap: [AppComponent],
58+
})
59+
export class AppModule {}
60+
```
61+
62+
3. Component class
63+
64+
Your emoji picker component should have an input with the type `Subject<string>` to emit the selected emojis. This input will be provided by the [`MessageInput`](../components/message-input.mdx) component.
65+
66+
We also defined an `isOpened` property that tells if the emoji picker should be opened or closed.
67+
68+
```typescript
69+
import { Component, Input, OnInit } from "@angular/core";
70+
import { Subject } from "rxjs";
71+
72+
@Component({
73+
selector: "app-emoji-picker",
74+
templateUrl: "./emoji-picker.component.html",
75+
styleUrls: ["./emoji-picker.component.scss"],
76+
})
77+
export class EmojiPickerComponent implements OnInit {
78+
isOpened = false;
79+
@Input() emojiInput$: Subject<string> | undefined;
80+
81+
constructor() {}
82+
83+
ngOnInit(): void {}
84+
85+
emojiSelected(event: any) {
86+
this.emojiInput$?.next(event.emoji.native);
87+
}
88+
}
89+
```
90+
91+
4. Component template
92+
93+
We create a button that can be used to toggle the emoji picker.
94+
95+
The [`emoji-mart`](https://www.npmjs.com/package/@ctrl/ngx-emoji-mart) component has a lot of configuration options, feel free to explore those.
96+
97+
We set the `color` input to the `primary-color` defined in the [stream-chat-css theme](https://github.com/GetStream/stream-chat-css/blob/develop/src/styles/_variables.scss).
98+
99+
The [`ngIf`](https://angular.io/api/common/NgIf) directive is used to hide/show the emoji picker.
100+
101+
The `emojiSelect` event is fired when a user selects an emoji, we emit the selected emoji using the `emojiSelected` method.
102+
103+
```html
104+
<button (click)="isOpened = !isOpened">
105+
<svg
106+
viewBox="0 0 28 28"
107+
width="100%"
108+
preserveAspectRatio="xMinYMin"
109+
xmlns="http://www.w3.org/2000/svg"
110+
>
111+
<g clip-rule="evenodd" fill-rule="evenodd">
112+
<path
113+
d="M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z"
114+
></path>
115+
</g>
116+
</svg>
117+
</button>
118+
119+
<emoji-mart
120+
class="picker"
121+
color="var(--primary-color)"
122+
*ngIf="isOpened"
123+
title="Pick your emoji…"
124+
emoji="point_up"
125+
(emojiSelect)="emojiSelected($event)"
126+
></emoji-mart>
127+
```
128+
129+
5. Component styles
130+
131+
```scss
132+
button {
133+
background-color: transparent;
134+
border: none;
135+
cursor: pointer;
136+
padding: 0;
137+
}
138+
139+
.picker {
140+
position: absolute;
141+
bottom: 100%;
142+
left: 0;
143+
transform: scale(0.8);
144+
transform-origin: 0% 100%;
145+
}
146+
147+
@media only screen and (min-device-width: 1024px) {
148+
.picker {
149+
transform: scale(1);
150+
}
151+
}
152+
```
153+
154+
## Provide your custom template
155+
156+
Let's provide our custom emoji picker template to the [`MessageInput`](../components/message-input.mdx) component:
157+
158+
```html
159+
<div id="root">
160+
<stream-channel-list></stream-channel-list>
161+
<stream-channel>
162+
<stream-channel-header></stream-channel-header>
163+
<stream-message-list></stream-message-list>
164+
<stream-notification-list></stream-notification-list>
165+
<stream-message-input
166+
[emojiPickerTemplate]="emojiPickerTemplate"
167+
></stream-message-input>
168+
<stream-thread name="thread">
169+
<stream-message-list
170+
name="thread-message-list"
171+
mode="thread"
172+
></stream-message-list>
173+
<stream-message-input
174+
mode="thread"
175+
name="thread-message-input"
176+
[emojiPickerTemplate]="emojiPickerTemplate"
177+
></stream-message-input>
178+
</stream-thread>
179+
</stream-channel>
180+
</div>
181+
182+
<!-- The MessageInput component will provide the emojiInput$ to emit the selected emojis and insert them in the textarea -->
183+
<ng-template #emojiPickerTemplate let-emojiInput$="emojiInput$">
184+
<app-emoji-picker [emojiInput$]="emojiInput$"></app-emoji-picker>
185+
</ng-template>
186+
```
187+
188+
This is how our emoji picker looks like:
189+
190+
<img src={Screenshot} width="500" />

docusaurus/docs/Angular/components/message-input.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,14 @@ Determines if the message is being dispalyed in a channel or in a [thread](https
165165
| ------------------ | ------- |
166166
| `main` or `thread` | `main` |
167167

168+
### emojiPickerTemplate
169+
170+
You can add an emoji picker by [providing your own emoji picker template](../code-examples/emoji-picker.mdx)
171+
172+
| Type |
173+
| --------------------------------------------- |
174+
| `TemplateRef<{emojiInput$: Subject<string>}>` |
175+
168176
## Outputs
169177

170178
### messageUpdate

package-lock.json

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

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,15 @@
7979
"@angular/platform-browser": "~12.2.0",
8080
"@angular/platform-browser-dynamic": "~12.2.0",
8181
"@angular/router": "~12.2.0",
82+
"@ctrl/ngx-emoji-mart": "^6.2.0",
8283
"@ngx-translate/core": "^13.0.0",
8384
"@ngx-translate/http-loader": "^6.0.0",
84-
"@stream-io/stream-chat-css": "2.2.1",
85+
"@stream-io/stream-chat-css": "2.3.2",
8586
"@stream-io/transliterate": "^1.5.2",
8687
"angular-mentions": "^1.4.0",
8788
"dayjs": "^1.10.7",
8889
"dotenv": "^10.0.0",
90+
"emoji-regex": "^10.0.0",
8991
"pretty-bytes": "^5.6.0",
9092
"rxjs": "~6.6.0",
9193
"stream-chat": "^5.0.0",

projects/sample-app/src/app/app.component.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
<stream-channel-header></stream-channel-header>
55
<stream-message-list></stream-message-list>
66
<stream-notification-list></stream-notification-list>
7-
<stream-message-input></stream-message-input>
7+
<stream-message-input
8+
[emojiPickerTemplate]="emojiPickerTemplate"
9+
></stream-message-input>
810
<stream-thread name="thread">
911
<stream-message-list
1012
name="thread-message-list"
@@ -13,6 +15,7 @@
1315
<stream-message-input
1416
mode="thread"
1517
name="thread-message-input"
18+
[emojiPickerTemplate]="emojiPickerTemplate"
1619
></stream-message-input>
1720
</stream-thread>
1821
</stream-channel>
@@ -27,3 +30,7 @@
2730
<ng-template #mentionTemplate let-item="item">
2831
{{ item.autocompleteLabel }}
2932
</ng-template>
33+
34+
<ng-template #emojiPickerTemplate let-emojiInput$="emojiInput$">
35+
<app-emoji-picker [emojiInput$]="emojiInput$"></app-emoji-picker>
36+
</ng-template>

0 commit comments

Comments
 (0)