Commit Graph
295 Commits
Author SHA1 Message Date
ZacharyZhang-NY a6f9a7b77b Capture · Roots: the roots round 2 missed
A sweep that read every render found 28 roots still on w_full,
reached by 64 components: the field button under Select and every
picker, the checked and mention fields, the slider track,
NumberInput, Steps, the state views, the agent previews, and every
chart and finance frame. All drop it. LivePreview's size_full becomes
h_full, since its card no longer fills.

Every host of those roots was listed and read, 231 in all. Five
tests that mounted a picker as the window root sit in a size_full
box, the index manager gives its method select a flex_1 box, and the
notification center and the gallery's state frames stack their state
views in a column so they stretch.

Each dropped root carries a debug selector, and six chapter tests
mount 43 components in a padded card whose column is measured by
content, through layout::tests::narrow_width: each root must take the
full 240px. With w_full back on the roots, all six fail.

AGENTS.md names the roots that keep w_full and why: picture frames
that keep a ratio, and rows that hand a text field its share.
2026-09-28 19:34:01 -04:00
ZacharyZhang-NY ad98ca7746 Capture · Roots: the twelve roots round 1 found
Eleven more roots drop w_full: the docked ActionBar, MessageBubble's
three arms, PromptInput, TitleBar, Tabs, the horizontal Divider with
and without a label, DropZone and Playlist. Their hosts in the crate
are blocks or flex columns. The gallery's docked ActionBar sits in an
items_center column, so the demo gives it the width.

AspectRatio keeps w_full, and AGENTS.md says why: taffy 0.9 follows a
ratio from a set width, not from a stretch, and without one the image
gallery's tiles and the ratio demo collapsed.

Every page and scripted state was shot again at full width and at
280px and compared with the shots from before T44a. Nothing collapsed
or shrank. The mail reader's attachments now wrap side by side, as
their row asks.
2026-09-28 16:30:47 -04:00
ZacharyZhang-NY 81e73b79c1 Capture · Roots: roots drop w_full; hosts give the width
145 component roots drop w_full, the early returns included. Three
field rows keep it, Input, InputGroup and TagInput: stretched without
a width, taffy 0.9 laid the field's flex_1 share at no width in the
template picker at 280px, and the placeholder drew nothing. Container
keeps it, since mx_auto needs a width to fill.

Hosts that relied on a root's width now give it: MessageList boxes
each row at the list's width, the splash gives its bar the column's,
and test stages that mount a component as the window's root sit in a
size_full box. Tests hold a narrow row across the list and the splash
bar across its column; each goes red without its fix.

