Compare commits

...

4 Commits

Author SHA1 Message Date
Brandy Smith
360fce73d4 chore: grab theme changes from next 2025-08-13 10:46:59 -04:00
Maria Hutt
8c21980a70 feat(theme): more changes 2025-08-12 15:50:23 -04:00
Maria Hutt
3c6bb9fb00 feat(core): component level theming 2025-08-12 15:50:11 -04:00
Maria Hutt
a130a4a63a feat(core): separate mode and theme 2025-08-12 15:48:22 -04:00
23 changed files with 1639 additions and 250 deletions

View File

@@ -1205,6 +1205,37 @@ ion-modal,part,backdrop
ion-modal,part,content
ion-modal,part,handle
ion-my-chip,shadow
ion-my-chip,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
ion-my-chip,prop,disabled,boolean,false,false,false
ion-my-chip,prop,hue,"bold" | "subtle" | undefined,'subtle',false,false
ion-my-chip,prop,mode,"ios" | "md",undefined,false,false
ion-my-chip,prop,outline,boolean,false,false,false
ion-my-chip,prop,shape,"rectangular" | "round" | "soft" | undefined,'soft',false,false
ion-my-chip,prop,size,"large" | "small" | undefined,'small',false,false
ion-my-chip,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-my-chip,css-prop,--ion-chip-border-width
ion-my-chip,css-prop,--ion-chip-focus-ring-color
ion-my-chip,css-prop,--ion-chip-focus-ring-width
ion-my-chip,css-prop,--ion-chip-font-weight
ion-my-chip,css-prop,--ion-chip-gap
ion-my-chip,css-prop,--ion-chip-hue-bold-bg
ion-my-chip,css-prop,--ion-chip-hue-bold-border-color
ion-my-chip,css-prop,--ion-chip-hue-bold-color
ion-my-chip,css-prop,--ion-chip-hue-subtle-bg
ion-my-chip,css-prop,--ion-chip-hue-subtle-border-color
ion-my-chip,css-prop,--ion-chip-hue-subtle-color
ion-my-chip,css-prop,--ion-chip-line-height
ion-my-chip,css-prop,--ion-chip-padding-horizontal
ion-my-chip,css-prop,--ion-chip-padding-vertical
ion-my-chip,css-prop,--ion-chip-shape-rectangular-border-radius
ion-my-chip,css-prop,--ion-chip-shape-round-border-radius
ion-my-chip,css-prop,--ion-chip-shape-soft-border-radius
ion-my-chip,css-prop,--ion-chip-size-large-font-size
ion-my-chip,css-prop,--ion-chip-size-large-min-height
ion-my-chip,css-prop,--ion-chip-size-small-font-size
ion-my-chip,css-prop,--ion-chip-size-small-min-height
ion-nav,shadow
ion-nav,prop,animated,boolean,true,false,false
ion-nav,prop,animation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
@@ -1231,6 +1262,7 @@ ion-nav,event,ionNavWillChange,void,false
ion-nav-link,none
ion-nav-link,prop,component,Function | HTMLElement | ViewController | null | string | undefined,undefined,false,false
ion-nav-link,prop,componentProps,undefined | { [key: string]: any; },undefined,false,false
ion-nav-link,prop,mode,"ios" | "md",undefined,false,false
ion-nav-link,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-nav-link,prop,routerDirection,"back" | "forward" | "root",'forward',false,false

View File

