-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Expand file tree
/
Copy pathcard.tsx
More file actions
158 lines (137 loc) · 4.96 KB
/
card.tsx
File metadata and controls
158 lines (137 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import type { ComponentInterface } from '@stencil/core';
import { Element, Component, Host, Prop, h } from '@stencil/core';
import type { AnchorInterface, ButtonInterface } from '@utils/element-interface';
import type { Attributes } from '@utils/helpers';
import { inheritAttributes, openURL } from '@utils/helpers';
import { createColorClasses } from '@utils/theme';
import { getIonTheme } from '../../global/ionic-global';
import type { AnimationBuilder, Color, Theme } from '../../interface';
import type { RouterDirection } from '../router/utils/interface';
/**
* @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.
*
* @part native - The native HTML button, anchor, or div element that wraps all child elements.
*/
@Component({
tag: 'ion-card',
styleUrls: {
ios: 'card.ios.scss',
md: 'card.md.scss',
ionic: 'card.ionic.scss',
},
shadow: true,
})
export class Card implements ComponentInterface, AnchorInterface, ButtonInterface {
private inheritedAriaAttributes: Attributes = {};
@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;
/**
* 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;
/**
* This attribute instructs browsers to download a URL instead of navigating to
* it, so the user will be prompted to save it as a local file. If the attribute
* has a value, it is used as the pre-filled file name in the Save prompt
* (the user can still change the file name if they want).
*/
@Prop() download: string | undefined;
/**
* 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 | undefined;
/**
* Specifies the relationship of the target object to the link object.
* The value is a space-separated list of [link types](https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types).
*/
@Prop() rel: string | undefined;
/**
* When using a router, it specifies the transition direction when navigating to
* another page using `href`.
*/
@Prop() routerDirection: RouterDirection = 'forward';
/**
* When using a router, it specifies the transition animation when navigating to
* another page using `href`.
*/
@Prop() routerAnimation: AnimationBuilder | undefined;
/**
* Set to `"soft"` for a card with slightly rounded corners, `"round"` for a card with more
* rounded corners, or `"rectangular"` for a card without rounded corners.
* Defaults to `"round"`.
*/
@Prop({ reflect: true }) shape?: 'soft' | 'round' | 'rectangular' = 'round';
/**
* Specifies where to display the linked URL.
* Only applies when an `href` is provided.
* Special keywords: `"_blank"`, `"_self"`, `"_parent"`, `"_top"`.
*/
@Prop() target: string | undefined;
componentWillLoad() {
this.inheritedAriaAttributes = inheritAttributes(this.el, ['aria-label']);
}
private isClickable(): boolean {
return this.href !== undefined || this.button;
}
private renderCard(theme: Theme) {
const clickable = this.isClickable();
if (!clickable) {
return [<slot></slot>];
}
const { href, routerAnimation, routerDirection, inheritedAriaAttributes } = this;
const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any);
const attrs =
TagType === 'button'
? { type: this.type }
: {
download: this.download,
href: this.href,
rel: this.rel,
target: this.target,
};
return (
<TagType
{...attrs}
{...inheritedAriaAttributes}
class="card-native"
part="native"
disabled={this.disabled}
onClick={(ev: Event) => openURL(href, ev, routerDirection, routerAnimation)}
>
<slot></slot>
{clickable && theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</TagType>
);
}
render() {
const { shape } = this;
const theme = getIonTheme(this);
return (
<Host
class={createColorClasses(this.color, {
[theme]: true,
[`card-${shape}`]: shape !== undefined,
'card-disabled': this.disabled,
'ion-activatable': this.isClickable(),
})}
>
{this.renderCard(theme)}
</Host>
);
}
}