From 04c6292b96dc0d53116eb18fd2f8510862ff3059 Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Mon, 1 Jun 2026 12:35:50 +0300 Subject: [PATCH 1/4] feat(ui5-checkbox): make component customizable --- packages/main/src/themes/CheckBox.css | 65 +++++++++----- packages/main/test/pages/CheckBox.html | 114 +++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 22 deletions(-) diff --git a/packages/main/src/themes/CheckBox.css b/packages/main/src/themes/CheckBox.css index 17a8b03cdba0..30056a2c6aa1 100644 --- a/packages/main/src/themes/CheckBox.css +++ b/packages/main/src/themes/CheckBox.css @@ -3,7 +3,8 @@ @import "./FormComponents.css"; :host(:not([hidden])) { - display: inline-block; + display: inline-flex; + align-items: center; } :host([required]) { @@ -11,7 +12,6 @@ } :host { - overflow: hidden; max-width: 100%; outline: none; border-radius: var(--_ui5_checkbox_border_radius); @@ -21,6 +21,7 @@ -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; + font-size: var(--sapFontSize); } /* disabled */ @@ -49,11 +50,7 @@ /* wrap */ :host(:not([wrapping-type="None"])[text]) .ui5-checkbox-root { - min-height: auto; - box-sizing: border-box; align-items: flex-start; - padding-top: var(--_ui5_checkbox_root_side_padding); - padding-bottom: var(--_ui5_checkbox_root_side_padding); } :host(:not([wrapping-type="None"])[text]) .ui5-checkbox-root .ui5-checkbox-label { @@ -120,16 +117,15 @@ position: relative; display: inline-flex; align-items: center; + overflow: hidden; max-width: 100%; - min-height: var(--_ui5_checkbox_width_height); - min-width: var(--_ui5_checkbox_width_height); - padding: 0 var(--_ui5_checkbox_wrapper_padding); + padding-block: var(--_ui5_checkbox_root_side_padding); + padding-inline: var(--_ui5_checkbox_wrapper_padding); box-sizing: border-box; outline: none; transition: var(--_ui5_checkbox_transition); border: var(--_ui5_checkbox_default_focus_border); border-radius: var(--_ui5_checkbox_border_radius); - box-sizing: border-box; } /* focused */ @@ -197,10 +193,11 @@ } .ui5-checkbox-inner { - min-width: var(--_ui5_checkbox_inner_width_height); - max-width: var(--_ui5_checkbox_inner_width_height); - height: var(--_ui5_checkbox_inner_width_height); - max-height: var(--_ui5_checkbox_inner_width_height); + min-width: 1.5714em; /* 1.375rem */ + max-width: 1.5714em; /* 1.375rem */ + height: 1.5714em; /* 1.375rem */ + max-height: 1.5714em; /* 1.375rem */ + flex-shrink: 0; border: var(--_ui5_checkbox_inner_border); border-radius: var(--_ui5_checkbox_inner_border_radius); background: var(--_ui5_checkbox_inner_background); @@ -217,8 +214,8 @@ left:50%; top:50%; transform: translate(-50%, -50%); - width: var(--_ui5_checkbox_partially_icon_size); - height: var(--_ui5_checkbox_partially_icon_size); + width: 0.8571em; /* 0.75rem */ + height: 0.8571em; /* 0.75rem */ } :host input { @@ -237,11 +234,12 @@ overflow: hidden; pointer-events: none; color: var(--_ui5_checkbox_label_color); + font-size: inherit; } .ui5-checkbox-icon { - width: var(--_ui5_checkbox_icon_size); - height: var(--_ui5_checkbox_icon_size); + width: 1.1429em; /* 1rem */ + height: 1.1429em; /* 1rem */ color: currentColor; cursor: inherit; position: absolute; @@ -257,14 +255,37 @@ :host([display-only]) .ui5-checkbox-display-only-icon-inner [ui5-icon] { color: var(--sapTextColor); + width: 1.1429em; /* 1rem */ + height: 1.1429em; /* 1rem */ } :host([display-only]) .ui5-checkbox-display-only-icon-inner { - min-width: var(--_ui5_checkbox_inner_width_height); - max-width: var(--_ui5_checkbox_inner_width_height); - height: var(--_ui5_checkbox_inner_width_height); - max-height: var(--_ui5_checkbox_inner_width_height); + min-width: 1.5714em; /* 1.375rem */ + max-width: 1.5714em; /* 1.375rem */ + height: 1.5714em; /* 1.375rem */ + max-height: 1.5714em; /* 1.375rem */ display: flex; align-items: center; justify-content: center; } + +@container style(--ui5_content_density: compact) { + .ui5-checkbox-inner { + min-width: 1.1429em; /* 1rem */ + max-width: 1.1429em; /* 1rem */ + height: 1.1429em; /* 1rem */ + max-height: 1.1429em; /* 1rem */ + } + + :host([indeterminate][checked]) .ui5-checkbox-inner::after { + width: 0.5714em; /* 0.5rem */ + height: 0.5714em; /* 0.5rem */ + } + + :host([display-only]) .ui5-checkbox-display-only-icon-inner { + min-width: 1.1429em; /* 1rem */ + max-width: 1.1429em; /* 1rem */ + height: 1.1429em; /* 1rem */ + max-height: 1.1429em; /* 1rem */ + } +} diff --git a/packages/main/test/pages/CheckBox.html b/packages/main/test/pages/CheckBox.html index 4a4fb9f660b9..3d9bd444e8e2 100644 --- a/packages/main/test/pages/CheckBox.html +++ b/packages/main/test/pages/CheckBox.html @@ -13,6 +13,65 @@ + + @@ -171,6 +230,61 @@ formValidationMessage.design = isValid ? "Positive" : "Negative"; } + + + + + + +
+

