@c80/ui 1.0.57 → 1.0.62
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/esm2022/index.js +13 -8
- package/esm2022/index.js.map +1 -1
- package/esm2022/lib/action-list/action-list.component.js +7 -0
- package/esm2022/lib/action-list/action-list.component.js.map +1 -1
- package/esm2022/lib/action-list/action-list.types.js.map +1 -1
- package/esm2022/lib/card-level/card-level.component.js +4 -3
- package/esm2022/lib/card-level/card-level.component.js.map +1 -1
- package/esm2022/lib/card-level/card-level.interface.js.map +1 -1
- package/esm2022/lib/card-level/index.js.map +1 -1
- package/esm2022/lib/error-notification/error-notification.component.js +41 -0
- package/esm2022/lib/error-notification/error-notification.component.js.map +1 -0
- package/esm2022/lib/error-notification/error-notification.types.js +2 -0
- package/esm2022/lib/error-notification/error-notification.types.js.map +1 -0
- package/esm2022/lib/error-notification/index.js +3 -0
- package/esm2022/lib/error-notification/index.js.map +1 -0
- package/esm2022/lib/header/header.component.js +8 -2
- package/esm2022/lib/header/header.component.js.map +1 -1
- package/esm2022/lib/header/header.types.js.map +1 -1
- package/esm2022/lib/icon/icon.component.js +11 -5
- package/esm2022/lib/icon/icon.component.js.map +1 -1
- package/esm2022/lib/icon/icon.definitions.js +108 -2
- package/esm2022/lib/icon/icon.definitions.js.map +1 -1
- package/esm2022/lib/icon/icon.types.js.map +1 -1
- package/esm2022/lib/icon/icon.utils.js +7 -0
- package/esm2022/lib/icon/icon.utils.js.map +1 -1
- package/esm2022/lib/icon/theme.service.js +20 -0
- package/esm2022/lib/icon/theme.service.js.map +1 -1
- package/esm2022/lib/info-list/info-list.component.js +3 -0
- package/esm2022/lib/info-list/info-list.component.js.map +1 -1
- package/esm2022/lib/input-field/input-field.component.js +19 -2
- package/esm2022/lib/input-field/input-field.component.js.map +1 -1
- package/esm2022/lib/input-search/c80-input-search.component.js +26 -0
- package/esm2022/lib/input-search/c80-input-search.component.js.map +1 -0
- package/esm2022/lib/input-search/index.js +2 -0
- package/esm2022/lib/input-search/index.js.map +1 -0
- package/esm2022/lib/modal/index.js.map +1 -1
- package/esm2022/lib/modal/modal.component.js +59 -2
- package/esm2022/lib/modal/modal.component.js.map +1 -1
- package/esm2022/lib/modal/modal.service.js +60 -3
- package/esm2022/lib/modal/modal.service.js.map +1 -1
- package/esm2022/lib/modal/modal.types.js +2 -0
- package/esm2022/lib/modal/modal.types.js.map +1 -0
- package/esm2022/lib/profile-stats/profile-stats.component.js +6 -2
- package/esm2022/lib/profile-stats/profile-stats.component.js.map +1 -1
- package/esm2022/lib/profile-stats/profile-stats.types.js.map +1 -1
- package/esm2022/lib/rating-display/index.js +2 -0
- package/esm2022/lib/rating-display/index.js.map +1 -0
- package/esm2022/lib/rating-display/rating-display.component.js +24 -0
- package/esm2022/lib/rating-display/rating-display.component.js.map +1 -0
- package/esm2022/lib/rating-stars/index.js +2 -0
- package/esm2022/lib/rating-stars/index.js.map +1 -0
- package/esm2022/lib/rating-stars/rating-stars.component.js +33 -0
- package/esm2022/lib/rating-stars/rating-stars.component.js.map +1 -0
- package/esm2022/lib/select/index.js +1 -1
- package/esm2022/lib/select/index.js.map +1 -1
- package/esm2022/lib/select/select.component.js +31 -1
- package/esm2022/lib/select/select.component.js.map +1 -1
- package/esm2022/lib/select/select.types.js +2 -0
- package/esm2022/lib/select/select.types.js.map +1 -0
- package/esm2022/lib/snackbar/index.js.map +1 -1
- package/esm2022/lib/snackbar/snackbar.component.js +19 -2
- package/esm2022/lib/snackbar/snackbar.component.js.map +1 -1
- package/esm2022/lib/snackbar/snackbar.service.js +9 -0
- package/esm2022/lib/snackbar/snackbar.service.js.map +1 -1
- package/esm2022/lib/snackbar/snackbar.types.js +2 -0
- package/esm2022/lib/snackbar/{snackbar.model.js.map → snackbar.types.js.map} +1 -1
- package/esm2022/lib/spinner/index.js +2 -0
- package/esm2022/lib/spinner/index.js.map +1 -0
- package/esm2022/lib/spinner/spinner.component.js +22 -0
- package/esm2022/lib/spinner/spinner.component.js.map +1 -0
- package/esm2022/lib/stat-card/index.js.map +1 -1
- package/esm2022/lib/stat-card/stat-card.component.js +3 -0
- package/esm2022/lib/stat-card/stat-card.component.js.map +1 -1
- package/esm2022/lib/stat-card/stat-card.types.js +2 -0
- package/esm2022/lib/stat-card/stat-card.types.js.map +1 -0
- package/esm2022/lib/tab/c80-tab.component.js +19 -2
- package/esm2022/lib/tab/c80-tab.component.js.map +1 -1
- package/esm2022/lib/tab/c80-tab.types.js +2 -0
- package/esm2022/lib/tab/c80-tab.types.js.map +1 -0
- package/esm2022/lib/tab/directives/c80-tab-item.directive.js +3 -0
- package/esm2022/lib/tab/directives/c80-tab-item.directive.js.map +1 -1
- package/esm2022/lib/tab/directives/c80-tab-label.directive.js +3 -0
- package/esm2022/lib/tab/directives/c80-tab-label.directive.js.map +1 -1
- package/esm2022/lib/tab/index.js.map +1 -1
- package/esm2022/lib/table/index.js +2 -0
- package/esm2022/lib/table/index.js.map +1 -1
- package/esm2022/lib/table/table-column-visibility.service.js +27 -34
- package/esm2022/lib/table/table-column-visibility.service.js.map +1 -1
- package/esm2022/lib/table/table-crud-state.service.js +7 -7
- package/esm2022/lib/table/table-crud-state.service.js.map +1 -1
- package/esm2022/lib/table/table-data-converter.service.js +18 -10
- package/esm2022/lib/table/table-data-converter.service.js.map +1 -1
- package/esm2022/lib/table/table-data-utils.service.js +18 -4
- package/esm2022/lib/table/table-data-utils.service.js.map +1 -1
- package/esm2022/lib/table/table-dto-mapper.service.js +98 -0
- package/esm2022/lib/table/table-dto-mapper.service.js.map +1 -0
- package/esm2022/lib/table/table-pagination.service.js +79 -0
- package/esm2022/lib/table/table-pagination.service.js.map +1 -0
- package/esm2022/lib/table/table-selection.service.js +14 -3
- package/esm2022/lib/table/table-selection.service.js.map +1 -1
- package/esm2022/lib/table/table.component.js +124 -22
- package/esm2022/lib/table/table.component.js.map +1 -1
- package/esm2022/lib/table/table.types.js.map +1 -1
- package/esm2022/lib/table/table.utils.js +10 -2
- package/esm2022/lib/table/table.utils.js.map +1 -1
- package/index.d.ts +13 -8
- package/lib/action-list/action-list.component.d.ts +7 -0
- package/lib/action-list/action-list.types.d.ts +2 -1
- package/lib/card-level/card-level.component.d.ts +4 -1
- package/lib/error-notification/error-notification.component.d.ts +20 -0
- package/lib/error-notification/error-notification.types.d.ts +4 -0
- package/lib/error-notification/index.d.ts +2 -0
- package/lib/header/header.component.d.ts +7 -1
- package/lib/header/header.types.d.ts +2 -0
- package/lib/icon/icon.component.d.ts +8 -0
- package/lib/icon/icon.types.d.ts +2 -0
- package/lib/icon/icon.utils.d.ts +7 -0
- package/lib/icon/theme.service.d.ts +17 -0
- package/lib/info-list/info-list.component.d.ts +3 -0
- package/lib/input-field/input-field.component.d.ts +17 -0
- package/lib/input-search/c80-input-search.component.d.ts +16 -0
- package/lib/input-search/index.d.ts +1 -0
- package/lib/modal/index.d.ts +1 -0
- package/lib/modal/modal.component.d.ts +58 -16
- package/lib/modal/modal.service.d.ts +73 -4
- package/lib/modal/modal.types.d.ts +15 -0
- package/lib/profile-stats/profile-stats.component.d.ts +4 -0
- package/lib/profile-stats/profile-stats.types.d.ts +6 -2
- package/lib/rating-display/index.d.ts +1 -0
- package/lib/rating-display/rating-display.component.d.ts +12 -0
- package/lib/rating-stars/index.d.ts +1 -0
- package/lib/rating-stars/rating-stars.component.d.ts +19 -0
- package/lib/select/index.d.ts +1 -1
- package/lib/select/select.component.d.ts +29 -1
- package/lib/snackbar/index.d.ts +1 -1
- package/lib/snackbar/snackbar.component.d.ts +18 -1
- package/lib/snackbar/snackbar.service.d.ts +10 -1
- package/lib/spinner/index.d.ts +1 -0
- package/lib/spinner/spinner.component.d.ts +12 -0
- package/lib/stat-card/index.d.ts +1 -0
- package/lib/stat-card/stat-card.component.d.ts +4 -7
- package/lib/stat-card/stat-card.types.d.ts +7 -0
- package/lib/tab/c80-tab.component.d.ts +17 -0
- package/lib/tab/directives/c80-tab-item.directive.d.ts +3 -0
- package/lib/tab/directives/c80-tab-label.directive.d.ts +3 -0
- package/lib/tab/index.d.ts +1 -1
- package/lib/table/index.d.ts +2 -0
- package/lib/table/table-column-visibility.service.d.ts +19 -6
- package/lib/table/table-crud-state.service.d.ts +23 -13
- package/lib/table/table-data-converter.service.d.ts +2 -0
- package/lib/table/table-data-utils.service.d.ts +7 -0
- package/lib/table/table-dto-mapper.service.d.ts +34 -0
- package/lib/table/table-pagination.service.d.ts +41 -0
- package/lib/table/table-selection.service.d.ts +14 -12
- package/lib/table/table.component.d.ts +27 -3
- package/lib/table/table.types.d.ts +17 -1
- package/lib/table/table.utils.d.ts +4 -1
- package/package.json +1 -1
- package/esm2022/lib/select/select.model.js +0 -2
- package/esm2022/lib/select/select.model.js.map +0 -1
- package/esm2022/lib/snackbar/snackbar.model.js +0 -2
- package/esm2022/lib/tab/c80-tab.model.js +0 -2
- package/esm2022/lib/tab/c80-tab.model.js.map +0 -1
- /package/lib/select/{select.model.d.ts → select.types.d.ts} +0 -0
- /package/lib/snackbar/{snackbar.model.d.ts → snackbar.types.d.ts} +0 -0
- /package/lib/tab/{c80-tab.model.d.ts → c80-tab.types.d.ts} +0 -0
package/esm2022/index.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
export * from './lib/
|
|
2
|
-
export * from './lib/icon';
|
|
3
|
-
export * from './lib/stat-card';
|
|
1
|
+
export * from './lib/action-list';
|
|
4
2
|
export * from './lib/card-level';
|
|
3
|
+
export * from './lib/header';
|
|
4
|
+
export * from './lib/icon';
|
|
5
|
+
export * from './lib/info-list';
|
|
6
|
+
export * from './lib/input-field';
|
|
7
|
+
export * from './lib/input-search';
|
|
5
8
|
export * from './lib/modal';
|
|
9
|
+
export * from './lib/profile-stats';
|
|
10
|
+
export * from './lib/rating-display';
|
|
11
|
+
export * from './lib/rating-stars';
|
|
6
12
|
export * from './lib/select';
|
|
7
13
|
export * from './lib/snackbar';
|
|
14
|
+
export * from './lib/spinner';
|
|
15
|
+
export * from './lib/stat-card';
|
|
8
16
|
export * from './lib/tab';
|
|
9
|
-
export * from './lib/
|
|
10
|
-
export * from './lib/
|
|
11
|
-
export * from './lib/header';
|
|
12
|
-
export * from './lib/profile-stats';
|
|
13
|
-
export * from './lib//input-field';
|
|
17
|
+
export * from './lib/table';
|
|
18
|
+
export * from './lib/error-notification';
|
|
14
19
|
//# sourceMappingURL=index.js.map
|
package/esm2022/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../libs/ui/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../libs/ui/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC","sourcesContent":["export * from './lib/action-list';\nexport * from './lib/card-level';\nexport * from './lib/header';\nexport * from './lib/icon';\nexport * from './lib/info-list';\nexport * from './lib/input-field';\nexport * from './lib/input-search';\nexport * from './lib/modal';\nexport * from './lib/profile-stats';\nexport * from './lib/rating-display';\nexport * from './lib/rating-stars';\nexport * from './lib/select';\nexport * from './lib/snackbar';\nexport * from './lib/spinner';\nexport * from './lib/stat-card';\nexport * from './lib/tab';\nexport * from './lib/table';\nexport * from './lib/error-notification';\n"]}
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';
|
|
2
2
|
import { IconComponent } from '../icon';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
4
7
|
export class ActionListComponent {
|
|
5
8
|
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
6
9
|
actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : []));
|
|
7
10
|
actionClick = output();
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param action
|
|
14
|
+
*/
|
|
8
15
|
onActionClick(action) {
|
|
9
16
|
if (typeof action.action === 'string') {
|
|
10
17
|
this.actionClick.emit(action.action);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-list.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/action-list/action-list.component.ts","../../../../../libs/ui/src/lib/action-list/action-list.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;
|
|
1
|
+
{"version":3,"file":"action-list.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/action-list/action-list.component.ts","../../../../../libs/ui/src/lib/action-list/action-list.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;AAExC;;GAEG;AAUH,MAAM,OAAO,mBAAmB;IAC5B,KAAK,GAAG,KAAK,CAAS,EAAE,iDAAC,CAAC;IAC1B,OAAO,GAAG,KAAK,CAAe,EAAE,mDAAC,CAAC;IAElC,WAAW,GAAG,MAAM,EAAU,CAAC;IAE/B;;;OAGG;IACO,aAAa,CAAC,MAAkB;QACtC,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC7C,MAAM,CAAC,MAAM,EAAE,CAAC;QACpB,CAAC;IACL,CAAC;wGAhBQ,mBAAmB;4FAAnB,mBAAmB,sXChBhC,w5BAoBM,8+BDTQ,aAAa;;4FAKd,mBAAmB;kBAT/B,SAAS;+BAEI,iBAAiB,cACf,IAAI,WACP,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM","sourcesContent":["import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';\nimport type { ActionItem } from './action-list.types';\nimport { IconComponent } from '../icon';\n\n/**\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-action-list',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './action-list.component.html',\n styleUrl: './action-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ActionListComponent {\n title = input<string>('');\n actions = input<ActionItem[]>([]);\n\n actionClick = output<string>();\n\n /**\n *\n * @param action\n */\n protected onActionClick(action: ActionItem): void {\n if (typeof action.action === 'string') {\n this.actionClick.emit(action.action);\n } else if (typeof action.action === 'function') {\n action.action();\n }\n }\n}","<div class=\"action-list\">\n @if (title()) {\n <h2 class=\"action-list__title\">{{ title() }}</h2>\n }\n\n @for (action of actions(); track $index) {\n <button class=\"action-list__item\" [class.action-list__item--danger]=\"action.isDanger\" [class.action-list__item--navigable]=\"action.isNavigable\" (click)=\"onActionClick(action)\">\n\n <div class=\"action-list__info\">\n <span class=\"action-list__label\">{{ action.label }}</span>\n @if (action.description) {\n <span class=\"action-list__description\">{{ action.description }}</span>\n }\n </div>\n\n @if (action.icon || action.isNavigable) {\n <c80-icon [button]=\"!action.isNavigable\" [icon]=\"action.icon || (action.isNavigable ? 'arrowRight' : '')\" [color]=\"action.isDanger ? 'warn' : undefined\" [title]=\"action.label\" />\n }\n </button>\n }\n</div>"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-list.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/action-list/action-list.types.ts"],"names":[],"mappings":"","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"action-list.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/action-list/action-list.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { IconType } from '../icon';\n\nexport interface ActionItem {\n label: string;\n description?: string;\n icon?: IconType;\n action?: string | (() => void);\n isDanger?: boolean;\n isNavigable?: boolean;\n}"]}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Component, input, computed, ChangeDetectionStrategy } from '@angular/core';
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
3
6
|
export class CardLevelComponent {
|
|
4
7
|
/* v8 ignore next */
|
|
5
8
|
cardLevelData = input.required(...(ngDevMode ? [{ debugName: "cardLevelData" }] : []));
|
|
@@ -34,9 +37,7 @@ export class CardLevelComponent {
|
|
|
34
37
|
}, ...(ngDevMode ? [{ debugName: "bidirectionalFillPercent" }] : []));
|
|
35
38
|
// Determina la dirección del fill (left/right)
|
|
36
39
|
/* v8 ignore next 3 */
|
|
37
|
-
fillDirection = computed(() => {
|
|
38
|
-
return this.cardLevelData().value >= 0 ? 'right' : 'left';
|
|
39
|
-
}, ...(ngDevMode ? [{ debugName: "fillDirection" }] : []));
|
|
40
|
+
fillDirection = computed(() => this.cardLevelData().value >= 0 ? 'right' : 'left', ...(ngDevMode ? [{ debugName: "fillDirection" }] : []));
|
|
40
41
|
// Color según el valor y umbrales
|
|
41
42
|
/* v8 ignore next 11 */
|
|
42
43
|
fillColor = computed(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card-level.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/card-level/card-level.component.ts","../../../../../libs/ui/src/lib/card-level/card-level.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;;
|
|
1
|
+
{"version":3,"file":"card-level.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/card-level/card-level.component.ts","../../../../../libs/ui/src/lib/card-level/card-level.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;;AAGpF;;GAEG;AAUH,MAAM,OAAO,kBAAkB;IAC7B,oBAAoB;IACpB,aAAa,GAAG,KAAK,CAAC,QAAQ,wDAAiB,CAAC;IAChD,oBAAoB;IACpB,IAAI,GAAG,KAAK,CAAS,CAAC,gDAAC,CAAC,CAAC,wCAAwC;IAEjE,uCAAuC;IACvC,sBAAsB;IACb,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;QACpD,OAAO,GAAG,KAAK,IAAI,SAAS,EAAE,CAAC;IACjC,CAAC,uDAAC,CAAC;IAEH,6BAA6B;IAC7B,sBAAsB;IACb,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QACjC,MAAM,SAAS,GAAG,GAAG,CAAC;QACtB,MAAM,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAChD,OAAO,GAAG,eAAe,IAAI,CAAC;IAChC,CAAC,qDAAC,CAAC;IAEH,oEAAoE;IACpE,sBAAsB;IACtB,eAAe,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACtC,CAAC,2DAAC,CAAC;IAEH,4DAA4D;IAC5D,sBAAsB;IACtB,wBAAwB,GAAG,QAAQ,CAAC,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACvC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC;IACjD,CAAC,oEAAC,CAAC;IAEH,+CAA+C;IAC/C,sBAAsB;IACtB,aAAa,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,yDAAC,CAAC;IAEnF,kCAAkC;IAClC,uBAAuB;IACvB,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,qBAAqB,CAAC;QAC/B,CAAC;QACD,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,OAAO,sBAAsB,CAAC;QAChC,CAAC;QACD,OAAO,sBAAsB,CAAC;IAChC,CAAC,qDAAC,CAAC;wGAxDQ,kBAAkB;4FAAlB,kBAAkB,0VCf/B,qtCAyBgE;;4FDVnD,kBAAkB;kBAT9B,SAAS;+BAEE,gBAAgB,cACd,IAAI,WACP,EAAE,mBAGM,uBAAuB,CAAC,MAAM","sourcesContent":["import { Component, input, computed, ChangeDetectionStrategy } from '@angular/core';\nimport type { CardLevelData } from './card-level.interface';\n\n/**\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-card-level',\n standalone: true,\n imports: [],\n templateUrl: './card-level.component.html',\n styleUrl: './card-level.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CardLevelComponent {\n /* v8 ignore next */\n cardLevelData = input.required<CardLevelData>();\n /* v8 ignore next */\n size = input<number>(1); // Multiplicador del tamaño base (220px)\n\n // ID único generado para el componente\n /* v8 ignore next 5 */\n readonly generatedId = computed(() => {\n const label = this.cardLevelData().label.toLowerCase().replaceAll(/\\s+/g, '-');\n const randomNum = Math.floor(Math.random() * 10000);\n return `${label}-${randomNum}`;\n });\n\n // Ancho calculado de la card\n /* v8 ignore next 4 */\n readonly cardWidth = computed(() => {\n const baseWidth = 140;\n const calculatedWidth = baseWidth * this.size();\n return `${calculatedWidth}px`;\n });\n\n // Detecta si el rango es bidireccional (min negativo, max positivo)\n /* v8 ignore next 4 */\n isBidirectional = computed(() => {\n const data = this.cardLevelData();\n return data.min < 0 && data.max > 0;\n });\n\n // Calcula el porcentaje de fill para barras bidireccionales\n /* v8 ignore next 4 */\n bidirectionalFillPercent = computed(() => {\n const data = this.cardLevelData();\n const totalRange = data.max - data.min;\n return Math.abs(data.value / totalRange) * 100;\n });\n\n // Determina la dirección del fill (left/right)\n /* v8 ignore next 3 */\n fillDirection = computed(() => this.cardLevelData().value >= 0 ? 'right' : 'left');\n\n // Color según el valor y umbrales\n /* v8 ignore next 11 */\n fillColor = computed(() => {\n const data = this.cardLevelData();\n const absValue = Math.abs(data.value);\n const absHigh = Math.abs(data.high);\n const absLow = Math.abs(data.low);\n\n if (absValue >= absHigh) {\n return 'var(--color-danger)';\n }\n if (absValue >= absLow) {\n return 'var(--color-warning)';\n }\n return 'var(--color-success)';\n });\n}\n","<!-- eslint-disable @angular-eslint/template/no-inline-styles -->\n<div class=\"card-level-container\" [style.width]=\"cardWidth()\">\n <label [for]=\"generatedId()\">\n <strong>{{ cardLevelData().label }}</strong>\n\n <span class=\"value-display\">\n @if (isBidirectional()) {\n <!-- Barra bidireccional desde el centro -->\n <div class=\"bidirectional-meter\">\n <div class=\"meter-track\">\n <div class=\"center-line\"></div>\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\n </div>\n </div>\n </div>\n } @else {\n <!-- Meter estándar para rangos unidireccionales -->\n <meter [id]=\"generatedId()\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\n </meter>\n }\n\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\n </span>\n </label>\n</div>\n<!-- eslint-enable @angular-eslint/template/no-inline-styles -->"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card-level.interface.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/card-level/card-level.interface.ts"],"names":[],"mappings":"","sourcesContent":["export interface CardLevelData {\
|
|
1
|
+
{"version":3,"file":"card-level.interface.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/card-level/card-level.interface.ts"],"names":[],"mappings":"","sourcesContent":["export interface CardLevelData {\n label: string;\n value: number;\n min: number;\n max: number;\n optimum: number;\n low: number;\n high: number;\n unit: string;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/card-level/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC","sourcesContent":["export * from './card-level.component';\
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/card-level/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC","sourcesContent":["export * from './card-level.component';\nexport * from './card-level.interface';\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
|
|
2
|
+
import { IconComponent } from '../icon';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Componente reutilizable para mostrar mensajes de error
|
|
6
|
+
*/
|
|
7
|
+
export class ErrorNotificationComponent {
|
|
8
|
+
config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
9
|
+
dismiss = output();
|
|
10
|
+
/**
|
|
11
|
+
* Divide el mensaje en oraciones separadas por '. '
|
|
12
|
+
* Excluye la última oración si termina en punto
|
|
13
|
+
*/
|
|
14
|
+
sentences = computed(() => {
|
|
15
|
+
const message = this.config().message;
|
|
16
|
+
const parts = message.split('. ');
|
|
17
|
+
// Si solo hay una parte, devolverla como está
|
|
18
|
+
if (parts.length === 1) {
|
|
19
|
+
return [message];
|
|
20
|
+
}
|
|
21
|
+
// Si la última parte está vacía (mensaje terminaba en '. '), eliminarla
|
|
22
|
+
if (parts.at(-1) === '') {
|
|
23
|
+
return parts.slice(0, -1).map(part => `${part}.`);
|
|
24
|
+
}
|
|
25
|
+
// Agregar punto a todas las partes excepto la última
|
|
26
|
+
return parts.map((part, index) => index === parts.length - 1 ? part : `${part}.`);
|
|
27
|
+
}, ...(ngDevMode ? [{ debugName: "sentences" }] : []));
|
|
28
|
+
/**
|
|
29
|
+
* Emite evento de cierre
|
|
30
|
+
*/
|
|
31
|
+
onDismiss() {
|
|
32
|
+
this.dismiss.emit();
|
|
33
|
+
}
|
|
34
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ErrorNotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
35
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: ErrorNotificationComponent, isStandalone: true, selector: "c80-error-notification", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dismiss: "dismiss" }, ngImport: i0, template: "<div class=\"error-notification\">\n <div class=\"error-notification__content\">\n <c80-icon icon=\"error\" [size]=\"1.2\" />\n <div class=\"error-notification__message\">\n @for (sentence of sentences(); track $index) {\n <p>{{ sentence }}</p>\n }\n </div>\n </div>\n @if (config().dismissible !== false) {\n <c80-icon icon=\"close\" [size]=\"0.8\" (click)=\"onDismiss()\" (keydown.enter)=\"onDismiss()\" class=\"error-notification__close\" aria-label=\"Cerrar notificaci\u00F3n\" />\n }\n</div>", styles: [".error-notification{display:flex;align-items:center;justify-content:space-between;gap:var(--spacing-sm);padding:var(--spacing-md);background:#8b000014;border:1px solid rgba(139,68,68,.2);border-radius:var(--border-radius-lg);color:#8b0000;animation:slideDown .3s cubic-bezier(.4,0,.2,1)}.error-notification p{margin:0;font-size:.875rem;line-height:1.5;font-weight:var(--font-weight-medium)}.error-notification__message{display:flex;flex-direction:column}.error-notification__content{display:flex;align-items:center;gap:var(--spacing-sm);flex:1}.error-notification__content c80-icon{flex-shrink:0}.error-notification__close{flex-shrink:0;cursor:pointer;opacity:.7;transition:opacity .2s}.error-notification__close:hover{opacity:1}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight", "dark"], outputs: ["iconClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
36
|
+
}
|
|
37
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ErrorNotificationComponent, decorators: [{
|
|
38
|
+
type: Component,
|
|
39
|
+
args: [{ selector: 'c80-error-notification', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"error-notification\">\n <div class=\"error-notification__content\">\n <c80-icon icon=\"error\" [size]=\"1.2\" />\n <div class=\"error-notification__message\">\n @for (sentence of sentences(); track $index) {\n <p>{{ sentence }}</p>\n }\n </div>\n </div>\n @if (config().dismissible !== false) {\n <c80-icon icon=\"close\" [size]=\"0.8\" (click)=\"onDismiss()\" (keydown.enter)=\"onDismiss()\" class=\"error-notification__close\" aria-label=\"Cerrar notificaci\u00F3n\" />\n }\n</div>", styles: [".error-notification{display:flex;align-items:center;justify-content:space-between;gap:var(--spacing-sm);padding:var(--spacing-md);background:#8b000014;border:1px solid rgba(139,68,68,.2);border-radius:var(--border-radius-lg);color:#8b0000;animation:slideDown .3s cubic-bezier(.4,0,.2,1)}.error-notification p{margin:0;font-size:.875rem;line-height:1.5;font-weight:var(--font-weight-medium)}.error-notification__message{display:flex;flex-direction:column}.error-notification__content{display:flex;align-items:center;gap:var(--spacing-sm);flex:1}.error-notification__content c80-icon{flex-shrink:0}.error-notification__close{flex-shrink:0;cursor:pointer;opacity:.7;transition:opacity .2s}.error-notification__close:hover{opacity:1}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
40
|
+
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
|
|
41
|
+
//# sourceMappingURL=error-notification.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-notification.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/error-notification/error-notification.component.ts","../../../../../libs/ui/src/lib/error-notification/error-notification.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;AAGxC;;GAEG;AAUH,MAAM,OAAO,0BAA0B;IACnC,MAAM,GAAG,KAAK,CAAC,QAAQ,iDAA2B,CAAC;IAEnD,OAAO,GAAG,MAAM,EAAQ,CAAC;IAEzB;;;OAGG;IACgB,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElC,8CAA8C;QAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;QAED,wEAAwE;QACxE,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;QACtD,CAAC;QAED,qDAAqD;QACrD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAC7B,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CACjD,CAAC;IACN,CAAC,qDAAC,CAAC;IAEH;;OAEG;IACO,SAAS;QACf,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;wGAlCQ,0BAA0B;4FAA1B,0BAA0B,yPChBvC,ujBAYM,y3BDDQ,aAAa;;4FAKd,0BAA0B;kBATtC,SAAS;+BAEI,wBAAwB,cACtB,IAAI,WACP,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM","sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';\nimport { IconComponent } from '../icon';\nimport type { ErrorNotificationConfig } from './error-notification.types';\n\n/**\n * Componente reutilizable para mostrar mensajes de error\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-error-notification',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './error-notification.component.html',\n styleUrl: './error-notification.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ErrorNotificationComponent {\n config = input.required<ErrorNotificationConfig>();\n\n dismiss = output<void>();\n\n /**\n * Divide el mensaje en oraciones separadas por '. '\n * Excluye la última oración si termina en punto\n */\n protected readonly sentences = computed(() => {\n const message = this.config().message;\n const parts = message.split('. ');\n\n // Si solo hay una parte, devolverla como está\n if (parts.length === 1) {\n return [message];\n }\n\n // Si la última parte está vacía (mensaje terminaba en '. '), eliminarla\n if (parts.at(-1) === '') {\n return parts.slice(0, -1).map(part => `${part}.`);\n }\n\n // Agregar punto a todas las partes excepto la última\n return parts.map((part, index) =>\n index === parts.length - 1 ? part : `${part}.`\n );\n });\n\n /**\n * Emite evento de cierre\n */\n protected onDismiss(): void {\n this.dismiss.emit();\n }\n}\n","<div class=\"error-notification\">\n <div class=\"error-notification__content\">\n <c80-icon icon=\"error\" [size]=\"1.2\" />\n <div class=\"error-notification__message\">\n @for (sentence of sentences(); track $index) {\n <p>{{ sentence }}</p>\n }\n </div>\n </div>\n @if (config().dismissible !== false) {\n <c80-icon icon=\"close\" [size]=\"0.8\" (click)=\"onDismiss()\" (keydown.enter)=\"onDismiss()\" class=\"error-notification__close\" aria-label=\"Cerrar notificación\" />\n }\n</div>"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-notification.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/error-notification/error-notification.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface ErrorNotificationConfig {\n message: string;\n dismissible?: boolean;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/error-notification/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC","sourcesContent":["export * from './error-notification.component';\nexport * from './error-notification.types';\n"]}
|
|
@@ -2,17 +2,23 @@ import { Location } from '@angular/common';
|
|
|
2
2
|
import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
|
|
3
3
|
import { IconComponent } from '../icon';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
5
8
|
export class HeaderComponent {
|
|
6
9
|
location = inject(Location);
|
|
7
10
|
config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
8
14
|
onBackClick() {
|
|
9
15
|
this.location.back();
|
|
10
16
|
}
|
|
11
17
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
18
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: HeaderComponent, isStandalone: true, selector: "c80-header", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<header class=\"header\" [class.header--no-border]=\"config().showBorder === false\">\n @if (config().showBackButton !== false) {\n <c80-icon button icon=\"arrowLeft\" [size]=\"1.2\" (iconClick)=\"onBackClick()\" title=\"Volver\" class=\"header__back-btn\" />\n }\n <h1 class=\"header__title\">{{ config().title }}</h1>\n <div class=\"header__actions\">\n <ng-content />\n </div>\n</header>", styles: [".header{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem;padding:1rem;border-bottom:1px solid var(--color-border)}.header--no-border{border-bottom:none}.header__back-btn{flex-shrink:0}.header__title{font-size:1.5rem;font-weight:600;color:var(--color-text-primary);margin:0;-webkit-user-select:none;user-select:none}.header__actions{display:flex;align-items:center;gap:var(--spacing-sm);flex-shrink:0;margin-left:auto}@media(max-width:768px){.header{padding:.75rem;gap:.75rem;margin-bottom:.5rem}.header__title{font-size:1.25rem}}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight", "dark"], outputs: ["iconClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
13
19
|
}
|
|
14
20
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: HeaderComponent, decorators: [{
|
|
15
21
|
type: Component,
|
|
16
|
-
args: [{ selector: 'c80-header', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"header\">\n <c80-icon button icon=\"arrowLeft\" [size]=\"1.2\" (iconClick)=\"onBackClick()\" title=\"Volver\" class=\"header__back-btn\" />\n <h1 class=\"header__title\">{{ config().title }}</h1>\n <
|
|
22
|
+
args: [{ selector: 'c80-header', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"header\" [class.header--no-border]=\"config().showBorder === false\">\n @if (config().showBackButton !== false) {\n <c80-icon button icon=\"arrowLeft\" [size]=\"1.2\" (iconClick)=\"onBackClick()\" title=\"Volver\" class=\"header__back-btn\" />\n }\n <h1 class=\"header__title\">{{ config().title }}</h1>\n <div class=\"header__actions\">\n <ng-content />\n </div>\n</header>", styles: [".header{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem;padding:1rem;border-bottom:1px solid var(--color-border)}.header--no-border{border-bottom:none}.header__back-btn{flex-shrink:0}.header__title{font-size:1.5rem;font-weight:600;color:var(--color-text-primary);margin:0;-webkit-user-select:none;user-select:none}.header__actions{display:flex;align-items:center;gap:var(--spacing-sm);flex-shrink:0;margin-left:auto}@media(max-width:768px){.header{padding:.75rem;gap:.75rem;margin-bottom:.5rem}.header__title{font-size:1.25rem}}\n"] }]
|
|
17
23
|
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });
|
|
18
24
|
//# sourceMappingURL=header.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/header/header.component.ts","../../../../../libs/ui/src/lib/header/header.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;
|
|
1
|
+
{"version":3,"file":"header.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/header/header.component.ts","../../../../../libs/ui/src/lib/header/header.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;AAGxC;;GAEG;AAUH,MAAM,OAAO,eAAe;IACP,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE7C,MAAM,GAAG,KAAK,CAAC,QAAQ,iDAAgB,CAAC;IAExC;;OAEG;IACO,WAAW;QACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;wGAVQ,eAAe;4FAAf,eAAe,4MCjB5B,iaAQS,snBDIK,aAAa;;4FAKd,eAAe;kBAT3B,SAAS;+BAEI,YAAY,cACV,IAAI,WACP,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM","sourcesContent":["import { Location } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';\nimport { IconComponent } from '../icon';\nimport type { HeaderConfig } from './header.types';\n\n/**\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-header',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './header.component.html',\n styleUrl: './header.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class HeaderComponent {\n private readonly location = inject(Location);\n\n config = input.required<HeaderConfig>();\n\n /**\n *\n */\n protected onBackClick(): void {\n this.location.back();\n }\n}","<header class=\"header\" [class.header--no-border]=\"config().showBorder === false\">\n @if (config().showBackButton !== false) {\n <c80-icon button icon=\"arrowLeft\" [size]=\"1.2\" (iconClick)=\"onBackClick()\" title=\"Volver\" class=\"header__back-btn\" />\n }\n <h1 class=\"header__title\">{{ config().title }}</h1>\n <div class=\"header__actions\">\n <ng-content />\n </div>\n</header>"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"header.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/header/header.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface HeaderConfig {\n title: string;\n}"]}
|
|
1
|
+
{"version":3,"file":"header.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/header/header.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface HeaderConfig {\n title: string;\n showBackButton?: boolean;\n showBorder?: boolean;\n}"]}
|
|
@@ -5,6 +5,9 @@ import { ICON_DEFINITIONS } from './icon.definitions';
|
|
|
5
5
|
import { transformToBoolean, shouldIconUseFill } from './icon.utils';
|
|
6
6
|
import { ThemeService } from './theme.service';
|
|
7
7
|
import * as i0 from "@angular/core";
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
8
11
|
export class IconComponent {
|
|
9
12
|
themeService = inject(ThemeService);
|
|
10
13
|
/* v8 ignore next */
|
|
@@ -54,26 +57,29 @@ export class IconComponent {
|
|
|
54
57
|
return !hasCustomColor && isOpacityReducedColor ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;
|
|
55
58
|
}, ...(ngDevMode ? [{ debugName: "iconOpacity" }] : []));
|
|
56
59
|
// Optimización: Un solo lookup a ICON_DEFINITIONS
|
|
57
|
-
iconDefinition = computed(() => {
|
|
58
|
-
return ICON_DEFINITIONS[this.icon()] ?? ICON_DEFINITIONS['default'];
|
|
59
|
-
}, ...(ngDevMode ? [{ debugName: "iconDefinition" }] : []));
|
|
60
|
+
iconDefinition = computed(() => ICON_DEFINITIONS[this.icon()] ?? ICON_DEFINITIONS['default'], ...(ngDevMode ? [{ debugName: "iconDefinition" }] : []));
|
|
60
61
|
iconPath = computed(() => this.iconDefinition().path, ...(ngDevMode ? [{ debugName: "iconPath" }] : []));
|
|
61
62
|
additionalShapes = computed(() => this.iconDefinition().additionalShapes ?? [], ...(ngDevMode ? [{ debugName: "additionalShapes" }] : []));
|
|
62
63
|
shouldFillIcon = computed(() => shouldIconUseFill(this.icon()), ...(ngDevMode ? [{ debugName: "shouldFillIcon" }] : []));
|
|
63
64
|
multiColorIcon = computed(() => this.iconDefinition().multiColor, ...(ngDevMode ? [{ debugName: "multiColorIcon" }] : []));
|
|
64
65
|
hasMultiPaths = computed(() => this.multiColorIcon() !== undefined, ...(ngDevMode ? [{ debugName: "hasMultiPaths" }] : []));
|
|
66
|
+
iconStrokeWidth = computed(() => this.iconDefinition().strokeWidth ?? SVG_STROKE_ATTRS.strokeWidth, ...(ngDevMode ? [{ debugName: "iconStrokeWidth" }] : []));
|
|
65
67
|
// Exponer constantes SVG al template
|
|
66
68
|
svgStrokeAttrs = SVG_STROKE_ATTRS;
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param event
|
|
72
|
+
*/
|
|
67
73
|
onButtonClick(event) {
|
|
68
74
|
if (!this.disabled()) {
|
|
69
75
|
this.iconClick.emit(event);
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
73
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: IconComponent, isStandalone: true, selector: "c80-icon", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, textLeft: { classPropertyName: "textLeft", publicName: "textLeft", isSignal: true, isRequired: false, transformFunction: null }, textRight: { classPropertyName: "textRight", publicName: "textRight", isSignal: true, isRequired: false, transformFunction: null }, dark: { classPropertyName: "dark", publicName: "dark", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { iconClick: "iconClick" }, ngImport: i0, template: "<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con m\u00FAltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"
|
|
79
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: IconComponent, isStandalone: true, selector: "c80-icon", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, textLeft: { classPropertyName: "textLeft", publicName: "textLeft", isSignal: true, isRequired: false, transformFunction: null }, textRight: { classPropertyName: "textRight", publicName: "textRight", isSignal: true, isRequired: false, transformFunction: null }, dark: { classPropertyName: "dark", publicName: "dark", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { iconClick: "iconClick" }, ngImport: i0, template: "<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con m\u00FAltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"iconStrokeWidth()\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\"\n [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\" />\n }\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}", styles: [":host{--icon-border-color: #e5e7eb;--icon-border-color-hover: #d1d5db;--icon-border-color-disabled: #f3f4f6;--icon-bg-hover: #f3f4f6;--icon-bg-active: #e5e7eb;--icon-text-color: #111827;--icon-border-radius: 4px;--icon-transition: .2s}:host .dark-mode{--icon-border-color: #374151;--icon-border-color-hover: #4b5563;--icon-border-color-disabled: #1f2937;--icon-bg-hover: #374151;--icon-bg-active: #4b5563;--icon-text-color: #f9fafb}:host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity var(--icon-transition)}:host button.icon-wrapper:focus-visible{outline:none;outline-offset:2px;border-radius:var(--icon-border-radius)}:host button.icon-wrapper:disabled{opacity:.5;cursor:default}:host .icon-content{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;min-width:0;min-height:0;padding:4px;margin:0 4px;transition:background var(--icon-transition);box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:var(--icon-bg-hover)}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:var(--icon-bg-active)}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none;color:var(--icon-text-color)}:host .icon-wrapper-border{border:1px solid var(--icon-border-color);border-radius:var(--icon-border-radius);padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:var(--icon-border-color-hover)}:host button.icon-wrapper-border:disabled{border-color:var(--icon-border-color-disabled)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
74
80
|
}
|
|
75
81
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: IconComponent, decorators: [{
|
|
76
82
|
type: Component,
|
|
77
|
-
args: [{ selector: 'c80-icon', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con m\u00FAltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"
|
|
83
|
+
args: [{ selector: 'c80-icon', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con m\u00FAltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"iconStrokeWidth()\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\"\n [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\" />\n }\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}", styles: [":host{--icon-border-color: #e5e7eb;--icon-border-color-hover: #d1d5db;--icon-border-color-disabled: #f3f4f6;--icon-bg-hover: #f3f4f6;--icon-bg-active: #e5e7eb;--icon-text-color: #111827;--icon-border-radius: 4px;--icon-transition: .2s}:host .dark-mode{--icon-border-color: #374151;--icon-border-color-hover: #4b5563;--icon-border-color-disabled: #1f2937;--icon-bg-hover: #374151;--icon-bg-active: #4b5563;--icon-text-color: #f9fafb}:host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity var(--icon-transition)}:host button.icon-wrapper:focus-visible{outline:none;outline-offset:2px;border-radius:var(--icon-border-radius)}:host button.icon-wrapper:disabled{opacity:.5;cursor:default}:host .icon-content{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;min-width:0;min-height:0;padding:4px;margin:0 4px;transition:background var(--icon-transition);box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:var(--icon-bg-hover)}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:var(--icon-bg-active)}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none;color:var(--icon-text-color)}:host .icon-wrapper-border{border:1px solid var(--icon-border-color);border-radius:var(--icon-border-radius);padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:var(--icon-border-color-hover)}:host button.icon-wrapper-border:disabled{border-color:var(--icon-border-color-disabled)}\n"] }]
|
|
78
84
|
}], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], customColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "customColor", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], button: [{ type: i0.Input, args: [{ isSignal: true, alias: "button", required: false }] }], border: [{ type: i0.Input, args: [{ isSignal: true, alias: "border", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], textLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "textLeft", required: false }] }], textRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "textRight", required: false }] }], dark: [{ type: i0.Input, args: [{ isSignal: true, alias: "dark", required: false }] }], iconClick: [{ type: i0.Output, args: ["iconClick"] }] } });
|
|
79
85
|
//# sourceMappingURL=icon.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/icon/icon.component.ts","../../../../../libs/ui/src/lib/icon/icon.component.html"],"names":[],"mappings":"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","sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport { Component, input, output, computed, ChangeDetectionStrategy, inject } from '@angular/core';\nimport {\n BASE_ICON_SIZE,\n BASE_ICON_COLORS,\n DISABLED_COLOR,\n DEFAULT_ICON_COLOR,\n DISABLED_OPACITY,\n SECONDARY_WARN_OPACITY,\n DEFAULT_OPACITY,\n OPACITY_REDUCED_COLORS,\n SVG_STROKE_ATTRS,\n THEME_DARK_COLOR,\n THEME_LIGHT_COLOR,\n} from './icon.constants';\nimport { ICON_DEFINITIONS } from './icon.definitions';\nimport type { ColorType, ButtonType, IconType } from './icon.types';\nimport { transformToBoolean, shouldIconUseFill } from './icon.utils';\nimport { ThemeService } from './theme.service';\n\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-icon',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './icon.component.html',\n styleUrls: ['./icon.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class IconComponent {\n private readonly themeService = inject(ThemeService);\n\n /* v8 ignore next */\n readonly icon = input<IconType>('check'); // Tipo de icono a mostrar\n /* v8 ignore next */\n readonly color = input<ColorType | undefined>(undefined); // Color del icono (primary, secondary, warn, success)\n /* v8 ignore next */\n readonly customColor = input<string | undefined>(undefined); // Color personalizado (sobrescribe color)\n /* v8 ignore next */\n readonly disabled = input(false); // Estado deshabilitado\n /* v8 ignore next */\n readonly size = input(1); // Multiplicador de tamaño (1 = 24px)\n /* v8 ignore next */\n readonly button = input(false, { transform: transformToBoolean }); // Renderiza como botón clickeable\n /* v8 ignore next */\n readonly border = input(false, { transform: transformToBoolean }); // Agrega borde al wrapper\n /* v8 ignore next */\n readonly type = input<ButtonType>('button'); // Tipo de botón (button, submit, reset)\n /* v8 ignore next */\n readonly textLeft = input<string | undefined>(undefined); // Texto a la izquierda del icono\n /* v8 ignore next */\n readonly textRight = input<string | undefined>(undefined); // Texto a la derecha del icono\n /* v8 ignore next */\n readonly dark = input(false, { transform: transformToBoolean }); // Modo oscuro\n\n readonly iconClick = output<Event>(); // Evento emitido al hacer click (solo si button=true)\n\n readonly iconSize = computed(() => BASE_ICON_SIZE * this.size());\n\n readonly isDarkMode = computed(() => this.dark() || this.themeService.isDark());\n\n readonly iconColor = computed(() => {\n if (this.disabled()) return DISABLED_COLOR;\n\n const custom = this.customColor();\n if (custom) return custom;\n\n const colorType = this.color();\n\n // Si no hay color específico, usar color adaptativo al tema\n if (!colorType) {\n return this.themeService.isDark() ? THEME_DARK_COLOR : THEME_LIGHT_COLOR;\n }\n\n return BASE_ICON_COLORS[colorType] ?? DEFAULT_ICON_COLOR;\n });\n\n readonly iconOpacity = computed(() => {\n if (this.disabled()) return DISABLED_OPACITY;\n\n const hasCustomColor = this.customColor() !== undefined;\n const colorType = this.color();\n const isOpacityReducedColor = colorType && OPACITY_REDUCED_COLORS.includes(colorType);\n\n return !hasCustomColor && isOpacityReducedColor ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;\n });\n\n // Optimización: Un solo lookup a ICON_DEFINITIONS\n readonly iconDefinition = computed(() => {\n return ICON_DEFINITIONS[this.icon()] ?? ICON_DEFINITIONS['default'];\n });\n\n readonly iconPath = computed(() => this.iconDefinition().path);\n\n readonly additionalShapes = computed(() => this.iconDefinition().additionalShapes ?? []);\n\n readonly shouldFillIcon = computed(() => shouldIconUseFill(this.icon()));\n\n readonly multiColorIcon = computed(() => this.iconDefinition().multiColor);\n\n readonly hasMultiPaths = computed(() => this.multiColorIcon() !== undefined);\n\n // Exponer constantes SVG al template\n readonly svgStrokeAttrs = SVG_STROKE_ATTRS;\n\n onButtonClick(event: Event): void {\n if (!this.disabled()) {\n this.iconClick.emit(event);\n }\n }\n}\n","<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con múltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\"\n [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\" />\n }\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}"]}
|
|
1
|
+
{"version":3,"file":"icon.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/icon/icon.component.ts","../../../../../libs/ui/src/lib/icon/icon.component.html"],"names":[],"mappings":"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","sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport { Component, input, output, computed, ChangeDetectionStrategy, inject } from '@angular/core';\nimport {\n BASE_ICON_SIZE,\n BASE_ICON_COLORS,\n DISABLED_COLOR,\n DEFAULT_ICON_COLOR,\n DISABLED_OPACITY,\n SECONDARY_WARN_OPACITY,\n DEFAULT_OPACITY,\n OPACITY_REDUCED_COLORS,\n SVG_STROKE_ATTRS,\n THEME_DARK_COLOR,\n THEME_LIGHT_COLOR,\n} from './icon.constants';\nimport { ICON_DEFINITIONS } from './icon.definitions';\nimport type { ColorType, ButtonType, IconType } from './icon.types';\nimport { transformToBoolean, shouldIconUseFill } from './icon.utils';\nimport { ThemeService } from './theme.service';\n\n\n/**\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-icon',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './icon.component.html',\n styleUrls: ['./icon.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class IconComponent {\n private readonly themeService = inject(ThemeService);\n\n /* v8 ignore next */\n readonly icon = input<IconType>('check'); // Tipo de icono a mostrar\n /* v8 ignore next */\n readonly color = input<ColorType | undefined>(undefined); // Color del icono (primary, secondary, warn, success)\n /* v8 ignore next */\n readonly customColor = input<string | undefined>(undefined); // Color personalizado (sobrescribe color)\n /* v8 ignore next */\n readonly disabled = input(false); // Estado deshabilitado\n /* v8 ignore next */\n readonly size = input(1); // Multiplicador de tamaño (1 = 24px)\n /* v8 ignore next */\n readonly button = input(false, { transform: transformToBoolean }); // Renderiza como botón clickeable\n /* v8 ignore next */\n readonly border = input(false, { transform: transformToBoolean }); // Agrega borde al wrapper\n /* v8 ignore next */\n readonly type = input<ButtonType>('button'); // Tipo de botón (button, submit, reset)\n /* v8 ignore next */\n readonly textLeft = input<string | undefined>(undefined); // Texto a la izquierda del icono\n /* v8 ignore next */\n readonly textRight = input<string | undefined>(undefined); // Texto a la derecha del icono\n /* v8 ignore next */\n readonly dark = input(false, { transform: transformToBoolean }); // Modo oscuro\n\n readonly iconClick = output<Event>(); // Evento emitido al hacer click (solo si button=true)\n\n readonly iconSize = computed(() => BASE_ICON_SIZE * this.size());\n\n readonly isDarkMode = computed(() => this.dark() || this.themeService.isDark());\n\n readonly iconColor = computed(() => {\n if (this.disabled()) return DISABLED_COLOR;\n\n const custom = this.customColor();\n if (custom) return custom;\n\n const colorType = this.color();\n\n // Si no hay color específico, usar color adaptativo al tema\n if (!colorType) {\n return this.themeService.isDark() ? THEME_DARK_COLOR : THEME_LIGHT_COLOR;\n }\n\n return BASE_ICON_COLORS[colorType] ?? DEFAULT_ICON_COLOR;\n });\n\n readonly iconOpacity = computed(() => {\n if (this.disabled()) return DISABLED_OPACITY;\n\n const hasCustomColor = this.customColor() !== undefined;\n const colorType = this.color();\n const isOpacityReducedColor = colorType && OPACITY_REDUCED_COLORS.includes(colorType);\n\n return !hasCustomColor && isOpacityReducedColor ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;\n });\n\n // Optimización: Un solo lookup a ICON_DEFINITIONS\n readonly iconDefinition = computed(() => ICON_DEFINITIONS[this.icon()] ?? ICON_DEFINITIONS['default']);\n\n readonly iconPath = computed(() => this.iconDefinition().path);\n\n readonly additionalShapes = computed(() => this.iconDefinition().additionalShapes ?? []);\n\n readonly shouldFillIcon = computed(() => shouldIconUseFill(this.icon()));\n\n readonly multiColorIcon = computed(() => this.iconDefinition().multiColor);\n\n readonly hasMultiPaths = computed(() => this.multiColorIcon() !== undefined);\n\n readonly iconStrokeWidth = computed(() => this.iconDefinition().strokeWidth ?? SVG_STROKE_ATTRS.strokeWidth);\n\n // Exponer constantes SVG al template\n readonly svgStrokeAttrs = SVG_STROKE_ATTRS;\n\n /**\n *\n * @param event\n */\n onButtonClick(event: Event): void {\n if (!this.disabled()) {\n this.iconClick.emit(event);\n }\n }\n}\n","<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con múltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"iconStrokeWidth()\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\"\n [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\" />\n }\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}"]}
|