ember-safe-button 3.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,239 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { assert } from '@ember/debug';
4
+ import { action } from '@ember/object';
5
+ import { hash } from '@ember/helper';
6
+
7
+ import { timeout } from 'ember-concurrency';
8
+ import { task } from 'ember-concurrency';
9
+
10
+ import embeddedAnimations from './animations/index.js';
11
+ import Safety from '../safety/index.gjs';
12
+ import Trigger from '../trigger/index.gjs';
13
+ import { SAFETY_STATUS } from '../../states.js';
14
+
15
+ const DEFAULT_TIMEOUT = 3000;
16
+ const DEFAULT_ANIMATION = 'slide';
17
+ console.log('DEBUG: ember-safe-button loaded');
18
+
19
+ /**
20
+ Main component.
21
+
22
+ ```hbs
23
+ <SafeButton
24
+ class="border-black"
25
+ @animation={{this.animation}}
26
+ @message="Delete me"
27
+ @timeout={{2000}}
28
+ @onConfirm={{action safeButtonClicked}} />
29
+ ```
30
+
31
+ ```
32
+ @class SafeButtonComponent
33
+ @param {string} [class="ember-safe-button"] CSS class to be applied on the wrapping element.
34
+ @param {object} [animation="slid"] Definition of animation; It can either be string and point to one of the pre-defined animations; Or it can be an object describing Web Animation API
35
+ @param {number} [timeout=3000] Number of millisenconds after which the safety rolls back over the trigger.
36
+ @param {string} [message="delete"] Text to be printed on the buttons in case block is not provided.
37
+ @param {function} onConfirm - Action to trigger whenever user clicks the trigger.
38
+ ```
39
+
40
+ When trying to construct your own `@animation` object you can take inspiration from the simple `slide` animation. The thing to keep in mind is that these go directly as parameters to [element.animate()](https://developer.mozilla.org/en-US/docs/Web/API/Element/animate) and that there are in fact four animations of which always two fire at the same time:
41
+
42
+ - `safety.unlocking` and `trigger.unlocking`
43
+ - `safety.locking` and `trigger.locking`
44
+
45
+ ```js
46
+ {
47
+ safety: {
48
+ unlocking: {
49
+ keyframes: [
50
+ { transform: 'translateX(0)' },
51
+ { transform: 'translateX(-100%)' },
52
+ ],
53
+ options: {
54
+ duration: 1000,
55
+ fill: 'both',
56
+ easing: 'ease',
57
+ },
58
+ },
59
+ locking: {
60
+ keyframes: [
61
+ { transform: 'translateX(-100%)' },
62
+ { transform: 'translateX(0)' },
63
+ ],
64
+ options: {
65
+ duration: 1000,
66
+ fill: 'both',
67
+ easing: 'ease',
68
+ },
69
+ },
70
+ },
71
+ trigger: {
72
+ unlocking: {
73
+ keyframes: [
74
+ { transform: 'translateX(100%)' },
75
+ { transform: 'translateX(0)' },
76
+ ],
77
+ options: {
78
+ duration: 1000,
79
+ fill: 'both',
80
+ easing: 'ease',
81
+ },
82
+ },
83
+ locking: {
84
+ keyframes: [
85
+ { transform: 'translateX(0)' },
86
+ { transform: 'translateX(100%)' },
87
+ ],
88
+ options: {
89
+ duration: 1000,
90
+ fill: 'both',
91
+ easing: 'ease',
92
+ },
93
+ },
94
+ },
95
+ }
96
+ ```
97
+ */
98
+ export default class SafeButtonComponent extends Component {
99
+ constructor() {
100
+ super(...arguments);
101
+
102
+ assert(
103
+ '@onConfirm attribute must be set',
104
+ typeof this.args.onConfirm === 'function',
105
+ );
106
+ }
107
+
108
+ @tracked safetyStatus = SAFETY_STATUS.LOCKED;
109
+
110
+ get activeAnimation() {
111
+ const animation = this.args.animation || DEFAULT_ANIMATION;
112
+
113
+ return typeof animation === 'string'
114
+ ? embeddedAnimations[animation]
115
+ : animation;
116
+ }
117
+
118
+ get webAnimations() {
119
+ const { activeAnimation, onUnlocked, onLocked } = this;
120
+
121
+ return {
122
+ safety: {
123
+ unlocking: ({ element }) => {
124
+ let animation = element.animate(
125
+ activeAnimation.safety.unlocking.keyframes,
126
+ activeAnimation.safety.unlocking.options,
127
+ );
128
+ animation.onfinish = onUnlocked;
129
+ },
130
+ locking: ({ element }) => {
131
+ let animation = element.animate(
132
+ activeAnimation.safety.locking.keyframes,
133
+ activeAnimation.safety.locking.options,
134
+ );
135
+ animation.onfinish = onLocked;
136
+ },
137
+ },
138
+ trigger: {
139
+ unlocking({ element }) {
140
+ element.animate(
141
+ activeAnimation.trigger.unlocking.keyframes,
142
+ activeAnimation.trigger.unlocking.options,
143
+ );
144
+ },
145
+ locking({ element }) {
146
+ element.animate(
147
+ activeAnimation.trigger.locking.keyframes,
148
+ activeAnimation.trigger.locking.options,
149
+ );
150
+ },
151
+ },
152
+ };
153
+ }
154
+
155
+ get timeout() {
156
+ return this.args.timeout || DEFAULT_TIMEOUT;
157
+ }
158
+
159
+ get displayedMessage() {
160
+ return this.args.message || 'delete';
161
+ }
162
+
163
+ @action
164
+ onUnlocking() {
165
+ this.safetyStatus = SAFETY_STATUS.UNLOCKING;
166
+ }
167
+
168
+ @action
169
+ onUnlocked() {
170
+ this.safetyStatus = SAFETY_STATUS.UNLOCKED;
171
+ this.triggerSafety.perform();
172
+ }
173
+
174
+ @action
175
+ onLocked() {
176
+ this.safetyStatus = SAFETY_STATUS.LOCKED;
177
+ }
178
+
179
+ triggerSafety = task(async () => {
180
+ await timeout(this.timeout);
181
+ this.safetyStatus = SAFETY_STATUS.LOCKING;
182
+ });
183
+
184
+ triggerInstance = <template>
185
+ <Trigger
186
+ @onClick={{@onConfirm}}
187
+ @safetyStatus={{this.safetyStatus}}
188
+ @displayedMessage={{this.displayedMessage}}
189
+ @webAnimations={{this.webAnimations.trigger}}
190
+ />
191
+ </template>;
192
+
193
+ safetyInstance = <template>
194
+ <Safety
195
+ @onClick={{this.onUnlocking}}
196
+ @safetyStatus={{this.safetyStatus}}
197
+ @displayedMessage={{this.displayedMessage}}
198
+ @webAnimations={{this.webAnimations.safety}}
199
+ />
200
+ </template>;
201
+
202
+ <template>
203
+ <div class="ember-safe-button" ...attributes>
204
+ {{#if (has-block)}}
205
+ {{yield
206
+ (hash
207
+ trigger=(component
208
+ Trigger
209
+ onClick=@onConfirm
210
+ safetyStatus=this.safetyStatus
211
+ displayedMessage=this.displayedMessage
212
+ webAnimations=this.webAnimations.trigger
213
+ )
214
+ safety=(component
215
+ Safety
216
+ onClick=this.onUnlocking
217
+ safetyStatus=this.safetyStatus
218
+ displayedMessage=this.displayedMessage
219
+ webAnimations=this.webAnimations.safety
220
+ )
221
+ )
222
+ }}
223
+ {{else}}
224
+ <Trigger
225
+ @onClick={{@onConfirm}}
226
+ @safetyStatus={{this.safetyStatus}}
227
+ @displayedMessage={{this.displayedMessage}}
228
+ @webAnimations={{this.webAnimations.trigger}}
229
+ />
230
+ <Safety
231
+ @onClick={{this.onUnlocking}}
232
+ @safetyStatus={{this.safetyStatus}}
233
+ @displayedMessage={{this.displayedMessage}}
234
+ @webAnimations={{this.webAnimations.safety}}
235
+ />
236
+ {{/if}}
237
+ </div>
238
+ </template>
239
+ }
@@ -0,0 +1,67 @@
1
+ import Component from '@glimmer/component';
2
+
3
+ import { on } from '@ember/modifier';
4
+ import animateMe from '../../modifiers/animate-me.js';
5
+ import { SAFETY_STATUS } from '../../states.js';
6
+
7
+ export const BASIC_CLASS = 'ember-safe-button-safety';
8
+ export const ARIA_LABELS = {
9
+ [SAFETY_STATUS.LOCKED]: 'Deactivate safety',
10
+ [SAFETY_STATUS.UNLOCKING]: 'Deactivating safety',
11
+ [SAFETY_STATUS.UNLOCKED]: 'Safety not active',
12
+ [SAFETY_STATUS.LOCKING]: 'Activating safety',
13
+ };
14
+
15
+ /**
16
+ Safety is a component that covers the trigger.
17
+
18
+ ```hbs
19
+ <SafeButton
20
+ @onConfirm={{action safeButtonClicked}} as |button|
21
+ >
22
+ <button.safety class="bg-grey-light">
23
+ This is safety
24
+ </button.safety>
25
+ </SafeButton>
26
+ ```
27
+
28
+ @class SafetyComponent
29
+ */
30
+ export default class SafetyComponent extends Component {
31
+ BASIC_CLASS = BASIC_CLASS;
32
+
33
+ get isDisabled() {
34
+ return this.args.safetyStatus === SAFETY_STATUS.UNLOCKED;
35
+ }
36
+
37
+ get focusMe() {
38
+ return !this.isDisabled;
39
+ }
40
+
41
+ get ariaLabel() {
42
+ return ARIA_LABELS[this.args.safetyStatus];
43
+ }
44
+
45
+ <template>
46
+ <button
47
+ class={{this.BASIC_CLASS}}
48
+ disabled={{this.isDisabled}}
49
+ aria-label={{this.ariaLabel}}
50
+ type="button"
51
+ tabindex={{if this.isDisabled "-1" "0"}}
52
+ ...attributes
53
+ {{on "click" @onClick}}
54
+ {{animateMe
55
+ safetyStatus=@safetyStatus
56
+ webAnimations=@webAnimations
57
+ focusMe=this.focusMe
58
+ }}
59
+ >
60
+ {{#if (has-block)}}
61
+ {{yield}}
62
+ {{else}}
63
+ {{@displayedMessage}}
64
+ {{/if}}
65
+ </button>
66
+ </template>
67
+ }
@@ -0,0 +1,57 @@
1
+ import Component from '@glimmer/component';
2
+ import { on } from '@ember/modifier';
3
+ import animateMe from '../../modifiers/animate-me.js';
4
+
5
+ import { SAFETY_STATUS } from '../../states.js';
6
+
7
+ export const BASIC_CLASS = 'ember-safe-button-trigger';
8
+
9
+ /**
10
+ Trigger is a component that is by default covered by safety and triggers the action passed to <SafeButton> when clicked.
11
+
12
+ ```hbs
13
+ <SafeButton
14
+ @onConfirm={{action safeButtonClicked}} as |button|
15
+ >
16
+ <button.trigger class="bg-red-dark">
17
+ Trigger
18
+ </button.trigger>
19
+ </SafeButton>
20
+ ```
21
+
22
+ @class SafetyComponent
23
+ */
24
+ export default class TriggerComponent extends Component {
25
+ BASIC_CLASS = BASIC_CLASS;
26
+
27
+ get isDisabled() {
28
+ return this.args.safetyStatus !== SAFETY_STATUS.UNLOCKED;
29
+ }
30
+
31
+ get focusMe() {
32
+ return !this.isDisabled;
33
+ }
34
+
35
+ <template>
36
+ <button
37
+ class={{this.BASIC_CLASS}}
38
+ disabled={{this.isDisabled}}
39
+ aria-label="Confirm action"
40
+ type="button"
41
+ tabindex={{if this.isDisabled "-1" "0"}}
42
+ ...attributes
43
+ {{on "click" @onClick}}
44
+ {{animateMe
45
+ safetyStatus=@safetyStatus
46
+ webAnimations=@webAnimations
47
+ focusMe=this.focusMe
48
+ }}
49
+ >
50
+ {{#if (has-block)}}
51
+ {{yield}}
52
+ {{else}}
53
+ {{@displayedMessage}}
54
+ {{/if}}
55
+ </button>
56
+ </template>
57
+ }
package/src/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { default as Trigger } from './components/trigger/index.gjs';
2
+ export { default as Safety } from './components/safety/index.gjs';
3
+ export { default as SafeButton } from './components/safe-button/index.gjs';
@@ -0,0 +1,22 @@
1
+ import { modifier } from 'ember-modifier';
2
+
3
+ import { SAFETY_STATUS } from '../states.js';
4
+
5
+ export default modifier(
6
+ (element, _, named) => {
7
+ if (named.focusMe) {
8
+ element.focus();
9
+ }
10
+
11
+ if (named.safetyStatus === SAFETY_STATUS.UNLOCKING) {
12
+ named.webAnimations.unlocking({
13
+ element,
14
+ });
15
+ } else if (named.safetyStatus === SAFETY_STATUS.LOCKING) {
16
+ named.webAnimations.locking({
17
+ element,
18
+ });
19
+ }
20
+ },
21
+ { eager: false },
22
+ );
package/src/states.js ADDED
@@ -0,0 +1,6 @@
1
+ export const SAFETY_STATUS = {
2
+ LOCKED: 1,
3
+ UNLOCKING: 2,
4
+ UNLOCKED: 3,
5
+ LOCKING: 4,
6
+ };
@@ -1,220 +0,0 @@
1
- import { buildTask } from 'ember-concurrency/async-arrow-runtime';
2
- import Component from '@glimmer/component';
3
- import { tracked } from '@glimmer/tracking';
4
- import { assert } from '@ember/debug';
5
- import { action } from '@ember/object';
6
- import { timeout } from 'ember-concurrency';
7
- import embeddedAnimations from './components/safe-button/animations/index.js';
8
- import { precompileTemplate } from '@ember/template-compilation';
9
- import { setComponentTemplate } from '@ember/component';
10
-
11
- function _applyDecoratedDescriptor(i, e, r, n, l) {
12
- var a = {};
13
- return Object.keys(n).forEach(function (i) {
14
- a[i] = n[i];
15
- }), a.enumerable = !!a.enumerable, a.configurable = !!a.configurable, ("value" in a || a.initializer) && (a.writable = true), a = r.slice().reverse().reduce(function (r, n) {
16
- return n(i, e, r) || r;
17
- }, a), l && void 0 !== a.initializer && (a.value = a.initializer ? a.initializer.call(l) : void 0, a.initializer = void 0), void 0 === a.initializer ? (Object.defineProperty(i, e, a), null) : a;
18
- }
19
- function _defineProperty(e, r, t) {
20
- return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
21
- value: t,
22
- enumerable: true,
23
- configurable: true,
24
- writable: true
25
- }) : e[r] = t, e;
26
- }
27
- function _initializerDefineProperty(e, i, r, l) {
28
- r && Object.defineProperty(e, i, {
29
- enumerable: r.enumerable,
30
- configurable: r.configurable,
31
- writable: r.writable,
32
- value: r.initializer ? r.initializer.call(l) : void 0
33
- });
34
- }
35
- function _toPrimitive(t, r) {
36
- if ("object" != typeof t || !t) return t;
37
- var e = t[Symbol.toPrimitive];
38
- if (void 0 !== e) {
39
- var i = e.call(t, r);
40
- if ("object" != typeof i) return i;
41
- throw new TypeError("@@toPrimitive must return a primitive value.");
42
- }
43
- return ("string" === r ? String : Number)(t);
44
- }
45
- function _toPropertyKey(t) {
46
- var i = _toPrimitive(t, "string");
47
- return "symbol" == typeof i ? i : i + "";
48
- }
49
-
50
- var TEMPLATE = precompileTemplate("<div class=\'ember-safe-button\' ...attributes>\n {{#if (has-block)}}\n {{yield\n (hash\n trigger=(component\n \'trigger\'\n onClick=@onConfirm\n safetyStatus=this.safetyStatus\n displayedMessage=this.displayedMessage\n webAnimations=this.webAnimations.trigger\n )\n safety=(component\n \'safety\'\n onClick=this.onUnlocking\n safetyStatus=this.safetyStatus\n displayedMessage=this.displayedMessage\n webAnimations=this.webAnimations.safety\n )\n )\n }}\n {{else}}\n <Trigger\n @onClick={{@onConfirm}}\n @safetyStatus={{this.safetyStatus}}\n @displayedMessage={{this.displayedMessage}}\n @webAnimations={{this.webAnimations.trigger}}\n />\n <Safety\n @onClick={{this.onUnlocking}}\n @safetyStatus={{this.safetyStatus}}\n @displayedMessage={{this.displayedMessage}}\n @webAnimations={{this.webAnimations.safety}}\n />\n {{/if}}\n</div>");
51
-
52
- var _class, _descriptor;
53
- const DEFAULT_TIMEOUT = 3000;
54
- const DEFAULT_ANIMATION = "slide";
55
- const SAFETY_STATUS = {
56
- LOCKED: 1,
57
- UNLOCKING: 2,
58
- UNLOCKED: 3,
59
- LOCKING: 4
60
- };
61
-
62
- /**
63
- Main component.
64
-
65
- ```hbs
66
- <SafeButton
67
- class="border-black"
68
- @animation={{this.animation}}
69
- @message="Delete me"
70
- @timeout={{2000}}
71
- @onConfirm={{action safeButtonClicked}} />
72
- ```
73
-
74
- ```
75
- @class SafeButtonComponent
76
- @param {string} [class="ember-safe-button"] CSS class to be applied on the wrapping element.
77
- @param {object} [animation="slid"] Definition of animation; It can either be string and point to one of the pre-defined animations; Or it can be an object describing Web Animation API
78
- @param {number} [timeout=3000] Number of millisenconds after which the safety rolls back over the trigger.
79
- @param {string} [message="delete"] Text to be printed on the buttons in case block is not provided.
80
- @param {function} onConfirm - Action to trigger whenever user clicks the trigger.
81
- ```
82
-
83
- When trying to construct your own `@animation` object you can take inspiration from the simple `slide` animation. The thing to keep in mind is that these go directly as parameters to [element.animate()](https://developer.mozilla.org/en-US/docs/Web/API/Element/animate) and that there are in fact four animations of which always two fire at the same time:
84
-
85
- - `safety.unlocking` and `trigger.unlocking`
86
- - `safety.locking` and `trigger.locking`
87
-
88
- ```js
89
- {
90
- safety: {
91
- unlocking: {
92
- keyframes: [
93
- { transform: 'translateX(0)' },
94
- { transform: 'translateX(-100%)' },
95
- ],
96
- options: {
97
- duration: 1000,
98
- fill: 'both',
99
- easing: 'ease',
100
- },
101
- },
102
- locking: {
103
- keyframes: [
104
- { transform: 'translateX(-100%)' },
105
- { transform: 'translateX(0)' },
106
- ],
107
- options: {
108
- duration: 1000,
109
- fill: 'both',
110
- easing: 'ease',
111
- },
112
- },
113
- },
114
- trigger: {
115
- unlocking: {
116
- keyframes: [
117
- { transform: 'translateX(100%)' },
118
- { transform: 'translateX(0)' },
119
- ],
120
- options: {
121
- duration: 1000,
122
- fill: 'both',
123
- easing: 'ease',
124
- },
125
- },
126
- locking: {
127
- keyframes: [
128
- { transform: 'translateX(0)' },
129
- { transform: 'translateX(100%)' },
130
- ],
131
- options: {
132
- duration: 1000,
133
- fill: 'both',
134
- easing: 'ease',
135
- },
136
- },
137
- },
138
- }
139
- ```
140
- */
141
- let SafeButtonComponent = (_class = class SafeButtonComponent extends Component {
142
- constructor() {
143
- super(...arguments);
144
- _initializerDefineProperty(this, "safetyStatus", _descriptor, this);
145
- _defineProperty(this, "triggerSafety", buildTask(() => ({
146
- context: this,
147
- generator: function* () {
148
- yield timeout(this.timeout);
149
- this.safetyStatus = SAFETY_STATUS.LOCKING;
150
- }
151
- }), null, "triggerSafety", null));
152
- assert("@onConfirm attribute must be set", typeof this.args.onConfirm === "function");
153
- }
154
- get activeAnimation() {
155
- const animation = this.args.animation || DEFAULT_ANIMATION;
156
- return typeof animation === "string" ? embeddedAnimations[animation] : animation;
157
- }
158
- get webAnimations() {
159
- const {
160
- activeAnimation,
161
- onUnlocked,
162
- onLocked
163
- } = this;
164
- return {
165
- safety: {
166
- unlocking: ({
167
- element
168
- }) => {
169
- let animation = element.animate(activeAnimation.safety.unlocking.keyframes, activeAnimation.safety.unlocking.options);
170
- animation.onfinish = onUnlocked;
171
- },
172
- locking: ({
173
- element
174
- }) => {
175
- let animation = element.animate(activeAnimation.safety.locking.keyframes, activeAnimation.safety.locking.options);
176
- animation.onfinish = onLocked;
177
- }
178
- },
179
- trigger: {
180
- unlocking({
181
- element
182
- }) {
183
- element.animate(activeAnimation.trigger.unlocking.keyframes, activeAnimation.trigger.unlocking.options);
184
- },
185
- locking({
186
- element
187
- }) {
188
- element.animate(activeAnimation.trigger.locking.keyframes, activeAnimation.trigger.locking.options);
189
- }
190
- }
191
- };
192
- }
193
- get timeout() {
194
- return this.args.timeout || DEFAULT_TIMEOUT;
195
- }
196
- get displayedMessage() {
197
- return this.args.message || "delete";
198
- }
199
- onUnlocking() {
200
- this.safetyStatus = SAFETY_STATUS.UNLOCKING;
201
- }
202
- onUnlocked() {
203
- this.safetyStatus = SAFETY_STATUS.UNLOCKED;
204
- this.triggerSafety.perform();
205
- }
206
- onLocked() {
207
- this.safetyStatus = SAFETY_STATUS.LOCKED;
208
- }
209
- }, _descriptor = _applyDecoratedDescriptor(_class.prototype, "safetyStatus", [tracked], {
210
- configurable: true,
211
- enumerable: true,
212
- writable: true,
213
- initializer: function () {
214
- return SAFETY_STATUS.LOCKED;
215
- }
216
- }), _applyDecoratedDescriptor(_class.prototype, "onUnlocking", [action], Object.getOwnPropertyDescriptor(_class.prototype, "onUnlocking"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "onUnlocked", [action], Object.getOwnPropertyDescriptor(_class.prototype, "onUnlocked"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "onLocked", [action], Object.getOwnPropertyDescriptor(_class.prototype, "onLocked"), _class.prototype), _class);
217
- setComponentTemplate(TEMPLATE, SafeButtonComponent);
218
-
219
- export { SAFETY_STATUS as S, _defineProperty as _, SafeButtonComponent as a };
220
- //# sourceMappingURL=index-BZOIdnQv.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-BZOIdnQv.js","sources":["../src/components/safe-button/index.js"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { assert } from \"@ember/debug\";\nimport { action } from \"@ember/object\";\n\nimport { timeout } from \"ember-concurrency\";\nimport { task } from \"ember-concurrency\";\n\nimport embeddedAnimations from \"./animations/index\";\n\nconst DEFAULT_TIMEOUT = 3000;\nconst DEFAULT_ANIMATION = \"slide\";\n\nexport const SAFETY_STATUS = {\n LOCKED: 1,\n UNLOCKING: 2,\n UNLOCKED: 3,\n LOCKING: 4,\n};\n\n/**\n Main component.\n\n ```hbs\n <SafeButton\n class=\"border-black\"\n @animation={{this.animation}}\n @message=\"Delete me\"\n @timeout={{2000}}\n @onConfirm={{action safeButtonClicked}} />\n ```\n\n ```\n @class SafeButtonComponent\n @param {string} [class=\"ember-safe-button\"] CSS class to be applied on the wrapping element.\n @param {object} [animation=\"slid\"] Definition of animation; It can either be string and point to one of the pre-defined animations; Or it can be an object describing Web Animation API\n @param {number} [timeout=3000] Number of millisenconds after which the safety rolls back over the trigger.\n @param {string} [message=\"delete\"] Text to be printed on the buttons in case block is not provided.\n @param {function} onConfirm - Action to trigger whenever user clicks the trigger.\n ```\n\n When trying to construct your own `@animation` object you can take inspiration from the simple `slide` animation. The thing to keep in mind is that these go directly as parameters to [element.animate()](https://developer.mozilla.org/en-US/docs/Web/API/Element/animate) and that there are in fact four animations of which always two fire at the same time:\n\n - `safety.unlocking` and `trigger.unlocking`\n - `safety.locking` and `trigger.locking`\n\n ```js\n {\n safety: {\n unlocking: {\n keyframes: [\n { transform: 'translateX(0)' },\n { transform: 'translateX(-100%)' },\n ],\n options: {\n duration: 1000,\n fill: 'both',\n easing: 'ease',\n },\n },\n locking: {\n keyframes: [\n { transform: 'translateX(-100%)' },\n { transform: 'translateX(0)' },\n ],\n options: {\n duration: 1000,\n fill: 'both',\n easing: 'ease',\n },\n },\n },\n trigger: {\n unlocking: {\n keyframes: [\n { transform: 'translateX(100%)' },\n { transform: 'translateX(0)' },\n ],\n options: {\n duration: 1000,\n fill: 'both',\n easing: 'ease',\n },\n },\n locking: {\n keyframes: [\n { transform: 'translateX(0)' },\n { transform: 'translateX(100%)' },\n ],\n options: {\n duration: 1000,\n fill: 'both',\n easing: 'ease',\n },\n },\n },\n }\n ```\n */\nexport default class SafeButtonComponent extends Component {\n constructor() {\n super(...arguments);\n\n assert(\n \"@onConfirm attribute must be set\",\n typeof this.args.onConfirm === \"function\"\n );\n }\n\n @tracked safetyStatus = SAFETY_STATUS.LOCKED;\n\n get activeAnimation() {\n const animation = this.args.animation || DEFAULT_ANIMATION;\n\n return typeof animation === \"string\"\n ? embeddedAnimations[animation]\n : animation;\n }\n\n get webAnimations() {\n const { activeAnimation, onUnlocked, onLocked } = this;\n\n return {\n safety: {\n unlocking: ({ element }) => {\n let animation = element.animate(\n activeAnimation.safety.unlocking.keyframes,\n activeAnimation.safety.unlocking.options\n );\n animation.onfinish = onUnlocked;\n },\n locking: ({ element }) => {\n let animation = element.animate(\n activeAnimation.safety.locking.keyframes,\n activeAnimation.safety.locking.options\n );\n animation.onfinish = onLocked;\n },\n },\n trigger: {\n unlocking({ element }) {\n element.animate(\n activeAnimation.trigger.unlocking.keyframes,\n activeAnimation.trigger.unlocking.options\n );\n },\n locking({ element }) {\n element.animate(\n activeAnimation.trigger.locking.keyframes,\n activeAnimation.trigger.locking.options\n );\n },\n },\n };\n }\n\n get timeout() {\n return this.args.timeout || DEFAULT_TIMEOUT;\n }\n\n get displayedMessage() {\n return this.args.message || \"delete\";\n }\n\n @action\n onUnlocking() {\n this.safetyStatus = SAFETY_STATUS.UNLOCKING;\n }\n\n @action\n onUnlocked() {\n this.safetyStatus = SAFETY_STATUS.UNLOCKED;\n this.triggerSafety.perform();\n }\n\n @action\n onLocked() {\n this.safetyStatus = SAFETY_STATUS.LOCKED;\n }\n\n triggerSafety = task(async () => {\n await timeout(this.timeout);\n this.safetyStatus = SAFETY_STATUS.LOCKING;\n });\n}\n"],"names":["DEFAULT_TIMEOUT","DEFAULT_ANIMATION","SAFETY_STATUS","LOCKED","UNLOCKING","UNLOCKED","LOCKING","SafeButtonComponent","_class","Component","constructor","arguments","_initializerDefineProperty","_descriptor","_defineProperty","_buildTask","context","generator","timeout","safetyStatus","assert","args","onConfirm","activeAnimation","animation","embeddedAnimations","webAnimations","onUnlocked","onLocked","safety","unlocking","element","animate","keyframes","options","onfinish","locking","trigger","displayedMessage","message","onUnlocking","triggerSafety","perform","_applyDecoratedDescriptor","prototype","tracked","configurable","enumerable","writable","initializer","action","Object","getOwnPropertyDescriptor","setComponentTemplate","TEMPLATE"],"mappings":"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"}