refactor(engine): extract shared spawn_tab_chip widget into ui_modal
Settings' tab_chip becomes a thin wrapper; the You hub (Phase E) will reuse the same widget so tabbed modals stay visually identical. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@ use crate::theme::{ImportError, import_theme, refresh_registry};
|
|||||||
use crate::ui_focus::FocusRow;
|
use crate::ui_focus::FocusRow;
|
||||||
use crate::ui_modal::{
|
use crate::ui_modal::{
|
||||||
ButtonVariant, spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header,
|
ButtonVariant, spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header,
|
||||||
|
spawn_tab_chip,
|
||||||
};
|
};
|
||||||
use crate::ui_theme::{
|
use crate::ui_theme::{
|
||||||
BG_BASE, BG_ELEVATED, BG_ELEVATED_HI, BORDER_SUBTLE, HighContrastBorder, RADIUS_SM,
|
BG_BASE, BG_ELEVATED, BG_ELEVATED_HI, BORDER_SUBTLE, HighContrastBorder, RADIUS_SM,
|
||||||
@@ -117,41 +118,22 @@ pub(super) fn spawn_settings_panel(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One Settings tab chip. The active chip is filled + bright; inactive
|
/// One Settings tab chip — thin wrapper over the shared
|
||||||
/// chips are quiet outlines.
|
/// [`spawn_tab_chip`] widget so Settings and the You hub stay visually
|
||||||
|
/// identical.
|
||||||
fn tab_chip(
|
fn tab_chip(
|
||||||
parent: &mut ChildSpawnerCommands,
|
parent: &mut ChildSpawnerCommands,
|
||||||
tab: SettingsTab,
|
tab: SettingsTab,
|
||||||
active: bool,
|
active: bool,
|
||||||
font_res: Option<&FontResource>,
|
font_res: Option<&FontResource>,
|
||||||
) {
|
) {
|
||||||
let font = TextFont {
|
spawn_tab_chip(
|
||||||
font: font_res.map(|f| f.0.clone()).unwrap_or_default(),
|
parent,
|
||||||
font_size: TYPE_CAPTION,
|
SettingsTabButton(tab),
|
||||||
..default()
|
tab.label(),
|
||||||
};
|
active,
|
||||||
parent
|
font_res,
|
||||||
.spawn((
|
);
|
||||||
SettingsTabButton(tab),
|
|
||||||
Button,
|
|
||||||
Node {
|
|
||||||
padding: UiRect::axes(VAL_SPACE_3, VAL_SPACE_2),
|
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
border: UiRect::all(Val::Px(1.0)),
|
|
||||||
border_radius: BorderRadius::all(Val::Px(RADIUS_SM)),
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
BackgroundColor(if active { BG_ELEVATED_HI } else { BG_BASE }),
|
|
||||||
BorderColor::all(if active { STATE_SUCCESS } else { BORDER_SUBTLE }),
|
|
||||||
HighContrastBorder::with_default(if active { STATE_SUCCESS } else { BORDER_SUBTLE }),
|
|
||||||
))
|
|
||||||
.with_children(|b| {
|
|
||||||
b.spawn((
|
|
||||||
Text::new(tab.label()),
|
|
||||||
font,
|
|
||||||
TextColor(if active { TEXT_PRIMARY } else { TEXT_SECONDARY }),
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Audio tab: the two volume rows.
|
/// Audio tab: the two volume rows.
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ use crate::settings_plugin::SettingsResource;
|
|||||||
use crate::ui_theme::{
|
use crate::ui_theme::{
|
||||||
ACCENT_PRIMARY, ACCENT_PRIMARY_HOVER, ACCENT_SECONDARY, BG_BASE, BG_ELEVATED, BG_ELEVATED_HI,
|
ACCENT_PRIMARY, ACCENT_PRIMARY_HOVER, ACCENT_SECONDARY, BG_BASE, BG_ELEVATED, BG_ELEVATED_HI,
|
||||||
BG_ELEVATED_PRESSED, BG_ELEVATED_TOP, BORDER_STRONG, BORDER_SUBTLE, HighContrastBorder,
|
BG_ELEVATED_PRESSED, BG_ELEVATED_TOP, BORDER_STRONG, BORDER_SUBTLE, HighContrastBorder,
|
||||||
MOTION_MODAL_SECS, RADIUS_LG, RADIUS_MD, SCRIM, TEXT_PRIMARY, TEXT_SECONDARY, TYPE_BODY_LG,
|
MOTION_MODAL_SECS, RADIUS_LG, RADIUS_MD, RADIUS_SM, SCRIM, STATE_SUCCESS, TEXT_PRIMARY,
|
||||||
TYPE_CAPTION, TYPE_HEADLINE, VAL_SPACE_2, VAL_SPACE_3, VAL_SPACE_4, VAL_SPACE_5,
|
TEXT_SECONDARY, TYPE_BODY_LG, TYPE_CAPTION, TYPE_HEADLINE, VAL_SPACE_2, VAL_SPACE_3,
|
||||||
scaled_duration,
|
VAL_SPACE_4, VAL_SPACE_5, scaled_duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -402,6 +402,46 @@ pub fn spawn_modal_button<M: Component>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// One tab chip for a tabbed modal (Settings, the You hub). The active
|
||||||
|
/// chip is filled + bright with a success-green border; inactive chips
|
||||||
|
/// are quiet outlines. `marker` is the plugin's click-target component
|
||||||
|
/// carrying which tab the chip selects.
|
||||||
|
pub fn spawn_tab_chip<M: Component>(
|
||||||
|
parent: &mut ChildSpawnerCommands,
|
||||||
|
marker: M,
|
||||||
|
label: &str,
|
||||||
|
active: bool,
|
||||||
|
font_res: Option<&FontResource>,
|
||||||
|
) {
|
||||||
|
let font = TextFont {
|
||||||
|
font: font_res.map(|f| f.0.clone()).unwrap_or_default(),
|
||||||
|
font_size: TYPE_CAPTION,
|
||||||
|
..default()
|
||||||
|
};
|
||||||
|
parent
|
||||||
|
.spawn((
|
||||||
|
marker,
|
||||||
|
Button,
|
||||||
|
Node {
|
||||||
|
padding: UiRect::axes(VAL_SPACE_3, VAL_SPACE_2),
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
border: UiRect::all(Val::Px(1.0)),
|
||||||
|
border_radius: BorderRadius::all(Val::Px(RADIUS_SM)),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
BackgroundColor(if active { BG_ELEVATED_HI } else { BG_BASE }),
|
||||||
|
BorderColor::all(if active { STATE_SUCCESS } else { BORDER_SUBTLE }),
|
||||||
|
HighContrastBorder::with_default(if active { STATE_SUCCESS } else { BORDER_SUBTLE }),
|
||||||
|
))
|
||||||
|
.with_children(|b| {
|
||||||
|
b.spawn((
|
||||||
|
Text::new(label),
|
||||||
|
font,
|
||||||
|
TextColor(if active { TEXT_PRIMARY } else { TEXT_SECONDARY }),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Generic touch-scroll helper
|
// Generic touch-scroll helper
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user