@@ -2072,6 +2072,45 @@ export namespace Components {
*/
"trigger": string | undefined;
}
interface IonMyChip {
/**
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
*/
"color"?: Color;
/**
* If `true`, the user cannot interact with the chip.
* @default false
*/
"disabled": boolean;
/**
* Set to `"bold"` for a chip with vibrant, bold colors or to `"subtle"` for a chip with muted, subtle colors. Only applies to the `ionic` theme.
* @default 'subtle'
*/
"hue"?: 'bold' | 'subtle';
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* Display an outline style button.
* @default false
*/
"outline": boolean;
/**
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully rounded corners, or `"rectangular"` for a chip without rounded corners. Defaults to `"round"` for the `"ionic"` theme and `"soft"` for all other themes.
* @default 'soft'
*/
"shape"?: 'soft' | 'round' | 'rectangular';
/**
* Set to `"small"` for a chip with less height and padding. Defaults to `"large"` for the ionic theme, and undefined for all other themes.
* @default 'small'
*/
"size"?: 'small' | 'large';
/**
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
}
interface IonNav {
/**
* If `true`, the nav should animate the transition of components.
@@ -2208,6 +2247,10 @@ export namespace Components {
* Data you want to pass to the component as props. Only used if the `"routerDirection"` is `"forward"` or `"root"`.
*/
"componentProps"?: ComponentProps;
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* The transition animation when navigating to another page.
*/
@@ -4535,6 +4578,12 @@ declare global {
prototype: HTMLIonModalElement;
new (): HTMLIonModalElement;
};
interface HTMLIonMyChipElement extends Components.IonMyChip, HTMLStencilElement {
}
var HTMLIonMyChipElement: {
prototype: HTMLIonMyChipElement;
new (): HTMLIonMyChipElement;
};
interface HTMLIonNavElementEventMap {
"ionNavWillLoad": void;
"ionNavWillChange": void;
@@ -5236,6 +5285,7 @@ declare global {
"ion-menu-button": HTMLIonMenuButtonElement;
"ion-menu-toggle": HTMLIonMenuToggleElement;
"ion-modal": HTMLIonModalElement;
"ion-my-chip": HTMLIonMyChipElement;
"ion-nav": HTMLIonNavElement;
"ion-nav-link": HTMLIonNavLinkElement;
"ion-note": HTMLIonNoteElement;
@@ -7375,6 +7425,45 @@ declare namespace LocalJSX {
*/
"trigger"?: string | undefined;
}
interface IonMyChip {
/**
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
*/
"color"?: Color;
/**
* If `true`, the user cannot interact with the chip.
* @default false
*/
"disabled"?: boolean;
/**
* Set to `"bold"` for a chip with vibrant, bold colors or to `"subtle"` for a chip with muted, subtle colors. Only applies to the `ionic` theme.
* @default 'subtle'
*/
"hue"?: 'bold' | 'subtle';
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* Display an outline style button.
* @default false
*/
"outline"?: boolean;
/**
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully rounded corners, or `"rectangular"` for a chip without rounded corners. Defaults to `"round"` for the `"ionic"` theme and `"soft"` for all other themes.
* @default 'soft'
*/
"shape"?: 'soft' | 'round' | 'rectangular';
/**
* Set to `"small"` for a chip with less height and padding. Defaults to `"large"` for the ionic theme, and undefined for all other themes.
* @default 'small'
*/
"size"?: 'small' | 'large';
/**
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
}
interface IonNav {
/**
* If `true`, the nav should animate the transition of components.
@@ -7420,6 +7509,10 @@ declare namespace LocalJSX {
* Data you want to pass to the component as props. Only used if the `"routerDirection"` is `"forward"` or `"root"`.
*/
"componentProps"?: ComponentProps;
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* The transition animation when navigating to another page.
*/
@@ -9166,6 +9259,7 @@ declare namespace LocalJSX {
"ion-menu-button": IonMenuButton;
"ion-menu-toggle": IonMenuToggle;
"ion-modal": IonModal;
"ion-my-chip": IonMyChip;
"ion-nav": IonNav;
"ion-nav-link": IonNavLink;
"ion-note": IonNote;
@@ -9269,6 +9363,7 @@ declare module "@stencil/core" {
"ion-menu-button": LocalJSX.IonMenuButton & JSXBase.HTMLAttributes<HTMLIonMenuButtonElement>;
"ion-menu-toggle": LocalJSX.IonMenuToggle & JSXBase.HTMLAttributes<HTMLIonMenuToggleElement>;
"ion-modal": LocalJSX.IonModal & JSXBase.HTMLAttributes<HTMLIonModalElement>;
"ion-my-chip": LocalJSX.IonMyChip & JSXBase.HTMLAttributes<HTMLIonMyChipElement>;
"ion-nav": LocalJSX.IonNav & JSXBase.HTMLAttributes<HTMLIonNavElement>;
"ion-nav-link": LocalJSX.IonNavLink & JSXBase.HTMLAttributes<HTMLIonNavLinkElement>;
"ion-note": LocalJSX.IonNote & JSXBase.HTMLAttributes<HTMLIonNoteElement>;

View File

@@ -0,0 +1,187 @@
@import "../../themes/ionic.functions.color";
@import "../../themes/ionic.mixins";
:host {
/**
* @prop --ion-chip-focus-ring-color: Color of the focus ring
* @prop --ion-chip-focus-ring-width: Width of the focus ring
* @prop --ion-chip-padding-horizontal: Padding top and bottom of the chip
* @prop --ion-chip-padding-vertical: Padding start and end of the chip
* @prop --ion-chip-font-weight: Font weight of the chip
* @prop --ion-chip-line-height: Line height of the chip
* @prop --ion-chip-gap: Gap between the chip and the text
* @prop --ion-chip-border-width: Border width of the chip
*
* @prop --ion-chip-shape-soft-border-radius: Border radius of the chip for the soft shape
* @prop --ion-chip-shape-round-border-radius: Border radius of the chip for the round shape
* @prop --ion-chip-shape-rectangular-border-radius: Border radius of the chip for the rectangular shape
*
* @prop --ion-chip-size-small-min-height: Minimum height of the chip for the small size
* @prop --ion-chip-size-large-min-height: Minimum height of the chip for the large size
* @prop --ion-chip-size-small-font-size: Font size of the chip for the small size
* @prop --ion-chip-size-large-font-size: Font size of the chip for the large size
*
* @prop --ion-chip-hue-subtle-bg: Background of the chip for the subtle hue
* @prop --ion-chip-hue-subtle-color: Color of the chip for the subtle hue
* @prop --ion-chip-hue-subtle-border-color: Border color of the chip for the subtle hue
* @prop --ion-chip-hue-bold-bg: Background of the chip for the bold hue
* @prop --ion-chip-hue-bold-color: Color of the chip for the bold hue
* @prop --ion-chip-hue-bold-border-color: Border color of the chip for the bold hue
*/
--ion-chip-focus-ring-color: var(--ion-color-blue-50);
--ion-chip-focus-ring-width: var(--ion-spacing-xs);
--ion-chip-padding-horizontal: var(--ion-spacing-xs);
--ion-chip-padding-vertical: var(--ion-spacing-sm);
--ion-chip-font-weight: var(--ion-font-weights-normal);
--ion-chip-line-height: var(--ion-line-heights-md);
--ion-chip-gap: var(--ion-spacing-xs);
--ion-chip-border-width: var(--ion-spacing-xxs);
--ion-chip-shape-soft-border-radius: var(--ion-radii-lg);
--ion-chip-shape-round-border-radius: var(--ion-radii-xxl);
--ion-chip-shape-rectangular-border-radius: var(--ion-radii-none);
--ion-chip-size-small-min-height: var(--ion-scaling-600);
--ion-chip-size-large-min-height: var(--ion-scaling-900);
--ion-chip-size-small-font-size: var(--ion-font-sizes-sm-rem);
--ion-chip-size-large-font-size: var(--ion-font-sizes-lg-rem);
--ion-chip-hue-subtle-bg: var(--ion-color-gray-100);
--ion-chip-hue-subtle-color: var(--ion-color-gray-800);
--ion-chip-hue-subtle-border-color: var(--ion-color-gray-300);
--ion-chip-hue-bold-bg: var(--ion-color-gray-700);
--ion-chip-hue-bold-color: var(--ion-color-white);
--ion-chip-hue-bold-border-color: var(--ion-color-gray-800);
@include font-smoothing();
@include padding(var(--ion-chip-padding-horizontal), var(--ion-chip-padding-vertical));
@include border-radius(var(--ion-chip-border-radius));
display: inline-flex;
position: relative;
align-items: center;
justify-content: center;
background: var(--ion-chip-background);
color: var(--ion-chip-color);
cursor: pointer;
font-weight: var(--ion-chip-font-weight);
line-height: var(--ion-chip-line-height);
gap: var(--ion-chip-gap);
overflow: hidden;
box-sizing: border-box;
vertical-align: middle;
}
:host(.chip-disabled) {
cursor: default;
pointer-events: none;
}
// Outline Chip
// ---------------------------------------------
:host(.chip-outline) {
border-width: var(--ion-chip-border-width);
border-style: solid; // Do we need to use a variable here? ionic uses tokens but all themes use solid so it's not really necessary
}
// Chip Shapes
// ---------------------------------------------
:host(.chip-soft) {
--ion-chip-border-radius: var(--ion-chip-shape-soft-border-radius);
}
:host(.chip-round) {
--ion-chip-border-radius: var(--ion-chip-shape-round-border-radius);
}
:host(.chip-rectangular) {
--ion-chip-border-radius: var(--ion-chip-shape-rectangular-border-radius);
}
// Size
// ---------------------------------------------
:host(.chip-small) {
min-height: var(--ion-chip-size-small-min-height);
font-size: var(--ion-chip-size-small-font-size);
}
:host(.chip-large) {
min-height: var(--ion-chip-size-large-min-height);
font-size: var(--ion-chip-size-large-font-size);
}
// Subtle Chip
// ---------------------------------------------
:host(.chip-subtle) {
--ion-chip-background: var(--ion-chip-hue-subtle-bg);
--ion-chip-color: var(--ion-chip-hue-subtle-color);
}
:host(.chip-outline.chip-subtle) {
border-color: var(--ion-chip-hue-subtle-border-color);
}
// Bold Chip
// ---------------------------------------------
:host(.chip-bold) {
--ion-chip-background: var(--ion-chip-hue-bold-bg);
--ion-chip-color: var(--ion-chip-hue-bold-color);
}
:host(.chip-outline.chip-bold) {
border-color: var(--ion-chip-hue-bold-border-color);
}
// Chip Colors
// ---------------------------------------------
// Subtle
:host(.chip-subtle.ion-color) {
background: current-color(
base,
$subtle: true
); // these don't work because we need to update the function to use the new color system
color: current-color(
contrast,
$subtle: true
); // these don't work because we need to update the function to use the new color system
}
:host(.chip-subtle.chip-outline.ion-color) {
border-color: current-color(
shade,
$subtle: true
); // these don't work because we need to update the function to use the new color system
}
// Bold
:host(.chip-bold.ion-color) {
background: current-color(
base
); // these don't work because we need to update the function to use the new color system
color: current-color(
contrast
); // these don't work because we need to update the function to use the new color system
}
:host(.chip-bold.chip-outline.ion-color) {
border-color: current-color(
shade
); // these don't work because we need to update the function to use the new color system
}

View File

@@ -0,0 +1,113 @@
import type { ComponentInterface } from '@stencil/core';
import { Component, Host, Prop, h, Element } from '@stencil/core';
import { createColorClasses } from '@utils/theme';
import { getIonMode, getIonCustomTheme } from '../../global/ionic-global';
import type { Color } from '../../interface';
import { generateCSSVars } from '../../themes/base/generate-css-vars';
/**
* @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-my-chip',
styleUrl: 'my-chip.base.scss',
shadow: true,
})
export class MyChip implements ComponentInterface {
private isThemed = false;
@Element() el!: HTMLElement;
/**
* The color to use from your application's color palette.
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
* For more information on colors, see [theming](/docs/theming/basics).
*/
@Prop({ reflect: true }) color?: Color;
/**
* Display an outline style button.
*/
@Prop() outline = false;
/**
* If `true`, the user cannot interact with the chip.
*/
@Prop() disabled = false;
/**
* Set to `"bold"` for a chip with vibrant, bold colors or to `"subtle"` for
* a chip with muted, subtle colors.
*
* Only applies to the `ionic` theme.
*/
// THOUGHT: Comparing to ChakraUI, they use variants (aka fills) for this
// maybe we should consider using variants: solid, outline, subtle
// they use solid for bold solid background, no outline, has states
// subtle for light background, no outline, has states
// outline for outline style, no background, has states
// surface for light background, with outline, has states
// ghost for no background, no outline, has states
// plain for no background, no outline, no states
@Prop() hue?: 'bold' | 'subtle' = 'subtle';
/**
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully
* rounded corners, or `"rectangular"` for a chip without rounded corners.
* Defaults to `"round"` for the `"ionic"` theme and `"soft"` for all other themes.
*/
@Prop() shape?: 'soft' | 'round' | 'rectangular' = 'soft';
/**
* Set to `"small"` for a chip with less height and padding.
*
* Defaults to `"large"` for the ionic theme, and undefined for all other themes.
*/
@Prop() size?: 'small' | 'large' = 'small';
componentWillLoad() {
const myCustomTheme = getIonCustomTheme();
const componentTheme = myCustomTheme.components['IonChip'];
// check if componentTheme is not an empty object or undefined
if (componentTheme !== undefined || Object.keys(componentTheme).length > 0) {
this.isThemed = true;
// apply a style tag to this component
const style = document.createElement('style');
style.innerHTML = [generateCSSVars(componentTheme, '--ion-chip-', ':host(.chip-themed)')].join('\n\n');
// Attach to Shadow Root if available, otherwise Light DOM
const root = this.el.shadowRoot ?? this.el;
root.appendChild(style);
}
}
render() {
const { hue, shape, size } = this;
const mode = getIonMode(this);
return (
<Host
aria-disabled={this.disabled ? 'true' : null}
class={createColorClasses(this.color, {
// Needed to properly add the custom styles else
// the styles would be ignored due to styling order
'chip-themed': this.isThemed,
[`chip-${shape}`]: shape !== undefined,
'chip-outline': this.outline,
'chip-disabled': this.disabled,
'ion-activatable': true,
'ion-focusable': !this.disabled,
[`chip-${size}`]: size !== undefined,
[`chip-${hue}`]: hue !== undefined,
})}
>
<slot></slot>
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</Host>
);
}
}

View File

@@ -0,0 +1,95 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>MyChip - Basic</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>MyChip - Basic</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding" id="content" style="text-align: center">
<h2>My Chip</h2>
<p>
This is a POC, not all the features are working as expected. For example, the color property still needs to be
worked on.
</p>
<p>You can verify that the variables are being generated correctly by inspecting the root element.</p>
<ion-my-chip>default</ion-my-chip>
<ion-my-chip outline>outline</ion-my-chip>
<ion-my-chip size="large">large</ion-my-chip>
<ion-my-chip hue="bold">bold</ion-my-chip>
<ion-my-chip hue="bold" outline>bold with outline</ion-my-chip>
<ion-my-chip color="primary">primary, subtle hue</ion-my-chip>
<ion-my-chip color="primary" hue="bold">primary, bold hue</ion-my-chip>
<ion-my-chip color="secondary">secondary, subtle hue</ion-my-chip>
<ion-my-chip color="secondary" hue="bold">secondary, bold hue</ion-my-chip>
</ion-content>
</ion-app>
<script>
window.Ionic = {
config: {
customTheme: {
palette: {
light: {
color: {
primary: {
bold: {
base: 'pink',
constrast: 'black',
},
},
secondary: {
bold: {
base: '#510aa8',
},
},
// gray: {
// 800: 'pink',
// }
},
},
},
components: {
IonChip: {
hue: {
subtle: {
bg: 'red',
color: 'white',
borderColor: 'black'
},
bold: {
bg: 'blue',
color: 'white',
borderColor: 'black'
}
}
},
},
},
},
};
</script>
</body>
</html>

View File

@@ -7,6 +7,9 @@ import type { RouterDirection } from '../router/utils/interface';
import { navLink } from './nav-link-utils';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
*/
@Component({
tag: 'ion-nav-link',
})

View File

@@ -11,61 +11,70 @@ $light: #222428;
$medium: #989aa2;
$dark: #f4f5f8;
$colors: (
$colors: (
primary: (
base: $primary,
contrast: #000,
shade: get-color-shade($primary),
tint: get-color-tint($primary)
base: $primary,
contrast: #000,
shade: get-color-shade($primary),
tint: get-color-tint($primary),
foreground: $primary,
),
secondary: (
base: $secondary,
contrast: #000,
shade: get-color-shade($secondary),
tint: get-color-tint($secondary)
base: $secondary,
contrast: #000,
shade: get-color-shade($secondary),
tint: get-color-tint($secondary),
foreground: $secondary,
),
tertiary: (
base: $tertiary,
contrast: #000,
shade: get-color-shade($tertiary),
tint: get-color-tint($tertiary)
base: $tertiary,
contrast: #000,
shade: get-color-shade($tertiary),
tint: get-color-tint($tertiary),
foreground: $tertiary,
),
success: (
base: $success,
contrast: #000,
shade: get-color-shade($success),
tint: get-color-tint($success)
base: $success,
contrast: #000,
shade: get-color-shade($success),
tint: get-color-tint($success),
foreground: $success,
),
warning: (
base: $warning,
contrast: #000,
shade: get-color-shade($warning),
tint: get-color-tint($warning)
base: $warning,
contrast: #000,
shade: get-color-shade($warning),
tint: get-color-tint($warning),
foreground: $warning,
),
danger: (
base: $danger,
contrast: #000,
shade: get-color-shade($danger),
tint: get-color-tint($danger)
base: $danger,
contrast: #000,
shade: get-color-shade($danger),
tint: get-color-tint($danger),
foreground: $danger,
),
light: (
base: $light,
contrast: #fff,
shade: get-color-shade($light),
tint: get-color-tint($light)
base: $light,
contrast: #fff,
shade: get-color-shade($light),
tint: get-color-tint($light),
foreground: $light,
),
medium: (
base: $medium,
contrast: #000,
shade: get-color-shade($medium),
tint: get-color-tint($medium)
base: $medium,
contrast: #000,
shade: get-color-shade($medium),
tint: get-color-tint($medium),
foreground: $medium,
),
dark: (
base: $dark,
contrast: #000,
shade: get-color-shade($dark),
tint: get-color-tint($dark)
)
base: $dark,
contrast: #000,
shade: get-color-shade($dark),
tint: get-color-tint($dark),
foreground: $dark,
),
);
@mixin dark-base-palette() {

View File

@@ -1,71 +1,80 @@
@use "sass:map";
@import "../../themes/ionic.functions.color";
$primary: #7cabff;
$secondary: #62bdff;
$tertiary: #b6b9f9;
$success: #4ada71;
$warning: #ffce31;
$danger: #fc9aa2;
$light: #222428;
$medium: #a8aab3;
$dark: #f4f5f8;
$primary: #7cabff;
$secondary: #62bdff;
$tertiary: #b6b9f9;
$success: #4ada71;
$warning: #ffce31;
$danger: #fc9aa2;
$light: #222428;
$medium: #a8aab3;
$dark: #f4f5f8;
$colors: (
$colors: (
primary: (
base: $primary,
contrast: #000,
shade: get-color-shade($primary),
tint: get-color-tint($primary)
base: $primary,
contrast: #000,
shade: get-color-shade($primary),
tint: get-color-tint($primary),
foreground: $primary,
),
secondary: (
base: $secondary,
contrast: #000,
shade: get-color-shade($secondary),
tint: get-color-tint($secondary)
base: $secondary,
contrast: #000,
shade: get-color-shade($secondary),
tint: get-color-tint($secondary),
foreground: $secondary,
),
tertiary: (
base: $tertiary,
contrast: #000,
shade: get-color-shade($tertiary),
tint: get-color-tint($tertiary)
base: $tertiary,
contrast: #000,
shade: get-color-shade($tertiary),
tint: get-color-tint($tertiary),
foreground: $tertiary,
),
success: (
base: $success,
contrast: #000,
shade: get-color-shade($success),
tint: get-color-tint($success)
base: $success,
contrast: #000,
shade: get-color-shade($success),
tint: get-color-tint($success),
foreground: $success,
),
warning: (
base: $warning,
contrast: #000,
shade: get-color-shade($warning),
tint: get-color-tint($warning)
base: $warning,
contrast: #000,
shade: get-color-shade($warning),
tint: get-color-tint($warning),
foreground: $warning,
),
danger: (
base: $danger,
contrast: #000,
shade: get-color-shade($danger),
tint: get-color-tint($danger)
base: $danger,
contrast: #000,
shade: get-color-shade($danger),
tint: get-color-tint($danger),
foreground: $danger,
),
light: (
base: $light,
contrast: #fff,
shade: get-color-shade($light),
tint: get-color-tint($light)
base: $light,
contrast: #fff,
shade: get-color-shade($light),
tint: get-color-tint($light),
foreground: $light,
),
medium: (
base: $medium,
contrast: #000,
shade: get-color-shade($medium),
tint: get-color-tint($medium)
base: $medium,
contrast: #000,
shade: get-color-shade($medium),
tint: get-color-tint($medium),
foreground: $medium,
),
dark: (
base: $dark,
contrast: #000,
shade: get-color-shade($dark),
tint: get-color-tint($dark)
)
base: $dark,
contrast: #000,
shade: get-color-shade($dark),
tint: get-color-tint($dark),
foreground: $dark,
),
);
/// Text step colors are generated based on
@@ -105,13 +114,12 @@ $lightest-text-color: $text-color;
--ion-color-#{$color-name}-shade: #{map.get($value, shade)};
--ion-color-#{$color-name}-tint: #{map.get($value, tint)};
}
}
}
@mixin high-contrast-dark-ios-palette() {
$background-color: #000000;
& {
--ion-background-color: #{$background-color};
--ion-background-color-rgb: #{color-to-rgb-list($background-color)};
@@ -175,7 +183,7 @@ $lightest-text-color: $text-color;
@mixin high-contrast-dark-md-palette() {
$background-color: #121212;
& {
--ion-background-color: #{$background-color};
--ion-background-color-rgb: #{color-to-rgb-list($background-color)};

View File

@@ -1,71 +1,80 @@
@use "sass:map";
@import "../../themes/ionic.functions.color";
$primary: #003fae;
$secondary: #01487b;
$tertiary: #3400e6;
$success: #004314;
$warning: #5f4100;
$danger: #9c000c;
$light: #f4f5f8;
$medium: #444446;
$dark: #222428;
$primary: #003fae;
$secondary: #01487b;
$tertiary: #3400e6;
$success: #004314;
$warning: #5f4100;
$danger: #9c000c;
$light: #f4f5f8;
$medium: #444446;
$dark: #222428;
$colors: (
$colors: (
primary: (
base: $primary,
contrast: #fff,
shade: get-color-shade($primary),
tint: get-color-tint($primary)
base: $primary,
contrast: #fff,
shade: get-color-shade($primary),
tint: get-color-tint($primary),
foreground: $primary,
),
secondary: (
base: $secondary,
contrast: #fff,
shade: get-color-shade($secondary),
tint: get-color-tint($secondary)
base: $secondary,
contrast: #fff,
shade: get-color-shade($secondary),
tint: get-color-tint($secondary),
foreground: $secondary,
),
tertiary: (
base: $tertiary,
contrast: #fff,
shade: get-color-shade($tertiary),
tint: get-color-tint($tertiary)
base: $tertiary,
contrast: #fff,
shade: get-color-shade($tertiary),
tint: get-color-tint($tertiary),
foreground: $tertiary,
),
success: (
base: $success,
contrast: #fff,
shade: get-color-shade($success),
tint: get-color-tint($success)
base: $success,
contrast: #fff,
shade: get-color-shade($success),
tint: get-color-tint($success),
foreground: $success,
),
warning: (
base: $warning,
contrast: #fff,
shade: get-color-shade($warning),
tint: get-color-tint($warning)
base: $warning,
contrast: #fff,
shade: get-color-shade($warning),
tint: get-color-tint($warning),
foreground: $warning,
),
danger: (
base: $danger,
contrast: #fff,
shade: get-color-shade($danger),
tint: get-color-tint($danger)
base: $danger,
contrast: #fff,
shade: get-color-shade($danger),
tint: get-color-tint($danger),
foreground: $danger,
),
light: (
base: $light,
contrast: #000,
shade: get-color-shade($light),
tint: get-color-tint($light)
base: $light,
contrast: #000,
shade: get-color-shade($light),
tint: get-color-tint($light),
foreground: $light,
),
medium: (
base: $medium,
contrast: #fff,
shade: get-color-shade($medium),
tint: get-color-tint($medium)
base: $medium,
contrast: #fff,
shade: get-color-shade($medium),
tint: get-color-tint($medium),
foreground: $medium,
),
dark: (
base: $dark,
contrast: #fff,
shade: get-color-shade($dark),
tint: get-color-tint($dark)
)
base: $dark,
contrast: #fff,
shade: get-color-shade($dark),
tint: get-color-tint($dark),
foreground: $dark,
),
);
/// Text step colors are generated based on

View File

@@ -41,7 +41,10 @@ html {
/**
* Includes fallback if Dynamic Type is not enabled.
*/
font: var(--ion-dynamic-font, 16px var(--ion-font-family));
// ion-font-sizes-root needs a fallback since the new theming isn't fully
// implemented in the framework yet.
font: var(--ion-dynamic-font, var(--ion-font-sizes-root, 16px) var(--ion-font-family));
// font: var(--ion-dynamic-font, var(--ion-font-sizes-root) var(--ion-font-family));
}
}

View File

@@ -1,7 +1,10 @@
import { getMode, setMode } from '@stencil/core';
import { printIonWarning } from '@utils/logging';
import type { IonicConfig, Mode } from '../interface';
import { defaultTheme as baseTheme } from '../themes/base/base.tokens';
import type { Theme as BaseTheme } from '../themes/base/base.tokens';
import { deepMerge, generateCSSVars } from '../themes/base/generate-css-vars';
import { printIonWarning } from '../utils/logging';
import { isPlatform, setupPlatforms } from '../utils/platform';
import { config, configFromSession, configFromURL, saveConfig } from './config';
@@ -10,8 +13,183 @@ import { config, configFromSession, configFromURL, saveConfig } from './config';
let defaultMode: Mode;
export const getIonMode = (ref?: any): Mode => {
return (ref && getMode(ref)) || defaultMode;
type Theme = 'ios' | 'md' | 'ionic';
const getElement = (ref: any): HTMLElement => {
if (ref && typeof ref === 'object' && ref.tagName) {
return ref;
}
return document.documentElement;
};
/**
* Prints a warning message to the developer to inform them of
* an invalid configuration of mode and theme.
* @param mode The invalid mode configuration.
* @param theme The invalid theme configuration.
*/
const printInvalidModeWarning = (mode: Mode, theme: Theme, ref?: any) => {
printIonWarning(
`Invalid mode and theme combination provided: mode: ${mode}, theme: ${theme}. Fallback mode ${getDefaultModeForTheme(
theme
)} will be used.`,
ref
);
};
const applyTheme = (userTheme: BaseTheme, prefix?: string) => {
const mergedTheme = deepMerge(baseTheme, userTheme);
const { palette, components, ...restTokens } = mergedTheme;
const { enabled, ...restDarkTokens } = palette.dark;
config.set('customTheme', mergedTheme);
const style = document.createElement('style');
style.innerHTML = [generateCSSVars(restTokens, prefix), generateCSSVars(palette.light, prefix)].join('\n\n');
if (enabled === 'system') {
style.innerHTML += `@media (prefers-color-scheme: dark) {\n${generateCSSVars(restDarkTokens, prefix)}\n}`;
}
document.head.appendChild(style);
};
/**
* Validates if a mode is accepted for a theme configuration.
* @param mode The mode to validate.
* @param theme The theme the mode is being used with.
* @returns `true` if the mode is valid for the theme, `false` if invalid.
*/
export const isModeValidForTheme = (mode: Mode, theme: Theme) => {
if (mode === 'md') {
return theme === 'md' || theme === 'ionic';
} else if (mode === 'ios') {
return theme === 'ios' || theme === 'ionic';
}
return false;
};
/**
* Returns the default mode for a specified theme.
* @param theme The theme to return a default mode for.
* @returns The default mode, either `ios` or `md`.
*/
const getDefaultModeForTheme = (theme: Theme): Mode => {
if (theme === 'ios') {
return 'ios';
}
return 'md';
};
/**
* Returns the default theme for a specified mode.
* @param mode The mode to return a default theme for.
* @returns The default theme.
*/
const getDefaultThemeForMode = (mode: Mode): Theme => {
if (mode === 'ios') {
return 'ios';
}
return 'md';
};
// const isModeSupported = (elmMode: string) => ['ios', 'md'].includes(elmMode);
// const isThemeSupported = (theme: string) => ['ios', 'md', 'ionic'].includes(theme);
// const isIonicElement = (elm: HTMLElement) => elm.tagName?.startsWith('ION-');
/**
* Returns the mode value of the element reference or the closest
* parent with a valid mode.
* @param ref The element reference to look up the mode for.
* @param theme Optionally can provide the theme to avoid an additional look-up.
* @returns The mode value for the element reference.
*/
export const getIonMode = (ref?: any, theme = getIonTheme(ref)): Mode => {
if (ref?.mode && isModeValidForTheme(ref?.mode, theme)) {
/**
* If the reference already has a mode configuration,
* use it instead of performing a look-up.
*/
return ref.mode;
} else {
const el = getElement(ref);
const mode = (el.closest('[mode]')?.getAttribute('mode') as Mode) || defaultMode;
if (isModeValidForTheme(mode, theme)) {
/**
* The mode configuration is supported for the configured theme.
*/
return mode;
} else {
printInvalidModeWarning(mode, theme, ref);
}
}
return getDefaultModeForTheme(theme);
};
/**
* Returns the theme value of the element reference or the closest
* parent with a valid theme.
*
* @param ref The element reference to look up the theme for.
* @returns The theme value for the element reference, defaults to
* the default theme if it cannot be determined.
*/
export const getIonTheme = (ref?: any): Theme => {
const theme: Theme = ref && getMode<Theme>(ref);
if (theme) {
return theme;
}
const el = getElement(ref);
const mode = ref?.mode ?? (el.closest('[mode]')?.getAttribute('mode') as Mode);
if (mode) {
return getDefaultThemeForMode(mode);
}
// Return a default theme string, not the baseTheme object
return 'md'; // or 'ionic' as your default
};
export const getIonCustomTheme = (): any => {
const customTheme = config.get('customTheme');
if (customTheme) {
return customTheme;
}
return baseTheme;
};
export const rIC = (callback: () => void) => {
if ('requestIdleCallback' in window) {
(window as any).requestIdleCallback(callback);
} else {
setTimeout(callback, 32);
}
};
export const needInputShims = () => {
/**
* iOS always needs input shims
*/
const needsShimsIOS = isPlatform(window, 'ios') && isPlatform(window, 'mobile');
if (needsShimsIOS) {
return true;
}
/**
* Android only needs input shims when running
* in the browser and only if the browser is using the
* new Chrome 108+ resize behavior: https://developer.chrome.com/blog/viewport-resize-behavior/
*/
const isAndroidMobileWeb = isPlatform(window, 'android') && isPlatform(window, 'mobileweb');
if (isAndroidMobileWeb) {
return true;
}
return false;
};
export const initialize = (userConfig: IonicConfig = {}) => {
@@ -53,6 +231,17 @@ export const initialize = (userConfig: IonicConfig = {}) => {
doc.documentElement.setAttribute('mode', defaultMode);
doc.documentElement.classList.add(defaultMode);
// Remove this line as 'theme' is not a valid IonicConfig key
// config.set('theme', defaultTheme);
// doc.documentElement.setAttribute('theme', defaultTheme);
// doc.documentElement.classList.add(defaultTheme);
const customTheme: BaseTheme | undefined = configObj.customTheme;
if (customTheme) {
applyTheme(customTheme);
}
if (config.getBoolean('_testing')) {
config.set('animated', false);
}

View File

@@ -0,0 +1,86 @@
import { defaultDarkTheme } from './dark.tokens';
import { defaultLightTheme } from './light.tokens';
export const defaultTheme = {
palette: {
light: defaultLightTheme,
dark: defaultDarkTheme,
},
// so far spacing is being used for
// padding, margin, gap, border-width, height, width
spacing: {
none: '0',
xxs: '2px',
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
xxl: '40px',
},
// scaling is used for width and height
scaling: {
0: '0',
100: '4px',
150: '6px',
200: '8px',
250: '10px',
300: '12px',
350: '14px',
400: '16px',
450: '18px',
500: '20px',
550: '22px',
600: '24px',
650: '26px',
700: '28px',
750: '30px',
800: '32px',
850: '34px',
900: '36px',
},
radii: {
none: '0',
xs: '1px',
sm: '2px',
md: '4px',
lg: '8px',
xl: '16px',
xxl: '32px',
},
dynamicFont: '-apple-system-body',
fontFamily: 'Roboto, "Helvetica Neue", sans-serif',
fontWeights: {
thin: '100',
extraLight: '200',
light: '300',
normal: '400',
medium: '500',
semiBold: '600',
bold: '700',
extraBold: '800',
black: '900',
},
fontSizes: {
root: '16px',
xxs: '10px',
xs: '12px',
sm: '14px',
md: '16px',
lg: '18px',
xl: '20px',
xxl: '24px',
},
lineHeights: {
xxs: '1',
xs: '1.2',
sm: '1.4',
md: '1.6',
lg: '1.8',
xl: '2',
xxl: '2.4',
},
components: {},
};
export type Theme = typeof defaultTheme;

View File

@@ -0,0 +1,58 @@
export const defaultDarkTheme = {
enabled: 'never', // 'always' | 'system' | 'class' | 'never'
color: {
primary: {
bold: {
base: '#0054e9',
constrast: '#ffffff',
shade: '#0041c4', // darker version
tint: '#0065ff', // lighter version
},
subtle: {
base: '#0054e9',
constrast: '#ffffff',
shade: '#0041c4', // darker version
tint: '#0065ff', // lighter version
},
},
secondary: {
bold: {
base: '#0163aa',
constrast: '#ffffff',
shade: '#015a9e',
tint: '#0176c4',
},
subtle: {
base: '#0163aa',
constrast: '#ffffff',
shade: '#015a9e',
tint: '#0176c4',
},
},
red: {
50: '#ffebee',
100: '#ffcdd2',
200: '#ef9a9a',
},
blue: {
50: '#e3f2fd',
100: '#bbdefb',
200: '#90caf9',
},
gray: {
50: '#f5f5f5',
100: '#eeeeee',
200: '#e0e0e0',
300: '#bdbdbd',
400: '#9e9e9e',
500: '#757575',
600: '#616161',
700: '#424242',
800: '#212121',
},
white: 'green',
black: '#000000',
},
};
export type Theme = typeof defaultDarkTheme;

View File

@@ -0,0 +1,45 @@
// import type { Theme } from './base.tokens';
export function generateCSSVars(theme: any, themePrefix = '--ion-', selector = ':root'): string {
const flatten = (obj: any, prefix = themePrefix): string =>
Object.entries(obj)
.flatMap(([key, val]) => {
// if key is camelCase, convert to kebab-case
if (key.match(/([a-z])([A-Z])/g)) {
key = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
// If it's a font-sizes key, create rem version
// This is necessary to support the dynamic font size feature
if (key === 'font-sizes' && typeof val === 'object' && val !== null) {
const fontSizeBase = parseFloat(theme.fontSizes.root);
return Object.entries(val).map(([sizeKey, sizeValue]) => {
const remValue = `${parseFloat(sizeValue) / fontSizeBase}rem`;
// Need a check to determine if the value is already in rem
return [
`${prefix}${key}-${sizeKey}: ${sizeValue};`, // original px value
`${prefix}${key}-${sizeKey}-rem: ${remValue};` // rem value
].join('\n');
}).join('\n');
}
return typeof val === 'object' && val !== null
? flatten(val, `${prefix}${key}-`)
: [`${prefix}${key}: ${val};`];
})
.join('\n');
return `${selector} {\n${flatten(theme)}\n}`;
}
// Simple deep merge function
export function deepMerge(target: any, source: any): any {
for (const key in source) {
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
target[key] = deepMerge(target[key] ?? {}, source[key]);
} else {
target[key] = source[key];
}
}
return target;
}

View File

@@ -0,0 +1,57 @@
export const defaultLightTheme = {
color: {
primary: {
bold: {
base: '#0054e9',
constrast: '#ffffff',
shade: '#0041c4', // darker version
tint: '#0065ff', // lighter version
},
subtle: {
base: '#0054e9',
constrast: '#ffffff',
shade: '#0041c4', // darker version
tint: '#0065ff', // lighter version
},
},
secondary: {
bold: {
base: '#0163aa',
constrast: '#ffffff',
shade: '#015a9e',
tint: '#0176c4',
},
subtle: {
base: '#0163aa',
constrast: '#ffffff',
shade: '#015a9e',
tint: '#0176c4',
},
},
red: {
50: '#ffebee',
100: '#ffcdd2',
200: '#ef9a9a',
},
blue: {
50: '#e3f2fd',
100: '#bbdefb',
200: '#90caf9',
},
gray: {
50: '#f5f5f5',
100: '#eeeeee',
200: '#e0e0e0',
300: '#bdbdbd',
400: '#9e9e9e',
500: '#757575',
600: '#616161',
700: '#424242',
800: '#212121',
},
white: '#ffffff',
black: '#000000',
},
};
export type Theme = typeof defaultLightTheme;

View File

@@ -1,14 +1,18 @@
@use "sass:map";
// Gets the active color's css variable from a variation. Alpha is optional.
// --------------------------------------------------------------------------------------------
// Example usage:
// current-color(base) => var(--ion-color-base)
// current-color(contrast, 0.1) => rgba(var(--ion-color-contrast-rgb), 0.1)
// --------------------------------------------------------------------------------------------
@function current-color($variation, $alpha: null) {
@function current-color($variation, $alpha: null, $subtle: false) {
$variable: if($subtle, "--ion-color-subtle-#{$variation}", "--ion-color-#{$variation}");
@if $alpha == null {
@return var(--ion-color-#{$variation});
@return var(#{$variable});
} @else {
@return rgba(var(--ion-color-#{$variation}-rgb), #{$alpha});
@return rgba(var(#{$variable}-rgb), #{$alpha});
}
}
@@ -19,19 +23,36 @@
// ion-color(secondary, contrast) => var(--ion-color-secondary-contrast)
// ion-color(primary, base, 0.5) => rgba(var(--ion-color-primary-rgb, 56, 128, 255), 0.5)
// --------------------------------------------------------------------------------------------
@function ion-color($name, $variation, $alpha: null, $rgb: null) {
$values: map-get($colors, $name);
$value: map-get($values, $variation);
$variable: --ion-color-#{$name}-#{$variation};
@function ion-color($name, $variation, $alpha: null, $rgb: null, $subtle: false) {
$values: map.get($colors, $name);
$values: map.get($values, if($subtle, subtle, bold));
$value: map.get($values, $variation);
// TODO(FW-6417): this can be removed when foreground is required
// Fallback to "base" variant when "foreground" variant is undefined
@if ($variation == foreground and $value == null) {
$variation: base;
$value: map.get($values, $variation);
}
// If the color requested is subtle we return `--ion-color-{color}-subtle-contrast`,
// otherwise we return `--ion-color-{color}-contrast`.
$variable: if($subtle, "--ion-color-#{$name}-subtle-#{$variation}", "--ion-color-#{$name}-#{$variation}");
// If the variation being used is "base", we do not include the variant.
// If the color requested is subtle we return `--ion-color-{color}-subtle`,
// otherwise we return `--ion-color-{color}`.
@if ($variation == base) {
$variable: --ion-color-#{$name};
$variable: if($subtle, "--ion-color-#{$name}-subtle", "--ion-color-#{$name}");
}
@if ($alpha) {
$value: color-to-rgb-list($value);
@return rgba(var(#{$variable}-rgb, $value), $alpha);
}
@if ($rgb) {
$value: color-to-rgb-list($value);
$variable: #{$variable}-rgb;
@@ -43,17 +64,181 @@
// Mixes a color with black to create its shade.
// --------------------------------------------------------------------------------------------
@function get-color-shade($color) {
@if (type-of($color) != color) {
@return $color;
}
@return mix(#000, $color, 12%);
}
// Mixes a color with white to create its tint.
// --------------------------------------------------------------------------------------------
@function get-color-tint($color) {
@if (type-of($color) != color) {
@return $color;
}
@return mix(#fff, $color, 10%);
}
// Converts a color to a comma separated rgb.
// --------------------------------------------------------------------------------------------
@function color-to-rgb-list($color) {
@return #{red($color)},#{green($color)},#{blue($color)};
@if (type-of($color) != color) {
@return $color;
}
@return #{red($color)}, #{green($color)}, #{blue($color)};
}
// Generates color variants for the specified color based on the
// colors map for whichever hue is passed (bold, subtle).
// --------------------------------------------------------------------------------------------
// Example usage (bold):
// .ion-color-primary {
// @include generate-color-variants("primary");
// }
//
// Example output (bold):
// .ion-color-primary {
// --ion-color-base: var(--ion-color-primary-base, #105cef) !important;
// --ion-color-base-rgb: var(--ion-color-primary-base-rgb, 16, 92, 239) !important;
// --ion-color-contrast: var(--ion-color-primary-contrast, #fff) !important;
// --ion-color-contrast-rgb: var(--ion-color-primary-contrast-rgb, 255, 255, 255) !important;
// --ion-color-shade: var(--ion-color-primary-shade, #0f54da) !important;
// --ion-color-tint: var(--ion-color-primary-tint, #94a5f4) !important;
// }
// --------------------------------------------------------------------------------------------
// Example usage (subtle):
// .ion-color-primary {
// @include generate-color-variants("primary", "subtle")
// }
//
// Example output (subtle):
// .ion-color-primary {
// --ion-color-subtle-base: var(--ion-color-primary-subtle-base, #f2f4fd) !important;
// --ion-color-subtle-base-rgb: var(--ion-color-primary-subtle-base-rgb, 242, 244, 253) !important;
// --ion-color-subtle-contrast: var(--ion-color-primary-subtle-contrast, #105cef) !important;
// --ion-color-subtle-contrast-rgb: var(--ion-color-primary-subtle-contrast-rgb, 16, 92, 239) !important;
// --ion-color-subtle-shade: var(--ion-color-primary-subtle-shade, #d0d7fa) !important;
// --ion-color-subtle-tint: var(--ion-color-primary-subtle-tint, #e9ecfc) !important;
// }
// --------------------------------------------------------------------------------------------
@mixin generate-color-variants($color-name, $hue: "bold") {
@if not($colors) {
@error 'No theme colors set. Please make sure to call set-theme-colors($colorsMap) before using ion-color()';
}
// Grab the different hue color maps for the
// specified color and then grab the map of color variants
$hue-colors: map.get($colors, $color-name);
$color-variants: map.get($hue-colors, $hue);
$prefix: if($hue == "subtle", "-subtle", "");
// TODO(FW-6417) this @if can be removed if we add subtle colors for ios and md
// Only proceed if the color variants exist
@if $color-variants {
// Grab the individual color variants
$base: map.get($color-variants, base);
$base-rgb: map.get($color-variants, base-rgb);
$contrast: map.get($color-variants, contrast);
$contrast-rgb: map.get($color-variants, contrast-rgb);
$shade: map.get($color-variants, shade);
$tint: map.get($color-variants, tint);
$foreground: map.get($color-variants, foreground);
// Generate CSS variables dynamically
--ion-color#{$prefix}-base: var(--ion-color-#{$color-name}#{$prefix}, #{$base}) !important;
--ion-color#{$prefix}-base-rgb: var(--ion-color-#{$color-name}#{$prefix}-rgb, #{$base-rgb}) !important;
--ion-color#{$prefix}-contrast: var(--ion-color-#{$color-name}#{$prefix}-contrast, #{$contrast}) !important;
--ion-color#{$prefix}-contrast-rgb: var(
--ion-color-#{$color-name}#{$prefix}-contrast-rgb,
#{$contrast-rgb}
) !important;
--ion-color#{$prefix}-shade: var(--ion-color-#{$color-name}#{$prefix}-shade, #{$shade}) !important;
--ion-color#{$prefix}-tint: var(--ion-color-#{$color-name}#{$prefix}-tint, #{$tint}) !important;
// TODO(FW-6417): remove the fallback variable when the foreground variable is
// required by all palettes for all themes:
// --ion-color#{$prefix}-foreground: var(--ion-color-#{$color-name}#{$prefix}-foreground, #{$foreground}) !important;
--ion-color#{$prefix}-foreground: var(
--ion-color-#{$color-name}#{$prefix}-foreground,
var(--ion-color-#{$color-name}#{$prefix}, #{$foreground})
) !important;
}
}
// Generates both bold and subtle color variables
// for the specified color in the colors map.
// --------------------------------------------------------------------------------------------
@mixin generate-color($color-name) {
@include generate-color-variants($color-name);
@include generate-color-variants($color-name, "subtle");
}
// Generates color variables for all colors in the colors map for both hues (bold, subtle).
// --------------------------------------------------------------------------------------------
// Example usage:
// :root {
// generate-color-variables()
// }
//
// Example output:
// :root {
// --ion-color-primary: #105cef;
// --ion-color-primary-rgb: 16, 92, 239;
// --ion-color-primary-contrast: #ffffff;
// --ion-color-primary-contrast-rgb: 255, 255, 255;
// --ion-color-primary-shade: #0f54da;
// --ion-color-primary-tint: #94a5f4;
// --ion-color-primary-foreground: #105cef;
// --ion-color-primary-subtle: #f2f4fd;
// --ion-color-primary-subtle-rgb: 242, 244, 253;
// --ion-color-primary-subtle-contrast: #105cef;
// --ion-color-primary-subtle-contrast-rgb: 16, 92, 239;
// --ion-color-primary-subtle-shade: #d0d7fa;
// --ion-color-primary-subtle-tint: #e9ecfc;
// --ion-color-primary-foreground: #105cef;
// ...
// --ion-color-dark: #292929;
// --ion-color-dark-rgb: 41, 41, 41;
// --ion-color-dark-contrast: #ffffff;
// --ion-color-dark-contrast-rgb: 255, 255, 255;
// --ion-color-dark-shade: #242424;
// --ion-color-dark-tint: #4e4e4e;
// --ion-color-dark-foreground: #242424;
// --ion-color-dark-subtle: #f5f5f5;
// --ion-color-dark-subtle-rgb: 245, 245, 245;
// --ion-color-dark-subtle-contrast: #292929;
// --ion-color-dark-subtle-contrast-rgb: 41, 41, 41;
// --ion-color-dark-subtle-shade: #e0e0e0;
// --ion-color-dark-subtle-tint: #efefef;
// --ion-color-dark-subtle-foreground: #242424;
// }
// --------------------------------------------------------------------------------------------
@mixin generate-color-variables() {
@if not($colors) {
@error 'No theme colors set. Please make sure to call set-theme-colors($colorsMap) before using ion-color().';
}
@each $color-name, $value in $colors {
@each $hue in (bold, subtle) {
$colors: map.get($value, $hue);
@if $colors != null {
$prefix: if($hue == subtle, "-subtle", "");
--ion-color-#{$color-name}#{$prefix}: #{map.get($colors, base)};
--ion-color-#{$color-name}#{$prefix}-rgb: #{map.get($colors, base-rgb)};
--ion-color-#{$color-name}#{$prefix}-contrast: #{map.get($colors, contrast)};
--ion-color-#{$color-name}#{$prefix}-contrast-rgb: #{map.get($colors, contrast-rgb)};
--ion-color-#{$color-name}#{$prefix}-shade: #{map.get($colors, shade)};
--ion-color-#{$color-name}#{$prefix}-tint: #{map.get($colors, tint)};
// TODO(FW-6417): this "if" can be removed when foreground is defined for ios/md
// themes. It should not be added until we want foreground to be required for
// ios and md because this will be a breaking change, requiring users to add
// `--ion-color-{color}-foreground` in order to override the default colors
@if (map.get($colors, foreground)) {
--ion-color-#{$color-name}#{$prefix}-foreground: #{map.get($colors, foreground)};
}
}
}
}
}

View File

@@ -7,92 +7,130 @@
// Default Ionic Colors
// -------------------------------------------------------------------------------------------
// Color map should provide
// - base: main color to be used.
// - contrast: Color that will provide readable text against the base color
// - shade: 12% darker version of the base color (mix with black)
// - tint: 10% lighter version of the base color (mix with white)
// - base: The main color used for backgrounds
// - base-rgb: The base color in RGB format
// - contrast: A color that ensures readable text on the base color
// - contrast-rgb: The contrast color in RGB format
// - shade: 12% darker version of the base color (mix with black), used for pressed/active states
// - tint: 10% lighter version of the base color (mix with white), used for focused/hover states
$primary: #0054e9;
$secondary: #0163aa;
$tertiary: #6030ff;
$success: #2dd55b;
$warning: #ffc409;
$danger: #c5000f;
$light: #f4f5f8;
$medium: #636469;
$dark: #222428;
$primary: #0054e9;
$secondary: #0163aa;
$tertiary: #6030ff;
$success: #2dd55b;
$warning: #ffc409;
$danger: #c5000f;
$light: #f4f5f8;
$medium: #636469;
$dark: #222428;
$colors: (
$colors: (
primary: (
base: $primary,
contrast: #fff,
shade: get-color-shade($primary),
tint: get-color-tint($primary)
bold: (
base: $primary,
base-rgb: color-to-rgb-list($primary),
contrast: #fff,
contrast-rgb: color-to-rgb-list(#fff),
shade: get-color-shade($primary),
tint: get-color-tint($primary),
),
),
secondary: (
base: $secondary,
contrast: #fff,
shade: get-color-shade($secondary),
tint: get-color-tint($secondary)
bold: (
base: $secondary,
base-rgb: color-to-rgb-list($secondary),
contrast: #fff,
contrast-rgb: color-to-rgb-list(#fff),
shade: get-color-shade($secondary),
tint: get-color-tint($secondary),
),
),
tertiary: (
base: $tertiary,
contrast: #fff,
shade: get-color-shade($tertiary),
tint: get-color-tint($tertiary)
bold: (
base: $tertiary,
base-rgb: color-to-rgb-list($tertiary),
contrast: #fff,
contrast-rgb: color-to-rgb-list(#fff),
shade: get-color-shade($tertiary),
tint: get-color-tint($tertiary),
),
),
success: (
base: $success,
contrast: #000,
shade: get-color-shade($success),
tint: get-color-tint($success)
bold: (
base: $success,
base-rgb: color-to-rgb-list($success),
contrast: #000,
contrast-rgb: color-to-rgb-list(#000),
shade: get-color-shade($success),
tint: get-color-tint($success),
),
),
warning: (
base: $warning,
contrast: #000,
shade: get-color-shade($warning),
tint: get-color-tint($warning)
bold: (
base: $warning,
base-rgb: color-to-rgb-list($warning),
contrast: #000,
contrast-rgb: color-to-rgb-list(#000),
shade: get-color-shade($warning),
tint: get-color-tint($warning),
),
),
danger: (
base: $danger,
contrast: #fff,
shade: get-color-shade($danger),
tint: get-color-tint($danger)
bold: (
base: $danger,
base-rgb: color-to-rgb-list($danger),
contrast: #fff,
contrast-rgb: color-to-rgb-list(#fff),
shade: get-color-shade($danger),
tint: get-color-tint($danger),
),
),
light: (
base: $light,
contrast: #000,
shade: get-color-shade($light),
tint: get-color-tint($light)
bold: (
base: $light,
base-rgb: color-to-rgb-list($light),
contrast: #000,
contrast-rgb: color-to-rgb-list(#000),
shade: get-color-shade($light),
tint: get-color-tint($light),
),
),
medium: (
base: $medium,
contrast: #fff,
shade: get-color-shade($medium),
tint: get-color-tint($medium)
bold: (
base: $medium,
base-rgb: color-to-rgb-list($medium),
contrast: #fff,
contrast-rgb: color-to-rgb-list(#fff),
shade: get-color-shade($medium),
tint: get-color-tint($medium),
),
),
dark: (
base: $dark,
contrast: #fff,
shade: get-color-shade($dark),
tint: get-color-tint($dark)
)
bold: (
base: $dark,
base-rgb: color-to-rgb-list($dark),
contrast: #fff,
contrast-rgb: color-to-rgb-list(#fff),
shade: get-color-shade($dark),
tint: get-color-tint($dark),
),
),
);
// Default Foreground and Background Colors
// -------------------------------------------------------------------------------------------
// Used internally to calculate the default steps
$background-color-value: #fff;
$background-color-rgb-value: 255, 255, 255;
$background-color-value: #fff;
$background-color-rgb-value: 255, 255, 255;
$text-color-value: #000;
$text-color-rgb-value: 0, 0, 0;
$text-color-value: #000;
$text-color-rgb-value: 0, 0, 0;
$background-color: var(--ion-background-color, $background-color-value);
$background-color-rgb: var(--ion-background-color-rgb, $background-color-rgb-value);
$text-color: var(--ion-text-color, $text-color-value);
$text-color-rgb: var(--ion-text-color-rgb, $text-color-rgb-value);
$background-color: var(--ion-background-color, $background-color-value);
$background-color-rgb: var(--ion-background-color-rgb, $background-color-rgb-value);
$text-color: var(--ion-text-color, $text-color-value);
$text-color-rgb: var(--ion-text-color-rgb, $text-color-rgb-value);
// Default Foreground and Background Step Colors
// -------------------------------------------------------------------------------------------
@@ -101,45 +139,159 @@ $text-color-rgb: var(--ion-text-color-rgb, $text-color-rgb-va
// For example, $text-color-step-XXX will be $text-color stepping towards $background-color,
// but a $background-color-step-XXX will be $background-color stepping towards $text-color.
$background-color-step-50: var(--ion-color-step-50, var(--ion-background-color-step-50, mix($text-color-value, $background-color-value, 5%)));
$background-color-step-100: var(--ion-color-step-100, var(--ion-background-color-step-100, mix($text-color-value, $background-color-value, 10%)));
$background-color-step-150: var(--ion-color-step-150, var(--ion-background-color-step-150, mix($text-color-value, $background-color-value, 15%)));
$background-color-step-200: var(--ion-color-step-200, var(--ion-background-color-step-200, mix($text-color-value, $background-color-value, 20%)));
$background-color-step-250: var(--ion-color-step-250, var(--ion-background-color-step-250, mix($text-color-value, $background-color-value, 25%)));
$background-color-step-300: var(--ion-color-step-300, var(--ion-background-color-step-300, mix($text-color-value, $background-color-value, 30%)));
$background-color-step-350: var(--ion-color-step-350, var(--ion-background-color-step-350, mix($text-color-value, $background-color-value, 35%)));
$background-color-step-400: var(--ion-color-step-400, var(--ion-background-color-step-400, mix($text-color-value, $background-color-value, 40%)));
$background-color-step-450: var(--ion-color-step-450, var(--ion-background-color-step-450, mix($text-color-value, $background-color-value, 45%)));
$background-color-step-500: var(--ion-color-step-500, var(--ion-background-color-step-500, mix($text-color-value, $background-color-value, 50%)));
$background-color-step-550: var(--ion-color-step-550, var(--ion-background-color-step-550, mix($text-color-value, $background-color-value, 55%)));
$background-color-step-600: var(--ion-color-step-600, var(--ion-background-color-step-600, mix($text-color-value, $background-color-value, 60%)));
$background-color-step-650: var(--ion-color-step-650, var(--ion-background-color-step-650, mix($text-color-value, $background-color-value, 65%)));
$background-color-step-700: var(--ion-color-step-700, var(--ion-background-color-step-700, mix($text-color-value, $background-color-value, 70%)));
$background-color-step-750: var(--ion-color-step-750, var(--ion-background-color-step-750, mix($text-color-value, $background-color-value, 75%)));
$background-color-step-800: var(--ion-color-step-800, var(--ion-background-color-step-800, mix($text-color-value, $background-color-value, 80%)));
$background-color-step-850: var(--ion-color-step-850, var(--ion-background-color-step-850, mix($text-color-value, $background-color-value, 85%)));
$background-color-step-900: var(--ion-color-step-900, var(--ion-background-color-step-900, mix($text-color-value, $background-color-value, 90%)));
$background-color-step-950: var(--ion-color-step-950, var(--ion-background-color-step-950, mix($text-color-value, $background-color-value, 95%)));
$text-color-step-50: var(--ion-color-step-950, var(--ion-text-color-step-50, mix($background-color-value, $text-color-value, 5%)));
$text-color-step-100: var(--ion-color-step-900, var(--ion-text-color-step-100, mix($background-color-value, $text-color-value, 10%)));
$text-color-step-150: var(--ion-color-step-850, var(--ion-text-color-step-150, mix($background-color-value, $text-color-value, 15%)));
$text-color-step-200: var(--ion-color-step-800, var(--ion-text-color-step-200, mix($background-color-value, $text-color-value, 20%)));
$text-color-step-250: var(--ion-color-step-750, var(--ion-text-color-step-250, mix($background-color-value, $text-color-value, 25%)));
$text-color-step-300: var(--ion-color-step-700, var(--ion-text-color-step-300, mix($background-color-value, $text-color-value, 30%)));
$text-color-step-350: var(--ion-color-step-650, var(--ion-text-color-step-350, mix($background-color-value, $text-color-value, 35%)));
$text-color-step-400: var(--ion-color-step-600, var(--ion-text-color-step-400, mix($background-color-value, $text-color-value, 40%)));
$text-color-step-450: var(--ion-color-step-550, var(--ion-text-color-step-450, mix($background-color-value, $text-color-value, 45%)));
$text-color-step-500: var(--ion-color-step-500, var(--ion-text-color-step-500, mix($background-color-value, $text-color-value, 50%)));
$text-color-step-550: var(--ion-color-step-450, var(--ion-text-color-step-550, mix($background-color-value, $text-color-value, 55%)));
$text-color-step-600: var(--ion-color-step-400, var(--ion-text-color-step-600, mix($background-color-value, $text-color-value, 60%)));
$text-color-step-650: var(--ion-color-step-350, var(--ion-text-color-step-650, mix($background-color-value, $text-color-value, 65%)));
$text-color-step-700: var(--ion-color-step-300, var(--ion-text-color-step-700, mix($background-color-value, $text-color-value, 70%)));
$text-color-step-750: var(--ion-color-step-250, var(--ion-text-color-step-750, mix($background-color-value, $text-color-value, 75%)));
$text-color-step-800: var(--ion-color-step-200, var(--ion-text-color-step-800, mix($background-color-value, $text-color-value, 80%)));
$text-color-step-850: var(--ion-color-step-150, var(--ion-text-color-step-850, mix($background-color-value, $text-color-value, 85%)));
$text-color-step-900: var(--ion-color-step-100, var(--ion-text-color-step-900, mix($background-color-value, $text-color-value, 90%)));
$text-color-step-950: var(--ion-color-step-50, var(--ion-text-color-step-950, mix($background-color-value, $text-color-value, 95%)));
$background-color-step-50: var(
--ion-color-step-50,
var(--ion-background-color-step-50, mix($text-color-value, $background-color-value, 5%))
);
$background-color-step-100: var(
--ion-color-step-100,
var(--ion-background-color-step-100, mix($text-color-value, $background-color-value, 10%))
);
$background-color-step-150: var(
--ion-color-step-150,
var(--ion-background-color-step-150, mix($text-color-value, $background-color-value, 15%))
);
$background-color-step-200: var(
--ion-color-step-200,
var(--ion-background-color-step-200, mix($text-color-value, $background-color-value, 20%))
);
$background-color-step-250: var(
--ion-color-step-250,
var(--ion-background-color-step-250, mix($text-color-value, $background-color-value, 25%))
);
$background-color-step-300: var(
--ion-color-step-300,
var(--ion-background-color-step-300, mix($text-color-value, $background-color-value, 30%))
);
$background-color-step-350: var(
--ion-color-step-350,
var(--ion-background-color-step-350, mix($text-color-value, $background-color-value, 35%))
);
$background-color-step-400: var(
--ion-color-step-400,
var(--ion-background-color-step-400, mix($text-color-value, $background-color-value, 40%))
);
$background-color-step-450: var(
--ion-color-step-450,
var(--ion-background-color-step-450, mix($text-color-value, $background-color-value, 45%))
);
$background-color-step-500: var(
--ion-color-step-500,
var(--ion-background-color-step-500, mix($text-color-value, $background-color-value, 50%))
);
$background-color-step-550: var(
--ion-color-step-550,
var(--ion-background-color-step-550, mix($text-color-value, $background-color-value, 55%))
);
$background-color-step-600: var(
--ion-color-step-600,
var(--ion-background-color-step-600, mix($text-color-value, $background-color-value, 60%))
);
$background-color-step-650: var(
--ion-color-step-650,
var(--ion-background-color-step-650, mix($text-color-value, $background-color-value, 65%))
);
$background-color-step-700: var(
--ion-color-step-700,
var(--ion-background-color-step-700, mix($text-color-value, $background-color-value, 70%))
);
$background-color-step-750: var(
--ion-color-step-750,
var(--ion-background-color-step-750, mix($text-color-value, $background-color-value, 75%))
);
$background-color-step-800: var(
--ion-color-step-800,
var(--ion-background-color-step-800, mix($text-color-value, $background-color-value, 80%))
);
$background-color-step-850: var(
--ion-color-step-850,
var(--ion-background-color-step-850, mix($text-color-value, $background-color-value, 85%))
);
$background-color-step-900: var(
--ion-color-step-900,
var(--ion-background-color-step-900, mix($text-color-value, $background-color-value, 90%))
);
$background-color-step-950: var(
--ion-color-step-950,
var(--ion-background-color-step-950, mix($text-color-value, $background-color-value, 95%))
);
$text-color-step-50: var(
--ion-color-step-950,
var(--ion-text-color-step-50, mix($background-color-value, $text-color-value, 5%))
);
$text-color-step-100: var(
--ion-color-step-900,
var(--ion-text-color-step-100, mix($background-color-value, $text-color-value, 10%))
);
$text-color-step-150: var(
--ion-color-step-850,
var(--ion-text-color-step-150, mix($background-color-value, $text-color-value, 15%))
);
$text-color-step-200: var(
--ion-color-step-800,
var(--ion-text-color-step-200, mix($background-color-value, $text-color-value, 20%))
);
$text-color-step-250: var(
--ion-color-step-750,
var(--ion-text-color-step-250, mix($background-color-value, $text-color-value, 25%))
);
$text-color-step-300: var(
--ion-color-step-700,
var(--ion-text-color-step-300, mix($background-color-value, $text-color-value, 30%))
);
$text-color-step-350: var(
--ion-color-step-650,
var(--ion-text-color-step-350, mix($background-color-value, $text-color-value, 35%))
);
$text-color-step-400: var(
--ion-color-step-600,
var(--ion-text-color-step-400, mix($background-color-value, $text-color-value, 40%))
);
$text-color-step-450: var(
--ion-color-step-550,
var(--ion-text-color-step-450, mix($background-color-value, $text-color-value, 45%))
);
$text-color-step-500: var(
--ion-color-step-500,
var(--ion-text-color-step-500, mix($background-color-value, $text-color-value, 50%))
);
$text-color-step-550: var(
--ion-color-step-450,
var(--ion-text-color-step-550, mix($background-color-value, $text-color-value, 55%))
);
$text-color-step-600: var(
--ion-color-step-400,
var(--ion-text-color-step-600, mix($background-color-value, $text-color-value, 60%))
);
$text-color-step-650: var(
--ion-color-step-350,
var(--ion-text-color-step-650, mix($background-color-value, $text-color-value, 65%))
);
$text-color-step-700: var(
--ion-color-step-300,
var(--ion-text-color-step-700, mix($background-color-value, $text-color-value, 70%))
);
$text-color-step-750: var(
--ion-color-step-250,
var(--ion-text-color-step-750, mix($background-color-value, $text-color-value, 75%))
);
$text-color-step-800: var(
--ion-color-step-200,
var(--ion-text-color-step-800, mix($background-color-value, $text-color-value, 80%))
);
$text-color-step-850: var(
--ion-color-step-150,
var(--ion-text-color-step-850, mix($background-color-value, $text-color-value, 85%))
);
$text-color-step-900: var(
--ion-color-step-100,
var(--ion-text-color-step-900, mix($background-color-value, $text-color-value, 90%))
);
$text-color-step-950: var(
--ion-color-step-50,
var(--ion-text-color-step-950, mix($background-color-value, $text-color-value, 95%))
);
// Default General Colors
// --------------------------------------------------
$placeholder-text-color: var(--ion-placeholder-color, $text-color-step-600);
$placeholder-text-color: var(--ion-placeholder-color, $text-color-step-600);

View File

@@ -238,6 +238,8 @@ export interface IonicConfig {
scrollAssist?: boolean;
hideCaretOnScroll?: boolean;
customTheme?: any;
// INTERNAL configs
// TODO(FW-2832): types
persistConfig?: boolean;

View File

@@ -51,6 +51,7 @@ export const DIRECTIVES = [
d.IonMenu,
d.IonMenuButton,
d.IonMenuToggle,
d.IonMyChip,
d.IonNavLink,
d.IonNote,
d.IonPicker,

View File

@@ -1464,14 +1464,36 @@ export declare interface IonMenuToggle extends Components.IonMenuToggle {}
@ProxyCmp({
inputs: ['component', 'componentProps', 'routerAnimation', 'routerDirection']
inputs: ['color', 'disabled', 'hue', 'mode', 'outline', 'shape', 'size', 'theme']
})
@Component({
selector: 'ion-my-chip',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['color', 'disabled', 'hue', 'mode', 'outline', 'shape', 'size', 'theme'],
})
export class IonMyChip {
protected el: HTMLIonMyChipElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
export declare interface IonMyChip extends Components.IonMyChip {}
@ProxyCmp({
inputs: ['component', 'componentProps', 'mode', 'routerAnimation', 'routerDirection']
})
@Component({
selector: 'ion-nav-link',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['component', 'componentProps', 'routerAnimation', 'routerDirection'],
inputs: ['component', 'componentProps', 'mode', 'routerAnimation', 'routerDirection'],
})
export class IonNavLink {
protected el: HTMLIonNavLinkElement;

View File

@@ -50,6 +50,7 @@ import { defineCustomElement as defineIonLoading } from '@ionic/core/components/
import { defineCustomElement as defineIonMenu } from '@ionic/core/components/ion-menu.js';
import { defineCustomElement as defineIonMenuButton } from '@ionic/core/components/ion-menu-button.js';
import { defineCustomElement as defineIonMenuToggle } from '@ionic/core/components/ion-menu-toggle.js';
import { defineCustomElement as defineIonMyChip } from '@ionic/core/components/ion-my-chip.js';
import { defineCustomElement as defineIonNavLink } from '@ionic/core/components/ion-nav-link.js';
import { defineCustomElement as defineIonNote } from '@ionic/core/components/ion-note.js';
import { defineCustomElement as defineIonPicker } from '@ionic/core/components/ion-picker.js';
@@ -1392,16 +1393,40 @@ export class IonMenuToggle {
export declare interface IonMenuToggle extends Components.IonMenuToggle {}
@ProxyCmp({
defineCustomElementFn: defineIonMyChip,
inputs: ['color', 'disabled', 'hue', 'mode', 'outline', 'shape', 'size', 'theme']
})
@Component({
selector: 'ion-my-chip',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['color', 'disabled', 'hue', 'mode', 'outline', 'shape', 'size', 'theme'],
standalone: true
})
export class IonMyChip {
protected el: HTMLIonMyChipElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
}
}
export declare interface IonMyChip extends Components.IonMyChip {}
@ProxyCmp({
defineCustomElementFn: defineIonNavLink,
inputs: ['component', 'componentProps', 'routerAnimation', 'routerDirection']
inputs: ['component', 'componentProps', 'mode', 'routerAnimation', 'routerDirection']
})
@Component({
selector: 'ion-nav-link',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['component', 'componentProps', 'routerAnimation', 'routerDirection'],
inputs: ['component', 'componentProps', 'mode', 'routerAnimation', 'routerDirection'],
standalone: true
})
export class IonNavLink {

View File

@@ -43,6 +43,7 @@ import { defineCustomElement as defineIonListHeader } from '@ionic/core/componen
import { defineCustomElement as defineIonMenu } from '@ionic/core/components/ion-menu.js';
import { defineCustomElement as defineIonMenuButton } from '@ionic/core/components/ion-menu-button.js';
import { defineCustomElement as defineIonMenuToggle } from '@ionic/core/components/ion-menu-toggle.js';
import { defineCustomElement as defineIonMyChip } from '@ionic/core/components/ion-my-chip.js';
import { defineCustomElement as defineIonNav } from '@ionic/core/components/ion-nav.js';
import { defineCustomElement as defineIonNavLink } from '@ionic/core/components/ion-nav-link.js';
import { defineCustomElement as defineIonNote } from '@ionic/core/components/ion-note.js';
@@ -116,6 +117,7 @@ export const IonListHeader = /*@__PURE__*/createReactComponent<JSX.IonListHeader
export const IonMenu = /*@__PURE__*/createReactComponent<JSX.IonMenu, HTMLIonMenuElement>('ion-menu', undefined, undefined, defineIonMenu);
export const IonMenuButton = /*@__PURE__*/createReactComponent<JSX.IonMenuButton, HTMLIonMenuButtonElement>('ion-menu-button', undefined, undefined, defineIonMenuButton);
export const IonMenuToggle = /*@__PURE__*/createReactComponent<JSX.IonMenuToggle, HTMLIonMenuToggleElement>('ion-menu-toggle', undefined, undefined, defineIonMenuToggle);
export const IonMyChip = /*@__PURE__*/createReactComponent<JSX.IonMyChip, HTMLIonMyChipElement>('ion-my-chip', undefined, undefined, defineIonMyChip);
export const IonNav = /*@__PURE__*/createReactComponent<JSX.IonNav, HTMLIonNavElement>('ion-nav', undefined, undefined, defineIonNav);
export const IonNavLink = /*@__PURE__*/createReactComponent<JSX.IonNavLink, HTMLIonNavLinkElement>('ion-nav-link', undefined, undefined, defineIonNavLink);
export const IonNote = /*@__PURE__*/createReactComponent<JSX.IonNote, HTMLIonNoteElement>('ion-note', undefined, undefined, defineIonNote);

View File

@@ -49,6 +49,7 @@ import { defineCustomElement as defineIonListHeader } from '@ionic/core/componen
import { defineCustomElement as defineIonMenu } from '@ionic/core/components/ion-menu.js';
import { defineCustomElement as defineIonMenuButton } from '@ionic/core/components/ion-menu-button.js';
import { defineCustomElement as defineIonMenuToggle } from '@ionic/core/components/ion-menu-toggle.js';
import { defineCustomElement as defineIonMyChip } from '@ionic/core/components/ion-my-chip.js';
import { defineCustomElement as defineIonNav } from '@ionic/core/components/ion-nav.js';
import { defineCustomElement as defineIonNavLink } from '@ionic/core/components/ion-nav-link.js';
import { defineCustomElement as defineIonNote } from '@ionic/core/components/ion-note.js';
@@ -643,6 +644,16 @@ export const IonMenuToggle: StencilVueComponent<JSX.IonMenuToggle> = /*@__PURE__
]);
export const IonMyChip: StencilVueComponent<JSX.IonMyChip> = /*@__PURE__*/ defineContainer<JSX.IonMyChip>('ion-my-chip', defineIonMyChip, [
'color',
'outline',
'disabled',
'hue',
'shape',
'size'
]);
export const IonNav: StencilVueComponent<JSX.IonNav> = /*@__PURE__*/ defineContainer<JSX.IonNav>('ion-nav', defineIonNav, [
'delegate',
'swipeGesture',