Repository navigation
feat(title): add recipe and tokens #31539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d2ed044
3512a03
238ac54
d20c2d2
3c7c840
ac08f44
94d9dad
035a4ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -37,6 +37,8 @@ This is a comprehensive list of the breaking changes introduced in the major ver | |||||
| - [Text](#version-10x-text) | ||||||
| - [Textarea](#version-10x-textarea) | ||||||
| - [Thumbnail](#version-10x-thumbnail) | ||||||
| - [Title](#version-10x-title) | ||||||
| - [Toolbar](#version-10x-toolbar) | ||||||
| - [Framework Specific](#version-10x-framework-specific) | ||||||
| - [Angular](#version-10x-angular) | ||||||
|
|
||||||
|
|
@@ -529,6 +531,72 @@ Use the **parent's** thumbnail tokens instead: | |||||
|
|
||||||
| Remove any instances that target the theme classes: `ion-thumbnail.md`, `ion-thumbnail.ios`. | ||||||
|
|
||||||
| <h4 id="version-10x-title">Title</h4> | ||||||
|
|
||||||
| The following breaking changes apply to `ion-title`: | ||||||
|
|
||||||
| 1. `--color` has been replaced. <sup>[1](#version-10x-title-replaced-css-variables)</sup> | ||||||
| 2. The color applied by the `color` prop is now driven by the centralized Ionic Theming system, scoped to the new `hue` property. <sup>[2](#version-10x-title-hue)</sup> | ||||||
| 3. The size classes now include the property name, and a title without `size` is now `medium`. <sup>[3](#version-10x-title-size-classes)</sup> | ||||||
| 4. The `title-rtl` class has been removed. <sup>[4](#version-10x-title-rtl-class)</sup> | ||||||
| 5. Theme classes (`ion-title.md`, `ion-title.ios`) are no longer supported. <sup>[5](#version-10x-title-theme-classes)</sup> | ||||||
|
|
||||||
| <h5 id="version-10x-title-replaced-css-variables">Replaced CSS variables</h5> | ||||||
|
|
||||||
| Use the new token structure for global styles, or the corresponding CSS variable for component-specific overrides: | ||||||
|
|
||||||
| | Old (9.x) | New token (global) | New CSS variable (component-specific) | | ||||||
| |---|---|---| | ||||||
| | `--color` | `IonTitle.color` | `--ion-title-color` | | ||||||
|
|
||||||
| <h5 id="version-10x-title-hue">New `hue` property and color tokens</h5> | ||||||
|
|
||||||
| A new `hue` property selects between vibrant and muted color variants. It defaults to `"bold"`, which preserves prior behavior when `color` is set. | ||||||
|
|
||||||
| When `color` is set, the title color now reads from a token instead of `--ion-color-base` directly. Global overrides should use the theme tokens; component-specific overrides use the corresponding CSS variables: | ||||||
|
|
||||||
| | Hue | Token (global) | CSS variable (component-specific) | | ||||||
| |---|---|---| | ||||||
| | `bold` | `IonTitle.hue.bold.semantic.default.color` | `--ion-title-hue-bold-semantic-default-color` | | ||||||
| | `subtle` | `IonTitle.hue.subtle.semantic.default.color` | `--ion-title-hue-subtle-semantic-default-color` | | ||||||
|
|
||||||
| <h5 id="version-10x-title-size-classes">Size classes</h5> | ||||||
|
|
||||||
| The classes `ion-title` adds for its size now include the property name. A title without `size` is now `medium`, which can also be set explicitly: | ||||||
|
|
||||||
| | Old (9.x) | New | | ||||||
| |---|---| | ||||||
| | `title-default` | `title-size-medium` | | ||||||
| | `title-small` | `title-size-small` | | ||||||
| | `title-large` | `title-size-large` | | ||||||
|
|
||||||
| `ion-toolbar` builds its own classes from these, so they change as well: | ||||||
|
|
||||||
| | Old (9.x) | New | | ||||||
| |---|---| | ||||||
| | `toolbar-title-default` | `toolbar-title-size-medium` | | ||||||
| | `toolbar-title-small` | `toolbar-title-size-small` | | ||||||
| | `toolbar-title-large` | `toolbar-title-size-large` | | ||||||
|
Comment on lines
+573
to
+579
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this go in toolbar's section instead? |
||||||
|
|
||||||
| <h5 id="version-10x-title-rtl-class">`title-rtl` class</h5> | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| `ion-title` no longer adds the `title-rtl` class. Use the `:dir(rtl)` pseudo-class instead: | ||||||
|
|
||||||
| ```diff | ||||||
| -ion-title.title-rtl { } | ||||||
| +ion-title:dir(rtl) { } | ||||||
| ``` | ||||||
|
|
||||||
| <h5 id="version-10x-title-theme-classes">Theme classes</h5> | ||||||
|
|
||||||
| Remove any instances that target the theme classes: `ion-title.md`, `ion-title.ios`. | ||||||
|
|
||||||
| <h4 id="version-10x-toolbar">Toolbar</h4> | ||||||
|
|
||||||
| The following breaking changes apply to `ion-toolbar`: | ||||||
|
|
||||||
| 1. The classes it adds for a slotted title's size now include the property name. <sup>[1](#version-10x-title-size-classes)</sup> | ||||||
|
|
||||||
| <h2 id="version-10x-framework-specific">Framework Specific</h2> | ||||||
|
|
||||||
| <h4 id="version-10x-angular">Angular</h4> | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,9 @@ | ||
| import { readTask, writeTask } from '@stencil/core'; | ||
| import { clamp } from '@utils/helpers'; | ||
|
|
||
| import { config } from '../../global/config'; | ||
| import type { IonTitleSize } from '../title/title.interface'; | ||
|
|
||
| const TRANSITION = 'all 0.2s ease-in-out'; | ||
| const ROLE_NONE = 'none'; | ||
| const ROLE_BANNER = 'banner'; | ||
|
|
@@ -211,11 +214,27 @@ export const setHeaderActive = (headerIndex: HeaderIndex, active = true) => { | |
| } | ||
| }; | ||
|
|
||
| /** | ||
| * Checks the `size` prop, then the attribute (the header can render before | ||
| * the title is defined), then the `IonTitle.size` config. | ||
| * | ||
| * @internal | ||
| * @param ionTitleEl - The title to check. | ||
| * @returns Whether the title is large. | ||
| */ | ||
| export const isLargeTitle = (ionTitleEl: HTMLIonTitleElement) => { | ||
| const attributeSize = ionTitleEl.getAttribute('size') as IonTitleSize | null; | ||
| const configSize = config.getObjectValue('IonTitle.size') as IonTitleSize | undefined; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking, possible follow-up for FW-6843
Could the header migration work out the collapsing title from where it sits rather than from its size? For example, treat the title inside This wouldn't break anything: |
||
| const size = ionTitleEl.size ?? attributeSize ?? configSize; | ||
|
|
||
| return size === 'large'; | ||
| }; | ||
|
|
||
| export const scaleLargeTitles = (toolbars: ToolbarIndex[] = [], scale = 1, transition = false) => { | ||
| toolbars.forEach((toolbar) => { | ||
| const ionTitle = toolbar.ionTitleEl; | ||
| const titleDiv = toolbar.innerTitleEl; | ||
| if (!ionTitle || ionTitle.size !== 'large') { | ||
| if (!ionTitle || !isLargeTitle(ionTitle)) { | ||
| return; | ||
| } | ||
|
|
||
|
|
||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The title in this snapshot now follows the page's md theme instead of the header's |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { newSpecPage } from '@stencil/core/testing'; | ||
|
|
||
| import { config } from '../../../global/config'; | ||
| import { ToolbarTitle } from '../../title/title'; | ||
| import { Header } from '../header'; | ||
|
|
||
| describe('header: condense', () => { | ||
| afterEach(() => { | ||
| config.reset({}); | ||
| }); | ||
|
|
||
| it('should condense when the title size is large', async () => { | ||
| const page = await newSpecPage({ | ||
| components: [Header, ToolbarTitle], | ||
| html: `<ion-header scroll-effect="condense"><ion-title size="large">Title</ion-title></ion-header>`, | ||
| }); | ||
|
|
||
| expect(page.root!.classList.contains('header-collapse-condense')).toBe(true); | ||
| }); | ||
|
|
||
| it('should condense when the config sets a large title size', async () => { | ||
| config.reset({ | ||
| customTheme: { config: { components: { IonTitle: { size: 'large' } } } }, | ||
| }); | ||
|
|
||
| const page = await newSpecPage({ | ||
| components: [Header, ToolbarTitle], | ||
| html: `<ion-header scroll-effect="condense"><ion-title>Title</ion-title></ion-header>`, | ||
| }); | ||
|
|
||
| expect(page.root!.classList.contains('header-collapse-condense')).toBe(true); | ||
| }); | ||
|
|
||
| it('should hide the header when the title is not large', async () => { | ||
| const page = await newSpecPage({ | ||
| components: [Header, ToolbarTitle], | ||
| html: `<ion-header scroll-effect="condense"><ion-title>Title</ion-title></ion-header>`, | ||
| }); | ||
|
|
||
| expect(page.root!.classList.contains('header-collapse-condense')).toBe(false); | ||
| expect(page.root!.classList.contains('header-collapse-condense-hidden')).toBe(true); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.