Skip to content

refactor(site): modularize homepage demo runtime#478

Open
hiqiancheng wants to merge 1 commit into
mainfrom
refactor/site-homepage-demo-modules-clean
Open

refactor(site): modularize homepage demo runtime#478
hiqiancheng wants to merge 1 commit into
mainfrom
refactor/site-homepage-demo-modules-clean

Conversation

@hiqiancheng

Copy link
Copy Markdown
Collaborator

Summary

  • extract a typed homepage demo scenario registry and shared src/title helpers
  • unify homepage demo host CSS between the Astro host component and runtime script
  • move homepage locale-switch demo syncing into a dedicated module with explicit scenario ids

Test Plan

  • pnpm --filter @touchai/site build

@github-actions github-actions Bot added the area:frontend Frontend UI or view-layer changes label Jun 18, 2026
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Refactor
    • Consolidated demo component CSS scoping and styling utilities into centralized shared modules.
    • Restructured homepage demo configuration with locale-specific scenario definitions and metadata.
    • Simplified demo rendering to use structured scenario identifiers and configuration-driven approach instead of hardcoded values.

Walkthrough

Extracts homepage demo scenario configuration into a typed registry (homepageDemoScenarios), moves CSS scoping and host-CSS generation into a shared host-css.ts module, adds a syncHomepageDemoLocale utility for locale-driven frame reloads and ARIA label updates, and refactors ComponentDemo.astro, component-demo-runtime.ts, and index.astro to consume these shared modules.

Changes

Homepage Demo Scenario Registry, CSS Scoping, and Locale Sync

Layer / File(s) Summary
Scenario types, registry, and src utilities
apps/site/src/components/homepage-demo/scenario-types.ts, apps/site/src/data/homepage-demo-scenarios.ts, apps/site/src/utils/homepage-demo-src.ts
Defines HomepageDemoScenarioId/HomepageDemoReplayScenarioId type aliases, HomepageDemoLocale/HomepageDemoVariant/HomepageDemoScenario interfaces, and the homepageDemoScenarios record with four scenarios (intro, solver, work-organizer, reminder) including per-locale src/title. Adds getHomepageDemoSrc/getHomepageDemoTitle lookup utilities.
Shared CSS scoping and host CSS generation
apps/site/src/components/homepage-demo/host-css.ts, apps/site/src/components/homepage-demo/README.md
Adds createHomepageDemoInstanceSelector, scopeHomepageDemoCss (CSS text parser that rewrites selectors to instance scope), and createHomepageDemoHostCss (large layout/responsive CSS template). README documents the module boundary.
ComponentDemo.astro refactor
apps/site/src/components/ComponentDemo.astro
Removes ~350 lines of inline CSS scoping helpers and hostCss template; imports and delegates to the shared host-css utilities. Extends Props with optional scenarioId and emits data-scenario-id on the rendered element.
component-demo-runtime.ts CSS update
apps/site/src/scripts/component-demo-runtime.ts
Replaces inline hostCssFor template with imported createHomepageDemoHostCss/scopeHomepageDemoCss/createHomepageDemoInstanceSelector. Extends TouchAiHost dataset type with scenarioId and initializes it during mount.
syncHomepageDemoLocale utility
apps/site/src/scripts/homepage-demo-locale.ts
Adds syncHomepageDemoLocale which performs two passes: updating replay card aria-label text per locale and reloading demo frames whose dataset.src differs from the locale variant, calling progress reset/background sync/restore callbacks around the reload.
index.astro locale-driven rendering and language switch
apps/site/src/pages/index.astro
Sets initialHomepageDemoLocale ('zh'), passes scenarioId plus computed src/title into all four ComponentDemo instances, and replaces the inline setLanguage block with a delegated call to syncHomepageDemoLocale.

Sequence Diagram(s)

