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
28 changes: 28 additions & 0 deletions BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver
- [Menu Toggle](#version-9x-menu-toggle)
- [Radio Group](#version-9x-radio-group)
- [Row](#version-9x-row)
- [Skeleton Text](#version-9x-skeleton-text)
- [Spinner](#version-9x-spinner)
- [Text](#version-9x-text)
- [Textarea](#version-9x-textarea)
Expand Down Expand Up @@ -362,6 +363,33 @@ The following breaking changes apply to `ion-row`:

Remove any instances that target the theme classes: `ion-row.md`, `ion-row.ios`.

<h4 id="version-9x-skeleton-text">Skeleton Text</h4>

The following breaking changes apply to `ion-skeleton-text`:

1. `--background` and `--background-rgb` CSS variables have been replaced with per-state background tokens, each split into an RGB value and an alpha. <sup>[1](#version-9x-skeleton-text-replaced-css-variables)</sup>
2. `--border-radius` has been replaced. <sup>[1](#version-9x-skeleton-text-replaced-css-variables)</sup>
3. Theme classes (`ion-skeleton-text.md`, `ion-skeleton-text.ios`) are no longer supported. <sup>[2](#version-9x-skeleton-text-theme-classes)</sup>

<h5 id="version-9x-skeleton-text-replaced-css-variables">Replaced CSS variables</h5>

The background is now defined per state (resting and animated), and each state exposes an RGB value plus an alpha so the color and its opacity can be set independently. Use the new token structure for global styles, or the corresponding CSS variable for component-specific overrides:

| Old (8.x) | New token (global) | New CSS variable (component-specific) |
|---|---|---|
| `--background-rgb` | `IonSkeletonText.default.background.rgb` | `--ion-skeleton-text-default-background-rgb` |
| `--background-rgb` | `IonSkeletonText.animated.background.rgb` | `--ion-skeleton-text-animated-background-rgb` |
| `--border-radius` | `IonSkeletonText.border.radius` | `--ion-skeleton-text-border-radius` |

The previously fixed opacities are now adjustable through new per-state alpha tokens (`IonSkeletonText.default.background.alpha` / `--ion-skeleton-text-default-background-alpha`, and the `animated` equivalents).

> [!NOTE]
> `--background` (the resting color) has been removed with no one-to-one replacement; set `--ion-skeleton-text-default-background-rgb` (and optionally `--ion-skeleton-text-default-background-alpha`) instead. The single `--background-rgb` variable previously tinted both the resting fill and the animated shimmer. It is now split per state, so set both `--ion-skeleton-text-default-background-rgb` and `--ion-skeleton-text-animated-background-rgb` to recolor both.

<h5 id="version-9x-skeleton-text-theme-classes">Theme classes</h5>

Remove any instances that target the theme classes: `ion-skeleton-text.md`, `ion-skeleton-text.ios`.

<h4 id="version-9x-spinner">Spinner</h4>

- Component CSS variables have been removed. The component now utilizes the centralized Ionic Theming system. Global updates should be managed via the theme tokens file, while component-specific overrides are handled through localized CSS variables.
Expand Down
12 changes: 8 additions & 4 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2595,10 +2595,14 @@ ion-select-option,prop,value,any,undefined,false,false
ion-skeleton-text,shadow
ion-skeleton-text,prop,animated,boolean,false,false,false
ion-skeleton-text,prop,mode,"ios" | "md",undefined,false,false
ion-skeleton-text,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-skeleton-text,css-prop,--background
ion-skeleton-text,css-prop,--background-rgb
ion-skeleton-text,css-prop,--border-radius
ion-skeleton-text,css-prop,--ion-skeleton-text-animated-background-alpha
ion-skeleton-text,css-prop,--ion-skeleton-text-animated-background-rgb
ion-skeleton-text,css-prop,--ion-skeleton-text-border-radius
ion-skeleton-text,css-prop,--ion-skeleton-text-default-background-alpha
ion-skeleton-text,css-prop,--ion-skeleton-text-default-background-rgb
ion-skeleton-text,css-prop,--ion-skeleton-text-line-height
ion-skeleton-text,css-prop,--ion-skeleton-text-margin-bottom
ion-skeleton-text,css-prop,--ion-skeleton-text-margin-top

ion-spinner,shadow
ion-spinner,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
Expand Down
8 changes: 0 additions & 8 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3891,10 +3891,6 @@ export namespace Components {
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
}
interface IonSpinner {
/**
Expand Down Expand Up @@ -9982,10 +9978,6 @@ declare namespace LocalJSX {
* Emitted when the styles change.
*/
"onIonStyle"?: (event: IonSkeletonTextCustomEvent<StyleEventDetail>) => void;
/**
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
}
interface IonSpinner {
/**
Expand Down
4 changes: 4 additions & 0 deletions core/src/components/avatar/avatar.common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@

overflow: hidden;
}

::slotted(ion-skeleton-text) {
@include border-radius(var(--border-radius, revert-layer));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This will eventually look like @include border-radius(var(--ion-avatar-border-radius, revert-layer)); when avatar is migrated.

}
31 changes: 31 additions & 0 deletions core/src/components/skeleton-text/skeleton-text.interface.ts

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I decided to split the background into two states and also introduced alpha. This would allow further flexibility for devs to customize their skeletons.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { IonMargin } from '../../themes/themes.interfaces';

export type IonSkeletonTextRecipe = {
animated?: {
background?: {
/** Opacity of the animated shimmer highlight, from 0 to 1. */
alpha?: string | number;

/** Highlight color of the animated shimmer, in RGB format (e.g. `255, 0, 0`). */
rgb?: string;
};
};

border?: {
radius?: string;
};

default?: {
background?: {
/** Opacity of the background when it's not being animated, from 0 to 1. */
alpha?: string | number;

/** Background color when it's not being animated in RGB format (e.g. `255, 0, 0`), also the base of the animated shimmer. */
rgb?: string;
};
};

lineHeight?: string;

margin?: Omit<IonMargin, 'end' | 'start'>;
};
57 changes: 38 additions & 19 deletions core/src/components/skeleton-text/skeleton-text.scss
Original file line number Diff line number Diff line change
@@ -1,30 +1,54 @@
@import "./skeleton-text.vars";
@use "../../themes/mixins" as mixins;

// Skeleton Text
// Skeleton Text: Common Styles
// --------------------------------------------------

// RGB fallback used when no theme provides the skeleton's background
$background-rgb-fallback: var(--ion-text-color-rgb, 0, 0, 0);

// Alpha fallbacks, used when no theme provides them
$default-alpha-fallback: 0.065;
$animated-alpha-fallback: 0.135;

// Resting color, also the base/edge stops of the animated shimmer
$background-default: rgba(
var(--ion-skeleton-text-default-background-rgb, $background-rgb-fallback),
var(--ion-skeleton-text-default-background-alpha, $default-alpha-fallback)
);

// Highlight color of the animated shimmer
$background-animated: rgba(
var(--ion-skeleton-text-animated-background-rgb, $background-rgb-fallback),
var(--ion-skeleton-text-animated-background-alpha, $animated-alpha-fallback)
);

:host {
/**
* @prop --background: Background of the skeleton text
* @prop --background-rgb: Background of the skeleton text in rgb format
* @prop --ion-skeleton-text-default-background-rgb: Background color when it's not being animated in RGB format (e.g. `255, 0, 0`), also the base of the animated shimmer
* @prop --ion-skeleton-text-default-background-alpha: Opacity of the background when it's not being animated, from 0 to 1
*
* @prop --border-radius: Border radius of the skeleton text
* @prop --ion-skeleton-text-animated-background-rgb: Highlight color of the animated shimmer in RGB format (e.g. `255, 0, 0`)
* @prop --ion-skeleton-text-animated-background-alpha: Opacity of the animated shimmer highlight, from 0 to 1
*
* @prop --ion-skeleton-text-border-radius: Border radius of the skeleton text
* @prop --ion-skeleton-text-line-height: Line height of the skeleton text
*
* @prop --ion-skeleton-text-margin-top: Top margin of the skeleton text
* @prop --ion-skeleton-text-margin-bottom: Bottom margin of the skeleton text
*/
--background: #{$skeleton-text-background};

@include border-radius(var(--border-radius, inherit));
@include mixins.border-radius(var(--ion-skeleton-text-border-radius, inherit));

display: block;

width: 100%;
height: inherit;

margin-top: 4px;
margin-bottom: 4px;
margin-top: var(--ion-skeleton-text-margin-top);
margin-bottom: var(--ion-skeleton-text-margin-bottom);

background: var(--background);
background: $background-default;

line-height: 10px;
line-height: var(--ion-skeleton-text-line-height);

user-select: none;

Expand All @@ -36,7 +60,7 @@ span {
}

:host(.in-media) {
@include margin(0);
@include mixins.margin(0);

height: 100%;
}
Expand All @@ -47,12 +71,7 @@ span {
:host(.skeleton-text-animated) {
position: relative;

background: linear-gradient(
to right,
$skeleton-text-background 8%,
$skeleton-text-background-animated 18%,
$skeleton-text-background 33%
);
background: linear-gradient(to right, $background-default 8%, $background-animated 18%, $background-default 33%);
background-size: 800px 104px;
animation-duration: 1s;
animation-fill-mode: forwards;
Expand Down
11 changes: 4 additions & 7 deletions core/src/components/skeleton-text/skeleton-text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import { Component, Element, Event, Host, Prop, h } from '@stencil/core';
import { hostContext } from '@utils/theme';

import { config } from '../../global/config';
import { getIonTheme } from '../../global/ionic-global';
import type { StyleEventDetail } from '../../interface';

/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the visual appearance of the component.
*/
@Component({
tag: 'ion-skeleton-text',
Expand All @@ -34,9 +32,10 @@ export class SkeletonText implements ComponentInterface {
}

private emitStyle() {
// The emitted property is used by item in order
// to add the item-skeleton-text class which applies
// overflow: hidden to its label
/*
* The emitted property is used by `ion-item` in order to add the
* `.item-skeleton-text` class which applies styles to `ion-label`.
*/
const style: StyleEventDetail = {
'skeleton-text': true,
};
Expand All @@ -47,12 +46,10 @@ export class SkeletonText implements ComponentInterface {
render() {
const animated = this.animated && config.getBoolean('animated', true);
const inMedia = hostContext('ion-avatar', this.el) || hostContext('ion-thumbnail', this.el);
const theme = getIonTheme(this);

return (
<Host
class={{
[theme]: true,
'skeleton-text-animated': animated,
'in-media': inMedia,
}}
Expand Down
19 changes: 0 additions & 19 deletions core/src/components/skeleton-text/skeleton-text.vars.scss

This file was deleted.

Loading
Loading