Customization 1 — font-size scaling (20px)

+

Set font-size on the host element. The box, icon, and label all scale proportionally. Works with and without text, and in display-only mode.

+
+ + + + + + + + + + +
+
+ +
+

Customization 2 — reduced padding via ::part(root) + focus ring fix (20px, 4px padding)

+

Override padding on the root part to tighten the hit area. Apply inset: 0 on the focus ::before so the ring follows the new bounds. Tab to see the focus ring.

+
+ + + + + +
+
+ +
+

Customization 3 — wrapping label with big font (24px, 300px wide)

+

Block padding and label alignment both scale correctly when the label wraps to multiple lines.

+
+ + +
+
+ +
+

Customization 4 — value states at big size (20px)

+

Value state colors and borders scale correctly at any font-size.

+
+ + + + +
+
+ From d56c7c4dc063d9fb44a8a35af6ded4386ac3c90e Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Tue, 2 Jun 2026 11:55:29 +0300 Subject: [PATCH 2/4] fix(ui5-checkbox): add compact density override for checkbox icon size --- packages/main/src/themes/CheckBox.css | 4 ++-- packages/main/src/themes/base/sizes-parameters.css | 8 ++++---- .../main/src/themes/sap_horizon/CheckBox-parameters.css | 2 +- .../src/themes/sap_horizon_dark/CheckBox-parameters.css | 2 +- .../src/themes/sap_horizon_hcb/CheckBox-parameters.css | 2 +- .../src/themes/sap_horizon_hcw/CheckBox-parameters.css | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/main/src/themes/CheckBox.css b/packages/main/src/themes/CheckBox.css index 30056a2c6aa1..d71dfe8f4c6f 100644 --- a/packages/main/src/themes/CheckBox.css +++ b/packages/main/src/themes/CheckBox.css @@ -238,8 +238,8 @@ } .ui5-checkbox-icon { - width: 1.1429em; /* 1rem */ - height: 1.1429em; /* 1rem */ + width: var(--_ui5_checkbox_icon_size); + height: var(--_ui5_checkbox_icon_size); color: currentColor; cursor: inherit; position: absolute; diff --git a/packages/main/src/themes/base/sizes-parameters.css b/packages/main/src/themes/base/sizes-parameters.css index 57d6495524ce..465302dd831a 100644 --- a/packages/main/src/themes/base/sizes-parameters.css +++ b/packages/main/src/themes/base/sizes-parameters.css @@ -14,8 +14,8 @@ --_ui5_calendar_overlay_width: 16rem; --_ui5_checkbox_root_side_padding: .6875rem; - --_ui5_checkbox_icon_size: 1rem; - --_ui5_checkbox_partially_icon_size: .75rem; + --_ui5_checkbox_icon_size: 1.1429em; /* 1rem */ + --_ui5_checkbox_partially_icon_size: 0.8571em; /* 0.75rem */ --_ui5_custom_list_item_rb_min_width: 2.75rem; --_ui5_day_picker_item_width: 2.25rem; --_ui5_day_picker_item_height: 2.875rem; @@ -200,8 +200,8 @@ --_ui5_checkbox_focus_position: var(--_ui5_checkbox_compact_focus_position); --_ui5_checkbox_wrapped_focus_inset_block: var(--_ui5_checkbox_focus_position); --_ui5_checkbox_inner_width_height: var(--_ui5_checkbox_compact_inner_size); - --_ui5_checkbox_icon_size: .75rem; - --_ui5_checkbox_partially_icon_size: .5rem; + --_ui5_checkbox_icon_size: 0.8571em; /* 0.75rem */ + --_ui5_checkbox_partially_icon_size: 0.5714em; /* 0.5rem */ /* ColorPicker */ --_ui5_color_picker_slider_progress_container_height: 1.125rem; diff --git a/packages/main/src/themes/sap_horizon/CheckBox-parameters.css b/packages/main/src/themes/sap_horizon/CheckBox-parameters.css index ad17ea3d8f27..7be479d64099 100644 --- a/packages/main/src/themes/sap_horizon/CheckBox-parameters.css +++ b/packages/main/src/themes/sap_horizon/CheckBox-parameters.css @@ -3,7 +3,7 @@ :host { --_ui5_checkbox_wrapper_padding: .6875rem; --_ui5_checkbox_width_height: 2.75rem; - --_ui5_checkbox_icon_size: 1rem; + --_ui5_checkbox_icon_size: 1.1429em; /* 1rem */ --_ui5_checkbox_label_color: var(--sapField_TextColor); /* default checkbox*/ --_ui5_checkbox_inner_border: solid var(--sapField_BorderWidth) var(--sapField_BorderColor); diff --git a/packages/main/src/themes/sap_horizon_dark/CheckBox-parameters.css b/packages/main/src/themes/sap_horizon_dark/CheckBox-parameters.css index ad17ea3d8f27..7be479d64099 100644 --- a/packages/main/src/themes/sap_horizon_dark/CheckBox-parameters.css +++ b/packages/main/src/themes/sap_horizon_dark/CheckBox-parameters.css @@ -3,7 +3,7 @@ :host { --_ui5_checkbox_wrapper_padding: .6875rem; --_ui5_checkbox_width_height: 2.75rem; - --_ui5_checkbox_icon_size: 1rem; + --_ui5_checkbox_icon_size: 1.1429em; /* 1rem */ --_ui5_checkbox_label_color: var(--sapField_TextColor); /* default checkbox*/ --_ui5_checkbox_inner_border: solid var(--sapField_BorderWidth) var(--sapField_BorderColor); diff --git a/packages/main/src/themes/sap_horizon_hcb/CheckBox-parameters.css b/packages/main/src/themes/sap_horizon_hcb/CheckBox-parameters.css index 67080c9f1b7d..0d6c87e4624d 100644 --- a/packages/main/src/themes/sap_horizon_hcb/CheckBox-parameters.css +++ b/packages/main/src/themes/sap_horizon_hcb/CheckBox-parameters.css @@ -3,7 +3,7 @@ :host { --_ui5_checkbox_wrapper_padding: .6875rem; --_ui5_checkbox_width_height: 2.75rem; - --_ui5_checkbox_icon_size: 1rem; + --_ui5_checkbox_icon_size: 1.1429em; /* 1rem */ --_ui5_checkbox_label_color: var(--sapField_TextColor); /* default checkbox*/ --_ui5_checkbox_inner_border: solid var(--sapField_BorderWidth) var(--sapField_BorderColor); diff --git a/packages/main/src/themes/sap_horizon_hcw/CheckBox-parameters.css b/packages/main/src/themes/sap_horizon_hcw/CheckBox-parameters.css index 67080c9f1b7d..0d6c87e4624d 100644 --- a/packages/main/src/themes/sap_horizon_hcw/CheckBox-parameters.css +++ b/packages/main/src/themes/sap_horizon_hcw/CheckBox-parameters.css @@ -3,7 +3,7 @@ :host { --_ui5_checkbox_wrapper_padding: .6875rem; --_ui5_checkbox_width_height: 2.75rem; - --_ui5_checkbox_icon_size: 1rem; + --_ui5_checkbox_icon_size: 1.1429em; /* 1rem */ --_ui5_checkbox_label_color: var(--sapField_TextColor); /* default checkbox*/ --_ui5_checkbox_inner_border: solid var(--sapField_BorderWidth) var(--sapField_BorderColor); From 80ee6f4c6eb8ea36101fb88509cc29685ebd479f Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Tue, 2 Jun 2026 12:10:44 +0300 Subject: [PATCH 3/4] refactor(ui5-checkbox): move em size values to parameters files --- packages/main/src/themes/CheckBox.css | 45 +++++-------------- .../src/themes/base/CheckBox-parameters.css | 4 +- 2 files changed, 14 insertions(+), 35 deletions(-) diff --git a/packages/main/src/themes/CheckBox.css b/packages/main/src/themes/CheckBox.css index d71dfe8f4c6f..20f3c70cd995 100644 --- a/packages/main/src/themes/CheckBox.css +++ b/packages/main/src/themes/CheckBox.css @@ -193,10 +193,10 @@ } .ui5-checkbox-inner { - min-width: 1.5714em; /* 1.375rem */ - max-width: 1.5714em; /* 1.375rem */ - height: 1.5714em; /* 1.375rem */ - max-height: 1.5714em; /* 1.375rem */ + min-width: var(--_ui5_checkbox_inner_width_height); + max-width: var(--_ui5_checkbox_inner_width_height); + height: var(--_ui5_checkbox_inner_width_height); + max-height: var(--_ui5_checkbox_inner_width_height); flex-shrink: 0; border: var(--_ui5_checkbox_inner_border); border-radius: var(--_ui5_checkbox_inner_border_radius); @@ -214,8 +214,8 @@ left:50%; top:50%; transform: translate(-50%, -50%); - width: 0.8571em; /* 0.75rem */ - height: 0.8571em; /* 0.75rem */ + width: var(--_ui5_checkbox_partially_icon_size); + height: var(--_ui5_checkbox_partially_icon_size); } :host input { @@ -255,37 +255,16 @@ :host([display-only]) .ui5-checkbox-display-only-icon-inner [ui5-icon] { color: var(--sapTextColor); - width: 1.1429em; /* 1rem */ - height: 1.1429em; /* 1rem */ + width: var(--_ui5_checkbox_icon_size); + height: var(--_ui5_checkbox_icon_size); } :host([display-only]) .ui5-checkbox-display-only-icon-inner { - min-width: 1.5714em; /* 1.375rem */ - max-width: 1.5714em; /* 1.375rem */ - height: 1.5714em; /* 1.375rem */ - max-height: 1.5714em; /* 1.375rem */ + min-width: var(--_ui5_checkbox_inner_width_height); + max-width: var(--_ui5_checkbox_inner_width_height); + height: var(--_ui5_checkbox_inner_width_height); + max-height: var(--_ui5_checkbox_inner_width_height); display: flex; align-items: center; justify-content: center; } - -@container style(--ui5_content_density: compact) { - .ui5-checkbox-inner { - min-width: 1.1429em; /* 1rem */ - max-width: 1.1429em; /* 1rem */ - height: 1.1429em; /* 1rem */ - max-height: 1.1429em; /* 1rem */ - } - - :host([indeterminate][checked]) .ui5-checkbox-inner::after { - width: 0.5714em; /* 0.5rem */ - height: 0.5714em; /* 0.5rem */ - } - - :host([display-only]) .ui5-checkbox-display-only-icon-inner { - min-width: 1.1429em; /* 1rem */ - max-width: 1.1429em; /* 1rem */ - height: 1.1429em; /* 1rem */ - max-height: 1.1429em; /* 1rem */ - } -} diff --git a/packages/main/src/themes/base/CheckBox-parameters.css b/packages/main/src/themes/base/CheckBox-parameters.css index bf1340f90d8a..dc2a466f4f94 100644 --- a/packages/main/src/themes/base/CheckBox-parameters.css +++ b/packages/main/src/themes/base/CheckBox-parameters.css @@ -14,7 +14,7 @@ --_ui5_checkbox_focus_outline: var(--sapContent_FocusWidth) var(--sapContent_FocusStyle) var(--sapContent_FocusColor); --_ui5_checkbox_focus_border_radius: 0; --_ui5_checkbox_outer_hover_background: transparent; - --_ui5_checkbox_inner_width_height: 1.375rem; + --_ui5_checkbox_inner_width_height: 1.5714em; /* 1.375rem */ --_ui5_checkbox_inner_border: solid .125rem var(--sapField_BorderColor); --_ui5_checkbox_inner_hover_border_color: var(--sapField_HoverBorderColor); --_ui5_checkbox_inner_hover_checked_border_color: var(--sapField_HoverBorderColor); @@ -36,7 +36,7 @@ --_ui5_checkbox_wrapped_focus_inset_block: var(--_ui5_checkbox_focus_position); --_ui5_checkbox_compact_wrapper_padding: .5rem; --_ui5_checkbox_compact_width_height: 2rem; - --_ui5_checkbox_compact_inner_size: 1rem; + --_ui5_checkbox_compact_inner_size: 1.1429em; /* 1rem */ --_ui5_checkbox_compact_focus_position: .375rem; --_ui5_checkbox_label_color: var(--sapContent_LabelColor); --_ui5_checkbox_label_offset: var(--_ui5_checkbox_wrapper_padding); From c16bbe31d37e37c4320b3656415a48cd669f1a8f Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Tue, 2 Jun 2026 14:53:48 +0300 Subject: [PATCH 4/4] chore: add font-size scaling tests --- packages/main/cypress/specs/CheckBox.cy.tsx | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/main/cypress/specs/CheckBox.cy.tsx b/packages/main/cypress/specs/CheckBox.cy.tsx index c8db82a08613..b9af06906ec9 100644 --- a/packages/main/cypress/specs/CheckBox.cy.tsx +++ b/packages/main/cypress/specs/CheckBox.cy.tsx @@ -369,6 +369,47 @@ describe("CheckBox general interaction", () => { }); }); +describe("Font-size scaling", () => { + it("scales inner box size when font-size is set on the host", () => { + cy.mount(); + + cy.get("[ui5-checkbox]") + .shadow() + .find(".ui5-checkbox-inner") + .then($inner => { + const size = $inner[0].getBoundingClientRect(); + expect(size.width).to.be.greaterThan(22); + expect(size.height).to.be.greaterThan(22); + }); + }); + + it("scales checkmark icon size when font-size is set on the host", () => { + cy.mount(); + + cy.get("[ui5-checkbox]") + .shadow() + .find(".ui5-checkbox-icon") + .then($icon => { + const size = $icon[0].getBoundingClientRect(); + expect(size.width).to.be.greaterThan(16); + expect(size.height).to.be.greaterThan(16); + }); + }); + + it("scales display-only icon size when font-size is set on the host", () => { + cy.mount(); + + cy.get("[ui5-checkbox]") + .shadow() + .find(".ui5-checkbox-display-only-icon-inner") + .then($inner => { + const size = $inner[0].getBoundingClientRect(); + expect(size.width).to.be.greaterThan(22); + expect(size.height).to.be.greaterThan(22); + }); + }); +}); + describe("Accessibility", () => { it("should announce the associated label when CheckBox is focused", () => { cy.mount(