sequenceDiagram
  participant Browser as Browser (user switches language)
  participant index as index.astro setLanguage
  participant syncLocale as syncHomepageDemoLocale
  participant registry as homepageDemoScenarios
  participant frame as ComponentDemo frame (DOM)

  Browser->>index: language toggle event
  index->>syncLocale: call(lang, replayLabels, replaySuffix, callbacks)
  syncLocale->>registry: lookup replayCardSelector for each replay scenario
  syncLocale->>frame: update replay card aria-label
  syncLocale->>registry: lookup locale variant src/title per scenario
  syncLocale->>frame: query by data-scenario-id
  alt src differs from current
    syncLocale->>frame: resetDemoProgressDedupe()
    syncLocale->>frame: update dataset.src + dataset.title
    syncLocale->>frame: frame.reload()
    frame-->>syncLocale: reload complete
    syncLocale->>frame: syncComponentBackground()
    syncLocale->>frame: restoreFeatureDemoProgress() (if restoreProgressOnReload)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • TouchAI-org/TouchAI#373: Foundational updates to ComponentDemo.astro and component-demo-runtime.ts that established the demo embedding and CSS scoping logic this PR refactors into shared utilities.
  • TouchAI-org/TouchAI#374: Touches the same ComponentDemo.astro and component-demo-runtime.ts CSS scoping and responsive sizing rules that are now extracted into host-css.ts.
  • TouchAI-org/TouchAI#376: Modifies the same demo CSS generation path in ComponentDemo.astro and component-demo-runtime.ts that this PR consolidates behind the new createHomepageDemoHostCss helper.

Suggested labels

area:frontend

🐇 A rabbit hops through the code at night,
Pulling out inline CSS to the light.
Scenarios named, locales aligned,
Each demo frame properly confined.
No more hardcoded paths in sight—
The registry hops everything right! 🌟


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Description check ❌ Error The PR description lacks critical sections required by the template: no 'Related issue or RFC' linking, no 'AI assistance disclosure' section, and incomplete 'Testing evidence' (missing most standard test commands). While it has a Summary, it does not meet the template's comprehensive requirements. Add the 'Related issue or RFC' section with issue link, complete the 'AI assistance disclosure' section (even if none applies), and provide full 'Testing evidence' with all relevant test command outputs (pnpm test:pr as minimum).
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor(site): modularize homepage demo runtime' follows Conventional Commits format and accurately summarizes the main refactoring changes across the homepage demo layer.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/site-homepage-demo-modules-clean

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/site/src/scripts/component-demo-runtime.ts (1)

80-171: ⚠️ Potential issue | 🟡 Minor

Remove dead code: scopeCss and scopeSelectorList are unused.

Both functions are defined but never called. scopeSelectorList (line 73) is only referenced within scopeCss (line 80), which itself has no callers in the codebase. Since the file imports and uses scopeHomepageDemoCss from the shared module instead, these local functions should be deleted.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/site/src/scripts/component-demo-runtime.ts` around lines 80 - 171, The
functions scopeCss and scopeSelectorList are dead code that should be removed.
Delete both function definitions entirely since scopeCss has no callers in the
codebase and scopeSelectorList is only referenced within scopeCss. The file
already imports and uses scopeHomepageDemoCss from the shared module instead,
making these local functions unnecessary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/site/src/components/homepage-demo/host-css.ts`:
- Around line 8-9: The regex pattern `/^\d+%$/` in the condition checking for
keyframe percentages only matches integer values like 50%, but fails to match
decimal percentages like 33.33% or 12.5%, causing them to be incorrectly
prefixed. Update the regex pattern to support optional decimal values by
allowing for a decimal point followed by digits after the initial digits,
ensuring both integer and decimal percentages are correctly recognized in CSS
keyframes.

In `@apps/site/src/pages/index.astro`:
- Around line 2645-2653: The setLanguage() function call at line 2659 executes
synchronously and references syncComponentBackground through the
syncHomepageDemoLocale() call within setLanguage()'s body, but
syncComponentBackground is not declared until line 2784, violating the temporal
dead zone. Move the setLanguage(savedLanguage === 'en' ? 'en' : 'zh') call to
execute after the syncComponentBackground declaration is complete, either by
placing it at the end of the script file after line 2784 or by wrapping it in a
deferred execution mechanism like setTimeout with zero delay to push it to the
end of the event loop.

