mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 17:42:15 +08:00
feat(theming): add new color variant for the ionic theme
This commit is contained in:
8
core/src/components.d.ts
vendored
8
core/src/components.d.ts
vendored
@ -553,6 +553,10 @@ export namespace Components {
|
||||
* Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered.
|
||||
*/
|
||||
"href": string | undefined;
|
||||
/**
|
||||
* Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for a button with muted, subtle colors.
|
||||
*/
|
||||
"hue"?: 'bold' | 'subtle';
|
||||
/**
|
||||
* The mode determines the platform behaviors of the component.
|
||||
*/
|
||||
@ -5916,6 +5920,10 @@ declare namespace LocalJSX {
|
||||
* Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered.
|
||||
*/
|
||||
"href"?: string | undefined;
|
||||
/**
|
||||
* Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for a button with muted, subtle colors.
|
||||
*/
|
||||
"hue"?: 'bold' | 'subtle';
|
||||
/**
|
||||
* The mode determines the platform behaviors of the component.
|
||||
*/
|
||||
|
@ -52,6 +52,11 @@
|
||||
--ripple-color: var(--background-activated);
|
||||
}
|
||||
|
||||
:host(.button-solid.button-subtle) {
|
||||
--background: #{globals.ion-color(primary, subtle)};
|
||||
--color: #{globals.ion-color(primary, base)};
|
||||
}
|
||||
|
||||
// Outline Button
|
||||
// --------------------------------------------------
|
||||
|
||||
@ -81,6 +86,11 @@
|
||||
// Ripple Effect
|
||||
// -------------------------------------------------------------------------------
|
||||
|
||||
:host(.button-solid.button-subtle.ion-color) .button-native {
|
||||
background: globals.current-color(subtle);
|
||||
color: globals.current-color(base);
|
||||
}
|
||||
|
||||
:host(.button-solid.ion-color) ion-ripple-effect {
|
||||
color: globals.current-color(shade);
|
||||
}
|
||||
|
@ -75,6 +75,12 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
*/
|
||||
@Prop({ reflect: true }) expand?: 'full' | 'block';
|
||||
|
||||
/**
|
||||
* Set to `"bold"` for a button with vibrant, bold colors or to `"subtle"` for
|
||||
* a button with muted, subtle colors.
|
||||
*/
|
||||
@Prop() hue?: 'bold' | 'subtle' = 'bold';
|
||||
|
||||
/**
|
||||
* Set to `"clear"` for a transparent button that resembles a flat button, to `"outline"`
|
||||
* for a transparent button with a border, or to `"solid"` for a button with a filled background.
|
||||
@ -349,8 +355,20 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
};
|
||||
|
||||
render() {
|
||||
const { buttonType, type, disabled, rel, target, href, color, expand, hasIconOnly, strong, inheritedAttributes } =
|
||||
this;
|
||||
const {
|
||||
buttonType,
|
||||
type,
|
||||
disabled,
|
||||
rel,
|
||||
target,
|
||||
href,
|
||||
color,
|
||||
expand,
|
||||
hue,
|
||||
hasIconOnly,
|
||||
strong,
|
||||
inheritedAttributes,
|
||||
} = this;
|
||||
|
||||
const theme = getIonTheme(this);
|
||||
const mode = getIonMode(this);
|
||||
@ -394,6 +412,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
[theme]: true,
|
||||
[buttonType]: true,
|
||||
[`${buttonType}-${expand}`]: expand !== undefined,
|
||||
[`${buttonType}-${hue}`]: hue !== undefined,
|
||||
[`${buttonType}-${size}`]: size !== undefined,
|
||||
[`${buttonType}-${shape}`]: true,
|
||||
[`${buttonType}-${fill}`]: true,
|
||||
|
@ -12,6 +12,12 @@
|
||||
<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>
|
||||
|
||||
<style>
|
||||
ion-button {
|
||||
margin: 8px 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -23,6 +29,8 @@
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding ion-text-center" id="content" no-bounce>
|
||||
<h2>Bold (default) Buttons</h2>
|
||||
|
||||
<p>
|
||||
<ion-button id="default">Default</ion-button>
|
||||
<ion-button class="ion-focused">Default.focused</ion-button>
|
||||
@ -83,48 +91,68 @@
|
||||
<ion-button class="ion-activated" color="dark">Dark.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<h2>Subtle Buttons</h2>
|
||||
|
||||
<p>
|
||||
<ion-button style="--opacity: 0.2">Opacity: 0.2</ion-button>
|
||||
<ion-button hue="subtle" id="default">Default</ion-button>
|
||||
<ion-button hue="subtle" class="ion-focused">Default.focused</ion-button>
|
||||
<ion-button hue="subtle" class="ion-activated">Default.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button expand="block" id="disabledButton" disabled>Button Disabled</ion-button>
|
||||
<ion-button expand="block" color="secondary" disabled>Secondary Disabled</ion-button>
|
||||
<ion-button expand="block" color="tertiary" style="--opacity: 1" disabled>Disabled opacity: 1</ion-button>
|
||||
<ion-button hue="subtle" color="primary">Primary</ion-button>
|
||||
<ion-button hue="subtle" color="primary" class="ion-focused">Primary.focused</ion-button>
|
||||
<ion-button hue="subtle" color="primary" class="ion-activated">Primary.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button expand="block" onclick="toggleDisabled()">Toggle Disabled</ion-button>
|
||||
<ion-button hue="subtle" color="secondary">Secondary</ion-button>
|
||||
<ion-button hue="subtle" class="ion-focused" color="secondary">Secondary.focused</ion-button>
|
||||
<ion-button hue="subtle" class="ion-activated" color="secondary">Secondary.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button id="dynamicColor1" onclick="changeColor(event)">Change Color</ion-button>
|
||||
<ion-button id="dynamicColor2" onclick="changeColor(event)" fill="outline">Change Color</ion-button>
|
||||
<ion-button hue="subtle" color="tertiary">Tertiary</ion-button>
|
||||
<ion-button hue="subtle" class="ion-focused" color="tertiary">Tertiary.focused</ion-button>
|
||||
<ion-button hue="subtle" class="ion-activated" color="tertiary">Tertiary.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button hue="subtle" color="success">Success</ion-button>
|
||||
<ion-button hue="subtle" color="success" class="ion-focused">Success.focused</ion-button>
|
||||
<ion-button hue="subtle" color="success" class="ion-activated">Success.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button hue="subtle" color="warning">Warning</ion-button>
|
||||
<ion-button hue="subtle" color="warning" class="ion-focused">Warning.focused</ion-button>
|
||||
<ion-button hue="subtle" color="warning" class="ion-activated">Warning.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button hue="subtle" color="danger">Danger</ion-button>
|
||||
<ion-button hue="subtle" color="danger" class="ion-focused">Danger.focused</ion-button>
|
||||
<ion-button hue="subtle" color="danger" class="ion-activated">Danger.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button hue="subtle" color="light">Light</ion-button>
|
||||
<ion-button hue="subtle" color="light" class="ion-focused">Light.focused</ion-button>
|
||||
<ion-button hue="subtle" color="light" class="ion-activated">Light.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button hue="subtle" color="medium">Medium</ion-button>
|
||||
<ion-button hue="subtle" color="medium" class="ion-focused">Medium.focused</ion-button>
|
||||
<ion-button hue="subtle" color="medium" class="ion-activated">Medium.activated</ion-button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<ion-button hue="subtle" color="dark">Dark</ion-button>
|
||||
<ion-button hue="subtle" color="dark" class="ion-focused">Dark.focused</ion-button>
|
||||
<ion-button hue="subtle" color="dark" class="ion-activated">Dark.activated</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
testingColors = ['primary', 'secondary', 'danger', 'dark'];
|
||||
testingColorIndex = {
|
||||
dynamicColor1: 0,
|
||||
dynamicColor2: 0,
|
||||
};
|
||||
|
||||
function changeColor(ev) {
|
||||
el = ev.currentTarget;
|
||||
|
||||
testingColorIndex[el.id] =
|
||||
testingColorIndex[el.id] >= testingColors.length - 1 ? 0 : testingColorIndex[el.id] + 1;
|
||||
newColor = testingColors[testingColorIndex[el.id]];
|
||||
|
||||
el.color = newColor;
|
||||
}
|
||||
|
||||
function toggleDisabled() {
|
||||
var buttonEl = document.getElementById('disabledButton');
|
||||
buttonEl.disabled = !buttonEl.disabled;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -93,6 +93,7 @@
|
||||
$contrast: map-get($value, contrast);
|
||||
$shade: map-get($value, shade);
|
||||
$tint: map-get($value, tint);
|
||||
$subtle: map-get($value, subtle);
|
||||
|
||||
--ion-color-base: var(--ion-color-#{$color-name}, #{$base}) !important;
|
||||
--ion-color-base-rgb: var(--ion-color-#{$color-name}-rgb, #{color-to-rgb-list($base)}) !important;
|
||||
@ -100,6 +101,7 @@
|
||||
--ion-color-contrast-rgb: var(--ion-color-#{$color-name}-contrast-rgb, #{color-to-rgb-list($contrast)}) !important;
|
||||
--ion-color-shade: var(--ion-color-#{$color-name}-shade, #{$shade}) !important;
|
||||
--ion-color-tint: var(--ion-color-#{$color-name}-tint, #{$tint}) !important;
|
||||
--ion-color-subtle: var(--ion-color-#{$color-name}-subtle, #{$subtle}) !important;
|
||||
}
|
||||
|
||||
// Generates the CSS variables for each color
|
||||
|
@ -17,77 +17,69 @@
|
||||
|
||||
// TODO(ROU-10778, ROU-10875): Sync the color names to the design system of
|
||||
// ios and md. This will allow us to have a single color map.
|
||||
$primary: #105cef;
|
||||
$secondary: initial;
|
||||
$tertiary: initial;
|
||||
$success: #1fbd3b;
|
||||
$warning: #e18300;
|
||||
$danger: #bf2222;
|
||||
$light: #f2f4fd;
|
||||
$medium: initial;
|
||||
$neutral: #626262;
|
||||
$dark: initial;
|
||||
|
||||
$ionic-colors: (
|
||||
primary: (
|
||||
base: $primary,
|
||||
contrast: #fff,
|
||||
shade: color.get-color-shade($primary),
|
||||
tint: color.get-color-tint($primary),
|
||||
base: globals.$ion-semantics-primary-base,
|
||||
contrast: globals.$ion-primitives-base-white,
|
||||
shade: globals.$ion-semantics-primary-800,
|
||||
tint: globals.$ion-semantics-primary-500,
|
||||
subtle: globals.$ion-semantics-primary-100,
|
||||
),
|
||||
secondary: (
|
||||
base: $secondary,
|
||||
contrast: $secondary,
|
||||
shade: color.get-color-shade($secondary),
|
||||
tint: color.get-color-tint($secondary),
|
||||
base: globals.$ion-semantics-info-base,
|
||||
contrast: globals.$ion-primitives-base-white,
|
||||
shade: globals.$ion-semantics-info-800,
|
||||
tint: globals.$ion-semantics-info-500,
|
||||
subtle: globals.$ion-semantics-info-100,
|
||||
),
|
||||
tertiary: (
|
||||
base: $tertiary,
|
||||
contrast: $tertiary,
|
||||
shade: color.get-color-shade($tertiary),
|
||||
tint: color.get-color-tint($tertiary),
|
||||
base: globals.$ion-primitives-violet-700,
|
||||
contrast: globals.$ion-primitives-base-white,
|
||||
shade: globals.$ion-primitives-violet-800,
|
||||
tint: globals.$ion-primitives-violet-500,
|
||||
subtle: globals.$ion-primitives-violet-100,
|
||||
),
|
||||
success: (
|
||||
base: $success,
|
||||
contrast: #000,
|
||||
shade: color.get-color-shade($success),
|
||||
tint: color.get-color-tint($success),
|
||||
base: globals.$ion-semantics-success-base,
|
||||
contrast: globals.$ion-primitives-base-white,
|
||||
shade: globals.$ion-semantics-success-800,
|
||||
tint: globals.$ion-semantics-success-500,
|
||||
subtle: globals.$ion-semantics-success-100,
|
||||
),
|
||||
warning: (
|
||||
base: $warning,
|
||||
contrast: #000,
|
||||
shade: color.get-color-shade($warning),
|
||||
tint: color.get-color-tint($warning),
|
||||
base: globals.$ion-semantics-warning-base,
|
||||
contrast: globals.$ion-primitives-base-white,
|
||||
shade: globals.$ion-semantics-warning-800,
|
||||
tint: globals.$ion-semantics-warning-500,
|
||||
subtle: globals.$ion-semantics-warning-100,
|
||||
),
|
||||
danger: (
|
||||
base: $danger,
|
||||
contrast: #fff,
|
||||
shade: color.get-color-shade($danger),
|
||||
tint: color.get-color-tint($danger),
|
||||
base: globals.$ion-semantics-danger-base,
|
||||
contrast: globals.$ion-primitives-base-white,
|
||||
shade: globals.$ion-semantics-danger-800,
|
||||
tint: globals.$ion-semantics-danger-500,
|
||||
subtle: globals.$ion-semantics-danger-100,
|
||||
),
|
||||
light: (
|
||||
base: $light,
|
||||
contrast: #000,
|
||||
shade: color.get-color-shade($light),
|
||||
tint: color.get-color-tint($light),
|
||||
base: globals.$ion-primitives-neutral-200,
|
||||
contrast: globals.$ion-primitives-base-black,
|
||||
shade: globals.$ion-primitives-neutral-300,
|
||||
tint: globals.$ion-primitives-neutral-100,
|
||||
subtle: globals.$ion-primitives-neutral-100,
|
||||
),
|
||||
medium: (
|
||||
base: $medium,
|
||||
contrast: $medium,
|
||||
shade: color.get-color-shade($medium),
|
||||
tint: color.get-color-tint($medium),
|
||||
),
|
||||
neutral: (
|
||||
base: $neutral,
|
||||
contrast: #fff,
|
||||
shade: color.get-color-shade($neutral),
|
||||
tint: color.get-color-tint($neutral),
|
||||
base: globals.$ion-primitives-neutral-700,
|
||||
contrast: globals.$ion-primitives-base-white,
|
||||
shade: globals.$ion-primitives-neutral-800,
|
||||
tint: globals.$ion-primitives-neutral-500,
|
||||
subtle: globals.$ion-primitives-neutral-100,
|
||||
),
|
||||
dark: (
|
||||
base: $dark,
|
||||
contrast: $dark,
|
||||
shade: color.get-color-shade($dark),
|
||||
tint: color.get-color-tint($dark),
|
||||
base: globals.$ion-primitives-neutral-1100,
|
||||
contrast: globals.$ion-primitives-base-white,
|
||||
shade: globals.$ion-primitives-neutral-1200,
|
||||
tint: globals.$ion-primitives-neutral-900,
|
||||
subtle: globals.$ion-primitives-neutral-100,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -345,14 +345,14 @@ export declare interface IonBreadcrumbs extends Components.IonBreadcrumbs {
|
||||
|
||||
|
||||
@ProxyCmp({
|
||||
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type']
|
||||
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type']
|
||||
})
|
||||
@Component({
|
||||
selector: 'ion-button',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: '<ng-content></ng-content>',
|
||||
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
||||
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'],
|
||||
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'],
|
||||
})
|
||||
export class IonButton {
|
||||
protected el: HTMLElement;
|
||||
|
@ -439,14 +439,14 @@ export declare interface IonBreadcrumbs extends Components.IonBreadcrumbs {
|
||||
|
||||
@ProxyCmp({
|
||||
defineCustomElementFn: defineIonButton,
|
||||
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type']
|
||||
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type']
|
||||
})
|
||||
@Component({
|
||||
selector: 'ion-button',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
template: '<ng-content></ng-content>',
|
||||
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
||||
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'],
|
||||
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'form', 'href', 'hue', 'mode', 'rel', 'routerAnimation', 'routerDirection', 'shape', 'size', 'strong', 'target', 'theme', 'type'],
|
||||
standalone: true
|
||||
})
|
||||
export class IonButton {
|
||||
|
@ -162,6 +162,7 @@ export const IonButton = /*@__PURE__*/ defineContainer<JSX.IonButton>('ion-butto
|
||||
'buttonType',
|
||||
'disabled',
|
||||
'expand',
|
||||
'hue',
|
||||
'fill',
|
||||
'routerDirection',
|
||||
'routerAnimation',
|
||||
|
Reference in New Issue
Block a user