whatsapp-ui-react 0.0.4 → 0.0.6

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/README.md CHANGED
@@ -20,6 +20,23 @@ npm install whatsapp-ui-react
20
20
 
21
21
  **Peer dependencies:** React 18+ and TailwindCSS v4.
22
22
 
23
+ ## Setup
24
+
25
+ ```css
26
+ /* global.css */
27
+ @import 'tailwindcss';
28
+ @import 'whatsapp-ui-react/css/natural.css';
29
+ @import 'whatsapp-ui-react/css/preset.css';
30
+ ```
31
+
32
+ Available themes: `natural` (default), `ocean`, `forest`, `rose`.
33
+
34
+ Use `theme="dark"` on `<Chat>` to switch to the dark variant of the loaded theme:
35
+
36
+ ```tsx
37
+ <Chat theme="dark" ... />
38
+ ```
39
+
23
40
  ## Usage
24
41
 
25
42
  ### Chat
@@ -156,25 +173,29 @@ Set `locked` to disable sending while still allowing typing:
156
173
 
157
174
  ## `<Chat>` props
158
175
 
159
- | Prop | Type | Default | Description |
160
- | -------------------- | --------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
161
- | `name` | `string` | | Contact or group name |
162
- | `avatarUrl` | `'online' \| 'typeing' \| string` | | Avatar image URL |
163
- | `subtitle` | `string` | | Status text below the name |
164
- | `children` | `ReactNode` | | Static content rendered at the top of the message area. Typically a `<History>` component. |
165
- | `showInputfield` | `boolean` | `true` | Show / hide the input bar |
166
- | `locked` | `boolean` | `false` | Allow typing but disable sending |
167
- | `inputPlaceholder` | `string` | `'Enter a message.'` | Textarea placeholder |
168
- | `inputValue` | `string` | | Controlled input value (use with `onInputValueChange`) |
169
- | `defaultInputValue` | `string` | | Uncontrolled initial value (internal state managed by component) |
170
- | `onInputValueChange` | `(v: string) => void` | | Called on every keystroke |
171
- | `onSendMessage` | `(v: string) => void` | | Called when a message is sent |
172
- | `onReply` | `ReactNode` | | `<Reply>` rules rendered inside the chat context |
173
- | `background` | `string \| null` | background image | Message area background. Hex color string for a solid fill; `null` or `'none'` for plain `#0a0a0a`; omit to use the default tiled image. |
174
- | `onEmojiClick` | `() => void` | | Emoji button click handler |
175
- | `onAttachClick` | `() => void` | | Attach button click handler |
176
- | `onCameraClick` | `() => void` | | Camera button click handler |
177
- | `onMicClick` | `() => void` | | Mic button click handler |
176
+ | Prop | Type | Default | Description |
177
+ | -------------------- | -------------------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
178
+ | `name` | `string` | | Contact or group name |
179
+ | `avatarUrl` | `string` | | Avatar image URL |
180
+ | `subtitle` | `string` | | Status text below the name |
181
+ | `children` | `ReactNode` | | Static content rendered at the top of the message area. Typically a `<History>` component. |
182
+ | `showInputfield` | `boolean` | `true` | Show / hide the input bar |
183
+ | `locked` | `boolean` | `false` | Allow typing but disable sending |
184
+ | `inputPlaceholder` | `string` | `'Enter a message.'` | Textarea placeholder |
185
+ | `inputValue` | `string` | | Controlled input value (use with `onInputValueChange`) |
186
+ | `defaultInputValue` | `string` | | Uncontrolled initial value (internal state managed by component) |
187
+ | `onInputValueChange` | `(v: string) => void` | | Called on every keystroke |
188
+ | `onSendMessage` | `(v: string) => void` | | Called when a message is sent |
189
+ | `onReply` | `ReactNode` | | `<Reply>` rules rendered inside the chat context |
190
+ | `background` | `string \| null` | background image | Message area background. Hex color string for a solid fill; `null` or `'none'` for plain `#0a0a0a`; omit to use the default tiled image. |
191
+ | `onEmojiClick` | `() => void` | | Emoji button click handler |
192
+ | `onAttachClick` | `() => void` | | Attach button click handler |
193
+ | `onCameraClick` | `() => void` | | Camera button click handler |
194
+ | `onMicClick` | `() => void` | | Mic button click handler |
195
+ | `theme` | `'dark' \| 'light'` | `'light'` | Adds the `dark` class to the root element to activate the dark variant of the loaded colour scheme |
196
+ | `colorScheme` | `'natural' \| 'ocean' \| 'forest' \| 'rose'` | | Colour palette applied via `data-wa-color`. Requires the matching CSS file to be imported. Falls back to global `@theme` when omitted. |
197
+ | `width` | `number \| string` | | Set Chat witdh |
198
+ | `height` | `number \| string` | | Set Chat height |
178
199
 