In `@apps/site/src/scripts/component-demo-runtime.ts`:
- Around line 537-541: The runtime code in the styleNode.textContent assignment
is inconsistently processing CSS compared to ComponentDemo.astro. Instead of
passing both scopedCss and createHomepageDemoHostCss(instanceSelector) through
scopeHomepageDemoCss, modify the code to concatenate them directly without
re-scoping, matching the approach used in ComponentDemo.astro. This eliminates
unnecessary processing since the host CSS selectors already begin with
instanceSelector and will pass through unchanged.
- Around line 1-6: The imports in the component-demo-runtime.ts file are not
sorted according to ESLint rules. Reorder the imports by sorting them
alphabetically by their source path while keeping type imports grouped
separately from regular imports. The type import from scenario-types and the
regular import from host-css need to be reorganized to satisfy the linter's sort
order requirements.

In `@apps/site/src/scripts/homepage-demo-locale.ts`:
- Around line 79-80: The demo host element's accessible name is not being
updated when the localized title changes during a locale switch. After the line
that sets frame.dataset.title to variant.title, add a line to also update the
frame element's aria-label attribute to the same variant.title value. This
ensures that screen reader users will hear the correct localized label when the
language is switched, keeping the accessible name synchronized with the visible
title.

In `@apps/site/src/utils/homepage-demo-src.ts`:
- Around line 1-5: The import statement is importing HomepageDemoScenarioId from
the wrong module. The type HomepageDemoScenarioId is not exported from
../data/homepage-demo-scenarios but rather from
../components/homepage-demo/scenario-types. Remove HomepageDemoScenarioId from
the import statement on the line importing from ../data/homepage-demo-scenarios,
and add a separate import statement to import HomepageDemoScenarioId from
../components/homepage-demo/scenario-types instead.

---

Outside diff comments:
In `@apps/site/src/scripts/component-demo-runtime.ts`:
- Around line 80-171: The functions scopeCss and scopeSelectorList are dead code
that should be removed. Delete both function definitions entirely since scopeCss
has no callers in the codebase and scopeSelectorList is only referenced within
scopeCss. The file already imports and uses scopeHomepageDemoCss from the shared
module instead, making these local functions unnecessary.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ee2e2011-f151-45df-b74f-e34b1648dc08

📥 Commits

Reviewing files that changed from the base of the PR and between 8207a25 and 91cbe68.

📒 Files selected for processing (9)
  • apps/site/src/components/ComponentDemo.astro
  • apps/site/src/components/homepage-demo/README.md
  • apps/site/src/components/homepage-demo/host-css.ts
  • apps/site/src/components/homepage-demo/scenario-types.ts
  • apps/site/src/data/homepage-demo-scenarios.ts
  • apps/site/src/pages/index.astro
  • apps/site/src/scripts/component-demo-runtime.ts
  • apps/site/src/scripts/homepage-demo-locale.ts
  • apps/site/src/utils/homepage-demo-src.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: CodeQL (rust)
🧰 Additional context used
🪛 ESLint
apps/site/src/utils/homepage-demo-src.ts

[error] 1-5: Run autofix to sort these imports!

(simple-import-sort/imports)

apps/site/src/scripts/homepage-demo-locale.ts

[error] 1-8: Run autofix to sort these imports!

(simple-import-sort/imports)


[error] 1-4: Replace ⏎····homepageDemoScenarios,⏎····type·HomepageDemoLocale,⏎ with ·homepageDemoScenarios,·type·HomepageDemoLocale·

(prettier/prettier)


[error] 72-72: Replace [data-scenario-id="${scenarioId}"] with ⏎············[data-scenario-id="${scenarioId}"]⏎········

(prettier/prettier)

apps/site/src/scripts/component-demo-runtime.ts

[error] 1-6: Run autofix to sort these imports!

(simple-import-sort/imports)

🪛 LanguageTool
apps/site/src/components/homepage-demo/README.md

