mtrl 0.8.0-next.19 → 0.8.0-next.21
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/dist/components/menu/constants.d.ts +32 -0
- package/dist/components/menu/types.d.ts +21 -0
- package/dist/index.cjs +12 -12
- package/dist/index.cjs.map +6 -6
- package/dist/index.js +12 -12
- package/dist/index.js.map +6 -6
- package/dist/package.json +1 -1
- package/dist/styles.css +2 -2
- package/package.json +1 -1
- package/src/styles/components/_menu.scss +189 -2
package/package.json
CHANGED
|
@@ -96,11 +96,18 @@ $component: "#{$prefix}-menu";
|
|
|
96
96
|
@include m.state-layer(t.color("on-surface"), "hover");
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
// The focus layer is for a person navigating by key. Focus moves into
|
|
100
|
+
// the menu however it was opened, so keying this off `:focus` marked
|
|
101
|
+
// the first item as soon as the menu appeared under the pointer, which
|
|
102
|
+
// reads as a highlight nobody asked for.
|
|
99
103
|
&:focus {
|
|
100
|
-
@include m.state-layer(t.color("on-surface"), "focus");
|
|
101
104
|
outline: none;
|
|
102
105
|
}
|
|
103
106
|
|
|
107
|
+
&:focus-visible {
|
|
108
|
+
@include m.state-layer(t.color("on-surface"), "focus");
|
|
109
|
+
}
|
|
110
|
+
|
|
104
111
|
&:active {
|
|
105
112
|
@include m.state-layer(t.color("on-surface"), "pressed");
|
|
106
113
|
}
|
|
@@ -161,7 +168,7 @@ $component: "#{$prefix}-menu";
|
|
|
161
168
|
@include m.state-layer(t.color("on-secondary-container"), "hover");
|
|
162
169
|
}
|
|
163
170
|
|
|
164
|
-
&:focus {
|
|
171
|
+
&:focus-visible {
|
|
165
172
|
@include m.state-layer(t.color("on-secondary-container"), "focus");
|
|
166
173
|
}
|
|
167
174
|
|
|
@@ -219,6 +226,25 @@ $component: "#{$prefix}-menu";
|
|
|
219
226
|
text-overflow: ellipsis;
|
|
220
227
|
}
|
|
221
228
|
|
|
229
|
+
// A label with a line under it. The stacking belongs to every
|
|
230
|
+
// variant, so a supporting line never runs into its label; the
|
|
231
|
+
// vertical menu adds its own type and colour on top.
|
|
232
|
+
&-label {
|
|
233
|
+
display: flex;
|
|
234
|
+
flex-direction: column;
|
|
235
|
+
justify-content: center;
|
|
236
|
+
flex: 1;
|
|
237
|
+
min-width: 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
&-supporting {
|
|
241
|
+
@include m.typography("body-medium");
|
|
242
|
+
color: t.color("on-surface-variant");
|
|
243
|
+
white-space: nowrap;
|
|
244
|
+
overflow: hidden;
|
|
245
|
+
text-overflow: ellipsis;
|
|
246
|
+
}
|
|
247
|
+
|
|
222
248
|
&-shortcut {
|
|
223
249
|
margin-left: 12px;
|
|
224
250
|
color: t.color("on-surface-variant");
|
|
@@ -286,6 +312,167 @@ $component: "#{$prefix}-menu";
|
|
|
286
312
|
}
|
|
287
313
|
|
|
288
314
|
// RTL Support
|
|
315
|
+
// -------------------------------------------------------------------------
|
|
316
|
+
// The M3 expressive vertical menu (Compose SegmentedMenuTokens and
|
|
317
|
+
// StandardMenuTokens / VibrantMenuTokens). A 16dp container holding 44dp
|
|
318
|
+
// items 2dp apart; an item is a 4dp rectangle at rest and rounds to 12dp
|
|
319
|
+
// as it is hovered, focused, pressed or selected, which is the expressive
|
|
320
|
+
// state this variant is for. The first and last items round to 12dp on
|
|
321
|
+
// their outer corners so the column reads as one block.
|
|
322
|
+
// -------------------------------------------------------------------------
|
|
323
|
+
&--vertical {
|
|
324
|
+
// Standard: surface-based, the lower-emphasis mapping
|
|
325
|
+
--#{$prefix}-menu-container: #{t.color("surface-container-low")};
|
|
326
|
+
--#{$prefix}-menu-label: #{t.color("on-surface")};
|
|
327
|
+
--#{$prefix}-menu-supporting: #{t.color("on-surface-variant")};
|
|
328
|
+
--#{$prefix}-menu-selected-container: #{t.color("tertiary-container")};
|
|
329
|
+
--#{$prefix}-menu-selected-label: #{t.color("on-tertiary-container")};
|
|
330
|
+
|
|
331
|
+
border-radius: v.shape("large");
|
|
332
|
+
background-color: var(--#{$prefix}-menu-container);
|
|
333
|
+
color: var(--#{$prefix}-menu-label);
|
|
334
|
+
padding: 8px;
|
|
335
|
+
|
|
336
|
+
// Vibrant: tertiary-based, more prominent, to be used sparingly
|
|
337
|
+
&.#{$component}--vibrant {
|
|
338
|
+
--#{$prefix}-menu-container: #{t.color("tertiary-container")};
|
|
339
|
+
--#{$prefix}-menu-label: #{t.color("on-tertiary-container")};
|
|
340
|
+
--#{$prefix}-menu-supporting: #{t.color("on-tertiary-container")};
|
|
341
|
+
--#{$prefix}-menu-selected-container: #{t.color("tertiary")};
|
|
342
|
+
--#{$prefix}-menu-selected-label: #{t.color("on-tertiary")};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.#{$component}-list {
|
|
346
|
+
display: flex;
|
|
347
|
+
flex-direction: column;
|
|
348
|
+
gap: 2px; // SegmentedGap
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.#{$component}-item {
|
|
352
|
+
@include m.typography("body-large");
|
|
353
|
+
min-height: 44px; // SegmentedMenuTokens.Item
|
|
354
|
+
padding: 8px 16px; // ItemTopSpace / ItemLeadingSpace
|
|
355
|
+
padding-inline-end: 16px;
|
|
356
|
+
color: var(--#{$prefix}-menu-label);
|
|
357
|
+
border-radius: v.shape("extra-small"); // ItemShape
|
|
358
|
+
transition:
|
|
359
|
+
border-radius v.motion("spring-fast-spatial-duration")
|
|
360
|
+
v.motion("spring-fast-spatial-easing"),
|
|
361
|
+
background-color v.motion("duration-short2")
|
|
362
|
+
v.motion("easing-standard");
|
|
363
|
+
|
|
364
|
+
// The shape is the state: 4dp at rest, 12dp once it is touched
|
|
365
|
+
&:hover,
|
|
366
|
+
&:focus-visible,
|
|
367
|
+
&:active {
|
|
368
|
+
border-radius: v.shape("medium");
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// The ends of the column round outwards, so the items read as one
|
|
372
|
+
&:first-child {
|
|
373
|
+
border-start-start-radius: v.shape("medium");
|
|
374
|
+
border-start-end-radius: v.shape("medium");
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
&:last-child {
|
|
378
|
+
border-end-start-radius: v.shape("medium");
|
|
379
|
+
border-end-end-radius: v.shape("medium");
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
&--selected {
|
|
383
|
+
background-color: var(--#{$prefix}-menu-selected-container);
|
|
384
|
+
color: var(--#{$prefix}-menu-selected-label);
|
|
385
|
+
border-radius: v.shape("medium"); // ItemSelectedShape
|
|
386
|
+
|
|
387
|
+
&:hover {
|
|
388
|
+
@include m.state-layer(var(--#{$prefix}-menu-selected-label), "hover");
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
&:focus-visible {
|
|
392
|
+
@include m.state-layer(var(--#{$prefix}-menu-selected-label), "focus");
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
&:active {
|
|
396
|
+
@include m.state-layer(var(--#{$prefix}-menu-selected-label), "pressed");
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
&--disabled {
|
|
401
|
+
color: color-mix(in srgb, var(--#{$prefix}-menu-label) 38%, transparent);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
&-icon {
|
|
405
|
+
color: var(--#{$prefix}-menu-supporting);
|
|
406
|
+
margin-inline-end: 12px; // ItemBetweenSpace
|
|
407
|
+
|
|
408
|
+
svg {
|
|
409
|
+
// ItemLeadingIconSize / ItemTrailingIconSize
|
|
410
|
+
width: 20px;
|
|
411
|
+
height: 20px;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
&-shortcut {
|
|
416
|
+
@include m.typography("label-small"); // ItemTrailingSupportingTextFont
|
|
417
|
+
color: var(--#{$prefix}-menu-supporting);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// A label with a line under it
|
|
421
|
+
&-label {
|
|
422
|
+
display: flex;
|
|
423
|
+
flex-direction: column;
|
|
424
|
+
justify-content: center;
|
|
425
|
+
flex: 1;
|
|
426
|
+
min-width: 0;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
&-supporting {
|
|
430
|
+
@include m.typography("body-medium"); // ItemSupportingTextFont
|
|
431
|
+
color: var(--#{$prefix}-menu-supporting);
|
|
432
|
+
white-space: nowrap;
|
|
433
|
+
overflow: hidden;
|
|
434
|
+
text-overflow: ellipsis;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
&--selected {
|
|
438
|
+
.#{$component}-item-icon,
|
|
439
|
+
.#{$component}-item-shortcut,
|
|
440
|
+
.#{$component}-item-supporting {
|
|
441
|
+
color: inherit;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// A grouped menu separates its runs of items with a divider; the gap
|
|
447
|
+
// treatment the spec shows is not offered on the web
|
|
448
|
+
// (m3.material.io menu guidelines, "Gaps & dividers")
|
|
449
|
+
.#{$component}-divider {
|
|
450
|
+
margin: 6px 0;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// -------------------------------------------------------------------------
|
|
455
|
+
// Shape morph on the container: while a submenu is open, the menu that
|
|
456
|
+
// opened it steps back to an 8dp corner and the active one takes 24dp
|
|
457
|
+
// (SegmentedMenuTokens.ActiveContainerShape and InactiveContainerShape).
|
|
458
|
+
// This is the expressive active state the spec describes.
|
|
459
|
+
// -------------------------------------------------------------------------
|
|
460
|
+
&--vertical {
|
|
461
|
+
transition:
|
|
462
|
+
transform v.motion("duration-medium1") v.motion("easing-emphasized"),
|
|
463
|
+
opacity v.motion("duration-medium1") v.motion("easing-emphasized"),
|
|
464
|
+
border-radius v.motion("spring-fast-spatial-duration")
|
|
465
|
+
v.motion("spring-fast-spatial-easing");
|
|
466
|
+
|
|
467
|
+
&.#{$component}--active {
|
|
468
|
+
border-radius: 24px;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
&.#{$component}--inactive {
|
|
472
|
+
border-radius: v.shape("small");
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
289
476
|
@include m.rtl {
|
|
290
477
|
transform-origin: top right;
|
|
291
478
|
|