@xiriframework/xiri-ng 0.2.18 → 0.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @xiriframework/xiri-ng
|
|
2
2
|
|
|
3
|
-
Angular UI component library for the Xiri Framework.
|
|
3
|
+
Angular UI component library for the [Xiri Framework](https://github.com/xiriframework) — a JSON-driven approach where your backend defines the UI and `xiri-ng` renders it. Pairs with [xiri-go](https://github.com/xiriframework/xiri-go) (Go backend) or any backend that emits the expected JSON shape.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,61 +8,156 @@ Angular UI component library for the Xiri Framework.
|
|
|
8
8
|
npm install @xiriframework/xiri-ng
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
Register the Xiri services in your application config. `api` is the base URL prepended to HTTP requests made by `XiriDataService`:
|
|
12
14
|
|
|
13
15
|
```typescript
|
|
16
|
+
import { ApplicationConfig } from '@angular/core';
|
|
17
|
+
import { provideHttpClient } from '@angular/common/http';
|
|
18
|
+
import { provideRouter } from '@angular/router';
|
|
14
19
|
import { provideXiriServices } from '@xiriframework/xiri-ng';
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
export const appConfig: ApplicationConfig = {
|
|
17
22
|
providers: [
|
|
23
|
+
provideHttpClient(),
|
|
24
|
+
provideRouter(routes),
|
|
18
25
|
provideXiriServices({ api: '/api/' }),
|
|
19
|
-
]
|
|
20
|
-
}
|
|
26
|
+
],
|
|
27
|
+
};
|
|
21
28
|
```
|
|
22
29
|
|
|
23
|
-
The
|
|
30
|
+
## The main entry point: `xiri-dyncomponent`
|
|
24
31
|
|
|
25
|
-
|
|
32
|
+
`xiri-ng` is designed around a central component that dynamically renders an array of JSON component definitions:
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<xiri-dyncomponent [data]="components"></xiri-dyncomponent>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { XiriDynComponentComponent, XiriDynData } from '@xiriframework/xiri-ng';
|
|
40
|
+
|
|
41
|
+
components: XiriDynData[] = [
|
|
42
|
+
{ type: 'page-header', data: { title: 'Dashboard' } },
|
|
43
|
+
{ type: 'stat-grid', data: { stats: [...], columns: 4 } },
|
|
44
|
+
{ type: 'table', data: { url: '/api/devices', ... } },
|
|
45
|
+
];
|
|
46
|
+
```
|
|
26
47
|
|
|
27
|
-
|
|
48
|
+
Individual components can also be used directly (all are standalone):
|
|
28
49
|
|
|
29
50
|
```typescript
|
|
30
|
-
import { XiriTableComponent
|
|
51
|
+
import { XiriTableComponent } from '@xiriframework/xiri-ng';
|
|
52
|
+
|
|
53
|
+
@Component({
|
|
54
|
+
selector: 'app-devices',
|
|
55
|
+
imports: [XiriTableComponent],
|
|
56
|
+
template: `<xiri-table [settings]="tableSettings" />`,
|
|
57
|
+
})
|
|
58
|
+
export class DevicesComponent { /* ... */ }
|
|
31
59
|
```
|
|
32
60
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
## Components
|
|
62
|
+
|
|
63
|
+
40+ standalone Material-Design components. Import individually for tree-shaking.
|
|
64
|
+
|
|
65
|
+
### Forms & data
|
|
66
|
+
|
|
67
|
+
| Component | Use case |
|
|
68
|
+
| ---------------------------- | -------------------------------------------------- |
|
|
69
|
+
| `XiriFormComponent` | Dynamic form with backend-driven fields + submit |
|
|
70
|
+
| `XiriFormFieldsComponent` | Just the fields — full control over submit flow |
|
|
71
|
+
| `XiriQueryComponent` | Filter form + live results via `xiri-dyncomponent` |
|
|
72
|
+
| `XiriTableComponent` | Full data table — sort, paginate, filter, inline-edit, export |
|
|
73
|
+
| `XiriRawTableComponent` | Minimal table for static data |
|
|
74
|
+
| `XiriDialogComponent` | Modal dialogs (question / form / table / waiting) |
|
|
75
|
+
| `XiriStepperComponent` | Multi-step wizard |
|
|
76
|
+
|
|
77
|
+
### Layout & navigation
|
|
78
|
+
|
|
79
|
+
| Component | Use case |
|
|
80
|
+
| ---------------------------- | -------------------------------------------------- |
|
|
81
|
+
| `XiriPageHeaderComponent` | Page title + subtitle + actions |
|
|
82
|
+
| `XiriToolbarComponent` | Toolbar with title, search, buttons |
|
|
83
|
+
| `XiriSectionComponent` | Collapsible content sections |
|
|
84
|
+
| `XiriDividerComponent` | Section divider with optional text/icon |
|
|
85
|
+
| `XiriTabsComponent` | Material tabs with lazy-loading |
|
|
86
|
+
| `XiriExpansionComponent` | Accordion panels with lazy-loading |
|
|
87
|
+
| `XiriSidenavComponent` | Side navigation with nested items |
|
|
88
|
+
| `XiriBreadcrumbComponent` | Breadcrumb trail |
|
|
89
|
+
|
|
90
|
+
### Cards, lists, info
|
|
91
|
+
|
|
92
|
+
| Component | Use case |
|
|
93
|
+
| --------------------------------- | --------------------------------------------- |
|
|
94
|
+
| `XiriCardComponent` | Card container with header + content |
|
|
95
|
+
| `XiriCardlinkComponent` | Clickable card as a navigation link |
|
|
96
|
+
| `XiriLinksComponent` | List of navigation links/buttons |
|
|
97
|
+
| `XiriListComponent` | Sectioned list with favorites |
|
|
98
|
+
| `XiriInfopointComponent` | Info card (icon + text + optional link) |
|
|
99
|
+
| `XiriImagetextComponent` | Image + text card |
|
|
100
|
+
| `XiriDescriptionListComponent` | Key/value pairs in 1-3 columns |
|
|
101
|
+
|
|
102
|
+
### Stats, progress, feedback
|
|
103
|
+
|
|
104
|
+
| Component | Use case |
|
|
105
|
+
| ----------------------------- | ------------------------------------------------- |
|
|
106
|
+
| `XiriStatComponent` | Single KPI tile with value + label + trend |
|
|
107
|
+
| `XiriStatGridComponent` | Grid of KPI tiles |
|
|
108
|
+
| `XiriMultiprogressComponent` | Multi-row progress bars |
|
|
109
|
+
| `XiriTimelineComponent` | Vertical or horizontal timeline |
|
|
110
|
+
| `XiriEmptyStateComponent` | Empty-state placeholder with optional action |
|
|
111
|
+
| `XiriSkeletonComponent` | Loading skeleton (text/circle/rect/table-row) |
|
|
112
|
+
| `XiriAlertComponent` | Alert / confirmation dialog content |
|
|
113
|
+
| `XiriDoneComponent` | Success checkmark |
|
|
114
|
+
| `XiriErrorComponent` | Error message display |
|
|
115
|
+
| `XiriHeaderComponent` | In-page section header |
|
|
116
|
+
|
|
117
|
+
### Buttons & search
|
|
118
|
+
|
|
119
|
+
| Component | Use case |
|
|
120
|
+
| ----------------------------- | ------------------------------------------------- |
|
|
121
|
+
| `XiriButtonComponent` | Single button with action handling |
|
|
122
|
+
| `XiriButtonlineComponent` | Horizontal button line |
|
|
123
|
+
| `XiriButtonstyleComponent` | Internal — button visual renderer |
|
|
124
|
+
| `XiriSearchComponent` | Debounced search input |
|
|
125
|
+
|
|
126
|
+
## Services
|
|
127
|
+
|
|
128
|
+
All services are `providedIn: 'root'` and are activated by `provideXiriServices()`:
|
|
129
|
+
|
|
130
|
+
| Service | Purpose |
|
|
131
|
+
| ------------------------------- | ----------------------------------------------------------------- |
|
|
132
|
+
| `XiriDataService` | HTTP client with automatic snackbar response handling |
|
|
133
|
+
| `XiriSnackbarService` | Toast notifications (success, error, info, warning) |
|
|
134
|
+
| `XiriResponseHandlerService` | Parses backend responses (refresh, goto, table-update) centrally |
|
|
135
|
+
| `XiriFormService` | Form data fetch/submit + state persistence |
|
|
136
|
+
| `XiriDownloadService` | File download handling (blob → browser) |
|
|
137
|
+
| `XiriDateService` | Unix timestamp ↔ locale-formatted strings (via `date-fns`) |
|
|
138
|
+
| `XiriNumberService` | Locale-aware number formatting |
|
|
139
|
+
| `XiriLocalStorageService` | Typed localStorage wrapper with timestamp-based expiry |
|
|
140
|
+
| `XiriSessionStorageService` | Typed sessionStorage wrapper |
|
|
141
|
+
| `ThemeService` | Theme management (light / dark / auto) via signals |
|
|
142
|
+
|
|
143
|
+
## Pipes
|
|
144
|
+
|
|
145
|
+
- `SafehtmlPipe` (`| safeHtml`) — bypass DomSanitizer for trusted HTML. Never feed user input into this pipe.
|
|
146
|
+
|
|
147
|
+
## Claude Code support
|
|
148
|
+
|
|
149
|
+
The main repository ships a [Claude Code](https://claude.com/claude-code) skill (`xiri-ng-expert`) that teaches Claude the full API, patterns, and conventions. See the [main README](https://github.com/xiriframework/xiri-ng#claude-code-integration) for installation.
|
|
150
|
+
|
|
151
|
+
## Peer dependencies
|
|
61
152
|
|
|
62
153
|
- Angular 21+
|
|
63
154
|
- Angular Material 21+
|
|
64
|
-
-
|
|
65
|
-
- RxJS 7+
|
|
155
|
+
- Angular CDK 21+
|
|
156
|
+
- RxJS 7.8+
|
|
157
|
+
- `date-fns` 4+
|
|
158
|
+
- `@date-fns/tz` 1+
|
|
159
|
+
- `ngx-mat-select-search` 8+
|
|
160
|
+
- `material-symbols` ≥ 0.40
|
|
66
161
|
|
|
67
162
|
## License
|
|
68
163
|
|
|
@@ -5149,11 +5149,11 @@ class XiriTimelineComponent {
|
|
|
5149
5149
|
this.settings = input.required(...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
|
|
5150
5150
|
}
|
|
5151
5151
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: XiriTimelineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5152
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.2", type: XiriTimelineComponent, isStandalone: true, selector: "xiri-timeline", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"timeline\">\n\t@for (item of settings().items; track $index; let last = $last) {\n\t\t<div class=\"timeline-item\" [class.last]=\"last\">\n\t\t\t<div class=\"timeline-marker\">\n\t\t\t\t<div class=\"timeline-dot\" [class]=\"item.iconColor || 'primary'\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t
|
|
5152
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.2", type: XiriTimelineComponent, isStandalone: true, selector: "xiri-timeline", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"timeline\" [class.horizontal]=\"settings().orientation === 'horizontal'\">\n\t@for (item of settings().items; track $index; let last = $last; let first = $first) {\n\t\t<div class=\"timeline-item\" [class.last]=\"last\" [class.first]=\"first\">\n\t\t\t<div class=\"timeline-marker\">\n\t\t\t\t<div class=\"timeline-line line-before\"></div>\n\t\t\t\t<div class=\"timeline-dot\" [class]=\"item.iconColor || 'primary'\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"timeline-line line-after\"></div>\n\t\t\t</div>\n\t\t\t<div class=\"timeline-content\">\n\t\t\t\t<div class=\"timeline-header\">\n\t\t\t\t\t<span class=\"timeline-title\">{{ item.title }}</span>\n\t\t\t\t\t@if (item.datetime) {\n\t\t\t\t\t\t<span class=\"timeline-datetime\">{{ item.datetime }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t@if (item.description && settings().orientation !== 'horizontal') {\n\t\t\t\t\t<div class=\"timeline-description\">{{ item.description }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:block;container-type:inline-size}.timeline{display:flex;flex-direction:column}.timeline-item{display:flex;gap:var(--xiri-spacing-md);animation:fadeInUp var(--xiri-duration-normal, .3s) var(--xiri-easing-decelerate, cubic-bezier(0, 0, .2, 1)) both}.timeline-item:nth-child(1){animation-delay:0ms}.timeline-item:nth-child(2){animation-delay:50ms}.timeline-item:nth-child(3){animation-delay:.1s}.timeline-item:nth-child(4){animation-delay:.15s}.timeline-item:nth-child(5){animation-delay:.2s}.timeline-item:nth-child(6){animation-delay:.25s}.timeline-item:nth-child(7){animation-delay:.3s}.timeline-item:nth-child(8){animation-delay:.35s}.timeline-item:nth-child(9){animation-delay:.4s}.timeline-item:nth-child(10){animation-delay:.45s}.timeline-item:nth-child(11){animation-delay:.5s}.timeline-item:nth-child(12){animation-delay:.55s}.timeline-item:nth-child(13){animation-delay:.6s}.timeline-item:nth-child(14){animation-delay:.65s}.timeline-item:nth-child(15){animation-delay:.7s}.timeline-item:nth-child(16){animation-delay:.75s}.timeline-item:nth-child(17){animation-delay:.8s}.timeline-item:nth-child(18){animation-delay:.85s}.timeline-item:nth-child(19){animation-delay:.9s}.timeline-item:nth-child(20){animation-delay:.95s}.timeline-item .timeline-line.line-before,.timeline-item.last .timeline-line.line-after{display:none}.timeline-marker{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:2.5rem}.timeline-dot{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--primary, #2892D9);color:var(--on-primary, white)}.timeline-dot mat-icon{font-size:1.25rem;width:1.25rem;height:1.25rem}.timeline-dot.primary{background:var(--primary)}.timeline-dot.secondary{background:var(--secondary)}.timeline-dot.tertiary{background:var(--tertiary)}.timeline-dot.accent{background:var(--secondary)}.timeline-dot.warn,.timeline-dot.error{background:var(--error)}.timeline-dot.success{background:var(--color-success)}.timeline-dot.emerald{background:#2892d9}.timeline-dot.red{background:#e74c3c}.timeline-dot.yellow{background:#f1c40f}.timeline-dot.green{background:#2ecc71}.timeline-dot.blue{background:#3498db}.timeline-dot.purple{background:#9b59b6}.timeline-dot.gray{background:#95a5a6}.timeline-dot.lightgray{background:#bdc3c7}.timeline-dot.darkgray{background:#7f8c8d}.timeline-dot.orange{background:#e67e22}.timeline-dot.white{background:#fff}.timeline-dot.black{background:#000}.timeline-dot.inherit{background:inherit}.timeline-line{width:2px;flex:1;min-height:var(--xiri-spacing-lg);background:var(--mat-sys-outline-variant, rgba(0, 0, 0, .12))}.timeline-content{padding-bottom:var(--xiri-spacing-lg);flex:1;min-width:0}.timeline-header{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;min-height:2.5rem;align-content:center}.timeline-title{font-weight:500;font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}.timeline-datetime{font-size:var(--xiri-font-size-helper, .75rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.timeline-description{margin-top:.25rem;font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));line-height:1.5}@container (min-width: 481px){.timeline.horizontal{flex-direction:row}.timeline.horizontal .timeline-item{flex:1;min-width:0;flex-direction:column;align-items:center;gap:var(--xiri-spacing-xs);padding-bottom:0}.timeline.horizontal .timeline-item .timeline-line.line-before{display:block}.timeline.horizontal .timeline-item.first .timeline-line.line-before{visibility:hidden}.timeline.horizontal .timeline-item.last .timeline-line.line-after{display:block;visibility:hidden}.timeline.horizontal .timeline-content,.timeline.horizontal .timeline-header{display:contents}.timeline.horizontal .timeline-title{order:-2;text-align:center;min-height:2.5em;display:flex;align-items:center;justify-content:center;padding:0 var(--xiri-spacing-xs)}.timeline.horizontal .timeline-marker{order:-1;width:100%;flex-direction:row;align-items:center;gap:0}.timeline.horizontal .timeline-datetime{order:1;text-align:center;min-height:1.5em;display:flex;align-items:center;justify-content:center}.timeline.horizontal .timeline-line{flex:1;width:auto;height:2px;min-height:0}}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5153
5153
|
}
|
|
5154
5154
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: XiriTimelineComponent, decorators: [{
|
|
5155
5155
|
type: Component,
|
|
5156
|
-
args: [{ selector: 'xiri-timeline', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIcon], template: "<div class=\"timeline\">\n\t@for (item of settings().items; track $index; let last = $last) {\n\t\t<div class=\"timeline-item\" [class.last]=\"last\">\n\t\t\t<div class=\"timeline-marker\">\n\t\t\t\t<div class=\"timeline-dot\" [class]=\"item.iconColor || 'primary'\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t
|
|
5156
|
+
args: [{ selector: 'xiri-timeline', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatIcon], template: "<div class=\"timeline\" [class.horizontal]=\"settings().orientation === 'horizontal'\">\n\t@for (item of settings().items; track $index; let last = $last; let first = $first) {\n\t\t<div class=\"timeline-item\" [class.last]=\"last\" [class.first]=\"first\">\n\t\t\t<div class=\"timeline-marker\">\n\t\t\t\t<div class=\"timeline-line line-before\"></div>\n\t\t\t\t<div class=\"timeline-dot\" [class]=\"item.iconColor || 'primary'\">\n\t\t\t\t\t@if (item.icon) {\n\t\t\t\t\t\t<mat-icon>{{ item.icon }}</mat-icon>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"timeline-line line-after\"></div>\n\t\t\t</div>\n\t\t\t<div class=\"timeline-content\">\n\t\t\t\t<div class=\"timeline-header\">\n\t\t\t\t\t<span class=\"timeline-title\">{{ item.title }}</span>\n\t\t\t\t\t@if (item.datetime) {\n\t\t\t\t\t\t<span class=\"timeline-datetime\">{{ item.datetime }}</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t@if (item.description && settings().orientation !== 'horizontal') {\n\t\t\t\t\t<div class=\"timeline-description\">{{ item.description }}</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:block;container-type:inline-size}.timeline{display:flex;flex-direction:column}.timeline-item{display:flex;gap:var(--xiri-spacing-md);animation:fadeInUp var(--xiri-duration-normal, .3s) var(--xiri-easing-decelerate, cubic-bezier(0, 0, .2, 1)) both}.timeline-item:nth-child(1){animation-delay:0ms}.timeline-item:nth-child(2){animation-delay:50ms}.timeline-item:nth-child(3){animation-delay:.1s}.timeline-item:nth-child(4){animation-delay:.15s}.timeline-item:nth-child(5){animation-delay:.2s}.timeline-item:nth-child(6){animation-delay:.25s}.timeline-item:nth-child(7){animation-delay:.3s}.timeline-item:nth-child(8){animation-delay:.35s}.timeline-item:nth-child(9){animation-delay:.4s}.timeline-item:nth-child(10){animation-delay:.45s}.timeline-item:nth-child(11){animation-delay:.5s}.timeline-item:nth-child(12){animation-delay:.55s}.timeline-item:nth-child(13){animation-delay:.6s}.timeline-item:nth-child(14){animation-delay:.65s}.timeline-item:nth-child(15){animation-delay:.7s}.timeline-item:nth-child(16){animation-delay:.75s}.timeline-item:nth-child(17){animation-delay:.8s}.timeline-item:nth-child(18){animation-delay:.85s}.timeline-item:nth-child(19){animation-delay:.9s}.timeline-item:nth-child(20){animation-delay:.95s}.timeline-item .timeline-line.line-before,.timeline-item.last .timeline-line.line-after{display:none}.timeline-marker{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:2.5rem}.timeline-dot{width:2.5rem;height:2.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:var(--primary, #2892D9);color:var(--on-primary, white)}.timeline-dot mat-icon{font-size:1.25rem;width:1.25rem;height:1.25rem}.timeline-dot.primary{background:var(--primary)}.timeline-dot.secondary{background:var(--secondary)}.timeline-dot.tertiary{background:var(--tertiary)}.timeline-dot.accent{background:var(--secondary)}.timeline-dot.warn,.timeline-dot.error{background:var(--error)}.timeline-dot.success{background:var(--color-success)}.timeline-dot.emerald{background:#2892d9}.timeline-dot.red{background:#e74c3c}.timeline-dot.yellow{background:#f1c40f}.timeline-dot.green{background:#2ecc71}.timeline-dot.blue{background:#3498db}.timeline-dot.purple{background:#9b59b6}.timeline-dot.gray{background:#95a5a6}.timeline-dot.lightgray{background:#bdc3c7}.timeline-dot.darkgray{background:#7f8c8d}.timeline-dot.orange{background:#e67e22}.timeline-dot.white{background:#fff}.timeline-dot.black{background:#000}.timeline-dot.inherit{background:inherit}.timeline-line{width:2px;flex:1;min-height:var(--xiri-spacing-lg);background:var(--mat-sys-outline-variant, rgba(0, 0, 0, .12))}.timeline-content{padding-bottom:var(--xiri-spacing-lg);flex:1;min-width:0}.timeline-header{display:flex;align-items:baseline;gap:.75rem;flex-wrap:wrap;min-height:2.5rem;align-content:center}.timeline-title{font-weight:500;font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface, rgba(0, 0, 0, .87))}.timeline-datetime{font-size:var(--xiri-font-size-helper, .75rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6))}.timeline-description{margin-top:.25rem;font-size:var(--xiri-font-size-body, .875rem);color:var(--mat-sys-on-surface-variant, rgba(0, 0, 0, .6));line-height:1.5}@container (min-width: 481px){.timeline.horizontal{flex-direction:row}.timeline.horizontal .timeline-item{flex:1;min-width:0;flex-direction:column;align-items:center;gap:var(--xiri-spacing-xs);padding-bottom:0}.timeline.horizontal .timeline-item .timeline-line.line-before{display:block}.timeline.horizontal .timeline-item.first .timeline-line.line-before{visibility:hidden}.timeline.horizontal .timeline-item.last .timeline-line.line-after{display:block;visibility:hidden}.timeline.horizontal .timeline-content,.timeline.horizontal .timeline-header{display:contents}.timeline.horizontal .timeline-title{order:-2;text-align:center;min-height:2.5em;display:flex;align-items:center;justify-content:center;padding:0 var(--xiri-spacing-xs)}.timeline.horizontal .timeline-marker{order:-1;width:100%;flex-direction:row;align-items:center;gap:0}.timeline.horizontal .timeline-datetime{order:1;text-align:center;min-height:1.5em;display:flex;align-items:center;justify-content:center}.timeline.horizontal .timeline-line{flex:1;width:auto;height:2px;min-height:0}}\n"] }]
|
|
5157
5157
|
}], propDecorators: { settings: [{ type: i0.Input, args: [{ isSignal: true, alias: "settings", required: true }] }] } });
|
|
5158
5158
|
|
|
5159
5159
|
var timeline_component = /*#__PURE__*/Object.freeze({
|