Every page and scripted state was shot with gpui 0.2.2 and with the port, light and dark, full width and at 280px, judged pair by pair by agents with skeptics, and every page's log diffed. What differed is fixed, each with a test that fails without it where the test platform can show it: - The gallery's harness takes posted mouse moves (gpui_macos listens to a tracking area), posts each drag move twice (it no longer replays a held drag), and waits three frames before each shot. - Rolling digits: a block column, so taffy 0.13 lends the cell no baseline, and a line of whole device pixels, since gpui snaps each length on its own. DescriptionList's row aligns ends. - Margins that taffy 0.13 collapses through a plain block: the drawer's pull and snap, the stagger and transition rise, the dialog and palette rises, the fullscreen dialog's slide. - An Input keeps room to type in a squeezed row; the field rows drop w_full, whose reason was taffy 0.9's. AGENTS.md's rules that named gpui 0.2.2 or taffy 0.9 were re-tested against both sources and rewritten, and new ones say what the port changed. TASKS.md's tags follow: what the new gpui makes possible is prove. Captions, doc comments and README say what holds now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
381 lines
14 KiB
Markdown
381 lines
14 KiB
Markdown
# Chapters 1–10
|
||
|
||
## T01 Primitives — `src/primitives`
|
||
|
||
- [x] Box / View — native `div()`
|
||
- [x] Text — native: strings and `StyledText` are elements
|
||
- [x] Icon (T00)
|
||
- [x] IconSet / IconRegistry (T00)
|
||
- [x] Svg — native `svg()`
|
||
- [x] Image — loading, failed, placeholder over `img()`
|
||
- [x] Canvas — native `canvas()`
|
||
- [x] Divider / Separator
|
||
- [x] Spacer — native `div().flex_1()`
|
||
- [x] Portal — native `deferred(anchored())`
|
||
- [x] Overlay / Backdrop
|
||
- [x] Slot — native `impl IntoElement` params and `ParentElement`
|
||
- [x] Show / When — native `.when()` / `.when_some()`
|
||
- [x] For / Each — native `.children(iter)`
|
||
- [x] Fragment — native: children take iterators
|
||
- [ ] VisuallyHidden — prove: gpui builds an AccessKit tree on macOS, Windows and Linux, not the web, from elements with an id and a `role`; a box that draws nothing, with an `aria_label`, must reach the macOS tree with its label
|
||
- [x] FocusRing
|
||
- [x] FocusScope / FocusTrap
|
||
- [x] ClickOutside — native `on_mouse_down_out`
|
||
- [x] HoverArea — native `on_hover` / `.hover()`
|
||
- [x] Pressable — press state, long press
|
||
- [x] KeyboardHandler — native `on_key_down` / `on_action`
|
||
- [x] Measure
|
||
- [x] ResizeObserver → `primitives::Measure`
|
||
- [x] IntersectionObserver
|
||
- [x] Clipboard — native `write_to_clipboard` / `read_from_clipboard`
|
||
- [x] Tooltip Trigger — owns `Tooltip`: delay, follow mouse, rich content
|
||
|
||
## T02 Typography — `src/typography`
|
||
|
||
- [x] Heading (H1–H6)
|
||
- [x] Title / Subtitle
|
||
- [x] Paragraph
|
||
- [x] Label
|
||
- [x] Caption
|
||
- [x] Overline
|
||
- [x] Code
|
||
- [x] Kbd — ⌘ / Ctrl by platform
|
||
- [x] KbdCombo
|
||
- [x] Blockquote
|
||
- [x] Highlight / Mark
|
||
- [x] Truncate → `typography::Ellipsis`; gpui's `.truncate()` holds only in a block of fixed width
|
||
- [x] LineClamp — native `.line_clamp(n)`
|
||
- [x] MiddleEllipsis
|
||
- [x] EllipsisTooltip
|
||
- [x] Link
|
||
- [x] ExternalLink
|
||
- [x] RelativeTime
|
||
- [x] DateTimeText
|
||
- [x] NumberText
|
||
- [x] CurrencyText
|
||
- [x] PercentText
|
||
- [x] FileSizeText
|
||
- [x] DurationText
|
||
- [x] PluralText
|
||
- [x] CopyableText
|
||
- [x] SelectableText — prove: selection over `StyledText` layout
|
||
- [x] Emoji — shortcodes
|
||
- [x] Latex / MathInline — prove: TeX subset
|
||
- [x] AnimatedNumber
|
||
- [x] Typewriter
|
||
- [x] GradientText — per-glyph tonal ramp
|
||
- [x] ShimmerText
|
||
|
||
## T03 Layout — `src/layout`
|
||
|
||
- [x] Stack / HStack / VStack
|
||
- [x] Flex — native `.flex()`
|
||
- [x] Grid / GridItem — native `.grid()`, `.col_span()`
|
||
- [x] SimpleGrid
|
||
- [x] Masonry
|
||
- [x] Center — native `.flex().items_center().justify_center()`
|
||
- [x] Container
|
||
- [x] AspectRatio
|
||
- [x] Inset / Padding — native `.p_*()`
|
||
- [x] Wrap — native `.flex_wrap()`
|
||
- [x] Absolute / Positioned — native `.absolute()`
|
||
- [x] Layer / ZStack
|
||
- [x] ScrollArea
|
||
- [x] Scrollbar
|
||
- [x] ScrollShadow
|
||
- [x] ScrollToTop
|
||
- [x] StickyHeader
|
||
- [x] SplitPane — horizontal, vertical, nested
|
||
- [x] ResizablePanel / ResizablePanelGroup → `layout::SplitPane`
|
||
- [x] ResizeHandle
|
||
- [x] Collapsible
|
||
- [x] Accordion / AccordionItem
|
||
- [x] Card / CardHeader / CardBody / CardFooter
|
||
- [x] Panel / PanelHeader
|
||
- [x] Section / SectionHeader
|
||
- [x] Group / Fieldset
|
||
- [x] Frame
|
||
- [x] Well
|
||
- [x] Sidebar
|
||
- [x] Drawer
|
||
- [x] Sheet
|
||
- [x] Page / PageHeader / PageContent
|
||
- [x] AppShell
|
||
- [x] MasterDetail
|
||
- [x] ThreeColumnLayout → `layout::SplitPane`
|
||
- [x] Dock / DockPanel
|
||
- [x] DockZone / DropIndicator
|
||
- [x] FloatingPanel
|
||
- [x] Pane / PaneGroup
|
||
- [x] Workspace — versioned layout snapshot
|
||
- [x] Viewport
|
||
|
||
## T04 Window & Shell — `src/shell`
|
||
|
||
- [x] TitleBar
|
||
- [x] WindowControls — macOS, Windows, Linux
|
||
- [x] TrafficLights → `shell::WindowControls`
|
||
- [x] WindowDragRegion — `shell::drag_region`: native drag area, Linux move, double-click zoom
|
||
- [x] WindowResizeBorder — `shell::ResizeBorder`: client decorations only; macOS and Windows resize natively
|
||
- [x] MenuBar → `menus::MenuBar` (T08b): the NativeMenu definitions, drawn in the window
|
||
- [x] NativeMenu — native `cx.set_menus()`
|
||
- [x] Toolbar / ToolbarGroup / ToolbarSeparator
|
||
- [x] StatusBar / StatusBarItem
|
||
- [x] ActivityBar
|
||
- [x] NavigationRail → `shell::ActivityBar`
|
||
- [x] TabBar
|
||
- [x] SplashScreen
|
||
- [x] AboutDialog
|
||
- [x] TrayIcon / TrayMenu — macOS `NSStatusItem`; other systems get an error
|
||
- [x] DockBadge — macOS dock tile; other systems get an error
|
||
- [x] JumpList — native `cx.set_dock_menu()`
|
||
- [ ] SystemNotification — prove: on macOS `cx.show_system_notification` posts only from an app bundle; unbundled, as `cargo run` starts it, gpui logs and drops the call, so Ely must check the bundle identifier and fail loud. A bundled gallery must post one and hand its response to the owner through `on_system_notification_response`
|
||
- [x] MultiWindow Manager
|
||
- [x] WindowSwitcher
|
||
- [x] QuickLauncher → `navigation::QuickLauncher` (T07c): a SearchPalette in an always-on-top window
|
||
- [x] MiniWindow / CompactMode
|
||
- [x] AlwaysOnTop — native `WindowKind::PopUp`
|
||
- [x] PictureInPicture → `shell::MiniWindow` at a screen corner; the host supplies the view
|
||
- [x] UpdateBanner / UpdateDialog
|
||
- [x] CrashReporter
|
||
- [x] OfflineIndicator
|
||
- [x] ZoomControl
|
||
|
||
## T05 Buttons & Actions — `src/buttons`
|
||
|
||
- [x] Button (T00)
|
||
- [x] IconButton (T00)
|
||
- [x] ButtonGroup
|
||
- [x] SplitButton → `menus::SplitButton` (T08a): its dropdown is a Menu
|
||
- [x] DropdownButton / MenuButton → `menus::DropdownMenu` (T08a)
|
||
- [x] ToggleButton
|
||
- [x] ToggleGroup
|
||
- [x] SegmentedControl
|
||
- [x] FloatingActionButton
|
||
- [x] LoadingButton → `buttons::Button` loading state, lands with Spinner (T11)
|
||
- [x] ConfirmButton — hold or click twice
|
||
- [x] HoldToConfirm → `buttons::ConfirmButton`
|
||
- [x] CopyButton
|
||
- [x] ShareButton
|
||
- [x] CloseButton
|
||
- [x] BackButton
|
||
- [x] MoreButton
|
||
- [x] ActionBar
|
||
- [x] BulkActionBar
|
||
- [x] ActionSheet
|
||
- [x] QuickActions
|
||
- [x] ShortcutHint → `buttons::Button::shortcut`
|
||
|
||
## T06a Forms · Text — `src/forms`
|
||
|
||
- [x] Input / TextField
|
||
- [x] TextArea → `forms::TextInput::multi_line`
|
||
- [x] PasswordInput
|
||
- [x] SearchInput
|
||
- [x] NumberInput
|
||
- [x] ScrubInput
|
||
- [x] CurrencyInput → `forms::NumberInput::currency`
|
||
- [x] PercentInput → `forms::NumberInput::percent`
|
||
- [x] UnitInput
|
||
- [x] EmailInput
|
||
- [x] UrlInput
|
||
- [x] PhoneInput
|
||
- [x] MaskedInput
|
||
- [x] PinInput / OTPInput
|
||
- [x] InlineEdit / EditableText
|
||
- [x] InputGroup / InputAddon
|
||
- [x] ClearableInput → `forms::Input::clearable`
|
||
- [x] AutoResizeInput → `forms::TextInput::multi_line`
|
||
- [x] MentionInput
|
||
- [x] HashtagInput → `forms::MentionInput` with `#`
|
||
- [x] TagInput / TokenInput
|
||
- [x] KeyValueInput
|
||
- [x] ListInput
|
||
- [x] PathInput — native dialog via `prompt_for_paths`
|
||
- [x] RegexInput
|
||
- [x] ExpressionInput
|
||
- [x] HotkeyInput / ShortcutRecorder
|
||
|
||
## T06b Forms · Selection
|
||
|
||
- [x] Checkbox
|
||
- [x] CheckboxGroup
|
||
- [x] CheckboxCard
|
||
- [x] Radio / RadioGroup
|
||
- [x] RadioCard
|
||
- [x] Switch / Toggle
|
||
- [x] Select
|
||
- [x] NativeSelect — blocked: gpui has no native popup menu
|
||
- [x] Combobox
|
||
- [x] Autocomplete → `forms::Combobox::free`
|
||
- [x] MultiSelect
|
||
- [x] CascadeSelect / Cascader
|
||
- [x] TreeSelect → `lists::TreeSelect` (T13b): forms cannot import lists
|
||
- [x] TransferList
|
||
- [x] ListBox
|
||
- [x] ChoiceChips / FilterChips
|
||
- [x] Rating
|
||
- [x] Slider
|
||
- [x] RangeSlider
|
||
- [x] VerticalSlider → `forms::Slider::vertical`
|
||
- [x] Knob / Dial
|
||
- [x] Stepper
|
||
|
||
## T06c Forms · Date & Time
|
||
|
||
- [x] Calendar
|
||
- [x] DatePicker
|
||
- [x] DateRangePicker
|
||
- [x] TimePicker
|
||
- [x] DateTimePicker
|
||
- [x] MonthPicker / YearPicker / QuarterPicker
|
||
- [x] WeekPicker
|
||
- [x] RelativeDatePicker
|
||
- [x] TimezoneSelect
|
||
- [x] DurationPicker
|
||
- [x] CronEditor
|
||
|
||
## T06d Forms · Color
|
||
|
||
- [x] ColorPicker — HSV, RGB, HEX, alpha → `forms::ColorPicker`
|
||
- [x] ColorSwatch → `forms::ColorSwatch`
|
||
- [x] ColorPalette → `forms::ColorPalette`
|
||
- [x] EyeDropper — proved: `NSColorSampler`; sRGB read tested (`read_srgb`), the sampler draws out of process → `forms::EyeDropper`
|
||
- [x] GradientEditor → `forms::GradientEditor`
|
||
|
||
## T06e Forms · Files
|
||
|
||
- [x] FilePicker / FileInput → `forms::FileInput`
|
||
- [x] FolderPicker → `forms::PathInput::directories` (T06a)
|
||
- [x] DropZone → `forms::DropZone`
|
||
- [x] UploadList → `forms::UploadList`, built with Loading & Motion (T11b): its rows are ProgressBars
|
||
- [x] ImageUpload — preview, crop → lands with Media (T26): its crop is the ImageCropper
|
||
- [x] AvatarUpload → `forms::AvatarUpload`, built with Data Display (T12a): it is an Avatar you replace
|
||
|
||
## T06f Forms · Other
|
||
|
||
- [x] SignaturePad → `forms::SignaturePad`
|
||
- [x] CodeInput → `forms::CodeInput`, colored by `code_highlights`
|
||
- [x] JsonInput → `forms::JsonInput`, colored by `json_highlights`
|
||
- [x] FontPicker → `forms::FontPicker`
|
||
- [x] IconPicker → `forms::IconPicker`
|
||
- [x] EmojiPicker → `forms::EmojiPicker`
|
||
- [x] LanguageSelect → `forms::Combobox::languages`
|
||
- [x] CountrySelect → `forms::Combobox::countries`
|
||
- [x] CurrencySelect → `forms::Combobox::currencies`
|
||
|
||
## T06g Forms · Structure
|
||
|
||
- [x] Form → `forms::Form`, Cmd-Enter submits
|
||
- [x] FormField → `forms::FormField`
|
||
- [x] FormLabel — required mark, help tip → `forms::FormLabel`
|
||
- [x] FormDescription / HelperText → `typography::Caption`, placed by `FormField::description`
|
||
- [x] FormError / ValidationMessage → `forms::FormError`
|
||
- [x] FormSection → `forms::FormSection`
|
||
- [x] FormActions → `buttons::ActionBar`
|
||
- [x] FieldArray → `forms::FieldArray`; ListInput and KeyValueInput use it
|
||
- [x] InlineForm → `forms::InlineForm`
|
||
- [x] WizardForm / MultiStepForm → lands with Navigation (T07): its frame is the Wizard
|
||
- [x] DirtyIndicator → `forms::DirtyIndicator`
|
||
|
||
## T07a Navigation · Tabs & paths — `src/navigation`
|
||
|
||
- [x] Tabs — top, left, bottom → `navigation::Tabs`
|
||
- [x] EditorTabs → `navigation::EditorTabs`
|
||
- [x] TabOverflowMenu → `navigation::TabOverflowMenu`
|
||
- [x] Breadcrumb → `navigation::Breadcrumb`
|
||
- [x] Pagination → `navigation::Pagination`
|
||
- [x] LoadMore → lands with Loading (T11a): its busy state is a Spinner
|
||
- [x] Stepper / Steps / Wizard → `navigation::Steps`, `navigation::Wizard`; also T06g WizardForm
|
||
|
||
## T07b Navigation · Places
|
||
|
||
- [x] Sidebar Navigation / NavItem / NavGroup → `navigation::NavItem`, `navigation::NavGroup`
|
||
- [x] NavigationMenu → `navigation::NavigationMenu`
|
||
- [x] ActivityBar Item → `shell::ActivityBar`
|
||
- [x] BackForwardNavigation → `navigation::BackForwardNavigation`
|
||
- [x] History Navigation → `navigation::BackForwardNavigation`
|
||
- [x] Anchor / TableOfContents → `navigation::Anchor`, `navigation::TableOfContents`
|
||
- [x] JumpTo / GoToLine → `navigation::GoToLine`
|
||
|
||
## T07c Navigation · Palettes & tour
|
||
|
||
- [x] CommandPalette → `navigation::CommandPalette`
|
||
- [x] QuickOpen → `navigation::QuickOpen`
|
||
- [x] QuickSwitcher → `navigation::QuickSwitcher`
|
||
- [x] SearchPalette → `navigation::SearchPalette`
|
||
- [x] SpotlightSearch → `navigation::SearchPalette`; T04 QuickLauncher opens it always on top
|
||
- [x] Tour / Onboarding → `overlays::Tour` (T09b): its steps are Spotlights
|
||
|
||
## T08a Menus · Menu & hosts — `src/menus`
|
||
|
||
- [x] Menu / MenuItem / MenuGroup / MenuSeparator → `menus::Menu` (`group`, `separator`), `menus::MenuItem`
|
||
- [x] SubMenu → `menus::MenuItem::submenu`
|
||
- [x] CheckboxMenuItem → `menus::MenuItem::check`
|
||
- [x] RadioMenuItem → `menus::MenuItem::radio`
|
||
- [x] MenuItemShortcut → `menus::MenuItem::keys`
|
||
- [x] MenuItemIcon → `menus::MenuItem::icon`
|
||
- [x] ContextMenu → `menus::ContextMenu`
|
||
- [x] DropdownMenu → `menus::DropdownMenu`; also T05 DropdownButton / MenuButton, and SplitButton as `menus::SplitButton`
|
||
- [x] OverflowMenu → `menus::OverflowMenu`
|
||
|
||
## T08b Menus · Bar, search & pie
|
||
|
||
- [x] MenuBar Menu → `menus::MenuBar`; also T04 MenuBar: the native menus, drawn in the window
|
||
- [x] MegaMenu → `navigation::NavigationMenu`: each entry opens a panel of links with a line of detail
|
||
- [x] SearchableMenu → `menus::SearchableMenu`
|
||
- [x] PieMenu / RadialMenu → `menus::PieMenu`, `menus::PieItem`
|
||
|
||
## T09a Overlays · Popovers & dialogs — `src/overlays`
|
||
|
||
- [x] Tooltip → `primitives::Tooltip`
|
||
- [x] Popover → `overlays::Popover`
|
||
- [x] HoverCard → `overlays::HoverCard`
|
||
- [x] Dialog / Modal → `overlays::Dialog`
|
||
- [x] AlertDialog → `overlays::AlertDialog`
|
||
- [x] ConfirmDialog → `overlays::ConfirmDialog`
|
||
- [x] PromptDialog → `overlays::PromptDialog`
|
||
- [x] FullscreenDialog → `overlays::Dialog::fullscreen`
|
||
- [x] Sheet → `layout::Sheet`
|
||
- [x] Drawer → `layout::Drawer`
|
||
|
||
## T09b Overlays · Guides & floats
|
||
|
||
- [x] Lightbox → `overlays::Lightbox`, `overlays::Slide`
|
||
- [x] Spotlight / Coachmark → `overlays::Spotlight`; also T07c Tour / Onboarding and T37 WelcomeTour as `overlays::Tour`
|
||
- [x] FloatingToolbar → `overlays::FloatingToolbar`
|
||
- [x] Callout / Peek → `overlays::Peek`
|
||
- [x] DropdownPanel → `overlays::Popover`
|
||
- [x] InlinePopup → `overlays::Popover` with the Link variant
|
||
- [x] ToastViewport → lands with Feedback (T10): it holds Toasts
|
||
|
||
## T10a Feedback · Messages — `src/feedback`
|
||
|
||
- [x] Toast — success, error, warning, info, action, undo; also T09b ToastViewport → `feedback::Toast`, `feedback::Toaster`, `feedback::ToastViewport`
|
||
- [x] Notification → `feedback::Notification`
|
||
- [x] NotificationCenter → `feedback::NotificationCenter`; also T10b EmptyState, which it shows when empty
|
||
- [x] Alert → `feedback::Alert`
|
||
- [x] Banner → `feedback::Banner`
|
||
- [x] Callout / Admonition → `feedback::Callout`
|
||
- [x] InlineMessage → `feedback::InlineMessage`
|
||
- [x] StatusMessage → `feedback::StatusMessage`
|
||
- [x] Snackbar → `feedback::Toast`
|
||
- [x] UndoToast → `feedback::Toast`
|
||
|
||
## T10b Feedback · States
|
||
|
||
- [x] ErrorView → `feedback::ErrorView`
|
||
- [x] ErrorBoundary — renders and logs a `Result` error; never catches panics → `feedback::ErrorBoundary`
|
||
- [x] NotFound / 404 → `feedback::ErrorView::not_found`
|
||
- [x] NoPermission / 403 → `feedback::ErrorView::no_permission`
|
||
- [x] Maintenance → `feedback::ErrorView::maintenance`
|
||
- [x] Offline → `feedback::ErrorView::offline`
|
||
- [x] EmptyState → `feedback::EmptyState`, built with T10a
|
||
- [x] Result → `feedback::ResultView`; a plain `Result` would shadow std's
|
||
- [x] ConfirmationCard → `feedback::ConfirmationCard`
|
||
- [x] SavingIndicator → `feedback::SavingIndicator`
|
||
- [x] SyncStatus → `feedback::SyncStatus`
|
||
- [x] ConnectionStatus → `feedback::ConnectionStatus`; its dot is `shell::OfflineIndicator`'s
|
||
- [x] Countdown → `feedback::Countdown`
|
||
- [x] Timer → `feedback::Timer`
|