Repository navigation
Conversation
The e-reader's opening modal draws its progress as a track and a fill whose pixel width the app store computes by hand, and the native <progress> tag is drawn as an empty box on pixel targets. There was no reusable bar. ProgressBar is a function component built from plain views. The app owns value, min and max. The fill width is the clamped fraction as a percentage, so out-of-range values, empty or inverted ranges and NaN draw as empty or full rather than overflowing, and the bar follows its container when it is resized. The clamping is exported as progressFraction. indeterminate swaps the fill for a CSS keyframe sweep that the track clips; reducedMotion replaces the sweep with a still, dimmed fill, since the engine has no prefers-reduced-motion media feature. The sweep exists only while the indeterminate class is on, so it stops as soon as the bar leaves that mode. The caller's class goes on the root and the parts use fixed progress-bar__ classes. There is no style prop: geatsc has no rule for forwarding a Style object through a function component. The README and .d.ts state the limits: only the value is clamped, the bar exposes no role or value to assistive technology and takes no keyboard input, and the sweep distance is fixed in pixels when the animation starts. The elements package marks *.css as side effects, since this is its first module that imports a stylesheet and a bundler could drop it under sideEffects: false. The demo in geastack/examples depends on @geastack/elements ^0.1.6, which does not export ProgressBar, so it type-checks only against this checkout until an elements release ships the component. Tests: added run-gea-progress-bar-pipeline.sh, which builds examples/apps/progress-bar and taps its buttons. It checks the initial 40%, stepping, values above max and below min, a zero range, resizing and the label. It checks the demo's fixed bars: no props, the default range, a fractional value, an empty label that takes no space, a negative range, an inverted range and NaN. Besides layout pixels it reads the fill's authored width (width_percent, per-mille) exactly, since layout rounds to pixels and clamps a negative width to 0, and it reads progressFraction's NaN result from the demo's label, since a native build parses "NaN%" as 0. It finds the bar by id. Over one sweep cycle it checks that the fill starts left of the track, travels past 70% of it and never paints beside the track. It checks that reduced motion stays still and dimmed, that the sweep stops when indeterminate is cleared, and that the fill sits at the start of the track in both cases. It reads pixels as the display's native pixel type. It passes locally on macOS with Homebrew bash 5, and the full core suite gives the same result as main apart from the new test. Each of these mutations, applied one at a time, makes it fail: no upper clamp, reducedMotion ignored, the label always shown, default min 10, default value 50, no overflow:hidden, no static opacity, the sweep starting or ending at 0%, range === 0 instead of !(range > 0), whole-percent rounding, a NaN-only lower guard, fraction <= 0 instead of !(fraction > 0), NaN mapped to 0.5, and id not forwarded to the root.
|
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 |
A native build resolves value imports of @geastack/elements to
components/index.ts, not index.d.ts. index.ts exported ProgressBar and
progressFraction but not the props type, so an app that wrote
`import { ProgressBar, type ProgressBarProps }` from
'@geastack/elements' type-checked but failed to compile natively with
"has no exported member named 'ProgressBarProps'". index.ts now
re-exports the type as index.d.ts does.
Tests: a scratch app importing ProgressBar and ProgressBarProps this
way, built with run-gea-native-app-pipeline.sh: fails with that error
before the change, builds and mounts after it.
run-gea-progress-bar-pipeline.sh still passes.
|
Pushed d90a9e0: |
Closes #42.
Problem
The e-reader's opening modal draws its progress as a track and a fill whose pixel width the store computes by hand, and the native
<progress>tag is drawn as an empty box on the pixel engine. There is no reusable progress bar.Change
ProgressBarin@geastack/elements, a function component built from plain views, following the contract proposed in #2 (placement inpackages/elements, controlled value, class maps for state, the caller'sclasson the root and fixedprogress-bar__*part classes).value,min(default 0),max(default 100),indeterminate,reducedMotion,label,id,class.progressFraction(value, min, max).indeterminatereplaces the fill with a CSS keyframe sweep that animatesleft, nottransform, and the track clips it. The sweep only exists while the indeterminate class is on, so it stops as soon as the bar leaves that mode.reducedMotionreplaces the sweep with a still, dimmed full-width fill. The engine has noprefers-reduced-motionmedia feature, so the app decides.styleprop. AStyleobject forwarded to a JSXstyleattribute fails to compile as C++, so the bar is sized and placed throughclass.packages/elements/package.jsonmarks*.cssas side effects.ProgressBar.tsxis the first module in the package that imports a stylesheet, and undersideEffects: falseanother bundler could drop it.Tests
packages/core/test/run-gea-progress-bar-pipeline.shbuildsapps/progress-barfrom geastack/examples (companion PR: geastack/examples#3) through the embedded pipeline and drives it with taps.test_gea_progress_bar_main.cppchecks:maxand belowmin, a zero range, resizing and the label;width_percent, per-mille) exactly as well as its layout pixels. Layout rounds to whole pixels and clamps a negative width to 0, so a pixel check alone cannot tell 33.3% from 33% or -20% from 0%;NaN%as 0;idreaching the root;indeterminateis cleared, and the fill then sits at the start of the track.Each of these mutations of
ProgressBar.tsx, applied one at a time, makes the test fail: no upper clamp,range === 0instead of!(range > 0), whole-percent rounding, a NaN-only lower guard,fraction <= 0instead of!(fraction > 0), NaN mapped to 0.5,idnot forwarded,reducedMotionignored, the label always shown, defaultmin10, defaultvalue50, nooverflow: hidden, no static opacity, and the sweep starting or ending at 0%.The full core suite, run test by test on macOS with Homebrew bash 5, gives 153/155 on this branch and the same result as
mainapart from the new test. The two failures fail onmaintoo:run-ui-memory-census.shneedsGEA_CENSUS_REFERENCE_ENGINE, andtest_gea_vite_module_graph_assets.mjsis fixed by #66.Target support
dev-web.mjs)ReaderStore.ts); not verified on hardwaredivandspan. Not checked whether these renderers run CSS keyframe animationsLimitations
label.indeterminateis toggled (documented in the.d.tsand README).Merge order and release
The test needs
apps/progress-barfrom geastack/examples, andrun-tests.shpicks the new script up automatically, so geastack/examples#3 should merge first. That app depends on@geastack/elements^0.1.6, which does not exportProgressBar, so it type-checks against this branch but not against the published package. I've left the elements release to you.