Skip to content
Open
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
36 changes: 35 additions & 1 deletion packages/cli/assets/templates/themes/neutral/neutralTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ export const neutralTheme = defineTheme({

// Text
'--color-text-primary': ['#171717', '#fafafa'],
'--color-text-secondary': ['#737373', '#a3a3a3'],
// Light secondary is neutral-600 (#525252), not 500 (#737373): 500 only
// reaches 4.19:1 on the T95 body (#f1f1f1), just under WCAG AA 4.5:1.
// 600 clears it (6.9:1 on body, 7.8:1 on card). Dark stays neutral-400.
'--color-text-secondary': ['#525252', '#a3a3a3'],
'--color-text-disabled': ['#a3a3a3', '#525252'],
'--color-text-accent': ['#262626', '#ebebeb'],
'--color-on-dark': '#ffffff',
Expand Down Expand Up @@ -482,6 +485,37 @@ export const neutralTheme = defineTheme({
},
},

// =========================================================================
// StatusDot — fill uses the SAME vivid stops as the filled semantic Badge
// (and ProgressBar), so a dot and its badge read as one status language.
//
// The default component maps each variant to a raw semantic token
// (--color-success / --color-error / --color-warning / --color-icon-
// secondary), which in light mode are the dark T30/T40 stops meant to
// sit as TEXT on a pastel surface — as a solid dot they read muddy
// (dark green / maroon / brown). Redirect them to the badge fills.
//
// success → badge success bg (green T45 / dark-ramp T60)
// warning → badge warning bg (yellow T85, same hex both modes)
// error → badge error bg (red T55 / dark-ramp T60)
// accent → badge info bg (blue T50 / dark-ramp T60) — the
// StatusDot "accent" is the info/attention color, so it
// pairs with the info badge rather than --color-accent
// (near-black #262626, the darkest offender).
//
// `neutral` is intentionally NOT overridden: the neutral badge bg is a
// near-invisible light gray (--color-background-gray #e5e5e5 / 10% white
// wash), fine as a large pill but unreadable as an 8px dot. It keeps the
// component default's visible mid-gray (--color-icon-secondary), which is
// not among the "too dark" cases.
// =========================================================================
statusdot: {
'variant:success': {backgroundColor: 'light-dark(#198100, #64af4c)'},
'variant:warning': {backgroundColor: '#ffce2f'},
'variant:error': {backgroundColor: 'light-dark(#e33f4a, #ff705d)'},
'variant:accent': {backgroundColor: 'light-dark(#0074e2, #6d9cfe)'},
},

// =========================================================================
// Banner — sits on a hue-tinted surface with colored text/icon:
// Light: pastel T90 bg (pulled from --color-{X}-muted / --color-background-blue)
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/Chat/Chat.doc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export const docs = {
{className: 'astryx-chat-system-message', visualProps: ['variant']},
{className: 'astryx-chat-message-metadata'},
{className: 'astryx-chat-send-button'},
{className: 'astryx-chat-dictation-button'},
{className: 'astryx-chat-layout-scroll-button'},
{className: 'astryx-chat-tokenized-text'},
{className: 'astryx-chat-tool-calls'},
{className: 'astryx-trigger-menu'},
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/Chat/ChatDictationButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {Button} from '../Button';
import {Icon} from '../Icon';
import {mergeProps} from '../utils';
import type {BaseProps} from '../BaseProps';
import {themeProps} from '../utils/themeProps';
import {useTranslator} from '../i18n';

// =============================================================================
Expand Down Expand Up @@ -140,7 +141,12 @@ export function ChatDictationButton({
return (
<span
ref={ref}
{...mergeProps(stylex.props(styles.wrapper, xstyle), className, style)}
{...mergeProps(
themeProps('chat-dictation-button'),
stylex.props(styles.wrapper, xstyle),
className,
style,
)}
{...rest}>
{isListening && (
<span
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/Chat/ChatLayoutScrollButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {Icon} from '../Icon';
import {Button} from '../Button';
import type {BaseProps} from '../BaseProps';
import {mergeProps} from '../utils';
import {themeProps} from '../utils/themeProps';
import {useTranslator} from '../i18n';

// =============================================================================
Expand Down Expand Up @@ -128,7 +129,12 @@ export function ChatLayoutScrollButton({
return (
<div
ref={ref}
{...mergeProps(stylex.props(styles.wrapper, xstyle), className, style)}
{...mergeProps(
themeProps('chat-layout-scroll-button'),
stylex.props(styles.wrapper, xstyle),
className,
style,
)}
{...rest}>
<div
{...stylex.props(
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/Chat/ChatSendButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {getIcon} from '../Icon/globalIconRegistry';
import {useChatComposerContext} from './ChatContext';

import type {BaseProps} from '../BaseProps';
import {mergeProps} from '../utils';
import {themeProps} from '../utils/themeProps';
import {useTranslator} from '../i18n';

Expand Down Expand Up @@ -115,9 +116,7 @@ export function ChatSendButton(props: ChatSendButtonProps): ReactNode {
isDisabled={!isStopShown && isDisabled}
onClick={isStopShown ? onStop : handleSend}
{...rest}
{...themeProps('chat-send-button')}
className={className}
style={style}
{...mergeProps(themeProps('chat-send-button'), {className}, style)}
xstyle={[styles.root, xstyle]}
/>
);
Expand Down
Loading