From 20a4a3370c5e6f2e784b71869f0990b41f6d35b5 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Wed, 11 Mar 2026 16:15:19 -0700 Subject: [PATCH] feat(item-divider): add recipe and tokens --- .../item-divider/item-divider.ios.scss | 5 +- .../item-divider/item-divider.md.scss | 16 +- .../components/item-divider/item-divider.scss | 337 ++++++++++++++++-- .../components/item-divider/item-divider.tsx | 7 +- core/src/components/thumbnail/thumbnail.scss | 5 +- core/src/themes/ionic/default.tokens.ts | 284 ++++++++++++++- core/src/themes/ionic/shared.tokens.ts | 159 +++++++++ core/src/themes/ios/default.tokens.ts | 186 +++++++++- core/src/themes/ios/shared.tokens.ts | 84 +++++ core/src/themes/md/default.tokens.ts | 291 ++++++++++++++- core/src/themes/md/shared.tokens.ts | 162 +++++++++ core/src/themes/themes.interfaces.ts | 1 + core/src/utils/theme.ts | 19 + 13 files changed, 1505 insertions(+), 51 deletions(-) create mode 100644 core/src/themes/ionic/shared.tokens.ts create mode 100644 core/src/themes/ios/shared.tokens.ts create mode 100644 core/src/themes/md/shared.tokens.ts diff --git a/core/src/components/item-divider/item-divider.ios.scss b/core/src/components/item-divider/item-divider.ios.scss index d6d9007011..66f09e7bae 100644 --- a/core/src/components/item-divider/item-divider.ios.scss +++ b/core/src/components/item-divider/item-divider.ios.scss @@ -12,7 +12,7 @@ @include border-radius(0); - position: relative; + position: relative; // doesn't seem to be needed?, no issues with it being missing for sticky min-height: $item-divider-ios-min-height; @@ -33,6 +33,7 @@ ); } +// all of these are null :host([slot="end"]) { @include margin( $item-ios-slot-end-margin-top, @@ -82,7 +83,7 @@ font-size: $item-ios-paragraph-font-size; - line-height: normal; + line-height: normal; // not needed since it's the default text-overflow: inherit; diff --git a/core/src/components/item-divider/item-divider.md.scss b/core/src/components/item-divider/item-divider.md.scss index 02ead8975e..f78959f15e 100644 --- a/core/src/components/item-divider/item-divider.md.scss +++ b/core/src/components/item-divider/item-divider.md.scss @@ -11,22 +11,26 @@ --padding-start: #{$item-divider-md-padding-start}; --inner-padding-end: #{$item-divider-md-padding-end}; - min-height: $item-divider-md-min-height; + min-height: $item-divider-md-min-height; // for ionic this should be the default - border-bottom: $item-divider-md-border-bottom; + border-bottom: $item-divider-md-border-bottom; // for ionic this should be null - font-size: dynamic-font($item-divider-md-font-size); + font-size: dynamic-font($item-divider-md-font-size); // for ionic this should be the default } // Material Design Item Divider Slots // -------------------------------------------------- ::slotted([slot="start"]) { - @include margin-horizontal($item-md-start-slot-margin-start, $item-md-start-slot-margin-end); + @include margin-horizontal( + $item-md-start-slot-margin-start, + //null + $item-md-start-slot-margin-end + ); // for ionic this should be 0 } ::slotted([slot="end"]) { - @include margin-horizontal($item-md-end-slot-margin-start, $item-md-end-slot-margin-end); + @include margin-horizontal($item-md-end-slot-margin-start, $item-md-end-slot-margin-end); //null } // Material Design Slotted Label @@ -52,7 +56,7 @@ } :host(.ion-color) ::slotted(ion-icon) { - color: current-color(contrast); + color: current-color(contrast); // for ionic this should be currentColor, inherit } ::slotted(ion-icon[slot]) { diff --git a/core/src/components/item-divider/item-divider.scss b/core/src/components/item-divider/item-divider.scss index aaae4b93d4..2a3e63fa8f 100644 --- a/core/src/components/item-divider/item-divider.scss +++ b/core/src/components/item-divider/item-divider.scss @@ -1,6 +1,7 @@ -@import "../../themes/native/native.globals"; +@use "../../themes/mixins" as mixins; +@use "../../themes/functions.color" as colors; -// Item Divider +// Item Divider: Common Styles // -------------------------------------------------- :host { @@ -19,26 +20,29 @@ * @prop --inner-padding-bottom: Bottom inner padding of the item divider * @prop --inner-padding-start: Start inner padding of the item divider */ - --padding-top: 0px; - --padding-end: 0px; - --padding-bottom: 0px; - --padding-start: 0px; - --inner-padding-top: 0px; - --inner-padding-end: 0px; - --inner-padding-bottom: 0px; - --inner-padding-start: 0px; + --background: var(--ion-item-divider-background); + --color: var(--ion-item-divider-color); + --padding-top: var(--ion-item-divider-padding-top); + --padding-end: var(--ion-item-divider-padding-end); + --padding-bottom: var(--ion-item-divider-padding-bottom); + --padding-start: var(--ion-item-divider-padding-start); + --inner-padding-top: var(--ion-item-divider-inner-padding-top); + --inner-padding-end: var(--ion-item-divider-inner-padding-end); + --inner-padding-bottom: var(--ion-item-divider-inner-padding-bottom); + --inner-padding-start: var(--ion-item-divider-inner-padding-start); - @include font-smoothing(); - @include margin(0); - @include padding(var(--padding-top), null, var(--padding-bottom), null); + @include mixins.font-smoothing(); + @include mixins.margin(0); + @include mixins.padding(var(--padding-top), null, var(--padding-bottom), null); + @include mixins.border-radius(0); /* stylelint-disable */ - @include ltr() { + @include mixins.ltr() { padding-right: var(--padding-end); padding-left: calc(var(--padding-start) + var(--ion-safe-area-left, 0px)); } - @include rtl() { + @include mixins.rtl() { padding-right: calc(var(--padding-start) + var(--ion-safe-area-right, 0px)); padding-left: var(--padding-end); } @@ -51,19 +55,26 @@ width: 100%; + min-height: var(--ion-item-divider-min-height); + + border-bottom: var(--ion-item-divider-border-bottom); + background: var(--background); color: var(--color); - font-family: $font-family-base; + font-family: var(--ion-font-family, inherit); + font-size: var(--ion-item-divider-font-size); + font-weight: var(--ion-item-divider-font-weight); overflow: hidden; - z-index: $z-index-item-divider; + + z-index: var(--ion-item-divider-z-index, auto); box-sizing: border-box; } :host(.ion-color) { - background: current-color(base); - color: current-color(contrast); + background: colors.current-color("base"); + color: colors.current-color("contrast"); } :host(.item-divider-sticky) { @@ -72,16 +83,16 @@ } .item-divider-inner { - @include margin(0); - @include padding(var(--inner-padding-top), null, var(--inner-padding-bottom), null); + @include mixins.margin(0); + @include mixins.padding(var(--inner-padding-top), null, var(--inner-padding-bottom), null); /* stylelint-disable */ - @include ltr() { + @include mixins.ltr() { padding-right: calc(var(--ion-safe-area-right, 0px) + var(--inner-padding-end)); padding-left: var(--inner-padding-start); } - @include rtl() { + @include mixins.rtl() { padding-right: var(--inner-padding-start); padding-left: calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end)); } @@ -113,3 +124,283 @@ overflow: hidden; } + +// Item Divider Slots +// -------------------------------------------------- + +:host([slot="start"]) { + @include mixins.margin( + var(--ion-item-divider-leading-anchor-margin-top, revert-layer), + var(--ion-item-divider-leading-anchor-margin-end, revert-layer), + var(--ion-item-divider-leading-anchor-margin-bottom, revert-layer), + var(--ion-item-divider-leading-anchor-margin-start, revert-layer) + ); +} + +::slotted([slot="start"]) { + @include mixins.margin-horizontal( + var(--ion-item-divider-leading-edge-margin-start, revert-layer), + var(--ion-item-divider-leading-edge-margin-end, revert-layer) + ); // for ionic this should be 0 +} + +::slotted([slot="end"]) { + @include mixins.margin-horizontal( + var(--ion-item-divider-trailing-edge-margin-start, revert-layer), + var(--ion-item-divider-trailing-edge-margin-end, revert-layer) + ); +} + +// Slotted Label +// -------------------------------------------------- + +::slotted(ion-label) { + @include mixins.margin( + var(--ion-item-divider-label-margin-top), + var(--ion-item-divider-label-margin-end), + var(--ion-item-divider-label-margin-bottom), + var(--ion-item-divider-label-margin-start) + ); +} + +// Slotted Icon +// -------------------------------------------------- + +::slotted(ion-icon) { + color: var(--ion-item-divider-icon-default-color); + + font-size: var(--ion-item-divider-icon-font-size); +} + +:host(.ion-color) ::slotted(ion-icon) { + color: var(--ion-item-divider-icon-semantic-default-color); +} + +::slotted(ion-icon[slot="start"]) { + @include mixins.margin( + var(--ion-item-divider-icon-leading-edge-margin-top, revert-layer), + var(--ion-item-divider-icon-leading-edge-margin-end, revert-layer), + var(--ion-item-divider-icon-leading-edge-margin-bottom, revert-layer), + var(--ion-item-divider-icon-leading-edge-margin-start, revert-layer) + ); +} + +::slotted(ion-icon[slot="end"]) { + @include mixins.margin( + var(--ion-item-divider-icon-trailing-edge-margin-top, revert-layer), + var(--ion-item-divider-icon-trailing-edge-margin-end, revert-layer), + var(--ion-item-divider-icon-trailing-edge-margin-bottom, revert-layer), + var(--ion-item-divider-icon-trailing-edge-margin-start, revert-layer) + ); +} + +// Slotted Note +// -------------------------------------------------- + +::slotted(ion-note) { + @include mixins.margin( + var(--ion-item-divider-note-margin-top), + var(--ion-item-divider-note-margin-end), + var(--ion-item-divider-note-margin-bottom), + var(--ion-item-divider-note-margin-start) + ); + + align-self: flex-start; + + font-size: var(--ion-item-divider-note-font-size); +} + +::slotted(ion-note[slot]) { + @include mixins.padding( + var(--ion-item-divider-note-padding-top), + var(--ion-item-divider-note-padding-end), + var(--ion-item-divider-note-padding-bottom), + var(--ion-item-divider-note-padding-start) + ); +} + +// Slotted Avatar +// -------------------------------------------------- + +::slotted(ion-avatar) { + @include mixins.margin( + var(--ion-item-divider-avatar-margin-top), + var(--ion-item-divider-avatar-margin-end), + var(--ion-item-divider-avatar-margin-bottom), + var(--ion-item-divider-avatar-margin-start) + ); + + width: var(--ion-item-divider-avatar-width, revert-layer); + height: var(--ion-item-divider-avatar-height, revert-layer); +} + +::slotted(ion-avatar[slot="start"]) { + @include mixins.margin-horizontal( + var(--ion-item-divider-avatar-leading-edge-margin-start), + var(--ion-item-divider-avatar-leading-edge-margin-end) + ); +} + +::slotted(ion-avatar[slot="end"]) { + @include mixins.margin-horizontal( + var(--ion-item-divider-avatar-trailing-edge-margin-start), + var(--ion-item-divider-avatar-trailing-edge-margin-end) + ); +} + +// Slotted Thumbnail +// -------------------------------------------------- + +::slotted(ion-thumbnail) { + // TODO(): separate width and height tokens for thumbnails + --size: var(--ion-item-divider-thumbnail-width); + + @include mixins.margin( + var(--ion-item-divider-thumbnail-margin-top), + var(--ion-item-divider-thumbnail-margin-end), + var(--ion-item-divider-thumbnail-margin-bottom), + var(--ion-item-divider-thumbnail-margin-start) + ); +} + +::slotted(ion-thumbnail[slot="start"]) { + @include mixins.margin-horizontal( + var(--ion-item-divider-thumbnail-leading-edge-margin-start), + var(--ion-item-divider-thumbnail-leading-edge-margin-end) + ); +} + +::slotted(ion-thumbnail[slot="end"]) { + @include mixins.margin-horizontal( + var(--ion-item-divider-thumbnail-trailing-edge-margin-start), + var(--ion-item-divider-thumbnail-trailing-edge-margin-end) + ); +} + +// Slotted Content +// -------------------------------------------------- + +::slotted(h1) { + @include mixins.margin( + var(--ion-item-divider-header1-margin-top), + var(--ion-item-divider-header1-margin-end), + var(--ion-item-divider-header1-margin-bottom), + var(--ion-item-divider-header1-margin-start) + ); +} + +::slotted(h2) { + @include mixins.margin( + var(--ion-item-divider-header2-margin-top), + var(--ion-item-divider-header2-margin-end), + var(--ion-item-divider-header2-margin-bottom), + var(--ion-item-divider-header2-margin-start) + ); +} + +::slotted(h2:last-child) { + @include mixins.margin( + var(--ion-item-divider-header2-trailing-margin-top), + var(--ion-item-divider-header2-trailing-margin-end), + var(--ion-item-divider-header2-trailing-margin-bottom, 0), + var(--ion-item-divider-header2-trailing-margin-start) + ); +} + +::slotted(h3) { + @include mixins.margin( + var(--ion-item-divider-header3-margin-top), + var(--ion-item-divider-header3-margin-end), + var(--ion-item-divider-header3-margin-bottom), + var(--ion-item-divider-header3-margin-start) + ); +} + +::slotted(h3:last-child) { + @include mixins.margin( + var(--ion-item-divider-header3-trailing-margin-top), + var(--ion-item-divider-header3-trailing-margin-end), + var(--ion-item-divider-header3-trailing-margin-bottom, 0), + var(--ion-item-divider-header3-trailing-margin-start) + ); +} + +::slotted(h4) { + @include mixins.margin( + var(--ion-item-divider-header4-margin-top), + var(--ion-item-divider-header4-margin-end), + var(--ion-item-divider-header4-margin-bottom), + var(--ion-item-divider-header4-margin-start) + ); +} + +::slotted(h4:last-child) { + @include mixins.margin( + var(--ion-item-divider-header4-trailing-margin-top), + var(--ion-item-divider-header4-trailing-margin-end), + var(--ion-item-divider-header4-trailing-margin-bottom, 0), + var(--ion-item-divider-header4-trailing-margin-start) + ); +} + +::slotted(h5) { + @include mixins.margin( + var(--ion-item-divider-header5-margin-top), + var(--ion-item-divider-header5-margin-end), + var(--ion-item-divider-header5-margin-bottom), + var(--ion-item-divider-header5-margin-start) + ); +} + +::slotted(h5:last-child) { + @include mixins.margin( + var(--ion-item-divider-header5-trailing-margin-top), + var(--ion-item-divider-header5-trailing-margin-end), + var(--ion-item-divider-header5-trailing-margin-bottom, 0), + var(--ion-item-divider-header5-trailing-margin-start) + ); +} + +::slotted(h6) { + @include mixins.margin( + var(--ion-item-divider-header6-margin-top), + var(--ion-item-divider-header6-margin-end), + var(--ion-item-divider-header6-margin-bottom), + var(--ion-item-divider-header6-margin-start) + ); +} + +::slotted(h6:last-child) { + @include mixins.margin( + var(--ion-item-divider-header6-trailing-margin-top), + var(--ion-item-divider-header6-trailing-margin-end), + var(--ion-item-divider-header6-trailing-margin-bottom, 0), + var(--ion-item-divider-header6-trailing-margin-start) + ); +} + +::slotted(p) { + @include mixins.margin( + var(--ion-item-divider-paragraph-margin-top), + var(--ion-item-divider-paragraph-margin-end), + var(--ion-item-divider-paragraph-margin-bottom), + var(--ion-item-divider-paragraph-margin-start) + ); + + color: var(--ion-item-divider-paragraph-color); + + font-size: var(--ion-item-divider-paragraph-font-size); + + text-overflow: var(--ion-item-divider-paragraph-text-overflow); + + overflow: var(--ion-item-divider-paragraph-overflow); // native are the same, can ionic be the same? +} + +::slotted(p:last-child) { + @include mixins.margin( + var(--ion-item-divider-paragraph-trailing-margin-top), + var(--ion-item-divider-paragraph-trailing-margin-end), + var(--ion-item-divider-paragraph-trailing-margin-bottom, 0), + var(--ion-item-divider-paragraph-trailing-margin-start) + ); +} diff --git a/core/src/components/item-divider/item-divider.tsx b/core/src/components/item-divider/item-divider.tsx index 96198e6f1a..3f992ed2db 100644 --- a/core/src/components/item-divider/item-divider.tsx +++ b/core/src/components/item-divider/item-divider.tsx @@ -15,11 +15,7 @@ import type { Color } from '../../interface'; */ @Component({ tag: 'ion-item-divider', - styleUrls: { - ios: 'item-divider.ios.scss', - md: 'item-divider.md.scss', - ionic: 'item-divider.md.scss', - }, + styleUrl: 'item-divider.scss', shadow: true, }) export class ItemDivider implements ComponentInterface { @@ -43,6 +39,7 @@ export class ItemDivider implements ComponentInterface { render() { const theme = getIonTheme(this); + console.log('theme', theme); return ( { + return `${size / baselinePixelSize}${unit}`; +};