UI Shell
A shell is a collection of components shared by all products within a platform. It provides a common set of interaction patterns that persist between and across products.
Overview
The UI shell consists of three modular components: the header, the left panel, and the right panel. Each component can be used on its own, but they are designed to work seamlessly together, providing a consistent and flexible user experience across different products and platforms.
Live demo
Note
This live demo contains only a preview of functionality and styles available for this component. Actual widgets may not show the exact same behavior but similar to expected.
CScreen:
UIShellLayout:
CScrollView:
CStackLayout:
adaptive: [False, True]
padding: dp(16)
spacing: dp(16)
CLabel:
style: "heading_06"
text: "Purpose and function"
CLabel:
markup: True
text: f"The shell is perhaps the most crucial piece of any UI built with [color=#0f62fe]Carbon[/color]. It contains the shared navigation framework for the entire design system and ties the products in IBM’s portfolio together in a cohesive and elegant way. The shell is the home of the topmost navigation, where users can quickly and dependably gain their bearings and move between pages.\n\nThe shell was designed with maximum flexibility built in, to serve the needs of a broad range of products and users. Adopting the shell ensures compliance with IBM design standards, simplifies development efforts, and provides great user experiences. All IBM products built with Carbon are required to use the shell’s header.\n\nTo better understand the purpose and function of the UI shell, consider the “shell” of MacOS, which contains the Apple menu, top-level navigation, and universal, OS-level controls at the top of the screen, as well as a universal dock along the bottom or side of the screen. The Carbon UI shell is roughly analogous in function to these parts of the Mac UI. For example, the app switcher portion of the shell can be compared to the dock in MacOS."
UIShell:
id: left_panel_shell
UIShellLeftPanel:
panel_shell: left_panel_shell
visibility: shell_menu_btn.active
ScrollView:
do_scroll_x: False
UIShellPanelLayout:
UIShellPanelSelectionLayout:
UIShellPanelSelectionItem:
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
default: True
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
text: "Link"
left_icon: "incomplete"
UIShellPanelSelectionItem:
text: "Link"
left_icon: "incomplete"
UIShell:
id: header_shell
UIShellHeader:
id: shell_header
UIShellHeaderMenuButton:
id: shell_menu_btn
UIShellHeaderName:
markup: True
text: "[font=ibmplexsans]IBM[/font] [Platform]"
CScreen:
UIShellLayout:
CScrollView:
CStackLayout:
adaptive: [False, True]
padding: dp(16)
spacing: dp(16)
CLabel:
style: "heading_06"
text: "Purpose and function"
CLabel:
markup: True
text: f"The shell is perhaps the most crucial piece of any UI built with [color=#0f62fe]Carbon[/color]. It contains the shared navigation framework for the entire design system and ties the products in IBM’s portfolio together in a cohesive and elegant way. The shell is the home of the topmost navigation, where users can quickly and dependably gain their bearings and move between pages.\n\nThe shell was designed with maximum flexibility built in, to serve the needs of a broad range of products and users. Adopting the shell ensures compliance with IBM design standards, simplifies development efforts, and provides great user experiences. All IBM products built with Carbon are required to use the shell’s header.\n\nTo better understand the purpose and function of the UI shell, consider the “shell” of MacOS, which contains the Apple menu, top-level navigation, and universal, OS-level controls at the top of the screen, as well as a universal dock along the bottom or side of the screen. The Carbon UI shell is roughly analogous in function to these parts of the Mac UI. For example, the app switcher portion of the shell can be compared to the dock in MacOS."
UIShell:
id: right_panel_shell
UIShellRightPanel:
panel_shell: right_panel_shell
visibility: shell_notification_btn.focus
UIShell:
id: header_shell
UIShellHeader:
id: shell_header
UIShellHeaderName:
markup: True
text: "[font=ibmplexsans]IBM[/font] [Platform]"
CAnchorLayout:
anchor_x: "right"
CGridLayout:
adaptive: [True, True]
rows: 1
UIShellButton:
id: shell_search_btn
icon: "search"
UIShellButton:
id: shell_notification_btn
icon: "notification"
UIShellButton:
id: shell_switcher_btn
icon: "switcher"
CScreen:
UIShellLayout:
CScrollView:
CStackLayout:
adaptive: [False, True]
padding: dp(16)
spacing: dp(16)
CLabel:
style: "heading_06"
text: "Purpose and function"
CLabel:
markup: True
text: f"The shell is perhaps the most crucial piece of any UI built with [color=#0f62fe]Carbon[/color]. It contains the shared navigation framework for the entire design system and ties the products in IBM’s portfolio together in a cohesive and elegant way. The shell is the home of the topmost navigation, where users can quickly and dependably gain their bearings and move between pages.\n\nThe shell was designed with maximum flexibility built in, to serve the needs of a broad range of products and users. Adopting the shell ensures compliance with IBM design standards, simplifies development efforts, and provides great user experiences. All IBM products built with Carbon are required to use the shell’s header.\n\nTo better understand the purpose and function of the UI shell, consider the “shell” of MacOS, which contains the Apple menu, top-level navigation, and universal, OS-level controls at the top of the screen, as well as a universal dock along the bottom or side of the screen. The Carbon UI shell is roughly analogous in function to these parts of the Mac UI. For example, the app switcher portion of the shell can be compared to the dock in MacOS."
UIShell:
id: left_panel_shell
UIShellLeftPanel:
panel_shell: left_panel_shell
visibility: shell_menu_btn.active
ScrollView:
do_scroll_x: False
UIShellPanelLayout:
UIShellPanelSelectionLayout:
UIShellPanelSelectionItem:
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
default: True
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
text: "Link"
left_icon: "incomplete"
UIShellPanelSelectionItem:
text: "Link"
left_icon: "incomplete"
UIShell:
id: right_panel_shell
UIShellRightPanel:
panel_shell: right_panel_shell
visibility: shell_notification_btn.focus
UIShell:
id: header_shell
UIShellHeader:
id: shell_header
UIShellHeaderMenuButton:
id: shell_menu_btn
UIShellHeaderName:
markup: True
text: "[font=ibmplexsans]IBM[/font] [Platform]"
CAnchorLayout:
anchor_x: "right"
CGridLayout:
adaptive: [True, True]
rows: 1
UIShellButton:
id: shell_search_btn
icon: "search"
UIShellButton:
id: shell_notification_btn
icon: "notification"
UIShellButton:
id: shell_switcher_btn
icon: "switcher"
Individual components
The class UIShell inherits from the class CStackLayout and holds different individual components.
UI shell header
The UI shell header serves as the primary navigation and orientation element for users within the interface. It can function independently or be integrated with the UI shell’s left and right panels to support more advanced navigation scenarios.
UI shell left panel
The left panel contains secondary navigation and is positioned below the header and fixed to the left. Both links and sub-menus can be used in the side-nav and may be mixed together.
UI shell right panel
The right panel is invoked by icons on the right side of the header, and remains anchored to that icon. Right panels have a consistent width, span the full height of the viewport, and are flush to the right edge of the viewport.
Example
from kivy.clock import Clock
from kivy.core.window import Window
def set_softinput(*args) -> None:
Window.keyboard_anim_args = {"d": 0.2, "t": "in_out_expo"}
Window.softinput_mode = "below_target"
Window.on_restore(Clock.schedule_once(set_softinput, 0.1))
from carbonkivy.app import CarbonApp
from carbonkivy.uix.screen import CScreen
from carbonkivy.uix.screenmanager import CScreenManager
class UI(CScreenManager):
pass
class HomeScreen(CScreen):
pass
class myapp(CarbonApp):
def __init__(self, *args, **kwargs) -> None:
super(myapp, self).__init__(*args, **kwargs)
self.load_all_kv_files(self.directory)
def build(self) -> UI:
self.manager_screens = UI()
self.manager_screens.add_widget(HomeScreen(name="home"))
return self.manager_screens
if __name__ == "__main__":
myapp().run()
<HomeScreen>:
UIShellLayout:
CScrollView:
CStackLayout:
adaptive: [False, True]
padding: dp(16)
spacing: dp(16)
CLabel:
style: "heading_06"
text: "Purpose and function"
CLabel:
markup: True
text: f"The shell is perhaps the most crucial piece of any UI built with [color=#0f62fe]Carbon[/color]. It contains the shared navigation framework for the entire design system and ties the products in IBM’s portfolio together in a cohesive and elegant way. The shell is the home of the topmost navigation, where users can quickly and dependably gain their bearings and move between pages.\n\nThe shell was designed with maximum flexibility built in, to serve the needs of a broad range of products and users. Adopting the shell ensures compliance with IBM design standards, simplifies development efforts, and provides great user experiences. All IBM products built with Carbon are required to use the shell’s header.\n\nTo better understand the purpose and function of the UI shell, consider the “shell” of MacOS, which contains the Apple menu, top-level navigation, and universal, OS-level controls at the top of the screen, as well as a universal dock along the bottom or side of the screen. The Carbon UI shell is roughly analogous in function to these parts of the Mac UI. For example, the app switcher portion of the shell can be compared to the dock in MacOS."
UIShell:
id: left_panel_shell
UIShellLeftPanel:
panel_shell: left_panel_shell
visibility: shell_menu_btn.active
ScrollView:
do_scroll_x: False
UIShellPanelLayout:
UIShellPanelSelectionLayout:
UIShellPanelSelectionItem:
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
default: True
text: "Category title"
left_icon: "incomplete"
right_icon: "chevron--down"
UIShellPanelSelectionItem:
text: "Link"
left_icon: "incomplete"
UIShellPanelSelectionItem:
text: "Link"
left_icon: "incomplete"
UIShell:
id: right_panel_shell
UIShellRightPanel:
panel_shell: right_panel_shell
visibility: shell_notification_btn.focus
UIShell:
id: header_shell
UIShellHeader:
id: shell_header
UIShellHeaderMenuButton:
id: shell_menu_btn
UIShellHeaderName:
markup: True
text: "[font=ibmplexsans]IBM[/font] [Platform]"
CAnchorLayout:
anchor_x: "right"
CGridLayout:
adaptive: [True, True]
rows: 1
UIShellButton:
id: shell_search_btn
icon: "search"
UIShellButton:
id: shell_notification_btn
icon: "notification"
UIShellButton:
id: shell_switcher_btn
icon: "switcher"
API
- class carbonkivy.uix.shell.shell.UIShell(*args: Any, **kwargs: Any)[source]
Bases:
CStackLayout
- class carbonkivy.uix.shell.shell.UIShellButton(*args: Any, **kwargs: Any)[source]
Bases:
CButtonGhost
- class carbonkivy.uix.shell.shell.UIShellHeader(*args: Any, **kwargs: Any)[source]
Bases:
CBoxLayout
- class carbonkivy.uix.shell.shell.UIShellHeaderMenuButton(*args: Any, **kwargs: Any)[source]
Bases:
UIShellButton
- class carbonkivy.uix.shell.shell.UIShellHeaderName(*args: Any, **kwargs: Any)[source]
Bases:
CLabel,StateFocusBehavior
- class carbonkivy.uix.shell.shell.UIShellLayout(*args: Any, **kwargs: Any)[source]
Bases:
CStackLayout
- class carbonkivy.uix.shell.shell.UIShellLeftPanel(*args: Any, **kwargs: Any)[source]
Bases:
CRelativeLayout- on_touch_down(touch)[source]
- on_touch_up(touch)[source]
- overlay[source]
ColorProperty(defaultvalue=0, **kw) Property that represents a color. The assignment can take either:
a collection of 3 or 4 float values between 0-1 (kivy default)
a string in the format #rrggbb or #rrggbbaa
a string representing color name (eg. ‘red’, ‘yellow’, ‘green’)
Object
colormapis used to retrieve color from color name and names definitions can be found at this link. Color can be assigned in different formats, but it will be returned asObservableListof 4 float elements with values between 0-1.- Parameters:
- defaultvalue: list or string, defaults to [1.0, 1.0, 1.0, 1.0]
Specifies the default value of the property.
Added in version 1.10.0.
Changed in version 2.0.0: Color value will be dispatched when set through indexing or slicing, but when setting with slice you must ensure that slice has 4 components with float values between 0-1. Assingning color name as value is now supported. Value None is allowed as default value for property.
- panel_shell[source]
ObjectProperty(defaultvalue=None, rebind=False, **kw) Property that represents a Python object.
- Parameters:
- defaultvalue: object type
Specifies the default value of the property.
- rebind: bool, defaults to False
Whether kv rules using this object as an intermediate attribute in a kv rule, will update the bound property when this object changes.
That is the standard behavior is that if there’s a kv rule
text: self.a.b.c.d, wherea,b, andcare properties withrebindFalseanddis aStringProperty. Then when the rule is applied,textbecomes bound only tod. Ifa,b, orcchange,textstill remains bound tod. Furthermore, if any of them wereNonewhen the rule was initially evaluated, e.g.bwasNone; thentextis bound toband will not become bound todeven whenbis changed to not beNone.By setting
rebindtoTrue, however, the rule will be re-evaluated and all the properties rebound when that intermediate property changes. E.g. in the example above, wheneverbchanges or becomes notNoneif it wasNonebefore,textis evaluated again and becomes rebound tod. The overall result is thattextis now bound to all the properties amonga,b, orcthat haverebindset toTrue.- **kwargs: a list of keyword arguments
- baseclass
If kwargs includes a baseclass argument, this value will be used for validation: isinstance(value, kwargs[‘baseclass’]).
Warning
To mark the property as changed, you must reassign a new python object.
Changed in version 1.9.0: rebind has been introduced.
Changed in version 1.7.0: baseclass parameter added.
- panel_width[source]
NumericProperty(defaultvalue=0, **kw) Property that represents a numeric value.
It only accepts the int or float numeric data type or a string that can be converted to a number as shown below. For other numeric types use ObjectProperty or use errorhandler to convert it to an int/float.
It does not support numpy numbers so they must be manually converted to int/float. E.g.
widget.num = np.arange(4)[0]will raise an exception. Numpy arrays are not supported at all, even by ObjectProperty because their comparison does not return a bool. But if you must use a Kivy property, use a ObjectProperty withcomparatorset tonp.array_equal. E.g.:>>> class A(EventDispatcher): ... data = ObjectProperty(comparator=np.array_equal) >>> a = A() >>> a.bind(data=print) >>> a.data = np.arange(2) <__main__.A object at 0x000001C839B50208> [0 1] >>> a.data = np.arange(3) <__main__.A object at 0x000001C839B50208> [0 1 2]- Parameters:
- defaultvalue: int or float, defaults to 0
Specifies the default value of the property.
>>> wid = Widget() >>> wid.x = 42 >>> print(wid.x) 42 >>> wid.x = "plop" Traceback (most recent call last): File "<stdin>", line 1, in <module> File "properties.pyx", line 93, in kivy.properties.Property.__set__ File "properties.pyx", line 111, in kivy.properties.Property.set File "properties.pyx", line 159, in kivy.properties.NumericProperty.check ValueError: NumericProperty accept only int/floatChanged in version 1.4.1: NumericProperty can now accept custom text and tuple value to indicate a type, like “in”, “pt”, “px”, “cm”, “mm”, in the format: ‘10pt’ or (10, ‘pt’).
- class carbonkivy.uix.shell.shell.UIShellPanelLayout(*args: Any, **kwargs: Any)[source]
Bases:
UIShellLayout
- class carbonkivy.uix.shell.shell.UIShellPanelSelectionItem(*args: Any, **kwargs: Any)[source]
Bases:
ButtonBehavior,CBoxLayout,StateFocusBehavior,HoverBehavior,SelectableBehavior- left_icon[source]
StringProperty(defaultvalue=u’’, **kw) Property that represents a string value.
- Parameters:
- defaultvalue: string, defaults to ‘’
Specifies the default value of the property.
- class carbonkivy.uix.shell.shell.UIShellPanelSelectionLayout(**kwargs)[source]
Bases:
CSelectionLayout
- class carbonkivy.uix.shell.shell.UIShellRightPanel(*args: Any, **kwargs: Any)[source]
Bases:
CRelativeLayout- master[source]
ObjectProperty(defaultvalue=None, rebind=False, **kw) Property that represents a Python object.
- Parameters:
- defaultvalue: object type
Specifies the default value of the property.
- rebind: bool, defaults to False
Whether kv rules using this object as an intermediate attribute in a kv rule, will update the bound property when this object changes.
That is the standard behavior is that if there’s a kv rule
text: self.a.b.c.d, wherea,b, andcare properties withrebindFalseanddis aStringProperty. Then when the rule is applied,textbecomes bound only tod. Ifa,b, orcchange,textstill remains bound tod. Furthermore, if any of them wereNonewhen the rule was initially evaluated, e.g.bwasNone; thentextis bound toband will not become bound todeven whenbis changed to not beNone.By setting
rebindtoTrue, however, the rule will be re-evaluated and all the properties rebound when that intermediate property changes. E.g. in the example above, wheneverbchanges or becomes notNoneif it wasNonebefore,textis evaluated again and becomes rebound tod. The overall result is thattextis now bound to all the properties amonga,b, orcthat haverebindset toTrue.- **kwargs: a list of keyword arguments
- baseclass
If kwargs includes a baseclass argument, this value will be used for validation: isinstance(value, kwargs[‘baseclass’]).
Warning
To mark the property as changed, you must reassign a new python object.
Changed in version 1.9.0: rebind has been introduced.
Changed in version 1.7.0: baseclass parameter added.
- on_touch_down(touch)[source]
- on_touch_up(touch)[source]
- overlay[source]
ColorProperty(defaultvalue=0, **kw) Property that represents a color. The assignment can take either:
a collection of 3 or 4 float values between 0-1 (kivy default)
a string in the format #rrggbb or #rrggbbaa
a string representing color name (eg. ‘red’, ‘yellow’, ‘green’)
Object
colormapis used to retrieve color from color name and names definitions can be found at this link. Color can be assigned in different formats, but it will be returned asObservableListof 4 float elements with values between 0-1.- Parameters:
- defaultvalue: list or string, defaults to [1.0, 1.0, 1.0, 1.0]
Specifies the default value of the property.
Added in version 1.10.0.
Changed in version 2.0.0: Color value will be dispatched when set through indexing or slicing, but when setting with slice you must ensure that slice has 4 components with float values between 0-1. Assingning color name as value is now supported. Value None is allowed as default value for property.
- panel_shell[source]
ObjectProperty(defaultvalue=None, rebind=False, **kw) Property that represents a Python object.
- Parameters:
- defaultvalue: object type
Specifies the default value of the property.
- rebind: bool, defaults to False
Whether kv rules using this object as an intermediate attribute in a kv rule, will update the bound property when this object changes.
That is the standard behavior is that if there’s a kv rule
text: self.a.b.c.d, wherea,b, andcare properties withrebindFalseanddis aStringProperty. Then when the rule is applied,textbecomes bound only tod. Ifa,b, orcchange,textstill remains bound tod. Furthermore, if any of them wereNonewhen the rule was initially evaluated, e.g.bwasNone; thentextis bound toband will not become bound todeven whenbis changed to not beNone.By setting
rebindtoTrue, however, the rule will be re-evaluated and all the properties rebound when that intermediate property changes. E.g. in the example above, wheneverbchanges or becomes notNoneif it wasNonebefore,textis evaluated again and becomes rebound tod. The overall result is thattextis now bound to all the properties amonga,b, orcthat haverebindset toTrue.- **kwargs: a list of keyword arguments
- baseclass
If kwargs includes a baseclass argument, this value will be used for validation: isinstance(value, kwargs[‘baseclass’]).
Warning
To mark the property as changed, you must reassign a new python object.
Changed in version 1.9.0: rebind has been introduced.
Changed in version 1.7.0: baseclass parameter added.
- panel_width[source]
NumericProperty(defaultvalue=0, **kw) Property that represents a numeric value.
It only accepts the int or float numeric data type or a string that can be converted to a number as shown below. For other numeric types use ObjectProperty or use errorhandler to convert it to an int/float.
It does not support numpy numbers so they must be manually converted to int/float. E.g.
widget.num = np.arange(4)[0]will raise an exception. Numpy arrays are not supported at all, even by ObjectProperty because their comparison does not return a bool. But if you must use a Kivy property, use a ObjectProperty withcomparatorset tonp.array_equal. E.g.:>>> class A(EventDispatcher): ... data = ObjectProperty(comparator=np.array_equal) >>> a = A() >>> a.bind(data=print) >>> a.data = np.arange(2) <__main__.A object at 0x000001C839B50208> [0 1] >>> a.data = np.arange(3) <__main__.A object at 0x000001C839B50208> [0 1 2]- Parameters:
- defaultvalue: int or float, defaults to 0
Specifies the default value of the property.
>>> wid = Widget() >>> wid.x = 42 >>> print(wid.x) 42 >>> wid.x = "plop" Traceback (most recent call last): File "<stdin>", line 1, in <module> File "properties.pyx", line 93, in kivy.properties.Property.__set__ File "properties.pyx", line 111, in kivy.properties.Property.set File "properties.pyx", line 159, in kivy.properties.NumericProperty.check ValueError: NumericProperty accept only int/floatChanged in version 1.4.1: NumericProperty can now accept custom text and tuple value to indicate a type, like “in”, “pt”, “px”, “cm”, “mm”, in the format: ‘10pt’ or (10, ‘pt’).