Styling Grammar
Contents
- 1 Syntax
- 2 Values
- 3 Properties
- 3.1 all
- 3.2 Font
- 3.3 Icon
- 3.4 Text
- 3.5 Border
- 3.5.1 border-top-size
- 3.5.2 border-right-size
- 3.5.3 border-bottom-size
- 3.5.4 border-left-size
- 3.5.5 border-top-color
- 3.5.6 border-right-color
- 3.5.7 border-bottom-color
- 3.5.8 border-left-color
- 3.5.9 border-top-left-radius
- 3.5.10 border-top-right-radius
- 3.5.11 border-bottom-right-radius
- 3.5.12 border-bottom-left-radius
- 3.5.13 border-size
- 3.5.14 border-color
- 3.5.15 border-radius
- 3.5.16 border (shorthand)
- 3.6 Padding
- 3.7 Spacing
- 3.8 Grid Color
- 3.9 background-color
- 3.10 body-align
- 3.11 leading-zeros
- 3.12 trailing-zeros
- 3.13 list-item-gap
- 3.14 list-over-flow-gap
- 3.15 line-height
- 4 Attributes
- 5 Expression (Function)
- 6 Some examples
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 {
|
The class selector and ID selector in CSS are not supported since the Spire styling doesn’t support them.
Selects all instances of the selector. | .TextBox | Not support | |
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.
|
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
|
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
Hexadecimal Colors
Syntax:
#rrggbb
Example:
TextBox {background-color: #ff0000;}
Hexadecimal Colors With Transparency
Syntax:
#rrggbbaa
Example:
TextBox {background-color: #ff000008;}
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);}
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);}
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.
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] {
}
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 {
background-color: transparent;
}
}
}