The gallery gains --narrow <px>, which lays each page in a padded
card at that width and shoots it without its script. The page
header wraps: the title takes the room and the theme switcher drops
below, where a long summary used to push it past the edge. A file
panel step waits for the panel to become key instead of a fixed
pause, which lost a race in a capture.
2026-09-28 13:07:22 -04:00
ZacharyZhang-NY 3be809a660 Tasks: split T44 into three 2026-09-28 09:12:25 -04:00
ZacharyZhang-NY 59f57c89c2 T43c Tooling · Catalogs passes review 2026-09-28 09:10:55 -04:00
ZacharyZhang-NY a7e492f28e Tooling · Catalogs: the audit reads active and code; avatar and container sizes
The audit now holds fg_subtle on active, a selected row's fill, and
each syntax color over the editor's surface, a code block and the
current line. What it found is fixed at the source: fg_subtle is
#696764 light and #94928f dark, syntax.comment follows it, and the
light number, constant and attribute darken to #a3591b, #aa5529 and
#9f5d12. The token viewer adds avatar and container sizes, draws a
container at its share of the widest so it stays in its row, and
names what it shows: the shared colors and scales. Tests pin every
variant, the hue each chart row reads and the code rows.
2026-09-28 08:57:52 -04:00
ZacharyZhang-NY d5271d03ea Tooling · Catalogs: token viewer, contrast audit; fg_subtle meets AA
DesignTokenViewer shows every token of the theme in the mode shown,
named as code reads it: colors with their hex, syntax, chart and
terminal colors, the type scale, radii, control and icon sizes,
elevations and spacing. A11yChecker audits each text color over the
surfaces it sits on at 4.5:1 and the focus ring and chart hues at
3:1, failures first. The audit found fg_subtle under 4.5:1 on hover
and overlay; it is #6f6d6a light and #8c8a87 dark now, and a test
holds all four Ely palettes to the audit. IconBrowser points to
forms::IconPicker and the ScreenshotTest Harness to the gallery's
capture, each with a section on the tooling page.
2026-09-28 08:23:39 -04:00
ZacharyZhang-NY bfd1285064 T43b Tooling · Inspection passes review 2026-09-28 08:05:26 -04:00
ZacharyZhang-NY 4d1a17d29a Tooling · Inspection: stalls count whole, the panel owns Tab, bound keys log
FpsMeter keeps the stamp before the last second, so a frame longer
than the span shows as the worst and a bar. The inspector's panel, a
second root out of the app's scope, sits in a FocusScope of its own,
so Tab goes on from Pick. EventLogger takes key downs through an
interceptor, which runs before bindings, and marks its box with a key
context to know focus is inside, so a field's Backspace and Enter log.
Tests hold the stall, Tab both ways through Pick, bound keys in a
field, a key while focus is outside, newest first and a bare border.
2026-09-28 07:54:54 -04:00
ZacharyZhang-NY 462e47b854 Tooling · Inspection: inspector, FPS meter, render counter and event logger
install_inspector draws gpui's debug inspector in Ely's look: a panel
with the picked box's source, ids and box model, and its margin,
border, padding and size drawn over the page through raise, since the
panel scrolls. FpsMeter counts frames on the executor's clock and
colors each by the frames it missed. RenderCounter counts the renders
of the view that draws it. EventLogger lists the input that reaches
what it holds, its canvas laid first so a child's stop hides nothing.
2026-09-28 07:13:12 -04:00
ZacharyZhang-NY 274089a8f6 T43a Tooling · Workbench passes review 2026-09-28 06:46:24 -04:00
ZacharyZhang-NY 8c038e2c24 Tooling · Workbench: the knobs seed the settings; knobs checked
The knobs join a layout::seeded seed, so a changed starting value,
option list or range starts every setting over, and a renamed knob
no longer fails. new() refuses no knobs, twin names and a number
outside its range. Controls are keyed by knob name. The test presses
keys without a refresh, so only a notify redraws, and walks the
switch twice, the slider twice and a pick the owner takes away.
2026-09-28 06:37:06 -04:00
ZacharyZhang-NY 1dbdafd056 Tooling · Workbench: a playground, and the gallery as the workbench
tooling::Playground lays a preview beside its knobs, each a switch, a
choice or a number that edits one property; the preview redraws from
the settings, which fail on a name or kind the knobs lack. The gallery
app is the ComponentGallery; its page 43 shows both.
2026-09-28 06:08:40 -04:00
ZacharyZhang-NY c9ff1f8f36 Tasks: split T43 into three 2026-09-28 06:03:22 -04:00
ZacharyZhang-NY 7ed840e02d T42g Misc · Export and import passes review 2026-09-28 06:03:05 -04:00
ZacharyZhang-NY 385faa0581 Misc · Export and import: reasons wrap; every way out tested
feedback::InlineMessage lays its words in a block that wraps, so the
importer's reason for unread text no longer runs past the dialog. The
reader skips a leading byte order mark, names the line an unclosed
quote opened on, and logs once per reading. Tests press each Cancel,
the scrim, Export with the first format, see focus return to the
opener, read new text under an open importer, and see a field with no
column come empty.
2026-09-28 05:50:28 -04:00
ZacharyZhang-NY 79fe78cefd Misc · Export and import: export, field mapping and a CSV importer
misc::ExportDialog offers the owner's formats as cards and hands the
chosen one over for the owner to write. misc::ImportDialog maps the
file's columns to the app's fields, matched by name to start, over a
preview, and asks for each required field's column. misc::CsvImporter
reads CSV as RFC 4180, lets the first row name the columns or not, and
maps it through the ImportDialog into records; text that does not read
says why.
2026-09-28 05:20:03 -04:00
ZacharyZhang-NY cbba4ddeec T42f Misc · Web passes review
in_view names its types in place and the non-macOS branch reads its fields, so builds off macOS stay free of warnings.
2026-09-28 05:07:35 -04:00
ZacharyZhang-NY c7c4c006a7 Misc · Web: the web view hands the keyboard back
WKWebView takes AppKit's first responder on a press and gpui's view
never asks for it back, so typed text went to the page for good. The
web view now hands it back through wry's focus_parent on every press
gpui gets and when its page drops. The gallery proves it with a native
key after a press on the page. in_view builds only where it is used,
its test covers a box that straddles the view's top, and the embed's
frame takes the card's bottom corners.
2026-09-28 04:59:11 -04:00
ZacharyZhang-NY 012a6e3105 Misc · Web: a web view proven with wry, and an iframe embed
misc::WebView lays wry 0.57's child WKWebView over the window at its
box, following it from a canvas in prepaint and hiding it out of view;
it loads an address or the owner's HTML, which makes it the HTML
preview. misc::IframeEmbed frames a page under its address with Open
in browser. EmbedCard points to chat::LinkPreviewCard, ShareSheet to
buttons::ShareButton; PrintButton is blocked, gpui 0.2.2 has no print
API.
2026-09-28 04:32:26 -04:00
ZacharyZhang-NY a978f7a6eb T42e Misc · Terms and notices passes review
A test walks Shift-Tab round the cookie banner past the resting Necessary switch.
2026-09-28 04:25:31 -04:00
ZacharyZhang-NY 8794a42d42 Misc · Terms and notices: tests for every way out; switch labels wrap
Tests now press Decline and the scrim, see focus return to the opener
after Accept, see necessary cookies stay on and off the Tab path, and
see the license list mark its row and read each version and license.
lists::ListItem marks its description and selected state for tests.
forms::Switch's label wraps in its own block, as Checkbox's does.
Ely's own row in the gallery shows both of its license texts.
2026-09-28 04:09:49 -04:00
ZacharyZhang-NY 2837c802b5 Misc · Terms and notices: licenses, consent and a cookie banner
misc::LicenseViewer lists what a product ships with each license beside
the chosen one's text. misc::ConsentDialog asks for a box before Accept
and answers each way out once, accept or decline. misc::CookieBanner
takes Accept all, Reject all, or a switch per kind through Choose, which
turns into Save choices on its focus. ChangeLog Viewer points to
data_display::Changelog.
2026-09-28 03:36:03 -04:00
ZacharyZhang-NY 320ab4ae3a T42d Misc · Asking and learning passes review
The poll's mark and its row's selector share one binding.
2026-09-28 03:24:15 -04:00
ZacharyZhang-NY 46aa381eee Misc · Asking and learning: Submit never rests; radio labels wrap
Survey's Submit asks for any missing answer instead of resting, so no
untick takes its focus handle out of the tree. Flashcards turn and go
round, and a quiz pick clears its ask, through methods the tests reach;
the poll's rows show which one holds the vote. forms::Radio's label
wraps in its own block, as Checkbox's does, so a long one stays in a
narrow box.
2026-09-28 03:11:52 -04:00
ZacharyZhang-NY 86c9de7d0a Misc · Asking and learning: a poll, a survey, a quiz and flashcards
misc::Poll turns to results once the owner holds the vote, with Change
vote on Vote's stop. misc::Survey asks on one page and sends when each
question is answered, thanking in Submit's place and focus. misc::Quiz
checks, goes on, scores and starts again on one button. misc::Flashcards
turn on a press and go round the deck, each face fading in.
2026-09-28 02:38:33 -04:00
ZacharyZhang-NY a213248910 T42c Misc · Codes and checks passes review
Tests now hold focus in the field after an answer and a passed captcha with no Tab stop.
2026-09-28 02:22:34 -04:00
ZacharyZhang-NY a184b4ef9a Misc · Codes and checks: the captcha keeps focus through every verdict
Verify never rests, so no verdict or new ask takes its focus handle out
of the tree; with nothing typed it sends focus to the field. Enter hands
nothing over while the owner checks. A pass moves focus from the resting
field to the Verified mark, so the field shows no ring and no caret.
2026-09-28 02:05:44 -04:00
ZacharyZhang-NY fd052086eb Tasks: the website's home page, components page and Cloudflare deploy 2026-09-28 01:40:15 -04:00
ZacharyZhang-NY 692fae6244 Misc · Codes and checks: a QR code scanner and a captcha
misc::QrCodeScanner reads QR codes with rqrr 0.11 from the frames the
host hands in, one at a time off the main thread, and hands each code
to the owner once. misc::Captcha shows the owner's picture over an
answer field that empties and keeps focus with each answer; the owner
says how it stood. BarcodeDisplay, Signature and Rating Widget point
to their homes.
2026-09-28 01:40:15 -04:00
ZacharyZhang-NY dc4911a68f T42b Misc · Numbers passes review 2026-09-28 01:14:17 -04:00
ZacharyZhang-NY 5e7fc24db9 Misc · Numbers: a result goes on whole; long readings wrap
A calculator result stays in the sum as `a`, handed to evaluate with
its whole value, so 1 ÷ 3 = × 3 = gives 1; sign turns it and delete
takes it. Equals waits on a dangling operator. The converter's reading
wraps in its box rather than ending in an ellipsis, and tests hold
Control, the = key, a point after a result and the six digits.
2026-09-28 01:06:32 -04:00
ZacharyZhang-NY 73f3399cea Misc · Numbers: a calculator and a unit converter
misc::Calculator works a typed sum in forms::evaluate's precedence,
from a pad or the keyboard; Enter is equals while the calculator
itself has focus, and Escape clears or passes on. misc::UnitConverter
reads an amount in another unit across seven kinds, with a swap.
Both show numbers through format::significant, which rounds through
Rust's exponent form.
2026-09-28 00:41:49 -04:00
ZacharyZhang-NY d1345cd14e T42a Misc · Time passes review 2026-09-28 00:30:00 -04:00
ZacharyZhang-NY b586300f0e Misc · Time: Lap turns Reset, laps and tickers tested
The stopwatch's second button reads Lap while running and Reset once
paused, on one focus handle, and Reset hands focus to Start, so no
press leaves focus stranded. Lap rows carry selectors; tests hold
their order and times, count the tickers' wakes, and a WorldClock
without places fails.
2026-09-28 00:21:23 -04:00
ZacharyZhang-NY 45ae161c18 Misc · Time: clocks and a stopwatch
misc::Clock shows the time in a zone, the system's unless told, as an
analog face with hour marks and three hands over its digits and a
label; it wakes its view at each whole second of the wall clock, and
only while the owner passes no moment. misc::WorldClock lays places in
rows: a small face, the place, how its day and hour stand against home,
and its time. misc::Stopwatch runs on the executor's clock in tenths,
holds while paused, marks laps while running and clears once paused;
Start and Pause share one button and its focus.
2026-09-27 23:51:58 -04:00
ZacharyZhang-NY 4777cd666b Tasks: split T42 into seven 2026-09-27 23:44:24 -04:00
ZacharyZhang-NY e97850163f T41c Maps · World passes review 2026-09-27 23:42:16 -04:00
ZacharyZhang-NY d52ca0e6a9 Maps · World: marks in their wash, the legend clear of the credit
A choropleth's points and lines now draw in their wash, as its doc
says, while its areas keep the page's color at their edges. The legend
moves to the top left, so the attribution a license asks for stays clear
at any width. A key given twice fails. WorldMap's keying by ISO code,
its Natural Earth credit and its acceptance of the bundle's codes, as
Kosovo's XK, each have a test; so does an endless value.
2026-09-27 23:35:04 -04:00
ZacharyZhang-NY a4ca1f04d4 Maps · World: choropleths and the world's countries
ChoroplethLayer washes each area by its value, keyed by its id or a
property's text or number, on one hue's scale from its faintest at the
least value to its strongest at the most; an area without a value reads
as no data. ChoroplethMap lays it on the owner's map, with or without
tiles, and puts a legend of the scale and of no data in the corner; a
value that matches no area is logged once. WorldMap washes Natural
Earth's 110m countries, bundled trimmed by scripts/countries.py, by ISO
3166 alpha-2 code, and fails on a key that is no code. A shape now
paints as one fill and one edge path per world in view.
2026-09-27 23:12:27 -04:00
ZacharyZhang-NY a64b78b673 T41b Maps · Layers passes review 2026-09-27 23:01:43 -04:00
ZacharyZhang-NY 3e5c5f37ba Maps · Layers: tests hold what clusters promise
Tests hold that a pan keeps a focused cluster, that a cluster away from
the view takes no Tab, that a zoom out folding a focused pin hands its
focus to the map, and that a press shows members far apart whole. The
heat test pins the quartic kernel's value halfway out; a ring of fewer
than four positions fails with its own reason, and has a test.
2026-09-27 22:57:05 -04:00
ZacharyZhang-NY e3a96b04e0 Maps · Layers: routes, GeoJSON, heat and clusters
MapView takes layers over its tiles and under its pins. RouteLine runs
along places the short way across the date line. read_geojson reads RFC
7946 to features, strictly: a position past the globe, a line of one
position or a ring that does not close fails with its reason, and a
feature placed nowhere keeps no geometry. GeoJsonLayer washes areas as
one path per polygon, so holes stay open, outlines them, strokes lines
and dots points. GeoHeatmap spreads weighted places in a quartic kernel
over small cells, scaled to the densest spot in view. Lines and areas
unwrap across the date line and repeat on every world in view.
cluster_markers gathers pins by squares of the world, so a pan keeps
each group; a cluster shows its count, and its press shows its members
whole, never farther out. A zoom that may regroup them hands a focused
pin's or cluster's focus to the map.
2026-09-27 22:35:40 -04:00
ZacharyZhang-NY 91a0fc2252 T41a Maps · View passes review 2026-09-27 22:20:08 -04:00
ZacharyZhang-NY d1202a88e2 Maps · View: a focused pin keeps focus off view
Each pin holds a keyed focus handle of its own, a Tab stop and pressable
while its place is in view, so a focused pin that pans out of view keeps
focus and the arrows go on panning, and a popup that scrolls away hands
focus back to its pin wherever it lies. A popup whose place is off view
takes no focus. Tests hold the tall card's cap and scrolling body, the
map staying under its wheel, and markers refuse a repeated key.
2026-09-27 22:14:42 -04:00
ZacharyZhang-NY 5f1c8ff46a Maps · View: pins in view take presses, the popup hands focus back
A pin whose place lies outside the view takes no press or Tab, as its
popup would not show. The popup takes focus when it shows and, the
frame it stops showing by its button, Escape, the owner or a pan, hands
focus back to what held it, so focus stays in the map. Its body scrolls
past the room on its side and it paints over the zoom buttons. Tiles
load through gpui's logging loader, so a tile that fails says so. A
drag's owner check has a test, and the per-move viewport logs at debug.
The maps tests split into the map's and the popup's.
2026-09-27 21:57:27 -04:00
ZacharyZhang-NY 931e0ed6f5 Maps · View: host tiles, pins and a popup, a picker, coordinates
maps::MapView lays the host's tile for each zoom, column and row in Web
Mercator, the nearest cut scaled past the zooms it serves, on whole
pixels. gpui packs pictures in its atlas without padding and samples
them linearly, so each tile draws with a one-pixel rim copied from its
own edge, one of its pixels larger each side and clipped, and no seam
shows. A drag, the wheel or the arrows pan; Command-wheel, + and - or
its buttons zoom about the pointer or the center; the owner keeps the
viewport. MapMarker pins take a press and Enter when the map hears
them; MapPopup opens toward the map's larger half and stays inside it,
closing by its button or Escape. LocationPicker picks the place under a
center crosshair; CoordinateDisplay writes degrees or degrees, minutes
and seconds with tabular figures and a copy button. The gallery's tiles
are Natural Earth's countries, cut z0 to z3 by scripts/tiles.py.
2026-09-27 21:22:50 -04:00
ZacharyZhang-NY 090520a9f1 Tasks: split T41 into view, layers and world 2026-09-27 20:57:30 -04:00
ZacharyZhang-NY 2863e4fde2 T40b a11y passes review 2026-09-27 20:52:32 -04:00
ZacharyZhang-NY 4aaff497fd Gallery: a blocked note wraps beside its dot
blocked() laid its text as a flex item beside the dot, and gpui measures
a text item's least width unwrapped, so a long note ran past its column
and the dot shrank to nothing. The text now sits in a flex_1 block with
no least width beside a dot that never shrinks, which rests on the first
line, as Alert holds its icon. The a11y note and the motion page's
Lottie note wrap inside their columns. A failed hue check names both
charts in hex.
2026-09-27 20:42:19 -04:00