feat(core): separate mode and theme

This commit is contained in:
Maria Hutt
2025-04-24 16:22:19 -07:00
parent 1e7a84f9bd
commit b1ecd4748b
16 changed files with 754 additions and 0 deletions

View File

@@ -1498,6 +1498,21 @@ 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,--background
ion-my-chip,css-prop,--border-radius
ion-my-chip,css-prop,--color
ion-my-chip,css-prop,--focus-ring-color
ion-my-chip,css-prop,--focus-ring-width
ion-nav,shadow
ion-nav,prop,animated,boolean,true,false,false
ion-nav,prop,animation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false

View File

@@ -2173,6 +2173,40 @@ 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.
*/
"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.
*/
"hue"?: 'bold' | 'subtle';
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* Display an outline style button.
*/
"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.
*/
"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.
*/
"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.
@@ -4759,6 +4793,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;
@@ -5457,6 +5497,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;
@@ -7695,6 +7736,40 @@ 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.
*/
"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.
*/
"hue"?: 'bold' | 'subtle';
/**
* The mode determines the platform behaviors of the component.
*/
"mode"?: "ios" | "md";
/**
* Display an outline style button.
*/
"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.
*/
"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.
*/
"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.
@@ -9617,6 +9692,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;
@@ -9720,6 +9796,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,156 @@
// @import "../../themes/native/native.globals";
@use "../../themes/functions.color" as color;
@use "../../themes/mixins" as mixins;
:host {
/**
* @prop --background: Background of the chip
* @prop --color: Color of the chip
* @prop --border-radius: Border radius of the chip
* @prop --focus-ring-color: Color of the focus ring
* @prop --focus-ring-width: Width of the focus ring
*/
--focus-ring-color: var(--ion-color-blue-50);
--focus-ring-width: var(--ion-spacing-xs);
@include mixins.font-smoothing();
@include mixins.padding(var(--ion-spacing-xs), var(--ion-spacing-sm));
@include mixins.border-radius(var(--border-radius));
display: inline-flex;
position: relative;
align-items: center;
justify-content: center;
background: var(--background);
color: var(--color);
font-weight: var(--ion-font-weights-normal);
line-height: var(--ion-line-heights-md);
cursor: pointer;
overflow: hidden;
vertical-align: middle;
gap: var(--ion-spacing-xs);
box-sizing: border-box;
}
:host(.chip-disabled) {
cursor: default;
pointer-events: none;
}
// Outline Chip
// ---------------------------------------------
:host(.chip-outline) {
border-width: var(--ion-spacing-xxs);
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: Focus
// ---------------------------------------------
:host(.ion-focused) {
outline: var(--focus-ring-width) solid var(--focus-ring-color);
outline-offset: var(--focus-ring-width);
}
// Chip Shapes
// ---------------------------------------------
:host(.chip-soft) {
--border-radius: var(--ion-radii-lg);
}
:host(.chip-round) {
--border-radius: var(--ion-radii-xxl);
}
:host(.chip-rectangular) {
--border-radius: var(--ion-radii-none);
}
// Size
// ---------------------------------------------
:host(.chip-small) {
min-height: var(--ion-spacing-lg);
font-size: var(--ion-font-sizs-sm);
}
:host(.chip-large) {
min-height: var(--ion-spacing-xxl);
font-size: var(--ion-font-sizes-lg);
}
// Subtle Chip
// ---------------------------------------------
:host(.chip-subtle) {
--background: var(--ion-color-gray-100);
--color: var(--ion-color-gray-800);
}
:host(.chip-outline.chip-subtle) {
border-color: var(--ion-color-gray-300);
}
// Bold Chip
// ---------------------------------------------
:host(.chip-bold) {
--background: var(--ion-color-gray-700);
--color: var(--ion-color-white);
}
:host(.chip-outline.chip-bold) {
border-color: var(--ion-color-gray-800);
}
// Chip Colors
// ---------------------------------------------
// Subtle
:host(.chip-subtle.ion-color) {
background: color.current-color(
base,
$subtle: true
); // these don't work because we need to update the function to use the new color system
color: 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: 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: color.current-color(
base
); // these don't work because we need to update the function to use the new color system
color: 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: 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,106 @@
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 {
@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) {
// apply a style tag to this component
const style = document.createElement('style');
style.innerHTML = [generateCSSVars(componentTheme, '--ion-', ':host')].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, {
[`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: {
spacing: {
sm: '12px',
},
palette: {
light: {
color: {
gray: {
800: 'pink',
},
},
},
},
},
},
},
},
};
</script>
</body>
</html>

View File

@@ -2,6 +2,9 @@ import { Build, getMode, setMode, getElement } from '@stencil/core';
import { printIonWarning } from '@utils/logging';
import type { IonicConfig, Mode, Theme } 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 { shouldUseCloseWatcher } from '../utils/hardware-back-button';
import { isPlatform, setupPlatforms } from '../utils/platform';
@@ -25,6 +28,23 @@ const printInvalidModeWarning = (mode: Mode, theme: Theme, ref?: any) => {
);
};
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.
@@ -132,6 +152,14 @@ export const getIonTheme = (ref?: any): Theme => {
return defaultTheme;
};
export const getIonCustomTheme = (): any => {
const customTheme = config.get('customTheme');
if (customTheme) {
return customTheme;
}
return defaultTheme;
};
export const rIC = (callback: () => void) => {
if ('requestIdleCallback' in window) {
(window as any).requestIdleCallback(callback);
@@ -225,6 +253,12 @@ export const initialize = (userConfig: IonicConfig = {}) => {
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,63 @@
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
// should we create scale for height and width instead?
// or keep it as is but change the keys to be numerical
// like 0.5, 1, 1.5, 2, 2.5, 3, etc?
spacing: {
none: '0',
xxs: '2px',
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
xxl: '40px',
},
radii: {
none: '0',
xs: '1px',
sm: '2px',
md: '4px',
lg: '8px',
xl: '16px',
xxl: '32px',
},
fontWeights: {
thin: '100',
extraLight: '200',
light: '300',
normal: '400',
medium: '500',
semiBold: '600',
bold: '700',
extraBold: '800',
black: '900',
},
fontSizes: {
xs: '12px',
sm: '14px',
md: '16px',
lg: '18px',
xl: '20px',
xxl: '24px',
},
lineHeights: {
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,30 @@
// 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();
}
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

@@ -364,6 +364,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

@@ -1426,6 +1426,28 @@ export class IonMenuToggle {
export declare interface IonMenuToggle extends Components.IonMenuToggle {}
@ProxyCmp({
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', 'theme']
})

View File

@@ -51,6 +51,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';
@@ -1420,6 +1421,30 @@ 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', 'mode', 'routerAnimation', 'routerDirection', 'theme']

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';
@@ -639,6 +640,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',