@sdcorejs/angular 20.0.3 → 20.0.4

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.
Files changed (37) hide show
  1. package/components/button/index.d.ts +1 -2
  2. package/components/form-generic/index.d.ts +3 -4
  3. package/components/query-builder/index.d.ts +247 -23
  4. package/components/section/index.d.ts +1 -2
  5. package/components/side-drawer/index.d.ts +1 -2
  6. package/components/stepper/index.d.ts +1 -2
  7. package/components/tab/index.d.ts +1 -2
  8. package/components/table/index.d.ts +1 -2
  9. package/components/upload-file/index.d.ts +2 -0
  10. package/fesm2022/sdcorejs-angular-components-button.mjs +2 -4
  11. package/fesm2022/sdcorejs-angular-components-button.mjs.map +1 -1
  12. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +6 -10
  13. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  14. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +669 -57
  15. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  16. package/fesm2022/sdcorejs-angular-components-section.mjs +2 -4
  17. package/fesm2022/sdcorejs-angular-components-section.mjs.map +1 -1
  18. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +2 -4
  19. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  20. package/fesm2022/sdcorejs-angular-components-stepper.mjs +2 -4
  21. package/fesm2022/sdcorejs-angular-components-stepper.mjs.map +1 -1
  22. package/fesm2022/sdcorejs-angular-components-tab.mjs +2 -4
  23. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  24. package/fesm2022/sdcorejs-angular-components-table.mjs +2 -4
  25. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  26. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +15 -4
  27. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  28. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +7 -2
  29. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  30. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +9 -3
  31. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  32. package/fesm2022/sdcorejs-angular-forms-input.mjs +2 -2
  33. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  34. package/fesm2022/sdcorejs-angular-services-notify.mjs +26 -8
  35. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  36. package/package.json +1 -1
  37. package/services/notify/index.d.ts +17 -0
