mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
feat(components): improve button states and add new css properties (#19440)
Before users had to know the exact opacity that the MD/iOS spec called for in order to change the hover or focused background color. This allows them to change the background without having to know the opacity. - changes apply to Action Sheet (Buttons), Back Button, Button, FAB Button, Item, Menu Button, Segment Button, Tab Button - greatly reduces the requirement by users to set the background hover, focused states for dark modes and custom themes, also eliminates the need to know what the hover opacity is for each based on the spec - updates the MD dark theme per their spec - adds a component guide for internal use changing Ionic components references #18279 fixes #20213 fixes #19965 BREAKING CHANGE: *Activated Class* The `activated` class that is automatically added to buttons on press has been renamed to `ion-activated`. This will be more consistent with our `ion-focused` class we add and also will reduce conflicts with user's CSS. *CSS Variables* The `--background-hover`, `--background-focused` and `--background-activated` CSS variables on components that render native buttons will now have an opacity automatically set. If you are setting any of these like the following: ``` --background-hover: rgba(44, 44, 44, 0.08); ``` You will likely not see a hover state anymore. It should be updated to only set the desired color: ``` --background-hover: rgba(44, 44, 44); ``` If the opacity desired is something other than what the spec asks for, use: ``` --background-hover: rgba(44, 44, 44); --background-hover-opacity: 1; ```
This commit is contained in:
@ -6,9 +6,18 @@
|
||||
|
||||
:host {
|
||||
--background: #{$action-sheet-ios-background-color};
|
||||
--background-selected: #{$action-sheet-ios-button-background-selected};
|
||||
--background-activated: #{$action-sheet-ios-button-background-activated};
|
||||
--backdrop-opacity: var(--ion-backdrop-opacity, 0.4);
|
||||
--button-background: #{$action-sheet-ios-button-background};
|
||||
--button-background-activated: #{$text-color};
|
||||
--button-background-activated-opacity: .08;
|
||||
--button-background-hover: currentColor;
|
||||
--button-background-hover-opacity: .04;
|
||||
--button-background-focused: currentColor;
|
||||
--button-background-focused-opacity: .12;
|
||||
--button-background-selected: #{$action-sheet-ios-button-background-selected};
|
||||
--button-background-selected-opacity: 1;
|
||||
--button-color: #{$action-sheet-ios-button-text-color};
|
||||
--color: #{$action-sheet-ios-title-color};
|
||||
|
||||
text-align: $action-sheet-ios-text-align;
|
||||
}
|
||||
@ -67,13 +76,13 @@
|
||||
backdrop-filter: $action-sheet-ios-button-translucent-filter;
|
||||
}
|
||||
|
||||
:host(.action-sheet-translucent) .action-sheet-button.activated {
|
||||
:host(.action-sheet-translucent) .action-sheet-button.ion-activated {
|
||||
background-color: $action-sheet-ios-translucent-background-color-activated;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
:host(.action-sheet-translucent) .action-sheet-cancel {
|
||||
background: var(--background-selected);
|
||||
background: var(--button-background-selected);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,16 +91,8 @@
|
||||
// Border is made with a linear gradient in order
|
||||
// to get the proper color and iOS blur effect
|
||||
|
||||
.action-sheet-title,
|
||||
.action-sheet-button {
|
||||
background-color: transparent;
|
||||
background-image: linear-gradient(0deg, $action-sheet-ios-button-border-color, $action-sheet-ios-button-border-color 50%, transparent 50%);
|
||||
background-repeat: no-repeat;
|
||||
|
||||
/* stylelint-disable-next-line all */
|
||||
background-position: bottom;
|
||||
|
||||
background-size: 100% 1px;
|
||||
.action-sheet-title {
|
||||
background: $action-sheet-ios-button-background;
|
||||
}
|
||||
|
||||
|
||||
@ -124,8 +125,6 @@
|
||||
|
||||
height: $action-sheet-ios-button-height;
|
||||
|
||||
color: var(--color, $action-sheet-ios-button-text-color);
|
||||
|
||||
font-size: $action-sheet-ios-button-font-size;
|
||||
|
||||
contain: strict;
|
||||
@ -142,17 +141,30 @@
|
||||
}
|
||||
|
||||
.action-sheet-selected {
|
||||
background: var(--background-selected);
|
||||
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.action-sheet-destructive {
|
||||
color: $action-sheet-ios-button-destructive-text-color;
|
||||
.action-sheet-cancel {
|
||||
font-weight: $action-sheet-ios-button-cancel-font-weight;
|
||||
|
||||
&::after {
|
||||
background: var(--button-background-selected);
|
||||
|
||||
opacity: var(--button-background-selected-opacity);
|
||||
}
|
||||
}
|
||||
|
||||
.action-sheet-cancel {
|
||||
background: var(--background-selected);
|
||||
// iOS Action Sheet Button: Destructive
|
||||
// ---------------------------------------------------
|
||||
|
||||
font-weight: $action-sheet-ios-button-cancel-font-weight;
|
||||
.action-sheet-destructive,
|
||||
.action-sheet-destructive.ion-activated,
|
||||
.action-sheet-destructive.ion-focused {
|
||||
color: $action-sheet-ios-button-destructive-text-color;
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.action-sheet-destructive:hover {
|
||||
color: $action-sheet-ios-button-destructive-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ $action-sheet-ios-button-border-color-alpha: .08 !default;
|
||||
$action-sheet-ios-button-border-color: rgba($text-color-rgb, $action-sheet-ios-button-border-color-alpha) !default;
|
||||
|
||||
/// @prop - Background color of the action sheet button
|
||||
$action-sheet-ios-button-background: transparent !default;
|
||||
$action-sheet-ios-button-background: linear-gradient(0deg, $action-sheet-ios-button-border-color, $action-sheet-ios-button-border-color 50%, transparent 50%) bottom / 100% 1px no-repeat transparent !default;
|
||||
|
||||
/// @prop - Background color alpha of the activated action sheet button
|
||||
$action-sheet-ios-button-background-alpha-activated: .08 !default;
|
||||
|
||||
@ -6,9 +6,18 @@
|
||||
|
||||
:host {
|
||||
--background: #{$action-sheet-md-background-color};
|
||||
--background-selected: #{var(--background, $action-sheet-md-button-background-selected)};
|
||||
--background-activated: var(--background);
|
||||
--backdrop-opacity: var(--ion-backdrop-opacity, 0.32);
|
||||
--button-background: transparent;
|
||||
--button-background-selected: currentColor;
|
||||
--button-background-selected-opacity: 0;
|
||||
--button-background-activated: transparent;
|
||||
--button-background-activated-opacity: 0;
|
||||
--button-background-hover: currentColor;
|
||||
--button-background-hover-opacity: .04;
|
||||
--button-background-focused: currentColor;
|
||||
--button-background-focused-opacity: .12;
|
||||
--button-color: #{var(--color, $action-sheet-md-button-text-color)};
|
||||
--color: #{$action-sheet-md-button-text-color};
|
||||
}
|
||||
|
||||
.action-sheet-title {
|
||||
@ -52,9 +61,6 @@
|
||||
|
||||
height: $action-sheet-md-button-height;
|
||||
|
||||
background: transparent;
|
||||
color: var(--color, $action-sheet-md-button-text-color);
|
||||
|
||||
font-size: $action-sheet-md-button-font-size;
|
||||
|
||||
text-align: $action-sheet-md-text-align;
|
||||
@ -67,7 +73,7 @@
|
||||
@include padding(null, null, 4px, null);
|
||||
@include margin($action-sheet-md-icon-margin-top, $action-sheet-md-icon-margin-end, $action-sheet-md-icon-margin-bottom, $action-sheet-md-icon-margin-start);
|
||||
|
||||
color: var(--color, $action-sheet-md-icon-color);
|
||||
color: #{$action-sheet-md-icon-color};
|
||||
|
||||
font-size: $action-sheet-md-icon-font-size;
|
||||
}
|
||||
|
||||
@ -87,13 +87,6 @@ $action-sheet-md-button-padding-start: $action-sheet-md-button-
|
||||
/// @prop - Background color of the action sheet button
|
||||
$action-sheet-md-button-background: transparent !default;
|
||||
|
||||
/// @prop - Background color of the action sheet activated button
|
||||
$action-sheet-md-button-background-activated: $background-color-step-50 !default;
|
||||
|
||||
/// @prop - Background color of the selected action sheet button
|
||||
$action-sheet-md-button-background-selected: null !default;
|
||||
|
||||
|
||||
// Action Sheet Icon
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
@ -6,9 +6,6 @@
|
||||
:host {
|
||||
/**
|
||||
* @prop --background: Background of the action sheet group
|
||||
* @prop --background-activated: Background of the action sheet button when pressed
|
||||
* @prop --background-selected: Background of the selected action sheet button
|
||||
*
|
||||
* @prop --color: Color of the action sheet text
|
||||
*
|
||||
* @prop --min-width: Minimum width of the action sheet
|
||||
@ -20,8 +17,28 @@
|
||||
* @prop --max-height: Maximum height of the action sheet
|
||||
*
|
||||
* @prop --backdrop-opacity: Opacity of the backdrop
|
||||
*
|
||||
* @prop --button-background: Background of the action sheet button
|
||||
* @prop --button-background-activated: Background of the action sheet button when pressed. Note: setting this will interfere with the Material Design ripple.
|
||||
* @prop --button-background-activated-opacity: Opacity of the action sheet button background when pressed
|
||||
* @prop --button-background-hover: Background of the action sheet button on hover
|
||||
* @prop --button-background-hover-opacity: Opacity of the action sheet button background on hover
|
||||
* @prop --button-background-focused: Background of the action sheet button when tabbed to
|
||||
* @prop --button-background-focused-opacity: Opacity of the action sheet button background when tabbed to
|
||||
* @prop --button-background-selected: Background of the selected action sheet button
|
||||
* @prop --button-background-selected-opacity: Opacity of the selected action sheet button background
|
||||
*
|
||||
* @prop --button-color: Color of the action sheet button
|
||||
* @prop --button-color-activated: Color of the action sheet button when pressed
|
||||
* @prop --button-color-hover: Color of the action sheet button on hover
|
||||
* @prop --button-color-focused: Color of the action sheet button when tabbed to
|
||||
* @prop --button-color-selected: Color of the selected action sheet button
|
||||
*/
|
||||
--color: initial;
|
||||
--button-color-activated: var(--button-color);
|
||||
--button-color-focused: var(--button-color);
|
||||
--button-color-hover: var(--button-color);
|
||||
--button-color-selected: var(--button-color);
|
||||
--min-width: auto;
|
||||
--width: #{$action-sheet-width};
|
||||
--max-width: #{$action-sheet-max-width};
|
||||
@ -68,6 +85,7 @@
|
||||
|
||||
.action-sheet-button {
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
width: 100%;
|
||||
|
||||
@ -75,16 +93,19 @@
|
||||
|
||||
outline: none;
|
||||
|
||||
background: var(--button-background);
|
||||
color: var(--button-color);
|
||||
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.action-sheet-button.activated {
|
||||
background: var(--background-activated);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.action-sheet-button-inner {
|
||||
display: flex;
|
||||
|
||||
position: relative;
|
||||
|
||||
flex-flow: row nowrap;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
@ -92,6 +113,8 @@
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.action-sheet-container {
|
||||
@ -124,6 +147,67 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
// Action Sheet: States
|
||||
// --------------------------------------------------
|
||||
|
||||
.action-sheet-button::after {
|
||||
@include button-state();
|
||||
}
|
||||
|
||||
|
||||
// Action Sheet: Selected
|
||||
// --------------------------------------------------
|
||||
|
||||
.action-sheet-selected {
|
||||
background: var(--background-selected);
|
||||
color: var(--button-color-selected);
|
||||
|
||||
&::after {
|
||||
background: var(--button-background-selected);
|
||||
|
||||
opacity: var(--button-background-selected-opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Action Sheet: Activated
|
||||
// --------------------------------------------------
|
||||
|
||||
.action-sheet-button.ion-activated {
|
||||
color: var(--button-color-activated);
|
||||
|
||||
&::after {
|
||||
background: var(--button-background-activated);
|
||||
|
||||
opacity: var(--button-background-activated-opacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Action Sheet: Focused
|
||||
// --------------------------------------------------
|
||||
|
||||
.action-sheet-button.ion-focused {
|
||||
color: var(--button-color-focused);
|
||||
|
||||
&::after {
|
||||
background: var(--button-background-focused);
|
||||
|
||||
opacity: var(--button-background-focused-opacity);
|
||||
}
|
||||
}
|
||||
|
||||
// Action Sheet: Hover
|
||||
// --------------------------------------------------
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.action-sheet-button:hover {
|
||||
color: var(--button-color-hover);
|
||||
|
||||
&::after {
|
||||
background: var(--button-background-hover);
|
||||
|
||||
opacity: var(--button-background-hover-opacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -226,7 +226,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
</div>
|
||||
}
|
||||
{buttons.map(b =>
|
||||
<button type="button" ion-activatable class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
|
||||
<button type="button" class={buttonClass(b)} onClick={() => this.buttonClick(b)}>
|
||||
<span class="action-sheet-button-inner">
|
||||
{b.icon && <ion-icon icon={b.icon} lazy={false} class="action-sheet-icon" />}
|
||||
{b.text}
|
||||
@ -252,6 +252,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
/>}
|
||||
{cancelButton.text}
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
@ -266,6 +267,7 @@ const buttonClass = (button: ActionSheetButton): CssClassMap => {
|
||||
return {
|
||||
'action-sheet-button': true,
|
||||
'ion-activatable': true,
|
||||
'ion-focusable': true,
|
||||
[`action-sheet-${button.role}`]: button.role !== undefined,
|
||||
...getClassMap(button.cssClass),
|
||||
};
|
||||
|
||||
@ -319,19 +319,31 @@ Type: `Promise<void>`
|
||||
|
||||
## CSS Custom Properties
|
||||
|
||||
| Name | Description |
|
||||
| ------------------------ | -------------------------------------------------- |
|
||||
| `--backdrop-opacity` | Opacity of the backdrop |
|
||||
| `--background` | Background of the action sheet group |
|
||||
| `--background-activated` | Background of the action sheet button when pressed |
|
||||
| `--background-selected` | Background of the selected action sheet button |
|
||||
| `--color` | Color of the action sheet text |
|
||||
| `--height` | height of the action sheet |
|
||||
| `--max-height` | Maximum height of the action sheet |
|
||||
| `--max-width` | Maximum width of the action sheet |
|
||||
| `--min-height` | Minimum height of the action sheet |
|
||||
| `--min-width` | Minimum width of the action sheet |
|
||||
| `--width` | Width of the action sheet |
|
||||
| Name | Description |
|
||||
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--backdrop-opacity` | Opacity of the backdrop |
|
||||
| `--background` | Background of the action sheet group |
|
||||
| `--button-background` | Background of the action sheet button |
|
||||
| `--button-background-activated` | Background of the action sheet button when pressed. Note: setting this will interfere with the Material Design ripple. |
|
||||
| `--button-background-activated-opacity` | Opacity of the action sheet button background when pressed |
|
||||
| `--button-background-focused` | Background of the action sheet button when tabbed to |
|
||||
| `--button-background-focused-opacity` | Opacity of the action sheet button background when tabbed to |
|
||||
| `--button-background-hover` | Background of the action sheet button on hover |
|
||||
| `--button-background-hover-opacity` | Opacity of the action sheet button background on hover |
|
||||
| `--button-background-selected` | Background of the selected action sheet button |
|
||||
| `--button-background-selected-opacity` | Opacity of the selected action sheet button background |
|
||||
| `--button-color` | Color of the action sheet button |
|
||||
| `--button-color-activated` | Color of the action sheet button when pressed |
|
||||
| `--button-color-focused` | Color of the action sheet button when tabbed to |
|
||||
| `--button-color-hover` | Color of the action sheet button on hover |
|
||||
| `--button-color-selected` | Color of the selected action sheet button |
|
||||
| `--color` | Color of the action sheet text |
|
||||
| `--height` | height of the action sheet |
|
||||
| `--max-height` | Maximum height of the action sheet |
|
||||
| `--max-width` | Maximum width of the action sheet |
|
||||
| `--min-height` | Minimum height of the action sheet |
|
||||
| `--min-width` | Minimum width of the action sheet |
|
||||
| `--width` | Width of the action sheet |
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
@ -40,10 +40,10 @@
|
||||
<style>
|
||||
.my-color-class {
|
||||
--background: #292929;
|
||||
--background-selected: #222222;
|
||||
--button-background-selected: #222222;
|
||||
|
||||
--color: #dfdfdf;
|
||||
;
|
||||
--button-color: #dfdfdf;
|
||||
}
|
||||
|
||||
.my-custom-class {
|
||||
@ -65,7 +65,7 @@
|
||||
const actionSheet = await actionSheetController.create(opts);
|
||||
await actionSheet.present();
|
||||
}
|
||||
|
||||
|
||||
async function presentBasic() {
|
||||
const mode = Ionic.mode;
|
||||
await openActionSheet({
|
||||
@ -80,7 +80,7 @@
|
||||
}, {
|
||||
text: 'Share',
|
||||
icon: 'share',
|
||||
cssClass: 'activated',
|
||||
cssClass: 'ion-activated',
|
||||
handler: () => {
|
||||
console.log('Share clicked');
|
||||
}
|
||||
@ -152,7 +152,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function presentWithCssClass(classList) {
|
||||
async function presentWithCssClass(classList) {
|
||||
await openActionSheet({
|
||||
header: "Custom Css Class",
|
||||
cssClass: classList ? classList : "my-color-class my-custom-class",
|
||||
@ -160,7 +160,7 @@
|
||||
{
|
||||
text: 'Add to Favorites',
|
||||
icon: 'star',
|
||||
cssClass: 'my-custom-button customClass activated',
|
||||
cssClass: 'my-custom-button customClass ion-activated',
|
||||
handler: () => {
|
||||
console.log('Add to Favorites clicked');
|
||||
}
|
||||
@ -272,7 +272,7 @@
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Text',
|
||||
cssClass: 'activated',
|
||||
cssClass: 'ion-activated',
|
||||
handler: () => {
|
||||
console.log('Copy Text clicked');
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@
|
||||
}
|
||||
}, {
|
||||
text: 'Copy Text',
|
||||
cssClass: 'activated',
|
||||
cssClass: 'ion-activated',
|
||||
handler: () => {
|
||||
console.log('Copy Text clicked');
|
||||
}
|
||||
@ -185,7 +185,7 @@
|
||||
}
|
||||
}, {
|
||||
text: 'Edit Title',
|
||||
cssClass: 'activated',
|
||||
cssClass: 'ion-activated',
|
||||
handler: () => {
|
||||
console.log('Edit Title clicked');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user