Styling Grammar

From Spire Trading Inc.
Revision as of 14:24, 6 September 2024 by Jon (talk | contribs) (Detailed reference of the styling grammar for the UI.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Syntax

Declarations

A property and value pair is called a declaration. The pair is separated by a colon, ':'. White spaces are ignored. Properties and values are case-insensitive. If the value is invalid for the property, the declaration will be ignored.

Property            value
background-color:   white

Declaration blocks

A pair of brackets, ‘{’ and ‘}’, are used to group multiple declarations into a block. The semicolon ‘;’ is used to separate different declarations.

{
    background-color: white;
    border-size: 1px;
}

Selector

The selector specifies which components are being applied for styles.

Selector types:

Selector Explanation Example Spire styling
Any selector (universal selector) Selects all components. * Any()
Type selector Selects all instances of the selector and of its subclasses. TextBox is_a<Type>
Property selector Selects elements based on the element having a given attribute explicitly set. Button[visibility=none]

Button:not([visibility=none])

Button && matches(Visibility::NONE)

Button && !matches(Visibility::NONE)

& nesting selector The & nesting selector makes the nested child rule selectors relative to the parent element. Without the & nesting selector, the child rule selector selects child elements. parentRule {

/* parent rule style properties */
& childRule {
/* child rule style properties */

}
}

The class selector and ID selector in CSS are not supported since the Spire styling doesn’t support them.

Class selector Selects all instances of the selector. .TextBox Not support
ID selector Matches all instances that has a specific object name. #my-label Not support


Pseudo-classes

The pseudo-class specifies a given state to the components. It starts with a colon.

:pseudo-class {
  property: value;
}
Selector Explanation Related components
:active Selects a component that is or belongs to the active window. All components
:disabled Selects a disabled component. All components
:hover Selects a hovered component. All components
:focus Selects a focused component. All components
:focus-in Selects a component that has focus or has a child that has focus.. All components
:focus-visible Selects a component if it was focused using a non-pointing device All components
:drag Selects a Dragged component. SplitView, ScrollBar
:press Selects a pressed component. Button, Slider, Slider2D, MenuButton
:read-only Selects a read-only component. All input boxes.
:rejected Selects a a component whose input value is rejected. TextBox, DurationBox, DestinationBox, SaleConditionBox, DateBox
:checked Selects a checked CheckBox. CheckBox
:selected Selects a selected list item. ListItem
:current Selects the current list item. ListItem
:precedes-current Selects the list item precedes the current item. ListItem
:hover-item Selects the hovered table item TableItem
:current-row Selects the current row in the table. TableBody
:current-column Selects the current column in the table. TableBody
:sortable Selects the column when it's sort order is not UNORDERED. TableHeaderItem
:filtered Selects the column when a filter is applied. TableHeaderItem
:pop-up Selects the widget displaying a pop-up. DropDownBox
:high-lighted Selects the highlighted widget. ColorSwatch
:is-positive Selects the DecimalBox when its value is positive. DecimalBox
:is-negative Selects the DecimalBox when its value is negative. DecimalBox
:uptick Selects the DecimalBox when its value has increased. DecimalBox
:downtick Selects the DecimalBox when its value has decreased. DecimalBox
:modifier-key Selects the KeyTag when it's displaying a modifier key. KeyTag
:escape-key Selects the KeyTag when it's displaying the ESC key. KeyTag
:today Selects the CalendarDatePicker when the current day is today. CalendarDatePicker
:out-of-month Selects the CalendarDatePicker when a day is outside of the current month. CalendarDatePicker
:has() Takes a selector as its argument and matches any element matching this selector. All components
:not() Selects a component that is not selected by a selector. All components
:flip() Flips what elements are selected. All components
:is() Selects any element that can be selected by one of the selectors in its list.


:is(selector1, selector2, ...)

All components


Pseudo-elements

A pseudo-element selects components that are the specific part of a selector. The pseudo-element must be used in combination with a block-level element selector. This means you cannot use pseudo-elements on its own without specifying a block-level element. Pseudo-elements start with a double colon :: .

selector::pseudo-element {
  property: value;
}
Selector Explanation Related components Spire styling
::placeholder Select the placeholder in the text box. TextBox, TextAreaBox PseudoElement


Sub-controls

Selectors can contain sub-controls that make it possible to restrict the application of a rule to specific sub-controls. Its syntax is same as pseudo-element’s.

selector::sub-controls{
  property: value;
}
Selector Explanation Related components
::row Selects all rows in the table. TableBody
::column Selects all columns in the table. TableBody
::prompt Selects the prompt in a key input box. KeyInputBox
::divider Selects the divider. TabView, SplitView
::body Selects the body component of a box or button. Box, Button
::empty-cell Selects the empty table cell in the EditableTableView. TableItem(EditableTableView)
::delete-button Selects the delete button in the EditableTableView. TableItem(EditableTableView)
::label Selects the label inside the TableHeaderItem. TableHeaderItem
::filter-button Selects the filter button inside the TableHeaderItem. TableHeaderItem
::hover-element Selects the hover element inside the TableHeaderItem. TableHeaderItem
::track Selects the track of the slider. Slider, Slider2D
::thumb Selects the thumb of the slider. Slider, Slider2D
::track-rail Selects the track rail of the slider. Slider
::track-fill Selects the track fill of the slider. Slider
::track-pad Selects the track pad of the 2d slider. Slider2D
::scrollbar-track Selects the track of the scroll bar. ScrollBar
::scrollbar-thumb Selects the thumb of the scroll bar. ScrollBar
::colon Selects the colon field. DurationBox
::alpha Selects the alpha component in the ColorCodePanel. ColorCodePanel
::primary Selects the primary component in the SplitView. SplitView
::secondary Selects the secondary component in the SplitView. SplitView


Selectors Combination

Selector Explanation Syntax Example CSS supports
Child selector Selects a component matched by the second selector that is the direct child of the component matched by the first. selector1 > selector2 TableView > TableBody Yes
Descendant selector Selects a component matched by the second selector that is the descendant of the component matched by the first. selector >> descendant- selector ColorPicker >> Alpha Yes, but a single space is used.
Parent selector Selects a component matched by the second selector that is the direct parent of the component matched by the first. :has(> child-selector)


ListItem:has(> TextBox)


The :has() pseudo-class can achieve the functionality.
Ancestor selector Selects a component matched by the second selector that is the ancestor of the component matched by the first. :has(>> descendant-selector)


TableItem:has(>> TableItem)


The :has() pseudo-class can achieve the functionality.
And selector Selects components that are matched by both selectors. <selector1><selector2> TextBox:hover


Combining Type selector and Pseudo-Class
Flip selector Flips what elements are selected. :flip() *:flip(:has(>> ListItem)) No
Not selector Selects a component that is not selected by a selector. :not() :not(:hover) :not()
Or selector Selects a component that is selected by at least one of two selectors. selector1, selector2 :hover, :focus

or


:is(:hover, :focus)

selector list
Sibling selector Selects a component matched by the second selector that is the sibling of the component matched by the first. selector % sibling-selector TextBox % Button Yes, but + is used.

Examples:


Child selector

is_a<Button>() > is_a<TextBox>()

Button > TextBox {
}

or

Button {
    TextBox {
    }
}

or

Button {
    & > TextBox {
    }
}

Descendant selector

is_a<Button>() >> is_a<TextBox>()

Button >> TextBox {
}

or

Button {
    & >> TextBox {
    }
}

Parent selector

is_a<Button>() < is_a<TextBox>()

Button:has(> TextBox) {

Cases used in practice:

auto body_selector = Any() > is_a<TableBody>();
auto item_selector = body_selector > Row() > is_a<TableItem>();
style.get((item_selector > EmptyCell()) < (HoverItem() || Current())).
    set(border_color(QColor(Qt::transparent)));

TableView > TableBody > TableBody::row >
 TableItem:has(> TableItem::empty-cell):hover-item,
TableView > TableBody > TableBody::row >
 TableItem:has(> TableItem::empty-cell):current {
}

or

TableView {
    TableBody {
        TableBody::row {
            TableItem {
                    &:has(> ::empty-cell) {
                        & :hover-item,
                        & :current {
                            border-color: transparent;
                        }
                    }
                }
            }
        }
    }
}

or

TableView {
    TableBody {
        TableBody::row {
            TableItem {
                    &:has(> ::empty-cell):is(:hover-item, :current) {
                        border-color: transparent;
                    }
                }
            }
        }
    }
}

