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

Carbon Design UI Shell

Carbon Design UI Shell 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

active[source]

BooleanProperty(defaultvalue=True, **kw) Property that represents only a boolean value.

Parameters:
defaultvalue: boolean

Specifies the default value of the property.

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]
on_visibility(*args) None[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 colormap is 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 as ObservableList of 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, where a, b, and c are properties with rebind False and d is a StringProperty. Then when the rule is applied, text becomes bound only to d. If a, b, or c change, text still remains bound to d. Furthermore, if any of them were None when the rule was initially evaluated, e.g. b was None; then text is bound to b and will not become bound to d even when b is changed to not be None.

By setting rebind to True, however, the rule will be re-evaluated and all the properties rebound when that intermediate property changes. E.g. in the example above, whenever b changes or becomes not None if it was None before, text is evaluated again and becomes rebound to d. The overall result is that text is now bound to all the properties among a, b, or c that have rebind set to True.

**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 with comparator set to np.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/float

Changed 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’).

visibility[source]

BooleanProperty(defaultvalue=True, **kw) Property that represents only a boolean value.

Parameters:
defaultvalue: boolean

Specifies the default value of the property.

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.

on_left_icon(*args) None[source]
on_right_icon(*args) None[source]
on_text(*args) None[source]
on_touch_down(touch: kivy.input.providers.mouse.MouseMotionEvent) bool[source]
right_icon[source]

StringProperty(defaultvalue=u’’, **kw) Property that represents a string value.

Parameters:
defaultvalue: string, defaults to ‘’

Specifies the default value of the property.

text[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, where a, b, and c are properties with rebind False and d is a StringProperty. Then when the rule is applied, text becomes bound only to d. If a, b, or c change, text still remains bound to d. Furthermore, if any of them were None when the rule was initially evaluated, e.g. b was None; then text is bound to b and will not become bound to d even when b is changed to not be None.

By setting rebind to True, however, the rule will be re-evaluated and all the properties rebound when that intermediate property changes. E.g. in the example above, whenever b changes or becomes not None if it was None before, text is evaluated again and becomes rebound to d. The overall result is that text is now bound to all the properties among a, b, or c that have rebind set to True.

**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]
on_visibility(*args) None[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 colormap is 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 as ObservableList of 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, where a, b, and c are properties with rebind False and d is a StringProperty. Then when the rule is applied, text becomes bound only to d. If a, b, or c change, text still remains bound to d. Furthermore, if any of them were None when the rule was initially evaluated, e.g. b was None; then text is bound to b and will not become bound to d even when b is changed to not be None.

By setting rebind to True, however, the rule will be re-evaluated and all the properties rebound when that intermediate property changes. E.g. in the example above, whenever b changes or becomes not None if it was None before, text is evaluated again and becomes rebound to d. The overall result is that text is now bound to all the properties among a, b, or c that have rebind set to True.

**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 with comparator set to np.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/float

Changed 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’).

visibility[source]

BooleanProperty(defaultvalue=True, **kw) Property that represents only a boolean value.

Parameters:
defaultvalue: boolean

Specifies the default value of the property.