179
200
  ## License
180
201
 
package/css/forest.css ADDED
@@ -0,0 +1,37 @@
1
+ [data-wa-color='forest'] {
2
+ --color-wa-bg: #eaf3ec;
3
+ --color-wa-bubble-out: #c8e6c9;
4
+ --color-wa-bubble-in: #ffffff;
5
+ --color-wa-avatar: #b8daba;
6
+ --color-wa-input: #ffffff;
7
+ --color-wa-divider: #d0e8d2;
8
+ --color-wa-text: #1b3a22;
9
+ --color-wa-text-secondary: #4a7a52;
10
+ --color-wa-text-body: #2d5c36;
11
+ --color-wa-icon: #3d6e45;
12
+ --color-wa-teal: #2e7d32;
13
+ --color-wa-send: #388e3c;
14
+ --color-wa-hover: #2e7d32;
15
+ --color-wa-scrollbar: rgba(46, 125, 50, 0.15);
16
+ --color-wa-scrollbar-thumb: rgba(46, 125, 50, 0.25);
17
+ --color-wa-scrollbar-thumb-hover: rgba(46, 125, 50, 0.4);
18
+ }
19
+
20
+ [data-wa-color='forest'].dark {
21
+ --color-wa-bg: #0d1f10;
22
+ --color-wa-bubble-out: #1b3d1e;
23
+ --color-wa-bubble-in: #162718;
24
+ --color-wa-avatar: #1e3c22;
25
+ --color-wa-input: #131f14;
26
+ --color-wa-divider: #0f1a10;
27
+ --color-wa-text: #d4eed6;
28
+ --color-wa-text-secondary: #72b876;
29
+ --color-wa-text-body: #a8d8ab;
30
+ --color-wa-icon: #80c484;
31
+ --color-wa-teal: #66bb6a;
32
+ --color-wa-send: #4caf50;
33
+ --color-wa-hover: #43a047;
34
+ --color-wa-scrollbar: rgba(102, 187, 106, 0.1);
35
+ --color-wa-scrollbar-thumb: rgba(102, 187, 106, 0.2);
36
+ --color-wa-scrollbar-thumb-hover: rgba(102, 187, 106, 0.35);
37
+ }
@@ -0,0 +1,75 @@
1
+ @theme {
2
+ --color-wa-bg: #f0f2f5;
3
+ --color-wa-bubble-out: #d9fdd3;
4
+ --color-wa-bubble-in: #ffffff;
5
+ --color-wa-avatar: #dfe5e7;
6
+ --color-wa-input: #ffffff;
7
+ --color-wa-divider: #e9edef;
8
+ --color-wa-text: #111b21;
9
+ --color-wa-text-secondary: #667781;
10
+ --color-wa-text-body: #3b4a54;
11
+ --color-wa-icon: #54656f;
12
+ --color-wa-teal: #0a7040;
13
+ --color-wa-send: #00a884;
14
+ --color-wa-hover: #008f72;
15
+ --color-wa-scrollbar: rgba(0, 0, 0, 0.1);
16
+ --color-wa-scrollbar-thumb: rgba(0, 0, 0, 0.18);
17
+ --color-wa-scrollbar-thumb-hover: rgba(0, 0, 0, 0.3);
18
+ }
19
+
20
+ .dark {
21
+ --color-wa-bg: #161717;
22
+ --color-wa-bubble-out: #144d37;
23
+ --color-wa-bubble-in: #202c33;
24
+ --color-wa-avatar: #2a3942;
25
+ --color-wa-input: #242626;
26
+ --color-wa-divider: #182229;
27
+ --color-wa-text: #e9edef;
28
+ --color-wa-text-secondary: #8696a0;
29
+ --color-wa-text-body: #d1d7db;
30
+ --color-wa-icon: #aebac1;
31
+ --color-wa-teal: #53bdeb;
32
+ --color-wa-send: #21c063;
33
+ --color-wa-hover: #00a884;
34
+ --color-wa-scrollbar: rgba(255, 255, 255, 0.1);
35
+ --color-wa-scrollbar-thumb: rgba(255, 255, 255, 0.18);
36
+ --color-wa-scrollbar-thumb-hover: rgba(255, 255, 255, 0.3);
37
+ }
38
+
39
+ [data-wa-color='natural'] {
40
+ --color-wa-bg: #f0f2f5;
41
+ --color-wa-bubble-out: #d9fdd3;
42
+ --color-wa-bubble-in: #ffffff;
43
+ --color-wa-avatar: #dfe5e7;
44
+ --color-wa-input: #ffffff;
45
+ --color-wa-divider: #e9edef;
46
+ --color-wa-text: #111b21;
47
+ --color-wa-text-secondary: #667781;
48
+ --color-wa-text-body: #3b4a54;
49
+ --color-wa-icon: #54656f;
50
+ --color-wa-teal: #0a7040;
51
+ --color-wa-send: #00a884;
52
+ --color-wa-hover: #008f72;
53
+ --color-wa-scrollbar: rgba(0, 0, 0, 0.1);
54
+ --color-wa-scrollbar-thumb: rgba(0, 0, 0, 0.18);
55
+ --color-wa-scrollbar-thumb-hover: rgba(0, 0, 0, 0.3);
56
+ }
57
+
58
+ [data-wa-color='natural'].dark {
59
+ --color-wa-bg: #161717;
60
+ --color-wa-bubble-out: #144d37;
61
+ --color-wa-bubble-in: #202c33;
62
+ --color-wa-avatar: #2a3942;
63
+ --color-wa-input: #242626;
64
+ --color-wa-divider: #182229;
65
+ --color-wa-text: #e9edef;
66
+ --color-wa-text-secondary: #8696a0;
67
+ --color-wa-text-body: #d1d7db;
68
+ --color-wa-icon: #aebac1;
69
+ --color-wa-teal: #53bdeb;
70
+ --color-wa-send: #21c063;
71
+ --color-wa-hover: #00a884;
72
+ --color-wa-scrollbar: rgba(255, 255, 255, 0.1);
73
+ --color-wa-scrollbar-thumb: rgba(255, 255, 255, 0.18);
74
+ --color-wa-scrollbar-thumb-hover: rgba(255, 255, 255, 0.3);
75
+ }
package/css/ocean.css ADDED
@@ -0,0 +1,37 @@
1
+ [data-wa-color='ocean'] {
2
+ --color-wa-bg: #e8f4f8;
3
+ --color-wa-bubble-out: #c8e6f5;
4
+ --color-wa-bubble-in: #ffffff;
5
+ --color-wa-avatar: #b2d8ea;
6
+ --color-wa-input: #ffffff;
7
+ --color-wa-divider: #cce5f0;
8
+ --color-wa-text: #0d2b3e;
9
+ --color-wa-text-secondary: #4a7a96;
10
+ --color-wa-text-body: #1a4a6b;
11
+ --color-wa-icon: #3a7a9c;
12
+ --color-wa-teal: #0077a8;
13
+ --color-wa-send: #0095c8;
14
+ --color-wa-hover: #0082b3;
15
+ --color-wa-scrollbar: rgba(0, 119, 168, 0.15);
16
+ --color-wa-scrollbar-thumb: rgba(0, 119, 168, 0.25);
17
+ --color-wa-scrollbar-thumb-hover: rgba(0, 119, 168, 0.4);
18
+ }
19
+
20
+ [data-wa-color='ocean'].dark {
21
+ --color-wa-bg: #0a1a24;
22
+ --color-wa-bubble-out: #0d3a52;
23
+ --color-wa-bubble-in: #112233;
24
+ --color-wa-avatar: #1a3a4e;
25
+ --color-wa-input: #0f2030;
26
+ --color-wa-divider: #0c1e2c;
27
+ --color-wa-text: #d0eaf8;
28
+ --color-wa-text-secondary: #6aaac8;
29
+ --color-wa-text-body: #a8d4ec;
30
+ --color-wa-icon: #7abcd6;
31
+ --color-wa-teal: #4dc4f0;
32
+ --color-wa-send: #1ab0e8;
33
+ --color-wa-hover: #00a8d8;
34
+ --color-wa-scrollbar: rgba(77, 196, 240, 0.1);
35
+ --color-wa-scrollbar-thumb: rgba(77, 196, 240, 0.2);
36
+ --color-wa-scrollbar-thumb-hover: rgba(77, 196, 240, 0.35);
37
+ }
package/css/preset.css ADDED
@@ -0,0 +1,23 @@
1
+ @source '../dist';
2
+
3
+ .wa-scrollbar {
4
+ scrollbar-width: thin;
5
+ scrollbar-color: var(--color-wa-scrollbar) transparent;
6
+ }
7
+
8
+ .wa-scrollbar::-webkit-scrollbar {
9
+ width: 0.25rem;
10
+ }
11
+
12
+ .wa-scrollbar::-webkit-scrollbar-track {
13
+ background-color: transparent;
14
+ }
15
+
16
+ .wa-scrollbar::-webkit-scrollbar-thumb {
17
+ background-color: var(--color-wa-scrollbar-thumb);
18
+ border-radius: 9999px;
19
+ }
20
+
21
+ .wa-scrollbar::-webkit-scrollbar-thumb:hover {
22
+ background-color: var(--color-wa-scrollbar-thumb-hover);
23
+ }
package/css/rose.css ADDED
@@ -0,0 +1,37 @@
1
+ [data-wa-color='rose'] {
2
+ --color-wa-bg: #fdf0f3;
3
+ --color-wa-bubble-out: #fadadf;
4
+ --color-wa-bubble-in: #ffffff;
5
+ --color-wa-avatar: #f5c6cf;
6
+ --color-wa-input: #ffffff;
7
+ --color-wa-divider: #f8dde2;
8
+ --color-wa-text: #3a0d18;
9
+ --color-wa-text-secondary: #9c4a5c;
10
+ --color-wa-text-body: #5c1a2c;
11
+ --color-wa-icon: #b05468;
12
+ --color-wa-teal: #c2185b;
13
+ --color-wa-send: #e91e63;
14
+ --color-wa-hover: #c2185b;
15
+ --color-wa-scrollbar: rgba(194, 24, 91, 0.15);
16
+ --color-wa-scrollbar-thumb: rgba(194, 24, 91, 0.25);
17
+ --color-wa-scrollbar-thumb-hover: rgba(194, 24, 91, 0.4);
18
+ }
19
+
20
+ [data-wa-color='rose'].dark {
21
+ --color-wa-bg: #1c0a10;
22
+ --color-wa-bubble-out: #3d1020;
23
+ --color-wa-bubble-in: #2a0e18;
24
+ --color-wa-avatar: #3a1020;
25
+ --color-wa-input: #1e0c12;
26
+ --color-wa-divider: #160810;
27
+ --color-wa-text: #fad0da;
28
+ --color-wa-text-secondary: #d4788c;
29
+ --color-wa-text-body: #f0aab8;
30
+ --color-wa-icon: #e08898;
31
+ --color-wa-teal: #f06292;
32
+ --color-wa-send: #ec407a;
33
+ --color-wa-hover: #e91e63;
34
+ --color-wa-scrollbar: rgba(240, 98, 146, 0.1);
35
+ --color-wa-scrollbar-thumb: rgba(240, 98, 146, 0.2);
36
+ --color-wa-scrollbar-thumb-hover: rgba(240, 98, 146, 0.35);
37
+ }
@@ -59,6 +59,24 @@ export interface ChatProps {
59
59
  onCameraClick?: () => void;
60
60
  /** Handler for the microphone button in the input bar. */
61
61
  onMicClick?: () => void;
62
+ /**
63
+ * Visual colour theme for the chat window.
64
+ * - `'light'` (default): WhatsApp light style.
65
+ * - `'dark'`: WhatsApp dark style.
66
+ */
67
+ theme?: 'dark' | 'light';
68
+ /**
69
+ * Colour scheme applied to the chat window. Requires the matching CSS file to be imported.
70
+ * - `'natural'` (default): Classic WhatsApp green.
71
+ * - `'ocean'`: Blue-teal palette.
72
+ * - `'forest'`: Deep green palette.
73
+ * - `'rose'`: Pink-rose palette.
74
+ */
75
+ colorScheme?: 'natural' | 'ocean' | 'forest' | 'rose';
76
+ /** Explicit width applied as an inline style (e.g. `400` or `'100%'`). */
77
+ width?: number | string;
78
+ /** Explicit height applied as an inline style (e.g. `600` or `'100%'`). */
79
+ height?: number | string;
62
80
  }
