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