Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver
- [Datetime](#version-10x-datetime)
- [Grid](#version-10x-grid)
- [Input Otp](#version-10x-input-otp)
- [Label](#version-10x-label)
- [Radio Group](#version-10x-radio-group)
- [Textarea](#version-10x-textarea)
- [Framework Specific](#version-10x-framework-specific)
Expand Down Expand Up @@ -223,6 +224,44 @@ Converted `ion-input-otp` to use [Shadow DOM](https://developer.mozilla.org/en-U

If you were targeting the internals of `ion-input-otp` in your CSS, you will need to target the `group`, `container`, `native`, `separator` or `description` [Shadow Parts](https://ionicframework.com/docs/theming/css-shadow-parts) instead, or use the provided CSS Variables.

<h4 id="version-10x-label">Label</h4>

Converted `ion-label` to use [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).

`ion-label` does not render any internal elements, so there are no Shadow Parts to target. However, the following changes may affect existing styles:

- The default heading (`h1` - `h6`) and paragraph (`p`) styles now only apply to elements that are direct children of `ion-label`. Headings and paragraphs nested inside another element, such as `ion-text`, no longer receive the label styles, and nested headings receive the global typography styles instead. To color the label text and headings, set the `color` property on `ion-label`. To color a paragraph or only part of the label, move `ion-text` inside the heading or paragraph:

```diff
<ion-label>
- <ion-text color="primary">
- <h3>Title</h3>
- </ion-text>
+ <h3><ion-text color="primary">Title</ion-text></h3>
<p>Description</p>
</ion-label>
```
- Global element styles for headings and paragraphs, such as `h2 { font-size: 20px; }`, now take precedence over the default label styles for those elements. Previously, the label styles took precedence. To keep the label styles, scope the global styles so they do not match elements inside `ion-label`.

```diff
- h2 {
+ h2:not(ion-label > h2) {
font-size: 20px;
}
```

The `:not()` selector increases the specificity of the global style. To keep the original specificity, wrap the exclusion in `:where()`:

```css
h2:where(:not(ion-label > h2)) {
font-size: 20px;
}
```

Complex selectors inside `:not()` require Chrome 88+, Firefox 84+ and Safari 9+, and `:where()` requires Chrome 88+, Firefox 78+ and Safari 14+.
- The global typography styles in `typography.css` no longer apply to headings that are direct children of `ion-label`. These headings are styled by `ion-label` instead.
- App styles that target `ion-label` directly now take precedence over the default `ion-label` styles. For example, a class that sets `color` on an `ion-label` inside of an `ion-item` previously had no effect because the label applied `var(--color)`, and it now changes the label color. Remove these styles if they are no longer wanted, or use the `--color` CSS variable to set the color of a label inside of an item.

<h4 id="version-10x-radio-group">Radio Group</h4>

Converted `ion-radio-group` to use [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM).
Expand Down
2 changes: 1 addition & 1 deletion core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1369,7 +1369,7 @@ ion-item-sliding,method,getSlidingRatio,getSlidingRatio() => Promise<number>
ion-item-sliding,method,open,open(side: Side | undefined) => Promise<void>
ion-item-sliding,event,ionDrag,any,true

ion-label,scoped
ion-label,shadow
ion-label,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-label,prop,mode,"ios" | "md",undefined,false,false
ion-label,prop,position,"fixed" | "floating" | "stacked" | undefined,undefined,false,false
Expand Down
27 changes: 27 additions & 0 deletions core/src/components/item/item.common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@
pointer-events: none;
}

:host(.item-interactive-disabled:not(.item-multiple-inputs)) ::slotted(ion-label) {
opacity: 0.3;
}

:host(.item-disabled) {
cursor: default;
opacity: 0.3;
Expand Down Expand Up @@ -314,6 +318,29 @@ a {
max-width: 100%;
}

/**
* Item styles win over the label's own styles when both target the
* same property, so positioned labels need their sizing set here
* to override the slotted label sizing above.
*/
::slotted(ion-label.label-fixed) {
flex: 0 0 100px;

width: 100px;
max-width: 200px;
}

::slotted(ion-label.label-stacked),
::slotted(ion-label.label-floating) {
width: auto;
}

// Overflow hidden is required for the proper
// margins between skeleton text elements
:host(.item-skeleton-text) ::slotted(ion-label) {
overflow: hidden;
}

// Item Input
// --------------------------------------------------

Expand Down
8 changes: 8 additions & 0 deletions core/src/components/item/item.ios.scss
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@
@include margin(10px, 8px, 10px, 0);
}

::slotted(ion-label.label-stacked) {
@include margin(null, null, 4px, null);
}

::slotted(ion-label.label-floating) {
@include margin(null, null, 0, null);
}

// iOS Stacked & Floating Inputs
// --------------------------------------------------

Expand Down
9 changes: 6 additions & 3 deletions core/src/components/item/item.md.scss
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,11 @@
// Material Design Floating/Stacked Label
// --------------------------------------------------

::slotted(ion-label.label-stacked),
::slotted(ion-label.label-floating) {
@include margin(0, 0, 0, 0);
}

:host(.item-label-stacked) ::slotted([slot="end"]),
:host(.item-label-floating) ::slotted([slot="end"]) {
@include margin(
Expand Down Expand Up @@ -254,8 +259,6 @@
}

:host(.ion-focused:not(.ion-color)) ::slotted(.label-stacked),
:host(.ion-focused:not(.ion-color)) ::slotted(.label-floating),
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-stacked),
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-floating) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The item-has-focus class was removed from item in v8 when we removed the legacy input support so these lines can be deleted:

:host(.ion-focused:not(.ion-color)) ::slotted(.label-floating) {
color: $label-md-text-color-focused;
}
8 changes: 2 additions & 6 deletions core/src/components/item/test/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,9 @@ <h2>H2 Title Text</h2>

<ion-item>
<ion-label>
<ion-text color="primary">
<h3>H3 Title Text</h3>
</ion-text>
<h3><ion-text color="primary">H3 Title Text</ion-text></h3>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In shadow DOM, label's ::slotted() styles only reach its direct children, so a heading nested inside ion-text loses label's heading styles and gets the global typography instead. Moving ion-text inside the heading keeps the h3 a direct child, so it still gets label's styles. This is documented in BREAKING.md.

<p>Paragraph line 1</p>
<ion-text color="secondary">
<p>Paragraph line 2 secondary</p>
</ion-text>
<p><ion-text color="secondary">Paragraph line 2 secondary</ion-text></p>
</ion-label>
</ion-item>

Expand Down

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 3px comes from the markup change, not the shadow conversion. The h3 used to be the only child of ion-text, so iOS's h3:last-child { margin-bottom: 0 } applied. Shadow DOM can only style direct children, so it's now <h3><ion-text>…</ion-text></h3>. It's no longer a last child, so it keeps its 3px bottom margin. The scoped label renders this markup identically.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 3 additions & 9 deletions core/src/components/item/test/colors/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@
<ion-label>
<h1>Heading</h1>
<p>Paragraph</p>
<ion-text color="secondary">
<p>Secondary paragraph</p>
</ion-text>
<p><ion-text color="secondary">Secondary paragraph</ion-text></p>
</ion-label>
</ion-item>

Expand Down Expand Up @@ -73,9 +71,7 @@ <h1>Heading</h1>
</ion-button>
<ion-label>
left icon buttons
<ion-text color="primary">
<p>Primary paragraph</p>
</ion-text>
<p><ion-text color="primary">Primary paragraph</ion-text></p>
</ion-label>
</ion-item>

Expand All @@ -86,9 +82,7 @@ <h1>Heading</h1>
</ion-button>
<ion-label>
disabled left icon buttons
<ion-text color="primary">
<p>Primary paragraph</p>
</ion-text>
<p><ion-text color="primary">Primary paragraph</ion-text></p>
</ion-label>
</ion-item>

Expand Down
8 changes: 2 additions & 6 deletions core/src/components/item/test/dividers/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@
<ion-item-group>
<ion-item>
<ion-label>
<ion-text color="secondary">
<h3>Secondary header</h3>
</ion-text>
<h3><ion-text color="secondary">Secondary header</ion-text></h3>
Plain Ol' div with some text
</ion-label>
</ion-item>
Expand Down Expand Up @@ -81,9 +79,7 @@ <h3>Secondary header</h3>

<ion-label>
Dark
<ion-text color="primary">
<h5>Primary h5</h5>
</ion-text>
<h5><ion-text color="primary">Primary h5</ion-text></h5>
</ion-label>
</ion-item-divider>

Expand Down
8 changes: 2 additions & 6 deletions core/src/components/item/test/theme-ionic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,9 @@ <h2>H2 Title Text</h2>

<ion-item>
<ion-label>
<ion-text color="primary">
<h3>H3 Title Text</h3>
</ion-text>
<h3><ion-text color="primary">H3 Title Text</ion-text></h3>
<p>Paragraph line 1</p>
<ion-text color="secondary">
<p>Paragraph line 2 secondary</p>
</ion-text>
<p><ion-text color="secondary">Paragraph line 2 secondary</ion-text></p>
</ion-label>
</ion-item>

Expand Down
54 changes: 20 additions & 34 deletions core/src/components/label/label.ios.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,47 +22,35 @@
:host(.label-floating) {
@include margin(null, null, 0, null);
@include transform(translate(0, 29px));
@include transform-origin(start, top);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was moved to label.scss.


transition: transform 150ms ease-in-out;
}

:host-context(.item-textarea).label-floating {
@include transform(translate(0, 28px));
}

:host-context(.item-has-focus).label-stacked,
:host-context(.item-has-focus).label-floating {
color: $label-ios-text-color-focused;
}

:host-context(.item-has-focus).label-floating,
:host-context(.item-has-placeholder:not(.item-input)).label-floating,
:host-context(.item-has-value).label-floating {
@include transform(scale(0.82));
}

// iOS Typography
// --------------------------------------------------

::slotted(*) h1 {
::slotted(h1) {
@include margin(3px, 0, 2px);

font-size: dynamic-font(22px);
font-weight: normal;

line-height: 1.2;
}

::slotted(*) h2 {
::slotted(h2) {
@include margin(0, 0, 2px);

font-size: dynamic-font(17px);
font-weight: normal;

line-height: 1.2;
}

::slotted(*) h3,
::slotted(*) h4,
::slotted(*) h5,
::slotted(*) h6 {
::slotted(h3),
::slotted(h4),
::slotted(h5),
::slotted(h6) {
@include margin(0, 0, 3px);

font-size: dynamic-font(14px);
Expand All @@ -71,14 +59,16 @@
line-height: normal;
}

::slotted(*) p {
::slotted(p) {
@include margin(
$item-ios-paragraph-margin-top,
$item-ios-paragraph-margin-end,
$item-ios-paragraph-margin-bottom,
$item-ios-paragraph-margin-start
);

color: #{$item-ios-paragraph-text-color};

font-size: $item-ios-paragraph-font-size;

line-height: normal;
Expand All @@ -88,19 +78,15 @@
overflow: inherit;
}

::slotted(p) {
color: #{$item-ios-paragraph-text-color};
}

:host(.in-item-color)::slotted(p) {
:host(.in-item-color) ::slotted(p) {
color: inherit;
}

::slotted(*) h2:last-child,
::slotted(*) h3:last-child,
::slotted(*) h4:last-child,
::slotted(*) h5:last-child,
::slotted(*) h6:last-child,
::slotted(*) p:last-child {
::slotted(h2:last-child),
::slotted(h3:last-child),
::slotted(h4:last-child),
::slotted(h5:last-child),
::slotted(h6:last-child),
::slotted(p:last-child) {
@include margin(null, null, 0, null);
}
3 changes: 0 additions & 3 deletions core/src/components/label/label.ios.vars.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
// iOS Label
// --------------------------------------------------

/// @prop - Text color of the stacked/floating label when it is focused
$label-ios-text-color-focused: null;

/// @prop - Font size of the label when the text wraps
$label-ios-text-wrap-font-size: dynamic-font(14px);

Expand Down
Loading
Loading