Properties & Events
ShinyTabbedPage
Section titled “ShinyTabbedPage”Tabs & selection
Section titled “Tabs & selection”| Property | Type | Default | Notes |
|---|---|---|---|
Tabs |
IList<ShinyTabItem> |
empty | The content property. |
SelectedIndex |
int |
0 |
Two-way. -1 when nothing is selected. |
SelectedItem |
ShinyTabItem? |
null |
Two-way, kept in step with SelectedIndex. |
Methods: GoTo(int index) and GoTo(string route) — both return false rather than throwing when the tab does not exist, is hidden or is disabled.
Events: SelectionChanged (TabSelectionChangedEventArgs: OldIndex, NewIndex, OldItem, NewItem) and TabReselected (the already-selected tab tapped again — scroll to top, pop to root).
Content
Section titled “Content”| Property | Type | Default | Notes |
|---|---|---|---|
Transition |
StateTransition |
Slide |
Direction-aware. |
TransitionDuration |
uint |
220 |
Milliseconds. Zero swaps instantly. |
TransitionEasing |
Easing |
CubicOut |
|
CacheTabContent |
bool |
true |
Off rebuilds — and resets — the tab every entry. |
SyncTitleWithTab |
bool |
true |
The page’s Title follows the selected tab. |
ContentHost |
StateView |
Read-only, for anything not passed through. |
Bar pass-throughs
Section titled “Bar pass-throughs”TabBarIsVisible, ContentBehindTabBar, CenterButton, IndicatorStyle, LabelMode, SelectedColor, UnselectedColor, IndicatorColor, BarHeight, BarBackgroundColor, BarCornerRadius, BarMargin, HasShadow, IconSize, AnimateIcons — each forwards to the same property on TabBar, which is exposed read-only for everything else.
ContentBehindTabBar runs the content full-bleed under the bar rather than stopping above it, for a translucent or floating bar. Leave room at the bottom of your own content.
ShinyTabItem
Section titled “ShinyTabItem”| Property | Type | Notes |
|---|---|---|
Title |
string? |
Filled in from an adopted page’s Title when unset. |
Icon |
string? |
A built-in motion icon name. |
IconSource |
MotionIconDefinition? |
Explicit artwork. Beats Icon and IconPathData. |
IconPathData |
string? |
A raw SVG path in a 24x24 box. |
IconImage |
ImageSource? |
A plain image. Does not animate, and is never recoloured. |
Motion |
MotionPreset |
Which motion plays on selection. |
Badge |
string? |
"" draws a dot; null draws nothing. |
BadgeColor |
Color? |
Unset follows the theme’s error colour. |
IsEnabled |
bool |
Dimmed, and cannot be selected. |
IsVisible |
bool |
Leaves the bar entirely; the rest re-space. |
Route |
string? |
A stable id for GoTo(string). Not a Shell route. |
Content |
View? |
Built with the markup. |
ContentTemplate |
DataTemplate? |
Built on first selection, then cached. Beats Content. |
Tag |
object? |
|
AdoptedPage |
ContentPage? |
Read-only. The page a template inflated, if it inflated one. |
PageContext |
BindableObject? |
Read-only. What the bar reads ShinyTabs values off. |
Events: Appearing, Disappearing — the event form of ITabAware.
ITabAware
Section titled “ITabAware”public interface ITabAware{ void OnTabAppearing(); void OnTabDisappearing();}Implement it on the tab’s content, on an adopted ContentPage, or on either one’s BindingContext. Each object is called once even when it is reachable both ways, and neither method ever fires twice in a row.
ShinyTabBar
Section titled “ShinyTabBar”| Property | Type | Default |
|---|---|---|
Items |
IList<ShinyTabItem> |
empty (content property) |
SelectedIndex / SelectedItem |
int / ShinyTabItem? |
0 / null |
BarHeight |
double |
62 |
BarBackgroundColor |
Color? |
theme surface-container |
BarCornerRadius |
double |
theme corner token (negative = unset) |
BarMargin / BarPadding |
Thickness |
0 / 4,6 |
HasShadow |
bool |
true |
SelectedColor |
Color? |
theme primary |
UnselectedColor |
Color? |
theme on-surface-variant |
IndicatorColor |
Color? |
theme secondary-container |
IndicatorStyle |
TabIndicatorStyle |
Pill |
IndicatorTransition |
TabIndicatorTransition |
Slide |
IndicatorEasing |
Easing |
CubicInOut |
LabelMode |
TabLabelMode |
Always |
IconSize / FontSize |
double |
24 / 11 |
AnimateIcons |
bool |
true |
AnimationDuration |
uint |
200 |
CenterButton |
TabCenterButton? |
null |
PageContext |
BindableObject? |
null |
IsMenuOpen |
bool |
false (two-way) |
SelectionChangedCommand |
ICommand? |
null |
TabIndicatorStyle: None · Pill · Line (top edge) · Underline (bottom edge) · Dot.
TabLabelMode: Always · SelectedOnly · Never.
TabSelectionAnimation: None · Scale (default) · Lift · Bounce · Fade · Indicator.
TabIndicatorTransition: Slide (default — one indicator travels between tabs) · None (drawn
inside each cell, so it appears rather than travels). Sliding needs measured geometry and falls back
to None until the bar has been laid out.
ITabAnimator
Section titled “ITabAnimator”public interface ITabAnimator{ Task AnimateAsync(TabAnimationContext context);}Called once per tab whose selected state actually changed — never on a restyle, a badge update or a
rebuild — for both ends of the change. TabAnimationContext carries Item, Cell, Icon,
Label, Indicator (whichever the current IndicatorStyle draws), IsSelected, Duration and
Bar. Setting Animator overrides SelectionAnimation; clear it to null to get the built-ins
back.
AutomationIds
Section titled “AutomationIds”Every tab cell carries tab-<route>, falling back to tab-<title> (lowercased, spaces hyphenated).
The centre button carries tab-center, on the circle itself — the element the tap gesture is
actually on. A tab with neither a Route nor a Title gets none, rather than an index-based id
that would point at a different tab as soon as the order changed.
Methods: GoTo(int), GoTo(string), OpenMenu(), CloseMenu().
Events: SelectionChanged, TabReselected, CenterClicked (cancellable — set Cancel to take the press over entirely), ActionInvoked, MenuOpened, MenuClosed.
PageContext is the element the bar reads ShinyTabs values off. ShinyTabbedPage and ShinyTabBarBehavior set it for you; set it yourself only when hosting the bar by hand.
TabCenterButton
Section titled “TabCenterButton”| Property | Type | Default | Notes |
|---|---|---|---|
Icon / IconSource / IconPathData / IconImage |
"plus" |
Same four sources as a tab. | |
Motion |
MotionPreset |
Default |
|
Mode |
TabCenterMode |
Menu |
Action never presents anything. |
Size |
double |
60 |
Diameter. |
IconSize |
double |
26 |
|
Overhang |
double |
-1 |
Negative = half of Size. |
Text |
string? |
null |
A caption under the circle. |
BackgroundColor |
Color? |
theme primary | |
ForegroundColor |
Color? |
theme on-primary | |
RotateOnOpen |
double |
45 |
Degrees while the menu is open. Zero disables. |
Command / CommandParameter |
Runs in both modes. | ||
IsEnabled |
bool |
true |
|
IsVisible |
bool |
true |
Hiding leaves the gap so tabs do not jump. Remove CenterButton to reclaim the space. |
Actions |
TabActionCollection |
empty | The app-wide fallback. Content property. |
MenuContent / MenuContentTemplate |
null |
The app-wide fallback. |
TabAction
Section titled “TabAction”Text, Icon / IconSource / IconPathData / IconImage, Motion, Command, CommandParameter, IsDestructive (draws the row in the theme’s error colour — nothing is confirmed for you), IsEnabled, IsSeparator (a divider; everything else on the action is ignored), Tag, and a Clicked event.
ShinyTabs attached properties
Section titled “ShinyTabs attached properties”Set on a page, a content view, a ShinyTabItem, or a ShellContent / Tab.
| Property | Type | Notes |
|---|---|---|
Badge |
string? |
Beats ShinyTabItem.Badge, for the tab that page is showing. |
BadgeColor |
Color? |
|
Icon |
string? |
Read by ShinyTabBarBehavior, where a ShellContent has nowhere else to say it. |
Title |
string? |
Overrides the tab’s label. |
Actions |
TabActionCollection |
Needs the <shiny:TabActionCollection> wrapper in XAML. |
MenuContent |
View? |
Beats Actions. |
MenuContentTemplate |
DataTemplate? |
Built fresh on every open. Beats MenuContent. |
IsTabBarVisible |
bool |
Hides the whole bar while that page is showing. |
ShinyTabBarBehavior
Section titled “ShinyTabBarBehavior”| Property | Type | Default | Notes |
|---|---|---|---|
Bar |
ShinyTabBar |
a stock bar | The content property. |
TabSource |
ShellTabSource |
Auto |
Auto · Sections · Items |
Transition |
StateTransition |
Fade |
Incoming page only. |
TransitionDuration |
uint |
200 |
|
HideOnPush |
bool |
true |
Hide on pages pushed onto a tab’s stack. |
Step 1 — Add the marketplace:
claude plugin marketplace add shinyorg/skillsStep 2 — Install the plugin:
claude plugin install shiny@shinyOne plugin installs all 35 Shiny skills. Your agent loads only the skill relevant to what you're building, so there's no cost to having them all available.
Step 1 — Add the marketplace:
copilot plugin marketplace add https://github.com/shinyorg/skillsStep 2 — Install the plugin:
copilot plugin install shiny@shinyOne plugin installs all 35 Shiny skills. Your agent loads only the skill relevant to what you're building, so there's no cost to having them all available.


