GPUI Kit v0.7.0
GPUI Kit v0.7.0 adds Toolbar, Questionnaire and TimeField, and makes window startup and overlay hosting consistent through a Base-owned Root. Plot primitives are now available without the styled component layer, while Input, TextView and charts gain richer editing, search, date/time and data-visualization APIs. This release also improves Dock interactions, accessibility, streaming and large-data performance; review the Breaking Changes below before upgrading.
New components
-
Toolbar and ToolbarGroup: compose application command rows with source-order controls, semantic groups, separators and flexible spacers. Left/Right moves focus through enabled controls with wrapping. The styled toolbar propagates its density to hosted controls and gives Buttons compact ghost presentation;
child/childrenaccept sized controls, whilecontent/contentsaccept labels, separators and custom content. The default size is Small; XSmall and Medium are supported, and Large uses Medium. Disabling toolbar navigation does not disable its controls automatically. (#3128) -
Questionnaire: build single-choice, multiple-choice and freeform questionnaires around
QuestionnaireState, with composable question, choice, input, progress and action parts. The component handles validation, optional skipping, keyboard shortcuts, focus, navigation and submission, using existing Radio, Checkbox, Input and Button controls. (#2878) -
TimeField and date/time picking: edit segmented hours and minutes, optionally seconds, using
TimeFieldState,TimePrecision::{Minute, Second}andHourCycle::{H23, H12}. A styled TimeField works independently in forms, and DatePicker enables time editing throughtime_precision,hour_cycleanddefault_time.date_time/set_date_timeexpose the combined value; date/time presets useDateRangePreset::date_time. In time-enabled single mode, each edit emits Change while the popup stays open; range mode remains date-only. DatePicker Change payloads require migration below. (#3206)
Window hosting and framework boundaries
-
One window entry point:
gpui_kit::open_window(options, cx, build)returns(AnyWindowHandle, Entity<V>)and always wraps application content ingpui_base::Root, independent of Cargo feature unification. Callgpui_kit::init(cx)first, return content from the builder, and retain the returned entity when you need application state. In async work, invoke the helper insidecx.update; quit/close actions and keybindings remain application-owned. (#3152) -
Automatic overlay hosting: Root owns content, overlay hosting, keyboard traversal and selection copying;
gpui_component::Rootre-exports the Base type. Component initialization registers per-window presentation for dialogs, sheets, notifications, menus, tooltips, touch selection and window chrome. Manual layer-rendering APIs are removed; application operations remain onWindowExt. (#3152) -
Root plugins: design systems can register typed
RootPluginimplementations withRoot::register_plugin, retrieve them withRoot::plugin, and use preparation, styling and decoration hooks. Plugins are instantiated per window in registration order. Register them before creating windows; replacing a factory affects future windows, and existing roots are not retrofitted. (#3152) -
Plot primitives in Base: scales, shapes, axes, grids, labels, the
Plottrait, path caches and hover tracking move togpui_kit::base::plot, enabling custom charts without a Component dependency. Existinggpui_kit::component::plotimports remain available through re-exports.PlotElement<P>is the element behind custom plots and#[derive(IntoPlot)];PlotMotionandPlotThemeprovide theme-projected pointer and hover motion. Base defaults to no motion, styled charts now acceptf32, and Component forwards itsdecimalfeature to Base. Custom primitive APIs require migration below. (#3258)
Simplified window startup
gpui_kit::init(cx) and gpui_kit::open_window provide a compact, standard startup sequence. The builder creates application content, and Kit supplies the Root and automatically hosts dialogs, sheets and notifications. Use WindowExt for Component operations, gpui_base::TextSelection for selection, and WindowOptions with window_border() for window decoration. (#3152)
gpui_kit::init(cx);
let (window_handle, content) =
gpui_kit::open_window(options, cx, |window, cx| {
build_content(window, cx)
})?;Updating existing window code
The following examples show how existing startup, overlay and window-operation code maps to the simplified APIs.
- cx.open_window(options, |window, cx| {
- let content = build_content(window, cx);
- cx.new(|cx| Root::new(content, window, cx))
- })
+ let (window_handle, content) =
+ gpui_kit::open_window(options, cx, |window, cx| {
+ build_content(window, cx)
+ })?;- let sheet_layer = Root::render_sheet_layer(window, cx);
- let dialog_layer = Root::render_dialog_layer(window, cx);
- let notification_layer = Root::render_notification_layer(window, cx);
-
div()
.child(content)
- .children(sheet_layer)
- .children(dialog_layer.map(|layer| deferred(layer).with_priority(1)))
- .children(notification_layer)- Root::bordered
- Root::window_shadow_size
+ window_border()- window.selected_text(cx)
+ TextSelection::selected_text(window, cx)
- window.has_text_selection(cx)
+ TextSelection::has_selection(window, cx)
- root.clear_text_selection(window, cx)
- window.clear_text_selection(cx)
+ TextSelection::clear(window, cx)
- window.end_text_selection(cx)
+ TextSelection::end(window, cx)- root.open_dialog(build, window, cx)
+ window.open_dialog(cx, build)
- root.close_dialog(window, cx)
+ window.close_dialog(cx)
- root.close_all_dialogs(window, cx)
+ window.close_all_dialogs(cx)
- root.open_sheet_at(placement, build, window, cx)
+ window.open_sheet_at(placement, cx, build)
- root.close_sheet(window, cx)
+ window.close_sheet(cx)
- root.push_notification(notification, window, cx)
+ window.push_notification(notification, cx)
- root.remove_notification::<T>(window, cx)
+ window.remove_notification::<T>(cx)
- root.remove_notification1::<T>(key, window, cx)
+ window.remove_notification1::<T>(key, cx)
- root.clear_notifications(window, cx)
+ window.clear_notifications(cx)Editor and text input
-
Atomic inline tokens: Input and Textarea can represent mentions, commands and resource references as
InlineTokenannotations. Usereplace_with_token/replace_range_with_tokento insert them,InputContent::with_tokento restore validated ranges, andcontent()to save a draft. Caret movement, selection, deletion and undo treat each token as one unit, while values and clipboard content remain plain text. Customize presentation withtokenand activation withon_token_clickorActivateToken. Tokens are opt-in and unavailable in Editor, NumberInput, password and formatted-mask modes. (#3113) -
Editor range decorations: independent consumers can create edit-tracked
RangeDecorationCollectionhandles throughEditorState::create_range_decorations_collection.RangeDecorationsupportsRangeDecorationStyle::{Fill, Frame}with optional color; collections can set, append, clear, read tracked ranges or dispose. Decorations use UTF-8 byte ranges and paint only visible spans, including soft wraps, CRLF and folded text.InputExtras::range_decorationshas a default empty implementation, so existing implementers continue to compile. (#3040) -
Textarea sizing and editor gutters: Textarea supports the standard size system like Input, and the line-number gutter adapts between three and seven digits instead of reserving an unsuitable fixed width. (#3191, #3205)
-
Focus, selection and asynchronous editing: corrected disabled-input pointer focus, preferred columns and vertical selection affinity, drag-selection autoscroll, stale completion/inline responses, IME selection direction and undo boundaries, replacement-field focus and explicit GoToDefinition requests. Accessibility Focus refuses disabled inputs; SetValue is advertised and applied only when editable. Re-requesting code actions refreshes an already-open menu, including empty results. (#3254, #3256, #3274)
-
Caret lifecycle and navigation: programmatic updates no longer start permanent blink/repaint loops on unfocused inputs; blur clears stale blink state so refocusing restores a blinking caret. Editing scrolls directly to a distant caret rather than animating through the whole document. (#3139, #3140, #3150)
-
Web clipboard paste: Input context menus offer Paste whenever the input is editable, and fall back to asynchronous clipboard reading when synchronous reading is unavailable. The paste request starts from the user action and rechecks editability when it resolves. (#3244)
-
Editor performance and Unicode safety: reduce diagnostic/definition-hover repaints, debounce transient hover requests, avoid inactive search rescans and query only visible search highlights. Syntax classification reuses Rope-backed parse results and injection trees. Tree-sitter receives bytes, preventing aborts when a read begins inside a multibyte character. (#3260, #3263, #3238)
-
Input context menus: documentation now makes clear that
InputState::context_menu(false)disables the entire right-click menu, including a custom Input/Textarea/Editor menu. Keep the state menu enabled when supplying a custom builder; the builder replaces the built-in items. (#3275)
Markdown and text rendering
-
Source-aware selection:
TextViewState::selected_source_range()returns the original Markdown byte range for the actual rendered selection, distinguishing repeated occurrences instead of guessing from selected text. (#3136) -
Search highlights and reveal: search
TextViewState::rendered_text()and applyRangeHighlightvalues withset_range_highlights;clear_range_highlightsremoves them. Ranges refer to UTF-8 bytes in rendered copy text, so searches can cross Markdown formatting. Highlights preserve layout, selection and copy behavior, and survive unchanged content and append-only streaming.reveal_rangemakes the starting line visible in a scrollable TextView or an application list;TextView::on_revealsupplies window-space bounds for custom scroll containers. Reveal is best effort, and highlights are currently Markdown-only. (#3215, #3216) -
Heading refinements: Base
TextViewStyle::with_headingaccepts a level-awareStyleRefinementcallback for typography, spacing, color and borders, layered over built-in heading defaults. Component keeps its existing compatibility heading fields and builders. (#3129) -
Markdown correctness: preserve ordered-list starting numbers and prose in unclaimed math spans, pair inline HTML tags correctly, and keep lines containing inline code as tall as equivalent plain-text lines. (#3204, #3178, #3240)
-
Streaming and large documents:
stream_fadestaggers by word and skips oversized chunks, with throttled repaints. Reuse inline layout and paragraph render caches, avoid unnecessary hover/selection work, and remove quadratic source-mapping and table-highlight reconciliation paths. Text selection in a cached dock view stays registered instead of flickering and keeping the window repainting. (#3153, #3226, #3180, #3261, #3247, #3273, #3193)
Charts and plot motion
-
Stable live-series geometry: LineChart and AreaChart support
y_domain(min, max)for a fixed value range andpoint_count(count)for reserved x-axis slots, so arriving data keeps its position. Values outside the fixed domain are clipped. BarChart addsband_countfor the equivalent fixed-band layout. (#3209, #3220) -
Axes, grids and reference lines: LineChart/AreaChart add
y_axis,y_axis_label_placement,y_tick_count,y_tick_format,x_tick_count,grid_columns,grid_dashed, repeatablereference_lineandy_padding. BarChart addsvalue_axis_label_placement,value_tick_format,band_tick_countandgrid_dashed.AxisLabelPlacement::{Outside, Inside}controls value-label placement.chart.grid/ThemeColor::chart_gridseparate grids from axis borders, with a 60%-opacity border fallback for themes that omit the token. (#3220, #3236) -
Bar labels and spacing:
label_colorcolors labels per datum,padding_inner/padding_outerexpose band spacing, andmin_lengthkeeps zero or small bars visible. Vertical charts reserve space for labels. BarChart and CandlestickChart exposemax_band_width, retaining their default 30px maximum while Base ScaleBand no longer imposes one. (#3217, #3258) -
Tooltip customization: LineChart, AreaChart, BarChart, RadarChart and CandlestickChart add
tooltip_title,tooltip_value,tooltip_value_colorandtooltip_content. Multivalue chart callbacks also receive a row index. PieChart and SankeyChart addtooltip_name/tooltip_valueindependently of labels painted on the chart.Tooltip::value_colorcolors the latest row andplain_rowadds totals without a swatch; a bar tooltip swatch follows the bar color. (#3228, #3176) -
Interaction and motion: chart IDs default to their construction site so hover works without an explicit ID; provide distinct IDs when multiple charts share a construction site.
interactive(false)removes hitboxes, hover emphasis, tooltips and path caches for placeholders or covered charts. Tooltip glides its own crosshair/dots and grows dot halos with hover progress;Tooltip::glide(false)disables that spring. Custom plots can usePlotHover::glideand the Base hover-motion helpers. (#3173, #3176, #3222, #3258) -
Painting performance: LineChart and AreaChart use index-based point placement to avoid quadratic value lookups and correctly position duplicate x values at their own indices. Candlestick wicks avoid per-candle path tessellation, and chart hover/painting avoids redundant work. (#3262)
Dock and resizing
-
Nested docks and tab closing: moving a panel from a dock that does not own it no longer creates duplicate or ghost tabs.
DockSkin::set_close_button_visibleenables built-in close buttons, hidden by default;TabGroupContext::is_panel_closablerespects both dock and panel constraints. Custom tab renderers retain control over presentation and frame geometry. (#3197) -
Continuous bottom-dock resizing: drag a collapsible bottom dock below its minimum, through the closed strip and back open in one motion. Release snaps to the nearer closed or minimum-open state; transient sizes below the minimum are not persisted. Custom resize drivers finish with
DockContext::end_resize. (#3229) -
Resize indicators: dividers grow their indicator as the pointer engages, hugging handles paint their hairline on the seam, and dock hairlines no longer draw over popovers. (#3175, #3200, #3221)
Theme synchronization
- Theme updates:
Theme::update(cx, |theme| ...)edits the global theme, reconciles solid colors and gradient tokens, updates the Base projection, resolves changed fonts and refreshes all windows. Use it for palette, mode, typography and other theme edits instead of manually synchronizing each representation.Theme::global_mutandTheme::sync_baseremain available for callers that manage synchronization themselves. (#3122)
Components and accessibility
-
Popover trigger styling:
Popover::trigger_stylenow applies to the actual trigger container, so width/flex refinements affect both parent layout and popup anchoring. Base Popover implements Styled; DropdownMenu keeps Button styling on the Button instead of applying it twice. (#3245) -
Attachment: composer attachments include
on_remove,on_retry,progress(percent)andtooltip; interactive controls and tooltips requireid. Progress is 0–100 and clamped. Media receives correctly rounded corners and upload/failure treatments, including retry when a failed image has no source.AttachmentGroup::track_scrolllets the application drive scrolling andwith_edge_fadesignals clipped attachments. Default chip geometry and failure styling change to the composer presentation. (#3195, #3233) -
Settings and GroupBox:
GroupBox::footer/SettingGroup::footerplace supporting content outside the group surface.SettingGroup::variantoverrides theSettings::with_group_variantdefault for one group;GroupBoxVariant::Normalpresents items without a card surface. Selecting a group on another settings page now scrolls to the intended group. (#3133, #3203, #3219) -
Table:
TableSelection::{None, Row, Column, Cell}withTableState::selection/set_selectionmodels the active selection as one value. Positional getters return only the active selection type; stale row appearance and accessibility selection state are corrected. Filler rows and cell rendering avoid redundant work. (#3143, #3264) -
Popover:
offsetsets the trigger gap andarrow(true)adds an arrow for all eight anchors. Horizontal-center anchor placement is corrected. Popover/AppMenu triggers use the new defaultSelectable::open/is_openmethods to distinguish an open popup from application selection; existing Selectable implementations retain the default compatibility behavior. (#3145, #3125) -
Dialog:
button_propsmerges explicitly supplied fields, preserving existing Cancel visibility and callbacks. AlertDialog addsok_text,ok_variant,cancel_textandcancel_variant. Oversized dialogs reclaim the upper window space while normal and stacked dialogs retain their preferred placement. (#3126, #3188) -
Select: closing an open menu emits
DismissEvent, including after Confirm; the popup aligns with the trigger at the right edge. Long option labels truncate with an ellipsis while keeping the checkmark visible. Custom full-row renderers receive a shrinkable container and should apply text truncation themselves. (#3144, #3218, #3280) -
Menus: context-menu actions fire once on the row actually pressed even when rows share a construction site. PopupMenu, DropdownMenu and Popover release their entities and subscriptions when their host disappears, preventing leaks and stale popup registrations from suppressing later Input context menus. (#3135, #3224, #3267, #3279)
-
Switch: the track shows a keyboard focus ring, with
focus_ring(false),tab_stopandtab_indexcontrols. Long labels no longer shrink the track. (#3120, #3154) -
Sidebar and List: SidebarMenuItem exposes its visible label, TreeItem role and selected state to assistive technology. SidebarMenuItem, ListItem and SidebarToggleButton accept
accessibility_label. The focused ListState container carries the List role, and a right-clicked list item retains its outline. (#3160, #3249, #3155) -
Chat composition:
Marker::alignment(MarkerAlignment::{Start, Center, End})controls row and wrapped-text alignment across variants.Message::id/roleprovide stable accessibility identity; Message content inherits caller/bubble typography. Ghost Bubble children are no longer clipped. (#3151, #3171, #3172) -
Form: caller styling such as padding, gaps and background takes effect, and
Field::visible(false)actually hides fields without leaving empty grid rows. Hidden fields are not built or laid out. (#3248, #3269)
Performance and resource use
-
Command: unchanged command models retain their measured rows and search results across parent rerenders, while new callbacks and selection updates still apply. Models with custom child closures or changed layout continue to remeasure. (#3268)
-
Tree and SearchableVec: visible tree rows avoid deep subtree clones and defer context-menu entry cloning until the menu opens. SearchableVec filters by indices instead of cloning matching items or entire groups, evaluating each match once. (#3265, #3279)
-
Carousel and Rating: ancestor scrolling no longer rebuilds Carousel geometry or interrupts a running snap animation. Rating repaints on real hover-value changes rather than every pointer movement. (#3266, #3270)
-
Pagination, ColorPicker, Accordion and Notification: ellipsis menus show at most the 100 hidden pages nearest the current page; closed ColorPicker popups defer their bodies; Accordion content unmounts after the closing spring settles; persistent notifications stop lifecycle ticking once transitions finish. See the Accordion state-lifetime note below. (#3279)
Shell, runtime and platform
-
GPUI snapshot: Kit now pins the complete
gpui-pre-*snapshot family to=0.3.7, including the newly published bench-metrics package. All 25 snapshot packages resolve together; the independentgpui-pre-reqwestfork remains at 0.12.15. (#3283) -
Shell inline tokens and TimeField: JavaScript InputState/TextareaState mirror token insertion, draft content, token slots and token click callbacks. JavaScript ranges use UTF-16 offsets, while Rust uses UTF-8 bytes; validation failures expose
error.code. Shell also exposes TimeField state/elements. Host integration adds optional retained-state methods viaStateMethodDescriptor/StateDescriptor::with_methodsand frame-owned interactive token subtrees. (#3113, #3206) -
Script image policy: HTML/Markdown TextView document images obey the creating script's HTTP GET capabilities, including intrinsic-size measurement and every redirect. Loading is asynchronous, view-owned and canceled on disposal, with timeout/body/redirect limits and no HTTPS downgrade. Non-HTTP(S) document images, including data URLs, are refused; the application-asset
image(path)API is unchanged. Base adds a narrow document-image source override for embedders. (#3230) -
Base controls: Base Dialog centers a normal-flow popup by default and blocks popup presses from reaching its backdrop; Base AlertDialog implements Styled. Base single-line Input vertically centers its text within its frame, while multiline layout is unchanged. These defaults do not alter styled Component Dialog/Input placement. (#3277, #3278)
-
Web and touch: Base WASM examples bundle IBM Plex Sans so
.SystemUIFontresolves and canvases render. Centered notification stacks work reliably on the web. A short touch drag that catches an active ScrollBounce no longer produces a reverse fling; intentional longer flings and edge bounce are preserved. (#3235, #3149, #3207)
Documentation and website
-
Versioned documentation: the latest release is served at
/, development docs at/versions/main, and release snapshots at/versions/<tag>. Snapshot isolation and version-local links prevent newer pages or navigation from leaking into older docs; shared WASM examples load from the site root, and historical versions without component pages still build. (#3159, #3189, #3243, #3165, #3196) -
Framework manual: expanded bilingual guides cover Entity, Window, Context, Render, RenderOnce, Element, Action/Event, ownership, focus, tasks, painting, text, accessibility, animation and WebAssembly, with runnable exercises and troubleshooting. New Packaging, Auto Update and Images guides cover distribution, user-level Linux installation, embedded assets,
img,svgand HTTP caching. Menu-bar guidance documents binding keys beforeset_menus, and focus guidance explains explicit Tab stops. (#3179, #3181, #3225, #3232, #3239, #3124) -
Website themes and navigation: the theme palette reads theme JSON directly, previews and confirms with keyboard navigation, restores on cancel, and synchronizes the chosen JSON with embedded WASM examples.
Cmd+K/Ctrl+Kopens theme selection;/opens docs search. Text selection usesselection.background, falling back toprimary.background, and active sidebar entries are easier to identify. Custom website themes and design-guide illustrations are refined. (#3198, #3241, #3242, #3237, #3211, #3212) -
Documentation licensing: eligible documentation prose and original illustrations carry CC BY 4.0 attribution; software and code examples retain Apache-2.0 permissions. (#3225)
Breaking Changes
Custom Plot primitives
Component plot import paths remain re-exported, but custom plots must migrate primitive APIs. StrokeStyle/stroke_style are removed in favor of Curve/curve; scale ranges become arrays, domains accept iterators, and PlotValue replaces the hidden Sealed bound. least_index becomes nearest_index; least_index_with_domain is removed. Arc paints/contains use the radii configured on the Arc, and Grid x/y accept iterators. ScaleBand has no implicit 30px cap: set max_band_width if needed. TooltipState, AxisText, label::Text, ArcData, StackPoint, StackSeries, SankeyLink, SankeyNodeLayout, SankeyLinkLayout and SankeyGraph are non-exhaustive and should use their constructors. PlotAxis::default() now equals new() with its x-axis line visible. IntoPlot derives use PlotElement<Self> rather than implementing Element directly; the hidden plot::tooltip::track_hover is removed. Base Theme struct literals need plot. Deprecated aliases remain this release for AXIS_GAP, dot_fill_color, dot_stroke_color, PlotHover::focus and Tooltip::focus; prefer axis_gutter, dot_fill, dot_stroke and progress. Existing chart curve builders remain unchanged. (#3258)
- use gpui_kit::base::plot::StrokeStyle;
+ use gpui_kit::base::plot::Curve;
- Line::new().stroke_style(StrokeStyle::StepAfter)
+ Line::new().curve(Curve::StepAfter)
- Area::new().stroke_style(StrokeStyle::Linear)
+ Area::new().curve(Curve::Linear)- let y = ScaleLinear::new(values.collect(), vec![height, 0.]);
+ let y = ScaleLinear::new(values, [height, 0.]);
- where Y: Copy + PartialOrd + Num + ToPrimitive + Sealed
+ where Y: PlotValue
- let ix = scale.least_index(tick);
+ let ix = scale.nearest_index(tick);
- arc.paint(&data, color, None, Some(radius), &bounds, window);
+ Arc::new().outer_radius(radius).paint(&data, color, &bounds, window);
- Grid::new().y(ticks.collect())
+ Grid::new().y(ticks) gpui_base::Theme {
appearance,
tokens,
scrollbar,
resizable,
+ plot: gpui_base::PlotTheme::default(),
}DatePicker event values
DatePickerEvent::Change now carries DateTime, not Date. Date-only consumers can use value.date(); format keeps its signature. Exhaustive matches on DateRangePresetValue must handle the new DateTime variant. (#3206)
cx.subscribe(&picker, |this, _, event, _| match event {
- DatePickerEvent::Change(date) => match date {
+ DatePickerEvent::Change(value) => match value.date() {
Date::Single(Some(date)) => { /* … */ }
_ => {}
},
});Base heading styling
Base TextViewStyle removes with_heading_base_font_size, heading_base_font_size, with_heading_font_size and heading_font_size. Use with_heading/heading and a StyleRefinement callback. The Component compatibility facade retains its old fields and builders. (#3129)
-TextViewStyle::default()
- .with_heading_base_font_size(px(14.))
- .with_heading_font_size(|level, base| resolve_size(level, base))
+TextViewStyle::default().with_heading(|level| {
+ StyleRefinement::default().text_size(resolve_size(level))
+})Table selection getters
Each positional getter reports only its active selection type. To obtain the row of a selected cell, map selected_cell() or match selection(); keep inactive-selection history in the application if required. (#3143)
table.set_selected_cell(5, 3, cx);
-let row = table.selected_row();
+let row = table.selected_cell().map(|(row_ix, _)| row_ix);
table.set_selected_row(2, cx);
-assert_eq!(table.selected_cell(), Some((5, 3)));
+assert_eq!(table.selected_cell(), None);
+assert_eq!(table.selection(), TableSelection::Row(2));BarChart tick counts
value_tick_count(n) now means n ticks, not n intervals. Add one to an explicit old count to preserve its appearance. The default changes from four intervals to five ticks, preserving the default chart layout. (#3209)
- BarChart::new(data).value_axis(true).value_tick_count(6)
+ BarChart::new(data).value_axis(true).value_tick_count(7)Custom tooltip motion
Tooltip now springs its own crosshair/dots. Remove a custom spring or use Tooltip::glide(false) to avoid applying motion twice. Pass full Dot halo sizes; Tooltip applies hover progress itself. (#3222)
- let center = self.band_center.unwrap_or(state.cross_line.x);
- Tooltip::new(cursor, bounds.size)
- .cross_line(CrossLine::new(point(center, state.cross_line.y)))
+ Tooltip::new(cursor, bounds.size)
+ .cross_line(CrossLine::new(state.cross_line))- Dot::new(p).halo(px(20. * hover.focus()))
+ Dot::new(p).halo(px(20.))Shell document image permissions
Script TextView signatures are unchanged, but remote document images now need explicit GET grants for their URL and every redirect target. Non-HTTP(S) sources, including data URLs, are refused; image(path) application assets are unaffected. (#3230)
- Policy::new()
+ Policy::new().with_capabilities(Capabilities::new().http_requests([
+ HttpRequestGrant::new("images.example", ["GET"], ["/image.png"], [] as [&str; 0]),
+ ]))Select dismissal ordering
Existing DismissEvent subscribers now run when an open menu closes. Confirm emits SelectEvent::Confirm followed by DismissEvent; opening or closing an already-closed menu does not dismiss. (#3144)
// An existing SelectState DismissEvent subscription after Escape:
-// No callback.
+// One callback after the menu transitions to closed.
// After confirming an item:
-// SelectEvent::Confirm only.
+// SelectEvent::Confirm, then DismissEvent.Popover horizontal-center anchors
LeftCenter places the popup to the right of the trigger; RightCenter places it to the left, both vertically centered. These no longer fall back to top-left positioning. Top/bottom anchors keep their default placement and do not flip when clamped. (#3145)
- .anchor(Anchor::LeftCenter) // Legacy top-left fallback
+ .anchor(Anchor::LeftCenter) // Right of the trigger, vertically centered
- .anchor(Anchor::RightCenter) // Legacy top-left fallback
+ .anchor(Anchor::RightCenter) // Left of the trigger, vertically centeredIndividually disabled Accordion items
An item marked disabled stays disabled instead of being accidentally enabled by its parent. Explicitly enable it if expansion is intended; builder signatures are unchanged. (#3141)
Accordion::new("settings").item(|item| item.title("Advanced").disabled(true))
-// Clicking Advanced can expand it.
+// Clicking Advanced leaves it closed.Message typography inheritance
Message no longer imposes text_sm and a 1.25 line height on its subtree. Header/footer typography remains local; bare MessageContent inherits the surrounding style, so explicitly style content that depended on the previous row defaults. (#3171)
- Message::new().content(MessageContent::new().child("plain text")) // rendered text_sm / 1.25
+ Message::new().content(MessageContent::new().child("plain text")) // inherits the caller's text styleBase Dialog placement and pointer occlusion
Normal-flow Base popups center by default; style the host to recover top-left placement. Popup presses no longer reach the backdrop, so size popup parts to their content instead of using a full-window popup wrapper. Styled Component Dialog positioning is unchanged. (#3277)
- Dialog::new(cx).popup(popup)
+ Dialog::new(cx).items_start().justify_start().popup(popup)Base single-line Input alignment
A Base single-line input fills its frame and vertically centers its line. If a tall frame relied on top placement, use a one-line-height frame for the previous appearance. Multiline and styled Component input layout is unchanged. (#3278)
Accordion content lifetime and pagination limits
Closed Accordion content unmounts after its close spring settles, dropping element/keyed state held inside the panel. Preserve durable state in entities. Under reduced motion this optimization keeps content mounted. Pagination ellipsis menus cap hidden-page choices at the nearest 100; use successive menus to reach farther pages. (#3279)
Form visibility and attachment presentation
Field::visible(false) now hides the field instead of being ignored. Attachment has new default chip sizing, radius, status overlays and failure colors; review applications that depended on its former content-sized geometry. (#3269, #3195)
Chart labels and duplicate x values
LineChart/AreaChart position duplicate x values at their individual indices, matching hover. Vertical BarChart with labels reserves slightly more top space (bars draw 2px shorter); PieChart tooltip labels are configured separately from leader-line labels. (#3262, #3217, #3176)
Thank you to everyone who contributed code, documentation, testing, and feedback!
What's Changed
- chore: Add a /release-notes command by @huacnlee in #3117
- chart: Start a pie leader line at the lifted slice edge by @madcodelife in #3121
- chore: Move the tested consumer crate into the workspace by @huacnlee in #3118
- chart: Fix the pie radius fallback and fit the gallery's region labels by @madcodelife in #3123
- docs: Bind keys before the menu bar, and say what makes a handle a Tab stop by @huacnlee in #3124
- input: Add atomic inline tokens to Input and Textarea by @suxiaoshao in #3113
- switch: Draw the focus ring when the switch is focused by @huacnlee in #3120
- theme: Add
Theme::updateto keep colors, tokens and the Base projection in step by @huacnlee in #3122 - popover: Tell the trigger it is open instead of selected by @huacnlee in #3125
- popup: Keep the client inset only on untiled window edges by @huacnlee in #3130
- dialog: Merge
button_propsinstead of replacing them by @huacnlee in #3126 - questionnaire: Add a Questionnaire component by @suxiaoshao in #2878
- menu: Draw a context menu only from the trigger that was pressed by @huacnlee in #3135
- input: Clear the blink state when the cursor stops by @novakduc in #3139
- input: Do not start the blink cursor on an unfocused input by @novakduc in #3140
- table: Read and write the selection as one
TableSelectionvalue by @violetpurpleish in #3143 - label: Skip highlights while masked by @violetpurpleish in #3142
- setting: Add optional footers outside group surfaces by @AprilNEA in #3133
- accordion: Preserve disabled state of individual items by @violetpurpleish in #3141
- select: Emit dismissal when an open menu closes by @violetpurpleish in #3144
- popover: Add offset and optional anchor-aligned arrows by @huacnlee in #3145
- gpui-pre: Inject staged crates as git dependencies in the kit check by @huacnlee in #3146
- gpui-pre: Publish even when gpui-kit fails the compatibility check by @huacnlee in #3148
- kit: Update GPUI to gpui-pre 0.3.6 by @huacnlee in #3147
- marker: Add
alignmentfor centered and trailing rows by @madcodelife in #3151 - text: Stagger
stream_fadeby word, dropping it for oversized chunks by @madcodelife in #3153 - list: Restore the outline on the right-clicked item by @madcodelife in #3155
- notification: Fix center notification stacks reliably on web by @huacnlee in #3149
- kit: Pin gpui-pre to the exact snapshot each release is built against by @huacnlee in #3163
- website: Publish versioned website builds by @huacnlee in #3159
- text_view: Add
TextViewState::selected_source_rangeby @tidely in #3136 - input: Scroll straight to a far-off caret after an edit by @Tryanks in #3150
- website: Load shared WASM examples from root by @huacnlee in #3165
- message: Add
idandrole, stop setting the row's typography by @madcodelife in #3171 - bubble: Do not clip the children of a
Ghostbubble by @madcodelife in #3172 - chart: Default a chart's id to its construction site by @madcodelife in #3173
- story: Keep a chart card's legend inside the card by @madcodelife in #3174
- root: Add Base window hosting and a single Kit startup entry point by @huacnlee in #3152
- resizable: Grow an indicator as the pointer engages a divider by @madcodelife in #3175
- markdown: Keep prose inside unclaimed math spans and pair inline HTML tags by @IHadACookie in #3178
- chart: Let a chart stand down, and let its tooltip say what it means by @madcodelife in #3176
- website: Add docs for GPUI action, event by @huacnlee in #3179
- toolbar: Add Toolbar and ToolbarGroup components by @bipinnatus2k in #3128
- switch: Preserve track width with long labels by @violetpurpleish in #3154
- website: add GPUI core concept guides by @huacnlee in #3181
- text: Refine heading styles by level by @wweziza in #3129
- text_view: Lay an inline flow out once, not every frame by @stippi in #3180
- website: isolate versioned documentation snapshots by @huacnlee in #3189
- dialog: Reclaim top space for oversized content by @huacnlee in #3188
- text_selection: Keep a participant whose cached view replayed its frame by @madcodelife in #3193
- website: Fix historical website builds without component pages by @huacnlee in #3196
- resizable: Draw a hugging handle's hairline on the seam by @madcodelife in #3200
- website: add JSON-backed theme command palette by @huacnlee in #3198
- dock: fix nested moves and add opt-in tab close controls by @huacnlee in #3197
- input: Add collection-owned geometric range decorations by @feigeCode in #3040
- editor: Size line-number gutter between three and seven digits by @huacnlee in #3205
- input: Let Textarea take a size, like Input by @Alanaktion in #3191
- highlighter: Remove deprecated usize import by @akeit0 in #3186
- a11y: accessible names for SidebarMenuItem, ListItem and SidebarToggleButton by @noosxe in #3160
- setting: let SettingGroup override the settings-level group variant by @ayangweb in #3203
- mobile: stop reverse fling after short ScrollBounce catch by @huacnlee in #3207
- website: Refine design guides and restore custom website themes by @huacnlee in #3211
- chart: Pin the y axis and reserve points in line and area charts, count ticks in
value_tick_countby @IHadACookie in #3209 - website: Pace radius hierarchy animation in distinct phases by @huacnlee in #3212
- story: Show slider scales through Story composition by @huacnlee in #3213
- markdown: Fix Markdown ordered-list starting numbers by @wabzqem in #3204
- select: Stop the popup from overhanging the trigger on the right by @madcodelife in #3218
- setting: Scroll to a group selected from another page by @madcodelife in #3219
- chart: Color a bar chart's labels per bar, set its band padding, and keep empty bars visible by @IHadACookie in #3217
- resizable: Stop a dock handle's hairline from painting over popovers by @madcodelife in #3221
- date_picker: Support editing the time of day with
TimeFieldby @madcodelife in #3206 - chart: Label the value axis, lay out the grid and mark reference lines in line, area and bar charts by @IHadACookie in #3220
- plot: Glide the tooltip's crosshair and dots in
Tooltipitself by @madcodelife in #3222 - text_view: Add range highlights by @white07S in #3215
- menu: Break Rc cycle that leaked PopupMenu entity on window close by @lysci in #3224
- text: Throttle streamed-fade repaints to reduce CPU use by @Astro-Han in #3226
- docs: expand GPUI core guides and improve documentation UI by @huacnlee in #3225
- chart: Customize series chart tooltips by @IHadACookie in #3228
- dock: Drag a bottom dock shut and back open in one continuous motion by @madcodelife in #3229
- attachment: Adopt the composer design with built-in remove, retry and progress by @madcodelife in #3195
- docs: deepen GPUI manual and add release guides by @huacnlee in #3232
- base: Bundle IBM Plex Sans so the web examples resolve
.SystemUIFontby @ihavecoke in #3235 - text_view: Add
TextViewState::reveal_rangeby @white07S in #3216 - highlighter: Read tree-sitter input as bytes to avoid aborting inside multi-byte chars by @huacnlee in #3238
- website: Make the active sidebar item stand out by @huacnlee in #3237
- chart: Add
chart.gridtheme color for grid lines by @madcodelife in #3236 - text: Keep a line with inline code as tall as a plain line by @huacnlee in #3240
- docs: add an Images guide covering img, svg and HTTP caching by @huacnlee in #3239
- website: fix text selection theme token by @yuuzhou5 in #3241
- shell: Enforce script network policy for TextView images by @lurenjia534 in #3230
- website: Fall back to
primary.backgroundfor themes withoutselection.backgroundby @madcodelife in #3242 - attachment: Show retry control when failed media has no source by @huacnlee in #3233
- website: Keep versioned docs links inside their version by @huacnlee in #3243
- docs: Share repository instructions across coding agents by @suxiaoshao in #3251
- input: Fix accessibility focus and SetValue by @steipete in #3246
- text: Avoid quadratic table highlight remapping by @lurenjia534 in #3247
- form: Apply Styled refinements to Form by @Yi-111-a in #3248
- list: Paint Role::List on focusable ListState container by @Yi-111-a in #3249
- input: Revert #3246 to restore reverse tab traversal by @huacnlee in #3253
- input: Restore guarded accessibility actions without changing tab order by @huacnlee in #3254
- input: Cover UI workflows and fix disabled focus and vertical selection by @huacnlee in #3256
- docs: base manual UI review checks on test coverage by @huacnlee in #3257
- perf(input): reduce redundant work in the code editor by @huacnlee in #3260
- perf(chart): speed up painting and hover by @huacnlee in #3262
- perf(text): reduce streaming, hover and selection work in TextView by @huacnlee in #3261
- perf(table): speed up cell rendering by @huacnlee in #3264
- perf(carousel): stop relayout on ancestor scroll by @huacnlee in #3266
- perf(highlighter): reuse injection trees by @huacnlee in #3263
- perf(tree): avoid cloning subtrees by @huacnlee in #3265
- perf(form): skip rendering hidden fields by @huacnlee in #3269
- perf(rating): skip redundant hover repaints by @huacnlee in #3270
- input: Refresh an open code action menu on a new request by @huacnlee in #3274
- perf(command): skip remeasuring unchanged rows by @huacnlee in #3268
- perf(menu): fix DropdownMenu memory leak by @huacnlee in #3267
- text_view: Avoid quadratic Markdown source mapping by @lurenjia534 in #3273
- docs(input): context_menu(false) also turns off a custom menu by @huacnlee in #3275
- input: Paste from the context menu on the wasm by @Muhammad-Owais-Warsi in #3244
- base: Center the Dialog popup by default and keep presses on it by @huacnlee in #3277
- base: Center a single-line Input in its frame by default by @huacnlee in #3278
- perf: reduce redundant work in six components by @huacnlee in #3279
- select: Truncate overflowing option labels with an ellipsis by @huacnlee in #3280
- plot: Move plot primitives to gpui-base by @huacnlee in #3258
- release: Skip Kit compatibility checks when publishing GPUI by @huacnlee in #3282
- popover: Apply trigger_style to the trigger container by @Yi-111-a in #3245
- kit: Update GPUI to gpui-pre 0.3.7 by @huacnlee in #3283
New Contributors
- @novakduc made their first contribution in #3139
- @violetpurpleish made their first contribution in #3143
- @AprilNEA made their first contribution in #3133
- @tidely made their first contribution in #3136
- @bipinnatus2k made their first contribution in #3128
- @wweziza made their first contribution in #3129
- @Alanaktion made their first contribution in #3191
- @akeit0 made their first contribution in #3186
- @noosxe made their first contribution in #3160
- @ayangweb made their first contribution in #3203
- @white07S made their first contribution in #3215
- @lysci made their first contribution in #3224
- @Astro-Han made their first contribution in #3226
- @yuuzhou5 made their first contribution in #3241
- @steipete made their first contribution in #3246
- @Yi-111-a made their first contribution in #3248
Full Changelog: v0.6.6...v0.7.0