Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/vite/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ if (!apiKey) {
const options: ChannelOptions = {
presence: true,
state: true,
limit: 10,
};

const sort: ChannelSort = { last_message_at: -1, updated_at: -1 };
Expand Down
90 changes: 43 additions & 47 deletions examples/vite/src/AppSettings/ActionsMenu/ActionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,53 +63,7 @@ const ActionsMenuButton = ({
</div>
);

export const ActionsMenu = ({ iconOnly = true }: { iconOnly?: boolean }) => (
<ActionsMenuInner iconOnly={iconOnly} />
);

function TriggerNotificationAction({ onTrigger }: { onTrigger: () => void }) {
const { closeMenu } = useContextMenuContext();

return (
<ContextMenuButton
label='Trigger Notification'
onClick={() => {
closeMenu();
onTrigger();
}}
/>
);
}

function TriggerAttachmentAction({ onTrigger }: { onTrigger: () => void }) {
const { closeMenu } = useContextMenuContext();

return (
<ContextMenuButton
label='Message Composer'
onClick={() => {
closeMenu();
onTrigger();
}}
/>
);
}

function TriggerWebSocketEventAction({ onTrigger }: { onTrigger: () => void }) {
const { closeMenu } = useContextMenuContext();

return (
<ContextMenuButton
label='Trigger WS Event'
onClick={() => {
closeMenu();
onTrigger();
}}
/>
);
}

const ActionsMenuInner = ({ iconOnly }: { iconOnly: boolean }) => {
export const ActionsMenu = ({ iconOnly = true }: { iconOnly?: boolean }) => {
const [menuButtonElement, setMenuButtonElement] = useState<HTMLButtonElement | null>(
null,
);
Expand Down Expand Up @@ -156,3 +110,45 @@ const ActionsMenuInner = ({ iconOnly }: { iconOnly: boolean }) => {
</div>
);
};

function TriggerNotificationAction({ onTrigger }: { onTrigger: () => void }) {
const { closeMenu } = useContextMenuContext();

return (
<ContextMenuButton
label='Trigger Notification'
onClick={() => {
closeMenu();
onTrigger();
}}
/>
);
}

function TriggerAttachmentAction({ onTrigger }: { onTrigger: () => void }) {
const { closeMenu } = useContextMenuContext();

return (
<ContextMenuButton
label='Message Composer'
onClick={() => {
closeMenu();
onTrigger();
}}
/>
);
}

function TriggerWebSocketEventAction({ onTrigger }: { onTrigger: () => void }) {
const { closeMenu } = useContextMenuContext();

return (
<ContextMenuButton
label='Trigger WS Event'
onClick={() => {
closeMenu();
onTrigger();
}}
/>
);
}
14 changes: 13 additions & 1 deletion examples/vite/src/AppSettings/AppSettings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@
gap: 16px;

.app__settings-group_button {
color: var(--str-chat__text-secondary);
color: var(--str-chat__text-tertiary);

.str-chat__icon--bolt,
.str-chat__icon--moon,
.str-chat__icon--sun {
fill: none;
stroke: currentColor;
stroke-width: 1.5px;
}

&.app__settings-group_button--toggle[aria-checked='true'] {
color: var(--str-chat__text-on-accent);
}
}
}

Expand Down
26 changes: 15 additions & 11 deletions examples/vite/src/AppSettings/AppSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { type ComponentType, useState } from 'react';
import {
Button,
ChatViewSelectorButton,
Expand All @@ -7,7 +7,6 @@ import {
IconEmoji,
IconMessageBubble,
} from 'stream-chat-react';
import { type ComponentType, useState } from 'react';

import { ActionsMenu } from './ActionsMenu';
import { GeneralTab } from './tabs/General';
Expand All @@ -16,7 +15,13 @@ import { NotificationsTab } from './tabs/Notifications';
import { ReactionsTab } from './tabs/Reactions';
import { SidebarTab } from './tabs/Sidebar';
import { appSettingsStore, useAppSettingsState } from './state';
import { IconGear, IconLightBulb, IconSidebar, IconTextDirection } from '../icons.tsx';
import {
IconGear,
IconMoon,
IconSidebar,
IconSun,
IconTextDirection,
} from '../icons.tsx';

type TabId = 'general' | 'messageActions' | 'notifications' | 'reactions' | 'sidebar';

Expand All @@ -34,24 +39,23 @@ const SidebarThemeToggle = ({ iconOnly = true }: { iconOnly?: boolean }) => {
theme: { mode },
} = useAppSettingsState();
const nextMode = mode === 'dark' ? 'light' : 'dark';

const Icon = mode === 'dark' ? IconSun : IconMoon;
return (
<ChatViewSelectorButton
aria-checked={mode === 'dark'}
aria-label={`Switch to ${nextMode} mode`}
aria-selected={mode === 'dark'}
className='app__settings-group_button'
className='app__settings-group_button app__settings-group_button--toggle'
iconOnly={iconOnly}
Icon={IconLightBulb}
Icon={Icon}
isActive={mode === 'dark'}
onClick={() =>
appSettingsStore.partialNext({
theme: { ...theme, mode: nextMode },
})
}
role='switch'
style={{ color: mode === 'dark' ? '#facc15' : undefined }}
text={mode === 'dark' ? 'Dark mode' : 'Light mode'}
text={mode === 'dark' ? 'Light mode' : 'Dark mode'}
/>
);
};
Expand All @@ -68,7 +72,7 @@ const SidebarRtlToggle = ({ iconOnly = true }: { iconOnly?: boolean }) => {
aria-checked={isRtl}
aria-label={`Switch to ${isRtl ? 'LTR' : 'RTL'} direction`}
aria-selected={isRtl}
className='app__settings-group_button'
className='app__settings-group_button app__settings-group_button--toggle'
iconOnly={iconOnly}
Icon={IconTextDirection}
isActive={isRtl}
Expand All @@ -89,9 +93,9 @@ export const AppSettings = ({ iconOnly = true }: { iconOnly?: boolean }) => {

return (
<div className='app__settings-group'>
<ActionsMenu iconOnly={iconOnly} />
<SidebarThemeToggle iconOnly={iconOnly} />
<SidebarRtlToggle iconOnly={iconOnly} />
<SidebarThemeToggle iconOnly={iconOnly} />
<ActionsMenu iconOnly={iconOnly} />
<ChatViewSelectorButton
className='app__settings-group_button'
iconOnly={iconOnly}
Expand Down
32 changes: 23 additions & 9 deletions examples/vite/src/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,33 @@ export const IconGear = createIcon(
{ viewBox: '0 0 16 16' },
);

export const IconLightBulb = createIcon(
'IconLightBulb',
<>
<path d='M12.2328 6.66736C12.2328 4.32904 10.3378 2.43302 7.99945 2.43298C5.66113 2.43298 3.76508 4.32901 3.76508 6.66736C3.76509 8.03465 4.4128 9.25078 5.42035 10.0258C5.44202 10.0425 5.46556 10.0594 5.48871 10.0765C6.00058 10.4543 6.43207 11.0657 6.43207 11.8119V12.6664C6.43232 13.5319 7.13392 14.2338 7.99945 14.2338C8.86496 14.2337 9.56658 13.5318 9.56683 12.6664V11.8119C9.56683 11.0657 9.99831 10.4543 10.5102 10.0765C10.5335 10.0593 10.556 10.0424 10.5776 10.0258L10.7631 9.87537C11.6644 9.09822 12.2328 7.94919 12.2328 6.66736ZM13.433 6.66736C13.433 8.42299 12.6002 9.98457 11.31 10.9769C11.2807 10.9995 11.2513 11.0205 11.2231 11.0414C10.9238 11.2623 10.767 11.55 10.767 11.8119V12.6664C10.7668 14.1946 9.5277 15.4329 7.99945 15.433C6.47116 15.433 5.23213 14.1946 5.23187 12.6664V11.8119C5.23187 11.5827 5.11171 11.3346 4.88129 11.1283L4.77582 11.0424L4.6889 10.9769C3.39867 9.98457 2.56587 8.42301 2.56586 6.66736C2.56586 3.66628 4.99838 1.23376 7.99945 1.23376C11.0005 1.2338 13.433 3.6663 13.433 6.66736Z' />
<path d='M10.1669 11.2338C10.4982 11.2338 10.7665 11.502 10.7665 11.8334C10.7665 12.1647 10.4982 12.433 10.1669 12.433H5.83193C5.50056 12.433 5.23232 12.1647 5.23232 11.8334C5.23232 11.502 5.50056 11.2338 5.83193 11.2338H10.1669Z' />
</>,
{ viewBox: '0 0 16 16' },
export const IconMoon = createIcon(
'IconMoon',
<path
d='M8.44608 2.19604C8.05317 3.4961 8.0203 4.87838 8.35097 6.19564C8.68165 7.5129 9.36348 8.71577 10.3238 9.67611C11.2842 10.6365 12.487 11.3183 13.8043 11.649C15.1215 11.9796 16.5038 11.9468 17.8039 11.5539C17.427 12.7931 16.7356 13.9136 15.797 14.8062C14.8584 15.6988 13.7047 16.3331 12.4481 16.6474C11.1916 16.9617 9.87504 16.9452 8.62676 16.5995C7.37848 16.2538 6.24101 15.5907 5.32512 14.6748C4.40923 13.7589 3.74615 12.6215 3.40046 11.3732C3.05477 10.1249 3.03826 8.80836 3.35252 7.5518C3.66679 6.29524 4.30113 5.14149 5.19375 4.20292C6.08638 3.26434 7.20686 2.57294 8.44608 2.19604Z'
stroke-linecap='round'
stroke-linejoin='round'
/>,
);

export const IconSun = createIcon(
'IconSun',
<path
d='M10 3.125V1.25M5 5L3.75 3.75M5 15L3.75 16.25M15 5L16.25 3.75M15 15L16.25 16.25M3.125 10H1.25M10 16.875V18.75M16.875 10H18.75M14.375 10C14.375 12.4162 12.4162 14.375 10 14.375C7.58375 14.375 5.625 12.4162 5.625 10C5.625 7.58375 7.58375 5.625 10 5.625C12.4162 5.625 14.375 7.58375 14.375 10Z'
stroke-linecap='round'
stroke-linejoin='round'
/>,
);

export const IconTextDirection = createIcon(
'IconTextDirection',
<path d='M9.5 2H12.5C12.7761 2 13 2.22386 13 2.5C13 2.77614 12.7761 3 12.5 3H11V12.5C11 12.7761 10.7761 13 10.5 13C10.2239 13 10 12.7761 10 12.5V3H9V12.5C9 12.7761 8.77614 13 8.5 13C8.22386 13 8 12.7761 8 12.5V8H7.5C5.567 8 4 6.433 4 4.5C4 2.567 5.567 1 7.5 1H9.5V2ZM8 3H7.5C6.11929 3 5 4.11929 5 4.5C5 5.88071 6.11929 7 7.5 7H8V3ZM3.85355 13.8536C3.65829 14.0488 3.34171 14.0488 3.14645 13.8536L1.14645 11.8536C0.951184 11.6583 0.951184 11.3417 1.14645 11.1464C1.34171 10.9512 1.65829 10.9512 1.85355 11.1464L3 12.2929V9.5C3 9.22386 3.22386 9 3.5 9C3.77614 9 4 9.22386 4 9.5V12.2929L5.14645 11.1464C5.34171 10.9512 5.65829 10.9512 5.85355 11.1464C6.04882 11.3417 6.04882 11.6583 5.85355 11.8536L3.85355 13.8536Z' />,
{ viewBox: '0 0 16 16' },
<path
d='M13.75 16.25L16.25 13.75L13.75 11.25M16.25 13.75H3.75M6.25 3.75L3.75 6.25L6.25 8.75M3.75 6.25H16.25'
stroke='currentColor'
stroke-width='1.5'
stroke-linecap='round'
stroke-linejoin='round'
/>,
);

export const IconInfoCircle = createIcon(
Expand Down
12 changes: 11 additions & 1 deletion src/components/Attachment/styling/ModalGallery.scss
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,17 @@
}

&:focus-visible {
@include utils.focusable;
outline: none;
}

&:focus-visible::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
border-radius: inherit;
box-shadow: inset 0 0 0 2px var(--str-chat__brand-300);
z-index: 1;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ChatView/styling/ChatView.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
}
}

.str-chat__chat-view__selector-button {
.str-chat__button.str-chat__chat-view__selector-button {
--str-chat-unread-count-badge-absolute-offset-vertical: 25%;

gap: 4px;
Expand Down
6 changes: 1 addition & 5 deletions src/components/Form/styling/NumericInput.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,12 @@
font-size: var(--str-chat__typography-font-size-sm, 0.875rem);
font-weight: var(--str-chat__typography-font-weight-medium, 500);
line-height: var(--str-chat__typography-line-height-tight, 1.25);
color: var(--str-chat__input-text-default, #1a1b25);
color: var(--str-chat__input-text-default);
text-align: center;
background: transparent;
border: none;
box-shadow: none;

&::placeholder {
color: var(--str-chat__input-text-placeholder, var(--str-chat__text-tertiary));
}

.str-chat__form-numeric-input--disabled & {
color: var(--str-chat__input-text-placeholder);
cursor: not-allowed;
Expand Down
6 changes: 0 additions & 6 deletions src/components/Form/styling/TextInput.scss
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,9 @@
background: transparent;
border: none;
outline: none;
outline-style: none;
box-shadow: none;
}

.str-chat__form-text-input .str-chat__form-text-input__input::placeholder {
color: var(--str-chat__input-text-placeholder);
}

.str-chat__form-text-input.str-chat__form-text-input--disabled
.str-chat__form-text-input__input {
color: var(--str-chat__input-text-placeholder);
Expand All @@ -154,7 +149,6 @@
.str-chat__form-text-input .str-chat__form-text-input__input:focus,
.str-chat__form-text-input .str-chat__form-text-input__input:focus-visible {
outline: none;
outline-style: none;
box-shadow: none;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ $attachment-preview-row-height: 72px;
gap: var(--str-chat__spacing-md);
}

.str-chat__attachment-preview-audio,
.str-chat__attachment-preview-voice-recording {
--chat-border-on-chat: var(--str-chat__chat-border-on-chat-incoming);
}

.str-chat__attachment-preview-audio,
.str-chat__attachment-preview-file,
.str-chat__attachment-preview-voice-recording,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const UnMemoizedScrollToLatestMessageButton = (
return (
<div className='str-chat__jump-to-latest-message'>
<Button
appearance='outline'
appearance='ghost'
aria-label={t('aria/Jump to latest message')}
aria-live='polite'
circular
Expand Down
5 changes: 5 additions & 0 deletions src/styling/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@
input[type='number'] {
-moz-appearance: textfield;
}

input::placeholder,
textarea::placeholder {
color: var(--str-chat__input-text-placeholder);
}
}