@@ -1 +1 @@
1
- {"version":3,"file":"sdcorejs-angular-components-query-builder.mjs","sources":["../../../projects/sdcorejs-angular/components/query-builder/src/query-builder.component.ts","../../../projects/sdcorejs-angular/components/query-builder/src/query-builder.component.html","../../../projects/sdcorejs-angular/components/query-builder/sdcorejs-angular-components-query-builder.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, HostListener } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\n\nexport interface QueryRule {\n field: string;\n operator: string;\n value: any;\n}\n\nexport interface QueryGroup {\n condition: 'AND' | 'OR';\n rules: (QueryRule | QueryGroup)[];\n isOpen?: boolean; // Trạng thái mở menu\n}\n\n@Component({\n selector: 'sd-query-builder',\n standalone: true,\n imports: [CommonModule, FormsModule],\n templateUrl: './query-builder.component.html',\n styleUrls: ['./query-builder.component.scss']\n})\nexport class SdQueryBuilder {\n @Input() group: QueryGroup = {\n condition: 'AND',\n rules: [\n { field: 'Employee ID', operator: 'Equal', value: '1' },\n { field: 'Title', operator: 'Equal', value: 'Sales Manager' },\n {\n condition: 'OR',\n rules: [\n { field: 'Select Field', operator: '', value: '' }\n ]\n }\n ]\n };\n\n @Output() groupChange = new EventEmitter<QueryGroup>();\n\n isGroup(item: any): item is QueryGroup {\n return (item as QueryGroup).rules !== undefined;\n }\n\n toggleCondition(group: QueryGroup, condition: 'AND' | 'OR') {\n group.condition = condition;\n }\n\n // --- LOGIC DROPDOWN & Z-INDEX ---\n toggleDropdown(group: QueryGroup, event: Event) {\n event.stopPropagation();\n // Đóng tất cả các dropdown khác để tránh chồng chéo\n if (!group.isOpen) {\n this.closeAllDropdowns(this.group);\n }\n group.isOpen = !group.isOpen;\n }\n\n @HostListener('document:click')\n closeAll() {\n this.closeAllDropdowns(this.group);\n }\n\n closeAllDropdowns(group: QueryGroup) {\n group.isOpen = false;\n group.rules.forEach(rule => {\n if (this.isGroup(rule)) this.closeAllDropdowns(rule);\n });\n }\n // --------------------------------\n\n addRule(group: QueryGroup) {\n group.rules.push({ field: '', operator: 'Equal', value: '' });\n group.isOpen = false;\n }\n\n addGroup(group: QueryGroup) {\n group.rules.push({\n condition: 'OR',\n rules: [{ field: '', operator: '', value: '' }]\n } as QueryGroup);\n group.isOpen = false;\n }\n\n removeItem(parentGroup: QueryGroup, index: number) {\n parentGroup.rules.splice(index, 1);\n }\n}","<div class=\"qb-container\">\n <ng-container *ngTemplateOutlet=\"groupTemplate; context: { $implicit: group, isRoot: true }\"></ng-container>\n</div>\n\n<ng-template #groupTemplate let-group let-isRoot=\"isRoot\" let-parent=\"parent\" let-index=\"index\">\n <div class=\"qb-group\">\n \n <div class=\"qb-header\" [class.is-open]=\"group.isOpen\">\n <div class=\"qb-condition-switch\">\n <button type=\"button\" \n [class.active]=\"group.condition === 'AND'\" \n (click)=\"toggleCondition(group, 'AND')\">AND</button>\n <button type=\"button\" \n [class.active]=\"group.condition === 'OR'\" \n (click)=\"toggleCondition(group, 'OR')\">OR</button>\n </div>\n\n <div class=\"qb-actions\">\n <button type=\"button\" class=\"btn-icon btn-add\" (click)=\"toggleDropdown(group, $event)\">+</button>\n \n <div class=\"qb-dropdown\" *ngIf=\"group.isOpen\" (click)=\"$event.stopPropagation()\" aria-hidden=\"true\">\n <button (click)=\"addGroup(group)\">+ Add Group</button>\n <button (click)=\"addRule(group)\">+ Add Condition</button>\n </div>\n\n <button *ngIf=\"!isRoot\" type=\"button\" class=\"btn-icon btn-remove\" (click)=\"removeItem(parent, index)\">✕</button>\n </div>\n </div>\n\n <div class=\"qb-body\">\n <div class=\"qb-list\">\n <div *ngFor=\"let item of group.rules; let i = index\" \n class=\"qb-treenode\"\n [class.is-group]=\"isGroup(item)\"\n [class.is-rule]=\"!isGroup(item)\">\n \n <ng-container *ngIf=\"!isGroup(item)\">\n <div class=\"qb-rule-card\">\n <div class=\"form-row\">\n <input class=\"form-input field-input\" [(ngModel)]=\"item.field\" placeholder=\"Select Field\">\n <ng-container *ngIf=\"item.field\">\n <div class=\"divider\"></div>\n <select class=\"form-input\" [(ngModel)]=\"item.operator\">\n <option value=\"Equal\">Equal</option>\n <option value=\"Not Equal\">Not Equal</option>\n </select>\n <div class=\"divider\"></div>\n <input class=\"form-input\" [(ngModel)]=\"item.value\" placeholder=\"Value\">\n </ng-container>\n <button type=\"button\" class=\"btn-icon btn-remove-rule\" (click)=\"removeItem(group, i)\">✕</button>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"isGroup(item)\">\n <ng-container *ngTemplateOutlet=\"groupTemplate; context: { $implicit: item, isRoot: false, parent: group, index: i }\"></ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n\n </div>\n</ng-template>","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdcorejs-angular-components-query-builder.mjs","sources":["../../../projects/sdcorejs-angular/components/query-builder/src/query-builder.model.ts","../../../projects/sdcorejs-angular/components/query-builder/src/query-builder.serializer.ts","../../../projects/sdcorejs-angular/components/query-builder/src/query-builder.component.ts","../../../projects/sdcorejs-angular/components/query-builder/src/query-builder.component.html","../../../projects/sdcorejs-angular/components/query-builder/sdcorejs-angular-components-query-builder.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Operator } from '@sdcorejs/utils/models';\n\n// ---------------------------------------------------------------------------\n// Field metadata — the public config a consumer declares so the builder knows\n// each filterable field's type (→ which operators make sense) and how to render\n// its value editor + view-mode label. Self-contained: query-builder does NOT\n// reuse query-bar's SdQueryField; it only borrows `Operator`/`Filter` from utils.\n// ---------------------------------------------------------------------------\n\n/** Field kinds the builder understands. Drives the operator set + value editor. */\nexport type SdQueryBuilderFieldType = 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'values';\n\n/** One option for a `values`-type field (enum / lookup). */\nexport interface SdQueryBuilderFieldOption {\n /** Stored value (sent inside the `Filter`). */\n value: any;\n /** Human-readable label shown in the select + view-mode string. */\n display: string;\n}\n\n/**\n * One filterable field. `key` matches `Filter.field` (dot-notation allowed);\n * `label` is what the view-mode raw string renders (field token = label).\n */\nexport interface SdQueryBuilderField {\n /** Dot-notation field path — written to `Filter.field`. */\n key: string;\n /** Human label — shown in the field picker AND as the view-mode field token. */\n label: string;\n /** Field type — picks the default operator set + value editor control. */\n type: SdQueryBuilderFieldType;\n /** Override the allowed operator set (otherwise `QB_OPERATORS_BY_TYPE[type]`). */\n operators?: Operator[];\n /** Override the starting operator (otherwise `QB_DEFAULT_OPERATOR_BY_TYPE[type]`). */\n defaultOperator?: Operator;\n /** Options for `type: 'values'` — the select list + display-label lookup. */\n values?: SdQueryBuilderFieldOption[];\n /** Label for the `true` branch of a boolean field (default `'Có'`). */\n trueLabel?: string;\n /** Label for the `false` branch of a boolean field (default `'Không'`). */\n falseLabel?: string;\n /** Lower bound for number / date value editors. */\n min?: number | string;\n /** Upper bound for number / date value editors. */\n max?: number | string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal tree — carries UI state (stable `id` for @for + dropdown `open`).\n// NEVER emitted; mapped to/from the public `Filter` by the serializer.\n// ---------------------------------------------------------------------------\n\nexport type QbNode = QbGroup | QbRule;\n\n/** A logical group of nodes joined by AND / OR. Maps to `FilterAndOr`. */\nexport interface QbGroup {\n id: string;\n kind: 'group';\n logic: 'AND' | 'OR';\n children: QbNode[];\n /** UI-only: whether this group's \"+\" dropdown is open. */\n open?: boolean;\n}\n\n/** A single `field operator value` condition. Maps to a leaf `Filter`. */\nexport interface QbRule {\n id: string;\n kind: 'rule';\n field?: string;\n operator?: Operator;\n /** Single value, `{ from, to }` for BETWEEN, or an array for IN / NOT_IN. */\n value?: any;\n}\n\n/** Type guard — narrows a `QbNode` to a `QbGroup`. */\nexport function isQbGroup(node: QbNode): node is QbGroup {\n return node.kind === 'group';\n}\n\n// ---------------------------------------------------------------------------\n// View-mode tokens — the serializer turns a `Filter` into a token stream so the\n// template can wrap each piece in a highlight `<span>` (operator / value / etc).\n// ---------------------------------------------------------------------------\n\nexport type QbTokenKind = 'field' | 'op' | 'value' | 'logic' | 'paren' | 'plain';\n\n/** One piece of the rendered raw query string, tagged for highlight styling. */\nexport interface QbToken {\n text: string;\n kind: QbTokenKind;\n}\n\n// ---------------------------------------------------------------------------\n// Operator vocabulary per field type. Mirrors query-bar's\n// SD_QUERY_OPERATORS_BY_TYPE so the two components stay consistent, but is kept\n// local so query-builder has no dependency on the query-bar package.\n// ---------------------------------------------------------------------------\n\n/** Allowed operators per field type — used when `field.operators` is not set. */\nexport const QB_OPERATORS_BY_TYPE: Record<SdQueryBuilderFieldType, Operator[]> = {\n string: ['CONTAIN', 'NOT_CONTAIN', 'EQUAL', 'NOT_EQUAL', 'START_WITH', 'END_WITH', 'NULL', 'NOT_NULL'],\n number: ['EQUAL', 'NOT_EQUAL', 'GREATER_THAN', 'GREATER_OR_EQUAL', 'LESS_THAN', 'LESS_OR_EQUAL', 'BETWEEN', 'NULL', 'NOT_NULL'],\n boolean: ['EQUAL', 'NOT_EQUAL'],\n date: ['EQUAL', 'NOT_EQUAL', 'GREATER_THAN', 'LESS_THAN', 'BETWEEN', 'NULL', 'NOT_NULL'],\n datetime: ['EQUAL', 'NOT_EQUAL', 'GREATER_THAN', 'LESS_THAN', 'BETWEEN', 'NULL', 'NOT_NULL'],\n values: ['IN', 'NOT_IN', 'EQUAL', 'NOT_EQUAL', 'NULL', 'NOT_NULL'],\n};\n\n/** Default operator when a rule is first created for a field. */\nexport const QB_DEFAULT_OPERATOR_BY_TYPE: Record<SdQueryBuilderFieldType, Operator> = {\n string: 'CONTAIN',\n number: 'EQUAL',\n boolean: 'EQUAL',\n date: 'BETWEEN',\n datetime: 'BETWEEN',\n values: 'IN',\n};\n\n/** Operators with no value payload — the value editor is hidden for these. */\nexport const QB_NO_DATA_OPERATORS: Operator[] = ['NULL', 'NOT_NULL'];\n\n/** Operators whose value is an array — the value editor offers multi-select. */\nexport const QB_MULTI_OPERATORS: Operator[] = ['IN', 'NOT_IN'];\n\n/** Operators allowed for `field` — explicit override wins, else the per-type set. */\nexport function qbAllowedOperators(field: SdQueryBuilderField | undefined): Operator[] {\n if (!field) return [];\n if (field.operators?.length) return field.operators;\n return QB_OPERATORS_BY_TYPE[field.type] ?? [];\n}\n\n/** Starting operator for a new rule on `field` — falls back to the per-type default. */\nexport function qbDefaultOperator(field: SdQueryBuilderField | undefined): Operator | undefined {\n if (!field) return undefined;\n const allowed = qbAllowedOperators(field);\n if (field.defaultOperator && allowed.includes(field.defaultOperator)) return field.defaultOperator;\n const byType = QB_DEFAULT_OPERATOR_BY_TYPE[field.type];\n return allowed.includes(byType) ? byType : allowed[0];\n}\n\n/** True when `op` is NULL / NOT_NULL (no value editor). */\nexport function qbIsNoDataOperator(op: Operator | undefined): boolean {\n return !!op && QB_NO_DATA_OPERATORS.includes(op);\n}\n\n/** True when `op` is IN / NOT_IN (array value). */\nexport function qbIsMultiOperator(op: Operator | undefined): boolean {\n return !!op && QB_MULTI_OPERATORS.includes(op);\n}\n\n// ---------------------------------------------------------------------------\n// Node factories — monotonic counter for stable, render-safe ids (no Math.random\n// / Date.now so SSR + tests stay deterministic).\n// ---------------------------------------------------------------------------\n\nlet qbSeq = 0;\n\n/** Next stable node id with the given prefix. */\nexport function qbId(prefix = 'qb'): string {\n return `${prefix}-${++qbSeq}`;\n}\n\n/** Build a fresh rule node (optionally pre-filled). */\nexport function qbNewRule(field?: string, operator?: Operator, value?: any): QbRule {\n return { id: qbId('r'), kind: 'rule', field, operator, value };\n}\n\n/** Build a fresh group node. */\nexport function qbNewGroup(logic: 'AND' | 'OR' = 'AND', children: QbNode[] = []): QbGroup {\n return { id: qbId('g'), kind: 'group', logic, children };\n}\n\n// ---------------------------------------------------------------------------\n// Relative dates — a date/datetime rule's value may be a relative spec resolved\n// at query time on the backend, instead of an absolute picked date. Emitted as a\n// structured object inside Filter.data. Only for single-value operators (not BETWEEN).\n// ---------------------------------------------------------------------------\n\n/** Offset unit for a relative date. */\nexport type SdQbRelativeUnit = 'day' | 'week' | 'month';\n\n/** Offset direction for a relative date. */\nexport type SdQbRelativeDirection = 'previous' | 'next';\n\n/** A relative (resolved-at-query-time) date value stored in `Filter.data`. */\nexport interface SdQbRelativeDate {\n /** `'now'` = current moment / today · `'offset'` = now ± amount × unit. */\n rel: 'now' | 'offset';\n /** Offset unit — only for `rel: 'offset'`. */\n unit?: SdQbRelativeUnit;\n /** Offset magnitude (>= 1) — only for `rel: 'offset'`. */\n amount?: number;\n /** Offset direction — only for `rel: 'offset'`. */\n direction?: SdQbRelativeDirection;\n}\n\n/** Date value editor mode for a date/datetime rule (derived from the rule value). */\nexport type QbDateMode = 'absolute' | 'now' | 'relative';\n\n/** Type guard — narrows an arbitrary value to a relative-date spec. */\nexport function qbIsRelativeDate(v: any): v is SdQbRelativeDate {\n return !!v && typeof v === 'object' && (v.rel === 'now' || v.rel === 'offset');\n}\n\n/** Starting relative value when a rule first switches to \"relative\" mode. */\nexport function qbDefaultRelative(): SdQbRelativeDate {\n return { rel: 'offset', unit: 'day', amount: 1, direction: 'previous' };\n}\n\n/** Stable option list for the date-mode select (module ref — never reallocated). */\nexport const QB_DATE_MODES: ReadonlyArray<{ value: QbDateMode; display: string }> = [\n { value: 'absolute', display: 'Ngày cụ thể' },\n { value: 'now', display: 'Hôm nay' },\n { value: 'relative', display: 'Tương đối' },\n];\n\n/** Stable combined direction×unit option list (token `'unit:direction'`). */\nexport const QB_RELATIVE_UNIT_OPTIONS: ReadonlyArray<{ value: string; display: string }> = [\n { value: 'day:previous', display: 'ngày trước' },\n { value: 'day:next', display: 'ngày tới' },\n { value: 'week:previous', display: 'tuần trước' },\n { value: 'week:next', display: 'tuần tới' },\n { value: 'month:previous', display: 'tháng trước' },\n { value: 'month:next', display: 'tháng tới' },\n];\n\n/** Shared empty option array — stable ref for fallbacks (avoids per-call allocation). */\nexport const QB_EMPTY_OPTIONS: SdQueryBuilderFieldOption[] = [];\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Filter, Operator } from '@sdcorejs/utils/models';\nimport {\n isQbGroup,\n QB_MULTI_OPERATORS,\n QB_NO_DATA_OPERATORS,\n qbIsRelativeDate,\n QbGroup,\n QbNode,\n QbRule,\n QbToken,\n qbNewGroup,\n qbNewRule,\n SdQbRelativeDate,\n SdQbRelativeUnit,\n SdQueryBuilderField,\n} from './query-builder.model';\n\n// SQL symbol for each single-value comparison operator.\nconst SYMBOL: Partial<Record<Operator, string>> = {\n EQUAL: '=',\n NOT_EQUAL: '!=',\n GREATER_THAN: '>',\n LESS_THAN: '<',\n GREATER_OR_EQUAL: '>=',\n LESS_OR_EQUAL: '<=',\n};\n\nconst LIKE_OPERATORS: Operator[] = ['CONTAIN', 'NOT_CONTAIN', 'START_WITH', 'NOT_START_WITH', 'END_WITH', 'NOT_END_WITH'];\n\n/** A `Filter` is a logical group when its operator is AND / OR and it carries a `data[]`. */\nfunction isAndOr(filter: any): filter is { operator: 'AND' | 'OR'; data: Filter[] } {\n return !!filter && (filter.operator === 'AND' || filter.operator === 'OR') && Array.isArray(filter.data);\n}\n\nfunction isEmptyValue(v: any): boolean {\n return v === null || v === undefined || v === '';\n}\n\n// ---------------------------------------------------------------------------\n// Internal tree → public Filter\n// ---------------------------------------------------------------------------\n\nfunction ruleToFilter(rule: QbRule): Filter | null {\n if (!rule.field || !rule.operator) return null;\n const operator = rule.operator;\n\n if (QB_NO_DATA_OPERATORS.includes(operator)) {\n return { field: rule.field as any, operator } as Filter;\n }\n\n if (operator === 'BETWEEN') {\n const v = rule.value;\n if (!v || typeof v !== 'object') return null;\n if (isEmptyValue(v.from) || isEmptyValue(v.to)) return null;\n return { field: rule.field as any, operator: 'BETWEEN', data: { from: v.from, to: v.to } } as Filter;\n }\n\n if (QB_MULTI_OPERATORS.includes(operator)) {\n const arr = Array.isArray(rule.value) ? rule.value : isEmptyValue(rule.value) ? [] : [rule.value];\n if (!arr.length) return null;\n return { field: rule.field as any, operator, data: arr } as Filter;\n }\n\n if (qbIsRelativeDate(rule.value)) {\n const v = rule.value;\n if (v.rel === 'now') return { field: rule.field as any, operator, data: { rel: 'now' } } as Filter;\n // offset — only emit when fully specified, else drop the incomplete rule\n if (v.unit && v.direction && typeof v.amount === 'number' && v.amount >= 1) {\n return {\n field: rule.field as any,\n operator,\n data: { rel: 'offset', unit: v.unit, amount: v.amount, direction: v.direction },\n } as Filter;\n }\n return null;\n }\n\n if (isEmptyValue(rule.value)) return null;\n return { field: rule.field as any, operator, data: rule.value } as Filter;\n}\n\nfunction nodeToFilter(node: QbNode): Filter | null {\n if (isQbGroup(node)) {\n const data = node.children.map(nodeToFilter).filter((f): f is Filter => f != null);\n if (!data.length) return null;\n return { operator: node.logic, data } as Filter;\n }\n return ruleToFilter(node);\n}\n\n/**\n * Map the internal builder tree to the public `Filter` (the root is always a\n * `FilterAndOr`). Rules missing field / operator / value — and empty nested\n * groups — are dropped so the result is always a valid `Filter`.\n *\n * @param group - the editable tree's root group.\n * @returns the canonical nested `Filter`, or `null` when no complete rule survives.\n */\nexport function treeToFilter(group: QbGroup): Filter | null {\n return nodeToFilter(group);\n}\n\n// ---------------------------------------------------------------------------\n// Public Filter → internal tree (for seeding [value])\n// ---------------------------------------------------------------------------\n\nfunction ruleFromFilter(filter: any): QbRule {\n const operator = filter.operator as Operator;\n if (QB_NO_DATA_OPERATORS.includes(operator)) {\n return qbNewRule(filter.field, operator);\n }\n return qbNewRule(filter.field, operator, filter.data);\n}\n\nfunction nodeFromFilter(filter: Filter): QbNode {\n return isAndOr(filter) ? groupFromFilter(filter) : ruleFromFilter(filter);\n}\n\nfunction groupFromFilter(filter: { operator: 'AND' | 'OR'; data: Filter[] }): QbGroup {\n return qbNewGroup(filter.operator, filter.data.map(nodeFromFilter));\n}\n\n/**\n * Inverse of {@link treeToFilter} — rebuild the editable tree from a `Filter` so a\n * consumer can seed `[value]`. A non-group (bare) filter is wrapped in an AND root;\n * `null` yields an empty AND root.\n *\n * @param filter - a `Filter` (group or leaf), or `null` / `undefined` for an empty tree.\n * @returns a fresh root `QbGroup` mirroring the filter's structure.\n */\nexport function filterToTree(filter: Filter | null | undefined): QbGroup {\n if (!filter) return qbNewGroup('AND', []);\n if (isAndOr(filter)) return groupFromFilter(filter);\n return qbNewGroup('AND', [ruleFromFilter(filter)]);\n}\n\n// ---------------------------------------------------------------------------\n// Public Filter → SQL-ish highlight tokens (view mode)\n// ---------------------------------------------------------------------------\n\nfunction escapeStr(s: string): string {\n return s.replace(/'/g, \"''\");\n}\n\nconst REL_UNIT_VI: Record<SdQbRelativeUnit, string> = { day: 'ngày', week: 'tuần', month: 'tháng' };\n\n/** Render a relative-date spec as readable Vietnamese for the view string. */\nfunction formatRelative(v: SdQbRelativeDate): string {\n if (v.rel === 'now') return 'hôm nay';\n const unit = REL_UNIT_VI[v.unit ?? 'day'];\n const dir = v.direction === 'next' ? 'tới' : 'trước';\n return `${v.amount ?? 1} ${unit} ${dir}`;\n}\n\n/** Format one scalar value for the view string — quoted/labelled per field type. */\nfunction formatScalar(field: SdQueryBuilderField | undefined, raw: any): string {\n if (qbIsRelativeDate(raw)) return formatRelative(raw);\n if (raw === null || raw === undefined) return '';\n if (field?.type === 'boolean') {\n return raw ? field.trueLabel ?? 'Có' : field.falseLabel ?? 'Không';\n }\n if (field?.type === 'values') {\n const opt = field.values?.find(o => o.value === raw);\n return `'${escapeStr(opt ? opt.display : String(raw))}'`;\n }\n if (field?.type === 'number' || typeof raw === 'number' || typeof raw === 'boolean') {\n return String(raw);\n }\n // string / date / datetime / unknown → quoted\n return `'${escapeStr(String(raw))}'`;\n}\n\nfunction likePattern(operator: Operator, raw: string): string {\n const esc = escapeStr(raw);\n if (operator === 'CONTAIN' || operator === 'NOT_CONTAIN') return `'%${esc}%'`;\n if (operator === 'START_WITH' || operator === 'NOT_START_WITH') return `'${esc}%'`;\n return `'%${esc}'`; // END_WITH / NOT_END_WITH\n}\n\nfunction ruleTokens(filter: any, fields: SdQueryBuilderField[]): QbToken[] {\n const field = fields.find(f => f.key === filter.field);\n const out: QbToken[] = [{ kind: 'field', text: field?.label ?? String(filter.field) }];\n const sp = () => out.push({ kind: 'plain', text: ' ' });\n const operator = filter.operator as Operator;\n\n if (QB_NO_DATA_OPERATORS.includes(operator)) {\n sp();\n out.push({ kind: 'op', text: operator === 'NULL' ? 'is null' : 'is not null' });\n return out;\n }\n\n if (operator === 'BETWEEN') {\n sp();\n out.push({ kind: 'op', text: 'between' });\n sp();\n out.push({ kind: 'value', text: formatScalar(field, filter.data?.from) });\n out.push({ kind: 'plain', text: ' and ' });\n out.push({ kind: 'value', text: formatScalar(field, filter.data?.to) });\n return out;\n }\n\n if (QB_MULTI_OPERATORS.includes(operator)) {\n sp();\n out.push({ kind: 'op', text: operator === 'IN' ? 'in' : 'not in' });\n sp();\n const arr: any[] = Array.isArray(filter.data) ? filter.data : [];\n out.push({ kind: 'value', text: `(${arr.map((v: any) => formatScalar(field, v)).join(', ')})` });\n return out;\n }\n\n if (LIKE_OPERATORS.includes(operator)) {\n sp();\n out.push({ kind: 'op', text: operator.startsWith('NOT_') ? 'not like' : 'like' });\n sp();\n out.push({ kind: 'value', text: likePattern(operator, String(filter.data ?? '')) });\n return out;\n }\n\n sp();\n out.push({ kind: 'op', text: SYMBOL[operator] ?? operator });\n sp();\n out.push({ kind: 'value', text: formatScalar(field, filter.data) });\n return out;\n}\n\nfunction tokensFor(filter: Filter, fields: SdQueryBuilderField[]): QbToken[] {\n if (isAndOr(filter)) {\n const out: QbToken[] = [];\n filter.data.forEach((child, i) => {\n if (i > 0) out.push({ kind: 'logic', text: ` ${filter.operator.toLowerCase()} ` });\n const childTokens = tokensFor(child, fields);\n // Wrap a nested multi-child group in parentheses; a single-child group needs none.\n if (isAndOr(child) && child.data.length > 1) {\n out.push({ kind: 'paren', text: '(' }, ...childTokens, { kind: 'paren', text: ')' });\n } else {\n out.push(...childTokens);\n }\n });\n return out;\n }\n return ruleTokens(filter, fields);\n}\n\n/**\n * Render a `Filter` to a SQL-ish token stream for view mode. Field tokens use the\n * matching field's `label`; operators map to SQL syntax (`= != like between is null …`);\n * `and` / `or` are lowercase; nested multi-child groups are wrapped in parentheses.\n * Returns a token stream (not a string) so the template can wrap each piece in a\n * highlight `<span>` keyed by `QbToken.kind`.\n *\n * @param filter - the `Filter` to render, or `null` / `undefined`.\n * @param fields - field metadata, used to resolve each field key to its display label + value formatting.\n * @returns the ordered tokens, or `[]` when `filter` is empty.\n */\nexport function filterToTokens(filter: Filter | null | undefined, fields: SdQueryBuilderField[]): QbToken[] {\n if (!filter) return [];\n return tokensFor(filter, fields);\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, booleanAttribute, computed, effect, input, model, signal, untracked } from '@angular/core';\nimport { SdDate } from '@sdcorejs/angular/forms/date';\nimport { SdDatetime } from '@sdcorejs/angular/forms/datetime';\nimport { SdInput } from '@sdcorejs/angular/forms/input';\nimport { SdSelect } from '@sdcorejs/angular/forms/select';\nimport { SdOperator } from '@sdcorejs/angular/components/operator';\nimport { Filter, Operator } from '@sdcorejs/utils/models';\nimport {\n isQbGroup,\n QB_DATE_MODES,\n QB_EMPTY_OPTIONS,\n QB_RELATIVE_UNIT_OPTIONS,\n QbDateMode,\n QbGroup,\n QbNode,\n QbRule,\n QbToken,\n qbAllowedOperators,\n qbDefaultOperator,\n qbDefaultRelative,\n qbIsMultiOperator,\n qbIsNoDataOperator,\n qbIsRelativeDate,\n qbNewGroup,\n qbNewRule,\n SdQbRelativeDirection,\n SdQbRelativeUnit,\n SdQueryBuilderField,\n SdQueryBuilderFieldOption,\n} from './query-builder.model';\nimport { filterToTokens, filterToTree, treeToFilter } from './query-builder.serializer';\n\n/** A logical `Filter` (AND / OR group) carries a `data[]` array. */\nfunction isAndOr(filter: any): boolean {\n return !!filter && (filter.operator === 'AND' || filter.operator === 'OR') && Array.isArray(filter.data);\n}\n\n/**\n * Visual filter / rule builder. Compose nested AND / OR groups of\n * `field operator value` conditions; emits the canonical `Filter` (root is a\n * `FilterAndOr` tree) via `[(value)]`, plus a flat `[(filters)]` mirror of the\n * root group's direct children. `mode=\"view\"` renders a read-only SQL-ish raw\n * string with highlighted operators + values.\n */\n@Component({\n selector: 'sd-query-builder',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet, SdOperator, SdSelect, SdInput, SdDate, SdDatetime],\n templateUrl: './query-builder.component.html',\n styleUrls: ['./query-builder.component.scss'],\n})\nexport class SdQueryBuilder {\n // -------------------------------------------------------------------------\n // Inputs\n // -------------------------------------------------------------------------\n\n /** Filterable fields — each declares a `type` that drives the operator set + value editor. */\n readonly fields = input<SdQueryBuilderField[]>([]);\n\n /** `'edit'` (default) = interactive tree · `'view'` = read-only raw-query string. */\n readonly mode = input<'edit' | 'view'>('edit');\n\n /** Disable all editing controls. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /** Prefix for `data-autoid` on inner controls (E2E selectors). */\n readonly autoId = input<string>();\n\n // -------------------------------------------------------------------------\n // Two-way models (output contract)\n // -------------------------------------------------------------------------\n\n /** Canonical output — the root `FilterAndOr` tree, or `null` when empty. `[(value)]`. */\n readonly value = model<Filter | null>(null);\n\n /** Convenience mirror — the root group's direct children. `[(filters)]`. */\n readonly filters = model<Filter[]>([]);\n\n /** Root group's logical connector. `[(rootLogic)]`. */\n readonly rootLogic = model<'AND' | 'OR'>('AND');\n\n // -------------------------------------------------------------------------\n // Internal source of truth — the editable tree (carries UI state).\n // -------------------------------------------------------------------------\n\n readonly #tree = signal<QbGroup>(qbNewGroup('AND'));\n readonly tree = this.#tree.asReadonly();\n\n /** Last filter WE emitted — used to recognise (and ignore) our own echo in the inbound effect. */\n #lastEmitted: Filter | null | undefined = undefined;\n\n // -------------------------------------------------------------------------\n // Derived state\n // -------------------------------------------------------------------------\n\n /** `field.key` → field, for fast lookup from a rule. */\n readonly fieldByKey = computed<Record<string, SdQueryBuilderField>>(() => {\n const map: Record<string, SdQueryBuilderField> = {};\n for (const f of this.fields()) map[f.key] = f;\n return map;\n });\n\n /** Boolean fields → their stable `[true,false]` option list. Memoized so the template\n * binding hands `sd-select` the SAME array ref each CD (else its `toObservable(items)`\n * → `markForCheck()` loops → OOM). Recomputes only when `fields()` changes. */\n readonly #booleanOptionsByKey = computed<Map<string, SdQueryBuilderFieldOption[]>>(() => {\n const map = new Map<string, SdQueryBuilderFieldOption[]>();\n for (const f of this.fields()) {\n if (f.type === 'boolean') {\n map.set(f.key, [\n { value: true, display: f.trueLabel ?? 'Có' },\n { value: false, display: f.falseLabel ?? 'Không' },\n ]);\n }\n }\n return map;\n });\n\n /** Stable option list for the date-mode select. */\n readonly dateModes = QB_DATE_MODES;\n /** Stable combined unit×direction option list for the relative select. */\n readonly relativeUnitOptions = QB_RELATIVE_UNIT_OPTIONS;\n\n /** View-mode token stream — recomputed from the emitted value. */\n readonly tokens = computed<QbToken[]>(() => filterToTokens(this.value(), this.fields()));\n\n readonly isView = computed(() => this.mode() === 'view');\n\n /** Expose the type-guard to the template. */\n readonly isGroup = isQbGroup;\n\n constructor() {\n // Inbound seeding: an EXTERNAL write to value / filters rebuilds the tree.\n // Our own emits are recognised via #lastEmitted and skipped (no echo loop).\n effect(() => {\n const v = this.value();\n const fl = this.filters();\n const incoming = this.#coalesce(v, fl);\n if (this.#filterEq(incoming, this.#lastEmitted)) return;\n this.#tree.set(filterToTree(incoming));\n this.#commit();\n });\n }\n\n #coalesce(v: Filter | null, fl: Filter[]): Filter | null {\n if (v) return v;\n if (fl && fl.length) return { operator: untracked(() => this.rootLogic()), data: fl } as Filter;\n return null;\n }\n\n #filterEq(a: Filter | null | undefined, b: Filter | null | undefined): boolean {\n return JSON.stringify(a ?? null) === JSON.stringify(b ?? null);\n }\n\n // -------------------------------------------------------------------------\n // Tree mutation → emit\n // -------------------------------------------------------------------------\n\n /** New root ref so the template (which reads `tree()`) re-renders. */\n #bumpTree(): void {\n this.#tree.set({ ...this.#tree() });\n }\n\n /** Recompute the output `Filter` from the tree and push it to value / filters / rootLogic. */\n #commit(): void {\n const filter = treeToFilter(this.#tree());\n this.#lastEmitted = filter;\n this.value.set(filter);\n this.filters.set(isAndOr(filter) ? (filter as any).data : filter ? [filter] : []);\n const logic = this.#tree().logic;\n if (this.rootLogic() !== logic) this.rootLogic.set(logic);\n }\n\n /** Mutate-in-place + re-render + emit. */\n #apply(): void {\n this.#bumpTree();\n this.#commit();\n }\n\n // -------------------------------------------------------------------------\n // Group / rule structural mutations\n // -------------------------------------------------------------------------\n\n /** Switch a group's AND/OR connector and re-emit. No-op when disabled or unchanged. */\n setGroupLogic(group: QbGroup, logic: 'AND' | 'OR'): void {\n if (this.disabled() || group.logic === logic) return;\n group.logic = logic;\n this.#apply();\n }\n\n /** Open this group's \"+\" menu (closing any other open one). UI-only — does not emit. */\n toggleDropdown(group: QbGroup, event: Event): void {\n if (this.disabled()) return;\n event.stopPropagation();\n const willOpen = !group.open;\n this.#closeAllDropdowns(this.#tree());\n group.open = willOpen;\n this.#bumpTree(); // UI-only — no emit\n }\n\n closeAllDropdowns(): void {\n if (!this.#hasOpenDropdown(this.#tree())) return; // avoid a re-render on every container click\n this.#closeAllDropdowns(this.#tree());\n this.#bumpTree();\n }\n\n #hasOpenDropdown(node: QbNode): boolean {\n if (!isQbGroup(node)) return false;\n return node.open === true || node.children.some(c => this.#hasOpenDropdown(c));\n }\n\n #closeAllDropdowns(node: QbNode): void {\n if (isQbGroup(node)) {\n node.open = false;\n node.children.forEach(c => this.#closeAllDropdowns(c));\n }\n }\n\n /** Append a blank rule to `group`. */\n addRule(group: QbGroup): void {\n if (this.disabled()) return;\n group.children.push(qbNewRule());\n group.open = false;\n this.#apply();\n }\n\n /** Append a nested sub-group (seeded with one blank rule) to `group`. */\n addGroup(group: QbGroup): void {\n if (this.disabled()) return;\n group.children.push(qbNewGroup('AND', [qbNewRule()]));\n group.open = false;\n this.#apply();\n }\n\n /** Remove the child at `index` from `parent` (a rule or a whole sub-group). */\n removeNode(parent: QbGroup, index: number): void {\n if (this.disabled()) return;\n parent.children.splice(index, 1);\n this.#apply();\n }\n\n // -------------------------------------------------------------------------\n // Rule field / operator / value mutations\n // -------------------------------------------------------------------------\n\n /**\n * Point `rule` at a new field. Resets operator to the field's default and the value\n * to that operator's empty shape — the old operator/value rarely fit the new type.\n *\n * @param rule - the rule being edited.\n * @param key - the chosen field key (from the field picker). Swap-only: a null / undefined\n * key is a no-op — the field can be changed but never cleared (issue #2).\n */\n setField(rule: QbRule, key: any): void {\n if (this.disabled()) return;\n if (key == null) return; // swap-only: never clear the field (issue #2)\n rule.field = key;\n const field = this.fieldByKey()[rule.field as string];\n const op = qbDefaultOperator(field);\n rule.operator = op;\n rule.value = this.#defaultValueFor(op);\n this.#apply();\n }\n\n /** Change `rule`'s operator and reshape its value to fit the new operator (array / range / none). */\n setOperator(rule: QbRule, op: Operator | undefined): void {\n if (this.disabled()) return;\n rule.operator = op;\n rule.value = this.#reshapeValue(op, rule.value);\n this.#apply();\n }\n\n /** Set a single-value rule's value (coercing numeric fields to `number`). */\n setScalar(rule: QbRule, raw: any): void {\n if (this.disabled()) return;\n rule.value = this.#coerce(rule, raw);\n this.#apply();\n }\n\n /** Set the lower bound of a BETWEEN rule's `{ from, to }` value. */\n setBetweenFrom(rule: QbRule, raw: any): void {\n if (this.disabled()) return;\n rule.value = { ...(rule.value ?? {}), from: this.#coerce(rule, raw) };\n this.#apply();\n }\n\n /** Set the upper bound of a BETWEEN rule's `{ from, to }` value. */\n setBetweenTo(rule: QbRule, raw: any): void {\n if (this.disabled()) return;\n rule.value = { ...(rule.value ?? {}), to: this.#coerce(rule, raw) };\n this.#apply();\n }\n\n /** Coerce numeric fields to `number` so the emitted Filter carries a real number. */\n #coerce(rule: QbRule, raw: any): any {\n const field = this.fieldByKey()[rule.field as string];\n if (field?.type === 'number' && raw !== null && raw !== undefined && raw !== '') {\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n return raw;\n }\n\n #defaultValueFor(op: Operator | undefined): any {\n if (qbIsMultiOperator(op)) return [];\n if (op === 'BETWEEN') return { from: null, to: null };\n return null;\n }\n\n #reshapeValue(op: Operator | undefined, current: any): any {\n if (qbIsNoDataOperator(op)) return null;\n if (qbIsMultiOperator(op)) return Array.isArray(current) ? current : current == null ? [] : [current];\n if (op === 'BETWEEN') {\n // a relative spec can't be a BETWEEN endpoint — reset to a fresh range\n return current && typeof current === 'object' && !Array.isArray(current) && !qbIsRelativeDate(current)\n ? current\n : { from: null, to: null };\n }\n // single value — keep a relative spec; otherwise drop array/range remnants\n if (qbIsRelativeDate(current)) return current;\n return Array.isArray(current) || (current && typeof current === 'object') ? null : current;\n }\n\n // -------------------------------------------------------------------------\n // Template helpers\n // -------------------------------------------------------------------------\n\n /** The field metadata for a rule's current `field` key (or undefined if unset). */\n fieldOf(rule: QbRule): SdQueryBuilderField | undefined {\n return rule.field ? this.fieldByKey()[rule.field] : undefined;\n }\n\n /** Operators allowed for a rule, derived from its field's type / override. */\n allowedOperators(rule: QbRule): Operator[] {\n return qbAllowedOperators(this.fieldOf(rule));\n }\n\n /** Whether to render the operator picker — hidden when only one operator is allowed. */\n showOperatorSelector(rule: QbRule): boolean {\n return this.allowedOperators(rule).length > 1;\n }\n\n /** True for NULL / NOT_NULL — the template then renders no value editor. */\n isNoData(op: Operator | undefined): boolean {\n return qbIsNoDataOperator(op);\n }\n\n /** True for IN / NOT_IN — the template then renders a multi-select value editor. */\n isMulti(op: Operator | undefined): boolean {\n return qbIsMultiOperator(op);\n }\n\n /** `[true/false]` option list for a boolean field's value select (stable reference). */\n booleanItems(field: SdQueryBuilderField): SdQueryBuilderFieldOption[] {\n return this.#booleanOptionsByKey().get(field.key) ?? QB_EMPTY_OPTIONS;\n }\n\n /** Current date-value mode of a rule, derived from its value (no separate state). */\n dateMode(rule: QbRule): QbDateMode {\n const v = rule.value;\n if (qbIsRelativeDate(v)) return v.rel === 'now' ? 'now' : 'relative';\n return 'absolute';\n }\n\n /** Switch a date/datetime rule's value mode, reseeding the value for the new mode. */\n setDateMode(rule: QbRule, mode: QbDateMode): void {\n if (this.disabled()) return;\n if (mode === 'now') rule.value = { rel: 'now' };\n else if (mode === 'relative') rule.value = qbDefaultRelative();\n else rule.value = null; // absolute — pick a concrete date\n this.#apply();\n }\n\n /** Read the offset amount of a relative rule (default 1). */\n relativeAmount(rule: QbRule): number {\n const v = rule.value;\n return qbIsRelativeDate(v) && v.rel === 'offset' ? v.amount ?? 1 : 1;\n }\n\n /** Set the offset amount (clamped to an integer >= 1). */\n setRelativeAmount(rule: QbRule, raw: any): void {\n if (this.disabled()) return;\n const n = Math.floor(Number(raw));\n const amount = Number.isNaN(n) || n < 1 ? 1 : n;\n const cur = qbIsRelativeDate(rule.value) ? rule.value : qbDefaultRelative();\n rule.value = { rel: 'offset', unit: cur.unit ?? 'day', amount, direction: cur.direction ?? 'previous' };\n this.#apply();\n }\n\n /** Read the `'unit:direction'` token of a relative rule (default `'day:previous'`). */\n relativeUnitDirValue(rule: QbRule): string {\n const v = rule.value;\n if (qbIsRelativeDate(v) && v.rel === 'offset') return `${v.unit ?? 'day'}:${v.direction ?? 'previous'}`;\n return 'day:previous';\n }\n\n /** Set the offset unit + direction from a `'unit:direction'` token. */\n setRelativeUnitDir(rule: QbRule, token: string): void {\n if (this.disabled()) return;\n const [unit, direction] = (token ?? 'day:previous').split(':') as [SdQbRelativeUnit, SdQbRelativeDirection];\n const cur = qbIsRelativeDate(rule.value) ? rule.value : qbDefaultRelative();\n rule.value = { rel: 'offset', unit, amount: cur.amount ?? 1, direction };\n this.#apply();\n }\n\n /** Build a `data-autoid` for an inner control under this builder's `autoId` prefix. */\n autoIdFor(suffix: string): string {\n return `${this.autoId() ?? 'qb'}-${suffix}`;\n }\n}\n","@if (isView()) {\n <div class=\"qb-view\" [attr.data-autoid]=\"autoIdFor('view')\" aria-readonly=\"true\">\n @if (tokens().length) {\n @for (t of tokens(); track $index) {\n <span class=\"qb-tok qb-tok-{{ t.kind }}\">{{ t.text }}</span>\n }\n } @else {\n <span class=\"qb-view-empty\">—</span>\n }\n </div>\n} @else {\n <div class=\"qb-container\" [class.is-disabled]=\"disabled()\" (click)=\"closeAllDropdowns()\">\n <ng-container [ngTemplateOutlet]=\"groupTpl\" [ngTemplateOutletContext]=\"{ $implicit: tree(), isRoot: true }\"></ng-container>\n </div>\n}\n\n<!-- Recursive group node -->\n<ng-template #groupTpl let-group let-isRoot=\"isRoot\" let-parent=\"parent\" let-index=\"index\">\n <div class=\"qb-group\" [class.is-root]=\"isRoot\">\n <div class=\"qb-header\" [class.is-open]=\"group.open\">\n <div class=\"qb-logic-switch\">\n <button type=\"button\" [class.active]=\"group.logic === 'AND'\" [disabled]=\"disabled()\" (click)=\"setGroupLogic(group, 'AND')\">AND</button>\n <button type=\"button\" [class.active]=\"group.logic === 'OR'\" [disabled]=\"disabled()\" (click)=\"setGroupLogic(group, 'OR')\">OR</button>\n </div>\n\n <div class=\"qb-actions\">\n <button type=\"button\" class=\"qb-btn qb-btn-add\" title=\"Thêm\" aria-label=\"Thêm điều kiện hoặc nhóm\" [disabled]=\"disabled()\" (click)=\"toggleDropdown(group, $event)\">+</button>\n @if (group.open) {\n <div class=\"qb-dropdown\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" (click)=\"addRule(group)\">+ Điều kiện</button>\n <button type=\"button\" (click)=\"addGroup(group)\">+ Nhóm</button>\n </div>\n }\n @if (!isRoot) {\n <button type=\"button\" class=\"qb-btn qb-btn-remove\" title=\"Xoá nhóm\" aria-label=\"Xoá nhóm\" [disabled]=\"disabled()\" (click)=\"removeNode(parent, index)\">✕</button>\n }\n </div>\n </div>\n\n <div class=\"qb-body\">\n @for (node of group.children; track node.id; let i = $index) {\n <div class=\"qb-treenode\" [class.is-group]=\"isGroup(node)\" [class.is-rule]=\"!isGroup(node)\">\n @if (isGroup(node)) {\n <ng-container\n [ngTemplateOutlet]=\"groupTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: node, isRoot: false, parent: group, index: i }\"\n ></ng-container>\n } @else {\n <ng-container [ngTemplateOutlet]=\"ruleTpl\" [ngTemplateOutletContext]=\"{ $implicit: node, parent: group, index: i }\"></ng-container>\n }\n </div>\n } @empty {\n <div class=\"qb-empty\">Chưa có điều kiện</div>\n }\n </div>\n </div>\n</ng-template>\n\n<!-- Single rule node: field → operator → value -->\n<ng-template #ruleTpl let-rule let-parent=\"parent\" let-index=\"index\">\n <div class=\"qb-rule\">\n <sd-select\n class=\"qb-field\"\n [items]=\"fields()\"\n valueField=\"key\"\n displayField=\"label\"\n placeholder=\"Chọn trường\"\n size=\"sm\"\n [model]=\"rule.field\"\n (modelChange)=\"setField(rule, $event)\"\n [disabled]=\"disabled()\"\n [clearable]=\"false\"\n hideInlineError\n [autoId]=\"autoIdFor('field-' + index)\"\n ></sd-select>\n\n @if (rule.field) {\n <div class=\"qb-divider\"></div>\n\n @if (showOperatorSelector(rule)) {\n <sd-operator\n class=\"qb-op\"\n [operators]=\"allowedOperators(rule)\"\n [model]=\"rule.operator\"\n (modelChange)=\"setOperator(rule, $event)\"\n [disabled]=\"disabled()\"\n [autoId]=\"autoIdFor('op-' + index)\"\n ></sd-operator>\n }\n\n @if (rule.operator && !isNoData(rule.operator)) {\n <div class=\"qb-divider\"></div>\n\n @if (rule.operator === 'BETWEEN') {\n <div class=\"qb-between\">\n @switch (fieldOf(rule)?.type) {\n @case ('number') {\n <sd-input class=\"qb-val\" type=\"number\" placeholder=\"Từ\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-input>\n <span class=\"qb-dash\">—</span>\n <sd-input class=\"qb-val\" type=\"number\" placeholder=\"Đến\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-input>\n }\n @case ('date') {\n <sd-date class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-date>\n <span class=\"qb-dash\">—</span>\n <sd-date class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-date>\n }\n @case ('datetime') {\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.from\" (modelChange)=\"setBetweenFrom(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('from-' + index)\"></sd-datetime>\n <span class=\"qb-dash\">—</span>\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value?.to\" (modelChange)=\"setBetweenTo(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('to-' + index)\"></sd-datetime>\n }\n }\n </div>\n } @else {\n @switch (fieldOf(rule)?.type) {\n @case ('string') {\n <sd-input class=\"qb-val\" placeholder=\"Giá trị\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input>\n }\n @case ('number') {\n <sd-input class=\"qb-val\" type=\"number\" placeholder=\"Giá trị\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-input>\n }\n @case ('boolean') {\n <sd-select class=\"qb-val\" [items]=\"booleanItems(fieldOf(rule)!)\" valueField=\"value\" displayField=\"display\" placeholder=\"Giá trị\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"disabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\n }\n @case ('date') {\n @let _dateMode = dateMode(rule);\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dateMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"disabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\"></sd-select>\n @switch (_dateMode) {\n @case ('absolute') {\n <sd-date class=\"qb-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-date>\n }\n @case ('relative') {\n <sd-input class=\"qb-rel-amount\" type=\"number\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input>\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"disabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\n }\n }\n }\n @case ('datetime') {\n @let _dtMode = dateMode(rule);\n <sd-select class=\"qb-date-mode\" [items]=\"dateModes\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"_dtMode\" (modelChange)=\"setDateMode(rule, $event)\" [disabled]=\"disabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('datemode-' + index)\"></sd-select>\n @switch (_dtMode) {\n @case ('absolute') {\n <sd-datetime class=\"qb-val\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-datetime>\n }\n @case ('relative') {\n <sd-input class=\"qb-rel-amount\" type=\"number\" size=\"sm\" [model]=\"relativeAmount(rule)\" (modelChange)=\"setRelativeAmount(rule, $event)\" [disabled]=\"disabled()\" hideInlineError [autoId]=\"autoIdFor('rel-amount-' + index)\"></sd-input>\n <sd-select class=\"qb-rel-unit\" [items]=\"relativeUnitOptions\" valueField=\"value\" displayField=\"display\" size=\"sm\" [model]=\"relativeUnitDirValue(rule)\" (modelChange)=\"setRelativeUnitDir(rule, $event)\" [disabled]=\"disabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('rel-unit-' + index)\"></sd-select>\n }\n }\n }\n @case ('values') {\n <sd-select class=\"qb-val\" [items]=\"fieldOf(rule)!.values || []\" valueField=\"value\" displayField=\"display\" [multiple]=\"isMulti(rule.operator)\" placeholder=\"Giá trị\" size=\"sm\" [model]=\"rule.value\" (modelChange)=\"setScalar(rule, $event)\" [disabled]=\"disabled()\" [clearable]=\"false\" hideInlineError [autoId]=\"autoIdFor('val-' + index)\"></sd-select>\n }\n }\n }\n }\n }\n\n <button type=\"button\" class=\"qb-btn qb-btn-remove-rule\" title=\"Xoá điều kiện\" aria-label=\"Xoá điều kiện\" [disabled]=\"disabled()\" (click)=\"removeNode(parent, index)\">✕</button>\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["isAndOr"],"mappings":"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"}
@@ -2,10 +2,9 @@ import * as i0 from '@angular/core';
2
2
  import { inject, ElementRef, input, model, booleanAttribute, effect, Component } from '@angular/core';
3
3
  import * as i1 from '@angular/material/icon';
4
4
  import { MatIconModule } from '@angular/material/icon';
5
- import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
6
5
 
7
6
  /* eslint-disable @angular-eslint/no-input-rename */
8
- class SdSection extends SdBaseSecureComponent {
7
+ class SdSection {
9
8
  #el = inject(ElementRef);
10
9
  title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : []));
11
10
  subTitle = input(undefined, ...(ngDevMode ? [{ debugName: "subTitle" }] : []));
@@ -16,7 +15,6 @@ class SdSection extends SdBaseSecureComponent {
16
15
  hideHeader = input(false, ...(ngDevMode ? [{ debugName: "hideHeader", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
17
16
  noPaddingBody = input(false, ...(ngDevMode ? [{ debugName: "noPaddingBody", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
18
17
  constructor() {
19
- super();
20
18
  effect(() => {
21
19
  if (this.title()) {
22
20
  this.#el.nativeElement.removeAttribute('title');
@@ -34,7 +32,7 @@ class SdSection extends SdBaseSecureComponent {
34
32
  }
35
33
  };
36
34
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSection, deps: [], target: i0.ɵɵFactoryTarget.Component });
37
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdSection, isStandalone: true, selector: "sd-section", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subTitle: { classPropertyName: "subTitle", publicName: "subTitle", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconColor: { classPropertyName: "iconColor", publicName: "iconColor", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, collapsable: { classPropertyName: "collapsable", publicName: "collapsable", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null }, noPaddingBody: { classPropertyName: "noPaddingBody", publicName: "noPaddingBody", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange" }, usesInheritance: true, ngImport: i0, template: "@let _hideHeader = hideHeader();\n@let _collapsable = collapsable();\n@let _collapsed = collapsed();\n@let _title = title();\n@let _subTitle = subTitle();\n@let _iconColor = iconColor();\n<div class=\"rounded-8 bg-white\" [class.c-shadow-section]=\"!_collapsed\">\n @if (!_hideHeader) {\n <div\n class=\"d-flex align-items-center justify-content-between w-full px-16 py-8 cursor-pointer\"\n (click)=\"toggleCollapse()\"\n aria-hidden=\"true\">\n <div class=\"d-flex align-items-center\">\n <ng-content select=\"[sdHeaderLeft]\">\n @if (icon()) {\n <span\n class=\"mr-8 material-icons-outlined\"\n [class.text-primary]=\"_iconColor === 'primary'\"\n [class.text-secondary]=\"_iconColor === 'secondary'\"\n [class.text-error]=\"_iconColor === 'error'\"\n [class.text-warning]=\"_iconColor === 'warning'\"\n [class.text-success]=\"_iconColor === 'success'\">\n {{ icon() }}\n </span>\n }\n <div>\n @if (_title) {\n <div class=\"T16M\">{{ _title }}</div>\n }\n @if (_subTitle) {\n <div class=\"T12R text-secondary\">{{ _subTitle }}</div>\n }\n </div>\n </ng-content>\n </div>\n <div class=\"d-flex\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (_collapsable) {\n <div class=\"d-flex align-items-center\">\n @if (_collapsed) {\n <mat-icon>expand_more</mat-icon>\n } @else {\n <mat-icon>expand_less</mat-icon>\n }\n </div>\n }\n </div>\n </div>\n }\n @if (!_collapsed || _hideHeader) {\n <!-- N\u1EBFu header b\u1ECB \u1EA9n th\u00EC kh\u00F4ng c\u1EA7n border top -->\n <div [class.p-16]=\"!noPaddingBody()\" [class.c-no-padding-body]=\"noPaddingBody()\" [style.border-top]=\"_hideHeader ? 'none' : '1px solid #e6e6e6'\">\n <ng-content></ng-content>\n </div>\n }\n</div>\n", styles: [":host{width:100%;display:block}.c-no-padding-body{padding:0!important}.c-shadow-section{box-shadow:-1px 0 #f2f2f2 inset,1px 0 #f2f2f2 inset,0 1px #f2f2f2 inset,0 -1px #f2f2f2 inset,0 1px 2px #2f31361a}.cursor-pointer{cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
35
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdSection, isStandalone: true, selector: "sd-section", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subTitle: { classPropertyName: "subTitle", publicName: "subTitle", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconColor: { classPropertyName: "iconColor", publicName: "iconColor", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, collapsable: { classPropertyName: "collapsable", publicName: "collapsable", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null }, noPaddingBody: { classPropertyName: "noPaddingBody", publicName: "noPaddingBody", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange" }, ngImport: i0, template: "@let _hideHeader = hideHeader();\n@let _collapsable = collapsable();\n@let _collapsed = collapsed();\n@let _title = title();\n@let _subTitle = subTitle();\n@let _iconColor = iconColor();\n<div class=\"rounded-8 bg-white\" [class.c-shadow-section]=\"!_collapsed\">\n @if (!_hideHeader) {\n <div\n class=\"d-flex align-items-center justify-content-between w-full px-16 py-8 cursor-pointer\"\n (click)=\"toggleCollapse()\"\n aria-hidden=\"true\">\n <div class=\"d-flex align-items-center\">\n <ng-content select=\"[sdHeaderLeft]\">\n @if (icon()) {\n <span\n class=\"mr-8 material-icons-outlined\"\n [class.text-primary]=\"_iconColor === 'primary'\"\n [class.text-secondary]=\"_iconColor === 'secondary'\"\n [class.text-error]=\"_iconColor === 'error'\"\n [class.text-warning]=\"_iconColor === 'warning'\"\n [class.text-success]=\"_iconColor === 'success'\">\n {{ icon() }}\n </span>\n }\n <div>\n @if (_title) {\n <div class=\"T16M\">{{ _title }}</div>\n }\n @if (_subTitle) {\n <div class=\"T12R text-secondary\">{{ _subTitle }}</div>\n }\n </div>\n </ng-content>\n </div>\n <div class=\"d-flex\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (_collapsable) {\n <div class=\"d-flex align-items-center\">\n @if (_collapsed) {\n <mat-icon>expand_more</mat-icon>\n } @else {\n <mat-icon>expand_less</mat-icon>\n }\n </div>\n }\n </div>\n </div>\n }\n @if (!_collapsed || _hideHeader) {\n <!-- N\u1EBFu header b\u1ECB \u1EA9n th\u00EC kh\u00F4ng c\u1EA7n border top -->\n <div [class.p-16]=\"!noPaddingBody()\" [class.c-no-padding-body]=\"noPaddingBody()\" [style.border-top]=\"_hideHeader ? 'none' : '1px solid #e6e6e6'\">\n <ng-content></ng-content>\n </div>\n }\n</div>\n", styles: [":host{width:100%;display:block}.c-no-padding-body{padding:0!important}.c-shadow-section{box-shadow:-1px 0 #f2f2f2 inset,1px 0 #f2f2f2 inset,0 1px #f2f2f2 inset,0 -1px #f2f2f2 inset,0 1px 2px #2f31361a}.cursor-pointer{cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
38
36
  }
39
37
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSection, decorators: [{
40
38
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"sdcorejs-angular-components-section.mjs","sources":["../../../projects/sdcorejs-angular/components/section/src/section.component.ts","../../../projects/sdcorejs-angular/components/section/src/section.component.html","../../../projects/sdcorejs-angular/components/section/src/section-item/section-item.component.ts","../../../projects/sdcorejs-angular/components/section/src/section-item/section-item.component.html","../../../projects/sdcorejs-angular/components/section/sdcorejs-angular-components-section.ts"],"sourcesContent":["/* eslint-disable @angular-eslint/no-input-rename */\nimport { booleanAttribute, Component, effect, ElementRef, inject, input, model } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';\nimport { Color } from '@sdcorejs/utils/models';\n\n@Component({\n selector: 'sd-section',\n templateUrl: './section.component.html',\n styleUrls: ['./section.component.scss'],\n imports: [MatIconModule],\n})\nexport class SdSection extends SdBaseSecureComponent {\n #el = inject(ElementRef);\n\n title = input<string | undefined | null>(undefined);\n subTitle = input<string | undefined | null>(undefined);\n icon = input<string | undefined | null>(undefined);\n iconColor = input<Color>('primary', { alias: 'iconColor' });\n\n collapsed = model<boolean>(false, { alias: 'collapsed' });\n collapsable = input(false, { transform: booleanAttribute });\n hideHeader = input(false, { transform: booleanAttribute });\n noPaddingBody = input(false, { transform: booleanAttribute });\n\n constructor() {\n super();\n effect(() => {\n if (this.title()) {\n this.#el.nativeElement.removeAttribute('title');\n }\n });\n }\n\n toggleCollapse = () => {\n if (this.collapsable()) {\n this.collapsed.set(!this.collapsed());\n } else {\n if (this.collapsed()) {\n this.collapsed.set(false);\n }\n }\n };\n}\n","@let _hideHeader = hideHeader();\n@let _collapsable = collapsable();\n@let _collapsed = collapsed();\n@let _title = title();\n@let _subTitle = subTitle();\n@let _iconColor = iconColor();\n<div class=\"rounded-8 bg-white\" [class.c-shadow-section]=\"!_collapsed\">\n @if (!_hideHeader) {\n <div\n class=\"d-flex align-items-center justify-content-between w-full px-16 py-8 cursor-pointer\"\n (click)=\"toggleCollapse()\"\n aria-hidden=\"true\">\n <div class=\"d-flex align-items-center\">\n <ng-content select=\"[sdHeaderLeft]\">\n @if (icon()) {\n <span\n class=\"mr-8 material-icons-outlined\"\n [class.text-primary]=\"_iconColor === 'primary'\"\n [class.text-secondary]=\"_iconColor === 'secondary'\"\n [class.text-error]=\"_iconColor === 'error'\"\n [class.text-warning]=\"_iconColor === 'warning'\"\n [class.text-success]=\"_iconColor === 'success'\">\n {{ icon() }}\n </span>\n }\n <div>\n @if (_title) {\n <div class=\"T16M\">{{ _title }}</div>\n }\n @if (_subTitle) {\n <div class=\"T12R text-secondary\">{{ _subTitle }}</div>\n }\n </div>\n </ng-content>\n </div>\n <div class=\"d-flex\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (_collapsable) {\n <div class=\"d-flex align-items-center\">\n @if (_collapsed) {\n <mat-icon>expand_more</mat-icon>\n } @else {\n <mat-icon>expand_less</mat-icon>\n }\n </div>\n }\n </div>\n </div>\n }\n @if (!_collapsed || _hideHeader) {\n <!-- Nếu header bị ẩn thì không cần border top -->\n <div [class.p-16]=\"!noPaddingBody()\" [class.c-no-padding-body]=\"noPaddingBody()\" [style.border-top]=\"_hideHeader ? 'none' : '1px solid #e6e6e6'\">\n <ng-content></ng-content>\n </div>\n }\n</div>\n","import { Component, input } from '@angular/core';\n\n@Component({\n selector: 'sd-section-item',\n templateUrl: './section-item.component.html',\n styleUrls: ['section-item.component.scss'],\n standalone: true,\n})\nexport class SdSectionItem {\n label = input.required<string>();\n labelWidth = input<string, string | null | undefined>('150px', {\n transform: (val: any): string => {\n return val || '150px';\n },\n });\n}\n","<div class=\"c-item\">\n <div class=\"T14R text-black400\" [style.width]=\"labelWidth()\">{{ label() }}</div>\n <div style=\"flex: 1;\"><ng-content></ng-content></div>\n</div>","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdcorejs-angular-components-section.mjs","sources":["../../../projects/sdcorejs-angular/components/section/src/section.component.ts","../../../projects/sdcorejs-angular/components/section/src/section.component.html","../../../projects/sdcorejs-angular/components/section/src/section-item/section-item.component.ts","../../../projects/sdcorejs-angular/components/section/src/section-item/section-item.component.html","../../../projects/sdcorejs-angular/components/section/sdcorejs-angular-components-section.ts"],"sourcesContent":["/* eslint-disable @angular-eslint/no-input-rename */\nimport { booleanAttribute, Component, effect, ElementRef, inject, input, model } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { Color } from '@sdcorejs/utils/models';\n\n@Component({\n selector: 'sd-section',\n templateUrl: './section.component.html',\n styleUrls: ['./section.component.scss'],\n imports: [MatIconModule],\n})\nexport class SdSection {\n #el = inject(ElementRef);\n\n title = input<string | undefined | null>(undefined);\n subTitle = input<string | undefined | null>(undefined);\n icon = input<string | undefined | null>(undefined);\n iconColor = input<Color>('primary', { alias: 'iconColor' });\n\n collapsed = model<boolean>(false, { alias: 'collapsed' });\n collapsable = input(false, { transform: booleanAttribute });\n hideHeader = input(false, { transform: booleanAttribute });\n noPaddingBody = input(false, { transform: booleanAttribute });\n\n constructor() {\n effect(() => {\n if (this.title()) {\n this.#el.nativeElement.removeAttribute('title');\n }\n });\n }\n\n toggleCollapse = () => {\n if (this.collapsable()) {\n this.collapsed.set(!this.collapsed());\n } else {\n if (this.collapsed()) {\n this.collapsed.set(false);\n }\n }\n };\n}\n","@let _hideHeader = hideHeader();\n@let _collapsable = collapsable();\n@let _collapsed = collapsed();\n@let _title = title();\n@let _subTitle = subTitle();\n@let _iconColor = iconColor();\n<div class=\"rounded-8 bg-white\" [class.c-shadow-section]=\"!_collapsed\">\n @if (!_hideHeader) {\n <div\n class=\"d-flex align-items-center justify-content-between w-full px-16 py-8 cursor-pointer\"\n (click)=\"toggleCollapse()\"\n aria-hidden=\"true\">\n <div class=\"d-flex align-items-center\">\n <ng-content select=\"[sdHeaderLeft]\">\n @if (icon()) {\n <span\n class=\"mr-8 material-icons-outlined\"\n [class.text-primary]=\"_iconColor === 'primary'\"\n [class.text-secondary]=\"_iconColor === 'secondary'\"\n [class.text-error]=\"_iconColor === 'error'\"\n [class.text-warning]=\"_iconColor === 'warning'\"\n [class.text-success]=\"_iconColor === 'success'\">\n {{ icon() }}\n </span>\n }\n <div>\n @if (_title) {\n <div class=\"T16M\">{{ _title }}</div>\n }\n @if (_subTitle) {\n <div class=\"T12R text-secondary\">{{ _subTitle }}</div>\n }\n </div>\n </ng-content>\n </div>\n <div class=\"d-flex\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (_collapsable) {\n <div class=\"d-flex align-items-center\">\n @if (_collapsed) {\n <mat-icon>expand_more</mat-icon>\n } @else {\n <mat-icon>expand_less</mat-icon>\n }\n </div>\n }\n </div>\n </div>\n }\n @if (!_collapsed || _hideHeader) {\n <!-- Nếu header bị ẩn thì không cần border top -->\n <div [class.p-16]=\"!noPaddingBody()\" [class.c-no-padding-body]=\"noPaddingBody()\" [style.border-top]=\"_hideHeader ? 'none' : '1px solid #e6e6e6'\">\n <ng-content></ng-content>\n </div>\n }\n</div>\n","import { Component, input } from '@angular/core';\n\n@Component({\n selector: 'sd-section-item',\n templateUrl: './section-item.component.html',\n styleUrls: ['section-item.component.scss'],\n standalone: true,\n})\nexport class SdSectionItem {\n label = input.required<string>();\n labelWidth = input<string, string | null | undefined>('150px', {\n transform: (val: any): string => {\n return val || '150px';\n },\n });\n}\n","<div class=\"c-item\">\n <div class=\"T14R text-black400\" [style.width]=\"labelWidth()\">{{ label() }}</div>\n <div style=\"flex: 1;\"><ng-content></ng-content></div>\n</div>","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAAA;MAWa,SAAS,CAAA;AACpB,IAAA,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;AAExB,IAAA,KAAK,GAAG,KAAK,CAA4B,SAAS,iDAAC;AACnD,IAAA,QAAQ,GAAG,KAAK,CAA4B,SAAS,oDAAC;AACtD,IAAA,IAAI,GAAG,KAAK,CAA4B,SAAS,gDAAC;AAClD,IAAA,SAAS,GAAG,KAAK,CAAQ,SAAS,6CAAI,KAAK,EAAE,WAAW,EAAA,CAAA,GAAA,CAApB,EAAE,KAAK,EAAE,WAAW,EAAE,GAAC;AAE3D,IAAA,SAAS,GAAG,KAAK,CAAU,KAAK,6CAAI,KAAK,EAAE,WAAW,EAAA,CAAA,GAAA,CAApB,EAAE,KAAK,EAAE,WAAW,EAAE,GAAC;AACzD,IAAA,WAAW,GAAG,KAAK,CAAC,KAAK,+CAAI,SAAS,EAAE,gBAAgB,EAAA,CAAA,GAAA,CAA7B,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAC;AAC3D,IAAA,UAAU,GAAG,KAAK,CAAC,KAAK,8CAAI,SAAS,EAAE,gBAAgB,EAAA,CAAA,GAAA,CAA7B,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAC;AAC1D,IAAA,aAAa,GAAG,KAAK,CAAC,KAAK,iDAAI,SAAS,EAAE,gBAAgB,EAAA,CAAA,GAAA,CAA7B,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAC;AAE7D,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE;gBAChB,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,eAAe,CAAC,OAAO,CAAC;YACjD;AACF,QAAA,CAAC,CAAC;IACJ;IAEA,cAAc,GAAG,MAAK;AACpB,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;YACtB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACvC;aAAO;AACL,YAAA,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;AACpB,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YAC3B;QACF;AACF,IAAA,CAAC;wGA7BU,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAT,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EAAA,iBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECXtB,6hEAwDA,EAAA,MAAA,EAAA,CAAA,4OAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED/CY,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;4FAEZ,SAAS,EAAA,UAAA,EAAA,CAAA;kBANrB,SAAS;+BACE,YAAY,EAAA,OAAA,EAGb,CAAC,aAAa,CAAC,EAAA,QAAA,EAAA,6hEAAA,EAAA,MAAA,EAAA,CAAA,4OAAA,CAAA,EAAA;;;MEDb,aAAa,CAAA;AACxB,IAAA,KAAK,GAAG,KAAK,CAAC,QAAQ,gDAAU;IAChC,UAAU,GAAG,KAAK,CAAoC,OAAO,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,YAAA,EAC3D,SAAS,EAAE,CAAC,GAAQ,KAAY;gBAC9B,OAAO,GAAG,IAAI,OAAO;AACvB,YAAA,CAAC,EAAA,CAAA,GAAA,CAH4D;AAC7D,YAAA,SAAS,EAAE,CAAC,GAAQ,KAAY;gBAC9B,OAAO,GAAG,IAAI,OAAO;YACvB,CAAC;AACF,SAAA,CAAA,CAAA,CAAC;wGANS,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAb,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,aAAa,qVCR1B,mLAGM,EAAA,MAAA,EAAA,CAAA,8JAAA,CAAA,EAAA,CAAA;;4FDKO,aAAa,EAAA,UAAA,EAAA,CAAA;kBANzB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,cAGf,IAAI,EAAA,QAAA,EAAA,mLAAA,EAAA,MAAA,EAAA,CAAA,8JAAA,CAAA,EAAA;;;AENlB;;AAEG;;;;"}
@@ -4,13 +4,12 @@ import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import * as i0 from '@angular/core';
6
6
  import { viewChild, input, booleanAttribute, computed, output, signal, inject, ViewContainerRef, ApplicationRef, Injector, ChangeDetectorRef, DestroyRef, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
7
- import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
8
7
  import { SdLoadingService } from '@sdcorejs/angular/services';
9
8
  import * as uuid from 'uuid';
10
9
  import { Subject, fromEvent, merge } from 'rxjs';
11
10
  import { map, startWith, distinctUntilChanged, takeUntil } from 'rxjs/operators';
12
11
 
13
- class SdSideDrawer extends SdBaseSecureComponent {
12
+ class SdSideDrawer {
14
13
  id = `I${uuid.v4()}`;
15
14
  portal = viewChild.required(CdkPortal);
16
15
  title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
@@ -39,7 +38,6 @@ class SdSideDrawer extends SdBaseSecureComponent {
39
38
  #loadingService = inject(SdLoadingService);
40
39
  #destroyRef = inject(DestroyRef);
41
40
  constructor() {
42
- super();
43
41
  // Thay thế ngAfterViewInit, tự động chạy nội dung này khi DOM sẵn sàng để render
44
42
  afterNextRender(() => {
45
43
  // 1. Gắn portal vào body và lưu lại EmbeddedViewRef
@@ -114,7 +112,7 @@ class SdSideDrawer extends SdBaseSecureComponent {
114
112
  this.isHovered$ = merge(mouseEnter$, mouseLeave$).pipe(startWith(false), distinctUntilChanged(), takeUntil(this.#destroy$));
115
113
  }
116
114
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSideDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
117
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdSideDrawer, isStandalone: true, selector: "sd-side-drawer", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hideClose: { classPropertyName: "hideClose", publicName: "hideClose", isSignal: true, isRequired: false, transformFunction: null }, disableBackdropClose: { classPropertyName: "disableBackdropClose", publicName: "disableBackdropClose", isSignal: true, isRequired: false, transformFunction: null }, drawerClass: { classPropertyName: "drawerClass", publicName: "drawerClass", isSignal: true, isRequired: false, transformFunction: null }, autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sdClosed: "sdClosed" }, viewQueries: [{ propertyName: "portal", first: true, predicate: CdkPortal, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-title\">\n <ng-content select=\"[sdHeaderLeft]\">\n {{ title() }}\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-actions\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <svg\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <ng-content select=\"[sdFooter]\"></ng-content>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n", styles: [".sd-side-drawer{position:fixed;right:0;top:0;bottom:0;background-color:#fff;z-index:999;display:flex;flex-direction:column;opacity:0;visibility:hidden;transform:translate3d(100%,0,0);transition:all .3s ease-in-out;pointer-events:none;box-shadow:0 .4px .8px #0000001a,0 3px 6px #0003}.sd-side-drawer-active{opacity:1;visibility:visible;pointer-events:all;transform:translateZ(0)}.sd-side-drawer-header{min-height:64px;padding:12px 16px;display:flex;align-items:center;justify-content:space-between}.sd-side-drawer-header-actions{display:flex;align-items:center;gap:8px}.sd-side-drawer-title{font-size:20px;line-height:28px;font-weight:500;flex:1;margin-right:16px}.sd-side-drawer-close-btn{background:transparent;border:none;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--sd-secondary-color, #666);border-radius:50%;transition:background-color .2s,color .2s}.sd-side-drawer-close-btn:hover{background-color:#0000000a;color:var(--sd-primary-color, #333)}.sd-side-drawer-close-btn:focus{outline:none;background-color:#00000014}.sd-side-drawer-body{flex:1;position:relative}.sd-side-drawer-content{position:absolute;padding:0 16px 16px;inset:0;overflow:auto}.sd-side-drawer-footer{border-top:1px solid #dde0e5;padding:8px}.sd-side-drawer-backdrop{background-color:#0006;border:0;outline:none!important;position:fixed;inset:0;z-index:99;width:100%;height:100%;transition:all .3s ease-in-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
115
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdSideDrawer, isStandalone: true, selector: "sd-side-drawer", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hideClose: { classPropertyName: "hideClose", publicName: "hideClose", isSignal: true, isRequired: false, transformFunction: null }, disableBackdropClose: { classPropertyName: "disableBackdropClose", publicName: "disableBackdropClose", isSignal: true, isRequired: false, transformFunction: null }, drawerClass: { classPropertyName: "drawerClass", publicName: "drawerClass", isSignal: true, isRequired: false, transformFunction: null }, autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sdClosed: "sdClosed" }, viewQueries: [{ propertyName: "portal", first: true, predicate: CdkPortal, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-title\">\n <ng-content select=\"[sdHeaderLeft]\">\n {{ title() }}\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-actions\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <svg\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <ng-content select=\"[sdFooter]\"></ng-content>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n", styles: [".sd-side-drawer{position:fixed;right:0;top:0;bottom:0;background-color:#fff;z-index:999;display:flex;flex-direction:column;opacity:0;visibility:hidden;transform:translate3d(100%,0,0);transition:all .3s ease-in-out;pointer-events:none;box-shadow:0 .4px .8px #0000001a,0 3px 6px #0003}.sd-side-drawer-active{opacity:1;visibility:visible;pointer-events:all;transform:translateZ(0)}.sd-side-drawer-header{min-height:64px;padding:12px 16px;display:flex;align-items:center;justify-content:space-between}.sd-side-drawer-header-actions{display:flex;align-items:center;gap:8px}.sd-side-drawer-title{font-size:20px;line-height:28px;font-weight:500;flex:1;margin-right:16px}.sd-side-drawer-close-btn{background:transparent;border:none;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--sd-secondary-color, #666);border-radius:50%;transition:background-color .2s,color .2s}.sd-side-drawer-close-btn:hover{background-color:#0000000a;color:var(--sd-primary-color, #333)}.sd-side-drawer-close-btn:focus{outline:none;background-color:#00000014}.sd-side-drawer-body{flex:1;position:relative}.sd-side-drawer-content{position:absolute;padding:0 16px 16px;inset:0;overflow:auto}.sd-side-drawer-footer{border-top:1px solid #dde0e5;padding:8px}.sd-side-drawer-backdrop{background-color:#0006;border:0;outline:none!important;position:fixed;inset:0;z-index:99;width:100%;height:100%;transition:all .3s ease-in-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
118
116
  }
119
117
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSideDrawer, decorators: [{
120
118
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"sdcorejs-angular-components-side-drawer.mjs","sources":["../../../projects/sdcorejs-angular/components/side-drawer/src/side-drawer.component.ts","../../../projects/sdcorejs-angular/components/side-drawer/src/side-drawer.component.html","../../../projects/sdcorejs-angular/components/side-drawer/sdcorejs-angular-components-side-drawer.ts"],"sourcesContent":["import { CdkPortal, DomPortalOutlet, PortalModule } from '@angular/cdk/portal';\nimport { CommonModule } from '@angular/common';\nimport {\n ApplicationRef,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n DestroyRef,\n EmbeddedViewRef,\n Injector,\n ViewContainerRef,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild\n} from '@angular/core';\nimport { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';\nimport { SdLoadingService } from '@sdcorejs/angular/services';\nimport * as uuid from 'uuid';\nimport { fromEvent, merge, Observable, Subject } from 'rxjs';\nimport { map, takeUntil, startWith, distinctUntilChanged } from 'rxjs/operators';\n\n@Component({\n selector: 'sd-side-drawer',\n templateUrl: './side-drawer.component.html',\n styleUrls: ['./side-drawer.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, PortalModule],\n})\nexport class SdSideDrawer extends SdBaseSecureComponent {\n id = `I${uuid.v4()}`;\n \n portal = viewChild.required(CdkPortal);\n \n title = input<string>('');\n width = input<string>('480px');\n hideClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\n disableBackdropClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\n\n // Custom CSS class added to the root side-drawer container\n drawerClass = input<any>('');\n\n readonly autoIdInput = input<string | undefined | null>(undefined, { alias: 'autoId' });\n readonly autoId = computed(() =>\n this.autoIdInput() ? `components-side-drawer-${this.autoIdInput()}` : undefined\n );\n\n sdClosed = output<void>();\n\n #embeddedViewRef!: EmbeddedViewRef<any>;\n\n readonly #isOpenedSignal = signal(false);\n readonly #isLoadingSignal = signal(false);\n readonly isOpened = this.#isOpenedSignal.asReadonly();\n readonly isLoading = this.#isLoadingSignal.asReadonly();\n readonly dataOpened = computed(() => (this.#isOpenedSignal() ? 'true' : 'false'));\n readonly dataLoading = computed(() => (this.#isLoadingSignal() ? 'true' : 'false'));\n\n isHovered$!: Observable<boolean>;\n #destroy$ = new Subject<void>();\n #previousBodyOverflow: string | null = null;\n\n #viewContainerRef = inject(ViewContainerRef);\n #ar = inject(ApplicationRef);\n #injector = inject(Injector);\n #ref = inject(ChangeDetectorRef);\n #loadingService = inject(SdLoadingService);\n #destroyRef = inject(DestroyRef);\n\n constructor() {\n super();\n\n // Thay thế ngAfterViewInit, tự động chạy nội dung này khi DOM sẵn sàng để render\n afterNextRender(() => {\n // 1. Gắn portal vào body và lưu lại EmbeddedViewRef\n const outlet = new DomPortalOutlet(document.body, this.#ar, this.#injector);\n this.#embeddedViewRef = outlet.attachTemplatePortal(this.portal());\n \n // 2. Setup sự kiện hover ngay sau khi DOM thật đã được in ra\n this.#setupHoverSubscription();\n });\n\n // Thay thế ngOnDestroy bằng logic destroy trực tiếp \n this.#destroyRef.onDestroy(() => {\n this.#destroy$.next();\n this.#destroy$.complete();\n \n if (this.#embeddedViewRef) {\n this.#embeddedViewRef.destroy();\n }\n \n if (this.#isOpenedSignal()) {\n if (this.#previousBodyOverflow !== null) {\n document.body.style.overflow = this.#previousBodyOverflow;\n } else {\n document.body.style.overflow = '';\n }\n }\n });\n }\n\n open = () => {\n this.#ref.markForCheck();\n this.#isOpenedSignal.set(true);\n\n // Chặn scroll ở document body\n this.#previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n };\n\n close = () => {\n this.#ref.markForCheck();\n this.#isOpenedSignal.set(false);\n this.sdClosed.emit();\n this.stopLoading();\n \n // Khôi phục lại scroll ở document body\n if (this.#previousBodyOverflow !== null) {\n document.body.style.overflow = this.#previousBodyOverflow;\n this.#previousBodyOverflow = null;\n } else {\n document.body.style.overflow = '';\n }\n };\n\n startLoading = () => {\n this.#isLoadingSignal.set(true);\n this.#loadingService.stop(`#${this.id}`);\n this.#loadingService.start(`#${this.id}`);\n };\n\n stopLoading = () => {\n this.#isLoadingSignal.set(false);\n this.#loadingService.stop(`#${this.id}`);\n };\n\n preventScroll = (event: Event) => {\n event.preventDefault();\n };\n\n #setupHoverSubscription(): void {\n if (!this.#embeddedViewRef) return;\n\n // 3. Lấy DOM element trực tiếp từ rootNodes của EmbeddedViewRef\n const rootNodes = this.#embeddedViewRef.rootNodes;\n const element = rootNodes.find(\n (node) => node.nodeType === Node.ELEMENT_NODE && (node as HTMLElement).classList?.contains('sd-side-drawer')\n );\n\n if (!element) {\n console.warn('SdSideDrawer: Cannot find sd-side-drawer element to attach hover event');\n return;\n }\n\n // 4. Gắn event listeners trực tiếp lên element thật\n const mouseEnter$ = fromEvent(element, 'mouseenter').pipe(map(() => true));\n const mouseLeave$ = fromEvent(element, 'mouseleave').pipe(map(() => false));\n\n this.isHovered$ = merge(mouseEnter$, mouseLeave$).pipe(\n startWith(false),\n distinctUntilChanged(),\n takeUntil(this.#destroy$)\n );\n }\n}","<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-title\">\n <ng-content select=\"[sdHeaderLeft]\">\n {{ title() }}\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-actions\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <svg\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <ng-content select=\"[sdFooter]\"></ng-content>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdcorejs-angular-components-side-drawer.mjs","sources":["../../../projects/sdcorejs-angular/components/side-drawer/src/side-drawer.component.ts","../../../projects/sdcorejs-angular/components/side-drawer/src/side-drawer.component.html","../../../projects/sdcorejs-angular/components/side-drawer/sdcorejs-angular-components-side-drawer.ts"],"sourcesContent":["import { CdkPortal, DomPortalOutlet, PortalModule } from '@angular/cdk/portal';\nimport { CommonModule } from '@angular/common';\nimport {\n ApplicationRef,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n DestroyRef,\n EmbeddedViewRef,\n Injector,\n ViewContainerRef,\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild\n} from '@angular/core';\nimport { SdLoadingService } from '@sdcorejs/angular/services';\nimport * as uuid from 'uuid';\nimport { fromEvent, merge, Observable, Subject } from 'rxjs';\nimport { map, takeUntil, startWith, distinctUntilChanged } from 'rxjs/operators';\n\n@Component({\n selector: 'sd-side-drawer',\n templateUrl: './side-drawer.component.html',\n styleUrls: ['./side-drawer.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [CommonModule, PortalModule],\n})\nexport class SdSideDrawer {\n id = `I${uuid.v4()}`;\n \n portal = viewChild.required(CdkPortal);\n \n title = input<string>('');\n width = input<string>('480px');\n hideClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\n disableBackdropClose = input<boolean, boolean | ''>(false, { transform: booleanAttribute });\n\n // Custom CSS class added to the root side-drawer container\n drawerClass = input<any>('');\n\n readonly autoIdInput = input<string | undefined | null>(undefined, { alias: 'autoId' });\n readonly autoId = computed(() =>\n this.autoIdInput() ? `components-side-drawer-${this.autoIdInput()}` : undefined\n );\n\n sdClosed = output<void>();\n\n #embeddedViewRef!: EmbeddedViewRef<any>;\n\n readonly #isOpenedSignal = signal(false);\n readonly #isLoadingSignal = signal(false);\n readonly isOpened = this.#isOpenedSignal.asReadonly();\n readonly isLoading = this.#isLoadingSignal.asReadonly();\n readonly dataOpened = computed(() => (this.#isOpenedSignal() ? 'true' : 'false'));\n readonly dataLoading = computed(() => (this.#isLoadingSignal() ? 'true' : 'false'));\n\n isHovered$!: Observable<boolean>;\n #destroy$ = new Subject<void>();\n #previousBodyOverflow: string | null = null;\n\n #viewContainerRef = inject(ViewContainerRef);\n #ar = inject(ApplicationRef);\n #injector = inject(Injector);\n #ref = inject(ChangeDetectorRef);\n #loadingService = inject(SdLoadingService);\n #destroyRef = inject(DestroyRef);\n\n constructor() {\n\n // Thay thế ngAfterViewInit, tự động chạy nội dung này khi DOM sẵn sàng để render\n afterNextRender(() => {\n // 1. Gắn portal vào body và lưu lại EmbeddedViewRef\n const outlet = new DomPortalOutlet(document.body, this.#ar, this.#injector);\n this.#embeddedViewRef = outlet.attachTemplatePortal(this.portal());\n \n // 2. Setup sự kiện hover ngay sau khi DOM thật đã được in ra\n this.#setupHoverSubscription();\n });\n\n // Thay thế ngOnDestroy bằng logic destroy trực tiếp \n this.#destroyRef.onDestroy(() => {\n this.#destroy$.next();\n this.#destroy$.complete();\n \n if (this.#embeddedViewRef) {\n this.#embeddedViewRef.destroy();\n }\n \n if (this.#isOpenedSignal()) {\n if (this.#previousBodyOverflow !== null) {\n document.body.style.overflow = this.#previousBodyOverflow;\n } else {\n document.body.style.overflow = '';\n }\n }\n });\n }\n\n open = () => {\n this.#ref.markForCheck();\n this.#isOpenedSignal.set(true);\n\n // Chặn scroll ở document body\n this.#previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n };\n\n close = () => {\n this.#ref.markForCheck();\n this.#isOpenedSignal.set(false);\n this.sdClosed.emit();\n this.stopLoading();\n \n // Khôi phục lại scroll ở document body\n if (this.#previousBodyOverflow !== null) {\n document.body.style.overflow = this.#previousBodyOverflow;\n this.#previousBodyOverflow = null;\n } else {\n document.body.style.overflow = '';\n }\n };\n\n startLoading = () => {\n this.#isLoadingSignal.set(true);\n this.#loadingService.stop(`#${this.id}`);\n this.#loadingService.start(`#${this.id}`);\n };\n\n stopLoading = () => {\n this.#isLoadingSignal.set(false);\n this.#loadingService.stop(`#${this.id}`);\n };\n\n preventScroll = (event: Event) => {\n event.preventDefault();\n };\n\n #setupHoverSubscription(): void {\n if (!this.#embeddedViewRef) return;\n\n // 3. Lấy DOM element trực tiếp từ rootNodes của EmbeddedViewRef\n const rootNodes = this.#embeddedViewRef.rootNodes;\n const element = rootNodes.find(\n (node) => node.nodeType === Node.ELEMENT_NODE && (node as HTMLElement).classList?.contains('sd-side-drawer')\n );\n\n if (!element) {\n console.warn('SdSideDrawer: Cannot find sd-side-drawer element to attach hover event');\n return;\n }\n\n // 4. Gắn event listeners trực tiếp lên element thật\n const mouseEnter$ = fromEvent(element, 'mouseenter').pipe(map(() => true));\n const mouseLeave$ = fromEvent(element, 'mouseleave').pipe(map(() => false));\n\n this.isHovered$ = merge(mouseEnter$, mouseLeave$).pipe(\n startWith(false),\n distinctUntilChanged(),\n takeUntil(this.#destroy$)\n );\n }\n}","<ng-template cdkPortal>\n @let _isOpened = isOpened();\n <div\n [id]=\"id\"\n class=\"sd-side-drawer\"\n [ngStyle]=\"{ width: width() }\"\n [ngClass]=\"drawerClass()\"\n [class.sd-side-drawer-active]=\"_isOpened\"\n [attr.data-autoId]=\"autoId()\"\n [attr.data-opened]=\"dataOpened()\"\n [attr.data-loading]=\"dataLoading()\"\n #drawerContainer>\n @if (_isOpened) {\n <ng-container>\n <div class=\"sd-side-drawer-header\">\n <div class=\"sd-side-drawer-title\">\n <ng-content select=\"[sdHeaderLeft]\">\n {{ title() }}\n </ng-content>\n </div>\n <div class=\"sd-side-drawer-header-actions\">\n <ng-content select=\"[sdHeaderRight]\"></ng-content>\n @if (!hideClose()) {\n <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n <svg\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n }\n </div>\n </div>\n @if (_isOpened) {\n <div class=\"sd-side-drawer-body\">\n <div class=\"sd-side-drawer-content\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n <div class=\"sd-side-drawer-footer\">\n <ng-content select=\"[sdFooter]\"></ng-content>\n </div>\n </ng-container>\n }\n </div>\n @if (_isOpened) {\n <div\n aria-hidden=\"true\"\n class=\"sd-side-drawer-backdrop\"\n (click)=\"disableBackdropClose() ? null : close()\"\n (wheel)=\"preventScroll($event)\"\n (touchmove)=\"preventScroll($event)\"></div>\n }\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -5,7 +5,6 @@ import * as i2 from '@angular/material/icon';
5
5
  import { MatIconModule } from '@angular/material/icon';
6
6
  import * as i1 from '@angular/material/stepper';
7
7
  import { MatStepper, MatStepperModule } from '@angular/material/stepper';
8
- import { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';
9
8
 
10
9
  class SdStep {
11
10
  label = input.required(...(ngDevMode ? [{ debugName: "label" }] : []));
@@ -43,7 +42,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImpo
43
42
  }]
44
43
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], stepControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepControl", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], bodyTpl: [{ type: i0.ViewChild, args: ['body', { isSignal: true }] }] } });
45
44
 
46
- class SdStepper extends SdBaseSecureComponent {
45
+ class SdStepper {
47
46
  steps = contentChildren(SdStep, ...(ngDevMode ? [{ debugName: "steps" }] : []));
48
47
  selectedIndex = model(0, ...(ngDevMode ? [{ debugName: "selectedIndex" }] : []));
49
48
  // why: enforce sequential gating — only valid steps unlock the next.
@@ -76,7 +75,6 @@ class SdStepper extends SdBaseSecureComponent {
76
75
  return `var(--sd-${this.color()})`;
77
76
  }
78
77
  constructor() {
79
- super();
80
78
  // why: clamp selectedIndex when a step is removed past the active one.
81
79
  effect(() => {
82
80
  const len = this.steps().length;
@@ -110,7 +108,7 @@ class SdStepper extends SdBaseSecureComponent {
110
108
  step?.selectChange.emit();
111
109
  }
112
110
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdStepper, deps: [], target: i0.ɵɵFactoryTarget.Component });
113
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdStepper, isStandalone: true, selector: "sd-stepper", inputs: { selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, headerPosition: { classPropertyName: "headerPosition", publicName: "headerPosition", isSignal: true, isRequired: false, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null }, disableRipple: { classPropertyName: "disableRipple", publicName: "disableRipple", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndex: "selectedIndexChange", selectionChange: "selectionChange" }, host: { properties: { "attr.data-autoId": "this.autoIdAttr", "style.--sd-stepper-active-color": "this.cssActive", "style.--sd-stepper-active-bg": "this.cssActiveBg", "style.--sd-stepper-completed-color": "this.cssCompleted", "style.--sd-stepper-line-active-color": "this.cssLine" } }, queries: [{ propertyName: "steps", predicate: SdStep, isSignal: true }], viewQueries: [{ propertyName: "matStepper", first: true, predicate: MatStepper, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<mat-stepper\n class=\"sd-stepper\"\n [(selectedIndex)]=\"selectedIndex\"\n [linear]=\"linear()\"\n [orientation]=\"orientation()\"\n [labelPosition]=\"labelPosition()\"\n [headerPosition]=\"headerPosition()\"\n [animationDuration]=\"animationDuration()\"\n [disableRipple]=\"disableRipple()\"\n (selectionChange)=\"onSelectionChange($event)\">\n @for (step of steps(); track step; let i = $index) {\n <mat-step\n [stepControl]=\"step.stepControl() ?? undefined!\"\n [optional]=\"step.optional()\"\n [editable]=\"step.editable()\"\n [state]=\"step.state() ?? ''\"\n [errorMessage]=\"step.errorMessage() ?? ''\">\n <ng-template matStepLabel>\n <span class=\"sd-step__label\">\n @if (step.icon(); as ic) {\n <mat-icon class=\"sd-step__icon\">{{ ic }}</mat-icon>\n }\n <span class=\"sd-step__text\">{{ step.label() }}</span>\n </span>\n </ng-template>\n\n <ng-template matStepContent>\n <ng-container [ngTemplateOutlet]=\"step.bodyTpl()\"></ng-container>\n </ng-template>\n </mat-step>\n }\n</mat-stepper>\n", styles: [":host{display:block;--sd-stepper-active-color: var(--sd-primary, #1565c0);--sd-stepper-active-bg: var(--sd-primary, #1565c0);--sd-stepper-completed-color: var(--sd-primary, #1565c0);--sd-stepper-line-active-color: var(--sd-primary, #1565c0);--sd-stepper-error-color: var(--sd-error, #f44336);--sd-stepper-pending-bg: #e0e0e0;--sd-stepper-pending-color: rgba(0, 0, 0, .54);--sd-stepper-text-color: var(--sd-text-primary, #1a1a1a)}.sd-step__label{display:inline-flex;align-items:center;gap:4px}.sd-step__icon{font-size:18px;width:18px;height:18px;line-height:18px}.sd-step__text{white-space:nowrap}:host ::ng-deep .mat-step-icon{background-color:var(--sd-stepper-pending-bg);color:var(--sd-stepper-pending-color)}:host ::ng-deep .mat-step-icon-selected{background-color:var(--sd-stepper-active-bg)!important;color:#fff!important}:host ::ng-deep .mat-step-icon-state-done,:host ::ng-deep .mat-step-icon-state-edit{background-color:var(--sd-stepper-completed-color)!important;color:#fff!important}:host ::ng-deep .mat-step-icon-state-error{background-color:var(--sd-stepper-error-color)!important;color:#fff!important}:host ::ng-deep .mat-step-label.mat-step-label-active .mat-step-text-label{color:var(--sd-stepper-text-color);font-weight:500}:host ::ng-deep .mat-step-label-selected .mat-step-text-label{color:var(--sd-stepper-active-color);font-weight:600}:host ::ng-deep .mat-stepper-horizontal-line,:host ::ng-deep .mat-stepper-vertical-line:before{border-color:#0000001f}:host ::ng-deep .mat-step-header.cdk-program-focused,:host ::ng-deep .mat-step-header:hover{background-color:#00000005}\n"], dependencies: [{ kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i1.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i1.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i1.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i1.MatStepContent, selector: "ng-template[matStepContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
111
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdStepper, isStandalone: true, selector: "sd-stepper", inputs: { selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, headerPosition: { classPropertyName: "headerPosition", publicName: "headerPosition", isSignal: true, isRequired: false, transformFunction: null }, animationDuration: { classPropertyName: "animationDuration", publicName: "animationDuration", isSignal: true, isRequired: false, transformFunction: null }, disableRipple: { classPropertyName: "disableRipple", publicName: "disableRipple", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndex: "selectedIndexChange", selectionChange: "selectionChange" }, host: { properties: { "attr.data-autoId": "this.autoIdAttr", "style.--sd-stepper-active-color": "this.cssActive", "style.--sd-stepper-active-bg": "this.cssActiveBg", "style.--sd-stepper-completed-color": "this.cssCompleted", "style.--sd-stepper-line-active-color": "this.cssLine" } }, queries: [{ propertyName: "steps", predicate: SdStep, isSignal: true }], viewQueries: [{ propertyName: "matStepper", first: true, predicate: MatStepper, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-stepper\n class=\"sd-stepper\"\n [(selectedIndex)]=\"selectedIndex\"\n [linear]=\"linear()\"\n [orientation]=\"orientation()\"\n [labelPosition]=\"labelPosition()\"\n [headerPosition]=\"headerPosition()\"\n [animationDuration]=\"animationDuration()\"\n [disableRipple]=\"disableRipple()\"\n (selectionChange)=\"onSelectionChange($event)\">\n @for (step of steps(); track step; let i = $index) {\n <mat-step\n [stepControl]=\"step.stepControl() ?? undefined!\"\n [optional]=\"step.optional()\"\n [editable]=\"step.editable()\"\n [state]=\"step.state() ?? ''\"\n [errorMessage]=\"step.errorMessage() ?? ''\">\n <ng-template matStepLabel>\n <span class=\"sd-step__label\">\n @if (step.icon(); as ic) {\n <mat-icon class=\"sd-step__icon\">{{ ic }}</mat-icon>\n }\n <span class=\"sd-step__text\">{{ step.label() }}</span>\n </span>\n </ng-template>\n\n <ng-template matStepContent>\n <ng-container [ngTemplateOutlet]=\"step.bodyTpl()\"></ng-container>\n </ng-template>\n </mat-step>\n }\n</mat-stepper>\n", styles: [":host{display:block;--sd-stepper-active-color: var(--sd-primary, #1565c0);--sd-stepper-active-bg: var(--sd-primary, #1565c0);--sd-stepper-completed-color: var(--sd-primary, #1565c0);--sd-stepper-line-active-color: var(--sd-primary, #1565c0);--sd-stepper-error-color: var(--sd-error, #f44336);--sd-stepper-pending-bg: #e0e0e0;--sd-stepper-pending-color: rgba(0, 0, 0, .54);--sd-stepper-text-color: var(--sd-text-primary, #1a1a1a)}.sd-step__label{display:inline-flex;align-items:center;gap:4px}.sd-step__icon{font-size:18px;width:18px;height:18px;line-height:18px}.sd-step__text{white-space:nowrap}:host ::ng-deep .mat-step-icon{background-color:var(--sd-stepper-pending-bg);color:var(--sd-stepper-pending-color)}:host ::ng-deep .mat-step-icon-selected{background-color:var(--sd-stepper-active-bg)!important;color:#fff!important}:host ::ng-deep .mat-step-icon-state-done,:host ::ng-deep .mat-step-icon-state-edit{background-color:var(--sd-stepper-completed-color)!important;color:#fff!important}:host ::ng-deep .mat-step-icon-state-error{background-color:var(--sd-stepper-error-color)!important;color:#fff!important}:host ::ng-deep .mat-step-label.mat-step-label-active .mat-step-text-label{color:var(--sd-stepper-text-color);font-weight:500}:host ::ng-deep .mat-step-label-selected .mat-step-text-label{color:var(--sd-stepper-active-color);font-weight:600}:host ::ng-deep .mat-stepper-horizontal-line,:host ::ng-deep .mat-stepper-vertical-line:before{border-color:#0000001f}:host ::ng-deep .mat-step-header.cdk-program-focused,:host ::ng-deep .mat-step-header:hover{background-color:#00000005}\n"], dependencies: [{ kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i1.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i1.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i1.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "directive", type: i1.MatStepContent, selector: "ng-template[matStepContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
114
112
  }
115
113
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdStepper, decorators: [{
116
114
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"sdcorejs-angular-components-stepper.mjs","sources":["../../../projects/sdcorejs-angular/components/stepper/src/step.component.ts","../../../projects/sdcorejs-angular/components/stepper/src/stepper.component.ts","../../../projects/sdcorejs-angular/components/stepper/src/stepper.component.html","../../../projects/sdcorejs-angular/components/stepper/sdcorejs-angular-components-stepper.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\n\nexport type SdStepState = 'pending' | 'active' | 'completed' | 'error' | string;\n\n@Component({\n selector: 'sd-step',\n standalone: true,\n // why: identical pattern to <sd-tab> — capture projected content via #body\n // template ref so <sd-stepper> can render it inside mat-step's matStepContent\n // (lazy mount + animation-friendly).\n template: `<ng-template #body><ng-content></ng-content></ng-template>`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SdStep {\n label = input.required<string>();\n // Optional Material icon name shown when the step is in 'pending' state\n // (overrides the default numbered indicator).\n icon = input<string | null | undefined>(undefined);\n // Set true to mark the step skippable in linear mode.\n optional = input(false, { transform: booleanAttribute });\n // When false, user cannot return to this step after it's been completed.\n editable = input(true, { transform: booleanAttribute });\n // Reactive form / control. When the stepper is linear, the user can only\n // proceed past this step once stepControl.valid is true.\n stepControl = input<AbstractControl | null | undefined>(undefined);\n // Override the auto-derived state (eg force 'error' from outside on async validation).\n state = input<SdStepState | undefined>(undefined);\n // Error message rendered next to the step header when state is 'error'.\n errorMessage = input<string | undefined>(undefined);\n\n // Emitted when this step transitions to selected.\n selectChange = output<void>();\n\n // Body template captured from projected <ng-content>.\n bodyTpl = viewChild.required<TemplateRef<unknown>>('body');\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n contentChildren,\n effect,\n HostBinding,\n input,\n model,\n output,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { StepperSelectionEvent } from '@angular/cdk/stepper';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatStepperModule, MatStepper } from '@angular/material/stepper';\nimport { SdBaseSecureComponent } from '@sdcorejs/angular/components/base';\nimport { Color } from '@sdcorejs/utils/models';\nimport { SdStep } from './step.component';\n\n@Component({\n selector: 'sd-stepper',\n standalone: true,\n imports: [MatStepperModule, MatIconModule, NgTemplateOutlet],\n templateUrl: './stepper.component.html',\n styleUrls: ['./stepper.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SdStepper extends SdBaseSecureComponent {\n steps = contentChildren(SdStep);\n\n selectedIndex = model<number>(0);\n // why: enforce sequential gating — only valid steps unlock the next.\n linear = input(false, { transform: booleanAttribute });\n orientation = input<'horizontal' | 'vertical'>('horizontal');\n labelPosition = input<'end' | 'bottom'>('end');\n headerPosition = input<'top' | 'bottom'>('top');\n animationDuration = input<string>('500ms');\n disableRipple = input(false, { transform: booleanAttribute });\n // Drives the Core color CSS vars on indicators / connector / line.\n color = input<Color>('primary');\n autoId = input<string | undefined>(undefined);\n\n // Emits {previousIndex, selectedIndex, previousStep, selectedStep}.\n selectionChange = output<StepperSelectionEvent>();\n\n protected matStepper = viewChild(MatStepper);\n\n @HostBinding('attr.data-autoId') get autoIdAttr(): string | null {\n return this.autoId() ?? null;\n }\n\n // Core color CSS vars — same mechanism as <sd-tab-group>.\n @HostBinding('style.--sd-stepper-active-color') get cssActive(): string {\n return `var(--sd-${this.color()})`;\n }\n @HostBinding('style.--sd-stepper-active-bg') get cssActiveBg(): string {\n return `var(--sd-${this.color()})`;\n }\n @HostBinding('style.--sd-stepper-completed-color') get cssCompleted(): string {\n return `var(--sd-${this.color()})`;\n }\n @HostBinding('style.--sd-stepper-line-active-color') get cssLine(): string {\n return `var(--sd-${this.color()})`;\n }\n\n constructor() {\n super();\n // why: clamp selectedIndex when a step is removed past the active one.\n effect(() => {\n const len = this.steps().length;\n const cur = untracked(() => this.selectedIndex());\n if (len > 0 && cur >= len) {\n this.selectedIndex.set(Math.max(0, len - 1));\n }\n });\n }\n\n next(): void {\n this.matStepper()?.next();\n }\n\n previous(): void {\n this.matStepper()?.previous();\n }\n\n reset(): void {\n this.matStepper()?.reset();\n }\n\n goTo(index: number): void {\n const len = this.steps().length;\n if (len === 0) {\n this.selectedIndex.set(0);\n return;\n }\n this.selectedIndex.set(Math.max(0, Math.min(index, len - 1)));\n }\n\n protected onSelectionChange(ev: StepperSelectionEvent): void {\n this.selectionChange.emit(ev);\n // Forward to each step that just became selected so consumer can react.\n const step = this.steps()[ev.selectedIndex];\n step?.selectChange.emit();\n }\n}\n","<mat-stepper\n class=\"sd-stepper\"\n [(selectedIndex)]=\"selectedIndex\"\n [linear]=\"linear()\"\n [orientation]=\"orientation()\"\n [labelPosition]=\"labelPosition()\"\n [headerPosition]=\"headerPosition()\"\n [animationDuration]=\"animationDuration()\"\n [disableRipple]=\"disableRipple()\"\n (selectionChange)=\"onSelectionChange($event)\">\n @for (step of steps(); track step; let i = $index) {\n <mat-step\n [stepControl]=\"step.stepControl() ?? undefined!\"\n [optional]=\"step.optional()\"\n [editable]=\"step.editable()\"\n [state]=\"step.state() ?? ''\"\n [errorMessage]=\"step.errorMessage() ?? ''\">\n <ng-template matStepLabel>\n <span class=\"sd-step__label\">\n @if (step.icon(); as ic) {\n <mat-icon class=\"sd-step__icon\">{{ ic }}</mat-icon>\n }\n <span class=\"sd-step__text\">{{ step.label() }}</span>\n </span>\n </ng-template>\n\n <ng-template matStepContent>\n <ng-container [ngTemplateOutlet]=\"step.bodyTpl()\"></ng-container>\n </ng-template>\n </mat-step>\n }\n</mat-stepper>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdcorejs-angular-components-stepper.mjs","sources":["../../../projects/sdcorejs-angular/components/stepper/src/step.component.ts","../../../projects/sdcorejs-angular/components/stepper/src/stepper.component.ts","../../../projects/sdcorejs-angular/components/stepper/src/stepper.component.html","../../../projects/sdcorejs-angular/components/stepper/sdcorejs-angular-components-stepper.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\n\nexport type SdStepState = 'pending' | 'active' | 'completed' | 'error' | string;\n\n@Component({\n selector: 'sd-step',\n standalone: true,\n // why: identical pattern to <sd-tab> — capture projected content via #body\n // template ref so <sd-stepper> can render it inside mat-step's matStepContent\n // (lazy mount + animation-friendly).\n template: `<ng-template #body><ng-content></ng-content></ng-template>`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SdStep {\n label = input.required<string>();\n // Optional Material icon name shown when the step is in 'pending' state\n // (overrides the default numbered indicator).\n icon = input<string | null | undefined>(undefined);\n // Set true to mark the step skippable in linear mode.\n optional = input(false, { transform: booleanAttribute });\n // When false, user cannot return to this step after it's been completed.\n editable = input(true, { transform: booleanAttribute });\n // Reactive form / control. When the stepper is linear, the user can only\n // proceed past this step once stepControl.valid is true.\n stepControl = input<AbstractControl | null | undefined>(undefined);\n // Override the auto-derived state (eg force 'error' from outside on async validation).\n state = input<SdStepState | undefined>(undefined);\n // Error message rendered next to the step header when state is 'error'.\n errorMessage = input<string | undefined>(undefined);\n\n // Emitted when this step transitions to selected.\n selectChange = output<void>();\n\n // Body template captured from projected <ng-content>.\n bodyTpl = viewChild.required<TemplateRef<unknown>>('body');\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n contentChildren,\n effect,\n HostBinding,\n input,\n model,\n output,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { StepperSelectionEvent } from '@angular/cdk/stepper';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatStepperModule, MatStepper } from '@angular/material/stepper';\nimport { Color } from '@sdcorejs/utils/models';\nimport { SdStep } from './step.component';\n\n@Component({\n selector: 'sd-stepper',\n standalone: true,\n imports: [MatStepperModule, MatIconModule, NgTemplateOutlet],\n templateUrl: './stepper.component.html',\n styleUrls: ['./stepper.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SdStepper {\n steps = contentChildren(SdStep);\n\n selectedIndex = model<number>(0);\n // why: enforce sequential gating — only valid steps unlock the next.\n linear = input(false, { transform: booleanAttribute });\n orientation = input<'horizontal' | 'vertical'>('horizontal');\n labelPosition = input<'end' | 'bottom'>('end');\n headerPosition = input<'top' | 'bottom'>('top');\n animationDuration = input<string>('500ms');\n disableRipple = input(false, { transform: booleanAttribute });\n // Drives the Core color CSS vars on indicators / connector / line.\n color = input<Color>('primary');\n autoId = input<string | undefined>(undefined);\n\n // Emits {previousIndex, selectedIndex, previousStep, selectedStep}.\n selectionChange = output<StepperSelectionEvent>();\n\n protected matStepper = viewChild(MatStepper);\n\n @HostBinding('attr.data-autoId') get autoIdAttr(): string | null {\n return this.autoId() ?? null;\n }\n\n // Core color CSS vars — same mechanism as <sd-tab-group>.\n @HostBinding('style.--sd-stepper-active-color') get cssActive(): string {\n return `var(--sd-${this.color()})`;\n }\n @HostBinding('style.--sd-stepper-active-bg') get cssActiveBg(): string {\n return `var(--sd-${this.color()})`;\n }\n @HostBinding('style.--sd-stepper-completed-color') get cssCompleted(): string {\n return `var(--sd-${this.color()})`;\n }\n @HostBinding('style.--sd-stepper-line-active-color') get cssLine(): string {\n return `var(--sd-${this.color()})`;\n }\n\n constructor() {\n // why: clamp selectedIndex when a step is removed past the active one.\n effect(() => {\n const len = this.steps().length;\n const cur = untracked(() => this.selectedIndex());\n if (len > 0 && cur >= len) {\n this.selectedIndex.set(Math.max(0, len - 1));\n }\n });\n }\n\n next(): void {\n this.matStepper()?.next();\n }\n\n previous(): void {\n this.matStepper()?.previous();\n }\n\n reset(): void {\n this.matStepper()?.reset();\n }\n\n goTo(index: number): void {\n const len = this.steps().length;\n if (len === 0) {\n this.selectedIndex.set(0);\n return;\n }\n this.selectedIndex.set(Math.max(0, Math.min(index, len - 1)));\n }\n\n protected onSelectionChange(ev: StepperSelectionEvent): void {\n this.selectionChange.emit(ev);\n // Forward to each step that just became selected so consumer can react.\n const step = this.steps()[ev.selectedIndex];\n step?.selectChange.emit();\n }\n}\n","<mat-stepper\n class=\"sd-stepper\"\n [(selectedIndex)]=\"selectedIndex\"\n [linear]=\"linear()\"\n [orientation]=\"orientation()\"\n [labelPosition]=\"labelPosition()\"\n [headerPosition]=\"headerPosition()\"\n [animationDuration]=\"animationDuration()\"\n [disableRipple]=\"disableRipple()\"\n (selectionChange)=\"onSelectionChange($event)\">\n @for (step of steps(); track step; let i = $index) {\n <mat-step\n [stepControl]=\"step.stepControl() ?? undefined!\"\n [optional]=\"step.optional()\"\n [editable]=\"step.editable()\"\n [state]=\"step.state() ?? ''\"\n [errorMessage]=\"step.errorMessage() ?? ''\">\n <ng-template matStepLabel>\n <span class=\"sd-step__label\">\n @if (step.icon(); as ic) {\n <mat-icon class=\"sd-step__icon\">{{ ic }}</mat-icon>\n }\n <span class=\"sd-step__text\">{{ step.label() }}</span>\n </span>\n </ng-template>\n\n <ng-template matStepContent>\n <ng-container [ngTemplateOutlet]=\"step.bodyTpl()\"></ng-container>\n </ng-template>\n </mat-step>\n }\n</mat-stepper>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}