sync radius
This commit is contained in:
@@ -76,6 +76,7 @@ GPUI is a UI framework which also provides primitives for state and concurrency
|
||||
|
||||
- Dependency direction is one-way: `gpui-native-kit` (facade) → `gpui-native-core` / `gpui-native-editor` / … → `gpui-native-theme` + `gpui-native-icons` → gpui. No cycles. Nothing depends on `gpui-component`, `gpui-kit`, `gpuikit`, `bezel`, `native-theme`, or any gpui fork.
|
||||
- `crates/theme` owns the native theme engine and every color, radius, spacing, and metric value — no raw `rgb`/`rgba`/`hsla` or layout `px(...)` literals anywhere else.
|
||||
- Components always take corner radii from the theme `Radius` token (`cx.theme().radius`); never use gpui's `rounded_*` presets or hardcoded radii in components.
|
||||
- `crates/icons` owns icon resolution; components reference icons by semantic role — no glyph names, unicode symbols, or SVG paths anywhere else.
|
||||
- `crates/core` and its sibling crates own components: each one is a small self-contained implementation gated behind its own cargo feature. Features are additive, gate whole modules only, and may depend on other features. Behavior and presentation live together. No separate behavior layer — promote a shared helper only when a third component needs it.
|
||||
- Components are written in-tree. Other UI toolkits are read for API ideas only; never port their code or depend on them.
|
||||
|
||||
@@ -56,11 +56,16 @@ impl Global for Theme {}
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Radius {
|
||||
pub control: Pixels,
|
||||
/// Pill and circle shapes.
|
||||
pub full: Pixels,
|
||||
}
|
||||
|
||||
impl Default for Radius {
|
||||
fn default() -> Self {
|
||||
Self { control: px(6.) }
|
||||
Self {
|
||||
control: px(6.),
|
||||
full: px(9999.),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,8 +138,12 @@ pub(crate) fn resolve(
|
||||
}
|
||||
|
||||
let mut radius = Radius::default();
|
||||
if let Some(control) = preset.and_then(|def| def.control_radius) {
|
||||
radius.control = px(control);
|
||||
if let Some(control) = preset
|
||||
.and_then(|def| def.control_radius)
|
||||
.map(px)
|
||||
.or(system.control_radius)
|
||||
{
|
||||
radius.control = control;
|
||||
}
|
||||
|
||||
ResolvedTheme {
|
||||
@@ -182,11 +186,25 @@ mod tests {
|
||||
variant,
|
||||
accent,
|
||||
palette,
|
||||
control_radius: None,
|
||||
accessibility: AccessibilityPreferences::default(),
|
||||
source: SourceKind::Macos,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metric_priority_is_definition_then_system_then_fallback() {
|
||||
let mut stated = system(ThemeVariant::Dark, PartialPalette::default(), None);
|
||||
stated.control_radius = Some(px(4.));
|
||||
|
||||
let resolved = resolve(&stated, None, None);
|
||||
assert_eq!(resolved.radius.control, px(4.));
|
||||
|
||||
let def = ThemeDefinition::parse_toml("control_radius = 12.0\n").unwrap();
|
||||
let overridden = resolve(&stated, Some(&def), None);
|
||||
assert_eq!(overridden.radius.control, px(12.));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_system_resolves_to_the_neutral_fallback() {
|
||||
for variant in [ThemeVariant::Light, ThemeVariant::Dark] {
|
||||
|
||||
@@ -18,6 +18,9 @@ use super::ThemeSource;
|
||||
use crate::ThemeVariant;
|
||||
use crate::system::{AccessibilityPreferences, PartialPalette, SourceKind, SystemTheme};
|
||||
|
||||
/// Default control radius for macOS controls.
|
||||
const CONTROL_RADIUS_PTS: f32 = 6.0;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct MacosSource {
|
||||
_observers: Vec<Retained<ProtocolObject<dyn NSObjectProtocol>>>,
|
||||
@@ -98,6 +101,7 @@ impl ThemeSource for MacosSource {
|
||||
variant,
|
||||
accent: Self::color_to_hsla(&NSColor::controlAccentColor()),
|
||||
palette,
|
||||
control_radius: Some(gpui::px(CONTROL_RADIUS_PTS)),
|
||||
accessibility,
|
||||
source: SourceKind::Macos,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! The normalized snapshot a platform adapter produces.
|
||||
|
||||
use gpui::Hsla;
|
||||
use gpui::{Hsla, Pixels};
|
||||
|
||||
use crate::ThemeVariant;
|
||||
|
||||
@@ -55,6 +55,7 @@ pub struct SystemTheme {
|
||||
pub variant: ThemeVariant,
|
||||
pub accent: Option<Hsla>,
|
||||
pub palette: PartialPalette,
|
||||
pub control_radius: Option<Pixels>,
|
||||
pub accessibility: AccessibilityPreferences,
|
||||
pub source: SourceKind,
|
||||
}
|
||||
@@ -65,6 +66,7 @@ impl SystemTheme {
|
||||
variant,
|
||||
accent: None,
|
||||
palette: PartialPalette::default(),
|
||||
control_radius: None,
|
||||
accessibility: AccessibilityPreferences::default(),
|
||||
source: SourceKind::Fallback,
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ impl Render for Gallery {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let theme = cx.theme();
|
||||
let colors = theme.colors;
|
||||
let radius = theme.radius;
|
||||
let variant = theme.variant;
|
||||
let source = gpui_native_theme::detected_source(cx);
|
||||
let mode_override = gpui_native_theme::mode_override(cx);
|
||||
@@ -105,7 +106,8 @@ impl Render for Gallery {
|
||||
.text_sm()
|
||||
.text_color(colors.muted_foreground)
|
||||
.child(format!(
|
||||
"phase C — button · source: {source} · variant: {variant:?}"
|
||||
"phase C — button · source: {source} · variant: {variant:?} · control radius {}px",
|
||||
f32::from(theme.radius.control)
|
||||
)),
|
||||
),
|
||||
)
|
||||
@@ -125,6 +127,7 @@ impl Render for Gallery {
|
||||
label,
|
||||
active,
|
||||
colors,
|
||||
radius,
|
||||
move |_, _, cx| gpui_native_theme::set_mode_override(value, cx),
|
||||
)
|
||||
})),
|
||||
@@ -146,6 +149,7 @@ impl Render for Gallery {
|
||||
label,
|
||||
active,
|
||||
colors,
|
||||
radius,
|
||||
move |_, _, cx| {
|
||||
let _ = gpui_native_theme::set_preset(value, cx);
|
||||
},
|
||||
@@ -208,7 +212,7 @@ impl Render for Gallery {
|
||||
.child(
|
||||
div()
|
||||
.size_6()
|
||||
.rounded_full()
|
||||
.rounded(radius.full)
|
||||
.border_1()
|
||||
.border_color(colors.border)
|
||||
.bg(color),
|
||||
@@ -236,7 +240,7 @@ impl Render for Gallery {
|
||||
.child(
|
||||
div()
|
||||
.size_6()
|
||||
.rounded_full()
|
||||
.rounded(radius.full)
|
||||
.border_1()
|
||||
.border_color(colors.border)
|
||||
.bg(color),
|
||||
@@ -292,6 +296,7 @@ fn chip<F>(
|
||||
label: SharedString,
|
||||
active: bool,
|
||||
colors: gpui_native_theme::ColorTokens,
|
||||
radius: gpui_native_theme::Radius,
|
||||
on_click: F,
|
||||
) -> impl IntoElement + use<F>
|
||||
where
|
||||
@@ -301,7 +306,7 @@ where
|
||||
.id(SharedString::from(id))
|
||||
.px_3()
|
||||
.py_1()
|
||||
.rounded_full()
|
||||
.rounded(radius.full)
|
||||
.border_1()
|
||||
.text_xs()
|
||||
.cursor_pointer()
|
||||
|
||||
Reference in New Issue
Block a user