@ethora/chat-component 26.5.1 → 26.5.3

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
@@ -355,7 +355,8 @@ Below is a grouped reference for all `config` options.
355
355
  | `headerLogo` | `string \| React.ReactElement` | Custom logo in header. |
356
356
  | `headerMenu` | `() => void` | Custom menu handler. |
357
357
  | `headerChatMenu` | `() => void` | Custom room header menu handler. |
358
- | `colors` | `{ primary; secondary; icons? }` | Theme colours. `primary` also drives icon colours and the message sender name; set `colors.icons` to give icons (attach, mic, send, file, empty-state) a colour independent of `primary`. |
358
+ | `colors` | `{ primary; secondary; icons?; ownMessageBackground?; otherMessageBackground?; inputBackground? }` | Theme colours. `primary` drives icon colours and the sender name. `icons` themes every accent icon/icon-button (attach, mic, active send, new-chat, header, empty-state) — defaults to `primary`, so set a *distinct* value to decouple. `ownMessageBackground`/`otherMessageBackground`/`inputBackground` recolour the message bubbles and input bar. |
359
+ | `backgroundChat` | `{ color?; image? }` | Background colour and/or image for the messages area. (`image` as a string URL; pass an object URL for a `File`.) |
359
360
  | `typography` | `TypographyConfig` | Font family + size for the chat UI: `fontFamily` (or just `googleFontsFamily`) is applied across all chat text incl. messages and sender names; `fontSize` (px) scales message text, sender names, timestamps, inputs, room names and badges. Plus loaders (`googleFontsUrl`/`fontFaces`) and weight tokens. |
360
361
  | `fallbackScreens` | `{ noUser?; noConnection?; noRoom? }` | Replace the built-in screens (Ethora login form, "Connecting...", empty room state) with your own text or React nodes. A plain string is rendered as centered text. |
361
362
  | `hiddenRooms` | `{ titles?: string[]; jids?: string[] }` | Hide specific rooms from the room list and unread counters (e.g. `{ titles: ['Main chat'] }` to suppress the auto-created default room). |
@@ -3,6 +3,7 @@ interface SearchInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
3
3
  icon?: React.ReactNode;
4
4
  animated?: boolean;
5
5
  direction?: 'left' | 'right';
6
+ colorBg?: string;
6
7
  }
7
8
  declare const SearchInput: React.FC<SearchInputProps>;
8
9
  export { SearchInput };
@@ -2,6 +2,7 @@ import { default as React } from 'react';
2
2
  interface StyledInputProps {
3
3
  label?: string;
4
4
  color?: string;
5
+ colorBg?: string;
5
6
  helperText?: string;
6
7
  error?: boolean;
7
8
  [key: string]: any;
@@ -2,6 +2,7 @@ export declare const InputContainer: import('styled-components/dist/types').ISty
2
2
  export declare const MessageInputContainer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
3
3
  export declare const MessageInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, {
4
4
  $color?: string;
5
+ $colorBg?: string;
5
6
  }>> & string;
6
7
  export declare const HiddenFileInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
7
8
  export declare const Timer: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
@@ -11,13 +12,17 @@ export declare const FilePreviewContainer: import('styled-components/dist/types'
11
12
  export declare const FilePreview: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
12
13
  export declare const ImagePreview: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, never>> & string;
13
14
  export declare const VideoPreview: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').VideoHTMLAttributes<HTMLVideoElement>, HTMLVideoElement>, never>> & string;
14
- export declare const StyledInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, never>> & string;
15
+ export declare const StyledInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, {
16
+ $colorBg?: string;
17
+ }>> & string;
15
18
  export declare const TextareaWrapper: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
16
19
  $dynamicHeight?: number;
17
20
  $color?: string;
18
21
  $isFocused?: boolean;
22
+ $colorBg?: string;
19
23
  }>> & string;
20
24
  export declare const TextareaInput: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Substitute<import('react').DetailedHTMLProps<import('react').TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, {
21
25
  $dynamicHeight?: number;
22
26
  $color?: string;
27
+ $colorBg?: string;
23
28
  }>> & string;
@@ -11,13 +11,15 @@ export declare const resolveIconColor: (config?: Pick<IConfig, "colors"> | null)
11
11
  /** CSS variable read by the chat's chrome icons as their default colour. */
12
12
  export declare const ICON_COLOR_VAR = "--ethora-icon-color";
13
13
  /**
14
- * Publish the resolved icon colour on the `--ethora-icon-color` CSS variable.
15
- * Chrome icons default their `fill`/`stroke` to `var(--ethora-icon-color, …)`,
16
- * so setting this themes every neutral icon at once without touching call
17
- * sites. When neither `colors.icons` nor `colors.primary` is set, the variable
18
- * is removed and each icon falls back to its own literal default.
14
+ * Publish host theme colours as CSS variables that the chat's styled
15
+ * components read with their historical defaults as fallbacks. Covers icons,
16
+ * own/other message bubble backgrounds, the input bar, and the chat
17
+ * background (`backgroundChat.color` / `.image`).
19
18
  *
20
- * Semantic icons (destructive red, status ticks, brand) intentionally keep
21
- * their literal colours and ignore this variable. SSR-safe (no-op without DOM).
19
+ * Setting nothing keeps the chat pixel-identical (each var resolves to its
20
+ * literal fallback). SSR-safe (no-op without DOM). Semantic icons (destructive
21
+ * red, status ticks, brand) intentionally ignore the icon variable.
22
22
  */
23
- export declare const applyIconColor: (config?: Pick<IConfig, "colors"> | null) => void;
23
+ export declare const applyThemeColors: (config?: Pick<IConfig, "colors" | "backgroundChat"> | null) => void;
24
+ /** @deprecated use {@link applyThemeColors}; kept for backwards compatibility. */
25
+ export declare const applyIconColor: (config?: Pick<IConfig, "colors" | "backgroundChat"> | null) => void;
@@ -11,10 +11,12 @@ interface UnreadMessagesStats {
11
11
  displayTotal: string;
12
12
  displayByRoom: UnreadMessagesDisplayMap;
13
13
  /**
14
- * True while the unread counts are not trustworthy yet — i.e. until the
15
- * room list has been populated at least once (from cache or the API), or
16
- * until the first rooms load cycle finishes for an account with no rooms.
17
- * Lets consumers show a spinner/skeleton instead of a misleading "0".
14
+ * True while the unread counts are still settling on first load. Instead of
15
+ * surfacing the count as it ramps up (0 → 2 → 3 … as history backfills), the
16
+ * hook keeps `loading` true until the per-room counts have stopped changing
17
+ * for a short window, then latches it to false. After that first settle,
18
+ * live message increments update the counts immediately and never flip
19
+ * `loading` back on — it's a first-load indicator, not a per-update one.
18
20
  */
19
21
  loading: boolean;
20
22
  /** Alias of `loading` — matches the React Native SDK field name. */