shirkasoft-ui-components 1.3.5 → 1.3.7
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/shirkasoft-ui-components-breadcrumb.mjs +6 -6
- package/fesm2022/shirkasoft-ui-components-button.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-chart.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-confirm-dialog.mjs +6 -6
- package/fesm2022/shirkasoft-ui-components-date-picker.mjs +49 -50
- package/fesm2022/shirkasoft-ui-components-date-picker.mjs.map +1 -1
- package/fesm2022/shirkasoft-ui-components-fieldset.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-file-upload.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-knob.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-loading.mjs +12 -12
- package/fesm2022/shirkasoft-ui-components-modal.mjs +6 -6
- package/fesm2022/shirkasoft-ui-components-notification.mjs +6 -6
- package/fesm2022/shirkasoft-ui-components-price-input.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-rail-sidebar.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-select.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-sidebar.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-skeleton.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-table.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-tabs.mjs +18 -18
- package/fesm2022/shirkasoft-ui-components-tag.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-text-field.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-timeline.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-toggle.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-tooltip.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-wizard.mjs +6 -6
- package/package.json +1 -1
- package/types/shirkasoft-ui-components-date-picker.d.ts +10 -12
|
@@ -206,10 +206,10 @@ class TimelineComponent {
|
|
|
206
206
|
isSubItemActionDisabled(action, item, sub) {
|
|
207
207
|
return action.isDisabled ? action.isDisabled(item, sub) : false;
|
|
208
208
|
}
|
|
209
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
210
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: TimelineComponent, isStandalone: true, selector: "shk-timeline", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, showLine: { classPropertyName: "showLine", publicName: "showLine", isSignal: true, isRequired: false, transformFunction: null }, markerSize: { classPropertyName: "markerSize", publicName: "markerSize", isSignal: true, isRequired: false, transformFunction: null }, markerGradients: { classPropertyName: "markerGradients", publicName: "markerGradients", isSignal: true, isRequired: false, transformFunction: null }, showOpposite: { classPropertyName: "showOpposite", publicName: "showOpposite", isSignal: true, isRequired: false, transformFunction: null }, showDescription: { classPropertyName: "showDescription", publicName: "showDescription", isSignal: true, isRequired: false, transformFunction: null }, showSubItemMeta: { classPropertyName: "showSubItemMeta", publicName: "showSubItemMeta", isSignal: true, isRequired: false, transformFunction: null }, showSubItemPrice: { classPropertyName: "showSubItemPrice", publicName: "showSubItemPrice", isSignal: true, isRequired: false, transformFunction: null }, showSubItemCount: { classPropertyName: "showSubItemCount", publicName: "showSubItemCount", isSignal: true, isRequired: false, transformFunction: null }, subItemCountLabel: { classPropertyName: "subItemCountLabel", publicName: "subItemCountLabel", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, showAddItem: { classPropertyName: "showAddItem", publicName: "showAddItem", isSignal: true, isRequired: false, transformFunction: null }, addItemLabel: { classPropertyName: "addItemLabel", publicName: "addItemLabel", isSignal: true, isRequired: false, transformFunction: null }, addItemIcon: { classPropertyName: "addItemIcon", publicName: "addItemIcon", isSignal: true, isRequired: false, transformFunction: null }, addItemTooltip: { classPropertyName: "addItemTooltip", publicName: "addItemTooltip", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null }, showAddSubItem: { classPropertyName: "showAddSubItem", publicName: "showAddSubItem", isSignal: true, isRequired: false, transformFunction: null }, addSubItemLabel: { classPropertyName: "addSubItemLabel", publicName: "addSubItemLabel", isSignal: true, isRequired: false, transformFunction: null }, addSubItemTooltip: { classPropertyName: "addSubItemTooltip", publicName: "addSubItemTooltip", isSignal: true, isRequired: false, transformFunction: null }, itemActions: { classPropertyName: "itemActions", publicName: "itemActions", isSignal: true, isRequired: false, transformFunction: null }, subItemActions: { classPropertyName: "subItemActions", publicName: "subItemActions", isSignal: true, isRequired: false, transformFunction: null }, iconMap: { classPropertyName: "iconMap", publicName: "iconMap", isSignal: true, isRequired: false, transformFunction: null }, iconColors: { classPropertyName: "iconColors", publicName: "iconColors", isSignal: true, isRequired: false, transformFunction: null }, fallbackIcon: { classPropertyName: "fallbackIcon", publicName: "fallbackIcon", isSignal: true, isRequired: false, transformFunction: null }, showEmptyState: { classPropertyName: "showEmptyState", publicName: "showEmptyState", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyIcon: { classPropertyName: "emptyIcon", publicName: "emptyIcon", isSignal: true, isRequired: false, transformFunction: null }, editTooltip: { classPropertyName: "editTooltip", publicName: "editTooltip", isSignal: true, isRequired: false, transformFunction: null }, deleteTooltip: { classPropertyName: "deleteTooltip", publicName: "deleteTooltip", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, noSubItemsMessage: { classPropertyName: "noSubItemsMessage", publicName: "noSubItemsMessage", isSignal: true, isRequired: false, transformFunction: null }, customTemplates: { classPropertyName: "customTemplates", publicName: "customTemplates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { addItem: "addItem", addSubItem: "addSubItem", itemClick: "itemClick", subItemClick: "subItemClick" }, ngImport: i0, template: "<div class=\"space-y-4\">\n\n <!-- ============ Header ============ -->\n @if (showHeader() && (headerTitle() || showAddItem() || headerActions().length > 0)) {\n <div class=\"flex flex-wrap items-center justify-between gap-2\">\n @if (headerTitle()) {\n <div class=\"text-sm font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">\n {{ headerTitle() }}\n </div>\n }\n <div class=\"flex items-center gap-1.5 ml-auto\">\n @if (showAddItem()) {\n <button\n type=\"button\"\n (click)=\"addItem.emit()\"\n [attr.aria-label]=\"addItemTooltip()\"\n class=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon(addItemIcon())\" class=\"w-3.5 h-3.5\"></svg>\n {{ addItemLabel() }}\n </button>\n }\n @for (action of headerActions(); track $index) {\n @if (isHeaderActionVisible(action)) {\n <button\n type=\"button\"\n [class]=\"action.class || 'inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed'\"\n [disabled]=\"isHeaderActionDisabled(action)\"\n (click)=\"action.onClick()\"\n >\n @if (action.icon) {\n <svg [lucideIcon]=\"getIcon(action.icon)\" class=\"w-3.5 h-3.5\"></svg>\n }\n {{ action.label }}\n </button>\n }\n }\n </div>\n </div>\n }\n\n <!-- ============ Timeline ============ -->\n @if (items().length > 0) {\n <div class=\"relative\">\n @if (showLine()) {\n <div [class]=\"lineClass()\" aria-hidden=\"true\"></div>\n }\n\n @for (item of items(); track item.id; let i = $index) {\n @if (alignment() === 'alternate') {\n <div class=\"relative flex items-start gap-4 lg:grid lg:grid-cols-2 lg:gap-0\">\n <!-- Marker (centered on desktop) -->\n <div [class]=\"alternateMarkerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n\n <!-- Content card -->\n <div\n class=\"flex-1 min-w-0\"\n [class.lg:order-1]=\"$even\"\n [class.lg:order-2]=\"!$even\"\n [class.lg:pr-12]=\"$even\"\n [class.lg:pl-12]=\"!$even\"\n >\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n\n <!-- Opposite info -->\n @if (showOpposite()) {\n <div\n class=\"hidden lg:flex lg:items-center\"\n [class.lg:order-2]=\"$even\"\n [class.lg:order-1]=\"!$even\"\n [class.lg:pl-12]=\"$even\"\n [class.lg:justify-end]=\"!$even\"\n [class.lg:pr-12]=\"!$even\"\n >\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['opposite'] || itemInfo; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n }\n </div>\n } @else if (alignment() === 'split') {\n <!-- Split: markers centered, days on the left, activities on the right -->\n <div class=\"relative flex items-start gap-4 lg:grid lg:grid-cols-2 lg:gap-0\">\n <!-- Marker (centered on desktop) -->\n <div [class]=\"alternateMarkerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n\n <!-- Day info (always left) -->\n @if (showOpposite()) {\n <div class=\"hidden lg:flex lg:items-center lg:justify-end lg:pr-12 lg:order-1 lg:text-right\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['opposite'] || itemInfo; context: { $implicit: item, index: i, showDescription: true }\"\n ></ng-container>\n </div>\n }\n\n <!-- Content card (always right) -->\n <div class=\"flex-1 min-w-0 lg:order-2 lg:pl-12\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n </div>\n } @else {\n <!-- Left alignment -->\n <div class=\"relative flex items-start gap-4\">\n <div [class]=\"markerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n <div class=\"flex-1 min-w-0\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n </div>\n }\n }\n </div>\n } @else if (showEmptyState()) {\n <!-- ============ Empty state ============ -->\n <div class=\"text-center py-12\">\n @if (customTemplates()['empty']) {\n <ng-container *ngTemplateOutlet=\"customTemplates()['empty']\"></ng-container>\n } @else {\n <div class=\"w-16 h-16 mx-auto mb-4 _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] rounded-full flex items-center justify-center\">\n <svg [lucideIcon]=\"getIcon(emptyIcon())\" class=\"w-8 h-8 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n </div>\n <p class=\"text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\">{{ emptyMessage() }}</p>\n }\n </div>\n }\n\n <!-- ============ Templates ============ -->\n\n <ng-template #defaultMarker let-item let-index=\"index\">\n <span class=\"font-bold\">{{ markerText(item, index) }}</span>\n </ng-template>\n\n <ng-template #itemInfo let-item let-showDescription=\"showDescription\">\n <div>\n @if (item.badge !== undefined && item.badge !== null && item.badge !== '') {\n <div class=\"mb-2\">\n <span class=\"inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-semibold _shk-bg-surface-100 dark:[background-color:var(--shk-surface-200)] _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\">\n @if (item.badgeIcon) {\n <svg [lucideIcon]=\"getIcon(item.badgeIcon)\" class=\"w-3 h-3\"></svg>\n }\n {{ item.badge }}\n </span>\n </div>\n }\n @if (item.title) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">{{ item.title }}</div>\n }\n @let subCount = (item.subItems?.length || 0);\n @if (item.subtitle || (showSubItemCount() && subCount > 0)) {\n <div class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] mt-1\">\n {{ item.subtitle || (subCount + ' ' + subItemCountLabel()) }}\n </div>\n }\n @if (showDescription && item.description) {\n <div class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] mt-1 leading-relaxed\">{{ item.description }}</div>\n }\n </div>\n </ng-template>\n\n <ng-template #card let-item>\n @let subItems = item.subItems || [];\n <div class=\"shk-timeline-card mb-4 bg-white dark:[background-color:var(--shk-surface-50)] rounded-xl border _shk-border dark:[border-color:var(--shk-surface-200)] shadow-sm\">\n <!-- Header (mobile in alternate/split, always in left) -->\n <div class=\"flex items-center gap-2 px-4 pt-4 pb-2\" [class.lg:hidden]=\"alignment() === 'alternate' || alignment() === 'split'\">\n <ng-container *ngTemplateOutlet=\"itemInfo; context: { $implicit: item }\"></ng-container>\n </div>\n\n <!-- Description -->\n @if (showDescription() && item.description) {\n <div class=\"px-4 pt-3\">\n @if (customTemplates()['description']) {\n <ng-container *ngTemplateOutlet=\"customTemplates()['description']; context: { $implicit: item }\"></ng-container>\n } @else {\n <p class=\"text-sm _shk-text-surface-600 dark:[color:var(--shk-surface-600)] leading-relaxed\">{{ item.description }}</p>\n }\n </div>\n }\n\n <!-- Sub items -->\n @if (subItems.length > 0) {\n <div class=\"mt-2\">\n @for (sub of subItems; track sub.id) {\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['subItem'] || defaultSubItem; context: { $implicit: item, subItem: sub, last: $last, hasFooter: showAddSubItem() || itemActions().length > 0 }\"\n ></ng-container>\n }\n </div>\n } @else if (noSubItemsMessage()) {\n <div class=\"px-4 py-6 text-center\">\n <div class=\"inline-flex items-center gap-2 text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\">\n <svg [lucideIcon]=\"getIcon('info')\" class=\"w-4 h-4\"></svg>\n <span class=\"italic\">{{ noSubItemsMessage() }}</span>\n </div>\n </div>\n }\n\n <!-- Footer actions -->\n @if (showAddSubItem() || itemActions().length > 0) {\n <div class=\"flex items-center gap-1 px-4 py-2 rounded-b-xl _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border-t _shk-border dark:[border-color:var(--shk-surface-100)]\">\n @if (showAddSubItem()) {\n <button\n type=\"button\"\n (click)=\"addSubItem.emit(item)\"\n class=\"relative group inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium _shk-text-primary hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] rounded-lg transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('circle-plus')\" class=\"w-3.5 h-3.5\"></svg>\n {{ addSubItemLabel() }}\n <span class=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ addSubItemTooltip() }}\n </span>\n </button>\n }\n <div class=\"flex-1\"></div>\n @for (action of itemActions(); track $index) {\n @if (isItemActionVisible(action, item)) {\n <div class=\"relative group\">\n <button\n type=\"button\"\n (click)=\"action.onClick(item)\"\n [class]=\"'timeline-icon-btn ' + getItemActionClass(action, item)\"\n [disabled]=\"isItemActionDisabled(action, item)\"\n [attr.aria-label]=\"getItemActionLabel(action, item)\"\n >\n <svg [lucideIcon]=\"getIcon(getItemActionIconName(action, item))\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n <span class=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ getItemActionLabel(action, item) }}\n </span>\n </div>\n }\n }\n </div>\n }\n </div>\n </ng-template>\n\n <ng-template #defaultSubItem let-item let-sub=\"subItem\" let-last=\"last\" let-hasFooter=\"hasFooter\">\n <div class=\"px-4 py-3 border-t [border-color:var(--shk-surface-100)] dark:[border-color:var(--shk-surface-700)] hover:[background-color:color-mix(in srgb,var(--shk-primary-50)30%,transparent)] dark:hover:[background-color:color-mix(in srgb,var(--shk-primary-900)10%,transparent)] transition-colors duration-200 group\" [class.rounded-b-xl]=\"last && !hasFooter\">\n <div class=\"flex items-start gap-3\">\n <span\n [class]=\"sub.iconClass || 'flex items-center justify-center w-9 h-9 rounded-lg shrink-0 mt-0.5'\"\n [style]=\"sub.iconClass ? undefined : subItemStyle(sub)\"\n >\n <svg [lucideIcon]=\"getIcon(subItemIconName(sub))\" class=\"w-4 h-4\"></svg>\n </span>\n\n <div class=\"flex-1 min-w-0\">\n <div class=\"flex items-center gap-2 flex-wrap\">\n @if (sub.optional) {\n <span class=\"text-[10px] font-semibold uppercase tracking-wide px-1.5 py-0.5 rounded _shk-bg-amber-soft _shk-text-amber-600 dark:[color:var(--shk-amber-400)]\">\n {{ sub.optionalLabel || optionalLabel() }}\n </span>\n }\n <span class=\"font-medium _shk-text-surface-800 dark:[color:var(--shk-surface-800)] text-sm truncate\">{{ sub.title }}</span>\n @if (sub.subtitle) {\n <span class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] truncate\">\u00B7 {{ sub.subtitle }}</span>\n }\n </div>\n\n @if (showSubItemMeta() && (sub.meta?.length || 0) > 0) {\n <div class=\"flex flex-wrap items-center gap-x-3 gap-y-1 mt-1.5 text-xs _shk-text-surface-500 dark:[color:var(--shk-surface-500)]\">\n @for (m of sub.meta!; track $index) {\n <span class=\"flex items-center gap-1\">\n <svg [lucideIcon]=\"getIcon(m.icon)\" class=\"w-3 h-3\"></svg>\n @if (m.label) {\n <span class=\"font-medium\">{{ m.label }}:</span>\n }\n {{ m.value }}\n </span>\n }\n </div>\n }\n </div>\n\n <div class=\"flex items-center gap-0.5 shrink-0\">\n @if (showSubItemPrice() && sub.price !== undefined && sub.price !== null && sub.price !== '') {\n <span class=\"font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)] text-xs mr-1\">{{ sub.price }}</span>\n }\n @for (action of subItemActions(); track $index) {\n @if (isSubItemActionVisible(action, item, sub)) {\n <div class=\"relative group/action\">\n <button\n type=\"button\"\n (click)=\"action.onClick(item, sub)\"\n class=\"timeline-icon-btn opacity-100 lg:opacity-0 lg:group-hover:opacity-100 transition-opacity\"\n [disabled]=\"isSubItemActionDisabled(action, item, sub)\"\n [attr.aria-label]=\"getSubItemActionLabel(action, item, sub)\"\n >\n <svg [lucideIcon]=\"getIcon(getSubItemActionIconName(action, item, sub))\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n <span class=\"absolute top-full left-1/2 -translate-x-1/2 mt-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover/action:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ getSubItemActionLabel(action, item, sub) }}\n </span>\n </div>\n }\n }\n </div>\n </div>\n </div>\n </ng-template>\n\n</div>\n", styles: [":host{display:block}.timeline-icon-btn{padding:.375rem;display:inline-flex;align-items:center;justify-content:center;border-radius:.5rem;color:var(--shk-primary-600);transition:background-color .15s ease-in-out,color .15s ease-in-out,opacity .15s ease-in-out}.timeline-icon-btn:hover:not(:disabled){background-color:color-mix(in srgb,var(--shk-primary-50) 60%,transparent);color:var(--shk-primary-700)}.timeline-icon-btn:disabled{opacity:.4;cursor:not-allowed}.timeline-icon-btn svg{width:.875rem!important;height:.875rem!important}.shk-timeline-card{animation:shk-timeline-fade-in .3s ease-out}@keyframes shk-timeline-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
209
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: TimelineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
210
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: TimelineComponent, isStandalone: true, selector: "shk-timeline", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, showLine: { classPropertyName: "showLine", publicName: "showLine", isSignal: true, isRequired: false, transformFunction: null }, markerSize: { classPropertyName: "markerSize", publicName: "markerSize", isSignal: true, isRequired: false, transformFunction: null }, markerGradients: { classPropertyName: "markerGradients", publicName: "markerGradients", isSignal: true, isRequired: false, transformFunction: null }, showOpposite: { classPropertyName: "showOpposite", publicName: "showOpposite", isSignal: true, isRequired: false, transformFunction: null }, showDescription: { classPropertyName: "showDescription", publicName: "showDescription", isSignal: true, isRequired: false, transformFunction: null }, showSubItemMeta: { classPropertyName: "showSubItemMeta", publicName: "showSubItemMeta", isSignal: true, isRequired: false, transformFunction: null }, showSubItemPrice: { classPropertyName: "showSubItemPrice", publicName: "showSubItemPrice", isSignal: true, isRequired: false, transformFunction: null }, showSubItemCount: { classPropertyName: "showSubItemCount", publicName: "showSubItemCount", isSignal: true, isRequired: false, transformFunction: null }, subItemCountLabel: { classPropertyName: "subItemCountLabel", publicName: "subItemCountLabel", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, showAddItem: { classPropertyName: "showAddItem", publicName: "showAddItem", isSignal: true, isRequired: false, transformFunction: null }, addItemLabel: { classPropertyName: "addItemLabel", publicName: "addItemLabel", isSignal: true, isRequired: false, transformFunction: null }, addItemIcon: { classPropertyName: "addItemIcon", publicName: "addItemIcon", isSignal: true, isRequired: false, transformFunction: null }, addItemTooltip: { classPropertyName: "addItemTooltip", publicName: "addItemTooltip", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null }, showAddSubItem: { classPropertyName: "showAddSubItem", publicName: "showAddSubItem", isSignal: true, isRequired: false, transformFunction: null }, addSubItemLabel: { classPropertyName: "addSubItemLabel", publicName: "addSubItemLabel", isSignal: true, isRequired: false, transformFunction: null }, addSubItemTooltip: { classPropertyName: "addSubItemTooltip", publicName: "addSubItemTooltip", isSignal: true, isRequired: false, transformFunction: null }, itemActions: { classPropertyName: "itemActions", publicName: "itemActions", isSignal: true, isRequired: false, transformFunction: null }, subItemActions: { classPropertyName: "subItemActions", publicName: "subItemActions", isSignal: true, isRequired: false, transformFunction: null }, iconMap: { classPropertyName: "iconMap", publicName: "iconMap", isSignal: true, isRequired: false, transformFunction: null }, iconColors: { classPropertyName: "iconColors", publicName: "iconColors", isSignal: true, isRequired: false, transformFunction: null }, fallbackIcon: { classPropertyName: "fallbackIcon", publicName: "fallbackIcon", isSignal: true, isRequired: false, transformFunction: null }, showEmptyState: { classPropertyName: "showEmptyState", publicName: "showEmptyState", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyIcon: { classPropertyName: "emptyIcon", publicName: "emptyIcon", isSignal: true, isRequired: false, transformFunction: null }, editTooltip: { classPropertyName: "editTooltip", publicName: "editTooltip", isSignal: true, isRequired: false, transformFunction: null }, deleteTooltip: { classPropertyName: "deleteTooltip", publicName: "deleteTooltip", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, noSubItemsMessage: { classPropertyName: "noSubItemsMessage", publicName: "noSubItemsMessage", isSignal: true, isRequired: false, transformFunction: null }, customTemplates: { classPropertyName: "customTemplates", publicName: "customTemplates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { addItem: "addItem", addSubItem: "addSubItem", itemClick: "itemClick", subItemClick: "subItemClick" }, ngImport: i0, template: "<div class=\"space-y-4\">\n\n <!-- ============ Header ============ -->\n @if (showHeader() && (headerTitle() || showAddItem() || headerActions().length > 0)) {\n <div class=\"flex flex-wrap items-center justify-between gap-2\">\n @if (headerTitle()) {\n <div class=\"text-sm font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">\n {{ headerTitle() }}\n </div>\n }\n <div class=\"flex items-center gap-1.5 ml-auto\">\n @if (showAddItem()) {\n <button\n type=\"button\"\n (click)=\"addItem.emit()\"\n [attr.aria-label]=\"addItemTooltip()\"\n class=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon(addItemIcon())\" class=\"w-3.5 h-3.5\"></svg>\n {{ addItemLabel() }}\n </button>\n }\n @for (action of headerActions(); track $index) {\n @if (isHeaderActionVisible(action)) {\n <button\n type=\"button\"\n [class]=\"action.class || 'inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed'\"\n [disabled]=\"isHeaderActionDisabled(action)\"\n (click)=\"action.onClick()\"\n >\n @if (action.icon) {\n <svg [lucideIcon]=\"getIcon(action.icon)\" class=\"w-3.5 h-3.5\"></svg>\n }\n {{ action.label }}\n </button>\n }\n }\n </div>\n </div>\n }\n\n <!-- ============ Timeline ============ -->\n @if (items().length > 0) {\n <div class=\"relative\">\n @if (showLine()) {\n <div [class]=\"lineClass()\" aria-hidden=\"true\"></div>\n }\n\n @for (item of items(); track item.id; let i = $index) {\n @if (alignment() === 'alternate') {\n <div class=\"relative flex items-start gap-4 lg:grid lg:grid-cols-2 lg:gap-0\">\n <!-- Marker (centered on desktop) -->\n <div [class]=\"alternateMarkerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n\n <!-- Content card -->\n <div\n class=\"flex-1 min-w-0\"\n [class.lg:order-1]=\"$even\"\n [class.lg:order-2]=\"!$even\"\n [class.lg:pr-12]=\"$even\"\n [class.lg:pl-12]=\"!$even\"\n >\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n\n <!-- Opposite info -->\n @if (showOpposite()) {\n <div\n class=\"hidden lg:flex lg:items-center\"\n [class.lg:order-2]=\"$even\"\n [class.lg:order-1]=\"!$even\"\n [class.lg:pl-12]=\"$even\"\n [class.lg:justify-end]=\"!$even\"\n [class.lg:pr-12]=\"!$even\"\n >\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['opposite'] || itemInfo; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n }\n </div>\n } @else if (alignment() === 'split') {\n <!-- Split: markers centered, days on the left, activities on the right -->\n <div class=\"relative flex items-start gap-4 lg:grid lg:grid-cols-2 lg:gap-0\">\n <!-- Marker (centered on desktop) -->\n <div [class]=\"alternateMarkerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n\n <!-- Day info (always left) -->\n @if (showOpposite()) {\n <div class=\"hidden lg:flex lg:items-center lg:justify-end lg:pr-12 lg:order-1 lg:text-right\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['opposite'] || itemInfo; context: { $implicit: item, index: i, showDescription: true }\"\n ></ng-container>\n </div>\n }\n\n <!-- Content card (always right) -->\n <div class=\"flex-1 min-w-0 lg:order-2 lg:pl-12\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n </div>\n } @else {\n <!-- Left alignment -->\n <div class=\"relative flex items-start gap-4\">\n <div [class]=\"markerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n <div class=\"flex-1 min-w-0\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n </div>\n }\n }\n </div>\n } @else if (showEmptyState()) {\n <!-- ============ Empty state ============ -->\n <div class=\"text-center py-12\">\n @if (customTemplates()['empty']) {\n <ng-container *ngTemplateOutlet=\"customTemplates()['empty']\"></ng-container>\n } @else {\n <div class=\"w-16 h-16 mx-auto mb-4 _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] rounded-full flex items-center justify-center\">\n <svg [lucideIcon]=\"getIcon(emptyIcon())\" class=\"w-8 h-8 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n </div>\n <p class=\"text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\">{{ emptyMessage() }}</p>\n }\n </div>\n }\n\n <!-- ============ Templates ============ -->\n\n <ng-template #defaultMarker let-item let-index=\"index\">\n <span class=\"font-bold\">{{ markerText(item, index) }}</span>\n </ng-template>\n\n <ng-template #itemInfo let-item let-showDescription=\"showDescription\">\n <div>\n @if (item.badge !== undefined && item.badge !== null && item.badge !== '') {\n <div class=\"mb-2\">\n <span class=\"inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-semibold _shk-bg-surface-100 dark:[background-color:var(--shk-surface-200)] _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\">\n @if (item.badgeIcon) {\n <svg [lucideIcon]=\"getIcon(item.badgeIcon)\" class=\"w-3 h-3\"></svg>\n }\n {{ item.badge }}\n </span>\n </div>\n }\n @if (item.title) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">{{ item.title }}</div>\n }\n @let subCount = (item.subItems?.length || 0);\n @if (item.subtitle || (showSubItemCount() && subCount > 0)) {\n <div class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] mt-1\">\n {{ item.subtitle || (subCount + ' ' + subItemCountLabel()) }}\n </div>\n }\n @if (showDescription && item.description) {\n <div class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] mt-1 leading-relaxed\">{{ item.description }}</div>\n }\n </div>\n </ng-template>\n\n <ng-template #card let-item>\n @let subItems = item.subItems || [];\n <div class=\"shk-timeline-card mb-4 bg-white dark:[background-color:var(--shk-surface-50)] rounded-xl border _shk-border dark:[border-color:var(--shk-surface-200)] shadow-sm\">\n <!-- Header (mobile in alternate/split, always in left) -->\n <div class=\"flex items-center gap-2 px-4 pt-4 pb-2\" [class.lg:hidden]=\"alignment() === 'alternate' || alignment() === 'split'\">\n <ng-container *ngTemplateOutlet=\"itemInfo; context: { $implicit: item }\"></ng-container>\n </div>\n\n <!-- Description -->\n @if (showDescription() && item.description) {\n <div class=\"px-4 pt-3\">\n @if (customTemplates()['description']) {\n <ng-container *ngTemplateOutlet=\"customTemplates()['description']; context: { $implicit: item }\"></ng-container>\n } @else {\n <p class=\"text-sm _shk-text-surface-600 dark:[color:var(--shk-surface-600)] leading-relaxed\">{{ item.description }}</p>\n }\n </div>\n }\n\n <!-- Sub items -->\n @if (subItems.length > 0) {\n <div class=\"mt-2\">\n @for (sub of subItems; track sub.id) {\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['subItem'] || defaultSubItem; context: { $implicit: item, subItem: sub, last: $last, hasFooter: showAddSubItem() || itemActions().length > 0 }\"\n ></ng-container>\n }\n </div>\n } @else if (noSubItemsMessage()) {\n <div class=\"px-4 py-6 text-center\">\n <div class=\"inline-flex items-center gap-2 text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\">\n <svg [lucideIcon]=\"getIcon('info')\" class=\"w-4 h-4\"></svg>\n <span class=\"italic\">{{ noSubItemsMessage() }}</span>\n </div>\n </div>\n }\n\n <!-- Footer actions -->\n @if (showAddSubItem() || itemActions().length > 0) {\n <div class=\"flex items-center gap-1 px-4 py-2 rounded-b-xl _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border-t _shk-border dark:[border-color:var(--shk-surface-100)]\">\n @if (showAddSubItem()) {\n <button\n type=\"button\"\n (click)=\"addSubItem.emit(item)\"\n class=\"relative group inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium _shk-text-primary hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] rounded-lg transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('circle-plus')\" class=\"w-3.5 h-3.5\"></svg>\n {{ addSubItemLabel() }}\n <span class=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ addSubItemTooltip() }}\n </span>\n </button>\n }\n <div class=\"flex-1\"></div>\n @for (action of itemActions(); track $index) {\n @if (isItemActionVisible(action, item)) {\n <div class=\"relative group\">\n <button\n type=\"button\"\n (click)=\"action.onClick(item)\"\n [class]=\"'timeline-icon-btn ' + getItemActionClass(action, item)\"\n [disabled]=\"isItemActionDisabled(action, item)\"\n [attr.aria-label]=\"getItemActionLabel(action, item)\"\n >\n <svg [lucideIcon]=\"getIcon(getItemActionIconName(action, item))\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n <span class=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ getItemActionLabel(action, item) }}\n </span>\n </div>\n }\n }\n </div>\n }\n </div>\n </ng-template>\n\n <ng-template #defaultSubItem let-item let-sub=\"subItem\" let-last=\"last\" let-hasFooter=\"hasFooter\">\n <div class=\"px-4 py-3 border-t [border-color:var(--shk-surface-100)] dark:[border-color:var(--shk-surface-700)] hover:[background-color:color-mix(in srgb,var(--shk-primary-50)30%,transparent)] dark:hover:[background-color:color-mix(in srgb,var(--shk-primary-900)10%,transparent)] transition-colors duration-200 group\" [class.rounded-b-xl]=\"last && !hasFooter\">\n <div class=\"flex items-start gap-3\">\n <span\n [class]=\"sub.iconClass || 'flex items-center justify-center w-9 h-9 rounded-lg shrink-0 mt-0.5'\"\n [style]=\"sub.iconClass ? undefined : subItemStyle(sub)\"\n >\n <svg [lucideIcon]=\"getIcon(subItemIconName(sub))\" class=\"w-4 h-4\"></svg>\n </span>\n\n <div class=\"flex-1 min-w-0\">\n <div class=\"flex items-center gap-2 flex-wrap\">\n @if (sub.optional) {\n <span class=\"text-[10px] font-semibold uppercase tracking-wide px-1.5 py-0.5 rounded _shk-bg-amber-soft _shk-text-amber-600 dark:[color:var(--shk-amber-400)]\">\n {{ sub.optionalLabel || optionalLabel() }}\n </span>\n }\n <span class=\"font-medium _shk-text-surface-800 dark:[color:var(--shk-surface-800)] text-sm truncate\">{{ sub.title }}</span>\n @if (sub.subtitle) {\n <span class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] truncate\">\u00B7 {{ sub.subtitle }}</span>\n }\n </div>\n\n @if (showSubItemMeta() && (sub.meta?.length || 0) > 0) {\n <div class=\"flex flex-wrap items-center gap-x-3 gap-y-1 mt-1.5 text-xs _shk-text-surface-500 dark:[color:var(--shk-surface-500)]\">\n @for (m of sub.meta!; track $index) {\n <span class=\"flex items-center gap-1\">\n <svg [lucideIcon]=\"getIcon(m.icon)\" class=\"w-3 h-3\"></svg>\n @if (m.label) {\n <span class=\"font-medium\">{{ m.label }}:</span>\n }\n {{ m.value }}\n </span>\n }\n </div>\n }\n </div>\n\n <div class=\"flex items-center gap-0.5 shrink-0\">\n @if (showSubItemPrice() && sub.price !== undefined && sub.price !== null && sub.price !== '') {\n <span class=\"font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)] text-xs mr-1\">{{ sub.price }}</span>\n }\n @for (action of subItemActions(); track $index) {\n @if (isSubItemActionVisible(action, item, sub)) {\n <div class=\"relative group/action\">\n <button\n type=\"button\"\n (click)=\"action.onClick(item, sub)\"\n class=\"timeline-icon-btn opacity-100 lg:opacity-0 lg:group-hover:opacity-100 transition-opacity\"\n [disabled]=\"isSubItemActionDisabled(action, item, sub)\"\n [attr.aria-label]=\"getSubItemActionLabel(action, item, sub)\"\n >\n <svg [lucideIcon]=\"getIcon(getSubItemActionIconName(action, item, sub))\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n <span class=\"absolute top-full left-1/2 -translate-x-1/2 mt-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover/action:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ getSubItemActionLabel(action, item, sub) }}\n </span>\n </div>\n }\n }\n </div>\n </div>\n </div>\n </ng-template>\n\n</div>\n", styles: [":host{display:block}.timeline-icon-btn{padding:.375rem;display:inline-flex;align-items:center;justify-content:center;border-radius:.5rem;color:var(--shk-primary-600);transition:background-color .15s ease-in-out,color .15s ease-in-out,opacity .15s ease-in-out}.timeline-icon-btn:hover:not(:disabled){background-color:color-mix(in srgb,var(--shk-primary-50) 60%,transparent);color:var(--shk-primary-700)}.timeline-icon-btn:disabled{opacity:.4;cursor:not-allowed}.timeline-icon-btn svg{width:.875rem!important;height:.875rem!important}.shk-timeline-card{animation:shk-timeline-fade-in .3s ease-out}@keyframes shk-timeline-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
211
211
|
}
|
|
212
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
212
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: TimelineComponent, decorators: [{
|
|
213
213
|
type: Component,
|
|
214
214
|
args: [{ selector: 'shk-timeline', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, LucideDynamicIcon], template: "<div class=\"space-y-4\">\n\n <!-- ============ Header ============ -->\n @if (showHeader() && (headerTitle() || showAddItem() || headerActions().length > 0)) {\n <div class=\"flex flex-wrap items-center justify-between gap-2\">\n @if (headerTitle()) {\n <div class=\"text-sm font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">\n {{ headerTitle() }}\n </div>\n }\n <div class=\"flex items-center gap-1.5 ml-auto\">\n @if (showAddItem()) {\n <button\n type=\"button\"\n (click)=\"addItem.emit()\"\n [attr.aria-label]=\"addItemTooltip()\"\n class=\"inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon(addItemIcon())\" class=\"w-3.5 h-3.5\"></svg>\n {{ addItemLabel() }}\n </button>\n }\n @for (action of headerActions(); track $index) {\n @if (isHeaderActionVisible(action)) {\n <button\n type=\"button\"\n [class]=\"action.class || 'inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md _shk-bg-primary text-white hover:[background-color:var(--shk-primary-700)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed'\"\n [disabled]=\"isHeaderActionDisabled(action)\"\n (click)=\"action.onClick()\"\n >\n @if (action.icon) {\n <svg [lucideIcon]=\"getIcon(action.icon)\" class=\"w-3.5 h-3.5\"></svg>\n }\n {{ action.label }}\n </button>\n }\n }\n </div>\n </div>\n }\n\n <!-- ============ Timeline ============ -->\n @if (items().length > 0) {\n <div class=\"relative\">\n @if (showLine()) {\n <div [class]=\"lineClass()\" aria-hidden=\"true\"></div>\n }\n\n @for (item of items(); track item.id; let i = $index) {\n @if (alignment() === 'alternate') {\n <div class=\"relative flex items-start gap-4 lg:grid lg:grid-cols-2 lg:gap-0\">\n <!-- Marker (centered on desktop) -->\n <div [class]=\"alternateMarkerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n\n <!-- Content card -->\n <div\n class=\"flex-1 min-w-0\"\n [class.lg:order-1]=\"$even\"\n [class.lg:order-2]=\"!$even\"\n [class.lg:pr-12]=\"$even\"\n [class.lg:pl-12]=\"!$even\"\n >\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n\n <!-- Opposite info -->\n @if (showOpposite()) {\n <div\n class=\"hidden lg:flex lg:items-center\"\n [class.lg:order-2]=\"$even\"\n [class.lg:order-1]=\"!$even\"\n [class.lg:pl-12]=\"$even\"\n [class.lg:justify-end]=\"!$even\"\n [class.lg:pr-12]=\"!$even\"\n >\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['opposite'] || itemInfo; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n }\n </div>\n } @else if (alignment() === 'split') {\n <!-- Split: markers centered, days on the left, activities on the right -->\n <div class=\"relative flex items-start gap-4 lg:grid lg:grid-cols-2 lg:gap-0\">\n <!-- Marker (centered on desktop) -->\n <div [class]=\"alternateMarkerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n\n <!-- Day info (always left) -->\n @if (showOpposite()) {\n <div class=\"hidden lg:flex lg:items-center lg:justify-end lg:pr-12 lg:order-1 lg:text-right\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['opposite'] || itemInfo; context: { $implicit: item, index: i, showDescription: true }\"\n ></ng-container>\n </div>\n }\n\n <!-- Content card (always right) -->\n <div class=\"flex-1 min-w-0 lg:order-2 lg:pl-12\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n </div>\n } @else {\n <!-- Left alignment -->\n <div class=\"relative flex items-start gap-4\">\n <div [class]=\"markerColumnClass()\">\n <span [class]=\"markerClass(item, i)\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['marker'] || defaultMarker; context: { $implicit: item, index: i }\"\n ></ng-container>\n </span>\n </div>\n <div class=\"flex-1 min-w-0\">\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['content'] || card; context: { $implicit: item, index: i }\"\n ></ng-container>\n </div>\n </div>\n }\n }\n </div>\n } @else if (showEmptyState()) {\n <!-- ============ Empty state ============ -->\n <div class=\"text-center py-12\">\n @if (customTemplates()['empty']) {\n <ng-container *ngTemplateOutlet=\"customTemplates()['empty']\"></ng-container>\n } @else {\n <div class=\"w-16 h-16 mx-auto mb-4 _shk-bg-surface-100 dark:[background-color:var(--shk-surface-100)] rounded-full flex items-center justify-center\">\n <svg [lucideIcon]=\"getIcon(emptyIcon())\" class=\"w-8 h-8 _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\"></svg>\n </div>\n <p class=\"text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\">{{ emptyMessage() }}</p>\n }\n </div>\n }\n\n <!-- ============ Templates ============ -->\n\n <ng-template #defaultMarker let-item let-index=\"index\">\n <span class=\"font-bold\">{{ markerText(item, index) }}</span>\n </ng-template>\n\n <ng-template #itemInfo let-item let-showDescription=\"showDescription\">\n <div>\n @if (item.badge !== undefined && item.badge !== null && item.badge !== '') {\n <div class=\"mb-2\">\n <span class=\"inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-semibold _shk-bg-surface-100 dark:[background-color:var(--shk-surface-200)] _shk-text-surface-600 dark:[color:var(--shk-surface-600)]\">\n @if (item.badgeIcon) {\n <svg [lucideIcon]=\"getIcon(item.badgeIcon)\" class=\"w-3 h-3\"></svg>\n }\n {{ item.badge }}\n </span>\n </div>\n }\n @if (item.title) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">{{ item.title }}</div>\n }\n @let subCount = (item.subItems?.length || 0);\n @if (item.subtitle || (showSubItemCount() && subCount > 0)) {\n <div class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] mt-1\">\n {{ item.subtitle || (subCount + ' ' + subItemCountLabel()) }}\n </div>\n }\n @if (showDescription && item.description) {\n <div class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] mt-1 leading-relaxed\">{{ item.description }}</div>\n }\n </div>\n </ng-template>\n\n <ng-template #card let-item>\n @let subItems = item.subItems || [];\n <div class=\"shk-timeline-card mb-4 bg-white dark:[background-color:var(--shk-surface-50)] rounded-xl border _shk-border dark:[border-color:var(--shk-surface-200)] shadow-sm\">\n <!-- Header (mobile in alternate/split, always in left) -->\n <div class=\"flex items-center gap-2 px-4 pt-4 pb-2\" [class.lg:hidden]=\"alignment() === 'alternate' || alignment() === 'split'\">\n <ng-container *ngTemplateOutlet=\"itemInfo; context: { $implicit: item }\"></ng-container>\n </div>\n\n <!-- Description -->\n @if (showDescription() && item.description) {\n <div class=\"px-4 pt-3\">\n @if (customTemplates()['description']) {\n <ng-container *ngTemplateOutlet=\"customTemplates()['description']; context: { $implicit: item }\"></ng-container>\n } @else {\n <p class=\"text-sm _shk-text-surface-600 dark:[color:var(--shk-surface-600)] leading-relaxed\">{{ item.description }}</p>\n }\n </div>\n }\n\n <!-- Sub items -->\n @if (subItems.length > 0) {\n <div class=\"mt-2\">\n @for (sub of subItems; track sub.id) {\n <ng-container\n *ngTemplateOutlet=\"customTemplates()['subItem'] || defaultSubItem; context: { $implicit: item, subItem: sub, last: $last, hasFooter: showAddSubItem() || itemActions().length > 0 }\"\n ></ng-container>\n }\n </div>\n } @else if (noSubItemsMessage()) {\n <div class=\"px-4 py-6 text-center\">\n <div class=\"inline-flex items-center gap-2 text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-500)]\">\n <svg [lucideIcon]=\"getIcon('info')\" class=\"w-4 h-4\"></svg>\n <span class=\"italic\">{{ noSubItemsMessage() }}</span>\n </div>\n </div>\n }\n\n <!-- Footer actions -->\n @if (showAddSubItem() || itemActions().length > 0) {\n <div class=\"flex items-center gap-1 px-4 py-2 rounded-b-xl _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] border-t _shk-border dark:[border-color:var(--shk-surface-100)]\">\n @if (showAddSubItem()) {\n <button\n type=\"button\"\n (click)=\"addSubItem.emit(item)\"\n class=\"relative group inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium _shk-text-primary hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] rounded-lg transition-colors\"\n >\n <svg [lucideIcon]=\"getIcon('circle-plus')\" class=\"w-3.5 h-3.5\"></svg>\n {{ addSubItemLabel() }}\n <span class=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ addSubItemTooltip() }}\n </span>\n </button>\n }\n <div class=\"flex-1\"></div>\n @for (action of itemActions(); track $index) {\n @if (isItemActionVisible(action, item)) {\n <div class=\"relative group\">\n <button\n type=\"button\"\n (click)=\"action.onClick(item)\"\n [class]=\"'timeline-icon-btn ' + getItemActionClass(action, item)\"\n [disabled]=\"isItemActionDisabled(action, item)\"\n [attr.aria-label]=\"getItemActionLabel(action, item)\"\n >\n <svg [lucideIcon]=\"getIcon(getItemActionIconName(action, item))\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n <span class=\"absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ getItemActionLabel(action, item) }}\n </span>\n </div>\n }\n }\n </div>\n }\n </div>\n </ng-template>\n\n <ng-template #defaultSubItem let-item let-sub=\"subItem\" let-last=\"last\" let-hasFooter=\"hasFooter\">\n <div class=\"px-4 py-3 border-t [border-color:var(--shk-surface-100)] dark:[border-color:var(--shk-surface-700)] hover:[background-color:color-mix(in srgb,var(--shk-primary-50)30%,transparent)] dark:hover:[background-color:color-mix(in srgb,var(--shk-primary-900)10%,transparent)] transition-colors duration-200 group\" [class.rounded-b-xl]=\"last && !hasFooter\">\n <div class=\"flex items-start gap-3\">\n <span\n [class]=\"sub.iconClass || 'flex items-center justify-center w-9 h-9 rounded-lg shrink-0 mt-0.5'\"\n [style]=\"sub.iconClass ? undefined : subItemStyle(sub)\"\n >\n <svg [lucideIcon]=\"getIcon(subItemIconName(sub))\" class=\"w-4 h-4\"></svg>\n </span>\n\n <div class=\"flex-1 min-w-0\">\n <div class=\"flex items-center gap-2 flex-wrap\">\n @if (sub.optional) {\n <span class=\"text-[10px] font-semibold uppercase tracking-wide px-1.5 py-0.5 rounded _shk-bg-amber-soft _shk-text-amber-600 dark:[color:var(--shk-amber-400)]\">\n {{ sub.optionalLabel || optionalLabel() }}\n </span>\n }\n <span class=\"font-medium _shk-text-surface-800 dark:[color:var(--shk-surface-800)] text-sm truncate\">{{ sub.title }}</span>\n @if (sub.subtitle) {\n <span class=\"text-xs _shk-text-surface-400 dark:[color:var(--shk-surface-500)] truncate\">\u00B7 {{ sub.subtitle }}</span>\n }\n </div>\n\n @if (showSubItemMeta() && (sub.meta?.length || 0) > 0) {\n <div class=\"flex flex-wrap items-center gap-x-3 gap-y-1 mt-1.5 text-xs _shk-text-surface-500 dark:[color:var(--shk-surface-500)]\">\n @for (m of sub.meta!; track $index) {\n <span class=\"flex items-center gap-1\">\n <svg [lucideIcon]=\"getIcon(m.icon)\" class=\"w-3 h-3\"></svg>\n @if (m.label) {\n <span class=\"font-medium\">{{ m.label }}:</span>\n }\n {{ m.value }}\n </span>\n }\n </div>\n }\n </div>\n\n <div class=\"flex items-center gap-0.5 shrink-0\">\n @if (showSubItemPrice() && sub.price !== undefined && sub.price !== null && sub.price !== '') {\n <span class=\"font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)] text-xs mr-1\">{{ sub.price }}</span>\n }\n @for (action of subItemActions(); track $index) {\n @if (isSubItemActionVisible(action, item, sub)) {\n <div class=\"relative group/action\">\n <button\n type=\"button\"\n (click)=\"action.onClick(item, sub)\"\n class=\"timeline-icon-btn opacity-100 lg:opacity-0 lg:group-hover:opacity-100 transition-opacity\"\n [disabled]=\"isSubItemActionDisabled(action, item, sub)\"\n [attr.aria-label]=\"getSubItemActionLabel(action, item, sub)\"\n >\n <svg [lucideIcon]=\"getIcon(getSubItemActionIconName(action, item, sub))\" class=\"w-3.5 h-3.5\"></svg>\n </button>\n <span class=\"absolute top-full left-1/2 -translate-x-1/2 mt-1 px-2 py-1 text-xs _shk-bg-tooltip _shk-text-tooltip rounded whitespace-nowrap opacity-0 group-hover/action:opacity-100 transition pointer-events-none z-[9999] shadow-lg\">\n {{ getSubItemActionLabel(action, item, sub) }}\n </span>\n </div>\n }\n }\n </div>\n </div>\n </div>\n </ng-template>\n\n</div>\n", styles: [":host{display:block}.timeline-icon-btn{padding:.375rem;display:inline-flex;align-items:center;justify-content:center;border-radius:.5rem;color:var(--shk-primary-600);transition:background-color .15s ease-in-out,color .15s ease-in-out,opacity .15s ease-in-out}.timeline-icon-btn:hover:not(:disabled){background-color:color-mix(in srgb,var(--shk-primary-50) 60%,transparent);color:var(--shk-primary-700)}.timeline-icon-btn:disabled{opacity:.4;cursor:not-allowed}.timeline-icon-btn svg{width:.875rem!important;height:.875rem!important}.shk-timeline-card{animation:shk-timeline-fade-in .3s ease-out}@keyframes shk-timeline-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
215
215
|
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], alignment: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignment", required: false }] }], showLine: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLine", required: false }] }], markerSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "markerSize", required: false }] }], markerGradients: [{ type: i0.Input, args: [{ isSignal: true, alias: "markerGradients", required: false }] }], showOpposite: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOpposite", required: false }] }], showDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDescription", required: false }] }], showSubItemMeta: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubItemMeta", required: false }] }], showSubItemPrice: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubItemPrice", required: false }] }], showSubItemCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubItemCount", required: false }] }], subItemCountLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "subItemCountLabel", required: false }] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], headerTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTitle", required: false }] }], showAddItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAddItem", required: false }] }], addItemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "addItemLabel", required: false }] }], addItemIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "addItemIcon", required: false }] }], addItemTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "addItemTooltip", required: false }] }], headerActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerActions", required: false }] }], showAddSubItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAddSubItem", required: false }] }], addSubItemLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "addSubItemLabel", required: false }] }], addSubItemTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "addSubItemTooltip", required: false }] }], itemActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemActions", required: false }] }], subItemActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "subItemActions", required: false }] }], iconMap: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconMap", required: false }] }], iconColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconColors", required: false }] }], fallbackIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallbackIcon", required: false }] }], showEmptyState: [{ type: i0.Input, args: [{ isSignal: true, alias: "showEmptyState", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], emptyIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyIcon", required: false }] }], editTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTooltip", required: false }] }], deleteTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "deleteTooltip", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], noSubItemsMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSubItemsMessage", required: false }] }], customTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "customTemplates", required: false }] }], addItem: [{ type: i0.Output, args: ["addItem"] }], addSubItem: [{ type: i0.Output, args: ["addSubItem"] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], subItemClick: [{ type: i0.Output, args: ["subItemClick"] }] } });
|
|
@@ -66,8 +66,8 @@ class ToggleComponent {
|
|
|
66
66
|
this.onTouched();
|
|
67
67
|
this.checkedChange.emit(newValue);
|
|
68
68
|
}
|
|
69
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
70
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
69
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: ToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
70
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: ToggleComponent, isStandalone: true, selector: "shk-toggle", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange" }, providers: [
|
|
71
71
|
{
|
|
72
72
|
provide: NG_VALUE_ACCESSOR,
|
|
73
73
|
useExisting: forwardRef(() => ToggleComponent),
|
|
@@ -118,7 +118,7 @@ class ToggleComponent {
|
|
|
118
118
|
</div>
|
|
119
119
|
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
120
120
|
}
|
|
121
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
121
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: ToggleComponent, decorators: [{
|
|
122
122
|
type: Component,
|
|
123
123
|
args: [{
|
|
124
124
|
selector: 'shk-toggle',
|
|
@@ -135,14 +135,14 @@ class TooltipComponent {
|
|
|
135
135
|
ngOnDestroy() {
|
|
136
136
|
this.removeTooltip();
|
|
137
137
|
}
|
|
138
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
139
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
138
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
139
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: TooltipComponent, isStandalone: true, selector: "shk-tooltip", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, ngImport: i0, template: `
|
|
140
140
|
<div class="shk-tooltip-trigger inline-flex">
|
|
141
141
|
<ng-content></ng-content>
|
|
142
142
|
</div>
|
|
143
143
|
`, isInline: true }); }
|
|
144
144
|
}
|
|
145
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
145
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: TooltipComponent, decorators: [{
|
|
146
146
|
type: Component,
|
|
147
147
|
args: [{
|
|
148
148
|
selector: 'shk-tooltip',
|
|
@@ -11,10 +11,10 @@ class ShkWizardStepContent {
|
|
|
11
11
|
this.templateRef = templateRef;
|
|
12
12
|
this.stepId = input.required({ ...(ngDevMode ? { debugName: "stepId" } : /* istanbul ignore next */ {}), alias: 'shkWizardStepContent' });
|
|
13
13
|
}
|
|
14
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
15
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.
|
|
14
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: ShkWizardStepContent, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
15
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.23", type: ShkWizardStepContent, isStandalone: true, selector: "ng-template[shkWizardStepContent]", inputs: { stepId: { classPropertyName: "stepId", publicName: "shkWizardStepContent", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
|
|
16
16
|
}
|
|
17
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
17
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: ShkWizardStepContent, decorators: [{
|
|
18
18
|
type: Directive,
|
|
19
19
|
args: [{
|
|
20
20
|
selector: 'ng-template[shkWizardStepContent]',
|
|
@@ -151,10 +151,10 @@ class WizardComponent {
|
|
|
151
151
|
this.onNext();
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
155
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: WizardComponent, isStandalone: true, selector: "shk-wizard", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: false, transformFunction: null }, currentStep: { classPropertyName: "currentStep", publicName: "currentStep", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, headerSubtitle: { classPropertyName: "headerSubtitle", publicName: "headerSubtitle", isSignal: true, isRequired: false, transformFunction: null }, showBackButton: { classPropertyName: "showBackButton", publicName: "showBackButton", isSignal: true, isRequired: false, transformFunction: null }, backTooltip: { classPropertyName: "backTooltip", publicName: "backTooltip", isSignal: true, isRequired: false, transformFunction: null }, headerIcon: { classPropertyName: "headerIcon", publicName: "headerIcon", isSignal: true, isRequired: false, transformFunction: null }, showStepper: { classPropertyName: "showStepper", publicName: "showStepper", isSignal: true, isRequired: false, transformFunction: null }, stepperClickable: { classPropertyName: "stepperClickable", publicName: "stepperClickable", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showStepCounter: { classPropertyName: "showStepCounter", publicName: "showStepCounter", isSignal: true, isRequired: false, transformFunction: null }, stepCounterPrefix: { classPropertyName: "stepCounterPrefix", publicName: "stepCounterPrefix", isSignal: true, isRequired: false, transformFunction: null }, showCancel: { classPropertyName: "showCancel", publicName: "showCancel", isSignal: true, isRequired: false, transformFunction: null }, advanceOnNext: { classPropertyName: "advanceOnNext", publicName: "advanceOnNext", isSignal: true, isRequired: false, transformFunction: null }, prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, prevIcon: { classPropertyName: "prevIcon", publicName: "prevIcon", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelIcon: { classPropertyName: "cancelIcon", publicName: "cancelIcon", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, nextIcon: { classPropertyName: "nextIcon", publicName: "nextIcon", isSignal: true, isRequired: false, transformFunction: null }, finishLabel: { classPropertyName: "finishLabel", publicName: "finishLabel", isSignal: true, isRequired: false, transformFunction: null }, finishIcon: { classPropertyName: "finishIcon", publicName: "finishIcon", isSignal: true, isRequired: false, transformFunction: null }, primaryLabel: { classPropertyName: "primaryLabel", publicName: "primaryLabel", isSignal: true, isRequired: false, transformFunction: null }, primaryIcon: { classPropertyName: "primaryIcon", publicName: "primaryIcon", isSignal: true, isRequired: false, transformFunction: null }, primaryLoading: { classPropertyName: "primaryLoading", publicName: "primaryLoading", isSignal: true, isRequired: false, transformFunction: null }, primaryDisabled: { classPropertyName: "primaryDisabled", publicName: "primaryDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { currentStep: "currentStepChange", back: "back", cancel: "cancel", prev: "prev", next: "next", finish: "finish", stepChange: "stepChange" }, queries: [{ propertyName: "stepContents", predicate: ShkWizardStepContent, isSignal: true }], ngImport: i0, template: "<div class=\"min-h-full bg-transparent\">\n\n <!-- ============ Sticky Header + Stepper ============ -->\n @if (showHeader()) {\n <div\n class=\"sticky top-0 z-20 bg-white dark:[background-color:var(--shk-surface-50)] border-b _shk-border dark:[border-color:var(--shk-surface-200)] shadow-sm\"\n >\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-4\">\n <div class=\"flex items-center gap-4 mb-4\">\n @if (showBackButton()) {\n <button\n type=\"button\"\n (click)=\"back.emit()\"\n [attr.aria-label]=\"backTooltip()\"\n [attr.title]=\"backTooltip()\"\n class=\"shk-wizard-icon-btn shrink-0\"\n >\n <svg [lucideIcon]=\"getIcon('arrow-left')\" class=\"w-4 h-4\"></svg>\n </button>\n }\n <div class=\"flex-1 min-w-0 flex items-center gap-2.5\">\n @if (headerIcon()) {\n <span class=\"w-9 h-9 rounded-lg _shk-bg-primary-soft _shk-text-primary flex items-center justify-center shrink-0\">\n <svg [lucideIcon]=\"getIcon(headerIcon())\" class=\"w-4 h-4\"></svg>\n </span>\n }\n <div class=\"min-w-0\">\n <h1 class=\"text-xl font-bold _shk-text-surface-800 dark:[color:var(--shk-surface-800)] truncate\">\n {{ headerTitle() }}\n </h1>\n @if (headerSubtitle()) {\n <p class=\"text-xs _shk-text-surface-500 dark:[color:var(--shk-surface-500)] mt-0.5 truncate\">\n {{ headerSubtitle() }}\n </p>\n }\n </div>\n </div>\n <ng-content select=\"[shkWizardHeaderActions]\"></ng-content>\n </div>\n\n <!-- Stepper -->\n @if (showStepper() && steps().length > 1) {\n <div class=\"flex items-center gap-2 w-full max-w-3xl mx-auto\">\n @for (step of steps(); track step.id; let i = $index, last = $last) {\n <div class=\"flex items-center gap-3 shrink-0\">\n <button\n type=\"button\"\n (click)=\"goTo(step.id)\"\n [disabled]=\"!stepperClickable() || currentIndex() < i\"\n [attr.aria-label]=\"step.label\"\n class=\"shk-wizard-stepper-dot\"\n [class._shk-bg-primary]=\"currentIndex() > i || currentIndex() === i\"\n [class.text-white]=\"currentIndex() > i || currentIndex() === i\"\n [class._shk-bg-surface-200]=\"currentIndex() < i\"\n [class._shk-text-surface-500]=\"currentIndex() < i\"\n [class.cursor-pointer]=\"stepperClickable() && currentIndex() >= i\"\n [class.cursor-default]=\"!stepperClickable() || currentIndex() < i\"\n >\n @if (currentIndex() > i) {\n <svg [lucideIcon]=\"getIcon(step.icon || 'check')\" class=\"w-4 h-4\"></svg>\n } @else if (step.icon) {\n <svg [lucideIcon]=\"getIcon(step.icon)\" class=\"w-4 h-4\"></svg>\n } @else {\n {{ i + 1 }}\n }\n </button>\n <span\n class=\"text-sm font-semibold transition-colors whitespace-nowrap hidden sm:inline\"\n [class._shk-text-surface-800]=\"currentIndex() === i\"\n [class._shk-text-surface-500]=\"currentIndex() !== i\"\n [class.dark:[color:var(--shk-surface-800)]]=\"currentIndex() === i\"\n [class.dark:[color:var(--shk-surface-500)]]=\"currentIndex() !== i\"\n >\n {{ step.label }}\n </span>\n </div>\n\n @if (!last) {\n <div class=\"flex-1 h-0.5 _shk-bg-surface-200 dark:[background-color:var(--shk-surface-200)] relative overflow-hidden rounded-full\">\n <div\n class=\"absolute inset-y-0 left-0 _shk-bg-primary transition-all duration-300\"\n [class.w-full]=\"currentIndex() > i\"\n [class.w-0]=\"currentIndex() <= i\"\n ></div>\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- ============ Active step content ============ -->\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6 pb-28\">\n @if (currentIndex() >= 0) {\n @if (getStepTemplate(steps()[currentIndex()].id); as tpl) {\n <div class=\"shk-wizard-fade\" [style.view-transition-name]=\"'shk-wizard-step'\">\n <ng-container\n *ngTemplateOutlet=\"tpl; context: { step: currentStepObj(), index: currentIndex() }\"\n ></ng-container>\n </div>\n } @else {\n <p class=\"text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-400)]\">\n No hay contenido definido para el paso \u00AB{{ steps()[currentIndex()].label }}\u00BB.\n </p>\n }\n }\n </div>\n\n <!-- ============ Sticky Footer ============ -->\n @if (showFooter() && steps().length > 0) {\n <div\n class=\"sticky bottom-0 z-20 bg-white dark:[background-color:var(--shk-surface-50)] border-t _shk-border dark:[border-color:var(--shk-surface-200)] shadow-[0_-4px_12px_rgba(0,0,0,0.04)] mt-8\"\n >\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-end gap-3\">\n @if (showStepCounter()) {\n <span class=\"text-sm _shk-text-surface-500 dark:[color:var(--shk-surface-500)] mr-auto\">\n {{ stepCounterPrefix() }} {{ currentIndex() + 1 }} / {{ steps().length }}\n </span>\n }\n\n @if (isFirstStep()) {\n @if (showCancel()) {\n <button type=\"button\" (click)=\"cancel.emit()\" class=\"shk-wizard-btn-secondary\">\n @if (cancelIcon()) {\n <svg [lucideIcon]=\"getIcon(cancelIcon())\" class=\"w-4 h-4\"></svg>\n }\n {{ cancelLabel() }}\n </button>\n }\n } @else {\n <button type=\"button\" (click)=\"onPrev()\" class=\"shk-wizard-btn-secondary\">\n <svg [lucideIcon]=\"getIcon(prevIcon())\" class=\"w-4 h-4\"></svg>\n {{ prevLabel() }}\n </button>\n }\n\n <button\n type=\"button\"\n (click)=\"onPrimary()\"\n [disabled]=\"primaryDisabled() || primaryLoading()\"\n class=\"shk-wizard-btn-primary\"\n >\n @if (primaryLoading()) {\n <svg [lucideIcon]=\"getIcon('loader-circle')\" class=\"w-4 h-4 shk-wizard-spin\"></svg>\n } @else {\n @if (primaryActionIcon()) {\n <svg [lucideIcon]=\"getIcon(primaryActionIcon())\" class=\"w-4 h-4\"></svg>\n }\n }\n {{ primaryActionLabel() }}\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block}.shk-wizard-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:9999px;color:var(--shk-surface-600);transition:background-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-icon-btn:hover:not(:disabled){background-color:var(--shk-surface-100);color:var(--shk-surface-800)}.shk-wizard-icon-btn:disabled{cursor:default}.shk-wizard-icon-btn svg{width:1rem!important;height:1rem!important}.shk-wizard-stepper-dot{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border-radius:9999px;font-size:.875rem;font-weight:700;flex-shrink:0;transition:background-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-stepper-dot svg{width:1rem!important;height:1rem!important}.shk-wizard-btn-secondary{display:inline-flex;align-items:center;gap:.5rem;padding:.5rem 1rem;border-radius:.5rem;font-size:.875rem;font-weight:500;color:var(--shk-surface-700);background-color:transparent;border:1px solid var(--shk-surface-200);transition:background-color .15s ease-in-out,border-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-btn-secondary:hover:not(:disabled){background-color:var(--shk-surface-100);border-color:var(--shk-surface-300);color:var(--shk-surface-900)}.shk-wizard-btn-secondary:disabled{opacity:.5;cursor:not-allowed}.shk-wizard-btn-secondary svg{width:1rem!important;height:1rem!important}.shk-wizard-btn-primary{display:inline-flex;align-items:center;gap:.5rem;padding:.5rem 1rem;border-radius:.5rem;font-size:.875rem;font-weight:500;color:#fff;background-color:var(--shk-primary-600);box-shadow:0 6px 20px -6px color-mix(in srgb,var(--shk-primary-600) 55%,transparent);transition:background-color .15s ease-in-out,opacity .15s ease-in-out}.shk-wizard-btn-primary:hover:not(:disabled){background-color:var(--shk-primary-700)}.shk-wizard-btn-primary:disabled{opacity:.5;cursor:not-allowed;box-shadow:none}.shk-wizard-btn-primary svg{width:1rem!important;height:1rem!important}.shk-wizard-spin{animation:shk-wizard-spin .8s linear infinite}@keyframes shk-wizard-spin{to{transform:rotate(360deg)}}.shk-wizard-fade{animation:shk-wizard-fade .25s ease-out}@keyframes shk-wizard-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
154
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WizardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
155
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: WizardComponent, isStandalone: true, selector: "shk-wizard", inputs: { steps: { classPropertyName: "steps", publicName: "steps", isSignal: true, isRequired: false, transformFunction: null }, currentStep: { classPropertyName: "currentStep", publicName: "currentStep", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, headerSubtitle: { classPropertyName: "headerSubtitle", publicName: "headerSubtitle", isSignal: true, isRequired: false, transformFunction: null }, showBackButton: { classPropertyName: "showBackButton", publicName: "showBackButton", isSignal: true, isRequired: false, transformFunction: null }, backTooltip: { classPropertyName: "backTooltip", publicName: "backTooltip", isSignal: true, isRequired: false, transformFunction: null }, headerIcon: { classPropertyName: "headerIcon", publicName: "headerIcon", isSignal: true, isRequired: false, transformFunction: null }, showStepper: { classPropertyName: "showStepper", publicName: "showStepper", isSignal: true, isRequired: false, transformFunction: null }, stepperClickable: { classPropertyName: "stepperClickable", publicName: "stepperClickable", isSignal: true, isRequired: false, transformFunction: null }, showFooter: { classPropertyName: "showFooter", publicName: "showFooter", isSignal: true, isRequired: false, transformFunction: null }, showStepCounter: { classPropertyName: "showStepCounter", publicName: "showStepCounter", isSignal: true, isRequired: false, transformFunction: null }, stepCounterPrefix: { classPropertyName: "stepCounterPrefix", publicName: "stepCounterPrefix", isSignal: true, isRequired: false, transformFunction: null }, showCancel: { classPropertyName: "showCancel", publicName: "showCancel", isSignal: true, isRequired: false, transformFunction: null }, advanceOnNext: { classPropertyName: "advanceOnNext", publicName: "advanceOnNext", isSignal: true, isRequired: false, transformFunction: null }, prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, prevIcon: { classPropertyName: "prevIcon", publicName: "prevIcon", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelIcon: { classPropertyName: "cancelIcon", publicName: "cancelIcon", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, nextIcon: { classPropertyName: "nextIcon", publicName: "nextIcon", isSignal: true, isRequired: false, transformFunction: null }, finishLabel: { classPropertyName: "finishLabel", publicName: "finishLabel", isSignal: true, isRequired: false, transformFunction: null }, finishIcon: { classPropertyName: "finishIcon", publicName: "finishIcon", isSignal: true, isRequired: false, transformFunction: null }, primaryLabel: { classPropertyName: "primaryLabel", publicName: "primaryLabel", isSignal: true, isRequired: false, transformFunction: null }, primaryIcon: { classPropertyName: "primaryIcon", publicName: "primaryIcon", isSignal: true, isRequired: false, transformFunction: null }, primaryLoading: { classPropertyName: "primaryLoading", publicName: "primaryLoading", isSignal: true, isRequired: false, transformFunction: null }, primaryDisabled: { classPropertyName: "primaryDisabled", publicName: "primaryDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { currentStep: "currentStepChange", back: "back", cancel: "cancel", prev: "prev", next: "next", finish: "finish", stepChange: "stepChange" }, queries: [{ propertyName: "stepContents", predicate: ShkWizardStepContent, isSignal: true }], ngImport: i0, template: "<div class=\"min-h-full bg-transparent\">\n\n <!-- ============ Sticky Header + Stepper ============ -->\n @if (showHeader()) {\n <div\n class=\"sticky top-0 z-20 bg-white dark:[background-color:var(--shk-surface-50)] border-b _shk-border dark:[border-color:var(--shk-surface-200)] shadow-sm\"\n >\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-4\">\n <div class=\"flex items-center gap-4 mb-4\">\n @if (showBackButton()) {\n <button\n type=\"button\"\n (click)=\"back.emit()\"\n [attr.aria-label]=\"backTooltip()\"\n [attr.title]=\"backTooltip()\"\n class=\"shk-wizard-icon-btn shrink-0\"\n >\n <svg [lucideIcon]=\"getIcon('arrow-left')\" class=\"w-4 h-4\"></svg>\n </button>\n }\n <div class=\"flex-1 min-w-0 flex items-center gap-2.5\">\n @if (headerIcon()) {\n <span class=\"w-9 h-9 rounded-lg _shk-bg-primary-soft _shk-text-primary flex items-center justify-center shrink-0\">\n <svg [lucideIcon]=\"getIcon(headerIcon())\" class=\"w-4 h-4\"></svg>\n </span>\n }\n <div class=\"min-w-0\">\n <h1 class=\"text-xl font-bold _shk-text-surface-800 dark:[color:var(--shk-surface-800)] truncate\">\n {{ headerTitle() }}\n </h1>\n @if (headerSubtitle()) {\n <p class=\"text-xs _shk-text-surface-500 dark:[color:var(--shk-surface-500)] mt-0.5 truncate\">\n {{ headerSubtitle() }}\n </p>\n }\n </div>\n </div>\n <ng-content select=\"[shkWizardHeaderActions]\"></ng-content>\n </div>\n\n <!-- Stepper -->\n @if (showStepper() && steps().length > 1) {\n <div class=\"flex items-center gap-2 w-full max-w-3xl mx-auto\">\n @for (step of steps(); track step.id; let i = $index, last = $last) {\n <div class=\"flex items-center gap-3 shrink-0\">\n <button\n type=\"button\"\n (click)=\"goTo(step.id)\"\n [disabled]=\"!stepperClickable() || currentIndex() < i\"\n [attr.aria-label]=\"step.label\"\n class=\"shk-wizard-stepper-dot\"\n [class._shk-bg-primary]=\"currentIndex() > i || currentIndex() === i\"\n [class.text-white]=\"currentIndex() > i || currentIndex() === i\"\n [class._shk-bg-surface-200]=\"currentIndex() < i\"\n [class._shk-text-surface-500]=\"currentIndex() < i\"\n [class.cursor-pointer]=\"stepperClickable() && currentIndex() >= i\"\n [class.cursor-default]=\"!stepperClickable() || currentIndex() < i\"\n >\n @if (currentIndex() > i) {\n <svg [lucideIcon]=\"getIcon(step.icon || 'check')\" class=\"w-4 h-4\"></svg>\n } @else if (step.icon) {\n <svg [lucideIcon]=\"getIcon(step.icon)\" class=\"w-4 h-4\"></svg>\n } @else {\n {{ i + 1 }}\n }\n </button>\n <span\n class=\"text-sm font-semibold transition-colors whitespace-nowrap hidden sm:inline\"\n [class._shk-text-surface-800]=\"currentIndex() === i\"\n [class._shk-text-surface-500]=\"currentIndex() !== i\"\n [class.dark:[color:var(--shk-surface-800)]]=\"currentIndex() === i\"\n [class.dark:[color:var(--shk-surface-500)]]=\"currentIndex() !== i\"\n >\n {{ step.label }}\n </span>\n </div>\n\n @if (!last) {\n <div class=\"flex-1 h-0.5 _shk-bg-surface-200 dark:[background-color:var(--shk-surface-200)] relative overflow-hidden rounded-full\">\n <div\n class=\"absolute inset-y-0 left-0 _shk-bg-primary transition-all duration-300\"\n [class.w-full]=\"currentIndex() > i\"\n [class.w-0]=\"currentIndex() <= i\"\n ></div>\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- ============ Active step content ============ -->\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6 pb-28\">\n @if (currentIndex() >= 0) {\n @if (getStepTemplate(steps()[currentIndex()].id); as tpl) {\n <div class=\"shk-wizard-fade\" [style.view-transition-name]=\"'shk-wizard-step'\">\n <ng-container\n *ngTemplateOutlet=\"tpl; context: { step: currentStepObj(), index: currentIndex() }\"\n ></ng-container>\n </div>\n } @else {\n <p class=\"text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-400)]\">\n No hay contenido definido para el paso \u00AB{{ steps()[currentIndex()].label }}\u00BB.\n </p>\n }\n }\n </div>\n\n <!-- ============ Sticky Footer ============ -->\n @if (showFooter() && steps().length > 0) {\n <div\n class=\"sticky bottom-0 z-20 bg-white dark:[background-color:var(--shk-surface-50)] border-t _shk-border dark:[border-color:var(--shk-surface-200)] shadow-[0_-4px_12px_rgba(0,0,0,0.04)] mt-8\"\n >\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-end gap-3\">\n @if (showStepCounter()) {\n <span class=\"text-sm _shk-text-surface-500 dark:[color:var(--shk-surface-500)] mr-auto\">\n {{ stepCounterPrefix() }} {{ currentIndex() + 1 }} / {{ steps().length }}\n </span>\n }\n\n @if (isFirstStep()) {\n @if (showCancel()) {\n <button type=\"button\" (click)=\"cancel.emit()\" class=\"shk-wizard-btn-secondary\">\n @if (cancelIcon()) {\n <svg [lucideIcon]=\"getIcon(cancelIcon())\" class=\"w-4 h-4\"></svg>\n }\n {{ cancelLabel() }}\n </button>\n }\n } @else {\n <button type=\"button\" (click)=\"onPrev()\" class=\"shk-wizard-btn-secondary\">\n <svg [lucideIcon]=\"getIcon(prevIcon())\" class=\"w-4 h-4\"></svg>\n {{ prevLabel() }}\n </button>\n }\n\n <button\n type=\"button\"\n (click)=\"onPrimary()\"\n [disabled]=\"primaryDisabled() || primaryLoading()\"\n class=\"shk-wizard-btn-primary\"\n >\n @if (primaryLoading()) {\n <svg [lucideIcon]=\"getIcon('loader-circle')\" class=\"w-4 h-4 shk-wizard-spin\"></svg>\n } @else {\n @if (primaryActionIcon()) {\n <svg [lucideIcon]=\"getIcon(primaryActionIcon())\" class=\"w-4 h-4\"></svg>\n }\n }\n {{ primaryActionLabel() }}\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block}.shk-wizard-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:9999px;color:var(--shk-surface-600);transition:background-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-icon-btn:hover:not(:disabled){background-color:var(--shk-surface-100);color:var(--shk-surface-800)}.shk-wizard-icon-btn:disabled{cursor:default}.shk-wizard-icon-btn svg{width:1rem!important;height:1rem!important}.shk-wizard-stepper-dot{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border-radius:9999px;font-size:.875rem;font-weight:700;flex-shrink:0;transition:background-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-stepper-dot svg{width:1rem!important;height:1rem!important}.shk-wizard-btn-secondary{display:inline-flex;align-items:center;gap:.5rem;padding:.5rem 1rem;border-radius:.5rem;font-size:.875rem;font-weight:500;color:var(--shk-surface-700);background-color:transparent;border:1px solid var(--shk-surface-200);transition:background-color .15s ease-in-out,border-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-btn-secondary:hover:not(:disabled){background-color:var(--shk-surface-100);border-color:var(--shk-surface-300);color:var(--shk-surface-900)}.shk-wizard-btn-secondary:disabled{opacity:.5;cursor:not-allowed}.shk-wizard-btn-secondary svg{width:1rem!important;height:1rem!important}.shk-wizard-btn-primary{display:inline-flex;align-items:center;gap:.5rem;padding:.5rem 1rem;border-radius:.5rem;font-size:.875rem;font-weight:500;color:#fff;background-color:var(--shk-primary-600);box-shadow:0 6px 20px -6px color-mix(in srgb,var(--shk-primary-600) 55%,transparent);transition:background-color .15s ease-in-out,opacity .15s ease-in-out}.shk-wizard-btn-primary:hover:not(:disabled){background-color:var(--shk-primary-700)}.shk-wizard-btn-primary:disabled{opacity:.5;cursor:not-allowed;box-shadow:none}.shk-wizard-btn-primary svg{width:1rem!important;height:1rem!important}.shk-wizard-spin{animation:shk-wizard-spin .8s linear infinite}@keyframes shk-wizard-spin{to{transform:rotate(360deg)}}.shk-wizard-fade{animation:shk-wizard-fade .25s ease-out}@keyframes shk-wizard-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
156
156
|
}
|
|
157
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WizardComponent, decorators: [{
|
|
158
158
|
type: Component,
|
|
159
159
|
args: [{ selector: 'shk-wizard', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, LucideDynamicIcon], template: "<div class=\"min-h-full bg-transparent\">\n\n <!-- ============ Sticky Header + Stepper ============ -->\n @if (showHeader()) {\n <div\n class=\"sticky top-0 z-20 bg-white dark:[background-color:var(--shk-surface-50)] border-b _shk-border dark:[border-color:var(--shk-surface-200)] shadow-sm\"\n >\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-4\">\n <div class=\"flex items-center gap-4 mb-4\">\n @if (showBackButton()) {\n <button\n type=\"button\"\n (click)=\"back.emit()\"\n [attr.aria-label]=\"backTooltip()\"\n [attr.title]=\"backTooltip()\"\n class=\"shk-wizard-icon-btn shrink-0\"\n >\n <svg [lucideIcon]=\"getIcon('arrow-left')\" class=\"w-4 h-4\"></svg>\n </button>\n }\n <div class=\"flex-1 min-w-0 flex items-center gap-2.5\">\n @if (headerIcon()) {\n <span class=\"w-9 h-9 rounded-lg _shk-bg-primary-soft _shk-text-primary flex items-center justify-center shrink-0\">\n <svg [lucideIcon]=\"getIcon(headerIcon())\" class=\"w-4 h-4\"></svg>\n </span>\n }\n <div class=\"min-w-0\">\n <h1 class=\"text-xl font-bold _shk-text-surface-800 dark:[color:var(--shk-surface-800)] truncate\">\n {{ headerTitle() }}\n </h1>\n @if (headerSubtitle()) {\n <p class=\"text-xs _shk-text-surface-500 dark:[color:var(--shk-surface-500)] mt-0.5 truncate\">\n {{ headerSubtitle() }}\n </p>\n }\n </div>\n </div>\n <ng-content select=\"[shkWizardHeaderActions]\"></ng-content>\n </div>\n\n <!-- Stepper -->\n @if (showStepper() && steps().length > 1) {\n <div class=\"flex items-center gap-2 w-full max-w-3xl mx-auto\">\n @for (step of steps(); track step.id; let i = $index, last = $last) {\n <div class=\"flex items-center gap-3 shrink-0\">\n <button\n type=\"button\"\n (click)=\"goTo(step.id)\"\n [disabled]=\"!stepperClickable() || currentIndex() < i\"\n [attr.aria-label]=\"step.label\"\n class=\"shk-wizard-stepper-dot\"\n [class._shk-bg-primary]=\"currentIndex() > i || currentIndex() === i\"\n [class.text-white]=\"currentIndex() > i || currentIndex() === i\"\n [class._shk-bg-surface-200]=\"currentIndex() < i\"\n [class._shk-text-surface-500]=\"currentIndex() < i\"\n [class.cursor-pointer]=\"stepperClickable() && currentIndex() >= i\"\n [class.cursor-default]=\"!stepperClickable() || currentIndex() < i\"\n >\n @if (currentIndex() > i) {\n <svg [lucideIcon]=\"getIcon(step.icon || 'check')\" class=\"w-4 h-4\"></svg>\n } @else if (step.icon) {\n <svg [lucideIcon]=\"getIcon(step.icon)\" class=\"w-4 h-4\"></svg>\n } @else {\n {{ i + 1 }}\n }\n </button>\n <span\n class=\"text-sm font-semibold transition-colors whitespace-nowrap hidden sm:inline\"\n [class._shk-text-surface-800]=\"currentIndex() === i\"\n [class._shk-text-surface-500]=\"currentIndex() !== i\"\n [class.dark:[color:var(--shk-surface-800)]]=\"currentIndex() === i\"\n [class.dark:[color:var(--shk-surface-500)]]=\"currentIndex() !== i\"\n >\n {{ step.label }}\n </span>\n </div>\n\n @if (!last) {\n <div class=\"flex-1 h-0.5 _shk-bg-surface-200 dark:[background-color:var(--shk-surface-200)] relative overflow-hidden rounded-full\">\n <div\n class=\"absolute inset-y-0 left-0 _shk-bg-primary transition-all duration-300\"\n [class.w-full]=\"currentIndex() > i\"\n [class.w-0]=\"currentIndex() <= i\"\n ></div>\n </div>\n }\n }\n </div>\n }\n </div>\n </div>\n }\n\n <!-- ============ Active step content ============ -->\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-6 pb-28\">\n @if (currentIndex() >= 0) {\n @if (getStepTemplate(steps()[currentIndex()].id); as tpl) {\n <div class=\"shk-wizard-fade\" [style.view-transition-name]=\"'shk-wizard-step'\">\n <ng-container\n *ngTemplateOutlet=\"tpl; context: { step: currentStepObj(), index: currentIndex() }\"\n ></ng-container>\n </div>\n } @else {\n <p class=\"text-sm _shk-text-surface-400 dark:[color:var(--shk-surface-400)]\">\n No hay contenido definido para el paso \u00AB{{ steps()[currentIndex()].label }}\u00BB.\n </p>\n }\n }\n </div>\n\n <!-- ============ Sticky Footer ============ -->\n @if (showFooter() && steps().length > 0) {\n <div\n class=\"sticky bottom-0 z-20 bg-white dark:[background-color:var(--shk-surface-50)] border-t _shk-border dark:[border-color:var(--shk-surface-200)] shadow-[0_-4px_12px_rgba(0,0,0,0.04)] mt-8\"\n >\n <div class=\"w-full px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-end gap-3\">\n @if (showStepCounter()) {\n <span class=\"text-sm _shk-text-surface-500 dark:[color:var(--shk-surface-500)] mr-auto\">\n {{ stepCounterPrefix() }} {{ currentIndex() + 1 }} / {{ steps().length }}\n </span>\n }\n\n @if (isFirstStep()) {\n @if (showCancel()) {\n <button type=\"button\" (click)=\"cancel.emit()\" class=\"shk-wizard-btn-secondary\">\n @if (cancelIcon()) {\n <svg [lucideIcon]=\"getIcon(cancelIcon())\" class=\"w-4 h-4\"></svg>\n }\n {{ cancelLabel() }}\n </button>\n }\n } @else {\n <button type=\"button\" (click)=\"onPrev()\" class=\"shk-wizard-btn-secondary\">\n <svg [lucideIcon]=\"getIcon(prevIcon())\" class=\"w-4 h-4\"></svg>\n {{ prevLabel() }}\n </button>\n }\n\n <button\n type=\"button\"\n (click)=\"onPrimary()\"\n [disabled]=\"primaryDisabled() || primaryLoading()\"\n class=\"shk-wizard-btn-primary\"\n >\n @if (primaryLoading()) {\n <svg [lucideIcon]=\"getIcon('loader-circle')\" class=\"w-4 h-4 shk-wizard-spin\"></svg>\n } @else {\n @if (primaryActionIcon()) {\n <svg [lucideIcon]=\"getIcon(primaryActionIcon())\" class=\"w-4 h-4\"></svg>\n }\n }\n {{ primaryActionLabel() }}\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block}.shk-wizard-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:9999px;color:var(--shk-surface-600);transition:background-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-icon-btn:hover:not(:disabled){background-color:var(--shk-surface-100);color:var(--shk-surface-800)}.shk-wizard-icon-btn:disabled{cursor:default}.shk-wizard-icon-btn svg{width:1rem!important;height:1rem!important}.shk-wizard-stepper-dot{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border-radius:9999px;font-size:.875rem;font-weight:700;flex-shrink:0;transition:background-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-stepper-dot svg{width:1rem!important;height:1rem!important}.shk-wizard-btn-secondary{display:inline-flex;align-items:center;gap:.5rem;padding:.5rem 1rem;border-radius:.5rem;font-size:.875rem;font-weight:500;color:var(--shk-surface-700);background-color:transparent;border:1px solid var(--shk-surface-200);transition:background-color .15s ease-in-out,border-color .15s ease-in-out,color .15s ease-in-out}.shk-wizard-btn-secondary:hover:not(:disabled){background-color:var(--shk-surface-100);border-color:var(--shk-surface-300);color:var(--shk-surface-900)}.shk-wizard-btn-secondary:disabled{opacity:.5;cursor:not-allowed}.shk-wizard-btn-secondary svg{width:1rem!important;height:1rem!important}.shk-wizard-btn-primary{display:inline-flex;align-items:center;gap:.5rem;padding:.5rem 1rem;border-radius:.5rem;font-size:.875rem;font-weight:500;color:#fff;background-color:var(--shk-primary-600);box-shadow:0 6px 20px -6px color-mix(in srgb,var(--shk-primary-600) 55%,transparent);transition:background-color .15s ease-in-out,opacity .15s ease-in-out}.shk-wizard-btn-primary:hover:not(:disabled){background-color:var(--shk-primary-700)}.shk-wizard-btn-primary:disabled{opacity:.5;cursor:not-allowed;box-shadow:none}.shk-wizard-btn-primary svg{width:1rem!important;height:1rem!important}.shk-wizard-spin{animation:shk-wizard-spin .8s linear infinite}@keyframes shk-wizard-spin{to{transform:rotate(360deg)}}.shk-wizard-fade{animation:shk-wizard-fade .25s ease-out}@keyframes shk-wizard-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
160
160
|
}], propDecorators: { steps: [{ type: i0.Input, args: [{ isSignal: true, alias: "steps", required: false }] }], currentStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentStep", required: false }] }, { type: i0.Output, args: ["currentStepChange"] }], showHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeader", required: false }] }], headerTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTitle", required: false }] }], headerSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerSubtitle", required: false }] }], showBackButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBackButton", required: false }] }], backTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "backTooltip", required: false }] }], headerIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerIcon", required: false }] }], showStepper: [{ type: i0.Input, args: [{ isSignal: true, alias: "showStepper", required: false }] }], stepperClickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepperClickable", required: false }] }], showFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooter", required: false }] }], showStepCounter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showStepCounter", required: false }] }], stepCounterPrefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepCounterPrefix", required: false }] }], showCancel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCancel", required: false }] }], advanceOnNext: [{ type: i0.Input, args: [{ isSignal: true, alias: "advanceOnNext", required: false }] }], prevLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevLabel", required: false }] }], prevIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevIcon", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], cancelIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelIcon", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], nextIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextIcon", required: false }] }], finishLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "finishLabel", required: false }] }], finishIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "finishIcon", required: false }] }], primaryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryLabel", required: false }] }], primaryIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryIcon", required: false }] }], primaryLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryLoading", required: false }] }], primaryDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryDisabled", required: false }] }], back: [{ type: i0.Output, args: ["back"] }], cancel: [{ type: i0.Output, args: ["cancel"] }], prev: [{ type: i0.Output, args: ["prev"] }], next: [{ type: i0.Output, args: ["next"] }], finish: [{ type: i0.Output, args: ["finish"] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }], stepContents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ShkWizardStepContent), { isSignal: true }] }] } });
|
package/package.json
CHANGED
|
@@ -74,6 +74,10 @@ declare class DatePickerComponent implements ControlValueAccessor {
|
|
|
74
74
|
viewMeridiem: _angular_core.WritableSignal<"AM" | "PM">;
|
|
75
75
|
/** Date part selected but not yet committed until the time is confirmed. */
|
|
76
76
|
private pendingDate;
|
|
77
|
+
/** Selected year during the selection flow (year -> month -> day). */
|
|
78
|
+
selectedYearValue: _angular_core.WritableSignal<number | null>;
|
|
79
|
+
/** Selected month during the selection flow. */
|
|
80
|
+
selectedMonthValue: _angular_core.WritableSignal<number | null>;
|
|
77
81
|
/** Analog clock mode: 'hours' or 'minutes'. */
|
|
78
82
|
clockMode: _angular_core.WritableSignal<ClockMode>;
|
|
79
83
|
/** Internal view state for drill-down navigation (separates from input `view`). */
|
|
@@ -144,8 +148,6 @@ declare class DatePickerComponent implements ControlValueAccessor {
|
|
|
144
148
|
clockMinutes: _angular_core.Signal<number[]>;
|
|
145
149
|
/** The input format string based on locale. */
|
|
146
150
|
inputFormat: _angular_core.Signal<"MM/DD/YYYY" | "DD/MM/YYYY">;
|
|
147
|
-
/** Whether the drill-down navigation is active (view differs from input). */
|
|
148
|
-
isDrilledDown: _angular_core.Signal<boolean>;
|
|
149
151
|
/** (Unused legacy placeholder) plain year list. */
|
|
150
152
|
years: number[];
|
|
151
153
|
constructor();
|
|
@@ -163,12 +165,12 @@ declare class DatePickerComponent implements ControlValueAccessor {
|
|
|
163
165
|
prev(): void;
|
|
164
166
|
/** Navigates the calendar to the next year/month/decade. */
|
|
165
167
|
next(): void;
|
|
166
|
-
/** Selects a
|
|
167
|
-
selectDay(day: number): void;
|
|
168
|
-
/** Selects a month of the year (pending if time is shown). */
|
|
169
|
-
selectMonth(monthIndex: number): void;
|
|
170
|
-
/** Selects a year (pending if time is shown). */
|
|
168
|
+
/** Selects a year - stores it and navigates to month selection. */
|
|
171
169
|
selectYear(year: number): void;
|
|
170
|
+
/** Selects a month - stores it and navigates to day selection. */
|
|
171
|
+
selectMonth(monthIndex: number): void;
|
|
172
|
+
/** Selects a day - completes the date selection. */
|
|
173
|
+
selectDay(day: number): void;
|
|
172
174
|
/** Commits a value, updates the component, the control and the outputs. */
|
|
173
175
|
private setValue;
|
|
174
176
|
/** Confirms the selected time and commits the combined date+time value. */
|
|
@@ -246,17 +248,13 @@ declare class DatePickerComponent implements ControlValueAccessor {
|
|
|
246
248
|
x2: number;
|
|
247
249
|
y2: number;
|
|
248
250
|
};
|
|
249
|
-
/** Switches the drill-down view to months (from date view). */
|
|
250
|
-
drillToMonths(): void;
|
|
251
|
-
/** Switches the drill-down view to years (from month view). */
|
|
252
|
-
drillToYears(): void;
|
|
253
251
|
/** Drills down from year view to month view for the selected year. */
|
|
254
252
|
drillDownToMonth(year: number): void;
|
|
255
253
|
/** Drills down from month view to date view for the selected month. */
|
|
256
254
|
drillDownToDate(monthIndex: number): void;
|
|
257
255
|
/** Goes back one level in drill-down navigation. */
|
|
258
256
|
drillUp(): void;
|
|
259
|
-
/** Returns to the initial view
|
|
257
|
+
/** Returns to the initial view (year selection). */
|
|
260
258
|
drillToInitial(): void;
|
|
261
259
|
/** Formats input placeholder based on locale. */
|
|
262
260
|
inputPlaceholder(): string;
|