[style] ~7-~7: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... - src/components/ComponentDemo.astro is the compatibility host that still loads...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (6)
apps/site/src/components/homepage-demo/host-css.ts (1)

1-2: LGTM!

Also applies to: 32-123, 125-350

apps/site/src/components/homepage-demo/README.md (1)

1-10: LGTM!

apps/site/src/components/ComponentDemo.astro (1)

4-9: LGTM!

Also applies to: 15-15, 19-19, 78-81, 91-91

apps/site/src/scripts/component-demo-runtime.ts (1)

20-22: LGTM!

Also applies to: 607-607

apps/site/src/components/homepage-demo/scenario-types.ts (1)

1-3: LGTM!

apps/site/src/data/homepage-demo-scenarios.ts (1)

1-97: LGTM!

Comment on lines +8 to +9
if (trimmed.startsWith('from') || trimmed.startsWith('to') || /^\d+%$/.test(trimmed))
return trimmed;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keyframe percentage regex doesn't match decimal values.

The pattern /^\d+%$/ only matches integer percentages (e.g., 50%) but not decimal percentages like 33.33% or 12.5%, which are valid in CSS keyframes. If demo CSS contains decimal percentages, they would be incorrectly prefixed with the instance selector.

Proposed fix
-    if (trimmed.startsWith('from') || trimmed.startsWith('to') || /^\d+%$/.test(trimmed))
+    if (trimmed.startsWith('from') || trimmed.startsWith('to') || /^\d+(?:\.\d+)?%$/.test(trimmed))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (trimmed.startsWith('from') || trimmed.startsWith('to') || /^\d+%$/.test(trimmed))
return trimmed;
if (trimmed.startsWith('from') || trimmed.startsWith('to') || /^\d+(?:\.\d+)?%$/.test(trimmed))
return trimmed;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/site/src/components/homepage-demo/host-css.ts` around lines 8 - 9, The
regex pattern `/^\d+%$/` in the condition checking for keyframe percentages only
matches integer values like 50%, but fails to match decimal percentages like
33.33% or 12.5%, causing them to be incorrectly prefixed. Update the regex
pattern to support optional decimal values by allowing for a decimal point
followed by digits after the initial digits, ensuring both integer and decimal
percentages are correctly recognized in CSS keyframes.

Comment on lines +2645 to 2653
syncHomepageDemoLocale({
document,
lang,
replayLabels: localizedLabels.replayLabels,
replaySuffix: localizedLabels.replaySuffix,
resetDemoProgressDedupe,
syncComponentBackground,
restoreFeatureDemoProgress,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify call-site order vs const declaration order.
rg -n "const setLanguage|setLanguage\\(savedLanguage|const syncComponentBackground" apps/site/src/pages/index.astro
sed -n '2555,2668p' apps/site/src/pages/index.astro | nl -ba
sed -n '2778,2810p' apps/site/src/pages/index.astro | nl -ba

Repository: TouchAI-org/TouchAI

Length of output: 314


🏁 Script executed:

# Get context around the setLanguage definition, call, and syncComponentBackground declaration
sed -n '2555,2800p' apps/site/src/pages/index.astro | head -250

Repository: TouchAI-org/TouchAI

Length of output: 12409


🏁 Script executed:

# Get the rest of the context to see where syncComponentBackground and restoreFeatureDemoProgress are fully declared
sed -n '2784,2850p' apps/site/src/pages/index.astro

Repository: TouchAI-org/TouchAI

Length of output: 3798


🏁 Script executed:

# Find where restoreFeatureDemoProgress is declared
rg -n "const restoreFeatureDemoProgress|let restoreFeatureDemoProgress" apps/site/src/pages/index.astro

Repository: TouchAI-org/TouchAI

Length of output: 45


🏁 Script executed:

# Search more broadly for restoreFeatureDemoProgress
rg -n "restoreFeatureDemoProgress" apps/site/src/pages/index.astro | head -20

Repository: TouchAI-org/TouchAI

Length of output: 186


🏁 Script executed:

# Check if setLanguage call at line 2659 is wrapped in any async/deferred mechanism
sed -n '2655,2662p' apps/site/src/pages/index.astro

Repository: TouchAI-org/TouchAI

Length of output: 442


setLanguage() throws a ReferenceError immediately on page load due to accessing syncComponentBackground before its declaration.

At line 2659, setLanguage(savedLanguage === 'en' ? 'en' : 'zh') executes synchronously. The function body (lines 2561-2653) references syncComponentBackground at line 2648 when calling syncHomepageDemoLocale(). However, syncComponentBackground is not declared until line 2784, causing a temporal dead zone violation.

💡 Proposed fix (defer initial call until declarations are initialized)
 const languageToggle = document.querySelector('.lang-toggle');
 const savedLanguage = localStorage.getItem('touchai-language');
-setLanguage(savedLanguage === 'en' ? 'en' : 'zh');
+queueMicrotask(() => {
+    setLanguage(savedLanguage === 'en' ? 'en' : 'zh');
+});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/site/src/pages/index.astro` around lines 2645 - 2653, The setLanguage()
function call at line 2659 executes synchronously and references
syncComponentBackground through the syncHomepageDemoLocale() call within
setLanguage()'s body, but syncComponentBackground is not declared until line
2784, violating the temporal dead zone. Move the setLanguage(savedLanguage ===
'en' ? 'en' : 'zh') call to execute after the syncComponentBackground
declaration is complete, either by placing it at the end of the script file
after line 2784 or by wrapping it in a deferred execution mechanism like
setTimeout with zero delay to push it to the end of the event loop.

