@gjsify/adwaita-web 0.55.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/adwaita-web.css +137 -29
- package/dist/adwaita-web.css.map +1 -1
- package/lib/types/adw-status-page.spec.d.ts +1 -0
- package/lib/types/application.d.ts +24 -0
- package/lib/types/application.spec.d.ts +1 -0
- package/lib/types/attributes.d.ts +19 -0
- package/lib/types/elements/adw-action-row.d.ts +4 -0
- package/lib/types/elements/adw-application-window.d.ts +2 -0
- package/lib/types/elements/adw-combo-row.d.ts +4 -0
- package/lib/types/elements/adw-entry-row.d.ts +6 -0
- package/lib/types/elements/adw-expander-row.d.ts +2 -0
- package/lib/types/elements/adw-header-bar.d.ts +6 -0
- package/lib/types/elements/adw-overlay-split-view.d.ts +13 -0
- package/lib/types/elements/adw-sidebar.d.ts +3 -2
- package/lib/types/elements/adw-spin-row.d.ts +6 -0
- package/lib/types/elements/adw-switch-row.d.ts +4 -0
- package/lib/types/elements/adw-toggle-group.d.ts +17 -0
- package/lib/types/elements/adw-view-stack.d.ts +3 -0
- package/lib/types/elements/checks.d.ts +6 -0
- package/lib/types/elements/gtk-application-window.d.ts +2 -0
- package/lib/types/elements/gtk-drop-down.d.ts +3 -0
- package/lib/types/elements/gtk-entry.d.ts +10 -0
- package/lib/types/elements/gtk-menu-button.d.ts +2 -0
- package/lib/types/elements/gtk-scrolled-window.d.ts +26 -2
- package/lib/types/elements/gtk-stack.d.ts +3 -0
- package/lib/types/elements/gtk-switch.d.ts +3 -0
- package/lib/types/elements/gtk-window.d.ts +8 -2
- package/lib/types/glib.spec.d.ts +1 -0
- package/lib/types/gobject-door.d.ts +4 -0
- package/lib/types/gobject-door.spec.d.ts +1 -0
- package/lib/types/gobject-elements.d.ts +17 -0
- package/lib/types/gtksource/gtk-source-view.d.ts +77 -0
- package/lib/types/gtksource/gtk-source-view.spec.d.ts +2 -0
- package/lib/types/gtksource/web-editor-driver.d.ts +44 -0
- package/lib/types/index.d.ts +4 -1
- package/lib/types/menu-actions.spec.d.ts +1 -0
- package/lib/types/namespace/adw.d.ts +1 -0
- package/lib/types/namespace/gio.d.ts +2 -0
- package/lib/types/namespace/glib.d.ts +10 -0
- package/lib/types/namespace/gobject.d.ts +27 -0
- package/lib/types/namespace/gtk-enums.d.ts +22 -0
- package/lib/types/namespace/gtk.d.ts +2 -0
- package/lib/types/namespace/gtksource.d.ts +2 -0
- package/lib/types/row-line-clamp.d.ts +20 -0
- package/lib/types/row-tooltip.d.ts +8 -0
- package/lib/types/row-tooltip.spec.d.ts +1 -0
- package/lib/types/shared-tree-builder.d.ts +69 -20
- package/lib/types/shared-tree-mount.spec.d.ts +1 -0
- package/lib/types/styles.generated.d.ts +1 -1
- package/lib/types/widget-size.spec.d.ts +1 -0
- package/package.json +11 -9
- package/scss/_action_row.scss +39 -15
- package/scss/_button_row.scss +5 -0
- package/scss/_expander_row.scss +36 -3
- package/scss/_headerbar.scss +2 -1
- package/scss/_preferences_row.scss +9 -0
- package/scss/_reset.scss +1 -1
- package/scss/_row.scss +16 -0
- package/scss/_status_page.scss +1 -1
- package/scss/_toggle_group.scss +28 -0
- package/scss/_widget.scss +14 -3
- package/scss/_window.scss +13 -1
- package/src/adw-action-rows.spec.ts +255 -0
- package/src/adw-header-bar.spec.ts +18 -0
- package/src/adw-status-page.spec.ts +124 -0
- package/src/application.spec.ts +75 -0
- package/src/application.ts +92 -0
- package/src/attributes.ts +52 -0
- package/src/capabilities.mjs +3 -0
- package/src/construct-vectors.spec.ts +156 -1
- package/src/elements/adw-action-row.ts +31 -2
- package/src/elements/adw-alert-dialog.ts +4 -1
- package/src/elements/adw-application-window.ts +5 -0
- package/src/elements/adw-button-row.ts +7 -1
- package/src/elements/adw-combo-row.ts +26 -1
- package/src/elements/adw-entry-row.ts +22 -12
- package/src/elements/adw-expander-row.ts +34 -1
- package/src/elements/adw-header-bar.ts +18 -4
- package/src/elements/adw-overlay-split-view.ts +29 -6
- package/src/elements/adw-preferences-row.ts +5 -2
- package/src/elements/adw-sidebar.ts +33 -5
- package/src/elements/adw-spin-row.ts +37 -2
- package/src/elements/adw-split-button.ts +5 -1
- package/src/elements/adw-status-page.ts +10 -2
- package/src/elements/adw-switch-row.ts +25 -1
- package/src/elements/adw-toggle-group.ts +119 -10
- package/src/elements/adw-view-stack.ts +14 -0
- package/src/elements/adw-window.ts +9 -4
- package/src/elements/checks.ts +25 -1
- package/src/elements/gtk-application-window.ts +5 -0
- package/src/elements/gtk-drop-down.ts +16 -0
- package/src/elements/gtk-entry.ts +45 -7
- package/src/elements/gtk-menu-button.ts +12 -1
- package/src/elements/gtk-popover-menu.ts +7 -2
- package/src/elements/gtk-scrolled-window.ts +76 -7
- package/src/elements/gtk-stack.ts +8 -0
- package/src/elements/gtk-switch.ts +8 -0
- package/src/elements/gtk-window.ts +9 -3
- package/src/glib.spec.ts +34 -0
- package/src/gobject-door.spec.ts +119 -0
- package/src/gobject-door.ts +137 -0
- package/src/gobject-elements.ts +172 -0
- package/src/gtk-window.spec.ts +12 -0
- package/src/gtksource/gtk-source-view.spec.ts +69 -0
- package/src/gtksource/gtk-source-view.ts +379 -0
- package/src/gtksource/web-editor-driver.ts +260 -0
- package/src/index.ts +11 -1
- package/src/keyboard-operable.spec.ts +47 -11
- package/src/menu-actions.spec.ts +47 -0
- package/src/namespace/adw.ts +1 -0
- package/src/namespace/gio.ts +2 -0
- package/src/namespace/glib.ts +22 -0
- package/src/namespace/gobject.ts +37 -0
- package/src/namespace/gtk-enums.ts +15 -0
- package/src/namespace/gtk.ts +2 -0
- package/src/namespace/gtksource.ts +9 -0
- package/src/row-line-clamp.ts +74 -0
- package/src/row-tooltip.spec.ts +313 -0
- package/src/row-tooltip.ts +52 -0
- package/src/shared-tree-builder.ts +230 -42
- package/src/shared-tree-mount.spec.ts +130 -0
- package/src/shared-trees.spec.ts +15 -0
- package/src/split-button.spec.ts +2 -0
- package/src/styles.generated.ts +1 -1
- package/src/test.browser.mts +18 -0
- package/src/widget-size.spec.ts +117 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const AdwWidgetSizeTest: () => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/adwaita-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.57.0",
|
|
4
4
|
"description": "Adwaita/Libadwaita web components for browser targets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
],
|
|
39
39
|
"scripts": {
|
|
40
40
|
"clear": "gjsify clear lib dist tsconfig.tsbuildinfo scss/_icons.generated.scss src/styles.generated.ts",
|
|
41
|
-
"check": "gjsify run build:scss && gjsify tsc --noEmit",
|
|
41
|
+
"check": "gjsify run build:scss && gjsify tsc --noEmit && gjsify run check:consumer",
|
|
42
|
+
"check:consumer": "gjsify tsc -p tsconfig.consumer.json",
|
|
42
43
|
"build": "gjsify run build:scss && gjsify run build:types",
|
|
43
44
|
"build:scss": "node scripts/build-scss.mjs",
|
|
44
45
|
"build:types": "gjsify tsc",
|
|
@@ -49,16 +50,17 @@
|
|
|
49
50
|
"@codemirror/language": "^6.12.4",
|
|
50
51
|
"@codemirror/state": "^6.7.0",
|
|
51
52
|
"@codemirror/view": "^6.43.4",
|
|
52
|
-
"@gjsify/adwaita-core": "^0.
|
|
53
|
-
"@gjsify/adwaita-fonts": "^0.
|
|
54
|
-
"@gjsify/adwaita-icons": "^0.
|
|
53
|
+
"@gjsify/adwaita-core": "^0.57.0",
|
|
54
|
+
"@gjsify/adwaita-fonts": "^0.57.0",
|
|
55
|
+
"@gjsify/adwaita-icons": "^0.57.0",
|
|
56
|
+
"@gjsify/gtksource-core": "^0.57.0",
|
|
55
57
|
"@lezer/highlight": "^1.2.3"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
58
|
-
"@gjsify/blueprint": "^0.
|
|
59
|
-
"@gjsify/cli": "^0.
|
|
60
|
-
"@gjsify/unit": "^0.
|
|
61
|
-
"@gjsify/vite-plugin-blueprint": "^0.
|
|
60
|
+
"@gjsify/blueprint": "^0.57.0",
|
|
61
|
+
"@gjsify/cli": "^0.57.0",
|
|
62
|
+
"@gjsify/unit": "^0.57.0",
|
|
63
|
+
"@gjsify/vite-plugin-blueprint": "^0.57.0",
|
|
62
64
|
"sass": "^1.101.0",
|
|
63
65
|
"typescript": "^6.0.3"
|
|
64
66
|
},
|
package/scss/_action_row.scss
CHANGED
|
@@ -5,7 +5,14 @@
|
|
|
5
5
|
// Copyright (c) 2025 csm (adwaita-web). MIT License.
|
|
6
6
|
// Modifications: Adapted for @gjsify/adwaita-web Web Components.
|
|
7
7
|
|
|
8
|
-
adw-action-row
|
|
8
|
+
adw-action-row,
|
|
9
|
+
adw-switch-row,
|
|
10
|
+
adw-combo-row,
|
|
11
|
+
adw-spin-row {
|
|
12
|
+
// These row types inherit from AdwActionRow upstream and have
|
|
13
|
+
// title-lines/subtitle-lines properties. Match libadwaita: wrap by default
|
|
14
|
+
// (GtkLabel with wrap=true, lines=0), clamp via CSS custom property when
|
|
15
|
+
// title-lines/subtitle-lines > 0. See adw-action-row.ui lines 54-61, 70-81.
|
|
9
16
|
display: flex;
|
|
10
17
|
align-items: center;
|
|
11
18
|
gap: var(--spacing-m);
|
|
@@ -31,36 +38,53 @@ adw-action-row {
|
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
.adw-action-row-prefix,
|
|
34
|
-
.adw-action-row-suffix
|
|
41
|
+
.adw-action-row-suffix,
|
|
42
|
+
.adw-switch-row-prefix {
|
|
35
43
|
display: flex;
|
|
36
44
|
align-items: center;
|
|
37
45
|
gap: var(--spacing-xs);
|
|
38
46
|
flex-shrink: 0;
|
|
39
47
|
}
|
|
40
48
|
|
|
41
|
-
.adw-
|
|
42
|
-
|
|
43
|
-
flex-direction: column;
|
|
44
|
-
justify-content: center;
|
|
45
|
-
flex: 1 1 auto;
|
|
46
|
-
min-width: 0;
|
|
47
|
-
}
|
|
49
|
+
// The text column's own rule is `_row.scss`'s shared `.adw-row-text` — one spelling
|
|
50
|
+
// for all five rows, so the clamp selectors below can name it too.
|
|
48
51
|
|
|
52
|
+
// Title/subtitle WRAP BY DEFAULT, matching libadwaita's GtkLabel wrap=true,
|
|
53
|
+
// lines=0. The typography is this row type's own (it was here before the wrap); only
|
|
54
|
+
// `white-space` moves, and `overflow`/`text-overflow` are left to the clamped state
|
|
55
|
+
// below, where the ellipsis has a line count to truncate to.
|
|
49
56
|
.adw-row-title {
|
|
50
57
|
font-size: var(--font-size-base);
|
|
51
58
|
color: var(--card-fg-color);
|
|
52
|
-
white-space:
|
|
53
|
-
overflow:
|
|
54
|
-
text-overflow: ellipsis;
|
|
59
|
+
white-space: normal;
|
|
60
|
+
overflow-wrap: break-word;
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
.adw-row-subtitle {
|
|
58
64
|
font-size: var(--font-size-small);
|
|
59
65
|
opacity: var(--dim-opacity);
|
|
60
66
|
color: var(--card-fg-color);
|
|
61
|
-
white-space:
|
|
62
|
-
overflow:
|
|
63
|
-
|
|
67
|
+
white-space: normal;
|
|
68
|
+
overflow-wrap: break-word;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Clamped state — enabled by JS toggling .adw-row-clamp on the text container.
|
|
72
|
+
.adw-row-text.adw-row-clamp {
|
|
73
|
+
.adw-row-title,
|
|
74
|
+
.adw-row-subtitle {
|
|
75
|
+
display: -webkit-box;
|
|
76
|
+
-webkit-box-orient: vertical;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
text-overflow: var(--adw-row-ellipsize-overflow, ellipsis);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.adw-row-title {
|
|
82
|
+
-webkit-line-clamp: var(--adw-row-title-lines, 1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.adw-row-subtitle {
|
|
86
|
+
-webkit-line-clamp: var(--adw-row-subtitle-lines, 1);
|
|
87
|
+
}
|
|
64
88
|
}
|
|
65
89
|
}
|
|
66
90
|
|
package/scss/_button_row.scss
CHANGED
|
@@ -34,6 +34,11 @@ adw-button-row {
|
|
|
34
34
|
justify-content: center;
|
|
35
35
|
gap: var(--spacing-xs);
|
|
36
36
|
min-width: 0;
|
|
37
|
+
// The row centres its one button (`justify-content: center` above), so without this the
|
|
38
|
+
// contents box is exactly as wide as the button and `tooltip-text` reaches only that
|
|
39
|
+
// much of the row. Growing it and letting its own `justify-content: centre` do the
|
|
40
|
+
// centring draws the same button in the same place.
|
|
41
|
+
flex: 1 1 auto;
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
.adw-button-row-title {
|
package/scss/_expander_row.scss
CHANGED
|
@@ -32,12 +32,45 @@ adw-expander-row {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
// Title/subtitle WRAP BY DEFAULT, matching libadwaita's GtkLabel wrap=true,
|
|
36
|
+
// lines=0 — stated HERE, at this row's own specificity, because `_row.scss` carries
|
|
37
|
+
// a `white-space: nowrap` default for `.adw-row-subtitle` and an inherited one reaches
|
|
38
|
+
// the title. A rule that only turns `white-space` on inside the clamp selector cannot
|
|
39
|
+
// make a row wrap by DEFAULT: the clamp is the minority state.
|
|
35
40
|
.adw-row-title {
|
|
36
41
|
font-size: var(--font-size-base);
|
|
37
42
|
color: var(--card-fg-color);
|
|
38
|
-
white-space:
|
|
39
|
-
overflow:
|
|
40
|
-
|
|
43
|
+
white-space: normal;
|
|
44
|
+
overflow-wrap: break-word;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.adw-row-subtitle {
|
|
48
|
+
font-size: var(--font-size-small);
|
|
49
|
+
opacity: var(--dim-opacity);
|
|
50
|
+
color: var(--card-fg-color);
|
|
51
|
+
white-space: normal;
|
|
52
|
+
overflow-wrap: break-word;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Clamped state — JS toggles `.adw-row-clamp` on the TEXT COLUMN, the same node and
|
|
56
|
+
// the same class `_action_row.scss` keys off; reading it off the header instead never
|
|
57
|
+
// matched anything.
|
|
58
|
+
.adw-row-text.adw-row-clamp {
|
|
59
|
+
.adw-row-title,
|
|
60
|
+
.adw-row-subtitle {
|
|
61
|
+
display: -webkit-box;
|
|
62
|
+
-webkit-box-orient: vertical;
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
text-overflow: var(--adw-row-ellipsize-overflow, ellipsis);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.adw-row-title {
|
|
68
|
+
-webkit-line-clamp: var(--adw-row-title-lines, 1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.adw-row-subtitle {
|
|
72
|
+
-webkit-line-clamp: var(--adw-row-subtitle-lines, 1);
|
|
73
|
+
}
|
|
41
74
|
}
|
|
42
75
|
|
|
43
76
|
// The text column takes the free space so prefix/suffix widgets, the enable
|
package/scss/_headerbar.scss
CHANGED
|
@@ -119,7 +119,8 @@ adw-header-bar {
|
|
|
119
119
|
// would paint over them. Washing the stripes out with the bar's own opaque
|
|
120
120
|
// background colour renders identically and leaves the content alone.
|
|
121
121
|
.devel adw-header-bar,
|
|
122
|
-
adw-window.devel adw-header-bar
|
|
122
|
+
adw-window.devel adw-header-bar,
|
|
123
|
+
adw-application-window.devel adw-header-bar {
|
|
123
124
|
background-image:
|
|
124
125
|
linear-gradient(to bottom, transparent 0%, var(--headerbar-bg-color) 100%),
|
|
125
126
|
repeating-linear-gradient(
|
|
@@ -32,6 +32,15 @@ adw-preferences-row {
|
|
|
32
32
|
// stylesheet that resets selection.
|
|
33
33
|
.adw-row-title {
|
|
34
34
|
user-select: none;
|
|
35
|
+
|
|
36
|
+
// A row with NO content section has a `hidden` one, and `[hidden]` is
|
|
37
|
+
// `display: none !important` — so the row's free space belongs to no part at all and
|
|
38
|
+
// `tooltip-text`, which rides a part (`src/row-tooltip.ts`), reaches only the label's
|
|
39
|
+
// own width. Taking that space moves it into a box that draws nothing: the label is
|
|
40
|
+
// start-aligned and the content's items are `flex-end`, so nothing on screen moves.
|
|
41
|
+
&:has(~ .adw-preferences-row-content[hidden]) {
|
|
42
|
+
flex: 1 1 auto;
|
|
43
|
+
}
|
|
35
44
|
}
|
|
36
45
|
|
|
37
46
|
// The slot the `child` property lands in: the preference's own controls, which sit
|
package/scss/_reset.scss
CHANGED
|
@@ -47,7 +47,7 @@ $adw-components:
|
|
|
47
47
|
gtk-gl-area, gtk-graphics-offload, gtk-grid, gtk-grid-view, gtk-header-bar, gtk-image, gtk-inscription, gtk-label, gtk-level-bar,
|
|
48
48
|
gtk-link-button, gtk-list-box, gtk-list-box-row, gtk-list-view, gtk-media-controls, gtk-menu-button, gtk-overlay, gtk-page-setup-unix-dialog, gtk-paned,
|
|
49
49
|
gtk-password-entry, gtk-picture, gtk-popover, gtk-popover-bin, gtk-popover-menu, gtk-popover-menu-bar, gtk-print-unix-dialog,
|
|
50
|
-
gtk-progress-bar, gtk-revealer, gtk-scale, gtk-scale-button, gtk-scrollbar, gtk-scrolled-window, gtk-search-bar, gtk-search-entry, gtk-separator,
|
|
50
|
+
gtk-progress-bar, gtk-revealer, gtk-scale, gtk-scale-button, gtk-scrollbar, gtk-scrolled-window, gtk-search-bar, gtk-search-entry, gtk-separator, gtk-source-view,
|
|
51
51
|
gtk-spin-button, gtk-spinner, gtk-stack, gtk-stack-sidebar, gtk-stack-switcher, gtk-switch, gtk-text, gtk-text-view, gtk-toggle-button, gtk-tree-expander, gtk-video, gtk-viewport,
|
|
52
52
|
gtk-window, gtk-window-controls, gtk-window-handle;
|
|
53
53
|
|
package/scss/_row.scss
CHANGED
|
@@ -20,6 +20,16 @@ adw-combo-row {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
// A `tooltip-text` part must cover the ROW, not just the label text inside it: the browser
|
|
24
|
+
// resolves a tooltip by walking UP from the hovered node, so a part that stops at the text's
|
|
25
|
+
// own height lets the walk reach the host — whose `title` is the row's LABEL — over the rest
|
|
26
|
+
// of the widget. Measured on a 54px `adw-action-row`: the label text is 18px of it. The
|
|
27
|
+
// marker is `applyRowTooltip`'s (`src/row-tooltip.ts`); stretching changes nothing drawn,
|
|
28
|
+
// because these columns centre their own children.
|
|
29
|
+
[data-row-tooltip] {
|
|
30
|
+
align-self: stretch;
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
// Shared title/subtitle text column used by every row type (action/switch/
|
|
24
34
|
// combo/spin). The title is the primary label; the subtitle is dimmed and
|
|
25
35
|
// hidden when empty.
|
|
@@ -31,6 +41,12 @@ adw-combo-row {
|
|
|
31
41
|
min-width: 0;
|
|
32
42
|
}
|
|
33
43
|
|
|
44
|
+
// NO `.adw-row-title` default HERE, deliberately. `.adw-row-title` is also the class
|
|
45
|
+
// `<adw-entry-row>` and `<adw-preferences-row>` put on their titles, so a global
|
|
46
|
+
// `white-space: nowrap` here silently made those two rows un-wrapping too — a change
|
|
47
|
+
// to row types this feature was never scoped to. Each row type that wants a wrapping
|
|
48
|
+
// title says so in its own partial at its own specificity (see `_action_row.scss`,
|
|
49
|
+
// `_expander_row.scss`); a global default can only ever be the losing side of that.
|
|
34
50
|
.adw-row-subtitle {
|
|
35
51
|
font-size: var(--font-size-small);
|
|
36
52
|
opacity: var(--dim-opacity);
|
package/scss/_status_page.scss
CHANGED
|
@@ -53,7 +53,7 @@ adw-status-page {
|
|
|
53
53
|
|
|
54
54
|
// `.compact` — the documented smaller status page, for a sidebar or a popover
|
|
55
55
|
// (style-classes.md "Compact Status Page"): margins 24px 12px, the icon 96px with 12px
|
|
56
|
-
// under it, `.title-2`, and
|
|
56
|
+
// under it, `.title-2`, and 12px to the child (`_misc.scss`, statuspage.compact).
|
|
57
57
|
&.compact {
|
|
58
58
|
padding: 24px 12px;
|
|
59
59
|
|
package/scss/_toggle_group.scss
CHANGED
|
@@ -24,6 +24,13 @@ adw-toggle-group {
|
|
|
24
24
|
border-radius: var(--button-radius);
|
|
25
25
|
background-color: var(--button-bg-color);
|
|
26
26
|
|
|
27
|
+
// `toggle-group:disabled` (libadwaita `_toggle-group.scss:16`) — the whole group's
|
|
28
|
+
// background mixed toward transparent. Written against `[disabled]` and not `:disabled`:
|
|
29
|
+
// a custom element is never `:disabled`, the way `_expander.scss` records.
|
|
30
|
+
&[disabled] {
|
|
31
|
+
background-color: color-mix(in srgb, var(--button-bg-color) var(--disabled-opacity), transparent);
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
.adw-toggle-group-inner {
|
|
28
35
|
display: flex;
|
|
29
36
|
align-items: stretch;
|
|
@@ -70,6 +77,20 @@ adw-toggle-group {
|
|
|
70
77
|
outline-offset: 1px;
|
|
71
78
|
}
|
|
72
79
|
|
|
80
|
+
// A `<button disabled>` carries GTK's `:disabled` dimming — `_buttons.scss:58`,
|
|
81
|
+
// `filter: Opacity(var(--disabled-opacity))` — and `cursor: default` with it
|
|
82
|
+
// (`_button.scss`). Hover and active are suppressed because a disabled button takes
|
|
83
|
+
// neither, so the hover fill would linger over a toggle that cannot be pressed.
|
|
84
|
+
&:disabled {
|
|
85
|
+
opacity: var(--disabled-opacity);
|
|
86
|
+
cursor: default;
|
|
87
|
+
|
|
88
|
+
&:hover,
|
|
89
|
+
&:active {
|
|
90
|
+
background-color: transparent;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
73
94
|
// The active toggle — a raised white chip, the way libadwaita draws it.
|
|
74
95
|
&.active {
|
|
75
96
|
background-color: var(--active-toggle-bg-color);
|
|
@@ -81,6 +102,13 @@ adw-toggle-group {
|
|
|
81
102
|
&:hover {
|
|
82
103
|
background-color: var(--active-toggle-bg-color);
|
|
83
104
|
}
|
|
105
|
+
|
|
106
|
+
// The raised chip is what makes it read as raised; libadwaita drops the shadow on a
|
|
107
|
+
// disabled active toggle (`_toggle-group.scss:131`) so an unavailable choice does not
|
|
108
|
+
// look pressed.
|
|
109
|
+
&:disabled {
|
|
110
|
+
box-shadow: none;
|
|
111
|
+
}
|
|
84
112
|
}
|
|
85
113
|
}
|
|
86
114
|
|
package/scss/_widget.scss
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
// projected `.blp` hands them to `buildSharedTree` as attributes (`halign="center"`). Until
|
|
5
5
|
// this partial nothing read them, so the gallery's bottom sheet stretched the button its
|
|
6
6
|
// Blueprint centres. The margins are not here: an attribute cannot carry a length into CSS
|
|
7
|
-
// portably, so `shared-tree-builder.ts` writes them as inline style
|
|
7
|
+
// portably, so `shared-tree-builder.ts` writes them as inline style — and so are
|
|
8
|
+
// `width-request` / `height-request`, as the `min-width` / `min-height` they are.
|
|
8
9
|
//
|
|
9
10
|
// ALIGNMENT IS AN AUTO MARGIN, because that is the one CSS placement that means the same on
|
|
10
11
|
// both axes of a flex container and of a grid: GTK allocates a non-FILL child its natural
|
|
@@ -49,7 +50,17 @@
|
|
|
49
50
|
margin-block: auto;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
gtk-box:not([orientation='vertical']) > [hexpand],
|
|
53
|
-
gtk-box[orientation='vertical'] > [vexpand] {
|
|
53
|
+
gtk-box:not([orientation='vertical']) > [hexpand]:not([hexpand='false']),
|
|
54
|
+
gtk-box[orientation='vertical'] > [vexpand]:not([vexpand='false']) {
|
|
54
55
|
flex-grow: 1;
|
|
55
56
|
}
|
|
57
|
+
|
|
58
|
+
// An AUTHORED `hexpand: false` is the one case where absence is not enough: a widget that
|
|
59
|
+
// grows by default (`<gtk-scrolled-window>` is `flex: 1 1 0%`, the allocation of a window in a
|
|
60
|
+
// column) must stop, and GTK then gives it its NATURAL size rather than nothing — hence the
|
|
61
|
+
// `auto` basis, not just a zero grow. `width-request` (an inline `min-width`) is the floor.
|
|
62
|
+
gtk-box:not([orientation='vertical']) > [hexpand='false'],
|
|
63
|
+
gtk-box[orientation='vertical'] > [vexpand='false'] {
|
|
64
|
+
flex-grow: 0;
|
|
65
|
+
flex-basis: auto;
|
|
66
|
+
}
|
package/scss/_window.scss
CHANGED
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
// Copyright (c) 2025 csm (adwaita-web). MIT License.
|
|
7
7
|
// Modifications: Adapted for @gjsify/adwaita-web Web Components.
|
|
8
8
|
|
|
9
|
-
adw-window
|
|
9
|
+
// `adw-application-window` is `adw-window` plus a menubar (it extends the class and adds nothing
|
|
10
|
+
// else), so it is the same frame: without this an application window was an inline box with no
|
|
11
|
+
// size at all, and a tree rooted at one measured 0 x 0.
|
|
12
|
+
adw-window,
|
|
13
|
+
adw-application-window {
|
|
10
14
|
display: flex;
|
|
11
15
|
flex-direction: column;
|
|
12
16
|
background-color: var(--window-bg-color);
|
|
@@ -43,6 +47,14 @@ adw-window {
|
|
|
43
47
|
min-width: 0;
|
|
44
48
|
}
|
|
45
49
|
|
|
50
|
+
// A window hands its one child the WHOLE allocation, whatever that child's own expand flags say.
|
|
51
|
+
// On the web a box is only as tall as what it holds, so the `Gtk.Box` a `.blp` roots its content
|
|
52
|
+
// in stopped at its header bar and the split view below it drew a quarter of the window.
|
|
53
|
+
.adw-window-content > gtk-box {
|
|
54
|
+
flex: 1 1 auto;
|
|
55
|
+
min-height: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
// <gtk-window> — the GTK frame, in the SAME file upstream styles `Adw.Window` in: libadwaita
|
|
47
59
|
// keys `window { &.csd { … } }` off the GtkWindow CSS node
|
|
48
60
|
// (refs/libadwaita/src/stylesheet/widgets/_window.scss:1-31), and this element IS a window
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
// - libadwaita has no activatable opt-out for a button row, and
|
|
14
14
|
// `<adw-action-row activatable="false">` reads by PRESENCE, so it means the
|
|
15
15
|
// opposite of what it says.
|
|
16
|
+
// - the row `title-lines`/`subtitle-lines` clamp is observed as RENDERED GEOMETRY, not
|
|
17
|
+
// as computed style (see `renderedLineCount`).
|
|
16
18
|
import { describe, expect, it } from '@gjsify/unit';
|
|
17
19
|
|
|
18
20
|
import {
|
|
@@ -30,6 +32,9 @@ import { isIconAvailable } from './icon-registry.js';
|
|
|
30
32
|
import { fallbackMask, maskOf } from './icon-registry.spec.js';
|
|
31
33
|
|
|
32
34
|
import type { AdwActionRow } from './elements/adw-action-row.js';
|
|
35
|
+
import type { AdwComboRow } from './elements/adw-combo-row.js';
|
|
36
|
+
import type { AdwExpanderRow } from './elements/adw-expander-row.js';
|
|
37
|
+
import type { AdwSpinRow } from './elements/adw-spin-row.js';
|
|
33
38
|
import type { AdwSwitchRow } from './elements/adw-switch-row.js';
|
|
34
39
|
import type { AdwWindowTitle } from './elements/adw-window-title.js';
|
|
35
40
|
|
|
@@ -196,6 +201,134 @@ export const AdwActionRowsTest = async () => {
|
|
|
196
201
|
});
|
|
197
202
|
});
|
|
198
203
|
|
|
204
|
+
/**
|
|
205
|
+
* The number of lines a row title/subtitle element actually RENDERS, measured from its
|
|
206
|
+
* height divided by one line box's height.
|
|
207
|
+
*
|
|
208
|
+
* NOT the number of rects a `Range` over the element reports. Firefox reports a rect per
|
|
209
|
+
* laid-out line box and `-webkit-line-clamp` truncates the BOX without re-laying out the
|
|
210
|
+
* text, so a label clamped to one line still lists every line it would have taken:
|
|
211
|
+
* measured on a real `adw-switch-row`, `title-lines=1` gave 5 rects for a box that
|
|
212
|
+
* collapsed from 90px to 18px, and an isolated `display:-webkit-box;
|
|
213
|
+
* -webkit-line-clamp:1` probe gave 3 rects / 22px against 3 rects / 66px unclamped —
|
|
214
|
+
* identical rect counts, opposite line counts. Only the HEIGHT moves, so only the height
|
|
215
|
+
* can carry the claim; the rect count was never a line count and no `-webkit-line-clamp`
|
|
216
|
+
* implementation can satisfy `expect(rects.length).toBe(1)`.
|
|
217
|
+
*
|
|
218
|
+
* The step is the FIRST line box, not the computed `line-height`: the stylesheet sets no
|
|
219
|
+
* line-height on these labels, so `getComputedStyle().lineHeight` reads `normal` — which
|
|
220
|
+
* computes to no number at all.
|
|
221
|
+
*/
|
|
222
|
+
function renderedLineCount(el: HTMLElement): number {
|
|
223
|
+
const range = document.createRange();
|
|
224
|
+
range.selectNodeContents(el);
|
|
225
|
+
const rects = range.getClientRects();
|
|
226
|
+
const lineBox = rects.length > 0 ? rects[0]!.height : 0;
|
|
227
|
+
if (!(lineBox > 0)) return Number.NaN;
|
|
228
|
+
return Math.round(el.getBoundingClientRect().height / lineBox);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Default (0 = unlimited, the AdwActionRow pspec's sentinel): wraps freely.
|
|
232
|
+
await describe('<adw-action-row> title-lines / subtitle-lines (libadwaita conformance)', async () => {
|
|
233
|
+
await it('title-lines=0 (default) wraps to multiple lines in narrow container', () => {
|
|
234
|
+
const { el, host } = mount<AdwActionRow>('adw-action-row');
|
|
235
|
+
el.setAttribute(
|
|
236
|
+
'title',
|
|
237
|
+
'A very long title that should wrap across multiple lines when the container is narrow',
|
|
238
|
+
);
|
|
239
|
+
host.style.width = '200px';
|
|
240
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
241
|
+
expect(lines).toBeGreaterThan(1);
|
|
242
|
+
host.remove();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
await it('subtitle-lines=0 (default) wraps to multiple lines in narrow container', () => {
|
|
246
|
+
const { el, host } = mount<AdwActionRow>('adw-action-row');
|
|
247
|
+
el.setAttribute(
|
|
248
|
+
'subtitle',
|
|
249
|
+
'A very long subtitle that should wrap across multiple lines when the container is narrow',
|
|
250
|
+
);
|
|
251
|
+
host.style.width = '200px';
|
|
252
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-subtitle')!);
|
|
253
|
+
expect(lines).toBeGreaterThan(1);
|
|
254
|
+
host.remove();
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// title-lines > 0: clamps to N lines
|
|
258
|
+
await it('title-lines=1 clamps to exactly 1 line', () => {
|
|
259
|
+
const { el, host } = mount<AdwActionRow>('adw-action-row');
|
|
260
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
261
|
+
el.setAttribute('title-lines', '1');
|
|
262
|
+
host.style.width = '150px';
|
|
263
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
264
|
+
expect(lines).toBe(1);
|
|
265
|
+
host.remove();
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
await it('subtitle-lines=2 clamps to exactly 2 lines', () => {
|
|
269
|
+
const { el, host } = mount<AdwActionRow>('adw-action-row');
|
|
270
|
+
el.setAttribute('subtitle', 'Subtitle that is long enough to wrap into three lines if allowed');
|
|
271
|
+
el.setAttribute('subtitle-lines', '2');
|
|
272
|
+
host.style.width = '150px';
|
|
273
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-subtitle')!);
|
|
274
|
+
expect(lines).toBe(2);
|
|
275
|
+
host.remove();
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Dynamic attribute change
|
|
279
|
+
await it('changing title-lines from 0 to 1 applies clamping visually', () => {
|
|
280
|
+
const { el, host } = mount<AdwActionRow>('adw-action-row');
|
|
281
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
282
|
+
el.setAttribute('title-lines', '0');
|
|
283
|
+
host.style.width = '150px';
|
|
284
|
+
let lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
285
|
+
expect(lines).toBeGreaterThan(1);
|
|
286
|
+
|
|
287
|
+
el.setAttribute('title-lines', '1');
|
|
288
|
+
// Force reflow
|
|
289
|
+
el.getBoundingClientRect();
|
|
290
|
+
lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
291
|
+
expect(lines).toBe(1);
|
|
292
|
+
host.remove();
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
await it('changing title-lines from 1 to 0 removes clamping visually', () => {
|
|
296
|
+
const { el, host } = mount<AdwActionRow>('adw-action-row');
|
|
297
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
298
|
+
el.setAttribute('title-lines', '1');
|
|
299
|
+
host.style.width = '150px';
|
|
300
|
+
let lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
301
|
+
expect(lines).toBe(1);
|
|
302
|
+
|
|
303
|
+
el.setAttribute('title-lines', '0');
|
|
304
|
+
el.getBoundingClientRect();
|
|
305
|
+
lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
306
|
+
expect(lines).toBeGreaterThan(1);
|
|
307
|
+
host.remove();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Invalid/non-numeric values treated as 0 (unlimited) — AdwActionRow pspec range is 0..G_MAXINT
|
|
311
|
+
await it('title-lines="invalid" treated as unlimited (wraps)', () => {
|
|
312
|
+
const { el, host } = mount<AdwActionRow>('adw-action-row');
|
|
313
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
314
|
+
el.setAttribute('title-lines', 'invalid');
|
|
315
|
+
host.style.width = '150px';
|
|
316
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
317
|
+
expect(lines).toBeGreaterThan(1);
|
|
318
|
+
host.remove();
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
await it('subtitle-lines="-1" treated as unlimited (wraps)', () => {
|
|
322
|
+
const { el, host } = mount<AdwActionRow>('adw-action-row');
|
|
323
|
+
el.setAttribute('subtitle', 'Subtitle that is long enough to wrap if allowed');
|
|
324
|
+
el.setAttribute('subtitle-lines', '-1');
|
|
325
|
+
host.style.width = '150px';
|
|
326
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-subtitle')!);
|
|
327
|
+
expect(lines).toBeGreaterThan(1);
|
|
328
|
+
host.remove();
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
199
332
|
await describe('<adw-switch-row> notify::active (libadwaita conformance vectors)', async () => {
|
|
200
333
|
for (const vector of SWITCH_ROW_NOTIFY_VECTORS) {
|
|
201
334
|
await it(`${vector.name} — ${vector.rule}`, () => {
|
|
@@ -244,6 +377,76 @@ export const AdwActionRowsTest = async () => {
|
|
|
244
377
|
host.remove();
|
|
245
378
|
});
|
|
246
379
|
}
|
|
380
|
+
|
|
381
|
+
// title-lines / subtitle-lines tests (same behavior as adw-action-row)
|
|
382
|
+
await it('title-lines=0 (default) wraps to multiple lines in narrow container', () => {
|
|
383
|
+
const { el, host } = mount<AdwSwitchRow>('adw-switch-row');
|
|
384
|
+
el.setAttribute(
|
|
385
|
+
'title',
|
|
386
|
+
'A very long title that should wrap across multiple lines when the container is narrow',
|
|
387
|
+
);
|
|
388
|
+
host.style.width = '200px';
|
|
389
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
390
|
+
expect(lines).toBeGreaterThan(1);
|
|
391
|
+
host.remove();
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
await it('subtitle-lines=0 (default) wraps to multiple lines in narrow container', () => {
|
|
395
|
+
const { el, host } = mount<AdwSwitchRow>('adw-switch-row');
|
|
396
|
+
el.setAttribute(
|
|
397
|
+
'subtitle',
|
|
398
|
+
'A very long subtitle that should wrap across multiple lines when the container is narrow',
|
|
399
|
+
);
|
|
400
|
+
host.style.width = '200px';
|
|
401
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-subtitle')!);
|
|
402
|
+
expect(lines).toBeGreaterThan(1);
|
|
403
|
+
host.remove();
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
await it('title-lines=1 clamps to exactly 1 line', () => {
|
|
407
|
+
const { el, host } = mount<AdwSwitchRow>('adw-switch-row');
|
|
408
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
409
|
+
el.setAttribute('title-lines', '1');
|
|
410
|
+
host.style.width = '150px';
|
|
411
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
412
|
+
expect(lines).toBe(1);
|
|
413
|
+
host.remove();
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
await it('subtitle-lines=2 clamps to exactly 2 lines', () => {
|
|
417
|
+
const { el, host } = mount<AdwSwitchRow>('adw-switch-row');
|
|
418
|
+
el.setAttribute('subtitle', 'Subtitle that is long enough to wrap into three lines if allowed');
|
|
419
|
+
el.setAttribute('subtitle-lines', '2');
|
|
420
|
+
host.style.width = '150px';
|
|
421
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-subtitle')!);
|
|
422
|
+
expect(lines).toBe(2);
|
|
423
|
+
host.remove();
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
await it('changing title-lines from 0 to 1 applies clamping visually', () => {
|
|
427
|
+
const { el, host } = mount<AdwSwitchRow>('adw-switch-row');
|
|
428
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
429
|
+
el.setAttribute('title-lines', '0');
|
|
430
|
+
host.style.width = '150px';
|
|
431
|
+
let lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
432
|
+
expect(lines).toBeGreaterThan(1);
|
|
433
|
+
|
|
434
|
+
el.setAttribute('title-lines', '1');
|
|
435
|
+
el.getBoundingClientRect();
|
|
436
|
+
lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
437
|
+
expect(lines).toBe(1);
|
|
438
|
+
host.remove();
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
await it('title-lines="invalid" treated as unlimited (wraps)', () => {
|
|
442
|
+
const { el, host } = mount<AdwSwitchRow>('adw-switch-row');
|
|
443
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
444
|
+
el.setAttribute('title-lines', 'invalid');
|
|
445
|
+
host.style.width = '150px';
|
|
446
|
+
const lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
447
|
+
expect(lines).toBeGreaterThan(1);
|
|
448
|
+
host.remove();
|
|
449
|
+
});
|
|
247
450
|
});
|
|
248
451
|
|
|
249
452
|
await describe('<adw-switch-row> prefix slot (inherited add_prefix)', async () => {
|
|
@@ -419,4 +622,56 @@ export const AdwActionRowsTest = async () => {
|
|
|
419
622
|
host.remove();
|
|
420
623
|
});
|
|
421
624
|
});
|
|
625
|
+
|
|
626
|
+
// Line-clamping tests for other row types that inherit title-lines/subtitle-lines
|
|
627
|
+
await describe('<adw-combo-row> title-lines / subtitle-lines', async () => {
|
|
628
|
+
await it('title-lines=0 wraps, title-lines=1 clamps to 1 line', () => {
|
|
629
|
+
const { el, host } = mount<AdwComboRow>('adw-combo-row');
|
|
630
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
631
|
+
el.setAttribute('title-lines', '0');
|
|
632
|
+
host.style.width = '150px';
|
|
633
|
+
let lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
634
|
+
expect(lines).toBeGreaterThan(1);
|
|
635
|
+
|
|
636
|
+
el.setAttribute('title-lines', '1');
|
|
637
|
+
el.getBoundingClientRect();
|
|
638
|
+
lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
639
|
+
expect(lines).toBe(1);
|
|
640
|
+
host.remove();
|
|
641
|
+
});
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
await describe('<adw-spin-row> title-lines / subtitle-lines', async () => {
|
|
645
|
+
await it('title-lines=0 wraps, title-lines=1 clamps to 1 line', () => {
|
|
646
|
+
const { el, host } = mount<AdwSpinRow>('adw-spin-row');
|
|
647
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
648
|
+
el.setAttribute('title-lines', '0');
|
|
649
|
+
host.style.width = '150px';
|
|
650
|
+
let lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
651
|
+
expect(lines).toBeGreaterThan(1);
|
|
652
|
+
|
|
653
|
+
el.setAttribute('title-lines', '1');
|
|
654
|
+
el.getBoundingClientRect();
|
|
655
|
+
lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
656
|
+
expect(lines).toBe(1);
|
|
657
|
+
host.remove();
|
|
658
|
+
});
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
await describe('<adw-expander-row> title-lines / subtitle-lines', async () => {
|
|
662
|
+
await it('title-lines=0 wraps, title-lines=1 clamps to 1 line', () => {
|
|
663
|
+
const { el, host } = mount<AdwExpanderRow>('adw-expander-row');
|
|
664
|
+
el.setAttribute('title', 'Title that is long enough to wrap if allowed');
|
|
665
|
+
el.setAttribute('title-lines', '0');
|
|
666
|
+
host.style.width = '150px';
|
|
667
|
+
let lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
668
|
+
expect(lines).toBeGreaterThan(1);
|
|
669
|
+
|
|
670
|
+
el.setAttribute('title-lines', '1');
|
|
671
|
+
el.getBoundingClientRect();
|
|
672
|
+
lines = renderedLineCount(el.querySelector('.adw-row-title')!);
|
|
673
|
+
expect(lines).toBe(1);
|
|
674
|
+
host.remove();
|
|
675
|
+
});
|
|
676
|
+
});
|
|
422
677
|
};
|