feat(card): add button functionality (#17997)

closes #17773
This commit is contained in:
Josh Beard
2019-05-07 15:12:28 -04:00
committed by Brandy Carney
parent ef989779b0
commit 669ec0da3d
9 changed files with 266 additions and 9 deletions

View File

@@ -13,7 +13,13 @@
transform: translateZ(0);
transition: transform 500ms $card-ios-transition-timing-function;
font-size: $card-ios-font-size;
box-shadow: $card-ios-box-shadow;
}
:host(.activated) {
transform: #{$card-ios-transform-activated};
}

View File

@@ -32,3 +32,9 @@ $card-ios-font-size: 14px !default;
/// @prop - Color of the card text
$card-ios-text-color: $text-color-step-400 !default;
/// @prop - Transition timing function of the card
$card-ios-transition-timing-function: cubic-bezier(0.12, 0.72, 0.29, 1) !default;
/// @prop - Transform of the card on activate
$card-ios-transform-activated: scale3d(.97, .97, 1) !default;

View File

@@ -50,3 +50,54 @@
::slotted(*) ion-list {
@include margin(0);
}
// Disabled Card
// --------------------------------------------------
:host(.card-disabled) {
cursor: default;
opacity: .3;
pointer-events: none;
}
// Native
// --------------------------------------------------
.card-native {
@include text-inherit();
@include padding(0);
@include margin(0);
width: 100%;
min-height: var(--min-height);
transition: var(--transition);
border-width: var(--border-width);
border-style: var(--border-style);
border-color: var(--border-color);
outline: none;
background: var(--background);
}
.card-native::-moz-focus-inner {
border: 0;
}
button, a {
cursor: pointer;
user-select: none;
-webkit-user-drag: none;
}
// Card Button Ripple effect
// --------------------------------------------------
ion-ripple-effect {
color: var(--ripple-color);
}

View File

@@ -1,7 +1,7 @@
import { Component, ComponentInterface, Prop } from '@stencil/core';
import { Color, Mode } from '../../interface';
import { createColorClasses } from '../../utils/theme';
import { Color, Mode, RouterDirection } from '../../interface';
import { createColorClasses, openURL } from '../../utils/theme';
@Component({
tag: 'ion-card',
@@ -13,6 +13,8 @@ import { createColorClasses } from '../../utils/theme';
})
export class Card implements ComponentInterface {
@Prop({ context: 'window' }) win!: Window;
/**
* The color to use from your application's color palette.
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
@@ -25,12 +27,72 @@ export class Card implements ComponentInterface {
*/
@Prop() mode!: Mode;
/**
* If `true`, a button tag will be rendered and the card will be tappable.
*/
@Prop() button = false;
/**
* The type of the button. Only used when an `onclick` or `button` property is present.
*/
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
/**
* If `true`, the user cannot interact with the card.
*/
@Prop() disabled = false;
/**
* Contains a URL or a URL fragment that the hyperlink points to.
* If this property is set, an anchor tag will be rendered.
*/
@Prop() href?: string;
/**
* When using a router, it specifies the transition direction when navigating to
* another page using `href`.
*/
@Prop() routerDirection: RouterDirection = 'forward';
private isClickable(): boolean {
return (this.href !== undefined || this.button);
}
hostData() {
return {
class: {
[`${this.mode}`]: true,
...createColorClasses(this.color),
[`${this.mode}`]: true
'card-disabled': this.disabled,
'ion-activatable': this.isClickable()
}
};
}
render() {
const clickable = this.isClickable();
if (!clickable) {
return [
<slot></slot>
];
}
const { href, mode, win, routerDirection, type } = this;
const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div' as any;
const attrs = TagType === 'button' ? { type } : { href };
return (
<TagType
{...attrs}
class="card-native"
disabled={this.disabled}
onClick={(ev: Event) => openURL(win, href, ev, routerDirection)}
>
<slot></slot>
{clickable && mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</TagType>
);
}
}

View File

@@ -182,10 +182,15 @@ export default Example;
## Properties
| Property | Attribute | Description | Type | Default |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ----------- |
| `color` | `color` | 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). | `string \| undefined` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
| Property | Attribute | Description | Type | Default |
| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ----------- |
| `button` | `button` | If `true`, a button tag will be rendered and the card will be tappable. | `boolean` | `false` |
| `color` | `color` | 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). | `string \| undefined` | `undefined` |
| `disabled` | `disabled` | If `true`, the user cannot interact with the card. | `boolean` | `false` |
| `href` | `href` | Contains a URL or a URL fragment that the hyperlink points to. If this property is set, an anchor tag will be rendered. | `string \| undefined` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
| `routerDirection` | `router-direction` | When using a router, it specifies the transition direction when navigating to another page using `href`. | `"back" \| "forward" \| "root"` | `'forward'` |
| `type` | `type` | The type of the button. Only used when an `onclick` or `button` property is present. | `"button" \| "reset" \| "submit"` | `'button'` |
## CSS Custom Properties

View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="UTF-8">
<title>Card - 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 src="../../../../../dist/ionic.js"></script>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Card - Button</ion-title>
</ion-toolbar>
</ion-header>
<ion-content id="content">
<ion-card button>
<ion-card-header>
<ion-card-subtitle>
Subtitle
</ion-card-subtitle>
<ion-card-title>
Button Card
</ion-card-title>
</ion-card-header>
<ion-card-content>
This is content, inside of a card with a button attribute.
</ion-card-content>
</ion-card>
<ion-card href="#">
<ion-card-header>
<ion-card-title>
Anchor Card
</ion-card-title>
</ion-card-header>
<ion-card-content>
This is content, inside of a card with a href attribute.
</ion-card-content>
</ion-card>
<ion-card button>
<div style="position: absolute; top: 0; left:0; right:0; bottom:0;">
<img src="https://images.unsplash.com/photo-1483354483454-4cd359948304?dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D">
</div>
<ion-card-header>
<ion-card-subtitle>
Subtitle
</ion-card-subtitle>
<ion-card-title>
Title
</ion-card-title>
</ion-card-header>
<ion-card-content>
This button should have a background.
</ion-card-content>
</ion-card>
</ion-content>
</ion-app>
<style>
.content {
background: #e5e5e5;
}
</style>
</body>
</html>