ui: Refactor data-attrs constants, enum for bool strings (#27002)

* refactor: Data-attribute constants + boolean string enum

* refactor: Use CSS class string constants

* refactor: Address review comments
This commit is contained in:
Aleksander Grygier
2026-08-13 20:01:12 +02:00
committed by GitHub
parent fa4ec4590c
commit bdffafa5df
40 changed files with 280 additions and 189 deletions
@@ -2,7 +2,7 @@
// fenced-code-block flow: while the caret sits inside a fenced
// block region - closed, or still OPEN while the user is typing
// one - plain Enter adds a line instead of submitting the message.
// The textarea path is covered here end-to-end (the contenteditable
// The textarea path is covered here end-to-end (the ChatFormInputRich
// consumes the same case locally; see chat-form-input-rich).
import ChatFormTestWrapper from './components/ChatFormTestWrapper.svelte';
@@ -1,4 +1,4 @@
// Guards the newline contract of the chat-form contenteditable: browsers
// Guards the newline contract of the ChatFormInputRich: browsers
// restructure the flat DOM on Enter (`<div>` wrappers, `<br>` shapes) and
// serialization must fold those back into `\n` so the emitted value never
// diverges from what is on screen.
@@ -13,7 +13,7 @@ const SOURCE = 'see [docs](file:///a/b) here';
function editableIn(container: HTMLElement): HTMLElement {
const el = container.querySelector('[role="textbox"]');
if (!(el instanceof HTMLElement)) throw new Error('contenteditable not rendered');
if (!(el instanceof HTMLElement)) throw new Error('ChatFormInputRich not rendered');
return el;
}
@@ -1,4 +1,4 @@
// Guards the editing-key contract of the chat-form contenteditable:
// Guards the editing-key contract of the ChatFormInputRich:
// undo/redo is replayed from source snapshots (the token rebuilds destroy
// the native undo stack), and Tab is NOT intercepted (WCAG 2.1.2 no
// keyboard trap), matching the plain textarea.
@@ -13,7 +13,7 @@ const SOURCE = 'see [docs](file:///a/b)';
function editableIn(container: HTMLElement): HTMLElement {
const el = container.querySelector('[role="textbox"]');
if (!(el instanceof HTMLElement)) throw new Error('contenteditable not rendered');
if (!(el instanceof HTMLElement)) throw new Error('ChatFormInputRich not rendered');
return el;
}
@@ -1,4 +1,4 @@
// Guards the clipboard contract of the chat-form contenteditable:
// Guards the clipboard contract of the ChatFormInputRich:
// copy/cut expose the markdown SOURCE of the selection (each badge
// contributes its full `[name](file://...)` link) and pasting such
// markdown re-renders the badges.
@@ -16,7 +16,7 @@ const BADGE_SELECTOR = '[data-mention-badge="true"]';
function editableIn(container: HTMLElement): HTMLElement {
const el = container.querySelector('[role="textbox"]');
if (!(el instanceof HTMLElement)) throw new Error('contenteditable not rendered');
if (!(el instanceof HTMLElement)) throw new Error('ChatFormInputRich not rendered');
return el;
}
@@ -3,7 +3,7 @@
// it, the picker still opens but explains why instead of firing searches
// that would only fail with "Search failed".
import ChatFormMentionPicker from '$lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerMention.svelte';
import ChatFormPickerMention from '$lib/components/app/chat/ChatForm/ChatFormPickers/ChatFormPickerMention.svelte';
import { DISABLED_TOOL_KEYS_LOCALSTORAGE_KEY } from '$lib/constants';
import { BuiltInTool } from '$lib/enums';
import { toolsStore } from '$lib/stores/tools.svelte';
@@ -25,7 +25,7 @@ function setBuiltinTools(defs: OpenAIToolDefinition[]) {
}
function renderPicker() {
return render(ChatFormMentionPicker, {
return render(ChatFormPickerMention, {
isOpen: true,
onClose: () => {},
onSelect: () => {},
@@ -39,7 +39,7 @@ afterEach(() => {
localStorage.removeItem(DISABLED_TOOL_KEYS_LOCALSTORAGE_KEY);
});
describe('ChatFormMentionPicker file_glob_search gate', () => {
describe('ChatFormPickerMention file_glob_search gate', () => {
it('explains that file search is unavailable when the server has no tools', async () => {
setBuiltinTools([]);
renderPicker();