Skip to content

Commit 33beba4

Browse files
asynclizcopybara-github
authored andcommitted
feat(labs): add expressive menu utility class component
PiperOrigin-RevId: 901039036
1 parent f6c1871 commit 33beba4

19 files changed

Lines changed: 1989 additions & 24 deletions

labs/gb/components/checkbox/checkbox.scss

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,27 @@
6464
height: 48px;
6565
background-image: none;
6666
outline: none;
67+
margin: 0;
68+
--icon: 'check';
69+
70+
&:is(:indeterminate, .indeterminate)::before {
71+
--icon: 'remove';
72+
}
6773

6874
&::before {
69-
content: '';
75+
content: var(--icon);
76+
display: inline-flex;
77+
align-items: center;
78+
justify-content: center;
7079
box-sizing: border-box;
80+
overflow: hidden;
81+
aspect-ratio: 1;
7182
width: var(--container-size);
72-
height: var(--container-size);
7383
background: var(--container-color);
7484
border-radius: var(--container-shape);
7585
border: var(--outline-width) solid var(--outline-color);
7686
color: var(--icon-color);
77-
font-family: var(--md-icon-font);
78-
font-size: var(--icon-size);
79-
line-height: 1;
87+
font: var(--icon-size) / 1 var(--md-icon-font);
8088
}
8189

8290
&::after {
@@ -92,14 +100,6 @@
92100
transition: var(--ripple-transition);
93101
animation: var(--ripple-animation), var(--focus-ring-animation);
94102
}
95-
96-
&:is(:checked, .checked)::before {
97-
content: 'check';
98-
}
99-
100-
&:is(:indeterminate, .indeterminate)::before {
101-
content: 'remove';
102-
}
103103
}
104104
}
105105
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//
2+
// Copyright 2026 Google LLC
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
6+
@mixin root {
7+
--container-shape: var(--md-sys-shape-corner-lg);
8+
--gap: 0;
9+
}
10+
11+
@mixin segmented {
12+
--gap: 2px;
13+
}
14+
15+
@mixin item {
16+
--container-height: 56px;
17+
--container-color: transparent;
18+
--container-shape: var(--md-sys-shape-corner-xs);
19+
--label-text-color: var(--md-sys-color-on-surface);
20+
--label-text: var(--md-sys-typescale-body-lg);
21+
--label-text-tracking: var(--md-sys-typescale-body-lg-tracking);
22+
--leading-space: 16px;
23+
--trailing-space: 16px;
24+
--between-space: 12px;
25+
--top-space: 10px;
26+
--bottom-space: 10px;
27+
--avatar-size: 40px;
28+
--avatar-shape: var(--md-sys-shape-corner-full);
29+
--avatar-color: var(--md-sys-color-primary-container);
30+
--avatar-label: var(--md-sys-typescale-title-md);
31+
--avatar-label-tracking: var(--md-sys-typescale-title-md-tracking);
32+
--avatar-label-color: var(--md-sys-color-on-primary-container);
33+
--leading-icon-color: var(--md-sys-color-on-surface-variant);
34+
--leading-icon-size: 20px;
35+
--trailing-icon-color: var(--md-sys-color-on-surface-variant);
36+
--trailing-icon-size: 20px;
37+
--overline: var(--md-sys-typescale-label-sm);
38+
--overline-tracking: var(--md-sys-typescale-label-sm-tracking);
39+
--overline-color: var(--md-sys-color-on-surface-variant);
40+
--supporting-text: var(--md-sys-typescale-body-md);
41+
--supporting-text-tracking: var(--md-sys-typescale-body-md-tracking);
42+
--supporting-text-color: var(--md-sys-color-on-surface-variant);
43+
--trailing-supporting-text: var(--md-sys-typescale-label-sm);
44+
--trailing-supporting-text-tracking: var(
45+
--md-sys-typescale-label-sm-tracking
46+
);
47+
--trailing-supporting-text-color: var(--md-sys-color-on-surface-variant);
48+
}
49+
50+
@mixin item-segmented {
51+
--container-color: var(--md-sys-color-surface);
52+
}
53+
54+
@mixin item-hovered {
55+
--container-shape: var(--md-sys-shape-corner-md);
56+
--leading-icon-color: var(--md-sys-color-on-surface);
57+
--trailing-icon-color: var(--md-sys-color-on-surface);
58+
}
59+
60+
@mixin item-focused {
61+
--container-shape: var(--md-sys-shape-corner-lg);
62+
--leading-icon-color: var(--md-sys-color-on-surface);
63+
--trailing-icon-color: var(--md-sys-color-on-surface);
64+
}
65+
66+
@mixin item-pressed {
67+
--container-shape: var(--md-sys-shape-corner-lg);
68+
--leading-icon-color: var(--md-sys-color-on-surface);
69+
--trailing-icon-color: var(--md-sys-color-on-surface);
70+
}
71+
72+
@mixin item-selected {
73+
--container-shape: var(--md-sys-shape-corner-lg);
74+
--container-color: var(--md-sys-color-secondary-container);
75+
--label-text-color: var(--md-sys-color-on-secondary-container);
76+
--leading-icon-color: var(--md-sys-color-on-secondary-container);
77+
--trailing-icon-color: var(--md-sys-color-on-secondary-container);
78+
--overline-color: var(--md-sys-color-on-secondary-container);
79+
--supporting-text-color: var(--md-sys-color-on-secondary-container);
80+
--trailing-supporting-text-color: var(
81+
--md-sys-color-on-secondary-container
82+
);
83+
}
84+
85+
@mixin item-disabled {
86+
--container-shape: var(--md-sys-shape-corner-xs);
87+
--container-color: hsl(from var(--md-sys-color-on-surface) h s l / 10%);
88+
--label-text-color: hsl(from var(--md-sys-color-on-surface) h s l / 38%);
89+
--leading-icon-color: hsl(
90+
from var(--md-sys-color-on-surface) h s l / 38%
91+
);
92+
--trailing-icon-color: hsl(
93+
from var(--md-sys-color-on-surface) h s l / 38%
94+
);
95+
--overline-color: hsl(from var(--md-sys-color-on-surface) h s l / 38%);
96+
--supporting-text-color: hsl(
97+
from var(--md-sys-color-on-surface) h s l / 38%
98+
);
99+
--trailing-supporting-text-color: hsl(
100+
from var(--md-sys-color-on-surface) h s l / 38%
101+
);
102+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @license
3+
* Copyright 2026 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import './material-collection.js';
8+
import './index.js';
9+
10+
import {
11+
KnobTypesToKnobs,
12+
MaterialCollection,
13+
materialInitsToStoryInits,
14+
setUpDemo,
15+
} from './material-collection.js';
16+
import {boolInput, Knob} from './index.js';
17+
18+
import {stories, StoryKnobs} from './stories.js';
19+
20+
const collection = new MaterialCollection<KnobTypesToKnobs<StoryKnobs>>(
21+
'List',
22+
[
23+
new Knob('segmented', {
24+
ui: boolInput(),
25+
defaultValue: true,
26+
}),
27+
new Knob('nonInteractive', {
28+
ui: boolInput(),
29+
}),
30+
],
31+
);
32+
33+
collection.addStories(...materialInitsToStoryInits(stories));
34+
35+
setUpDemo(collection, {fonts: 'roboto', icons: 'material-symbols'});

0 commit comments

Comments
 (0)