Repository navigation
Conversation
Apps had no reusable way to show persistent feedback inside a layout: an
info, success, warning or error message with an optional title, an
action and a way to dismiss it.
InlineAlert is a function component built from plain views and native
<button> elements. A class map on the box picks the variant's colors,
and a visible severity label names the variant, so the meaning does not
rely on color alone. The label defaults to English, severityLabel takes
a translation, and an empty label falls back to the default so the cue
is never blank; dismissLabel does the same. Title, message and the
action button render only when their text is not empty, and the dismiss
button only when dismissible is set. Dismissing calls onDismiss and
nothing else: the app owns visibility and removes the alert. The root
carries role="status", or role="alert" for errors, which the browser
target exposes to screen readers; native targets ignore it. The caller's
class goes on the root and the parts use fixed inline-alert__ classes.
There is no style prop, since geatsc has no rule for forwarding a Style
object through a function component.
On the pixel engine an auto-width button in a flex row took the whole
row, so the buttons use width: fit-content, with max-width: 100% for a
long label. The actions row wraps, so a pair of buttons that does not
fit in a narrow alert puts the dismiss button on a second line instead
of pushing the action button out of the row. The components index
exports the prop and variant types from index.ts as well as index.d.ts:
a native build resolves value imports to the .ts sources, so `import {
InlineAlert, type InlineAlertVariant }` otherwise failed with "has no
exported member". The elements package marks *.css as side effects, so a
bundler cannot drop the stylesheet import.
The README and .d.ts state the limits. With the built-in bitmap font,
pixel targets draw ASCII only, so a character such as a Turkish ü or ş
draws as "?" unless the app enables runtime TTF fonts or a
--gea-font-charset. Right-to-left layout is not handled. In a native
build, an alert inside a conditional branch keeps the props it was first
rendered with, a geatsc behavior that affects any component; the README
points to the demo in geastack/examples, which renders each alert from a
class component whose template root is an element.
Tests: added run-gea-elements-inline-alert-pipeline.sh, which builds an
in-core fixture app, so it needs no app in the examples checkout; like
the other app pipelines it compiles with --allow-any. It checks on the
native engine: each variant's class, default or translated severity
label, role, and distinct fill and stripe colors; the caller's id and
class on the root; that title, message and buttons render only when
given, with empty strings and an explicit undefined; that empty severity
and dismiss labels fall back to the defaults; that the parts stack as
severity, title, message, buttons; that a long message and a long title
wrap inside a 200 px alert that grows with them; that each button is
exactly as wide as its label plus padding and border, stays on one line
inside the actions row and ends its line, with a pair on one line in a
wide alert and wrapped in a narrow one; that onAction and onDismiss fire
once per press and only for their own alert, that a dismiss button
without onDismiss does nothing, that an app-removed alert leaves the
tree, and that a variant changed by the app re-renders with the new
class, label and role. Each of 29 mutations, applied one at a time,
makes it fail, among them: a wrong default variant or label, the
translated label ignored, empty severity or dismiss labels kept, title,
message or action guards changed to undefined checks, the dismiss button
always shown, the callbacks swapped, id or class not forwarded, the role
dropped or given to the wrong variant, a wrong variant class, no
fit-content, no flex-wrap, no justify-content, a reversed actions row,
narrower or taller button padding, the title after the message, the
error colors dropped, and nowrap on the message or title. tsc 5.9.3
strict passes on the component and the fixture. In the browser DOM dev
server the fixture renders, responds to clicks, sets the roles and wraps
the narrow button pair. Full core suite on this branch with Homebrew
bash 5: 154 of 156 pass; the two failures,
test_gea_vite_module_graph_assets.mjs and run-ui-memory-census.sh, fail
the same way on main (b2b1ac1) and are environment gaps. That suite run
predates the last round of review fixes, which change only InlineAlert's
own files, its fixture and its test; after them the InlineAlert test was
run again and passes. Not run: the WASM simulator, devices, and the
macOS, iOS and Windows renderers, which draw the buttons as native
widgets (source only).
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
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. Comment |
This was referenced Oct 18, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #37.
Problem
Apps have no reusable way to show persistent feedback inside a layout: an info, success, warning or error message with an optional title, an action and a way to dismiss it.
Change
InlineAlertin@geastack/elements, a function component built from plain views and native<button>elements. It follows the contract proposed in #2 (#67): placement inpackages/elements, controlled, class maps for state, the caller'sclasson the root, fixedinline-alert__*part classes, and nostyleprop.variant('info' | 'success' | 'warning' | 'error', default'info'),title,message,severityLabel,actionLabel,onAction,dismissible,dismissLabel,onDismiss,id,class. TheinlineAlertSeverityLabel(variant)helper is exported.severityLabeltakes a translation, and an empty string falls back to the default so the cue is never blank.dismissLabeldoes the same.dismissibleis set.onDismissand nothing else; the app removes the alert.role="status", orrole="alert"for errors. The browser target exposes it to screen readers; native targets ignore it.width: fit-contentwithmax-width: 100%. The actions row wraps, so in a narrow alert the dismiss button moves to a second line instead of pushing the action out of the row.components/index.tsexportsInlineAlertPropsandInlineAlertVariantas well asindex.d.ts. A native build resolves value imports toindex.ts, soimport { InlineAlert, type InlineAlertVariant }otherwise fails in geatsc with "has no exported member". The same gap in the existing components is fixed in Elements: Add a ProgressBar component #69 and Elements: Type VirtualList's item template as an element #71, and Docs: Document the component contribution contract #67 adds the rule to the contract.package.jsonmarks*.cssas side effects, the same change as Elements: Add a ProgressBar component #69.Tests
packages/core/test/run-gea-elements-inline-alert-pipeline.shbuilds an in-core fixture app (packages/core/test/fixtures/gea-elements-inline-alert). It needs no app from geastack/examples and does not depend on any other open PR.test_gea_elements_inline_alert_main.cppchecks, on the native engine:idandclassland on the root;undefined;onActionandonDismissfire once per press and only for their own alert;onDismissdoes nothing;Each of 29 mutations, applied one at a time, makes the test fail, including:
undefinedchecks, or the dismiss button always shown;id,classor the role dropped or misassigned;fit-content, noflex-wrap, nojustify-content, a reversed actions row, or different button padding;nowrapon the message or title.Other checks:
main(b2b1ac1):run-ui-memory-census.shneedsGEA_CENSUS_REFERENCE_ENGINE, andtest_gea_vite_module_graph_assets.mjsis fixed by Point the module-graph asset test's compiler at this checkout's Core #66. That suite run predates the last review fixes, which touch only InlineAlert's own files, fixture and test; after them the InlineAlert test was run again and passes.Target support
dev-web.mjs)--gea-font-charsetfit-contentsizing are honored is not verifiedLimitations
Related
apps/inline-alert. This PR's test does not need it, so either can merge first. The demo depends on@geastack/elements^0.1.6, which does not exportInlineAlert, so it type-checks only against this branch until a release. I've left the release to you.packages/elements/README.mdand thepackage.jsonexports, where both PRs add an entry, plus the identicalsideEffectschange. Whichever merges second needs a few lines of rebase, and I'll do it.