Ancestor selector

is_a<Button>() << is_a<TextBox>(

Button:has(>> TextBox) {
}

And selector

is_a<TextBox>() && Hover()

TextBox:hover
is_a<TextBox>() && ReadOnly() && Disabled()

TextBox:read-only:disabled
is_a<TextBox>() && !Prompt()

TextBox:not(KeyInputBox::Prompt)

Flip selector

+Any()

*:flip()

Not selector

!Hover()

:not(:hover)
!Prompt()

:not(KeyInputBox::prompt)

Or selector

is_a<TextBox>() && (Hover() || Focus()).
    set(border_color(QColor(0x4B23A0)));

TextBox:hover, TextBox:focus {
    border-color: 0x4B23A0;
}

or

TextBox {
    &:hover,
    &:focus {
        border-color: 0x4B23A0;
    }
}

or

TextBox {
    &:is(:hover, :focus) {
        border-color: 0x4B23A0;
    }
}

Sibling selector

is_a<TextBox>() % is_a<Button>()

TextBox % Button

TextBox {
    & % Button {
    }
}

Rules

A selector list and an associated declaration block are called a rule.

TextBox {
    background-color: white;
    border-size: 1px;
}

A commas, ‘,’, is used to separated different selectors which have the the same declaration block.

TextBox, Button {
    background-color: white;
    border-size: 1px;
}

Inheritance

Unlike CSS, a component doesn’t automatically inherit font and color settings from its parent component.


Nesting style

Nesting refers to the practice of placing rules inside other rules. It allows you to group related styles together to improve readability and reduce repetition.

parent {
  /* parent styles */
  child {
    /* child of parent styles */
  }
}

parent {
  /* parent styles */
  & child {
    /* child of parent styles */
  }
}

The difference between using & nesting selectors and not using nesting selectors.

  • without the & nesting selector
Button {
  /* parent styles */
  :hover {
    /* child of parent styles */
  }
}

It automatically adds the Child selector > between the selectors to create a new selector rule(CSS adds a whitespace between the selectors, building the descendant relationship between selectors by default). The following code shows the equivalent non-nested rules:

Button {
    /* parent styles */
}

/* styles the hovered button's children. */
Button > :hover {
    /* child of parent styles */
}

is_a<Button>() > Hover()
  • with the & nesting selector
Button {
  /* parent styles */
  & :hover {
    /* child of parent styles */
  }
}

With the & nesting selector added with no whitespace, the above block equals to the following code:

Button {
    /* parent styles */
}

/* styles the hovered button. */
Button:hover {
}

is_a<Button>() && Hover()

Other examples

is_a<Button>() >> is_a<TextBox>()

Button {
  /* parent styles */
  & >> TextBox {
    /* child of parent styles */
  }
}

or

Button {
    >> TextBox {
        background-color: black;
    }
}

Button {
    /* parent styles */
}

/* styles the hovered button. */
Button >> TextBox {
    /* child of parent styles */
}

Values

Number

A decimal integer or a real number.

Example:

0, 1, 10, 1.5


Length

Syntax:

Number(px | pt | ch)


Color

  1. Hexadecimal Colors

    Syntax:

    #rrggbb

    Example:

    TextBox {background-color: #ff0000;}

  1. Hexadecimal Colors With Transparency

    Syntax:

    #rrggbbaa

    Example:

    TextBox {background-color: #ff000008;}

  1. RGB Colors

    An RGB color value is specified with syntax rgb(), which has the following syntax:

    rgb(red, green, blue)

    Each parameter is an integer between 0 and 255.

    Example:

    TextBox {background-color: rgb(255, 0, 0);}

  1. RGBA Colors

    RGBA color values are an extension of RGB color values with an alpha channel. The syntax is

    rgba(red, green, blue, alpha)

    The alpha parameter is a number between 0.0 (fully transparent) and 1.0 (fully opaque).

    Example:

    TextBox {background-color: rgba(255, 0, 0, 0.3);}

  1. Predefined Color Names

    Only three color names that have been used in Spire are defined here.

    • transparent
    • white
    • black

    Example:

    TextBox {background-color: transparent;}


Font Style

  • normal
  • italic
  • oblique

Example:

#TextBox {font-style: italic;}


Font Weight

Predefined weight values which Qt supports:

  • thin

    Same as 100.

  • extra-light

    Same as 200.

  • light

    Same as 300.

  • normal

    Same as 400.

  • medium

    Same as 500.

  • demi-bold

    Same as 600.

  • bold

    Same as 700.

  • extra-bold

    Same as 800.

  • black

    Same as 900.


Alignment

{left | right | top | bottom | center}*


Time

It represents a time value expressed in seconds or milliseconds. There is no space between Number and s or ms.

Syntax:

Number(s | ms)


Overflow

  • none

    The list extends indefinitely.

  • wrap

    List items wrap to fill the perpendicular space.


EdgeNavigation

  • contain

    Selection stops at the current selection.

  • wrap

    Selection moves from the first item to last item and vice versa.


Orientation

  • horizontal

    The element is laid out horizontally.

  • vertical

    The element is laid out vertically.


DateFormat

  • YYYYMMDD

    The year, month, and day can be input in a YYYY-MM-DD format.

  • MMDD

    The month and day can be input in a MM-DD format.


Visibility

  • visible

    The element is visible.

  • invisible

    The element is invisible.

  • none

    The element is treated as if it has a width and height of 0.


Properties

all

The all property is a property that resets all properties.

Value:

  • unset

    The unset keyword clears styles of all properties, which has the different meaning with CSS unset. In CSS, unset specifies that all the element's properties should be changed to their inherited values if they inherit by default, or to their initial values if not.

Syntax:

all: unset;

Example:


TextBox:read-only {
    all: unset;
}

style.get(ReadOnly()).clear();

Font

font-family

Example:

#TextBox {font-family: "Roboto";}


font-style

Example:

#TextBox {font-style: normal;}


font-weight

The weights available depend on the font-style that is currently set. It doesn’t support arbitrary values since QFont::setWeight() uses QFont::Weight enumeration as the parameter. Referring to Font weight.

Example:

#TextBox {font-weight: normal;}


font-size

Sets the element's font size. Only pt and px metrics are supported.
Example:


#TextBox {font-size: 12px;}


font (shorthand)

Syntax:

font = font-style? font-weight? font-size font-family

Example:

#TextBox {font: normal medium 12px "Roboto";}


Icon

url

Syntax:

url(filename)

filename is the name of a file on the local disk or stored using the Qt resource system.

Example:

url(":/Icons/spire.svg”)


fill

Syntax:

fill = color | none

Example:

Icon { fill: 0xA0A0A0; }
Icon { fill: none; }

icon-image

Syntax:

icon-image = url (width height)?

Example:

Icon { icon-image: url(":/Icons/spire.svg”) 16px 16px; }

Text

text-align

Value: Alignment

Example:

TextBox {
  text-align: left;
}

text-color

Value: Color

Example:

TextBox {
  text-color: black;
}

text-style (Shorthand)

Syntax:

text-style = font text-color

Example:

TextBox {
    text-style: normal 12px "Roboto" black;
}

Border

border-top-size

Styles the size of the top border.

Value: Length

Example:

Box { border-top-size: 1px; }


border-right-size

Styles the size of the right border.

Value: Length

Example:

Box { border-right-size: 1px; }


border-bottom-size

Styles the size of the bottom border.

Value: Length

Example:

Box { border-bottom-size: 1px; }


border-left-size

Styles the size of the left border.

Value: Length

Example:

Box { border-left-size: 1px; }


border-top-color

Styles the color of the top border.

Value: Color

Example:

Box { border-top-color: 0x4B23A0; }


border-right-color

Styles the color of the right border.

Value: Color

Example:

Box { border-right-color: 0x4B23A0; }


border-bottom-color

Styles the color of the bottom border.

Value: Color

Example:

Box { border-bottom-color: 0x4B23A0; }


border-left-color

Styles the color of the left border.

Value: Color

Example:

Box { border-left-color: 0x4B23A0; }


border-top-left-radius

Styles the radius of the border's top left corner.

Value: Length

Example:

Box { border-top-left-radius: 1px; }


border-top-right-radius

Styles the radius of the border's top right corner.

Value: Length

Example:

Box { border-top-right-radius: 1px; }


border-bottom-right-radius

Styles the radius of the border's bottom right corner.

Value: Length

Example:

Box { border-bottom-right-radius: 1px; }


border-bottom-left-radius

Styles the radius of the border's bottom left corner.

Value: Length

Example:

Box { border-bottom-left-radius: 1px; }


border-size

Applies a single size to all four borders: border-top-size, border-right-size, border-bottom-size and border-left-size.

Value: Length

Example:

Box { border-size: 1px; }


border-color

Applies a single color to all four border: border-top-color, border-right-color, border-bottom-color and border-left-color.

Value: Color

Example:

Box { border-color: 0x4B23A0; }


border-radius

Applies a single radius to all four corners: border-top-left-radius, border-top-right-radius, border-bottom-right-radius and border-bottom-left-radius.

Value: Length

Example:

Box { border-radius: 1px; }


border (shorthand)

Styles all border colors and sizes.

Syntax:

border = border-size border-color

Example:

TextBox {
    border: 1px 0x4B23A0;
}

Padding

padding-top

Styles the size of the top padding.

Value: Length

Example:

Box { padding-top: 8px; }


padding-right

Styles the size of the right padding.

Value: Length

Example:

Box { padding-right: 8px; }

padding-bottom

Styles the size of the bottom padding.

Value: Length

Example:

Box { padding-bottom: 8px; }

padding-left

Styles the size of the left padding.

Value: Length

Example:

Box { padding-left: 8px; }

horizontal-padding

Styles the size of the left and right padding.

Value: Length

Example:

Box { horiztontal-padding: 8px; }

vertical-padding

Styles the size of the top and bottom padding.

Value: Length

Example:

Box { vertical-padding: 8px; }

padding

Styles all four padding size of an element at once.

Value: Length

Example:

Box { padding: 8px; }

Spacing

horizontal-spacing

Styles the horizontal spacing between items in the table body.

Value: Length

Example:

TableBody { horizontal-spacing: 8px; }

vertical-spacing

Styles the vertical spacing between items in the table body.

Value: Length

Example:

TableBody { vertical-spacing: 8px; }

spacing

Styles the spacing between items in the table body.

Value: Length

Example:

TableBody { spacing: 8px; }

Grid Color

horizontal-grid-color

Styles the color of the horizontal grid lines in the table body.

Value: Color

Example:

TableBody { horizontal-grid-color: transparent; }

vertical-grid-color

Styles the color of the vertical grid lines in the table body.

Value: Color

Example:

TableBody { vertical-grid-color: transparent; }

grid-color

Styles the color of the grid lines.

Value: Color

Example:

TableBody { grid-color: transparent; }

background-color

Sets the background color of an element.

Value: Color

Example:

Box { background-color: transparent; }

body-align

Sets the alignment of the body in a box.

Value: Alignment

Example:

DurationBox { body-align: center; }

leading-zeros

The number of leading zeros added as padding to a number.

Value: Number

Example:

DecimalBox { leading-zeros: 4; }

trailing-zeros

The number of trailing zeros added as padding to the fractional part of a number.

Value: Number

Example:

DecimalBox { trailing-zeros: 4; }

list-item-gap

Sets the spacing between list items.

Value: Length

Example:

ListView { list-item-gap: 2px; }

list-over-flow-gap

Sets the gap between list items on overflow=WRAP in direction perpendicular to list direction.

Value: Length

Example:

ListView { list-over-flow-gap: 2px; }

line-height

Styles the line height as a percentage of the font height in the TextAreaBox.

Value: Number

Example:

TextAreaBox { line-height: 1.2; }

Attributes

overflow

Specifies how to layout items on overflow in the ListView.

Value: Overflow

Example:

ListView { overflow: wrap; }

ListView[overflow=wrap] {
}

edge-navigation

Specifies the navigation behavior when the first or last list item is selected and the key for next or previous list item is pressed.

Value: EdgeNavigation

Example:

ListView { edge-navigation: wrap; }

ListView[edge-navigation=wrap] {
}

orientation

Specifies the orientation of the ListView.

Value: Orientation

Example:

ListView { orientation: vertical; }

ListView[orientation=vertical] {
}

date-format

Specifies the accepted date format of the DateBox.

Value: DateFormat

Example:

DateBox { date-format: YYYYMMDD; }

DateBox[date-format=YYYYMMDD] {
}

visibility

It specifies whether an element is visible.

Value: Visibility

Example:

Tag:read-only > Button {
 visibility: none;
}

Expression (Function)

chain

It chains two Expressions together, evaluating to the first until the first expression terminates, and then evaluating to the second.

Syntax:

chain(expression1, expression2)

Example:

TextBox {
    border-color: chain(timeout(0xB71C1C, 550ms), revert);
}

linear

It calculates a linear transition between two sub-expressions.

Syntax:

linear(initial-expression, end-expression, duration)

Example:

TextBox {
    border-color: linear(0xB71C1C, revert, 300ms);
}

minimum

It calculates the minimum of two values.

Syntax:

min(expression1, expression2)

Example:

Box {
    border-size: min(10, 20);
}

revert

It reverts a property's value as if it had not been set by the current rule. It doesn’t take any parameters.

Syntax:

revert

Example:

TextBox {
    border-color: chain(timeout(0xF2F2FF, 250ms),
    linear(0xF2F2FF, revert, 300ms));
}

timeout

It evaluates an expression for a specified duration and then terminates.

Syntax:

timout(expression, duration)

Example:

TextBox {
    border-color: chain(timeout(0xB71C1C, 550ms), revert);
}

Some examples

Child selector with pseudo-classes

Button
style.get((Checked() && !Hover() && !Press()) > is_a<Icon>()).
    set(Fill(QColor(0x7F5EEC)));

Button:checked:not(:hover):not(:press) > Icon {
    fill: 0x7F5EEC;
}

Flip in the DecimalBox

update_style(*decimal_box, [] (auto& style) {
  style.get(ReadOnly() > is_a<Button>()).set(Visibility::NONE);
  style.get(+Any() > (is_a<Button>() && !matches(Visibility::NONE))).
    set(PaddingRight(scale_width(24)));
});

DecimalBox {
    & :read-only {
        Button {
            visibility: none;
        }
    }
    & :flip(> Button:not([visibility=none])) {
        padding-right: 24px;
    }
}

Clear

update_style(*m_text_box, [] (auto& style) {
  style.get(ReadOnly()).clear();
  style.get(Disabled()).clear();
  style.get(ReadOnly() && Disabled()).clear();
});

DropDownBox > TextBox {
    & :read-only {
        all: unset;
    }
    & :disabled {
        all: unset;
    }
    & :read-only:disabled {
        all: unset;
    }
}

Update icons for the Slider

 auto track_image = QImage(":/Icons/hue-spectrum.png");
 auto thumb_image =
   imageFromSvg(":/Icons/color-thumb.svg", scale(14, 14));
 update_style(*slider, [&] (auto& style) {
   style.get(Any() > Track()).set(IconImage(track_image));
   style.get(Any() > Thumb() > is_a<Icon>()).
     set(Fill(boost::optional<QColor>())).
     set(IconImage(thumb_image));
   style.get(Focus() > Thumb() > is_a<Icon>()).
     set(Fill(QColor(0x808080)));
   });


Slider {
    ::track {
        icon-image: url(":/Icons/hue-spectrum.png");
    }
    ::thumb > Icon {
        icon-image: url(":/Icons/color-thumb.svg") 14px 14px;
        fill: none;
    }
    & :focus {
        ::thumb > Icon {
            fill: 0x808080;
        }
    }
}

LabelButton styling

 style.get(Any() > Body()).
   set(TextAlign(Qt::Alignment(Qt::AlignCenter))).
   set(border(scale_width(1), QColor(Qt::transparent))).
   set(BackgroundColor(QColor(0xEBEBEB))).
   set(horizontal_padding(scale_width(8)));
 style.get(Hover() > Body()).
   set(TextColor(QColor(0xFFFFFF))).
   set(BackgroundColor(QColor(0x4B23A0)));
 style.get(Press() > Body()).
   set(TextColor(QColor(0xFFFFFF))).
   set(BackgroundColor(QColor(0x7E71B8)));
 style.get(FocusVisible() > Body()).set(border_color(QColor(0x4B23A0)));
 style.get(Disabled() > Body()).set(TextColor(QColor(0xB8B8B8)));


 Button {
     ::body {
         text-align: center;
         boder: 1px transparent;
         background-color: 0xEBEBEB;
         horizontal-padding: 8px;
     }
     &:hover {
         ::body {
             text-color: 0xFFFFFF;
             background-color: 0x4B23A0;
         }
     }
     &:press {
         ::body {
             text-color: 0xFFFFFF;
             background-color: 0x7E71B8;
         }
     }
     &:focus-visible {
         ::body {
             border-color: 0x4B23A0;
         }
     }
     &:disabled {
         ::body {
             text-color: 0xB8B8B8;
         }
     }
 }

DeleteIconButton styling

update_style(*button, [] (auto& style) {
  style.get(Any() > is_a<Box>()).
    set(BackgroundColor(QColor(Qt::transparent)));
  style.get(Any() > is_a<Icon>()).
    set(BackgroundColor(QColor(Qt::transparent))).
    set(Fill(QColor(0xA0A0A0)));
  style.get((Hover() || Press()) > is_a<Icon>()).
    set(BackgroundColor(QColor(0xEBEBEB))).
    set(Fill(QColor(0x4B23A0)));
  style.get(Disabled() > is_a<Icon>()).set(Fill(QColor(0xD0D0D0)));
});

Button {
    Box {
        background-color: transparent;
    }
    Icon {
        background-color: transparent;
        fill: 0xA0A0A0;
    }
    & :hover,
    & :press {
        Icon {
            background-color: 0xEBEBEB;
            fill: 0x4B23A0;
        }
    }
    & :disabled {
        Icon {
            fill: 0xD0D0D0;
        }
    }
}

TextBox styling

TextBox
auto style = StyleSheet();
auto font = QFont("Roboto");
font.setWeight(QFont::Normal);
font.setPixelSize(scale_width(12));
style.get(Any()).
  set(BackgroundColor(QColor(0xFFFFFF))).
  set(border(scale_width(1), QColor(0xC8C8C8))).
  set(text_style(font, QColor(Qt::black))).
  set(TextAlign(Qt::Alignment(Qt::AlignLeft) | Qt::AlignVCenter)).
  set(horizontal_padding(scale_width(8))).
  set(vertical_padding(scale_height(5)));
style.get(Hover() || Focus()).
  set(border_color(QColor(0x4B23A0)));
style.get(ReadOnly()).
  set(BackgroundColor(QColor(Qt::transparent))).
  set(border_color(QColor(Qt::transparent))).
  set(horizontal_padding(0));
style.get(Disabled()).
  set(BackgroundColor(QColor(0xF5F5F5))).
  set(border_color(QColor(0xC8C8C8))).
  set(TextColor(QColor(0xC8C8C8)));
style.get(ReadOnly() && Disabled()).
  set(BackgroundColor(QColor(Qt::transparent))).
  set(border_color(QColor(Qt::transparent)));
style.get(Rejected()).
  set(BackgroundColor(chain(timeout(QColor(0xFFF1F1), milliseconds(250)),
    linear(QColor(0xFFF1F1), revert, milliseconds(300))))).
  set(border_color(
    chain(timeout(QColor(0xB71C1C), milliseconds(550)), revert)));
style.get(Placeholder()).set(TextColor(QColor(0xA0A0A0)));
style.get(Disabled() > Placeholder()).set(TextColor(QColor(0xC8C8C8)));
TextBox {
    background-color: 0xFFFFFF;
    border: 1px 0xC8C8C8;
    text-style: normal 12px "Roboto" black;
    text-align: left;
    horizontal-padding: 8px;
    vertical-padding: 5px;
    & :hover,
    & :focus {
        border-color: 0x4B23A0;
    }
    & :read-only {
        background-color: transparent;
        border-color: transparent;
        horizontal-padding: 0px;
    }
    & :disabled {
        background-color: 0xF5F5F5;
        border-color: 0xC8C8C8;
        text-color: 0xC8C8C8;
    }
    & :read-only:disabled {
        background-color: transparent;
        border-color: transparent;
    }
    & :rejected {
        background-color: chain(timeout(0xB71C1C, 250ms), linear(0xFFF1F1, revert, 300ms));
        border-color: chain(timeout(0xB71C1C, 550ms), revert);
    }
    & ::placeholder {
        text-color: 0xA0A0A0;
    }
    & :disabled::placeholder {
        text-color: 0xC8C8C8;
    }
}

DropDownBox styling

auto style = StyleSheet();
style.get(ReadOnly() > is_a<TextBox>()).
  set(BackgroundColor(QColor(Qt::transparent))).
  set(border_color(QColor(Qt::transparent))).
  set(horizontal_padding(0));
style.get(Disabled() > is_a<TextBox>()).
  set(BackgroundColor(QColor(0xF5F5F5))).
  set(border_color(QColor(0xC8C8C8))).
  set(TextColor(QColor(0xC8C8C8)));
style.get((ReadOnly() && Disabled()) > is_a<TextBox>()).
  set(BackgroundColor(QColor(Qt::transparent))).
  set(border_color(QColor(Qt::transparent)));
style.get(Any() > (is_a<Icon>() && !(+Any() << is_a<ListItem>()))).
  set(Fill(QColor(0x333333))).
  set(BackgroundColor(QColor(Qt::transparent)));
style.get(Disabled() > (is_a<Icon>() && !(+Any() << is_a<ListItem>()))).
  set(Fill(QColor(0xC8C8C8)));
style.get(ReadOnly() > (is_a<Icon>() && !(+Any() << is_a<ListItem>()))).
  set(Visibility::NONE);
style.get(Any() > (is_a<TextBox>() && !(+Any() << is_a<ListItem>()))).
  set(PaddingRight(scale_width(14)));
style.get(PopUp() > is_a<TextBox>() ||
    (+Any() > is_a<Button>() && (Hover() || FocusIn())) > is_a<TextBox>()).
  set(border_color(QColor(0x4B23A0)));
style.get(ReadOnly() > (is_a<TextBox>() && !(+Any() << is_a<ListItem>()))).
  set(horizontal_padding(0)).
  set(border_color(QColor(Qt::transparent))).
  set(BackgroundColor(QColor(Qt::transparent)));
DropDownBox {
    & :read-only > TextBox {
        background-color: transparent;
        border-color: transparent;
        horizontal-padding: 0;
    }
    & :disabled > TextBox {
        background-color: 0xF5F5F5;
        border-color: 0xC8C8C8;
        text-color: 0xC8C8C8;
    }
    & :read-only:disabled > TextBox {
        background-color: transparent;
        border-color: transparent;
    }
    & :not(:flip(:has(>> ListItem))) {
        Icon {
            fill: 0x333333;
            background-color: transparent;
        }
        TextBox {
            padding-right: 14px;
        }
    }
    & :disabled:not(:flip(:has(>> ListItem))) > Icon {
        fill: 0xC8C8C8;
    }
    & :read-only:not(:flip(:has(>> ListItem))) > Icon {
        visibility: none;
    }
    & :pop-up,
    & :hover:flip(> Button),
    & :focus-in:flip(> Button) {
        TextBox {
            border-color: 0x4B23A0;
        }
    }
    & :read-only:not(:flip(:has(>> ListItem))) {
        TextBox {
            horizontal-padding: 0;
            border-color: transparent;
            background-color: transparent;
        }
    }
}

or

& :pop-up,
& :flip(> Button):is(:hover, :focus-in) {
    TextBox {
        border-color: 0x4B23A0;
    }
}

EditableTableView styling

    auto style = StyleSheet();
    auto body_selector = Any() > is_a<TableBody>();
    auto item_selector = body_selector > Row() > is_a<TableItem>();
    style.get(item_selector > Any() >
        (ReadOnly() && !(+Any() << is_a<ListItem>()) && !Prompt())).
      set(horizontal_padding(scale_width(8)));
    style.get(item_selector >  Any() > ReadOnly() >
        (is_a<TextBox>() && !(+Any() << is_a<ListItem>()) && !Prompt())).
      set(horizontal_padding(scale_width(8)));
    style.get((item_selector > !ReadOnly()) << Current()).
      set(border_color(QColor(Qt::transparent)));
    style.get(body_selector > Row() > Current()).
      set(BackgroundColor(Qt::transparent));
    style.get(body_selector > Row() > HoverItem()).
      set(border_color(QColor(0xA0A0A0)));
    style.get(body_selector > (Row() && Hover())).
      set(BackgroundColor(0xF2F2FF));
    style.get(item_selector > DeleteButton()).
      set(Visibility(Visibility::INVISIBLE));
    style.get(item_selector > DeleteButton() > is_a<Box>()).
      set(BackgroundColor(QColor(Qt::transparent))).
      set(horizontal_padding(scale_width(2))).
      set(vertical_padding(scale_height(2)));
    style.get(item_selector > DeleteButton() > is_a<Icon>()).
      set(BackgroundColor(QColor(Qt::transparent)));
    style.get(body_selector > (CurrentRow() || (Row() && Hover())) >
        is_a<TableItem>() > DeleteButton()).
      set(Visibility(Visibility::VISIBLE));
    style.get((body_selector > (CurrentRow() || (Row() && Hover()))) >
        DeleteButton() > is_a<Icon>()).
      set(Fill(QColor(0x535353)));
    style.get(body_selector > (Row() && Hover()) > DeleteButton() >
        (is_a<Icon>() && Hover())).
      set(BackgroundColor(QColor(0xDFDFEB))).
      set(Fill(QColor(0xB71C1C)));
    style.get(body_selector > CurrentRow() > DeleteButton() >
        (is_a<Icon>() && Hover())).
      set(BackgroundColor(QColor(0xD0CEEB))).
      set(Fill(QColor(0xB71C1C)));
    style.get((item_selector > EmptyCell()) << (HoverItem() || Current())).
      set(border_color(QColor(Qt::transparent)));
    style.get(body_selector > CurrentRow()).
      set(BackgroundColor(QColor(0xE2E0FF)));
    style.get(body_selector > CurrentColumn()).
      set(BackgroundColor(Qt::transparent));

EditableTableView {
    TableBody {
        TableBody::row {
            TableItem {
                * {
                    :not(:flip(:has(>> ListItem))) {
                        :read-only:not(KeyInputBox::prompt) {
                            horizontal-padding: 8px;
                        }
                    }
                    :read-only:not(:flip(:has(>> ListItem))) {
                        TextBox:not(KeyInputBox::prompt) {
                            horizontal-padding: 8px;
                        }
                    }
                }
            }
            & :current:has(> :not(:read-only)) {
                border-color: transparent;
            }
            & :current {
                background-color: transparent;
            }
            & :hover-item {
                border-color: 0xA0A0A0;
            }
            ::delete-button {
                visibility: invisible;
                Box {
                    background-color: transparent;
                    horizontal-padding: 2px;
                    vertical-padding: 2px;
                }
                Icon {
                    background-color: transparent;
                }
            }
            & :has(> ::empty-cell) {
                & :hover-item,
                & :current {
                    border-color: transparent;
                }
            }
        }
        & :hover {
            background-color: 0xF2F2FF;
            TableItem::delete-button {
                visibility: visible;
                Icon {
                    fill: 0x535353;
                    & :hover {
                        background-color: 0xDFDFEB;
                        fill: 0xB71C1C;
                    }
                }
            }
        }
        & :current-row {
            background-color: 0xE2E0FF;
            TableItem::delete-button {
                visibility: visible;
                Icon {
                    fill: 0x535353;
                    & :hover {
                        background-color: 0xDFDFEB;
                        fill: 0xB71C1C;
                    }
                }
            }
        }
        & :current-column {
            backgournd-color: transparent;
        }
    }
}