Skip to content
This repository was archived by the owner on Oct 4, 2026. It is now read-only.
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ let host: HTMLDivElement | null = null;
let root: Root | null = null;
(globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }).IS_REACT_ACT_ENVIRONMENT = true;

// Border colors transition, so a fixed sleep can read an interpolated color on a loaded runner.
const transitionsSettled = (element: Element) => expect.poll(() => element.getAnimations().length).toBe(0);

afterEach(async () => {
await act(() => root?.unmount());
host?.remove();
Expand Down Expand Up @@ -53,6 +56,7 @@ describe('form control interaction styles', () => {
globalThis.setTimeout(resolve, 200);
});
});
await transitionsSettled(input);
expect(getComputedStyle(input).outlineStyle).toBe('none');
expect(getComputedStyle(input).borderTopColor).toBe(accentBorderColor);
await act(async () => {
Expand All @@ -62,6 +66,7 @@ describe('form control interaction styles', () => {
});
});
expect(document.activeElement).toBe(trigger);
await transitionsSettled(trigger);
expect(getComputedStyle(trigger).outlineStyle).toBe('none');
expect(getComputedStyle(trigger).borderTopColor).toBe(accentBorderColor);

Expand All @@ -73,6 +78,7 @@ describe('form control interaction styles', () => {
});
});
expect(trigger.getAttribute('data-state')).toBe('open');
await transitionsSettled(trigger);
const hoveredFocusBorderColor = getComputedStyle(trigger).borderTopColor;
expect(hoveredFocusBorderColor).toBe(accentBorderColor);

Expand All @@ -82,6 +88,7 @@ describe('form control interaction styles', () => {
globalThis.setTimeout(resolve, 200);
});
});
await transitionsSettled(trigger);
expect(hoveredFocusBorderColor).toBe(getComputedStyle(trigger).borderTopColor);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ afterEach(async () => {
});

describe('toast contrast', () => {
// Success and warning fills (green/orange 600) stay below AA even for full-strength white text.
it.each(['error', 'info'] as const)('renders a %s description at AA contrast', async (type) => {
it.each(['error', 'info', 'success', 'warning'] as const)('renders a %s description at AA contrast', async (type) => {
host = document.createElement('div');
document.body.append(host);
root = createRoot(host);
Expand Down
10 changes: 9 additions & 1 deletion invokeai/frontend/webv2/src/platform/ui/theme/recipes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,19 @@ export const popoverSlotRecipe = defineSlotRecipe({
},
});

/** Chakra dims descriptions to 80%, which drops them below AA on the solid status fills. */
/**
* Keep white status text at AA: Chakra dims descriptions to 80%, and its green/orange 600 fills are too light
* for white at any opacity, so success and warning use the 700 step.
*/
export const toastSlotRecipe = defineSlotRecipe({
...chakraSlotRecipes.toast,
base: {
...chakraSlotRecipes.toast.base,
root: {
...chakraSlotRecipes.toast.base?.root,
'&[data-type=success]': { ...chakraSlotRecipes.toast.base?.root?.['&[data-type=success]'], bg: 'green.700' },
'&[data-type=warning]': { ...chakraSlotRecipes.toast.base?.root?.['&[data-type=warning]'], bg: 'orange.700' },
},
description: { ...chakraSlotRecipes.toast.base?.description, opacity: 1 },
},
});
Expand Down
Loading