mirror of
https://github.com/material-components/material-web.git
synced 2024-10-26 13:40:03 +03:00
feat(typography): add @material/web/typography/md-typescale
classes
Fixes #1050 View the updated [typography docs](https://github.com/material-components/material-web/blob/main/docs/theming/typography.md#classes) for more info. PiperOrigin-RevId: 613259080
This commit is contained in:
parent
758e61581e
commit
36dd77ef97
@ -7,6 +7,7 @@
|
|||||||
import '@material/web/divider/divider.js';
|
import '@material/web/divider/divider.js';
|
||||||
|
|
||||||
import {MaterialStoryInit} from './material-collection.js';
|
import {MaterialStoryInit} from './material-collection.js';
|
||||||
|
import {styles as typescaleStyles} from '@material/web/typography/md-typescale.js';
|
||||||
import {css, html} from 'lit';
|
import {css, html} from 'lit';
|
||||||
|
|
||||||
/** Knob types for divider stories. */
|
/** Knob types for divider stories. */
|
||||||
@ -18,7 +19,9 @@ export interface StoryKnobs {
|
|||||||
|
|
||||||
const standard: MaterialStoryInit<StoryKnobs> = {
|
const standard: MaterialStoryInit<StoryKnobs> = {
|
||||||
name: 'Divider',
|
name: 'Divider',
|
||||||
styles: css`
|
styles: [
|
||||||
|
typescaleStyles,
|
||||||
|
css`
|
||||||
ul {
|
ul {
|
||||||
border: 1px solid var(--md-sys-color-outline);
|
border: 1px solid var(--md-sys-color-outline);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -28,15 +31,16 @@ const standard: MaterialStoryInit<StoryKnobs> = {
|
|||||||
|
|
||||||
li {
|
li {
|
||||||
color: var(--md-sys-color-on-background);
|
color: var(--md-sys-color-on-background);
|
||||||
font-family: system-ui;
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 16px;
|
margin: 16px;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
],
|
||||||
render(knobs) {
|
render(knobs) {
|
||||||
return html`
|
return html`
|
||||||
<ul
|
<ul
|
||||||
aria-label="A list of items with decorative and non-decorative separators">
|
aria-label="A list of items with decorative and non-decorative separators"
|
||||||
|
class="md-typescale-body-medium">
|
||||||
<li>List item one</li>
|
<li>List item one</li>
|
||||||
<md-divider
|
<md-divider
|
||||||
?inset=${knobs.inset}
|
?inset=${knobs.inset}
|
||||||
|
@ -10,7 +10,7 @@ order: 3
|
|||||||
|
|
||||||
<!--*
|
<!--*
|
||||||
# Document freshness: For more information, see go/fresh-source.
|
# Document freshness: For more information, see go/fresh-source.
|
||||||
freshness: { owner: 'lizmitchell' reviewed: '2023-09-06' }
|
freshness: { owner: 'lizmitchell' reviewed: '2024-03-05' }
|
||||||
tag: 'docType:howTo'
|
tag: 'docType:howTo'
|
||||||
*-->
|
*-->
|
||||||
|
|
||||||
@ -71,6 +71,36 @@ A
|
|||||||
is a collection of font styles: `font-family`, `font-size`, `line-height`, and
|
is a collection of font styles: `font-family`, `font-size`, `line-height`, and
|
||||||
`font-weight`.
|
`font-weight`.
|
||||||
|
|
||||||
|
### Classes
|
||||||
|
|
||||||
|
<!-- go/md-typescale -->
|
||||||
|
|
||||||
|
Typescales can be applied to an element using the classes from the typescale
|
||||||
|
stylesheet.
|
||||||
|
|
||||||
|
Class names follow the naming convention `.md-typescale-<scale>-<size>`.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import {styles as typescaleStyles} from '@material/web/typography/md-typescale.js';
|
||||||
|
|
||||||
|
// `typescaleStyles.styleSheet` is a `CSSStyleSheet` that can be added to a
|
||||||
|
// document or shadow root's `adoptedStyleSheets` to use the `.md-typescale-*`
|
||||||
|
// classes.
|
||||||
|
document.adoptedStyleSheets.push(typescaleStyles.styleSheet);
|
||||||
|
|
||||||
|
// `typescaleStyles` can also be added to a `LitElement` component's styles.
|
||||||
|
class App extends LitElement {
|
||||||
|
static styles = [typescaleStyles, css`...`];
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<h1 class="md-typescale-display-large">Large display</h1>
|
||||||
|
<p class="md-typescale-body-medium">Body text</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Tokens
|
### Tokens
|
||||||
|
|
||||||
Typescales can be set using
|
Typescales can be set using
|
||||||
|
@ -11,6 +11,7 @@ import '@material/web/iconbutton/icon-button.js';
|
|||||||
import '@material/web/iconbutton/outlined-icon-button.js';
|
import '@material/web/iconbutton/outlined-icon-button.js';
|
||||||
|
|
||||||
import {MaterialStoryInit} from './material-collection.js';
|
import {MaterialStoryInit} from './material-collection.js';
|
||||||
|
import {styles as typescaleStyles} from '@material/web/typography/md-typescale.js';
|
||||||
import {css, html} from 'lit';
|
import {css, html} from 'lit';
|
||||||
|
|
||||||
/** Knob types for icon button stories. */
|
/** Knob types for icon button stories. */
|
||||||
@ -20,7 +21,9 @@ export interface StoryKnobs {
|
|||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = css`
|
const styles = [
|
||||||
|
typescaleStyles,
|
||||||
|
css`
|
||||||
.column {
|
.column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -34,19 +37,16 @@ const styles = css`
|
|||||||
|
|
||||||
p {
|
p {
|
||||||
color: var(--md-sys-color-on-surface);
|
color: var(--md-sys-color-on-surface);
|
||||||
font: var(--md-sys-typescale-body-medium-weight, 400)
|
|
||||||
var(--md-sys-typescale-body-medium-size, 0.875rem) /
|
|
||||||
var(--md-sys-typescale-body-medium-line-height, 1.25rem)
|
|
||||||
var(--md-sys-typescale-body-medium-font, 'Roboto');
|
|
||||||
}
|
}
|
||||||
`;
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
const buttons: MaterialStoryInit<StoryKnobs> = {
|
const buttons: MaterialStoryInit<StoryKnobs> = {
|
||||||
name: 'Icon button variants',
|
name: 'Icon button variants',
|
||||||
styles,
|
styles,
|
||||||
render({icon, disabled}) {
|
render({icon, disabled}) {
|
||||||
return html`
|
return html`
|
||||||
<div class="row">
|
<div class="row md-typescale-body-medium">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<p>Standard</p>
|
<p>Standard</p>
|
||||||
<md-icon-button aria-label="Open settings" ?disabled=${disabled}>
|
<md-icon-button aria-label="Open settings" ?disabled=${disabled}>
|
||||||
|
@ -10,6 +10,7 @@ import '@material/web/labs/card/filled-card.js';
|
|||||||
import '@material/web/labs/card/outlined-card.js';
|
import '@material/web/labs/card/outlined-card.js';
|
||||||
|
|
||||||
import {MaterialStoryInit} from './material-collection.js';
|
import {MaterialStoryInit} from './material-collection.js';
|
||||||
|
import {styles as typescaleStyles} from '@material/web/typography/md-typescale.js';
|
||||||
import {css, html} from 'lit';
|
import {css, html} from 'lit';
|
||||||
|
|
||||||
/** Knob types for card stories. */
|
/** Knob types for card stories. */
|
||||||
@ -18,16 +19,14 @@ export interface StoryKnobs {}
|
|||||||
const MEDIA_IMAGE =
|
const MEDIA_IMAGE =
|
||||||
'data:image/png;base64,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';
|
'data:image/png;base64,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';
|
||||||
|
|
||||||
const styles = css`
|
const styles = [
|
||||||
|
typescaleStyles,
|
||||||
|
css`
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
color: var(--md-sys-color-on-surface);
|
color: var(--md-sys-color-on-surface);
|
||||||
font: var(--md-sys-typescale-body-medium-weight, 400)
|
|
||||||
var(--md-sys-typescale-body-medium-size, 0.875rem) /
|
|
||||||
var(--md-sys-typescale-body-medium-line-height, 1.25rem)
|
|
||||||
var(--md-sys-typescale-body-medium-font, 'Roboto');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
@ -49,14 +48,15 @@ const styles = css`
|
|||||||
padding: 16px;
|
padding: 16px;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
`;
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
const cards: MaterialStoryInit<StoryKnobs> = {
|
const cards: MaterialStoryInit<StoryKnobs> = {
|
||||||
name: 'Cards',
|
name: 'Cards',
|
||||||
styles,
|
styles,
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="container">
|
<div class="container md-typescale-body-medium">
|
||||||
<md-elevated-card class="card">
|
<md-elevated-card class="card">
|
||||||
<img src=${MEDIA_IMAGE} alt="Placeholder image" />
|
<img src=${MEDIA_IMAGE} alt="Placeholder image" />
|
||||||
<div class="content">A static elevated card</div>
|
<div class="content">A static elevated card</div>
|
||||||
@ -81,7 +81,7 @@ const withActions: MaterialStoryInit<StoryKnobs> = {
|
|||||||
styles,
|
styles,
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="container">
|
<div class="container md-typescale-body-medium">
|
||||||
<md-elevated-card class="card">
|
<md-elevated-card class="card">
|
||||||
<img src=${MEDIA_IMAGE} alt="Placeholder image" />
|
<img src=${MEDIA_IMAGE} alt="Placeholder image" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -14,6 +14,7 @@ import {MaterialStoryInit} from './material-collection.js';
|
|||||||
import {MdTabs} from '@material/web/tabs/tabs.js';
|
import {MdTabs} from '@material/web/tabs/tabs.js';
|
||||||
import {css, html, nothing} from 'lit';
|
import {css, html, nothing} from 'lit';
|
||||||
import {ref} from 'lit/directives/ref.js';
|
import {ref} from 'lit/directives/ref.js';
|
||||||
|
import {styles as typescaleStyles} from '../../typography/md-typescale.js';
|
||||||
|
|
||||||
/** Knob types for Tabs stories. */
|
/** Knob types for Tabs stories. */
|
||||||
export interface StoryKnobs {
|
export interface StoryKnobs {
|
||||||
@ -23,14 +24,9 @@ export interface StoryKnobs {
|
|||||||
content: string;
|
content: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = css`
|
const styles = [
|
||||||
[role='tabpanel']:not([hidden]) {
|
typescaleStyles,
|
||||||
font-family:
|
css`
|
||||||
Roboto,
|
|
||||||
Material Sans,
|
|
||||||
system-ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
[role='tabpanel']:not(.subtabs) {
|
[role='tabpanel']:not(.subtabs) {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
@ -47,7 +43,8 @@ const styles = css`
|
|||||||
.controls {
|
.controls {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
`;
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
const primary: MaterialStoryInit<StoryKnobs> = {
|
const primary: MaterialStoryInit<StoryKnobs> = {
|
||||||
name: 'Primary Tabs',
|
name: 'Primary Tabs',
|
||||||
@ -94,21 +91,45 @@ const primary: MaterialStoryInit<StoryKnobs> = {
|
|||||||
</md-primary-tab>
|
</md-primary-tab>
|
||||||
</md-tabs>
|
</md-tabs>
|
||||||
|
|
||||||
<div role="tabpanel" id="panel-one" aria-labelledby="tab-one"
|
<div
|
||||||
>Keyboard</div
|
role="tabpanel"
|
||||||
>
|
class="md-typescale-body-medium"
|
||||||
<div role="tabpanel" id="panel-two" aria-labelledby="tab-two" hidden
|
id="panel-one"
|
||||||
>Guitar</div
|
aria-labelledby="tab-one">
|
||||||
>
|
Keyboard
|
||||||
<div role="tabpanel" id="panel-three" aria-labelledby="tab-three" hidden
|
</div>
|
||||||
>Drums</div
|
<div
|
||||||
>
|
role="tabpanel"
|
||||||
<div role="tabpanel" id="panel-four" aria-labelledby="tab-four" hidden
|
class="md-typescale-body-medium"
|
||||||
>Bass</div
|
id="panel-two"
|
||||||
>
|
aria-labelledby="tab-two"
|
||||||
<div role="tabpanel" id="panel-five" aria-labelledby="tab-five" hidden
|
hidden>
|
||||||
>Saxophone</div
|
Guitar
|
||||||
>
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-three"
|
||||||
|
aria-labelledby="tab-three"
|
||||||
|
hidden>
|
||||||
|
Drums
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-four"
|
||||||
|
aria-labelledby="tab-four"
|
||||||
|
hidden>
|
||||||
|
Bass
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-five"
|
||||||
|
aria-labelledby="tab-five"
|
||||||
|
hidden>
|
||||||
|
Saxophone
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -139,16 +160,37 @@ const secondary: MaterialStoryInit<StoryKnobs> = {
|
|||||||
</md-secondary-tab>
|
</md-secondary-tab>
|
||||||
</md-tabs>
|
</md-tabs>
|
||||||
|
|
||||||
<div role="tabpanel" id="panel-one" aria-labelledby="tab-one">Travel</div>
|
<div
|
||||||
<div role="tabpanel" id="panel-two" aria-labelledby="tab-two" hidden
|
role="tabpanel"
|
||||||
>Hotel</div
|
class="md-typescale-body-medium"
|
||||||
>
|
id="panel-one"
|
||||||
<div role="tabpanel" id="panel-three" aria-labelledby="tab-three" hidden
|
aria-labelledby="tab-one">
|
||||||
>Activities</div
|
Travel
|
||||||
>
|
</div>
|
||||||
<div role="tabpanel" id="panel-four" aria-labelledby="tab-four" hidden
|
<div
|
||||||
>Food</div
|
role="tabpanel"
|
||||||
>
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-two"
|
||||||
|
aria-labelledby="tab-two"
|
||||||
|
hidden>
|
||||||
|
Hotel
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-three"
|
||||||
|
aria-labelledby="tab-three"
|
||||||
|
hidden>
|
||||||
|
Activities
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-four"
|
||||||
|
aria-labelledby="tab-four"
|
||||||
|
hidden>
|
||||||
|
Food
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -189,7 +231,7 @@ const scrolling: MaterialStoryInit<StoryKnobs> = {
|
|||||||
const custom: MaterialStoryInit<StoryKnobs> = {
|
const custom: MaterialStoryInit<StoryKnobs> = {
|
||||||
name: 'Custom Tabs',
|
name: 'Custom Tabs',
|
||||||
styles: [
|
styles: [
|
||||||
styles,
|
...styles,
|
||||||
css`
|
css`
|
||||||
.custom {
|
.custom {
|
||||||
/* colors */
|
/* colors */
|
||||||
@ -216,7 +258,8 @@ const custom: MaterialStoryInit<StoryKnobs> = {
|
|||||||
aria-label="A custom themed tab bar"
|
aria-label="A custom themed tab bar"
|
||||||
class="custom"
|
class="custom"
|
||||||
active-tab-index=${knobs.activeTabIndex}
|
active-tab-index=${knobs.activeTabIndex}
|
||||||
.autoActivate=${knobs.autoActivate}>
|
.autoActivate=${knobs.autoActivate}
|
||||||
|
${setupTabPanels()}>
|
||||||
<md-primary-tab id="tab-one" aria-controls="panel-one">
|
<md-primary-tab id="tab-one" aria-controls="panel-one">
|
||||||
${tabContent('flight', 'Travel')}
|
${tabContent('flight', 'Travel')}
|
||||||
</md-primary-tab>
|
</md-primary-tab>
|
||||||
@ -231,16 +274,37 @@ const custom: MaterialStoryInit<StoryKnobs> = {
|
|||||||
</md-primary-tab>
|
</md-primary-tab>
|
||||||
</md-tabs>
|
</md-tabs>
|
||||||
|
|
||||||
<div role="tabpanel" id="panel-one" aria-labelledby="tab-one">Travel</div>
|
<div
|
||||||
<div role="tabpanel" id="panel-two" aria-labelledby="tab-two" hidden
|
role="tabpanel"
|
||||||
>Hotel</div
|
class="md-typescale-body-medium"
|
||||||
>
|
id="panel-one"
|
||||||
<div role="tabpanel" id="panel-three" aria-labelledby="tab-three" hidden
|
aria-labelledby="tab-one">
|
||||||
>Activities</div
|
Travel
|
||||||
>
|
</div>
|
||||||
<div role="tabpanel" id="panel-four" aria-labelledby="tab-four" hidden
|
<div
|
||||||
>Food</div
|
role="tabpanel"
|
||||||
>
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-two"
|
||||||
|
aria-labelledby="tab-two"
|
||||||
|
hidden>
|
||||||
|
Hotel
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-three"
|
||||||
|
aria-labelledby="tab-three"
|
||||||
|
hidden>
|
||||||
|
Activities
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="panel-four"
|
||||||
|
aria-labelledby="tab-four"
|
||||||
|
hidden>
|
||||||
|
Food
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -269,32 +333,63 @@ const primaryAndSecondary: MaterialStoryInit<StoryKnobs> = {
|
|||||||
</md-primary-tab>
|
</md-primary-tab>
|
||||||
</md-tabs>
|
</md-tabs>
|
||||||
|
|
||||||
<div role="tabpanel" id="movies" class="subtabs" aria-label="Movies">
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="movies"
|
||||||
|
class="subtabs"
|
||||||
|
aria-label="Movies">
|
||||||
<md-tabs
|
<md-tabs
|
||||||
aria-label="Secondary tabs for movies"
|
aria-label="Secondary tabs for movies"
|
||||||
active-tab-index=${knobs.activeTabIndex}
|
active-tab-index=${knobs.activeTabIndex}
|
||||||
.autoActivate=${knobs.autoActivate}
|
.autoActivate=${knobs.autoActivate}
|
||||||
${setupTabPanels()}>
|
${setupTabPanels()}>
|
||||||
<md-secondary-tab aria-controls="star-wars"
|
<md-secondary-tab aria-controls="star-wars">
|
||||||
>Star Wars</md-secondary-tab
|
Star Wars
|
||||||
>
|
</md-secondary-tab>
|
||||||
<md-secondary-tab aria-controls="avengers">Avengers</md-secondary-tab>
|
<md-secondary-tab aria-controls="avengers">
|
||||||
|
Avengers
|
||||||
|
</md-secondary-tab>
|
||||||
<md-secondary-tab aria-controls="jaws">Jaws </md-secondary-tab>
|
<md-secondary-tab aria-controls="jaws">Jaws </md-secondary-tab>
|
||||||
<md-secondary-tab aria-controls="forzen">Frozen </md-secondary-tab>
|
<md-secondary-tab aria-controls="forzen">Frozen </md-secondary-tab>
|
||||||
</md-tabs>
|
</md-tabs>
|
||||||
|
|
||||||
<div role="tabpanel" id="star-wars" aria-label="Star Wars"
|
<div
|
||||||
>Star Wars</div
|
role="tabpanel"
|
||||||
>
|
class="md-typescale-body-medium"
|
||||||
<div role="tabpanel" id="avengers" aria-label="Avengers" hidden
|
id="star-wars"
|
||||||
>Avengers</div
|
aria-label="Star Wars">
|
||||||
>
|
Star Wars
|
||||||
<div role="tabpanel" id="jaws" aria-label="Jaws" hidden>Jaws</div>
|
</div>
|
||||||
<div role="tabpanel" id="frozen" aria-label="Frozen" hidden>Frozen</div>
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="avengers"
|
||||||
|
aria-label="Avengers"
|
||||||
|
hidden>
|
||||||
|
Avengers
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="jaws"
|
||||||
|
aria-label="Jaws"
|
||||||
|
hidden>
|
||||||
|
Jaws
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="frozen"
|
||||||
|
aria-label="Frozen"
|
||||||
|
hidden>
|
||||||
|
Frozen
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
id="photos"
|
id="photos"
|
||||||
class="subtabs"
|
class="subtabs"
|
||||||
aria-label="Photos"
|
aria-label="Photos"
|
||||||
@ -303,31 +398,60 @@ const primaryAndSecondary: MaterialStoryInit<StoryKnobs> = {
|
|||||||
aria-label="Secondary tabs for photos"
|
aria-label="Secondary tabs for photos"
|
||||||
active-tab-index=${knobs.activeTabIndex}
|
active-tab-index=${knobs.activeTabIndex}
|
||||||
.autoActivate=${knobs.autoActivate}>
|
.autoActivate=${knobs.autoActivate}>
|
||||||
<md-secondary-tab aria-controls="yosemite">Yosemite</md-secondary-tab>
|
<md-secondary-tab aria-controls="yosemite">
|
||||||
<md-secondary-tab aria-controls="mona-lisa"
|
Yosemite
|
||||||
>Mona Lisa</md-secondary-tab
|
</md-secondary-tab>
|
||||||
>
|
<md-secondary-tab aria-controls="mona-lisa">
|
||||||
<md-secondary-tab aria-controls="swiss-alps"
|
Mona Lisa
|
||||||
>Swiss Alps</md-secondary-tab
|
</md-secondary-tab>
|
||||||
>
|
<md-secondary-tab aria-controls="swiss-alps">
|
||||||
<md-secondary-tab aria-controls="niagra-falls"
|
Swiss Alps
|
||||||
>Niagra Falls</md-secondary-tab
|
</md-secondary-tab>
|
||||||
>
|
<md-secondary-tab aria-controls="niagra-falls">
|
||||||
|
Niagra Falls
|
||||||
|
</md-secondary-tab>
|
||||||
</md-tabs>
|
</md-tabs>
|
||||||
|
|
||||||
<div role="tabpanel" id="yosemite" aria-label="Yosemite">Yosemite</div>
|
<div
|
||||||
<div role="tabpanel" id="mona-lisa" aria-label="Mona Lisa" hidden
|
role="tabpanel"
|
||||||
>Mona Lisa</div
|
class="md-typescale-body-medium"
|
||||||
>
|
id="yosemite"
|
||||||
<div role="tabpanel" id="swiss-alps" aria-label="Swiss Alps" hidden
|
aria-label="Yosemite">
|
||||||
>Swiss Alps</div
|
Yosemite
|
||||||
>
|
</div>
|
||||||
<div role="tabpanel" id="niagra-falls" aria-label="Niagra Falls" hidden
|
<div
|
||||||
>Niagra Falls</div
|
role="tabpanel"
|
||||||
>
|
class="md-typescale-body-medium"
|
||||||
|
id="mona-lisa"
|
||||||
|
aria-label="Mona Lisa"
|
||||||
|
hidden>
|
||||||
|
Mona Lisa
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="swiss-alps"
|
||||||
|
aria-label="Swiss Alps"
|
||||||
|
hidden>
|
||||||
|
Swiss Alps
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="niagra-falls"
|
||||||
|
aria-label="Niagra Falls"
|
||||||
|
hidden>
|
||||||
|
Niagra Falls
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div role="tabpanel" id="music" class="subtabs" aria-label="Music" hidden>
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="music"
|
||||||
|
class="subtabs"
|
||||||
|
aria-label="Music"
|
||||||
|
hidden>
|
||||||
<md-tabs
|
<md-tabs
|
||||||
aria-label="Secondary tabs for music"
|
aria-label="Secondary tabs for music"
|
||||||
active-tab-index=${knobs.activeTabIndex}
|
active-tab-index=${knobs.activeTabIndex}
|
||||||
@ -335,22 +459,45 @@ const primaryAndSecondary: MaterialStoryInit<StoryKnobs> = {
|
|||||||
${setupTabPanels()}>
|
${setupTabPanels()}>
|
||||||
<md-secondary-tab aria-controls="rock">Rock </md-secondary-tab>
|
<md-secondary-tab aria-controls="rock">Rock </md-secondary-tab>
|
||||||
<md-secondary-tab aria-controls="ambient">Ambient </md-secondary-tab>
|
<md-secondary-tab aria-controls="ambient">Ambient </md-secondary-tab>
|
||||||
<md-secondary-tab aria-controls="sounds"
|
<md-secondary-tab aria-controls="sounds">
|
||||||
>Soundscapes</md-secondary-tab
|
Soundscapes
|
||||||
>
|
</md-secondary-tab>
|
||||||
<md-secondary-tab aria-controls="noise">White Noise</md-secondary-tab>
|
<md-secondary-tab aria-controls="noise">
|
||||||
|
White Noise
|
||||||
|
</md-secondary-tab>
|
||||||
</md-tabs>
|
</md-tabs>
|
||||||
|
|
||||||
<div role="tabpanel" id="rock" aria-label="Rock">Rock</div>
|
<div
|
||||||
<div role="tabpanel" id="ambient" aria-label="Ambient" hidden
|
role="tabpanel"
|
||||||
>Ambient</div
|
class="md-typescale-body-medium"
|
||||||
>
|
id="rock"
|
||||||
<div role="tabpanel" id="sounds" aria-label="Soundscapes" hidden
|
aria-label="Rock">
|
||||||
>Soundscapes</div
|
Rock
|
||||||
>
|
</div>
|
||||||
<div role="tabpanel" id="noise" aria-label="White noise" hidden
|
<div
|
||||||
>White Noise</div
|
role="tabpanel"
|
||||||
>
|
class="md-typescale-body-medium"
|
||||||
|
id="ambient"
|
||||||
|
aria-label="Ambient"
|
||||||
|
hidden>
|
||||||
|
Ambient
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="sounds"
|
||||||
|
aria-label="Soundscapes"
|
||||||
|
hidden>
|
||||||
|
Soundscapes
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
class="md-typescale-body-medium"
|
||||||
|
id="noise"
|
||||||
|
aria-label="White noise"
|
||||||
|
hidden>
|
||||||
|
White Noise
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
@ -403,16 +550,18 @@ const dynamic: MaterialStoryInit<StoryKnobs> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html` <div class="controls">
|
return html` <div class="controls">
|
||||||
<md-icon-button @click=${addTab}><md-icon>add</md-icon></md-icon-button>
|
<md-icon-button @click=${addTab}>
|
||||||
<md-icon-button @click=${removeTab}
|
<md-icon>add</md-icon>
|
||||||
><md-icon>remove</md-icon></md-icon-button
|
</md-icon-button>
|
||||||
>
|
<md-icon-button @click=${removeTab}>
|
||||||
<md-icon-button @click=${moveTabTowardsStart}
|
<md-icon>remove</md-icon>
|
||||||
><md-icon>chevron_left</md-icon></md-icon-button
|
</md-icon-button>
|
||||||
>
|
<md-icon-button @click=${moveTabTowardsStart}>
|
||||||
<md-icon-button @click=${moveTabTowardsEnd}
|
<md-icon>chevron_left</md-icon>
|
||||||
><md-icon>chevron_right</md-icon></md-icon-button
|
</md-icon-button>
|
||||||
>
|
<md-icon-button @click=${moveTabTowardsEnd}>
|
||||||
|
<md-icon>chevron_right</md-icon>
|
||||||
|
</md-icon-button>
|
||||||
</div>
|
</div>
|
||||||
<md-tabs
|
<md-tabs
|
||||||
class="scrolling"
|
class="scrolling"
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
// go/keep-sorted start
|
// go/keep-sorted start
|
||||||
@use 'sass:list';
|
@use 'sass:list';
|
||||||
|
@use 'sass:map';
|
||||||
// go/keep-sorted end
|
// go/keep-sorted end
|
||||||
// go/keep-sorted start
|
// go/keep-sorted start
|
||||||
@use '../tokens';
|
@use '../tokens';
|
||||||
@ -20,11 +21,11 @@
|
|||||||
/// @use '@material/web/typography/typescale';
|
/// @use '@material/web/typography/typescale';
|
||||||
///
|
///
|
||||||
/// :root {
|
/// :root {
|
||||||
/// @include typescale.theme(
|
/// @include typescale.theme((
|
||||||
/// 'body-medium-size': 1rem,
|
/// 'body-medium-size': 1rem,
|
||||||
/// 'body-medium-line-height': 1.5rem,
|
/// 'body-medium-line-height': 1.5rem,
|
||||||
/// /* ... */
|
/// /* ... */
|
||||||
/// );
|
/// ));
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// /* Generated CSS */
|
/// /* Generated CSS */
|
||||||
@ -48,3 +49,109 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Emits `.md-typescale-*` classes with font styles for each typescale in the
|
||||||
|
/// provided `$tokens`.
|
||||||
|
///
|
||||||
|
/// @example scss
|
||||||
|
/// @include typescale.styles(tokens.md-sys-typescale-values());
|
||||||
|
/// // Generates the following CSS:
|
||||||
|
/// .md-typescale-display-small { font: ...; }
|
||||||
|
/// .md-typescale-display-medium { font: ...; }
|
||||||
|
/// .md-typescale-display-large { font: ...; }
|
||||||
|
/// .md-typescale-body-small { font: ...; }
|
||||||
|
/// .md-typescale-body-medium { font: ...; }
|
||||||
|
/// .md-typescale-body-large { font: ...; }
|
||||||
|
/// // etc...
|
||||||
|
///
|
||||||
|
/// @param {Map} $tokens - A Map with `md-sys-typescale` token values.
|
||||||
|
/// @output Emits `.md-typescale-*` classes for each typescale size.
|
||||||
|
@mixin styles($tokens) {
|
||||||
|
$typescale-properties: _tokens-to-typescale-properties-map($tokens);
|
||||||
|
|
||||||
|
// Use the default layer for lowered specificity.
|
||||||
|
@layer {
|
||||||
|
@each $typescale, $properties in $typescale-properties {
|
||||||
|
// $typescale is a scale and size (ex. 'body-medium').
|
||||||
|
// $properties is a Map with 'font', 'size', 'line-height', 'weight', and
|
||||||
|
// an optional 'weight-prominent'.
|
||||||
|
.md-typescale-#{$typescale} {
|
||||||
|
font: map.get($properties, 'weight')
|
||||||
|
map.get($properties, 'size') /
|
||||||
|
map.get($properties, 'line-height')
|
||||||
|
map.get($properties, 'font');
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typescale-#{$typescale}-prominent {
|
||||||
|
// Inherit the font styles from the non-prominent selector. This adds
|
||||||
|
// another class selector to the regular styles, instead of re-emitting
|
||||||
|
// them.
|
||||||
|
// ```
|
||||||
|
// .md-typescale-label-medium, .md-typescale-label-medium-prominent {
|
||||||
|
// font: ...;
|
||||||
|
// }
|
||||||
|
// .md-typescale-label-medium-prominent {
|
||||||
|
// font-weight: ...;
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
@extend .md-typescale-#{$typescale};
|
||||||
|
|
||||||
|
// Note: the prominent selector is not emitted by Sass when a
|
||||||
|
// typescale's prominent values are null.
|
||||||
|
font-weight: map.get($properties, 'weight-prominent');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Takes a md-sys-typescale token values Map and returns a Map whose keys are
|
||||||
|
/// typescale names ('body-medium', 'label-large', etc) and whose values are a
|
||||||
|
/// Map of properties for that Typescale ('font', 'size', etc).
|
||||||
|
@function _tokens-to-typescale-properties-map($tokens) {
|
||||||
|
$typescale-properties: ();
|
||||||
|
// The keys of $typescale-properties. Each typescale is joined with each size
|
||||||
|
// ('display-small', 'display-medium', 'display-large', 'headline-small'...).
|
||||||
|
$typescales: ('display', 'headline', 'title', 'body', 'label');
|
||||||
|
$sizes: ('small', 'medium', 'large');
|
||||||
|
// The keys to the Map for each scale in $typescale-properties. These
|
||||||
|
// properties are required...
|
||||||
|
$required-properties: ('font', 'line-height', 'size', 'weight');
|
||||||
|
// ...while not all typescales have these properties.
|
||||||
|
$optional-properties: ('weight-prominent');
|
||||||
|
$properties: list.join($required-properties, $optional-properties);
|
||||||
|
|
||||||
|
@each $typescale in $typescales {
|
||||||
|
@each $size in $sizes {
|
||||||
|
$typescale-and-size: #{$typescale}-#{$size};
|
||||||
|
|
||||||
|
@each $property in $properties {
|
||||||
|
$token: '#{$typescale-and-size}-#{$property}';
|
||||||
|
$value: map.get($tokens, $token);
|
||||||
|
@if $value ==
|
||||||
|
null and
|
||||||
|
list.index($required-properties, $property) !=
|
||||||
|
null
|
||||||
|
{
|
||||||
|
@error 'Missing required typescale token `#{$token}`';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove token to check if we used them all at the end of the function.
|
||||||
|
$tokens: map.remove($tokens, $token);
|
||||||
|
$typescale-properties: map.set(
|
||||||
|
$typescale-properties,
|
||||||
|
$typescale-and-size,
|
||||||
|
$property,
|
||||||
|
$value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$unused-tokens: map.keys($tokens);
|
||||||
|
$unused-token-count: list.length($unused-tokens);
|
||||||
|
@if $unused-token-count > 0 {
|
||||||
|
@error 'Missing styles for #{$unused-token-count} typescale tokens (#{$unused-tokens})';
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $typescale-properties;
|
||||||
|
}
|
||||||
|
11
typography/md-typescale.scss
Normal file
11
typography/md-typescale.scss
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2024 Google LLC
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
// go/keep-sorted start
|
||||||
|
@use '../tokens';
|
||||||
|
@use './typescale';
|
||||||
|
// go/keep-sorted end
|
||||||
|
|
||||||
|
@include typescale.styles(tokens.md-sys-typescale-values());
|
Loading…
Reference in New Issue
Block a user