63
81
  /**
64
82
  * Top-level chat component. Manages the message list state and composes
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Chat.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAKnD,2DAA2D;AAC3D,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,UAAU,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAC5E;AAED,4CAA4C;AAC5C,MAAM,WAAW,SAAS;IACxB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAA;IAC1C;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,EAAE,CAAA;IACjC,iEAAiE;IACjE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,iIAAiI;IACjI,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5C,sHAAsH;IACtH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,4GAA4G;IAC5G,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAC1B,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAC1B,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;CACxB;AAED;;;;;;GAMG;AACH,QAAA,MAAM,IAAI,8EAwIR,CAAA;AAEF,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/Chat.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAKnD,2DAA2D;AAC3D,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,UAAU,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAC5E;AAED,4CAA4C;AAC5C,MAAM,WAAW,SAAS;IACxB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAA;IAC1C;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,EAAE,CAAA;IACjC,iEAAiE;IACjE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,iIAAiI;IACjI,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,qGAAqG;IACrG,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5C,sHAAsH;IACtH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,4GAA4G;IAC5G,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAC1B,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;IAC1B,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACxB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACrD,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACzB;AAED;;;;;;GAMG;AACH,QAAA,MAAM,IAAI,8EAsJR,CAAA;AAEF,OAAO,EAAE,IAAI,EAAE,CAAA"}