-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Expand file tree
/
Copy pathfab-button.tsx
More file actions
executable file
·236 lines (205 loc) · 7.13 KB
/
fab-button.tsx
File metadata and controls
executable file
·236 lines (205 loc) · 7.13 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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
import xRegular from '@phosphor-icons/core/assets/regular/x.svg';
import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Component, Element, Event, Host, Prop, h } from '@stencil/core';
import type { AnchorInterface, ButtonInterface } from '@utils/element-interface';
import { inheritAriaAttributes, openURL } from '@utils/helpers';
import type { Attributes } from '@utils/helpers';
import { createColorClasses, hostContext } from '@utils/theme';
import { close } from 'ionicons/icons';
import { config } from '../../global/config';
import { getIonTheme } from '../../global/ionic-global';
import type { AnimationBuilder, Color } 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 or anchor element that wraps all child elements.
* @part close-icon - The close icon that is displayed when a fab list opens (uses ion-icon).
*/
@Component({
tag: 'ion-fab-button',
styleUrls: {
ios: 'fab-button.ios.scss',
md: 'fab-button.md.scss',
ionic: 'fab-button.md.scss',
},
shadow: true,
})
export class FabButton implements ComponentInterface, AnchorInterface, ButtonInterface {
private fab: HTMLIonFabElement | null = null;
private inheritedAttributes: 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`, the fab button will be show a close icon.
*/
@Prop() activated = false;
/**
* If `true`, the user cannot interact with the fab button.
*/
@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;
/**
* Specifies where to display the linked URL.
* Only applies when an `href` is provided.
* Special keywords: `"_blank"`, `"_self"`, `"_parent"`, `"_top"`.
*/
@Prop() target: string | undefined;
/**
* If `true`, the fab button will show when in a fab-list.
*/
@Prop() show = false;
/**
* If `true`, the fab button will be translucent.
* Only applies when the theme is `"ios"` and the device supports
* [`backdrop-filter`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter#Browser_compatibility).
*/
@Prop() translucent = false;
/**
* The type of the button.
*/
@Prop() type: 'submit' | 'reset' | 'button' = 'button';
/**
* The size of the button. Set this to `small` in order to have a mini fab button.
*/
@Prop() size?: 'small';
/**
* The icon name to use for the close icon. This will appear when the fab button
* is pressed. Only applies if it is the main button inside of a fab containing a
* fab list.
*/
@Prop() closeIcon?: string;
/**
* Emitted when the button has focus.
*/
@Event() ionFocus!: EventEmitter<void>;
/**
* Emitted when the button loses focus.
*/
@Event() ionBlur!: EventEmitter<void>;
connectedCallback() {
this.fab = this.el.closest('ion-fab');
}
private onFocus = () => {
this.ionFocus.emit();
};
private onBlur = () => {
this.ionBlur.emit();
};
private onClick = () => {
const { fab } = this;
if (!fab) {
return;
}
fab.toggle();
};
componentWillLoad() {
this.inheritedAttributes = inheritAriaAttributes(this.el);
}
get fabButtonCloseIcon() {
// Return the icon if it is explicitly set
if (this.closeIcon != null) {
return this.closeIcon;
}
// Determine the theme and map to default icons
const theme = getIonTheme(this);
const defaultIcons = {
ios: close,
ionic: xRegular,
md: close,
};
// Get the default icon based on the theme, falling back to 'md' icon if necessary
const defaultIcon = defaultIcons[theme] || defaultIcons.md;
// Return the configured fab button close icon or the default icon
return config.get('fabButtonCloseIcon', defaultIcon);
}
render() {
const { el, disabled, fabButtonCloseIcon, color, href, activated, show, translucent, size, inheritedAttributes } =
this;
const inList = hostContext('ion-fab-list', el);
const theme = getIonTheme(this);
const TagType = href === undefined ? 'button' : ('a' as any);
const attrs =
TagType === 'button'
? { type: this.type }
: {
download: this.download,
href,
rel: this.rel,
target: this.target,
};
return (
<Host
onClick={this.onClick}
aria-disabled={disabled ? 'true' : null}
class={createColorClasses(color, {
[theme]: true,
'fab-button-in-list': inList,
'fab-button-translucent-in-list': inList && translucent,
'fab-button-close-active': activated,
'fab-button-show': show,
'fab-button-disabled': disabled,
'fab-button-translucent': translucent,
'ion-activatable': true,
'ion-focusable': true,
[`fab-button-${size}`]: size !== undefined,
})}
>
<TagType
{...attrs}
class="button-native"
part="native"
disabled={disabled}
onFocus={this.onFocus}
onBlur={this.onBlur}
onClick={(ev: Event) => openURL(href, ev, this.routerDirection, this.routerAnimation)}
{...inheritedAttributes}
>
<ion-icon
aria-hidden="true"
icon={fabButtonCloseIcon}
part="close-icon"
class="close-icon"
lazy={false}
></ion-icon>
<span class="button-inner">
<slot></slot>
</span>
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</TagType>
</Host>
);
}
}