Comment on lines +1 to +6
import type { HomepageDemoScenarioId } from '../components/homepage-demo/scenario-types';
import {
createHomepageDemoHostCss,
createHomepageDemoInstanceSelector,
scopeHomepageDemoCss,
} from '../components/homepage-demo/host-css';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Sort imports to satisfy linter.

ESLint reports these imports need to be sorted.

Proposed fix
-import type { HomepageDemoScenarioId } from '../components/homepage-demo/scenario-types';
 import {
     createHomepageDemoHostCss,
     createHomepageDemoInstanceSelector,
     scopeHomepageDemoCss,
 } from '../components/homepage-demo/host-css';
+import type { HomepageDemoScenarioId } from '../components/homepage-demo/scenario-types';
🧰 Tools
🪛 ESLint

[error] 1-6: Run autofix to sort these imports!

(simple-import-sort/imports)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/site/src/scripts/component-demo-runtime.ts` around lines 1 - 6, The
imports in the component-demo-runtime.ts file are not sorted according to ESLint
rules. Reorder the imports by sorting them alphabetically by their source path
while keeping type imports grouped separately from regular imports. The type
import from scenario-types and the regular import from host-css need to be
reorganized to satisfy the linter's sort order requirements.

Source: Linters/SAST tools

Comment on lines 537 to 541
if (styleNode) {
styleNode.textContent = scopeCss(
`${scopedCss}\n${hostCssFor(host.dataset.demoId || '')}`,
`touchai-component-demo[data-demo-id="${host.dataset.demoId || ''}"]`
styleNode.textContent = scopeHomepageDemoCss(
`${scopedCss}\n${createHomepageDemoHostCss(instanceSelector)}`,
instanceSelector
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Inconsistent CSS generation with ComponentDemo.astro.

The runtime passes createHomepageDemoHostCss(instanceSelector) through scopeHomepageDemoCss, but ComponentDemo.astro concatenates them directly without re-scoping the host CSS. While this works (selectors already starting with instanceSelector pass through unchanged), it's unnecessary processing and creates an inconsistency between build-time and runtime behavior.

Proposed fix to match ComponentDemo.astro approach
     if (styleNode) {
-        styleNode.textContent = scopeHomepageDemoCss(
-            `${scopedCss}\n${createHomepageDemoHostCss(instanceSelector)}`,
-            instanceSelector
-        );
+        styleNode.textContent = `${scopeHomepageDemoCss(scopedCss, instanceSelector)}\n${createHomepageDemoHostCss(instanceSelector)}`;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (styleNode) {
styleNode.textContent = scopeCss(
`${scopedCss}\n${hostCssFor(host.dataset.demoId || '')}`,
`touchai-component-demo[data-demo-id="${host.dataset.demoId || ''}"]`
styleNode.textContent = scopeHomepageDemoCss(
`${scopedCss}\n${createHomepageDemoHostCss(instanceSelector)}`,
instanceSelector
);
if (styleNode) {
styleNode.textContent = `${scopeHomepageDemoCss(scopedCss, instanceSelector)}\n${createHomepageDemoHostCss(instanceSelector)}`;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/site/src/scripts/component-demo-runtime.ts` around lines 537 - 541, The
runtime code in the styleNode.textContent assignment is inconsistently
processing CSS compared to ComponentDemo.astro. Instead of passing both
scopedCss and createHomepageDemoHostCss(instanceSelector) through
scopeHomepageDemoCss, modify the code to concatenate them directly without
re-scoping, matching the approach used in ComponentDemo.astro. This eliminates
unnecessary processing since the host CSS selectors already begin with
instanceSelector and will pass through unchanged.

