codexly-ui 0.11.9 → 0.12.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.
- package/fesm2022/codexly-ui.mjs +187 -61
- package/fesm2022/codexly-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/codexly-ui.d.ts +18 -3
package/fesm2022/codexly-ui.mjs
CHANGED
|
@@ -12096,33 +12096,85 @@ const TOAST_DEFAULT_ICON = {
|
|
|
12096
12096
|
white: 'info',
|
|
12097
12097
|
};
|
|
12098
12098
|
const c = CLX_COLOR_MAP;
|
|
12099
|
-
// ───
|
|
12099
|
+
// ─── Card background (tinted surface) per type ────────────────────────────────
|
|
12100
|
+
const TOAST_BG_MAP = {
|
|
12101
|
+
red: c.red.bgSubtle,
|
|
12102
|
+
orange: c.orange.bgSubtle,
|
|
12103
|
+
amber: c.amber.bgSubtle,
|
|
12104
|
+
yellow: c.yellow.bgSubtle,
|
|
12105
|
+
lime: c.lime.bgSubtle,
|
|
12106
|
+
green: c.green.bgSubtle,
|
|
12107
|
+
emerald: c.emerald.bgSubtle,
|
|
12108
|
+
teal: c.teal.bgSubtle,
|
|
12109
|
+
cyan: c.cyan.bgSubtle,
|
|
12110
|
+
sky: c.sky.bgSubtle,
|
|
12111
|
+
blue: c.blue.bgSubtle,
|
|
12112
|
+
indigo: c.indigo.bgSubtle,
|
|
12113
|
+
violet: c.violet.bgSubtle,
|
|
12114
|
+
purple: c.purple.bgSubtle,
|
|
12115
|
+
fuchsia: c.fuchsia.bgSubtle,
|
|
12116
|
+
pink: c.pink.bgSubtle,
|
|
12117
|
+
rose: c.rose.bgSubtle,
|
|
12118
|
+
slate: c.slate.bgSubtle,
|
|
12119
|
+
gray: c.gray.bgSubtle,
|
|
12120
|
+
zinc: c.zinc.bgSubtle,
|
|
12121
|
+
neutral: c.neutral.bgSubtle,
|
|
12122
|
+
stone: c.stone.bgSubtle,
|
|
12123
|
+
white: c.white.bgSubtle,
|
|
12124
|
+
};
|
|
12125
|
+
// ─── Card border color per type ───────────────────────────────────────────────
|
|
12100
12126
|
const TOAST_BORDER_MAP = {
|
|
12101
|
-
red: c.red.
|
|
12102
|
-
orange: c.orange.
|
|
12103
|
-
amber: c.amber.
|
|
12104
|
-
yellow: c.yellow.
|
|
12105
|
-
lime: c.lime.
|
|
12106
|
-
green: c.green.
|
|
12107
|
-
emerald: c.emerald.
|
|
12108
|
-
teal: c.teal.
|
|
12109
|
-
cyan: c.cyan.
|
|
12110
|
-
sky: c.sky.
|
|
12111
|
-
blue: c.blue.
|
|
12112
|
-
indigo: c.indigo.
|
|
12113
|
-
violet: c.violet.
|
|
12114
|
-
purple: c.purple.
|
|
12115
|
-
fuchsia: c.fuchsia.
|
|
12116
|
-
pink: c.pink.
|
|
12117
|
-
rose: c.rose.
|
|
12118
|
-
slate: c.slate.
|
|
12119
|
-
gray: c.gray.
|
|
12120
|
-
zinc: c.zinc.
|
|
12121
|
-
neutral: c.neutral.
|
|
12122
|
-
stone: c.stone.
|
|
12123
|
-
white: c.white.
|
|
12127
|
+
red: c.red.borderLight,
|
|
12128
|
+
orange: c.orange.borderLight,
|
|
12129
|
+
amber: c.amber.borderLight,
|
|
12130
|
+
yellow: c.yellow.borderLight,
|
|
12131
|
+
lime: c.lime.borderLight,
|
|
12132
|
+
green: c.green.borderLight,
|
|
12133
|
+
emerald: c.emerald.borderLight,
|
|
12134
|
+
teal: c.teal.borderLight,
|
|
12135
|
+
cyan: c.cyan.borderLight,
|
|
12136
|
+
sky: c.sky.borderLight,
|
|
12137
|
+
blue: c.blue.borderLight,
|
|
12138
|
+
indigo: c.indigo.borderLight,
|
|
12139
|
+
violet: c.violet.borderLight,
|
|
12140
|
+
purple: c.purple.borderLight,
|
|
12141
|
+
fuchsia: c.fuchsia.borderLight,
|
|
12142
|
+
pink: c.pink.borderLight,
|
|
12143
|
+
rose: c.rose.borderLight,
|
|
12144
|
+
slate: c.slate.borderLight,
|
|
12145
|
+
gray: c.gray.borderLight,
|
|
12146
|
+
zinc: c.zinc.borderLight,
|
|
12147
|
+
neutral: c.neutral.borderLight,
|
|
12148
|
+
stone: c.stone.borderLight,
|
|
12149
|
+
white: c.white.borderLight,
|
|
12150
|
+
};
|
|
12151
|
+
// ─── Icon disc background per type (solid, paired with white icon glyph) ─────
|
|
12152
|
+
const TOAST_ICON_BG_MAP = {
|
|
12153
|
+
red: c.red.bgBase,
|
|
12154
|
+
orange: c.orange.bgBase,
|
|
12155
|
+
amber: c.amber.bgBase,
|
|
12156
|
+
yellow: c.yellow.bgBase,
|
|
12157
|
+
lime: c.lime.bgBase,
|
|
12158
|
+
green: c.green.bgBase,
|
|
12159
|
+
emerald: c.emerald.bgBase,
|
|
12160
|
+
teal: c.teal.bgBase,
|
|
12161
|
+
cyan: c.cyan.bgBase,
|
|
12162
|
+
sky: c.sky.bgBase,
|
|
12163
|
+
blue: c.blue.bgBase,
|
|
12164
|
+
indigo: c.indigo.bgBase,
|
|
12165
|
+
violet: c.violet.bgBase,
|
|
12166
|
+
purple: c.purple.bgBase,
|
|
12167
|
+
fuchsia: c.fuchsia.bgBase,
|
|
12168
|
+
pink: c.pink.bgBase,
|
|
12169
|
+
rose: c.rose.bgBase,
|
|
12170
|
+
slate: c.slate.bgBase,
|
|
12171
|
+
gray: c.gray.bgBase,
|
|
12172
|
+
zinc: c.zinc.bgBase,
|
|
12173
|
+
neutral: c.neutral.bgBase,
|
|
12174
|
+
stone: c.stone.bgBase,
|
|
12175
|
+
white: c.white.bgBase,
|
|
12124
12176
|
};
|
|
12125
|
-
// ───
|
|
12177
|
+
// ─── Title / accent text color per type ───────────────────────────────────────
|
|
12126
12178
|
const TOAST_COLOR_MAP = {
|
|
12127
12179
|
red: c.red.textBase,
|
|
12128
12180
|
orange: c.orange.textBase,
|
|
@@ -12201,11 +12253,29 @@ class ClxToastComponent {
|
|
|
12201
12253
|
_destroyed = false;
|
|
12202
12254
|
// ─── Derived visuals ──────────────────────────────────────────────────────
|
|
12203
12255
|
_icon = computed(() => this.entry().icon ?? TOAST_DEFAULT_ICON[this.entry().type], ...(ngDevMode ? [{ debugName: "_icon" }] : /* istanbul ignore next */ []));
|
|
12256
|
+
_bgClass = computed(() => TOAST_BG_MAP[this.entry().type], ...(ngDevMode ? [{ debugName: "_bgClass" }] : /* istanbul ignore next */ []));
|
|
12204
12257
|
_borderClass = computed(() => TOAST_BORDER_MAP[this.entry().type], ...(ngDevMode ? [{ debugName: "_borderClass" }] : /* istanbul ignore next */ []));
|
|
12258
|
+
_iconBgClass = computed(() => TOAST_ICON_BG_MAP[this.entry().type], ...(ngDevMode ? [{ debugName: "_iconBgClass" }] : /* istanbul ignore next */ []));
|
|
12205
12259
|
_colorClass = computed(() => TOAST_COLOR_MAP[this.entry().type], ...(ngDevMode ? [{ debugName: "_colorClass" }] : /* istanbul ignore next */ []));
|
|
12206
12260
|
_progressColor = computed(() => TOAST_PROGRESS_MAP[this.entry().type], ...(ngDevMode ? [{ debugName: "_progressColor" }] : /* istanbul ignore next */ []));
|
|
12207
12261
|
_buttonColor = computed(() => this.entry().type, ...(ngDevMode ? [{ debugName: "_buttonColor" }] : /* istanbul ignore next */ []));
|
|
12208
12262
|
_actions = computed(() => this.entry().actions ?? (this.entry().action ? [this.entry().action] : []), ...(ngDevMode ? [{ debugName: "_actions" }] : /* istanbul ignore next */ []));
|
|
12263
|
+
_relativeTime = computed(() => {
|
|
12264
|
+
const ts = this.entry().timestamp;
|
|
12265
|
+
if (!ts)
|
|
12266
|
+
return '';
|
|
12267
|
+
const diffMs = Date.now() - ts.getTime();
|
|
12268
|
+
const min = Math.round(diffMs / 60000);
|
|
12269
|
+
if (min < 1)
|
|
12270
|
+
return 'ahora';
|
|
12271
|
+
if (min < 60)
|
|
12272
|
+
return `hace ${min} min`;
|
|
12273
|
+
const hr = Math.round(min / 60);
|
|
12274
|
+
if (hr < 24)
|
|
12275
|
+
return `hace ${hr} h`;
|
|
12276
|
+
const day = Math.round(hr / 24);
|
|
12277
|
+
return `hace ${day} d`;
|
|
12278
|
+
}, ...(ngDevMode ? [{ debugName: "_relativeTime" }] : /* istanbul ignore next */ []));
|
|
12209
12279
|
get _card() {
|
|
12210
12280
|
return this._el.nativeElement.querySelector('.clx-toast-card');
|
|
12211
12281
|
}
|
|
@@ -12282,40 +12352,57 @@ class ClxToastComponent {
|
|
|
12282
12352
|
<!-- Toast card -->
|
|
12283
12353
|
<div
|
|
12284
12354
|
#card
|
|
12285
|
-
class="clx-toast-card relative flex items-start gap-3 w-full
|
|
12286
|
-
[class]="_borderClass()"
|
|
12355
|
+
class="clx-toast-card relative flex items-start gap-3.5 w-full backdrop-blur-md shadow-lg rounded-xl border px-4 py-3.5 overflow-hidden"
|
|
12356
|
+
[class]="_bgClass() + ' ' + _borderClass()"
|
|
12287
12357
|
(mouseenter)="_onMouseEnter()"
|
|
12288
12358
|
(mouseleave)="_onMouseLeave()"
|
|
12289
12359
|
>
|
|
12290
|
-
<!-- Icon -->
|
|
12360
|
+
<!-- Icon disc -->
|
|
12291
12361
|
<span
|
|
12292
|
-
|
|
12293
|
-
[
|
|
12294
|
-
|
|
12295
|
-
class="
|
|
12296
|
-
|
|
12297
|
-
></span>
|
|
12362
|
+
class="shrink-0 w-8 h-8 rounded-full flex items-center justify-center"
|
|
12363
|
+
[class]="_iconBgClass()"
|
|
12364
|
+
>
|
|
12365
|
+
<span clx-icon [name]="_icon()" size="sm" class="text-white"></span>
|
|
12366
|
+
</span>
|
|
12298
12367
|
|
|
12299
12368
|
<!-- Content -->
|
|
12300
|
-
<div class="flex-1 min-w-0">
|
|
12369
|
+
<div class="flex-1 min-w-0 pt-0.5">
|
|
12370
|
+
@if (entry().category) {
|
|
12371
|
+
<div class="flex items-center gap-1.5 mb-0.5">
|
|
12372
|
+
<span class="text-[11px] font-bold uppercase tracking-wide" [class]="_colorClass()">
|
|
12373
|
+
{{ entry().category }}
|
|
12374
|
+
</span>
|
|
12375
|
+
@if (entry().timestamp) {
|
|
12376
|
+
<span class="w-0.5 h-0.5 rounded-full bg-clx-text-subtle opacity-60"></span>
|
|
12377
|
+
<span class="text-[11px] text-clx-text-subtle">{{ _relativeTime() }}</span>
|
|
12378
|
+
}
|
|
12379
|
+
</div>
|
|
12380
|
+
}
|
|
12301
12381
|
@if (entry().title) {
|
|
12302
|
-
<p class="text-sm font-semibold leading-snug mb-0.5" [class]="_colorClass()">
|
|
12382
|
+
<p class="text-sm font-semibold leading-snug mb-0.5 flex items-center gap-1.5 flex-wrap" [class]="_colorClass()">
|
|
12303
12383
|
{{ entry().title }}
|
|
12384
|
+
@if (entry().badgeLabel) {
|
|
12385
|
+
<span
|
|
12386
|
+
class="text-[10px] font-bold uppercase tracking-wide px-1.5 py-0.5 rounded text-white"
|
|
12387
|
+
[class]="_iconBgClass()"
|
|
12388
|
+
>
|
|
12389
|
+
{{ entry().badgeLabel }}
|
|
12390
|
+
</span>
|
|
12391
|
+
}
|
|
12304
12392
|
</p>
|
|
12305
12393
|
}
|
|
12306
|
-
<p class="text-sm text-clx-text
|
|
12394
|
+
<p class="text-sm text-clx-text leading-snug wrap-break-word opacity-80">
|
|
12307
12395
|
{{ entry().message }}
|
|
12308
12396
|
</p>
|
|
12309
12397
|
@if (_actions().length) {
|
|
12310
|
-
<div class="flex items-center gap-
|
|
12311
|
-
@for (a of _actions(); track a.label) {
|
|
12398
|
+
<div class="flex items-center gap-2 mt-2.5">
|
|
12399
|
+
@for (a of _actions(); track a.label; let first = $first) {
|
|
12312
12400
|
<button
|
|
12313
12401
|
clx-button
|
|
12314
12402
|
type="button"
|
|
12315
|
-
[variant]="a.variant ?? '
|
|
12403
|
+
[variant]="(a.variant ?? (first ? 'primary' : 'ghost')) === 'primary' ? 'solid' : 'ghost'"
|
|
12316
12404
|
[color]="_buttonColor()"
|
|
12317
12405
|
size="xs"
|
|
12318
|
-
[class]="a.variant && a.variant !== 'link' ? '' : '-ml-1 h-auto p-0'"
|
|
12319
12406
|
(click)="_onAction(a)"
|
|
12320
12407
|
>
|
|
12321
12408
|
{{ a.label }}
|
|
@@ -12340,9 +12427,9 @@ class ClxToastComponent {
|
|
|
12340
12427
|
|
|
12341
12428
|
<!-- Progress bar -->
|
|
12342
12429
|
@if (entry().showProgress && entry().duration > 0) {
|
|
12343
|
-
<div class="absolute bottom-0 left-
|
|
12430
|
+
<div class="absolute bottom-0 left-px right-px h-0.5 overflow-hidden rounded-b-[11px]">
|
|
12344
12431
|
<div
|
|
12345
|
-
class="h-full w-full origin-left transition-none"
|
|
12432
|
+
class="h-full w-full origin-left transition-none opacity-45"
|
|
12346
12433
|
[class]="_progressColor()"
|
|
12347
12434
|
[ngStyle]="{ transform: 'scaleX(' + (_progressPct() / 100) + ')' }"
|
|
12348
12435
|
></div>
|
|
@@ -12357,40 +12444,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
12357
12444
|
<!-- Toast card -->
|
|
12358
12445
|
<div
|
|
12359
12446
|
#card
|
|
12360
|
-
class="clx-toast-card relative flex items-start gap-3 w-full
|
|
12361
|
-
[class]="_borderClass()"
|
|
12447
|
+
class="clx-toast-card relative flex items-start gap-3.5 w-full backdrop-blur-md shadow-lg rounded-xl border px-4 py-3.5 overflow-hidden"
|
|
12448
|
+
[class]="_bgClass() + ' ' + _borderClass()"
|
|
12362
12449
|
(mouseenter)="_onMouseEnter()"
|
|
12363
12450
|
(mouseleave)="_onMouseLeave()"
|
|
12364
12451
|
>
|
|
12365
|
-
<!-- Icon -->
|
|
12452
|
+
<!-- Icon disc -->
|
|
12366
12453
|
<span
|
|
12367
|
-
|
|
12368
|
-
[
|
|
12369
|
-
|
|
12370
|
-
class="
|
|
12371
|
-
|
|
12372
|
-
></span>
|
|
12454
|
+
class="shrink-0 w-8 h-8 rounded-full flex items-center justify-center"
|
|
12455
|
+
[class]="_iconBgClass()"
|
|
12456
|
+
>
|
|
12457
|
+
<span clx-icon [name]="_icon()" size="sm" class="text-white"></span>
|
|
12458
|
+
</span>
|
|
12373
12459
|
|
|
12374
12460
|
<!-- Content -->
|
|
12375
|
-
<div class="flex-1 min-w-0">
|
|
12461
|
+
<div class="flex-1 min-w-0 pt-0.5">
|
|
12462
|
+
@if (entry().category) {
|
|
12463
|
+
<div class="flex items-center gap-1.5 mb-0.5">
|
|
12464
|
+
<span class="text-[11px] font-bold uppercase tracking-wide" [class]="_colorClass()">
|
|
12465
|
+
{{ entry().category }}
|
|
12466
|
+
</span>
|
|
12467
|
+
@if (entry().timestamp) {
|
|
12468
|
+
<span class="w-0.5 h-0.5 rounded-full bg-clx-text-subtle opacity-60"></span>
|
|
12469
|
+
<span class="text-[11px] text-clx-text-subtle">{{ _relativeTime() }}</span>
|
|
12470
|
+
}
|
|
12471
|
+
</div>
|
|
12472
|
+
}
|
|
12376
12473
|
@if (entry().title) {
|
|
12377
|
-
<p class="text-sm font-semibold leading-snug mb-0.5" [class]="_colorClass()">
|
|
12474
|
+
<p class="text-sm font-semibold leading-snug mb-0.5 flex items-center gap-1.5 flex-wrap" [class]="_colorClass()">
|
|
12378
12475
|
{{ entry().title }}
|
|
12476
|
+
@if (entry().badgeLabel) {
|
|
12477
|
+
<span
|
|
12478
|
+
class="text-[10px] font-bold uppercase tracking-wide px-1.5 py-0.5 rounded text-white"
|
|
12479
|
+
[class]="_iconBgClass()"
|
|
12480
|
+
>
|
|
12481
|
+
{{ entry().badgeLabel }}
|
|
12482
|
+
</span>
|
|
12483
|
+
}
|
|
12379
12484
|
</p>
|
|
12380
12485
|
}
|
|
12381
|
-
<p class="text-sm text-clx-text
|
|
12486
|
+
<p class="text-sm text-clx-text leading-snug wrap-break-word opacity-80">
|
|
12382
12487
|
{{ entry().message }}
|
|
12383
12488
|
</p>
|
|
12384
12489
|
@if (_actions().length) {
|
|
12385
|
-
<div class="flex items-center gap-
|
|
12386
|
-
@for (a of _actions(); track a.label) {
|
|
12490
|
+
<div class="flex items-center gap-2 mt-2.5">
|
|
12491
|
+
@for (a of _actions(); track a.label; let first = $first) {
|
|
12387
12492
|
<button
|
|
12388
12493
|
clx-button
|
|
12389
12494
|
type="button"
|
|
12390
|
-
[variant]="a.variant ?? '
|
|
12495
|
+
[variant]="(a.variant ?? (first ? 'primary' : 'ghost')) === 'primary' ? 'solid' : 'ghost'"
|
|
12391
12496
|
[color]="_buttonColor()"
|
|
12392
12497
|
size="xs"
|
|
12393
|
-
[class]="a.variant && a.variant !== 'link' ? '' : '-ml-1 h-auto p-0'"
|
|
12394
12498
|
(click)="_onAction(a)"
|
|
12395
12499
|
>
|
|
12396
12500
|
{{ a.label }}
|
|
@@ -12415,9 +12519,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
12415
12519
|
|
|
12416
12520
|
<!-- Progress bar -->
|
|
12417
12521
|
@if (entry().showProgress && entry().duration > 0) {
|
|
12418
|
-
<div class="absolute bottom-0 left-
|
|
12522
|
+
<div class="absolute bottom-0 left-px right-px h-0.5 overflow-hidden rounded-b-[11px]">
|
|
12419
12523
|
<div
|
|
12420
|
-
class="h-full w-full origin-left transition-none"
|
|
12524
|
+
class="h-full w-full origin-left transition-none opacity-45"
|
|
12421
12525
|
[class]="_progressColor()"
|
|
12422
12526
|
[ngStyle]="{ transform: 'scaleX(' + (_progressPct() / 100) + ')' }"
|
|
12423
12527
|
></div>
|
|
@@ -17410,6 +17514,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
17410
17514
|
args: [{ providedIn: 'root' }]
|
|
17411
17515
|
}] });
|
|
17412
17516
|
|
|
17517
|
+
const NOTIFICATION_SEVERITY_TO_TOAST_TYPE = {
|
|
17518
|
+
success: 'green',
|
|
17519
|
+
warning: 'amber',
|
|
17520
|
+
info: 'sky',
|
|
17521
|
+
error: 'red',
|
|
17522
|
+
};
|
|
17413
17523
|
class ClxToastService {
|
|
17414
17524
|
_appRef = inject(ApplicationRef);
|
|
17415
17525
|
_injector = inject(Injector);
|
|
@@ -17430,6 +17540,9 @@ class ClxToastService {
|
|
|
17430
17540
|
message: options.message,
|
|
17431
17541
|
title: options.title,
|
|
17432
17542
|
icon: options.icon,
|
|
17543
|
+
category: options.category,
|
|
17544
|
+
timestamp: options.timestamp,
|
|
17545
|
+
badgeLabel: options.badgeLabel,
|
|
17433
17546
|
position,
|
|
17434
17547
|
duration: options.duration ?? TOAST_DEFAULTS.duration,
|
|
17435
17548
|
showProgress: options.showProgress ?? TOAST_DEFAULTS.showProgress,
|
|
@@ -17457,6 +17570,19 @@ class ClxToastService {
|
|
|
17457
17570
|
info(message, opts = {}) {
|
|
17458
17571
|
this.show({ ...opts, type: 'sky', message });
|
|
17459
17572
|
}
|
|
17573
|
+
/** Shows a toast built straight from a live ClxNotificationItem (e.g. on SSE arrival) — the same
|
|
17574
|
+
* object already driving the notification panel/bell, no manual field mapping at the call site. */
|
|
17575
|
+
fromNotification(item, opts = {}) {
|
|
17576
|
+
this.show({
|
|
17577
|
+
...opts,
|
|
17578
|
+
type: NOTIFICATION_SEVERITY_TO_TOAST_TYPE[item.severity],
|
|
17579
|
+
icon: item.icon,
|
|
17580
|
+
title: item.title,
|
|
17581
|
+
message: item.detail ?? '',
|
|
17582
|
+
category: item.category,
|
|
17583
|
+
timestamp: new Date(item.createdAt),
|
|
17584
|
+
});
|
|
17585
|
+
}
|
|
17460
17586
|
dismissAll() {
|
|
17461
17587
|
this._containers.forEach(c => c.instance.entries.set([]));
|
|
17462
17588
|
}
|