mn-angular-lib 1.0.99 → 1.0.100
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.
|
@@ -253,6 +253,11 @@ const mnButtonVariants = tv({
|
|
|
253
253
|
disabled: {
|
|
254
254
|
true: 'opacity-50 pointer-events-none',
|
|
255
255
|
},
|
|
256
|
+
// Busy state: dim and block interaction like `disabled`, and hint the wait cursor.
|
|
257
|
+
// The spinner itself is rendered in the template (see mn-button.html).
|
|
258
|
+
loading: {
|
|
259
|
+
true: 'opacity-50 pointer-events-none cursor-wait',
|
|
260
|
+
},
|
|
256
261
|
wrap: {
|
|
257
262
|
true: 'whitespace-normal',
|
|
258
263
|
false: 'whitespace-nowrap',
|
|
@@ -333,6 +338,7 @@ const mnButtonVariants = tv({
|
|
|
333
338
|
color: 'primary',
|
|
334
339
|
borderRadius: 'lg',
|
|
335
340
|
disabled: false,
|
|
341
|
+
loading: false,
|
|
336
342
|
wrap: false,
|
|
337
343
|
hover: true,
|
|
338
344
|
},
|
|
@@ -340,6 +346,7 @@ const mnButtonVariants = tv({
|
|
|
340
346
|
|
|
341
347
|
class MnButton {
|
|
342
348
|
data = {};
|
|
349
|
+
// A loading button is treated as non-interactive: it blocks clicks and is unfocusable,
|
|
343
350
|
// Bind the computed classes to the host element
|
|
344
351
|
get hostClasses() {
|
|
345
352
|
return mnButtonVariants({
|
|
@@ -348,33 +355,45 @@ class MnButton {
|
|
|
348
355
|
color: this.data.color,
|
|
349
356
|
borderRadius: this.data.borderRadius,
|
|
350
357
|
disabled: this.data.disabled,
|
|
358
|
+
loading: this.data.loading,
|
|
351
359
|
wrap: this.data.wrap,
|
|
352
360
|
hover: this.data.hover,
|
|
353
361
|
});
|
|
354
362
|
}
|
|
363
|
+
// Signals assistive tech that the control is busy while a loading action runs.
|
|
364
|
+
get ariaBusy() {
|
|
365
|
+
return this.data.loading ? 'true' : null;
|
|
366
|
+
}
|
|
355
367
|
// For accessibility (works for both <button> and <a>)
|
|
356
368
|
get ariaDisabled() {
|
|
357
369
|
return this.data.disabled ? 'true' : null;
|
|
358
370
|
}
|
|
359
371
|
// Only meaningful for <button>. For <a> it does nothing semantically.
|
|
360
372
|
get disabledAttr() {
|
|
361
|
-
return this.
|
|
373
|
+
return this.isBlocked ? '' : null;
|
|
362
374
|
}
|
|
363
|
-
// Make disabled anchors unfocusable + prevent activation
|
|
375
|
+
// Make disabled/loading anchors unfocusable + prevent activation
|
|
364
376
|
get tabIndex() {
|
|
365
|
-
return this.
|
|
377
|
+
return this.isBlocked ? '-1' : null;
|
|
378
|
+
}
|
|
379
|
+
// so an in-flight action cannot be triggered a second time.
|
|
380
|
+
get isBlocked() {
|
|
381
|
+
return !!(this.data.disabled || this.data.loading);
|
|
366
382
|
}
|
|
367
383
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
368
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
384
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnButton, isStandalone: true, selector: "button[mnButton], a[mnButton]", inputs: { data: "data" }, host: { properties: { "class": "this.hostClasses", "attr.aria-busy": "this.ariaBusy", "attr.aria-disabled": "this.ariaDisabled", "attr.disabled": "this.disabledAttr", "attr.tabindex": "this.tabIndex" } }, ngImport: i0, template: "@if (data.loading) {\n <span\n aria-hidden=\"true\"\n class=\"inline-block h-4 w-4 shrink-0 mr-2 animate-spin rounded-full border-2 border-current border-r-transparent\"\n ></span>\n}\n<ng-content></ng-content>\n" });
|
|
369
385
|
}
|
|
370
386
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnButton, decorators: [{
|
|
371
387
|
type: Component,
|
|
372
|
-
args: [{ selector: 'button[mnButton], a[mnButton]', standalone: true, template: "<ng-content></ng-content>\n" }]
|
|
388
|
+
args: [{ selector: 'button[mnButton], a[mnButton]', standalone: true, template: "@if (data.loading) {\n <span\n aria-hidden=\"true\"\n class=\"inline-block h-4 w-4 shrink-0 mr-2 animate-spin rounded-full border-2 border-current border-r-transparent\"\n ></span>\n}\n<ng-content></ng-content>\n" }]
|
|
373
389
|
}], propDecorators: { data: [{
|
|
374
390
|
type: Input
|
|
375
391
|
}], hostClasses: [{
|
|
376
392
|
type: HostBinding,
|
|
377
393
|
args: ['class']
|
|
394
|
+
}], ariaBusy: [{
|
|
395
|
+
type: HostBinding,
|
|
396
|
+
args: ['attr.aria-busy']
|
|
378
397
|
}], ariaDisabled: [{
|
|
379
398
|
type: HostBinding,
|
|
380
399
|
args: ['attr.aria-disabled']
|