codexly-ui 0.13.6 → 0.14.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.
@@ -15004,6 +15004,158 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
15004
15004
  }]
15005
15005
  }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shadow: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], triggerLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerLabel", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }] } });
15006
15006
 
15007
+ /** Generic sample values keyed by variable name — covers the real {{variable}} vocabulary already
15008
+ * used across Codexly's notification/label templates (see NotificationTypeCatalog on the backend
15009
+ * and LABEL_TEMPLATE_VARS on the frontend), so a preview looks realistic with zero configuration.
15010
+ * A consumer can still override/extend via the `vars` input; this is only the fallback for any
15011
+ * key it doesn't supply. */
15012
+ const TEMPLATE_PREVIEW_SAMPLE_VARS = {
15013
+ orderNumber: 'ORD-4471',
15014
+ orderId: 'ORD-4471',
15015
+ amount: '198.000',
15016
+ toStatus: 'Confirmada',
15017
+ fromStatus: 'Pendiente',
15018
+ trackingNumber: 'TRK-88213045',
15019
+ customerName: 'Juan Pérez',
15020
+ customerPhone: '+57 300 123 4567',
15021
+ customerAddress: 'Carrera 45 # 12-34',
15022
+ customerCity: 'Bogotá',
15023
+ customerNeighborhood: 'Chapinero',
15024
+ companyName: 'CodexlyShop',
15025
+ companyStyledName: 'Codexly<span style="color:#f5c400">Shop</span>',
15026
+ companyLogo: '',
15027
+ senderLabel: 'Transportadora',
15028
+ senderName: 'Envía',
15029
+ variantName: 'Casco abatible ICH 3120',
15030
+ variantSku: 'CAS-3120-NEG',
15031
+ sellerName: 'David Medina',
15032
+ referenceId: 'a1b2c3d4-0000-0000-0000-000000000000',
15033
+ };
15034
+ /** Naive {{key}} → value string replacement — the exact primitive already used by
15035
+ * ShipmentLabelModalComponent (`html.split('{{key}}').join(v)`) and mirrored server-side by
15036
+ * NotificationDispatcher.render() (Java, plain .replace loop, no expressions). Kept here as the
15037
+ * single shared implementation so every consumer (this component, ShipmentLabelModalComponent)
15038
+ * renders previews identically instead of drifting. Unresolved {{key}} placeholders are left
15039
+ * as-is (visible literally), same as the real dispatchers when a var wasn't supplied. */
15040
+ function renderClxTemplate(body, vars) {
15041
+ let result = body;
15042
+ for (const [key, value] of Object.entries(vars)) {
15043
+ result = result.split(`{{${key}}}`).join(value);
15044
+ }
15045
+ return result;
15046
+ }
15047
+
15048
+ /** Read-only live preview of a `{{variable}}` template — for a template EDITOR (notification
15049
+ * templates, shipping label templates, ...) to show what the body will actually look like once
15050
+ * substituted, instead of only exposing the raw markup/placeholders. "Dumb" like ClxNotification/
15051
+ * ClxToast: it never fetches sample data itself — pass real values via `vars`, or rely on the
15052
+ * built-in generic fallbacks (TEMPLATE_PREVIEW_SAMPLE_VARS) for any key you don't supply.
15053
+ *
15054
+ * Substitution is the same naive {{key}} → value replace used by the real dispatchers (backend
15055
+ * NotificationDispatcher.render() in Java, and ShipmentLabelModalComponent client-side) — no
15056
+ * expression evaluation, so a Thymeleaf-flavored body (th:if/th:each, used only by the PROMOTION
15057
+ * notification type) will show its raw tags rather than truly rendering; that's a known, accepted
15058
+ * gap, not a bug — this component previews the plain {{var}} vocabulary every other template uses. */
15059
+ class ClxTemplatePreviewComponent {
15060
+ _sanitizer = inject(DomSanitizer);
15061
+ /** Raw template body — plain text (toast/in-app) or HTML (rich, e.g. an email body). */
15062
+ body = input('', ...(ngDevMode ? [{ debugName: "body" }] : /* istanbul ignore next */ []));
15063
+ /** Optional separate title/subject, substituted the same way as body. Shown above the message in
15064
+ * plain-toast/plain-inapp mode; ignored in rich mode (the body itself carries its own heading). */
15065
+ title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
15066
+ mode = input('rich', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
15067
+ /** Material Symbols icon shown in plain-toast/plain-inapp mode — defaults to 'notifications'. */
15068
+ icon = input(undefined, ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
15069
+ /** Sample values for {{key}} substitution — merged OVER the built-in generic fallbacks
15070
+ * (TEMPLATE_PREVIEW_SAMPLE_VARS), so you only need to pass the keys you want to control
15071
+ * (e.g. a real shipment's data) and every other {{var}} still resolves to something readable. */
15072
+ vars = input(undefined, ...(ngDevMode ? [{ debugName: "vars" }] : /* istanbul ignore next */ []));
15073
+ _mergedVars = computed(() => ({
15074
+ ...TEMPLATE_PREVIEW_SAMPLE_VARS,
15075
+ ...(this.vars() ?? {}),
15076
+ }), ...(ngDevMode ? [{ debugName: "_mergedVars" }] : /* istanbul ignore next */ []));
15077
+ _title = computed(() => this.title() ? renderClxTemplate(this.title(), this._mergedVars()) : '', ...(ngDevMode ? [{ debugName: "_title" }] : /* istanbul ignore next */ []));
15078
+ _renderedText = computed(() => renderClxTemplate(this.body(), this._mergedVars()), ...(ngDevMode ? [{ debugName: "_renderedText" }] : /* istanbul ignore next */ []));
15079
+ _renderedHtml = computed(() => this._sanitizer.bypassSecurityTrustHtml(renderClxTemplate(this.body(), this._mergedVars())), ...(ngDevMode ? [{ debugName: "_renderedHtml" }] : /* istanbul ignore next */ []));
15080
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxTemplatePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15081
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxTemplatePreviewComponent, isStandalone: true, selector: "clx-template-preview", inputs: { body: { classPropertyName: "body", publicName: "body", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, vars: { classPropertyName: "vars", publicName: "vars", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
15082
+ @switch (mode()) {
15083
+ @case ('plain-toast') {
15084
+ <div class="flex items-start gap-3.5 w-full rounded-xl border border-clx-border-soft bg-clx-surface px-4 py-3.5">
15085
+ <span class="shrink-0 w-8 h-8 rounded-full flex items-center justify-center bg-clx-primary">
15086
+ <span clx-icon [name]="icon() ?? 'notifications'" size="sm" class="text-white"></span>
15087
+ </span>
15088
+ <div class="flex-1 min-w-0 pt-0.5">
15089
+ @if (_title()) {
15090
+ <p class="text-sm font-semibold leading-snug mb-0.5 text-clx-text-label">{{ _title() }}</p>
15091
+ }
15092
+ <p class="text-sm text-clx-text leading-snug wrap-break-word opacity-80">{{ _renderedText() }}</p>
15093
+ </div>
15094
+ </div>
15095
+ }
15096
+ @case ('plain-inapp') {
15097
+ <div class="flex items-start gap-3 rounded-lg border border-clx-border-soft bg-clx-surface px-3 py-2.5">
15098
+ <span class="flex items-center justify-center rounded-lg shrink-0 w-8.5 h-8.5 mt-0.5 bg-clx-primary-subtle text-clx-primary">
15099
+ <span clx-icon [name]="icon() ?? 'notifications'" size="sm"></span>
15100
+ </span>
15101
+ <div class="flex-1 min-w-0">
15102
+ @if (_title()) {
15103
+ <p class="text-sm font-[600] text-clx-text-label">{{ _title() }}</p>
15104
+ }
15105
+ <p class="mt-0.5 text-sm text-clx-text-muted">{{ _renderedText() }}</p>
15106
+ </div>
15107
+ </div>
15108
+ }
15109
+ @default {
15110
+ <div class="rounded-xl border border-clx-border-soft bg-white overflow-hidden" [innerHTML]="_renderedHtml()"></div>
15111
+ }
15112
+ }
15113
+ `, isInline: true, dependencies: [{ kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
15114
+ }
15115
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxTemplatePreviewComponent, decorators: [{
15116
+ type: Component,
15117
+ args: [{
15118
+ selector: 'clx-template-preview',
15119
+ standalone: true,
15120
+ imports: [ClxIconComponent],
15121
+ encapsulation: ViewEncapsulation.None,
15122
+ changeDetection: ChangeDetectionStrategy.OnPush,
15123
+ template: `
15124
+ @switch (mode()) {
15125
+ @case ('plain-toast') {
15126
+ <div class="flex items-start gap-3.5 w-full rounded-xl border border-clx-border-soft bg-clx-surface px-4 py-3.5">
15127
+ <span class="shrink-0 w-8 h-8 rounded-full flex items-center justify-center bg-clx-primary">
15128
+ <span clx-icon [name]="icon() ?? 'notifications'" size="sm" class="text-white"></span>
15129
+ </span>
15130
+ <div class="flex-1 min-w-0 pt-0.5">
15131
+ @if (_title()) {
15132
+ <p class="text-sm font-semibold leading-snug mb-0.5 text-clx-text-label">{{ _title() }}</p>
15133
+ }
15134
+ <p class="text-sm text-clx-text leading-snug wrap-break-word opacity-80">{{ _renderedText() }}</p>
15135
+ </div>
15136
+ </div>
15137
+ }
15138
+ @case ('plain-inapp') {
15139
+ <div class="flex items-start gap-3 rounded-lg border border-clx-border-soft bg-clx-surface px-3 py-2.5">
15140
+ <span class="flex items-center justify-center rounded-lg shrink-0 w-8.5 h-8.5 mt-0.5 bg-clx-primary-subtle text-clx-primary">
15141
+ <span clx-icon [name]="icon() ?? 'notifications'" size="sm"></span>
15142
+ </span>
15143
+ <div class="flex-1 min-w-0">
15144
+ @if (_title()) {
15145
+ <p class="text-sm font-[600] text-clx-text-label">{{ _title() }}</p>
15146
+ }
15147
+ <p class="mt-0.5 text-sm text-clx-text-muted">{{ _renderedText() }}</p>
15148
+ </div>
15149
+ </div>
15150
+ }
15151
+ @default {
15152
+ <div class="rounded-xl border border-clx-border-soft bg-white overflow-hidden" [innerHTML]="_renderedHtml()"></div>
15153
+ }
15154
+ }
15155
+ `,
15156
+ }]
15157
+ }], propDecorators: { body: [{ type: i0.Input, args: [{ isSignal: true, alias: "body", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], vars: [{ type: i0.Input, args: [{ isSignal: true, alias: "vars", required: false }] }] } });
15158
+
15007
15159
  // ── Base classes ─────────────────────────────────────────────────────────────
15008
15160
  const TABLE_BASE_CLASS = 'w-full text-left border-collapse text-sm';
15009
15161
  const TABLE_HEADER_CELL_CLASS = 'px-4 py-3 font-semibold whitespace-nowrap';
@@ -18719,5 +18871,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
18719
18871
  * Generated bundle index. Do not edit.
18720
18872
  */
18721
18873
 
18722
- export { CLX_ADDON_BORDER, CLX_ADDON_TEXT, CLX_ALERT_OPTIONS, CLX_ALERT_RESOLVE, CLX_BG_ADDON, CLX_BG_DISABLED, CLX_BG_ICON_WRAP, CLX_BG_SECTION, CLX_BG_SURFACE, CLX_BORDER_DEFAULT, CLX_BORDER_DISABLED, CLX_BORDER_MEDIUM, CLX_COLOR_HEX, CLX_COLOR_HEX_100, CLX_COLOR_MAP, CLX_FONT_CATALOG, CLX_MODAL_ANIM_CONFIG, CLX_MODAL_DATA, CLX_MODAL_REF, CLX_OPTION_DISABLED, CLX_PLACEHOLDER, CLX_RADIO_GROUP, CLX_RADIUS_MAP, CLX_TEXT_BODY, CLX_TEXT_DISABLED, CLX_TEXT_HEADING, CLX_TEXT_HINT, CLX_TEXT_IDLE, CLX_TEXT_INPUT, CLX_TEXT_LABEL, CLX_TEXT_OPTION, CLX_TEXT_SUBTITLE, CLX_TEXT_TITLE, CLX_THEME_CONFIG, CLX_THEME_DEFAULTS, CLX_TOAST_DEFAULTS, ClxAlertComponent, ClxAlertService, ClxAnimateDirective, ClxAnimateGroupDirective, ClxAnimateService, ClxAppLayoutComponent, ClxAvatarComponent, ClxBadgeComponent, ClxBrandComponent, ClxButtonComponent, ClxButtonGroupComponent, ClxCardBodyDirective, ClxCardComponent, ClxCardExpiryInputComponent, ClxCardFooterDirective, ClxCardHeaderActionsDirective, ClxCardHeaderDirective, ClxCardNumberInputComponent, ClxCardValidators, ClxCarouselComponent, ClxCarouselDirective, ClxCartComponent, ClxCartSummaryDrawer, ClxCellDirective, ClxCheckboxComponent, ClxCollapseComponent, ClxColorPickerComponent, ClxColumnDefDirective, ClxDateRangePickerComponent, ClxDatepickerComponent, ClxDrawerComponent, ClxDrawerService, ClxEditorComponent, ClxEditorImageModalComponent, ClxEditorLinkModalComponent, ClxFabComponent, ClxFilterPanelComponent, ClxHeaderCellDirective, ClxIconComponent, ClxInputComponent, ClxListComponent, ClxListItemComponent, ClxMenuComponent, ClxMenuItemComponent, ClxMenuItemTrailingDirective, ClxModalComponent, ClxModalService, ClxNativeOverlayService, ClxNavGroupComponent, ClxNotificationComponent, ClxNumberComponent, ClxOtpComponent, ClxPageEmptyComponent, ClxPageHeaderComponent, ClxPageHeaderTitleDirective, ClxPageNotFoundComponent, ClxPageServerErrorComponent, ClxPageUnauthorizedComponent, ClxPaginationComponent, ClxProductComponent, ClxProductDetailComponent, ClxProductQuickViewComponent, ClxProfileComponent, ClxProgressBarComponent, ClxRadioComponent, ClxRadioGroupComponent, ClxRatingComponent, ClxSearchComponent, ClxSelectComponent, ClxSkeletonComponent, ClxSliderComponent, ClxSocialIconComponent, ClxSpinnerComponent, ClxStatCardComponent, ClxStepComponent, ClxStepperComponent, ClxSwitchComponent, ClxTabDirective, ClxTableActionsComponent, ClxTableComponent, ClxTabsComponent, ClxTagComponent, ClxTextareaComponent, ClxThemeService, ClxTimelineComponent, ClxTimelineItemComponent, ClxTimepickerComponent, ClxToastComponent, ClxToastContainerComponent, ClxToastService, ClxTooltipComponent, ClxTooltipDirective, ClxTreeComponent, ClxUploadComponent, ClxWishlistComponent, ClxWizardComponent, TIMEPICKER_SIZE_MAP, detectClxCardBrand, isClxCardExpired, parseColorInput, provideCodexlyTheme, resolveColor, resolveContainerRadius, resolveRadius };
18874
+ export { CLX_ADDON_BORDER, CLX_ADDON_TEXT, CLX_ALERT_OPTIONS, CLX_ALERT_RESOLVE, CLX_BG_ADDON, CLX_BG_DISABLED, CLX_BG_ICON_WRAP, CLX_BG_SECTION, CLX_BG_SURFACE, CLX_BORDER_DEFAULT, CLX_BORDER_DISABLED, CLX_BORDER_MEDIUM, CLX_COLOR_HEX, CLX_COLOR_HEX_100, CLX_COLOR_MAP, CLX_FONT_CATALOG, CLX_MODAL_ANIM_CONFIG, CLX_MODAL_DATA, CLX_MODAL_REF, CLX_OPTION_DISABLED, CLX_PLACEHOLDER, CLX_RADIO_GROUP, CLX_RADIUS_MAP, CLX_TEXT_BODY, CLX_TEXT_DISABLED, CLX_TEXT_HEADING, CLX_TEXT_HINT, CLX_TEXT_IDLE, CLX_TEXT_INPUT, CLX_TEXT_LABEL, CLX_TEXT_OPTION, CLX_TEXT_SUBTITLE, CLX_TEXT_TITLE, CLX_THEME_CONFIG, CLX_THEME_DEFAULTS, CLX_TOAST_DEFAULTS, ClxAlertComponent, ClxAlertService, ClxAnimateDirective, ClxAnimateGroupDirective, ClxAnimateService, ClxAppLayoutComponent, ClxAvatarComponent, ClxBadgeComponent, ClxBrandComponent, ClxButtonComponent, ClxButtonGroupComponent, ClxCardBodyDirective, ClxCardComponent, ClxCardExpiryInputComponent, ClxCardFooterDirective, ClxCardHeaderActionsDirective, ClxCardHeaderDirective, ClxCardNumberInputComponent, ClxCardValidators, ClxCarouselComponent, ClxCarouselDirective, ClxCartComponent, ClxCartSummaryDrawer, ClxCellDirective, ClxCheckboxComponent, ClxCollapseComponent, ClxColorPickerComponent, ClxColumnDefDirective, ClxDateRangePickerComponent, ClxDatepickerComponent, ClxDrawerComponent, ClxDrawerService, ClxEditorComponent, ClxEditorImageModalComponent, ClxEditorLinkModalComponent, ClxFabComponent, ClxFilterPanelComponent, ClxHeaderCellDirective, ClxIconComponent, ClxInputComponent, ClxListComponent, ClxListItemComponent, ClxMenuComponent, ClxMenuItemComponent, ClxMenuItemTrailingDirective, ClxModalComponent, ClxModalService, ClxNativeOverlayService, ClxNavGroupComponent, ClxNotificationComponent, ClxNumberComponent, ClxOtpComponent, ClxPageEmptyComponent, ClxPageHeaderComponent, ClxPageHeaderTitleDirective, ClxPageNotFoundComponent, ClxPageServerErrorComponent, ClxPageUnauthorizedComponent, ClxPaginationComponent, ClxProductComponent, ClxProductDetailComponent, ClxProductQuickViewComponent, ClxProfileComponent, ClxProgressBarComponent, ClxRadioComponent, ClxRadioGroupComponent, ClxRatingComponent, ClxSearchComponent, ClxSelectComponent, ClxSkeletonComponent, ClxSliderComponent, ClxSocialIconComponent, ClxSpinnerComponent, ClxStatCardComponent, ClxStepComponent, ClxStepperComponent, ClxSwitchComponent, ClxTabDirective, ClxTableActionsComponent, ClxTableComponent, ClxTabsComponent, ClxTagComponent, ClxTemplatePreviewComponent, ClxTextareaComponent, ClxThemeService, ClxTimelineComponent, ClxTimelineItemComponent, ClxTimepickerComponent, ClxToastComponent, ClxToastContainerComponent, ClxToastService, ClxTooltipComponent, ClxTooltipDirective, ClxTreeComponent, ClxUploadComponent, ClxWishlistComponent, ClxWizardComponent, TEMPLATE_PREVIEW_SAMPLE_VARS, TIMEPICKER_SIZE_MAP, detectClxCardBrand, isClxCardExpired, parseColorInput, provideCodexlyTheme, renderClxTemplate, resolveColor, resolveContainerRadius, resolveRadius };
18723
18875
  //# sourceMappingURL=codexly-ui.mjs.map