Skip to content

Demo of A2UI v0.9 lit renderer#601

Open
jacobsimionato wants to merge 30 commits intogoogle:mainfrom
jacobsimionato:renderer-implement-2
Open

Demo of A2UI v0.9 lit renderer#601
jacobsimionato wants to merge 30 commits intogoogle:mainfrom
jacobsimionato:renderer-implement-2

Conversation

@jacobsimionato
Copy link
Collaborator

No description provided.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This is a substantial pull request that introduces the v0.9 architecture for the web renderers, successfully centralizing a significant amount of logic into the @a2ui/web_core package. This is a great architectural improvement that will enhance maintainability and consistency across different frameworks. The introduction of a demo application for the v0.9 Lit renderer is also a valuable addition.

My review focuses on some critical and high-severity issues in the new core implementation. These include a configuration change that reduces type safety across the project, a potential memory leak due to unmanaged subscriptions in the component context, and some issues related to accessibility and data model correctness. Addressing these will be crucial for the stability and robustness of the new v0.9 architecture.


/* Linting */
"strict": true,
"strict": false,
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

Disabling strict mode ("strict": false) is a significant regression in code quality and safety. It hides a wide range of potential bugs, null-pointer errors, and type mismatches that TypeScript is designed to catch. The project should aim to re-enable strict mode and fix the resulting type errors. This will improve long-term maintainability and reduce runtime errors. Many of the other issues found in this review (like the use of any or @ts-ignore) are symptoms of this underlying problem.

Comment on lines +26 to +28
// Subscribe to changes. When data changes, trigger a re-render.
this.dataContext.subscribe(value.path, () => this.updateCallback());
return this.dataContext.getValue(value.path);
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

The resolve and resolveChildren methods subscribe to the dataContext to trigger updates, but there is no corresponding mechanism to unsubscribe. This will lead to memory leaks, as component contexts will never be garbage collected if they hold active subscriptions, and the updateCallback will be called unnecessarily for components that are no longer in the DOM.

A lifecycle method (e.g., dispose()) should be added to ComponentContext to clean up all subscriptions. This method would need to be called when a component is unmounted.

Comment on lines +41 to +44
for (const segment of segments) {
if (current[segment] === undefined || current[segment] === null) {
current[segment] = {};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The set method's logic for creating intermediate paths always creates an object ({}). This doesn't correctly handle JSON Pointer paths that should create arrays. For example, a path like /items/0 on an empty model should ideally result in { "items": ["..."] }, but this implementation will create { "items": { "0": "..." } }. This can lead to incorrect data structures and runtime errors when code expects an array but gets an object.

The implementation should be updated to check if a path segment is a valid array index and create an array instead of an object when appropriate.

Comment on lines 13 to 29
render() {
return html`
<div @click="${() => this.isOpen = true}" style="display: inline-block;">
${this.trigger}
</div>
${this.isOpen ? html`
<div class="modal-overlay" style="position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center;">
<div class="modal-content" style="background: white; padding: 20px; border-radius: 8px; min-width: 300px;">
${this.content}
<div style="margin-top: 20px; text-align: right;">
<button @click="${() => this.isOpen = false}">Close</button>
</div>
</div>
</div>
` : nothing}
`;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The A2UiModalWrapper component has several accessibility and maintainability issues:

  • Accessibility: The modal is triggered by a click on a <div>, which is not keyboard-accessible. This should be a <button> or have role="button" and tabindex="0" to be focusable and activatable with Enter/Space. Additionally, focus is not trapped within the modal when it's open, and it cannot be closed with the Escape key.
  • Maintainability: All styles are applied inline. This makes them hard to override, theme, and maintain. They should be moved to a static styles block within the component.

@@ -0,0 +1,18 @@
import { resolve } from 'path';
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The import resolve from the path module is not used in this file and should be removed to keep the code clean.

Comment on lines +11 to +12
// @ts-ignore - indexing might be flagged if variant is not strictly typed to keys
const variantClasses = theme[targetVariant] || {};
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The use of @ts-ignore here hides a potential typing issue. The variant property on TextRenderProps is a string, but it's being used to index theme.components.Text, which has a specific set of keys (h1, h2, body, etc.).

To fix this and remove the need for @ts-ignore, the variant type should be constrained to the actual keys of the theme's text component styles. This is a good example of an issue that would have been caught if strict mode were enabled.

Suggested change
// @ts-ignore - indexing might be flagged if variant is not strictly typed to keys
const variantClasses = theme[targetVariant] || {};
const variantClasses = theme[targetVariant as keyof typeof theme] || {};

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

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

1 participant