Comment on lines +79 to +80
frame.dataset.src = variant.src;
frame.dataset.title = variant.title;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep the demo host aria-label synchronized with localized title.

This updates data-title but not the host’s accessible name. After language switch, screen-reader region labels can stay in the previous locale.

💡 Proposed fix
         frame.dataset.src = variant.src;
         frame.dataset.title = variant.title;
+        frame.setAttribute('aria-label', variant.title);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/site/src/scripts/homepage-demo-locale.ts` around lines 79 - 80, The demo
host element's accessible name is not being updated when the localized title
changes during a locale switch. After the line that sets frame.dataset.title to
variant.title, add a line to also update the frame element's aria-label
attribute to the same variant.title value. This ensures that screen reader users
will hear the correct localized label when the language is switched, keeping the
accessible name synchronized with the visible title.

Comment on lines +1 to +5
import {
homepageDemoScenarios,
type HomepageDemoLocale,
type HomepageDemoScenarioId,
} from '../data/homepage-demo-scenarios';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify where HomepageDemoScenarioId is declared/exported vs imported.
rg -n "HomepageDemoScenarioId" \
  apps/site/src/components/homepage-demo/scenario-types.ts \
  apps/site/src/data/homepage-demo-scenarios.ts \
  apps/site/src/utils/homepage-demo-src.ts

Repository: TouchAI-org/TouchAI

Length of output: 1043


Import HomepageDemoScenarioId from the defining module, not the data module.

HomepageDemoScenarioId is not exported by ../data/homepage-demo-scenarios (only imported from ../components/homepage-demo/scenario-types), so this import breaks TypeScript symbol resolution.

💡 Proposed fix
 import {
     homepageDemoScenarios,
     type HomepageDemoLocale,
-    type HomepageDemoScenarioId,
 } from '../data/homepage-demo-scenarios';
+import type { HomepageDemoScenarioId } from '../components/homepage-demo/scenario-types';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import {
homepageDemoScenarios,
type HomepageDemoLocale,
type HomepageDemoScenarioId,
} from '../data/homepage-demo-scenarios';
import {
homepageDemoScenarios,
type HomepageDemoLocale,
} from '../data/homepage-demo-scenarios';
import type { HomepageDemoScenarioId } from '../components/homepage-demo/scenario-types';
🧰 Tools
🪛 ESLint

[error] 1-5: Run autofix to sort these imports!

(simple-import-sort/imports)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/site/src/utils/homepage-demo-src.ts` around lines 1 - 5, The import
statement is importing HomepageDemoScenarioId from the wrong module. The type
HomepageDemoScenarioId is not exported from ../data/homepage-demo-scenarios but
rather from ../components/homepage-demo/scenario-types. Remove
HomepageDemoScenarioId from the import statement on the line importing from
../data/homepage-demo-scenarios, and add a separate import statement to import
HomepageDemoScenarioId from ../components/homepage-demo/scenario-types instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:frontend Frontend UI or view-layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant