ngx-strata 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -99,6 +99,30 @@ const baseIconConfigs = [
99
99
  {
100
100
  name: 'calendar',
101
101
  url: 'assets/icons/calendar.svg'
102
+ },
103
+ {
104
+ name: 'clock',
105
+ url: 'assets/icons/clock.svg'
106
+ },
107
+ {
108
+ name: 'upload',
109
+ url: 'assets/icons/upload.svg'
110
+ },
111
+ {
112
+ name: 'camera',
113
+ url: 'assets/icons/camera.svg'
114
+ },
115
+ {
116
+ name: 'image',
117
+ url: 'assets/icons/image.svg'
118
+ },
119
+ {
120
+ name: 'check-single',
121
+ url: 'assets/icons/check-single.svg'
122
+ },
123
+ {
124
+ name: 'check-double',
125
+ url: 'assets/icons/check-double.svg'
102
126
  }
103
127
  ];
104
128
 
@@ -1220,6 +1244,8 @@ class StrataOverlayDirective {
1220
1244
  ...(ngDevMode ? [{ debugName: "overlayOffset" }] : /* istanbul ignore next */ []));
1221
1245
  overlayFitViewport = input(true, /* @ts-ignore */
1222
1246
  ...(ngDevMode ? [{ debugName: "overlayFitViewport" }] : /* istanbul ignore next */ []));
1247
+ overlayTarget = input(null, /* @ts-ignore */
1248
+ ...(ngDevMode ? [{ debugName: "overlayTarget" }] : /* istanbul ignore next */ []));
1223
1249
  element = inject(ElementRef);
1224
1250
  viewContainerRef = inject(ViewContainerRef);
1225
1251
  config = inject(STRATA_CONFIG, { optional: true });
@@ -1228,12 +1254,25 @@ class StrataOverlayDirective {
1228
1254
  viewRef;
1229
1255
  ngOnChanges() {
1230
1256
  if (this.overlayOpen()) {
1231
- this.create();
1257
+ if (!this.overlayEl) {
1258
+ this.create();
1259
+ }
1260
+ else {
1261
+ if (this.cleanup) {
1262
+ this.cleanup();
1263
+ }
1264
+ const target = this.getTarget();
1265
+ this.cleanup = autoUpdate(target, this.overlayEl, () => this.updatePosition());
1266
+ this.updatePosition();
1267
+ }
1232
1268
  }
1233
1269
  else {
1234
1270
  this.destroy();
1235
1271
  }
1236
1272
  }
1273
+ getTarget() {
1274
+ return this.overlayTarget() ?? this.element.nativeElement;
1275
+ }
1237
1276
  async create() {
1238
1277
  if (this.overlayEl)
1239
1278
  return;
@@ -1241,7 +1280,8 @@ class StrataOverlayDirective {
1241
1280
  this.viewRef.detectChanges();
1242
1281
  this.overlayEl = this.viewRef.rootNodes[0];
1243
1282
  document.body.appendChild(this.overlayEl);
1244
- this.cleanup = autoUpdate(this.element.nativeElement, this.overlayEl, () => this.updatePosition());
1283
+ const target = this.getTarget();
1284
+ this.cleanup = autoUpdate(target, this.overlayEl, () => this.updatePosition());
1245
1285
  }
1246
1286
  async updatePosition() {
1247
1287
  if (!this.overlayEl)
@@ -1264,14 +1304,15 @@ class StrataOverlayDirective {
1264
1304
  else {
1265
1305
  this.overlayEl.style.maxHeight = '';
1266
1306
  }
1267
- const { x, y } = await computePosition(this.element.nativeElement, this.overlayEl, {
1307
+ const target = this.getTarget();
1308
+ const { x, y } = await computePosition(target, this.overlayEl, {
1268
1309
  placement: this.overlayPlacement(),
1269
1310
  strategy: 'fixed',
1270
1311
  middleware
1271
1312
  });
1272
1313
  if (!this.overlayEl)
1273
1314
  return;
1274
- const { width } = this.element.nativeElement.getBoundingClientRect();
1315
+ const width = 'getBoundingClientRect' in target ? target.getBoundingClientRect().width : 0;
1275
1316
  Object.assign(this.overlayEl.style, {
1276
1317
  position: 'fixed',
1277
1318
  left: `${x}px`,
@@ -1298,14 +1339,14 @@ class StrataOverlayDirective {
1298
1339
  this.destroy();
1299
1340
  }
1300
1341
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataOverlayDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1301
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.1", type: StrataOverlayDirective, isStandalone: true, selector: "[stOverlay]", inputs: { stOverlay: { classPropertyName: "stOverlay", publicName: "stOverlay", isSignal: true, isRequired: true, transformFunction: null }, overlayOpen: { classPropertyName: "overlayOpen", publicName: "overlayOpen", isSignal: true, isRequired: false, transformFunction: null }, overlayPlacement: { classPropertyName: "overlayPlacement", publicName: "overlayPlacement", isSignal: true, isRequired: false, transformFunction: null }, overlayOffset: { classPropertyName: "overlayOffset", publicName: "overlayOffset", isSignal: true, isRequired: false, transformFunction: null }, overlayFitViewport: { classPropertyName: "overlayFitViewport", publicName: "overlayFitViewport", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { overlayOpen: "overlayOpenChange" }, usesOnChanges: true, ngImport: i0 });
1342
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.1", type: StrataOverlayDirective, isStandalone: true, selector: "[stOverlay]", inputs: { stOverlay: { classPropertyName: "stOverlay", publicName: "stOverlay", isSignal: true, isRequired: true, transformFunction: null }, overlayOpen: { classPropertyName: "overlayOpen", publicName: "overlayOpen", isSignal: true, isRequired: false, transformFunction: null }, overlayPlacement: { classPropertyName: "overlayPlacement", publicName: "overlayPlacement", isSignal: true, isRequired: false, transformFunction: null }, overlayOffset: { classPropertyName: "overlayOffset", publicName: "overlayOffset", isSignal: true, isRequired: false, transformFunction: null }, overlayFitViewport: { classPropertyName: "overlayFitViewport", publicName: "overlayFitViewport", isSignal: true, isRequired: false, transformFunction: null }, overlayTarget: { classPropertyName: "overlayTarget", publicName: "overlayTarget", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { overlayOpen: "overlayOpenChange" }, usesOnChanges: true, ngImport: i0 });
1302
1343
  }
1303
1344
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataOverlayDirective, decorators: [{
1304
1345
  type: Directive,
1305
1346
  args: [{
1306
1347
  selector: '[stOverlay]'
1307
1348
  }]
1308
- }], propDecorators: { stOverlay: [{ type: i0.Input, args: [{ isSignal: true, alias: "stOverlay", required: true }] }], overlayOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayOpen", required: false }] }, { type: i0.Output, args: ["overlayOpenChange"] }], overlayPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayPlacement", required: false }] }], overlayOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayOffset", required: false }] }], overlayFitViewport: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayFitViewport", required: false }] }] } });
1349
+ }], propDecorators: { stOverlay: [{ type: i0.Input, args: [{ isSignal: true, alias: "stOverlay", required: true }] }], overlayOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayOpen", required: false }] }, { type: i0.Output, args: ["overlayOpenChange"] }], overlayPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayPlacement", required: false }] }], overlayOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayOffset", required: false }] }], overlayFitViewport: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayFitViewport", required: false }] }], overlayTarget: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayTarget", required: false }] }] } });
1309
1350
 
1310
1351
  class StrataActionMenuComponent {
1311
1352
  projectedButton = contentChild(StrataButtonDirective, { ...(ngDevMode ? { debugName: "projectedButton" } : /* istanbul ignore next */ {}), descendants: true,
@@ -1321,18 +1362,28 @@ class StrataActionMenuComponent {
1321
1362
  ...(ngDevMode ? [{ debugName: "buttonSize" }] : /* istanbul ignore next */ []));
1322
1363
  closeOnOutsideClick = input(true, /* @ts-ignore */
1323
1364
  ...(ngDevMode ? [{ debugName: "closeOnOutsideClick" }] : /* istanbul ignore next */ []));
1365
+ trigger = input(true, /* @ts-ignore */
1366
+ ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
1324
1367
  elementRef = inject(ElementRef);
1325
1368
  renderer = inject(Renderer2);
1326
1369
  menuOpen = signal(false, /* @ts-ignore */
1327
1370
  ...(ngDevMode ? [{ debugName: "menuOpen" }] : /* istanbul ignore next */ []));
1371
+ customTarget = signal(null, /* @ts-ignore */
1372
+ ...(ngDevMode ? [{ debugName: "customTarget" }] : /* istanbul ignore next */ []));
1373
+ contextMenuPlacement = signal(null, /* @ts-ignore */
1374
+ ...(ngDevMode ? [{ debugName: "contextMenuPlacement" }] : /* istanbul ignore next */ []));
1375
+ effectivePlacement = computed(() => {
1376
+ return this.contextMenuPlacement() ?? this.placement();
1377
+ }, /* @ts-ignore */
1378
+ ...(ngDevMode ? [{ debugName: "effectivePlacement" }] : /* istanbul ignore next */ []));
1328
1379
  constructor() {
1329
1380
  effect((onCleanup) => {
1330
1381
  const button = this.projectedButton() ?? this.defaultButton();
1331
- if (!button) {
1382
+ if (!button || !this.trigger()) {
1332
1383
  return;
1333
1384
  }
1334
1385
  const unlisten = this.renderer.listen(button.nativeElement, 'click', () => {
1335
- this.menuOpen.set(!this.menuOpen());
1386
+ this.toggle();
1336
1387
  });
1337
1388
  onCleanup(() => {
1338
1389
  unlisten();
@@ -1352,7 +1403,20 @@ class StrataActionMenuComponent {
1352
1403
  if (hostEl.contains(target) || (overlayEl && overlayEl.contains(target))) {
1353
1404
  return;
1354
1405
  }
1355
- this.menuOpen.set(false);
1406
+ this.close();
1407
+ });
1408
+ onCleanup(() => {
1409
+ unlisten();
1410
+ });
1411
+ });
1412
+ effect((onCleanup) => {
1413
+ if (!this.menuOpen()) {
1414
+ return;
1415
+ }
1416
+ const unlisten = this.renderer.listen('document', 'keydown', (event) => {
1417
+ if (event.key === 'Escape') {
1418
+ this.close();
1419
+ }
1356
1420
  });
1357
1421
  onCleanup(() => {
1358
1422
  unlisten();
@@ -1361,7 +1425,7 @@ class StrataActionMenuComponent {
1361
1425
  effect((onCleanup) => {
1362
1426
  const subs = this.actionMenuItems().map((item) => item.menuItemClicked.subscribe((shouldClose) => {
1363
1427
  if (shouldClose) {
1364
- this.menuOpen.set(false);
1428
+ this.close();
1365
1429
  }
1366
1430
  }));
1367
1431
  onCleanup(() => {
@@ -1369,18 +1433,95 @@ class StrataActionMenuComponent {
1369
1433
  });
1370
1434
  });
1371
1435
  }
1436
+ open() {
1437
+ this.customTarget.set(null);
1438
+ this.contextMenuPlacement.set(null);
1439
+ this.menuOpen.set(true);
1440
+ }
1441
+ close() {
1442
+ this.menuOpen.set(false);
1443
+ this.customTarget.set(null);
1444
+ this.contextMenuPlacement.set(null);
1445
+ }
1446
+ toggle() {
1447
+ if (this.menuOpen()) {
1448
+ this.close();
1449
+ }
1450
+ else {
1451
+ this.open();
1452
+ }
1453
+ }
1454
+ openAt(position, placement = 'bottom-start') {
1455
+ const clientX = 'clientX' in position ? position.clientX : position.x;
1456
+ const clientY = 'clientY' in position ? position.clientY : position.y;
1457
+ const virtualElement = {
1458
+ getBoundingClientRect() {
1459
+ return {
1460
+ x: clientX,
1461
+ y: clientY,
1462
+ top: clientY,
1463
+ left: clientX,
1464
+ bottom: clientY,
1465
+ right: clientX,
1466
+ width: 0,
1467
+ height: 0
1468
+ };
1469
+ }
1470
+ };
1471
+ this.customTarget.set(virtualElement);
1472
+ this.contextMenuPlacement.set(placement);
1473
+ this.menuOpen.set(true);
1474
+ }
1372
1475
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataActionMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1373
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataActionMenuComponent, isStandalone: true, selector: "st-action-menu", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, buttonSize: { classPropertyName: "buttonSize", publicName: "buttonSize", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutsideClick: { classPropertyName: "closeOnOutsideClick", publicName: "closeOnOutsideClick", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "projectedButton", first: true, predicate: StrataButtonDirective, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "actionMenuItems", predicate: StrataActionMenuItemComponent, isSignal: true }], viewQueries: [{ propertyName: "defaultButton", first: true, predicate: StrataButtonDirective, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "overlayDirective", first: true, predicate: StrataOverlayDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div [stOverlay]=\"menu\" [overlayOpen]=\"menuOpen()\" [overlayPlacement]=\"placement()\">\n <ng-content select=\"button[stButton]\"></ng-content>\n @if (!projectedButton()) {\n <button stButton [size]=\"buttonSize()\"><st-icon name=\"more\"></st-icon></button>\n }\n</div>\n\n<ng-template #menu>\n <st-card [padding]=\"false\" class=\"action-menu-card\"><ng-content select=\"st-action-menu-item\"></ng-content></st-card>\n</ng-template>\n", styles: ["st-card{width:fit-content}\n"], dependencies: [{ kind: "component", type: StrataCardComponent, selector: "st-card", inputs: ["elevated", "selectable", "padding", "variant"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataButtonDirective, selector: "[stButton]", inputs: ["variant", "size", "fullWidth"] }] });
1476
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataActionMenuComponent, isStandalone: true, selector: "st-action-menu", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, buttonSize: { classPropertyName: "buttonSize", publicName: "buttonSize", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutsideClick: { classPropertyName: "closeOnOutsideClick", publicName: "closeOnOutsideClick", isSignal: true, isRequired: false, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "projectedButton", first: true, predicate: StrataButtonDirective, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "actionMenuItems", predicate: StrataActionMenuItemComponent, isSignal: true }], viewQueries: [{ propertyName: "defaultButton", first: true, predicate: StrataButtonDirective, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "overlayDirective", first: true, predicate: StrataOverlayDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n [stOverlay]=\"menu\"\n [overlayOpen]=\"menuOpen()\"\n [overlayPlacement]=\"effectivePlacement()\"\n [overlayTarget]=\"customTarget()\">\n @if (trigger()) {\n <ng-content select=\"button[stButton]\"></ng-content>\n @if (!projectedButton()) {\n <button stButton [size]=\"buttonSize()\"><st-icon name=\"more\"></st-icon></button>\n }\n }\n</div>\n\n<ng-template #menu>\n <st-card [padding]=\"false\" class=\"action-menu-card\"><ng-content select=\"st-action-menu-item\"></ng-content></st-card>\n</ng-template>\n", styles: ["st-card{width:fit-content}\n"], dependencies: [{ kind: "component", type: StrataCardComponent, selector: "st-card", inputs: ["elevated", "selectable", "padding", "variant"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport", "overlayTarget"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataButtonDirective, selector: "[stButton]", inputs: ["variant", "size", "fullWidth"] }] });
1374
1477
  }
1375
1478
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataActionMenuComponent, decorators: [{
1376
1479
  type: Component,
1377
- args: [{ selector: 'st-action-menu', imports: [StrataCardComponent, StrataOverlayDirective, StrataIconComponent, StrataButtonDirective], template: "<div [stOverlay]=\"menu\" [overlayOpen]=\"menuOpen()\" [overlayPlacement]=\"placement()\">\n <ng-content select=\"button[stButton]\"></ng-content>\n @if (!projectedButton()) {\n <button stButton [size]=\"buttonSize()\"><st-icon name=\"more\"></st-icon></button>\n }\n</div>\n\n<ng-template #menu>\n <st-card [padding]=\"false\" class=\"action-menu-card\"><ng-content select=\"st-action-menu-item\"></ng-content></st-card>\n</ng-template>\n", styles: ["st-card{width:fit-content}\n"] }]
1480
+ args: [{ selector: 'st-action-menu', imports: [StrataCardComponent, StrataOverlayDirective, StrataIconComponent, StrataButtonDirective], template: "<div\n [stOverlay]=\"menu\"\n [overlayOpen]=\"menuOpen()\"\n [overlayPlacement]=\"effectivePlacement()\"\n [overlayTarget]=\"customTarget()\">\n @if (trigger()) {\n <ng-content select=\"button[stButton]\"></ng-content>\n @if (!projectedButton()) {\n <button stButton [size]=\"buttonSize()\"><st-icon name=\"more\"></st-icon></button>\n }\n }\n</div>\n\n<ng-template #menu>\n <st-card [padding]=\"false\" class=\"action-menu-card\"><ng-content select=\"st-action-menu-item\"></ng-content></st-card>\n</ng-template>\n", styles: ["st-card{width:fit-content}\n"] }]
1378
1481
  }], ctorParameters: () => [], propDecorators: { projectedButton: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrataButtonDirective), { ...{
1379
1482
  descendants: true,
1380
1483
  read: ElementRef
1381
1484
  }, isSignal: true }] }], defaultButton: [{ type: i0.ViewChild, args: [i0.forwardRef(() => StrataButtonDirective), { ...{
1382
1485
  read: ElementRef
1383
- }, isSignal: true }] }], overlayDirective: [{ type: i0.ViewChild, args: [i0.forwardRef(() => StrataOverlayDirective), { isSignal: true }] }], actionMenuItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrataActionMenuItemComponent), { isSignal: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], buttonSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonSize", required: false }] }], closeOnOutsideClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutsideClick", required: false }] }] } });
1486
+ }, isSignal: true }] }], overlayDirective: [{ type: i0.ViewChild, args: [i0.forwardRef(() => StrataOverlayDirective), { isSignal: true }] }], actionMenuItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrataActionMenuItemComponent), { isSignal: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], buttonSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonSize", required: false }] }], closeOnOutsideClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutsideClick", required: false }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }] } });
1487
+
1488
+ class StrataContextMenuDirective {
1489
+ stContextMenu = input.required(/* @ts-ignore */
1490
+ ...(ngDevMode ? [{ debugName: "stContextMenu" }] : /* istanbul ignore next */ []));
1491
+ stContextMenuDisabled = input(false, /* @ts-ignore */
1492
+ ...(ngDevMode ? [{ debugName: "stContextMenuDisabled" }] : /* istanbul ignore next */ []));
1493
+ stContextMenuPlacement = input('bottom-start', /* @ts-ignore */
1494
+ ...(ngDevMode ? [{ debugName: "stContextMenuPlacement" }] : /* istanbul ignore next */ []));
1495
+ contextMenuOpened = output();
1496
+ elementRef = inject(ElementRef);
1497
+ renderer = inject(Renderer2);
1498
+ unlisten;
1499
+ ngOnInit() {
1500
+ this.unlisten = this.renderer.listen(this.elementRef.nativeElement, 'contextmenu', (event) => {
1501
+ const menu = this.stContextMenu();
1502
+ if (this.stContextMenuDisabled() || !menu) {
1503
+ return;
1504
+ }
1505
+ event.preventDefault();
1506
+ event.stopPropagation();
1507
+ this.contextMenuOpened.emit(event);
1508
+ menu.openAt(event, this.stContextMenuPlacement());
1509
+ });
1510
+ }
1511
+ ngOnDestroy() {
1512
+ if (this.unlisten) {
1513
+ this.unlisten();
1514
+ }
1515
+ }
1516
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataContextMenuDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1517
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.1", type: StrataContextMenuDirective, isStandalone: true, selector: "[stContextMenu]", inputs: { stContextMenu: { classPropertyName: "stContextMenu", publicName: "stContextMenu", isSignal: true, isRequired: true, transformFunction: null }, stContextMenuDisabled: { classPropertyName: "stContextMenuDisabled", publicName: "stContextMenuDisabled", isSignal: true, isRequired: false, transformFunction: null }, stContextMenuPlacement: { classPropertyName: "stContextMenuPlacement", publicName: "stContextMenuPlacement", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contextMenuOpened: "contextMenuOpened" }, ngImport: i0 });
1518
+ }
1519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataContextMenuDirective, decorators: [{
1520
+ type: Directive,
1521
+ args: [{
1522
+ selector: '[stContextMenu]'
1523
+ }]
1524
+ }], propDecorators: { stContextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "stContextMenu", required: true }] }], stContextMenuDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "stContextMenuDisabled", required: false }] }], stContextMenuPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "stContextMenuPlacement", required: false }] }], contextMenuOpened: [{ type: i0.Output, args: ["contextMenuOpened"] }] } });
1384
1525
 
1385
1526
  class StrataTextStackComponent {
1386
1527
  overflow = input('truncate', /* @ts-ignore */
@@ -1652,7 +1793,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
1652
1793
  }, template: "<ng-content select=\"[stButton], st-divider\" #buttons></ng-content>\n" }]
1653
1794
  }], propDecorators: { justification: [{ type: i0.Input, args: [{ isSignal: true, alias: "justification", required: false }] }] } });
1654
1795
 
1655
- class StrataTimePickerComponent {
1796
+ class StrataChatComponent {
1797
+ spacing = input('comfortable', /* @ts-ignore */
1798
+ ...(ngDevMode ? [{ debugName: "spacing" }] : /* istanbul ignore next */ []));
1799
+ hostClasses = computed(() => `st-chat ${this.spacing()}`, /* @ts-ignore */
1800
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1801
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1802
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.1", type: StrataChatComponent, isStandalone: true, selector: "st-chat", inputs: { spacing: { classPropertyName: "spacing", publicName: "spacing", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: "<ng-content />\n", styles: [":host{--st-chat-bg: transparent;--st-chat-gap: var(--st-space-3);--st-chat-gap-compact: var(--st-space-1);display:flex;flex-direction:column;width:100%;max-width:100%;min-width:0;box-sizing:border-box;background-color:var(--st-chat-bg);gap:var(--st-chat-gap)}:host>*{min-width:0;max-width:100%;box-sizing:border-box}:host.compact{gap:var(--st-chat-gap-compact);--st-chat-message-padding: var(--st-space-1) var(--st-space-2)}:host.comfortable{gap:var(--st-chat-gap)}\n"] });
1803
+ }
1804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatComponent, decorators: [{
1805
+ type: Component,
1806
+ args: [{ selector: 'st-chat', imports: [], host: {
1807
+ '[class]': 'hostClasses()'
1808
+ }, template: "<ng-content />\n", styles: [":host{--st-chat-bg: transparent;--st-chat-gap: var(--st-space-3);--st-chat-gap-compact: var(--st-space-1);display:flex;flex-direction:column;width:100%;max-width:100%;min-width:0;box-sizing:border-box;background-color:var(--st-chat-bg);gap:var(--st-chat-gap)}:host>*{min-width:0;max-width:100%;box-sizing:border-box}:host.compact{gap:var(--st-chat-gap-compact);--st-chat-message-padding: var(--st-space-1) var(--st-space-2)}:host.comfortable{gap:var(--st-chat-gap)}\n"] }]
1809
+ }], propDecorators: { spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }] } });
1810
+
1811
+ class StrataChatMessageComponent {
1812
+ variant = input('incoming', /* @ts-ignore */
1813
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
1814
+ timestamp = input(null, /* @ts-ignore */
1815
+ ...(ngDevMode ? [{ debugName: "timestamp" }] : /* istanbul ignore next */ []));
1816
+ status = input(null, /* @ts-ignore */
1817
+ ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
1818
+ showAvatar = input(true, { ...(ngDevMode ? { debugName: "showAvatar" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1819
+ position = input('single', /* @ts-ignore */
1820
+ ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
1821
+ groupVariant = signal(null, /* @ts-ignore */
1822
+ ...(ngDevMode ? [{ debugName: "groupVariant" }] : /* istanbul ignore next */ []));
1823
+ groupPosition = signal(null, /* @ts-ignore */
1824
+ ...(ngDevMode ? [{ debugName: "groupPosition" }] : /* istanbul ignore next */ []));
1825
+ groupShowAvatar = signal(null, /* @ts-ignore */
1826
+ ...(ngDevMode ? [{ debugName: "groupShowAvatar" }] : /* istanbul ignore next */ []));
1827
+ groupPreserveAvatarSpace = signal(false, /* @ts-ignore */
1828
+ ...(ngDevMode ? [{ debugName: "groupPreserveAvatarSpace" }] : /* istanbul ignore next */ []));
1829
+ effectiveVariant = computed(() => this.groupVariant() ?? this.variant(), /* @ts-ignore */
1830
+ ...(ngDevMode ? [{ debugName: "effectiveVariant" }] : /* istanbul ignore next */ []));
1831
+ effectivePosition = computed(() => this.groupPosition() ?? this.position(), /* @ts-ignore */
1832
+ ...(ngDevMode ? [{ debugName: "effectivePosition" }] : /* istanbul ignore next */ []));
1833
+ effectiveShowAvatar = computed(() => this.groupShowAvatar() ?? this.showAvatar(), /* @ts-ignore */
1834
+ ...(ngDevMode ? [{ debugName: "effectiveShowAvatar" }] : /* istanbul ignore next */ []));
1835
+ hostClasses = computed(() => {
1836
+ const classes = [
1837
+ 'st-chat-message',
1838
+ this.effectiveVariant(),
1839
+ this.effectivePosition()
1840
+ ];
1841
+ return classes.join(' ');
1842
+ }, /* @ts-ignore */
1843
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1844
+ setGroupConfig(variant, position, showAvatar, preserveAvatarSpace) {
1845
+ this.groupVariant.set(variant);
1846
+ this.groupPosition.set(position);
1847
+ this.groupShowAvatar.set(showAvatar);
1848
+ this.groupPreserveAvatarSpace.set(preserveAvatarSpace);
1849
+ }
1850
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1851
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataChatMessageComponent, isStandalone: true, selector: "st-chat-message", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, timestamp: { classPropertyName: "timestamp", publicName: "timestamp", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, showAvatar: { classPropertyName: "showAvatar", publicName: "showAvatar", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: "<div class=\"st-chat-message-container\">\n @if (effectiveVariant() === 'incoming') {\n <div\n class=\"st-chat-message-avatar\"\n [class.hidden]=\"!effectiveShowAvatar()\"\n [class.preserve-space]=\"groupPreserveAvatarSpace()\"\n >\n <ng-content select=\"[slot=avatar]\" />\n </div>\n }\n\n <div class=\"st-chat-message-body\">\n <div class=\"st-chat-message-bubble\">\n <div class=\"st-chat-message-media\">\n <ng-content select=\"[slot=media]\" />\n </div>\n <div class=\"st-chat-message-text\">\n <ng-content />\n </div>\n </div>\n\n <div class=\"st-chat-message-footer\">\n @if (timestamp()) {\n <span class=\"st-chat-message-timestamp\">{{ timestamp() }}</span>\n }\n @if (effectiveVariant() === 'outgoing' && status()) {\n <span class=\"st-chat-message-status\" [class]=\"'status-' + status()\">\n @if (status() === 'sent') {\n <st-icon name=\"check-single\" size=\"xs\"></st-icon>\n } @else if (status() === 'delivered' || status() === 'read') {\n <st-icon name=\"check-double\" size=\"xs\"></st-icon>\n }\n </span>\n }\n <ng-content select=\"[slot=footer]\" />\n </div>\n </div>\n\n @if (effectiveVariant() === 'outgoing') {\n <div\n class=\"st-chat-message-avatar\"\n [class.hidden]=\"!effectiveShowAvatar()\"\n [class.preserve-space]=\"groupPreserveAvatarSpace()\"\n >\n <ng-content select=\"[slot=avatar]\" />\n </div>\n }\n</div>\n", styles: [":host{--st-chat-message-bg-incoming: var(--st-color-bg-raised);--st-chat-message-color-incoming: var(--st-color-text-primary);--st-chat-message-border-incoming: var(--st-color-border-subtle);--st-chat-message-bg-outgoing: var(--st-color-control-primary-bg);--st-chat-message-color-outgoing: var(--st-color-control-primary-text);--st-chat-message-border-outgoing: transparent;--st-chat-message-radius: var(--st-border-radius-xl);--st-chat-message-radius-sm: var(--st-border-radius-sm);--st-chat-message-max-width: 75%;--st-chat-message-padding: var(--st-space-2) var(--st-space-3);--st-chat-avatar-size: 32px;--st-chat-avatar-gap: var(--st-space-2);--st-chat-status-read-color: var(--st-color-accent-default);display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box}:host .st-chat-message-container{display:flex;align-items:flex-end;gap:var(--st-chat-avatar-gap);width:100%;max-width:100%;min-width:0;box-sizing:border-box}:host .st-chat-message-avatar{flex-shrink:0;display:flex;align-items:flex-end;width:var(--st-chat-avatar-size);min-width:var(--st-chat-avatar-size)}:host .st-chat-message-avatar:empty:not(.preserve-space){display:none}:host .st-chat-message-avatar.hidden{visibility:hidden}:host .st-chat-message-body{display:flex;flex-direction:column;max-width:var(--st-chat-message-max-width);min-width:0}:host .st-chat-message-bubble{padding:var(--st-chat-message-padding);font-size:var(--st-font-sm);line-height:1.45;word-break:break-word;overflow-wrap:anywhere;max-width:100%;min-width:0;box-sizing:border-box;overflow:hidden;transition:background-color var(--st-transition-normal),border-color var(--st-transition-normal)}:host .st-chat-message-media{overflow:hidden;border-radius:calc(var(--st-chat-message-radius) - 2px);margin-bottom:var(--st-space-1);width:100%;max-width:100%}:host .st-chat-message-media:empty{display:none;margin-bottom:0}:host .st-chat-message-media img,:host .st-chat-message-media video{display:block;width:100%;max-width:100%;height:auto;max-height:280px;object-fit:cover;border-radius:inherit}:host .st-chat-message-text:empty{display:none}:host .st-chat-message-footer{display:flex;align-items:center;gap:var(--st-space-1);font-size:var(--st-font-xs);color:var(--st-color-text-tertiary);margin-top:2px;-webkit-user-select:none;user-select:none}:host .st-chat-message-footer:empty{display:none}:host .st-chat-message-footer .st-chat-message-timestamp{font-variant-numeric:tabular-nums}:host .st-chat-message-footer .st-chat-message-status{display:inline-flex;align-items:center;line-height:1}:host .st-chat-message-footer .st-chat-message-status.status-read{color:var(--st-chat-status-read-color)}:host.incoming .st-chat-message-container{justify-content:flex-start}:host.incoming .st-chat-message-body{align-items:flex-start}:host.incoming .st-chat-message-bubble{background-color:var(--st-chat-message-bg-incoming);color:var(--st-chat-message-color-incoming);border:1px solid var(--st-chat-message-border-incoming)}:host.incoming .st-chat-message-footer{justify-content:flex-start}:host.incoming.single .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm)}:host.incoming.first .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm)}:host.incoming.middle .st-chat-message-bubble{border-radius:var(--st-chat-message-radius-sm) var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm)}:host.incoming.last .st-chat-message-bubble{border-radius:var(--st-chat-message-radius-sm) var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-border-radius-xs)}:host.outgoing .st-chat-message-container{justify-content:flex-end}:host.outgoing .st-chat-message-body{align-items:flex-end}:host.outgoing .st-chat-message-bubble{background-color:var(--st-chat-message-bg-outgoing);color:var(--st-chat-message-color-outgoing);border:1px solid var(--st-chat-message-border-outgoing)}:host.outgoing .st-chat-message-footer{justify-content:flex-end}:host.outgoing.single .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm) var(--st-chat-message-radius)}:host.outgoing.first .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm) var(--st-chat-message-radius)}:host.outgoing.middle .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius-sm) var(--st-chat-message-radius-sm) var(--st-chat-message-radius)}:host.outgoing.last .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius-sm) var(--st-border-radius-xs) var(--st-chat-message-radius)}\n"], dependencies: [{ kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }] });
1852
+ }
1853
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatMessageComponent, decorators: [{
1854
+ type: Component,
1855
+ args: [{ selector: 'st-chat-message', imports: [StrataIconComponent], host: {
1856
+ '[class]': 'hostClasses()'
1857
+ }, template: "<div class=\"st-chat-message-container\">\n @if (effectiveVariant() === 'incoming') {\n <div\n class=\"st-chat-message-avatar\"\n [class.hidden]=\"!effectiveShowAvatar()\"\n [class.preserve-space]=\"groupPreserveAvatarSpace()\"\n >\n <ng-content select=\"[slot=avatar]\" />\n </div>\n }\n\n <div class=\"st-chat-message-body\">\n <div class=\"st-chat-message-bubble\">\n <div class=\"st-chat-message-media\">\n <ng-content select=\"[slot=media]\" />\n </div>\n <div class=\"st-chat-message-text\">\n <ng-content />\n </div>\n </div>\n\n <div class=\"st-chat-message-footer\">\n @if (timestamp()) {\n <span class=\"st-chat-message-timestamp\">{{ timestamp() }}</span>\n }\n @if (effectiveVariant() === 'outgoing' && status()) {\n <span class=\"st-chat-message-status\" [class]=\"'status-' + status()\">\n @if (status() === 'sent') {\n <st-icon name=\"check-single\" size=\"xs\"></st-icon>\n } @else if (status() === 'delivered' || status() === 'read') {\n <st-icon name=\"check-double\" size=\"xs\"></st-icon>\n }\n </span>\n }\n <ng-content select=\"[slot=footer]\" />\n </div>\n </div>\n\n @if (effectiveVariant() === 'outgoing') {\n <div\n class=\"st-chat-message-avatar\"\n [class.hidden]=\"!effectiveShowAvatar()\"\n [class.preserve-space]=\"groupPreserveAvatarSpace()\"\n >\n <ng-content select=\"[slot=avatar]\" />\n </div>\n }\n</div>\n", styles: [":host{--st-chat-message-bg-incoming: var(--st-color-bg-raised);--st-chat-message-color-incoming: var(--st-color-text-primary);--st-chat-message-border-incoming: var(--st-color-border-subtle);--st-chat-message-bg-outgoing: var(--st-color-control-primary-bg);--st-chat-message-color-outgoing: var(--st-color-control-primary-text);--st-chat-message-border-outgoing: transparent;--st-chat-message-radius: var(--st-border-radius-xl);--st-chat-message-radius-sm: var(--st-border-radius-sm);--st-chat-message-max-width: 75%;--st-chat-message-padding: var(--st-space-2) var(--st-space-3);--st-chat-avatar-size: 32px;--st-chat-avatar-gap: var(--st-space-2);--st-chat-status-read-color: var(--st-color-accent-default);display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box}:host .st-chat-message-container{display:flex;align-items:flex-end;gap:var(--st-chat-avatar-gap);width:100%;max-width:100%;min-width:0;box-sizing:border-box}:host .st-chat-message-avatar{flex-shrink:0;display:flex;align-items:flex-end;width:var(--st-chat-avatar-size);min-width:var(--st-chat-avatar-size)}:host .st-chat-message-avatar:empty:not(.preserve-space){display:none}:host .st-chat-message-avatar.hidden{visibility:hidden}:host .st-chat-message-body{display:flex;flex-direction:column;max-width:var(--st-chat-message-max-width);min-width:0}:host .st-chat-message-bubble{padding:var(--st-chat-message-padding);font-size:var(--st-font-sm);line-height:1.45;word-break:break-word;overflow-wrap:anywhere;max-width:100%;min-width:0;box-sizing:border-box;overflow:hidden;transition:background-color var(--st-transition-normal),border-color var(--st-transition-normal)}:host .st-chat-message-media{overflow:hidden;border-radius:calc(var(--st-chat-message-radius) - 2px);margin-bottom:var(--st-space-1);width:100%;max-width:100%}:host .st-chat-message-media:empty{display:none;margin-bottom:0}:host .st-chat-message-media img,:host .st-chat-message-media video{display:block;width:100%;max-width:100%;height:auto;max-height:280px;object-fit:cover;border-radius:inherit}:host .st-chat-message-text:empty{display:none}:host .st-chat-message-footer{display:flex;align-items:center;gap:var(--st-space-1);font-size:var(--st-font-xs);color:var(--st-color-text-tertiary);margin-top:2px;-webkit-user-select:none;user-select:none}:host .st-chat-message-footer:empty{display:none}:host .st-chat-message-footer .st-chat-message-timestamp{font-variant-numeric:tabular-nums}:host .st-chat-message-footer .st-chat-message-status{display:inline-flex;align-items:center;line-height:1}:host .st-chat-message-footer .st-chat-message-status.status-read{color:var(--st-chat-status-read-color)}:host.incoming .st-chat-message-container{justify-content:flex-start}:host.incoming .st-chat-message-body{align-items:flex-start}:host.incoming .st-chat-message-bubble{background-color:var(--st-chat-message-bg-incoming);color:var(--st-chat-message-color-incoming);border:1px solid var(--st-chat-message-border-incoming)}:host.incoming .st-chat-message-footer{justify-content:flex-start}:host.incoming.single .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm)}:host.incoming.first .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm)}:host.incoming.middle .st-chat-message-bubble{border-radius:var(--st-chat-message-radius-sm) var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm)}:host.incoming.last .st-chat-message-bubble{border-radius:var(--st-chat-message-radius-sm) var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-border-radius-xs)}:host.outgoing .st-chat-message-container{justify-content:flex-end}:host.outgoing .st-chat-message-body{align-items:flex-end}:host.outgoing .st-chat-message-bubble{background-color:var(--st-chat-message-bg-outgoing);color:var(--st-chat-message-color-outgoing);border:1px solid var(--st-chat-message-border-outgoing)}:host.outgoing .st-chat-message-footer{justify-content:flex-end}:host.outgoing.single .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm) var(--st-chat-message-radius)}:host.outgoing.first .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius) var(--st-chat-message-radius-sm) var(--st-chat-message-radius)}:host.outgoing.middle .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius-sm) var(--st-chat-message-radius-sm) var(--st-chat-message-radius)}:host.outgoing.last .st-chat-message-bubble{border-radius:var(--st-chat-message-radius) var(--st-chat-message-radius-sm) var(--st-border-radius-xs) var(--st-chat-message-radius)}\n"] }]
1858
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], timestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "timestamp", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], showAvatar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAvatar", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }] } });
1859
+
1860
+ class StrataChatGroupComponent {
1861
+ variant = input('incoming', /* @ts-ignore */
1862
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
1863
+ messages = contentChildren(StrataChatMessageComponent, { ...(ngDevMode ? { debugName: "messages" } : /* istanbul ignore next */ {}), descendants: true });
1864
+ hostClasses = computed(() => `st-chat-group ${this.variant()}`, /* @ts-ignore */
1865
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1866
+ constructor() {
1867
+ effect(() => {
1868
+ const items = this.messages();
1869
+ const variant = this.variant();
1870
+ const count = items.length;
1871
+ items.forEach((msg, index) => {
1872
+ if (count === 1) {
1873
+ msg.setGroupConfig(variant, 'single', true, false);
1874
+ return;
1875
+ }
1876
+ const isFirst = index === 0;
1877
+ const isLast = index === count - 1;
1878
+ const position = isFirst ? 'first' : isLast ? 'last' : 'middle';
1879
+ const showAvatar = isLast;
1880
+ const preserveAvatarSpace = variant === 'incoming' && !isLast;
1881
+ msg.setGroupConfig(variant, position, showAvatar, preserveAvatarSpace);
1882
+ });
1883
+ });
1884
+ }
1885
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1886
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.1", type: StrataChatGroupComponent, isStandalone: true, selector: "st-chat-group", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, queries: [{ propertyName: "messages", predicate: StrataChatMessageComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-content />\n", styles: [":host{--st-chat-group-gap: var(--st-space-1);display:flex;flex-direction:column;width:100%;max-width:100%;min-width:0;box-sizing:border-box;gap:var(--st-chat-group-gap)}:host>*{min-width:0;max-width:100%;box-sizing:border-box}\n"] });
1887
+ }
1888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatGroupComponent, decorators: [{
1889
+ type: Component,
1890
+ args: [{ selector: 'st-chat-group', imports: [], host: {
1891
+ '[class]': 'hostClasses()'
1892
+ }, template: "<ng-content />\n", styles: [":host{--st-chat-group-gap: var(--st-space-1);display:flex;flex-direction:column;width:100%;max-width:100%;min-width:0;box-sizing:border-box;gap:var(--st-chat-group-gap)}:host>*{min-width:0;max-width:100%;box-sizing:border-box}\n"] }]
1893
+ }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], messages: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrataChatMessageComponent), { ...{ descendants: true }, isSignal: true }] }] } });
1894
+
1895
+ class StrataChatSeparatorComponent {
1896
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatSeparatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1897
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.1", type: StrataChatSeparatorComponent, isStandalone: true, selector: "st-chat-separator", host: { classAttribute: "st-chat-separator" }, ngImport: i0, template: "<div class=\"st-chat-separator-line\"></div>\n<div class=\"st-chat-separator-content\">\n <ng-content />\n</div>\n<div class=\"st-chat-separator-line\"></div>\n", styles: [":host{--st-chat-separator-color: var(--st-color-text-tertiary);--st-chat-separator-line-color: var(--st-color-border-subtle);--st-chat-separator-font-size: var(--st-font-xs);display:flex;align-items:center;justify-content:center;gap:var(--st-space-3);width:100%;box-sizing:border-box}:host .st-chat-separator-line{flex:1;height:1px;background-color:var(--st-chat-separator-line-color)}:host .st-chat-separator-content{display:inline-flex;align-items:center;font-size:var(--st-chat-separator-font-size);color:var(--st-chat-separator-color);white-space:nowrap;font-weight:var(--st-font-weight-medium)}\n"] });
1898
+ }
1899
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatSeparatorComponent, decorators: [{
1900
+ type: Component,
1901
+ args: [{ selector: 'st-chat-separator', imports: [], host: {
1902
+ class: 'st-chat-separator'
1903
+ }, template: "<div class=\"st-chat-separator-line\"></div>\n<div class=\"st-chat-separator-content\">\n <ng-content />\n</div>\n<div class=\"st-chat-separator-line\"></div>\n", styles: [":host{--st-chat-separator-color: var(--st-color-text-tertiary);--st-chat-separator-line-color: var(--st-color-border-subtle);--st-chat-separator-font-size: var(--st-font-xs);display:flex;align-items:center;justify-content:center;gap:var(--st-space-3);width:100%;box-sizing:border-box}:host .st-chat-separator-line{flex:1;height:1px;background-color:var(--st-chat-separator-line-color)}:host .st-chat-separator-content{display:inline-flex;align-items:center;font-size:var(--st-chat-separator-font-size);color:var(--st-chat-separator-color);white-space:nowrap;font-weight:var(--st-font-weight-medium)}\n"] }]
1904
+ }] });
1905
+
1906
+ class StrataChatTypingComponent {
1907
+ variant = input('incoming', /* @ts-ignore */
1908
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
1909
+ ariaLabel = input('Typing', /* @ts-ignore */
1910
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1911
+ hostClasses = computed(() => `st-chat-typing ${this.variant()}`, /* @ts-ignore */
1912
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1913
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatTypingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1914
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataChatTypingComponent, isStandalone: true, selector: "st-chat-typing", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: "<div class=\"st-chat-typing-container\" role=\"status\" [attr.aria-label]=\"ariaLabel()\">\n @if (variant() === 'incoming') {\n <div class=\"st-chat-typing-avatar\">\n <ng-content select=\"[slot=avatar]\" />\n </div>\n }\n\n <div class=\"st-chat-typing-bubble\">\n <span class=\"st-chat-typing-dot\"></span>\n <span class=\"st-chat-typing-dot\"></span>\n <span class=\"st-chat-typing-dot\"></span>\n </div>\n\n @if (variant() === 'outgoing') {\n <div class=\"st-chat-typing-avatar\">\n <ng-content select=\"[slot=avatar]\" />\n </div>\n }\n</div>\n", styles: [":host{--st-chat-typing-dot-size: 6px;--st-chat-typing-dot-color: var(--st-color-text-tertiary);--st-chat-typing-bubble-bg-incoming: var(--st-color-bg-raised);--st-chat-typing-bubble-bg-outgoing: var(--st-color-control-primary-bg);display:block;width:100%;box-sizing:border-box}:host .st-chat-typing-container{display:flex;align-items:flex-end;gap:var(--st-chat-avatar-gap, var(--st-space-2));width:100%;box-sizing:border-box}:host .st-chat-typing-avatar{flex-shrink:0;display:flex;align-items:flex-end;width:var(--st-chat-avatar-size, 32px);min-width:var(--st-chat-avatar-size, 32px)}:host .st-chat-typing-avatar:empty{display:none}:host .st-chat-typing-bubble{display:inline-flex;align-items:center;gap:var(--st-space-1);padding:var(--st-space-2) var(--st-space-3);min-height:32px;box-sizing:border-box;border-radius:var(--st-border-radius-xl)}:host .st-chat-typing-dot{width:var(--st-chat-typing-dot-size);height:var(--st-chat-typing-dot-size);border-radius:var(--st-border-radius-full);background-color:var(--st-chat-typing-dot-color);animation:st-chat-typing-bounce 1.4s infinite ease-in-out both}:host .st-chat-typing-dot:nth-child(1){animation-delay:-.32s}:host .st-chat-typing-dot:nth-child(2){animation-delay:-.16s}:host .st-chat-typing-dot:nth-child(3){animation-delay:0s}:host.incoming .st-chat-typing-container{justify-content:flex-start}:host.incoming .st-chat-typing-bubble{background-color:var(--st-chat-typing-bubble-bg-incoming);border:1px solid var(--st-color-border-subtle);border-radius:var(--st-border-radius-xl) var(--st-border-radius-xl) var(--st-border-radius-xl) var(--st-border-radius-sm)}:host.outgoing .st-chat-typing-container{justify-content:flex-end}:host.outgoing .st-chat-typing-bubble{background-color:var(--st-chat-typing-bubble-bg-outgoing);border:1px solid transparent;border-radius:var(--st-border-radius-xl) var(--st-border-radius-xl) var(--st-border-radius-sm) var(--st-border-radius-xl)}@keyframes st-chat-typing-bounce{0%,80%,to{transform:translateY(0);opacity:.35}40%{transform:translateY(-4px);opacity:1}}\n"] });
1915
+ }
1916
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataChatTypingComponent, decorators: [{
1917
+ type: Component,
1918
+ args: [{ selector: 'st-chat-typing', imports: [], host: {
1919
+ '[class]': 'hostClasses()'
1920
+ }, template: "<div class=\"st-chat-typing-container\" role=\"status\" [attr.aria-label]=\"ariaLabel()\">\n @if (variant() === 'incoming') {\n <div class=\"st-chat-typing-avatar\">\n <ng-content select=\"[slot=avatar]\" />\n </div>\n }\n\n <div class=\"st-chat-typing-bubble\">\n <span class=\"st-chat-typing-dot\"></span>\n <span class=\"st-chat-typing-dot\"></span>\n <span class=\"st-chat-typing-dot\"></span>\n </div>\n\n @if (variant() === 'outgoing') {\n <div class=\"st-chat-typing-avatar\">\n <ng-content select=\"[slot=avatar]\" />\n </div>\n }\n</div>\n", styles: [":host{--st-chat-typing-dot-size: 6px;--st-chat-typing-dot-color: var(--st-color-text-tertiary);--st-chat-typing-bubble-bg-incoming: var(--st-color-bg-raised);--st-chat-typing-bubble-bg-outgoing: var(--st-color-control-primary-bg);display:block;width:100%;box-sizing:border-box}:host .st-chat-typing-container{display:flex;align-items:flex-end;gap:var(--st-chat-avatar-gap, var(--st-space-2));width:100%;box-sizing:border-box}:host .st-chat-typing-avatar{flex-shrink:0;display:flex;align-items:flex-end;width:var(--st-chat-avatar-size, 32px);min-width:var(--st-chat-avatar-size, 32px)}:host .st-chat-typing-avatar:empty{display:none}:host .st-chat-typing-bubble{display:inline-flex;align-items:center;gap:var(--st-space-1);padding:var(--st-space-2) var(--st-space-3);min-height:32px;box-sizing:border-box;border-radius:var(--st-border-radius-xl)}:host .st-chat-typing-dot{width:var(--st-chat-typing-dot-size);height:var(--st-chat-typing-dot-size);border-radius:var(--st-border-radius-full);background-color:var(--st-chat-typing-dot-color);animation:st-chat-typing-bounce 1.4s infinite ease-in-out both}:host .st-chat-typing-dot:nth-child(1){animation-delay:-.32s}:host .st-chat-typing-dot:nth-child(2){animation-delay:-.16s}:host .st-chat-typing-dot:nth-child(3){animation-delay:0s}:host.incoming .st-chat-typing-container{justify-content:flex-start}:host.incoming .st-chat-typing-bubble{background-color:var(--st-chat-typing-bubble-bg-incoming);border:1px solid var(--st-color-border-subtle);border-radius:var(--st-border-radius-xl) var(--st-border-radius-xl) var(--st-border-radius-xl) var(--st-border-radius-sm)}:host.outgoing .st-chat-typing-container{justify-content:flex-end}:host.outgoing .st-chat-typing-bubble{background-color:var(--st-chat-typing-bubble-bg-outgoing);border:1px solid transparent;border-radius:var(--st-border-radius-xl) var(--st-border-radius-xl) var(--st-border-radius-sm) var(--st-border-radius-xl)}@keyframes st-chat-typing-bounce{0%,80%,to{transform:translateY(0);opacity:.35}40%{transform:translateY(-4px);opacity:1}}\n"] }]
1921
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
1922
+
1923
+ class StrataTimeStepperComponent {
1656
1924
  format = input('24h', /* @ts-ignore */
1657
1925
  ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
1658
1926
  showSeconds = input(false, /* @ts-ignore */
@@ -1820,30 +2088,264 @@ class StrataTimePickerComponent {
1820
2088
  setDisabledState(isDisabled) {
1821
2089
  this.cvaDisabled.set(isDisabled);
1822
2090
  }
1823
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataTimePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1824
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataTimePickerComponent, isStandalone: true, selector: "st-time-picker", inputs: { format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { properties: { "class.st-time-picker": "true", "class.st-disabled": "effectiveDisabled()", "attr.aria-disabled": "effectiveDisabled() ? \"true\" : null" } }, providers: [
2091
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataTimeStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2092
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataTimeStepperComponent, isStandalone: true, selector: "st-time-stepper", inputs: { format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { properties: { "class.st-time-stepper": "true", "class.st-disabled": "effectiveDisabled()", "attr.aria-disabled": "effectiveDisabled() ? \"true\" : null" } }, providers: [
1825
2093
  {
1826
2094
  provide: NG_VALUE_ACCESSOR,
1827
- useExisting: forwardRef(() => StrataTimePickerComponent),
2095
+ useExisting: forwardRef(() => StrataTimeStepperComponent),
1828
2096
  multi: true
1829
2097
  }
1830
- ], ngImport: i0, template: "<div class=\"st-time-picker-inner\">\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementHours()\"\n aria-label=\"Increment hours\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementHours()\" (keydown.arrowdown)=\"decrementHours()\">\n {{ displayHours() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementHours()\"\n aria-label=\"Decrement hours\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n\n <span class=\"st-time-sep\">:</span>\n\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementMinutes()\"\n aria-label=\"Increment minutes\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementMinutes()\" (keydown.arrowdown)=\"decrementMinutes()\">\n {{ displayMinutes() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementMinutes()\"\n aria-label=\"Decrement minutes\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n\n @if (showSeconds()) {\n <span class=\"st-time-sep\">:</span>\n\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementSeconds()\"\n aria-label=\"Increment seconds\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementSeconds()\" (keydown.arrowdown)=\"decrementSeconds()\">\n {{ displaySeconds() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementSeconds()\"\n aria-label=\"Decrement seconds\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n }\n\n @if (is12h()) {\n <div class=\"st-time-col st-meridiem-col\">\n <button\n type=\"button\"\n class=\"st-meridiem-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"toggleMeridiem()\"\n aria-label=\"Toggle AM PM\"\n >\n {{ meridiem() }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:inline-flex;align-items:center;box-sizing:border-box}:host.st-size-sm .st-time-val{min-width:34px;height:32px;font-size:var(--st-font-md);border-radius:var(--st-border-radius-sm)}:host.st-size-sm .st-time-arrow-btn{width:34px;height:20px}:host.st-size-sm .st-time-sep{font-size:var(--st-font-lg);margin:0 2px}:host.st-size-sm .st-meridiem-btn{height:32px;font-size:var(--st-font-xs);padding:0 var(--st-space-2);border-radius:var(--st-border-radius-sm)}:host.st-size-lg .st-time-val{min-width:54px;height:50px;font-size:1.5rem;border-radius:var(--st-border-radius-lg)}:host.st-size-lg .st-time-arrow-btn{width:54px;height:28px}:host.st-size-lg .st-time-sep{font-size:1.75rem;margin:0 6px}:host.st-size-lg .st-meridiem-btn{height:50px;font-size:var(--st-font-md);padding:0 var(--st-space-4);border-radius:var(--st-border-radius-lg)}:host.st-disabled{opacity:.55;pointer-events:none}.st-time-picker-inner{display:inline-flex;align-items:center;gap:var(--st-space-1);padding:0;background:transparent;border:none;color:var(--st-color-text-primary);-webkit-user-select:none;user-select:none}.st-time-col{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--st-space-1)}.st-time-arrow-btn{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);width:44px;height:24px;border-radius:var(--st-border-radius-sm);transition:background var(--st-transition-fast),color var(--st-transition-fast)}.st-time-arrow-btn:hover:not(:disabled){background:var(--st-color-control-bg-hover, var(--st-color-bg-default));color:var(--st-color-text-primary)}.st-time-arrow-btn:disabled{opacity:.4;cursor:not-allowed}.st-time-val{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:42px;font-family:var(--st-font-mono);font-size:var(--st-font-lg);font-weight:var(--st-font-weight-semibold);background:transparent;border:1px solid var(--st-border);border-radius:var(--st-border-radius-md);color:var(--st-color-text-primary);outline:none;cursor:default;transition:border-color var(--st-transition-fast)}.st-time-val:focus-visible{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}.st-time-sep{font-weight:var(--st-font-weight-bold);color:var(--st-color-text-secondary);font-size:var(--st-font-xl);margin:0 4px}.st-meridiem-col{margin-left:var(--st-space-1)}.st-meridiem-btn{background:transparent;border:1px solid var(--st-border);color:var(--st-color-text-primary);border-radius:var(--st-border-radius-md);height:42px;font-size:var(--st-font-sm);font-weight:var(--st-font-weight-semibold);padding:0 var(--st-space-3);cursor:pointer;transition:background var(--st-transition-fast),border-color var(--st-transition-fast)}.st-meridiem-btn:hover:not(:disabled){background:var(--st-color-control-bg-hover, var(--st-color-bg-default));border-color:var(--st-color-border-strong)}.st-meridiem-btn:disabled{opacity:.4;cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }] });
2098
+ ], ngImport: i0, template: "<div class=\"st-time-stepper-inner\">\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementHours()\"\n aria-label=\"Increment hours\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementHours()\" (keydown.arrowdown)=\"decrementHours()\">\n {{ displayHours() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementHours()\"\n aria-label=\"Decrement hours\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n\n <span class=\"st-time-sep\">:</span>\n\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementMinutes()\"\n aria-label=\"Increment minutes\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementMinutes()\" (keydown.arrowdown)=\"decrementMinutes()\">\n {{ displayMinutes() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementMinutes()\"\n aria-label=\"Decrement minutes\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n\n @if (showSeconds()) {\n <span class=\"st-time-sep\">:</span>\n\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementSeconds()\"\n aria-label=\"Increment seconds\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementSeconds()\" (keydown.arrowdown)=\"decrementSeconds()\">\n {{ displaySeconds() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementSeconds()\"\n aria-label=\"Decrement seconds\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n }\n\n @if (is12h()) {\n <div class=\"st-time-col st-meridiem-col\">\n <button\n type=\"button\"\n class=\"st-meridiem-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"toggleMeridiem()\"\n aria-label=\"Toggle AM PM\"\n >\n {{ meridiem() }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:inline-flex;align-items:center;box-sizing:border-box}:host.st-disabled{opacity:.55;pointer-events:none}.st-time-stepper-inner{display:inline-flex;align-items:center;gap:var(--st-space-1);padding:0;background:transparent;border:none;color:var(--st-color-text-primary);-webkit-user-select:none;user-select:none}.st-time-col{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--st-space-1)}.st-time-arrow-btn{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);width:44px;height:24px;border-radius:var(--st-border-radius-sm);transition:background var(--st-transition-fast),color var(--st-transition-fast)}.st-time-arrow-btn:hover:not(:disabled){background:var(--st-color-control-bg-hover, var(--st-color-bg-default));color:var(--st-color-text-primary)}.st-time-arrow-btn:disabled{opacity:.4;cursor:not-allowed}.st-time-val{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:42px;font-family:var(--st-font-mono);font-size:var(--st-font-lg);font-weight:var(--st-font-weight-semibold);background:transparent;border:1px solid var(--st-border);border-radius:var(--st-border-radius-md);color:var(--st-color-text-primary);outline:none;cursor:default;transition:border-color var(--st-transition-fast)}.st-time-val:focus-visible{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}.st-time-sep{font-weight:var(--st-font-weight-bold);color:var(--st-color-text-secondary);font-size:var(--st-font-xl);margin:0 4px}.st-meridiem-col{margin-left:var(--st-space-1)}.st-meridiem-btn{background:transparent;border:1px solid var(--st-border);color:var(--st-color-text-primary);border-radius:var(--st-border-radius-md);height:42px;font-size:var(--st-font-sm);font-weight:var(--st-font-weight-semibold);padding:0 var(--st-space-3);cursor:pointer;transition:background var(--st-transition-fast),border-color var(--st-transition-fast)}.st-meridiem-btn:hover:not(:disabled){background:var(--st-color-control-bg-hover, var(--st-color-bg-default));border-color:var(--st-color-border-strong)}.st-meridiem-btn:disabled{opacity:.4;cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }] });
1831
2099
  }
1832
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataTimePickerComponent, decorators: [{
2100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataTimeStepperComponent, decorators: [{
1833
2101
  type: Component,
1834
- args: [{ selector: 'st-time-picker', imports: [CommonModule, StrataIconComponent], providers: [
2102
+ args: [{ selector: 'st-time-stepper', imports: [CommonModule, StrataIconComponent], providers: [
1835
2103
  {
1836
2104
  provide: NG_VALUE_ACCESSOR,
1837
- useExisting: forwardRef(() => StrataTimePickerComponent),
2105
+ useExisting: forwardRef(() => StrataTimeStepperComponent),
1838
2106
  multi: true
1839
2107
  }
1840
2108
  ], host: {
1841
- '[class.st-time-picker]': 'true',
2109
+ '[class.st-time-stepper]': 'true',
1842
2110
  '[class.st-disabled]': 'effectiveDisabled()',
1843
2111
  '[attr.aria-disabled]': 'effectiveDisabled() ? "true" : null'
1844
- }, template: "<div class=\"st-time-picker-inner\">\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementHours()\"\n aria-label=\"Increment hours\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementHours()\" (keydown.arrowdown)=\"decrementHours()\">\n {{ displayHours() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementHours()\"\n aria-label=\"Decrement hours\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n\n <span class=\"st-time-sep\">:</span>\n\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementMinutes()\"\n aria-label=\"Increment minutes\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementMinutes()\" (keydown.arrowdown)=\"decrementMinutes()\">\n {{ displayMinutes() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementMinutes()\"\n aria-label=\"Decrement minutes\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n\n @if (showSeconds()) {\n <span class=\"st-time-sep\">:</span>\n\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementSeconds()\"\n aria-label=\"Increment seconds\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementSeconds()\" (keydown.arrowdown)=\"decrementSeconds()\">\n {{ displaySeconds() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementSeconds()\"\n aria-label=\"Decrement seconds\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n }\n\n @if (is12h()) {\n <div class=\"st-time-col st-meridiem-col\">\n <button\n type=\"button\"\n class=\"st-meridiem-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"toggleMeridiem()\"\n aria-label=\"Toggle AM PM\"\n >\n {{ meridiem() }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:inline-flex;align-items:center;box-sizing:border-box}:host.st-size-sm .st-time-val{min-width:34px;height:32px;font-size:var(--st-font-md);border-radius:var(--st-border-radius-sm)}:host.st-size-sm .st-time-arrow-btn{width:34px;height:20px}:host.st-size-sm .st-time-sep{font-size:var(--st-font-lg);margin:0 2px}:host.st-size-sm .st-meridiem-btn{height:32px;font-size:var(--st-font-xs);padding:0 var(--st-space-2);border-radius:var(--st-border-radius-sm)}:host.st-size-lg .st-time-val{min-width:54px;height:50px;font-size:1.5rem;border-radius:var(--st-border-radius-lg)}:host.st-size-lg .st-time-arrow-btn{width:54px;height:28px}:host.st-size-lg .st-time-sep{font-size:1.75rem;margin:0 6px}:host.st-size-lg .st-meridiem-btn{height:50px;font-size:var(--st-font-md);padding:0 var(--st-space-4);border-radius:var(--st-border-radius-lg)}:host.st-disabled{opacity:.55;pointer-events:none}.st-time-picker-inner{display:inline-flex;align-items:center;gap:var(--st-space-1);padding:0;background:transparent;border:none;color:var(--st-color-text-primary);-webkit-user-select:none;user-select:none}.st-time-col{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--st-space-1)}.st-time-arrow-btn{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);width:44px;height:24px;border-radius:var(--st-border-radius-sm);transition:background var(--st-transition-fast),color var(--st-transition-fast)}.st-time-arrow-btn:hover:not(:disabled){background:var(--st-color-control-bg-hover, var(--st-color-bg-default));color:var(--st-color-text-primary)}.st-time-arrow-btn:disabled{opacity:.4;cursor:not-allowed}.st-time-val{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:42px;font-family:var(--st-font-mono);font-size:var(--st-font-lg);font-weight:var(--st-font-weight-semibold);background:transparent;border:1px solid var(--st-border);border-radius:var(--st-border-radius-md);color:var(--st-color-text-primary);outline:none;cursor:default;transition:border-color var(--st-transition-fast)}.st-time-val:focus-visible{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}.st-time-sep{font-weight:var(--st-font-weight-bold);color:var(--st-color-text-secondary);font-size:var(--st-font-xl);margin:0 4px}.st-meridiem-col{margin-left:var(--st-space-1)}.st-meridiem-btn{background:transparent;border:1px solid var(--st-border);color:var(--st-color-text-primary);border-radius:var(--st-border-radius-md);height:42px;font-size:var(--st-font-sm);font-weight:var(--st-font-weight-semibold);padding:0 var(--st-space-3);cursor:pointer;transition:background var(--st-transition-fast),border-color var(--st-transition-fast)}.st-meridiem-btn:hover:not(:disabled){background:var(--st-color-control-bg-hover, var(--st-color-bg-default));border-color:var(--st-color-border-strong)}.st-meridiem-btn:disabled{opacity:.4;cursor:not-allowed}\n"] }]
2112
+ }, template: "<div class=\"st-time-stepper-inner\">\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementHours()\"\n aria-label=\"Increment hours\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementHours()\" (keydown.arrowdown)=\"decrementHours()\">\n {{ displayHours() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementHours()\"\n aria-label=\"Decrement hours\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n\n <span class=\"st-time-sep\">:</span>\n\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementMinutes()\"\n aria-label=\"Increment minutes\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementMinutes()\" (keydown.arrowdown)=\"decrementMinutes()\">\n {{ displayMinutes() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementMinutes()\"\n aria-label=\"Decrement minutes\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n\n @if (showSeconds()) {\n <span class=\"st-time-sep\">:</span>\n\n <div class=\"st-time-col\">\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"incrementSeconds()\"\n aria-label=\"Increment seconds\"\n >\n <st-icon name=\"arrow-up\" size=\"xs\"></st-icon>\n </button>\n <span class=\"st-time-val\" tabindex=\"0\" (keydown.arrowup)=\"incrementSeconds()\" (keydown.arrowdown)=\"decrementSeconds()\">\n {{ displaySeconds() }}\n </span>\n <button\n type=\"button\"\n class=\"st-time-arrow-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"decrementSeconds()\"\n aria-label=\"Decrement seconds\"\n >\n <st-icon name=\"arrow-down\" size=\"xs\"></st-icon>\n </button>\n </div>\n }\n\n @if (is12h()) {\n <div class=\"st-time-col st-meridiem-col\">\n <button\n type=\"button\"\n class=\"st-meridiem-btn\"\n [disabled]=\"effectiveDisabled()\"\n (click)=\"toggleMeridiem()\"\n aria-label=\"Toggle AM PM\"\n >\n {{ meridiem() }}\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:inline-flex;align-items:center;box-sizing:border-box}:host.st-disabled{opacity:.55;pointer-events:none}.st-time-stepper-inner{display:inline-flex;align-items:center;gap:var(--st-space-1);padding:0;background:transparent;border:none;color:var(--st-color-text-primary);-webkit-user-select:none;user-select:none}.st-time-col{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--st-space-1)}.st-time-arrow-btn{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);width:44px;height:24px;border-radius:var(--st-border-radius-sm);transition:background var(--st-transition-fast),color var(--st-transition-fast)}.st-time-arrow-btn:hover:not(:disabled){background:var(--st-color-control-bg-hover, var(--st-color-bg-default));color:var(--st-color-text-primary)}.st-time-arrow-btn:disabled{opacity:.4;cursor:not-allowed}.st-time-val{display:inline-flex;align-items:center;justify-content:center;min-width:44px;height:42px;font-family:var(--st-font-mono);font-size:var(--st-font-lg);font-weight:var(--st-font-weight-semibold);background:transparent;border:1px solid var(--st-border);border-radius:var(--st-border-radius-md);color:var(--st-color-text-primary);outline:none;cursor:default;transition:border-color var(--st-transition-fast)}.st-time-val:focus-visible{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}.st-time-sep{font-weight:var(--st-font-weight-bold);color:var(--st-color-text-secondary);font-size:var(--st-font-xl);margin:0 4px}.st-meridiem-col{margin-left:var(--st-space-1)}.st-meridiem-btn{background:transparent;border:1px solid var(--st-border);color:var(--st-color-text-primary);border-radius:var(--st-border-radius-md);height:42px;font-size:var(--st-font-sm);font-weight:var(--st-font-weight-semibold);padding:0 var(--st-space-3);cursor:pointer;transition:background var(--st-transition-fast),border-color var(--st-transition-fast)}.st-meridiem-btn:hover:not(:disabled){background:var(--st-color-control-bg-hover, var(--st-color-bg-default));border-color:var(--st-color-border-strong)}.st-meridiem-btn:disabled{opacity:.4;cursor:not-allowed}\n"] }]
1845
2113
  }], ctorParameters: () => [], propDecorators: { format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], showSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSeconds", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
1846
2114
 
2115
+ let nextUniqueTimepickerId = 0;
2116
+ class StrataTimepickerComponent {
2117
+ defaultId = `st-timepicker-${nextUniqueTimepickerId++}`;
2118
+ label = input(undefined, /* @ts-ignore */
2119
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2120
+ id = input(undefined, /* @ts-ignore */
2121
+ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
2122
+ name = input(undefined, /* @ts-ignore */
2123
+ ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
2124
+ placeholder = input('Select time', /* @ts-ignore */
2125
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
2126
+ size = input('md', /* @ts-ignore */
2127
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
2128
+ placement = input('bottom-start', /* @ts-ignore */
2129
+ ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
2130
+ format = input('24h', /* @ts-ignore */
2131
+ ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
2132
+ showSeconds = input(false, { ...(ngDevMode ? { debugName: "showSeconds" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2133
+ minuteStep = input(1, /* @ts-ignore */
2134
+ ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
2135
+ clearable = input(true, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2136
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2137
+ readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2138
+ fullWidth = input(false, { ...(ngDevMode ? { debugName: "fullWidth" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2139
+ state = input(undefined, /* @ts-ignore */
2140
+ ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
2141
+ error = input(false, { ...(ngDevMode ? { debugName: "error" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2142
+ message = input(undefined, /* @ts-ignore */
2143
+ ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
2144
+ colorMessage = input(true, { ...(ngDevMode ? { debugName: "colorMessage" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2145
+ value = model(null, /* @ts-ignore */
2146
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
2147
+ timeSelected = output();
2148
+ open = signal(false, /* @ts-ignore */
2149
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
2150
+ textInputValue = signal('', /* @ts-ignore */
2151
+ ...(ngDevMode ? [{ debugName: "textInputValue" }] : /* istanbul ignore next */ []));
2152
+ cvaDisabled = signal(false, /* @ts-ignore */
2153
+ ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
2154
+ effectiveDisabled = computed(() => this.disabled() || this.cvaDisabled(), /* @ts-ignore */
2155
+ ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
2156
+ effectiveId = computed(() => this.id() ?? this.name() ?? this.defaultId, /* @ts-ignore */
2157
+ ...(ngDevMode ? [{ debugName: "effectiveId" }] : /* istanbul ignore next */ []));
2158
+ effectiveState = computed(() => {
2159
+ if (this.error()) {
2160
+ return 'error';
2161
+ }
2162
+ return this.state() ?? 'default';
2163
+ }, /* @ts-ignore */
2164
+ ...(ngDevMode ? [{ debugName: "effectiveState" }] : /* istanbul ignore next */ []));
2165
+ isMessageError = computed(() => this.effectiveState() === 'error' && this.colorMessage(), /* @ts-ignore */
2166
+ ...(ngDevMode ? [{ debugName: "isMessageError" }] : /* istanbul ignore next */ []));
2167
+ isMessageSuccess = computed(() => this.effectiveState() === 'success' && this.colorMessage(), /* @ts-ignore */
2168
+ ...(ngDevMode ? [{ debugName: "isMessageSuccess" }] : /* istanbul ignore next */ []));
2169
+ isMessageWarning = computed(() => this.effectiveState() === 'warning' && this.colorMessage(), /* @ts-ignore */
2170
+ ...(ngDevMode ? [{ debugName: "isMessageWarning" }] : /* istanbul ignore next */ []));
2171
+ onChange = () => undefined;
2172
+ onTouched = () => undefined;
2173
+ overlayDirective = viewChild(StrataOverlayDirective, /* @ts-ignore */
2174
+ ...(ngDevMode ? [{ debugName: "overlayDirective" }] : /* istanbul ignore next */ []));
2175
+ elementRef = inject(ElementRef);
2176
+ renderer = inject(Renderer2);
2177
+ destroyRef = inject(DestroyRef);
2178
+ constructor() {
2179
+ const unlisten = this.renderer.listen('document', 'pointerdown', (event) => {
2180
+ if (!this.open())
2181
+ return;
2182
+ const target = event.target;
2183
+ if (!target)
2184
+ return;
2185
+ const hostEl = this.elementRef.nativeElement;
2186
+ const overlayEl = this.overlayDirective()?.getOverlayElement();
2187
+ if (hostEl.contains(target) || (overlayEl && overlayEl.contains(target))) {
2188
+ return;
2189
+ }
2190
+ this.open.set(false);
2191
+ });
2192
+ this.destroyRef.onDestroy(() => unlisten());
2193
+ }
2194
+ toggle(event) {
2195
+ if (this.effectiveDisabled() || this.readonly())
2196
+ return;
2197
+ if (event) {
2198
+ event.preventDefault();
2199
+ event.stopPropagation();
2200
+ }
2201
+ this.open.set(!this.open());
2202
+ }
2203
+ onInputTextChange(value) {
2204
+ this.textInputValue.set(value);
2205
+ if (!value.trim()) {
2206
+ this.updateTimeValue(null);
2207
+ return;
2208
+ }
2209
+ const parsed = this.parseTimeString(value);
2210
+ if (parsed) {
2211
+ this.updateTimeValue(parsed);
2212
+ }
2213
+ }
2214
+ onInputBlur() {
2215
+ this.onTouched();
2216
+ const val = this.value();
2217
+ if (val) {
2218
+ this.textInputValue.set(this.formatTimeValue(val));
2219
+ }
2220
+ else {
2221
+ this.textInputValue.set('');
2222
+ }
2223
+ }
2224
+ onStepperTimeSelected(val) {
2225
+ this.updateTimeValue(val);
2226
+ }
2227
+ clear(event) {
2228
+ event.stopPropagation();
2229
+ if (this.effectiveDisabled() || this.readonly())
2230
+ return;
2231
+ this.updateTimeValue(null);
2232
+ }
2233
+ formatTimeValue(val) {
2234
+ if (!val)
2235
+ return '';
2236
+ let hours = 0;
2237
+ let minutes = 0;
2238
+ let seconds = 0;
2239
+ if (val instanceof Date) {
2240
+ hours = val.getHours();
2241
+ minutes = val.getMinutes();
2242
+ seconds = val.getSeconds();
2243
+ }
2244
+ else if (typeof val === 'string') {
2245
+ const parts = val.trim().split(':');
2246
+ hours = parseInt(parts[0], 10) || 0;
2247
+ minutes = parseInt(parts[1], 10) || 0;
2248
+ seconds = parts[2] ? parseInt(parts[2], 10) || 0 : 0;
2249
+ }
2250
+ const pad = (n) => n.toString().padStart(2, '0');
2251
+ if (this.format() === '12h') {
2252
+ const isPM = hours >= 12;
2253
+ const h12 = hours % 12 || 12;
2254
+ const meridiem = isPM ? 'PM' : 'AM';
2255
+ return this.showSeconds()
2256
+ ? `${pad(h12)}:${pad(minutes)}:${pad(seconds)} ${meridiem}`
2257
+ : `${pad(h12)}:${pad(minutes)} ${meridiem}`;
2258
+ }
2259
+ return this.showSeconds()
2260
+ ? `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`
2261
+ : `${pad(hours)}:${pad(minutes)}`;
2262
+ }
2263
+ parseTimeString(input) {
2264
+ const trimmed = input.trim();
2265
+ if (!trimmed)
2266
+ return null;
2267
+ const is12hInput = /am|pm/i.test(trimmed);
2268
+ const cleanTime = trimmed.replace(/\s*(am|pm)/i, '').trim();
2269
+ const parts = cleanTime.split(':').map((p) => parseInt(p, 10));
2270
+ if (parts.some((n) => isNaN(n)))
2271
+ return null;
2272
+ let [h, m, s] = parts;
2273
+ m = m ?? 0;
2274
+ s = s ?? 0;
2275
+ if (is12hInput || this.format() === '12h') {
2276
+ const isPM = /pm/i.test(trimmed);
2277
+ if (h < 1 || h > 12 || m < 0 || m > 59 || s < 0 || s > 59)
2278
+ return null;
2279
+ if (isPM && h < 12)
2280
+ h += 12;
2281
+ if (!isPM && h === 12)
2282
+ h = 0;
2283
+ }
2284
+ else {
2285
+ if (h < 0 || h > 23 || m < 0 || m > 59 || s < 0 || s > 59)
2286
+ return null;
2287
+ }
2288
+ const pad = (n) => n.toString().padStart(2, '0');
2289
+ return this.showSeconds() ? `${pad(h)}:${pad(m)}:${pad(s)}` : `${pad(h)}:${pad(m)}`;
2290
+ }
2291
+ updateTimeValue(val) {
2292
+ this.value.set(val);
2293
+ this.textInputValue.set(this.formatTimeValue(val));
2294
+ this.timeSelected.emit(val);
2295
+ this.onChange(val);
2296
+ this.onTouched();
2297
+ }
2298
+ writeValue(val) {
2299
+ this.value.set(val);
2300
+ this.textInputValue.set(this.formatTimeValue(val));
2301
+ }
2302
+ registerOnChange(fn) {
2303
+ this.onChange = fn;
2304
+ }
2305
+ registerOnTouched(fn) {
2306
+ this.onTouched = fn;
2307
+ }
2308
+ setDisabledState(isDisabled) {
2309
+ this.cvaDisabled.set(isDisabled);
2310
+ }
2311
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataTimepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2312
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataTimepickerComponent, isStandalone: true, selector: "st-timepicker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, colorMessage: { classPropertyName: "colorMessage", publicName: "colorMessage", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", timeSelected: "timeSelected" }, host: { properties: { "class.st-timepicker": "true", "class.st-size-sm": "size() === \"sm\"", "class.st-size-md": "size() === \"md\"", "class.st-size-lg": "size() === \"lg\"", "class.st-disabled": "effectiveDisabled()", "attr.aria-disabled": "effectiveDisabled() ? \"true\" : null", "class.st-state-error": "effectiveState() === \"error\"", "class.st-state-success": "effectiveState() === \"success\"", "class.st-state-warning": "effectiveState() === \"warning\"", "class.st-error": "effectiveState() === \"error\"", "attr.aria-invalid": "effectiveState() === \"error\" ? \"true\" : null" } }, providers: [
2313
+ {
2314
+ provide: NG_VALUE_ACCESSOR,
2315
+ useExisting: forwardRef(() => StrataTimepickerComponent),
2316
+ multi: true
2317
+ }
2318
+ ], viewQueries: [{ propertyName: "overlayDirective", first: true, predicate: StrataOverlayDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <label class=\"st-label\" [for]=\"effectiveId()\">{{ label() }}</label>\n}\n\n<div\n class=\"st-input-wrapper\"\n [class.full-width]=\"fullWidth()\"\n [class.disabled]=\"effectiveDisabled()\"\n [class.open]=\"open()\"\n [stOverlay]=\"timeOverlay\"\n [overlayOpen]=\"open()\"\n [overlayPlacement]=\"placement()\"\n>\n <input\n type=\"text\"\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [value]=\"textInputValue()\"\n [disabled]=\"effectiveDisabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onInputTextChange($any($event.target).value)\"\n (blur)=\"onInputBlur()\"\n (click)=\"toggle($event)\"\n (keydown.enter)=\"toggle($event)\"\n (keydown.escape)=\"open.set(false)\"\n />\n\n <div class=\"affix\">\n @if (clearable() && value() && !effectiveDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"st-icon-btn\"\n (click)=\"clear($event)\"\n aria-label=\"Clear time\"\n >\n <st-icon name=\"close\" size=\"xs\"></st-icon>\n </button>\n }\n\n <span class=\"st-trigger-icon\" (click)=\"toggle($event)\">\n <st-icon name=\"clock\" size=\"xs\"></st-icon>\n </span>\n </div>\n</div>\n\n@if (message()) {\n <div class=\"st-input-field-footer\">\n <span\n class=\"st-input-field-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </span>\n </div>\n}\n\n<ng-template #timeOverlay>\n <div class=\"st-timepicker-dropdown\">\n <st-time-stepper\n [value]=\"value()\"\n [format]=\"format()\"\n [showSeconds]=\"showSeconds()\"\n [minuteStep]=\"minuteStep()\"\n [disabled]=\"effectiveDisabled()\"\n (valueChange)=\"onStepperTimeSelected($event)\"\n ></st-time-stepper>\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%}:host label{margin-bottom:var(--st-space-2)}.st-input-wrapper{display:flex;align-items:center;box-sizing:border-box;height:var(--st-interactive-element-height-md);background-color:var(--st-color-bg-raised);border:1px solid var(--st-border-muted);border-radius:var(--st-border-radius-md);overflow:hidden;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast)}.st-input-wrapper:hover{background-color:var(--st-color-input-hover);border-color:var(--st-color-border-strong)}.st-input-wrapper:focus-within,.st-input-wrapper.open{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}:host(.st-size-sm) .st-input-wrapper{height:var(--st-interactive-element-height-sm);border-radius:var(--st-border-radius-sm)}:host(.st-size-sm) input{padding:0 var(--st-size-xxs);font-size:var(--st-font-sm)}:host(.st-size-sm) .affix{padding-right:var(--st-size-xxs)}:host(.st-size-lg) .st-input-wrapper{height:var(--st-interactive-element-height-lg)}:host(.st-state-error) .st-input-wrapper,:host(.st-error) .st-input-wrapper{border-color:var(--st-color-feedback-error-default);outline-color:var(--st-color-feedback-error-default)}:host(.st-state-success) .st-input-wrapper{border-color:var(--st-color-feedback-success-default);outline-color:var(--st-color-feedback-success-default)}:host(.st-state-warning) .st-input-wrapper{border-color:var(--st-color-feedback-warning-default);outline-color:var(--st-color-feedback-warning-default)}:host(.st-disabled){opacity:.55;pointer-events:none;cursor:not-allowed}input{border:none;background:none;width:100%;padding:0 var(--st-size-xs);color:var(--st-color-text-primary);font-size:var(--st-font-md);font-family:inherit;height:100%;cursor:pointer;outline:none}input::placeholder{color:var(--st-color-text-tertiary)}.affix{display:flex;align-items:center;padding-right:var(--st-size-xs);gap:var(--st-space-1);color:var(--st-color-text-tertiary)}.st-icon-btn,.st-trigger-icon{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);transition:color var(--st-transition-fast)}.st-icon-btn:hover,.st-trigger-icon:hover{color:var(--st-color-text-primary)}.st-input-field-footer{display:flex;margin-top:var(--st-space-1);line-height:1.25}.st-input-field-message{font-size:var(--st-font-sm);color:var(--st-color-text-secondary)}.st-input-field-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-input-field-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-input-field-message.st-message-warning{color:var(--st-color-feedback-warning-text)}.st-timepicker-dropdown{border:1px solid var(--st-border);border-radius:var(--st-border-radius-lg);background-color:var(--st-color-bg-raised);box-shadow:var(--st-shadow-2);padding:var(--st-space-3);overflow:hidden;animation:st-popover-in var(--st-transition-fast) ease-out;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport", "overlayTarget"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataTimeStepperComponent, selector: "st-time-stepper", inputs: ["format", "showSeconds", "minuteStep", "disabled", "value"], outputs: ["valueChange"] }] });
2319
+ }
2320
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataTimepickerComponent, decorators: [{
2321
+ type: Component,
2322
+ args: [{ selector: 'st-timepicker', imports: [
2323
+ CommonModule,
2324
+ FormsModule,
2325
+ StrataIconComponent,
2326
+ StrataOverlayDirective,
2327
+ StrataTimeStepperComponent
2328
+ ], providers: [
2329
+ {
2330
+ provide: NG_VALUE_ACCESSOR,
2331
+ useExisting: forwardRef(() => StrataTimepickerComponent),
2332
+ multi: true
2333
+ }
2334
+ ], host: {
2335
+ '[class.st-timepicker]': 'true',
2336
+ '[class.st-size-sm]': 'size() === "sm"',
2337
+ '[class.st-size-md]': 'size() === "md"',
2338
+ '[class.st-size-lg]': 'size() === "lg"',
2339
+ '[class.st-disabled]': 'effectiveDisabled()',
2340
+ '[attr.aria-disabled]': 'effectiveDisabled() ? "true" : null',
2341
+ '[class.st-state-error]': 'effectiveState() === "error"',
2342
+ '[class.st-state-success]': 'effectiveState() === "success"',
2343
+ '[class.st-state-warning]': 'effectiveState() === "warning"',
2344
+ '[class.st-error]': 'effectiveState() === "error"',
2345
+ '[attr.aria-invalid]': 'effectiveState() === "error" ? "true" : null'
2346
+ }, template: "@if (label()) {\n <label class=\"st-label\" [for]=\"effectiveId()\">{{ label() }}</label>\n}\n\n<div\n class=\"st-input-wrapper\"\n [class.full-width]=\"fullWidth()\"\n [class.disabled]=\"effectiveDisabled()\"\n [class.open]=\"open()\"\n [stOverlay]=\"timeOverlay\"\n [overlayOpen]=\"open()\"\n [overlayPlacement]=\"placement()\"\n>\n <input\n type=\"text\"\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [value]=\"textInputValue()\"\n [disabled]=\"effectiveDisabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onInputTextChange($any($event.target).value)\"\n (blur)=\"onInputBlur()\"\n (click)=\"toggle($event)\"\n (keydown.enter)=\"toggle($event)\"\n (keydown.escape)=\"open.set(false)\"\n />\n\n <div class=\"affix\">\n @if (clearable() && value() && !effectiveDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"st-icon-btn\"\n (click)=\"clear($event)\"\n aria-label=\"Clear time\"\n >\n <st-icon name=\"close\" size=\"xs\"></st-icon>\n </button>\n }\n\n <span class=\"st-trigger-icon\" (click)=\"toggle($event)\">\n <st-icon name=\"clock\" size=\"xs\"></st-icon>\n </span>\n </div>\n</div>\n\n@if (message()) {\n <div class=\"st-input-field-footer\">\n <span\n class=\"st-input-field-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </span>\n </div>\n}\n\n<ng-template #timeOverlay>\n <div class=\"st-timepicker-dropdown\">\n <st-time-stepper\n [value]=\"value()\"\n [format]=\"format()\"\n [showSeconds]=\"showSeconds()\"\n [minuteStep]=\"minuteStep()\"\n [disabled]=\"effectiveDisabled()\"\n (valueChange)=\"onStepperTimeSelected($event)\"\n ></st-time-stepper>\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%}:host label{margin-bottom:var(--st-space-2)}.st-input-wrapper{display:flex;align-items:center;box-sizing:border-box;height:var(--st-interactive-element-height-md);background-color:var(--st-color-bg-raised);border:1px solid var(--st-border-muted);border-radius:var(--st-border-radius-md);overflow:hidden;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast)}.st-input-wrapper:hover{background-color:var(--st-color-input-hover);border-color:var(--st-color-border-strong)}.st-input-wrapper:focus-within,.st-input-wrapper.open{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}:host(.st-size-sm) .st-input-wrapper{height:var(--st-interactive-element-height-sm);border-radius:var(--st-border-radius-sm)}:host(.st-size-sm) input{padding:0 var(--st-size-xxs);font-size:var(--st-font-sm)}:host(.st-size-sm) .affix{padding-right:var(--st-size-xxs)}:host(.st-size-lg) .st-input-wrapper{height:var(--st-interactive-element-height-lg)}:host(.st-state-error) .st-input-wrapper,:host(.st-error) .st-input-wrapper{border-color:var(--st-color-feedback-error-default);outline-color:var(--st-color-feedback-error-default)}:host(.st-state-success) .st-input-wrapper{border-color:var(--st-color-feedback-success-default);outline-color:var(--st-color-feedback-success-default)}:host(.st-state-warning) .st-input-wrapper{border-color:var(--st-color-feedback-warning-default);outline-color:var(--st-color-feedback-warning-default)}:host(.st-disabled){opacity:.55;pointer-events:none;cursor:not-allowed}input{border:none;background:none;width:100%;padding:0 var(--st-size-xs);color:var(--st-color-text-primary);font-size:var(--st-font-md);font-family:inherit;height:100%;cursor:pointer;outline:none}input::placeholder{color:var(--st-color-text-tertiary)}.affix{display:flex;align-items:center;padding-right:var(--st-size-xs);gap:var(--st-space-1);color:var(--st-color-text-tertiary)}.st-icon-btn,.st-trigger-icon{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);transition:color var(--st-transition-fast)}.st-icon-btn:hover,.st-trigger-icon:hover{color:var(--st-color-text-primary)}.st-input-field-footer{display:flex;margin-top:var(--st-space-1);line-height:1.25}.st-input-field-message{font-size:var(--st-font-sm);color:var(--st-color-text-secondary)}.st-input-field-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-input-field-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-input-field-message.st-message-warning{color:var(--st-color-feedback-warning-text)}.st-timepicker-dropdown{border:1px solid var(--st-border);border-radius:var(--st-border-radius-lg);background-color:var(--st-color-bg-raised);box-shadow:var(--st-shadow-2);padding:var(--st-space-3);overflow:hidden;animation:st-popover-in var(--st-transition-fast) ease-out;display:flex;align-items:center;justify-content:center}\n"] }]
2347
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], showSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSeconds", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], colorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorMessage", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], timeSelected: [{ type: i0.Output, args: ["timeSelected"] }], overlayDirective: [{ type: i0.ViewChild, args: [i0.forwardRef(() => StrataOverlayDirective), { isSignal: true }] }] } });
2348
+
1847
2349
  function isSameDay(a, b) {
1848
2350
  if (!a || !b)
1849
2351
  return false;
@@ -2622,7 +3124,7 @@ class StrataDatePickerComponent {
2622
3124
  useExisting: forwardRef(() => StrataDatePickerComponent),
2623
3125
  multi: true
2624
3126
  }
2625
- ], viewQueries: [{ propertyName: "overlayDirective", first: true, predicate: StrataOverlayDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <label class=\"st-label\" [for]=\"effectiveId()\">{{ label() }}</label>\n}\n\n<div\n class=\"st-input-wrapper\"\n [class.full-width]=\"fullWidth()\"\n [class.disabled]=\"effectiveDisabled()\"\n [class.open]=\"open()\"\n [stOverlay]=\"calendarOverlay\"\n [overlayOpen]=\"open()\"\n [overlayPlacement]=\"placement()\"\n>\n <input\n type=\"text\"\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [value]=\"textInputValue()\"\n [disabled]=\"effectiveDisabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onInputTextChange($any($event.target).value)\"\n (blur)=\"onInputBlur()\"\n (click)=\"toggle($event)\"\n (keydown.enter)=\"toggle($event)\"\n (keydown.escape)=\"open.set(false)\"\n />\n\n <div class=\"affix\">\n @if (clearable() && value() && !effectiveDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"st-icon-btn\"\n (click)=\"clear($event)\"\n aria-label=\"Clear date\"\n >\n <st-icon name=\"close\" size=\"xs\"></st-icon>\n </button>\n }\n\n <span class=\"st-trigger-icon\" (click)=\"toggle($event)\">\n <st-icon name=\"calendar\" size=\"xs\"></st-icon>\n </span>\n </div>\n</div>\n\n@if (message()) {\n <div class=\"st-input-field-footer\">\n <span\n class=\"st-input-field-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </span>\n </div>\n}\n\n<ng-template #calendarOverlay>\n <div class=\"st-datepicker-dropdown\" [class.st-datepicker-with-time]=\"showTime()\">\n <st-calendar\n mode=\"single\"\n [size]=\"calendarSize()\"\n [locale]=\"locale()\"\n [value]=\"value()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [disabledDates]=\"disabledDates()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n (dateSelected)=\"onCalendarDateSelected($event)\"\n ></st-calendar>\n @if (showTime()) {\n <div class=\"st-datepicker-time-side\">\n <st-time-picker\n [value]=\"value()\"\n [format]=\"timeFormat()\"\n [showSeconds]=\"showSeconds()\"\n [minuteStep]=\"minuteStep()\"\n [disabled]=\"effectiveDisabled()\"\n (valueChange)=\"onTimeSelected($event)\"\n ></st-time-picker>\n </div>\n }\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%}:host label{margin-bottom:var(--st-space-2)}.st-input-wrapper{display:flex;align-items:center;box-sizing:border-box;height:var(--st-interactive-element-height-md);background-color:var(--st-color-bg-raised);border:1px solid var(--st-border-muted);border-radius:var(--st-border-radius-md);overflow:hidden;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast)}.st-input-wrapper:hover{background-color:var(--st-color-input-hover);border-color:var(--st-color-border-strong)}.st-input-wrapper:focus-within,.st-input-wrapper.open{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}:host(.st-size-sm) .st-input-wrapper{height:var(--st-interactive-element-height-sm);border-radius:var(--st-border-radius-sm)}:host(.st-size-sm) input{padding:0 var(--st-size-xxs);font-size:var(--st-font-sm)}:host(.st-size-sm) .affix{padding-right:var(--st-size-xxs)}:host(.st-size-lg) .st-input-wrapper{height:var(--st-interactive-element-height-lg)}:host(.st-state-error) .st-input-wrapper,:host(.st-error) .st-input-wrapper{border-color:var(--st-color-feedback-error-default);outline-color:var(--st-color-feedback-error-default)}:host(.st-state-success) .st-input-wrapper{border-color:var(--st-color-feedback-success-default);outline-color:var(--st-color-feedback-success-default)}:host(.st-state-warning) .st-input-wrapper{border-color:var(--st-color-feedback-warning-default);outline-color:var(--st-color-feedback-warning-default)}:host(.st-disabled){opacity:.55;pointer-events:none;cursor:not-allowed}input{border:none;background:none;width:100%;padding:0 var(--st-size-xs);color:var(--st-color-text-primary);font-size:var(--st-font-md);font-family:inherit;height:100%;cursor:pointer;outline:none}input::placeholder{color:var(--st-color-text-tertiary)}.affix{display:flex;align-items:center;padding-right:var(--st-size-xs);gap:var(--st-space-1);color:var(--st-color-text-tertiary)}.st-icon-btn,.st-trigger-icon{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);transition:color var(--st-transition-fast)}.st-icon-btn:hover,.st-trigger-icon:hover{color:var(--st-color-text-primary)}.st-input-field-footer{display:flex;margin-top:var(--st-space-1);line-height:1.25}.st-input-field-message{font-size:var(--st-font-sm);color:var(--st-color-text-secondary)}.st-input-field-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-input-field-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-input-field-message.st-message-warning{color:var(--st-color-feedback-warning-text)}.st-datepicker-dropdown{border:1px solid var(--st-border);border-radius:var(--st-border-radius-lg);background-color:var(--st-color-bg-raised);box-shadow:var(--st-shadow-2);padding:var(--st-space-3);overflow:hidden;animation:st-popover-in var(--st-transition-fast) ease-out}.st-datepicker-dropdown.st-datepicker-with-time{display:flex;align-items:stretch;gap:0;padding:0}.st-datepicker-dropdown.st-datepicker-with-time>st-calendar{padding:var(--st-space-3)}.st-datepicker-time-side{display:flex;align-items:center;justify-content:center;padding:var(--st-space-3) var(--st-space-4);border-left:1px solid var(--st-border-subtle)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataCalendarComponent, selector: "st-calendar", inputs: ["mode", "size", "locale", "value", "rangeValue", "viewDate", "minDate", "maxDate", "disabledDates", "firstDayOfWeek", "showAdjacentMonths", "disabled"], outputs: ["valueChange", "rangeValueChange", "viewDateChange", "dateSelected", "rangeSelected"] }, { kind: "component", type: StrataTimePickerComponent, selector: "st-time-picker", inputs: ["format", "showSeconds", "minuteStep", "disabled", "value"], outputs: ["valueChange"] }] });
3127
+ ], viewQueries: [{ propertyName: "overlayDirective", first: true, predicate: StrataOverlayDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <label class=\"st-label\" [for]=\"effectiveId()\">{{ label() }}</label>\n}\n\n<div\n class=\"st-input-wrapper\"\n [class.full-width]=\"fullWidth()\"\n [class.disabled]=\"effectiveDisabled()\"\n [class.open]=\"open()\"\n [stOverlay]=\"calendarOverlay\"\n [overlayOpen]=\"open()\"\n [overlayPlacement]=\"placement()\"\n>\n <input\n type=\"text\"\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [value]=\"textInputValue()\"\n [disabled]=\"effectiveDisabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onInputTextChange($any($event.target).value)\"\n (blur)=\"onInputBlur()\"\n (click)=\"toggle($event)\"\n (keydown.enter)=\"toggle($event)\"\n (keydown.escape)=\"open.set(false)\"\n />\n\n <div class=\"affix\">\n @if (clearable() && value() && !effectiveDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"st-icon-btn\"\n (click)=\"clear($event)\"\n aria-label=\"Clear date\"\n >\n <st-icon name=\"close\" size=\"xs\"></st-icon>\n </button>\n }\n\n <span class=\"st-trigger-icon\" (click)=\"toggle($event)\">\n <st-icon name=\"calendar\" size=\"xs\"></st-icon>\n </span>\n </div>\n</div>\n\n@if (message()) {\n <div class=\"st-input-field-footer\">\n <span\n class=\"st-input-field-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </span>\n </div>\n}\n\n<ng-template #calendarOverlay>\n <div class=\"st-datepicker-dropdown\" [class.st-datepicker-with-time]=\"showTime()\">\n <st-calendar\n mode=\"single\"\n [size]=\"calendarSize()\"\n [locale]=\"locale()\"\n [value]=\"value()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [disabledDates]=\"disabledDates()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n (dateSelected)=\"onCalendarDateSelected($event)\"\n ></st-calendar>\n @if (showTime()) {\n <div class=\"st-datepicker-time-side\">\n <st-time-stepper\n [value]=\"value()\"\n [format]=\"timeFormat()\"\n [showSeconds]=\"showSeconds()\"\n [minuteStep]=\"minuteStep()\"\n [disabled]=\"effectiveDisabled()\"\n (valueChange)=\"onTimeSelected($event)\"\n ></st-time-stepper>\n </div>\n }\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%}:host label{margin-bottom:var(--st-space-2)}.st-input-wrapper{display:flex;align-items:center;box-sizing:border-box;height:var(--st-interactive-element-height-md);background-color:var(--st-color-bg-raised);border:1px solid var(--st-border-muted);border-radius:var(--st-border-radius-md);overflow:hidden;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast)}.st-input-wrapper:hover{background-color:var(--st-color-input-hover);border-color:var(--st-color-border-strong)}.st-input-wrapper:focus-within,.st-input-wrapper.open{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}:host(.st-size-sm) .st-input-wrapper{height:var(--st-interactive-element-height-sm);border-radius:var(--st-border-radius-sm)}:host(.st-size-sm) input{padding:0 var(--st-size-xxs);font-size:var(--st-font-sm)}:host(.st-size-sm) .affix{padding-right:var(--st-size-xxs)}:host(.st-size-lg) .st-input-wrapper{height:var(--st-interactive-element-height-lg)}:host(.st-state-error) .st-input-wrapper,:host(.st-error) .st-input-wrapper{border-color:var(--st-color-feedback-error-default);outline-color:var(--st-color-feedback-error-default)}:host(.st-state-success) .st-input-wrapper{border-color:var(--st-color-feedback-success-default);outline-color:var(--st-color-feedback-success-default)}:host(.st-state-warning) .st-input-wrapper{border-color:var(--st-color-feedback-warning-default);outline-color:var(--st-color-feedback-warning-default)}:host(.st-disabled){opacity:.55;pointer-events:none;cursor:not-allowed}input{border:none;background:none;width:100%;padding:0 var(--st-size-xs);color:var(--st-color-text-primary);font-size:var(--st-font-md);font-family:inherit;height:100%;cursor:pointer;outline:none}input::placeholder{color:var(--st-color-text-tertiary)}.affix{display:flex;align-items:center;padding-right:var(--st-size-xs);gap:var(--st-space-1);color:var(--st-color-text-tertiary)}.st-icon-btn,.st-trigger-icon{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);transition:color var(--st-transition-fast)}.st-icon-btn:hover,.st-trigger-icon:hover{color:var(--st-color-text-primary)}.st-input-field-footer{display:flex;margin-top:var(--st-space-1);line-height:1.25}.st-input-field-message{font-size:var(--st-font-sm);color:var(--st-color-text-secondary)}.st-input-field-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-input-field-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-input-field-message.st-message-warning{color:var(--st-color-feedback-warning-text)}.st-datepicker-dropdown{border:1px solid var(--st-border);border-radius:var(--st-border-radius-lg);background-color:var(--st-color-bg-raised);box-shadow:var(--st-shadow-2);padding:var(--st-space-3);overflow:hidden;animation:st-popover-in var(--st-transition-fast) ease-out}.st-datepicker-dropdown.st-datepicker-with-time{display:flex;align-items:stretch;gap:0;padding:0}.st-datepicker-dropdown.st-datepicker-with-time>st-calendar{padding:var(--st-space-3)}.st-datepicker-time-side{display:flex;align-items:center;justify-content:center;padding:var(--st-space-3) var(--st-space-4);border-left:1px solid var(--st-border-subtle)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport", "overlayTarget"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataCalendarComponent, selector: "st-calendar", inputs: ["mode", "size", "locale", "value", "rangeValue", "viewDate", "minDate", "maxDate", "disabledDates", "firstDayOfWeek", "showAdjacentMonths", "disabled"], outputs: ["valueChange", "rangeValueChange", "viewDateChange", "dateSelected", "rangeSelected"] }, { kind: "component", type: StrataTimeStepperComponent, selector: "st-time-stepper", inputs: ["format", "showSeconds", "minuteStep", "disabled", "value"], outputs: ["valueChange"] }] });
2626
3128
  }
2627
3129
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataDatePickerComponent, decorators: [{
2628
3130
  type: Component,
@@ -2632,7 +3134,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
2632
3134
  StrataIconComponent,
2633
3135
  StrataOverlayDirective,
2634
3136
  StrataCalendarComponent,
2635
- StrataTimePickerComponent
3137
+ StrataTimeStepperComponent
2636
3138
  ], providers: [
2637
3139
  {
2638
3140
  provide: NG_VALUE_ACCESSOR,
@@ -2651,7 +3153,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
2651
3153
  '[class.st-state-warning]': 'effectiveState() === "warning"',
2652
3154
  '[class.st-error]': 'effectiveState() === "error"',
2653
3155
  '[attr.aria-invalid]': 'effectiveState() === "error" ? "true" : null'
2654
- }, template: "@if (label()) {\n <label class=\"st-label\" [for]=\"effectiveId()\">{{ label() }}</label>\n}\n\n<div\n class=\"st-input-wrapper\"\n [class.full-width]=\"fullWidth()\"\n [class.disabled]=\"effectiveDisabled()\"\n [class.open]=\"open()\"\n [stOverlay]=\"calendarOverlay\"\n [overlayOpen]=\"open()\"\n [overlayPlacement]=\"placement()\"\n>\n <input\n type=\"text\"\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [value]=\"textInputValue()\"\n [disabled]=\"effectiveDisabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onInputTextChange($any($event.target).value)\"\n (blur)=\"onInputBlur()\"\n (click)=\"toggle($event)\"\n (keydown.enter)=\"toggle($event)\"\n (keydown.escape)=\"open.set(false)\"\n />\n\n <div class=\"affix\">\n @if (clearable() && value() && !effectiveDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"st-icon-btn\"\n (click)=\"clear($event)\"\n aria-label=\"Clear date\"\n >\n <st-icon name=\"close\" size=\"xs\"></st-icon>\n </button>\n }\n\n <span class=\"st-trigger-icon\" (click)=\"toggle($event)\">\n <st-icon name=\"calendar\" size=\"xs\"></st-icon>\n </span>\n </div>\n</div>\n\n@if (message()) {\n <div class=\"st-input-field-footer\">\n <span\n class=\"st-input-field-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </span>\n </div>\n}\n\n<ng-template #calendarOverlay>\n <div class=\"st-datepicker-dropdown\" [class.st-datepicker-with-time]=\"showTime()\">\n <st-calendar\n mode=\"single\"\n [size]=\"calendarSize()\"\n [locale]=\"locale()\"\n [value]=\"value()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [disabledDates]=\"disabledDates()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n (dateSelected)=\"onCalendarDateSelected($event)\"\n ></st-calendar>\n @if (showTime()) {\n <div class=\"st-datepicker-time-side\">\n <st-time-picker\n [value]=\"value()\"\n [format]=\"timeFormat()\"\n [showSeconds]=\"showSeconds()\"\n [minuteStep]=\"minuteStep()\"\n [disabled]=\"effectiveDisabled()\"\n (valueChange)=\"onTimeSelected($event)\"\n ></st-time-picker>\n </div>\n }\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%}:host label{margin-bottom:var(--st-space-2)}.st-input-wrapper{display:flex;align-items:center;box-sizing:border-box;height:var(--st-interactive-element-height-md);background-color:var(--st-color-bg-raised);border:1px solid var(--st-border-muted);border-radius:var(--st-border-radius-md);overflow:hidden;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast)}.st-input-wrapper:hover{background-color:var(--st-color-input-hover);border-color:var(--st-color-border-strong)}.st-input-wrapper:focus-within,.st-input-wrapper.open{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}:host(.st-size-sm) .st-input-wrapper{height:var(--st-interactive-element-height-sm);border-radius:var(--st-border-radius-sm)}:host(.st-size-sm) input{padding:0 var(--st-size-xxs);font-size:var(--st-font-sm)}:host(.st-size-sm) .affix{padding-right:var(--st-size-xxs)}:host(.st-size-lg) .st-input-wrapper{height:var(--st-interactive-element-height-lg)}:host(.st-state-error) .st-input-wrapper,:host(.st-error) .st-input-wrapper{border-color:var(--st-color-feedback-error-default);outline-color:var(--st-color-feedback-error-default)}:host(.st-state-success) .st-input-wrapper{border-color:var(--st-color-feedback-success-default);outline-color:var(--st-color-feedback-success-default)}:host(.st-state-warning) .st-input-wrapper{border-color:var(--st-color-feedback-warning-default);outline-color:var(--st-color-feedback-warning-default)}:host(.st-disabled){opacity:.55;pointer-events:none;cursor:not-allowed}input{border:none;background:none;width:100%;padding:0 var(--st-size-xs);color:var(--st-color-text-primary);font-size:var(--st-font-md);font-family:inherit;height:100%;cursor:pointer;outline:none}input::placeholder{color:var(--st-color-text-tertiary)}.affix{display:flex;align-items:center;padding-right:var(--st-size-xs);gap:var(--st-space-1);color:var(--st-color-text-tertiary)}.st-icon-btn,.st-trigger-icon{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);transition:color var(--st-transition-fast)}.st-icon-btn:hover,.st-trigger-icon:hover{color:var(--st-color-text-primary)}.st-input-field-footer{display:flex;margin-top:var(--st-space-1);line-height:1.25}.st-input-field-message{font-size:var(--st-font-sm);color:var(--st-color-text-secondary)}.st-input-field-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-input-field-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-input-field-message.st-message-warning{color:var(--st-color-feedback-warning-text)}.st-datepicker-dropdown{border:1px solid var(--st-border);border-radius:var(--st-border-radius-lg);background-color:var(--st-color-bg-raised);box-shadow:var(--st-shadow-2);padding:var(--st-space-3);overflow:hidden;animation:st-popover-in var(--st-transition-fast) ease-out}.st-datepicker-dropdown.st-datepicker-with-time{display:flex;align-items:stretch;gap:0;padding:0}.st-datepicker-dropdown.st-datepicker-with-time>st-calendar{padding:var(--st-space-3)}.st-datepicker-time-side{display:flex;align-items:center;justify-content:center;padding:var(--st-space-3) var(--st-space-4);border-left:1px solid var(--st-border-subtle)}\n"] }]
3156
+ }, template: "@if (label()) {\n <label class=\"st-label\" [for]=\"effectiveId()\">{{ label() }}</label>\n}\n\n<div\n class=\"st-input-wrapper\"\n [class.full-width]=\"fullWidth()\"\n [class.disabled]=\"effectiveDisabled()\"\n [class.open]=\"open()\"\n [stOverlay]=\"calendarOverlay\"\n [overlayOpen]=\"open()\"\n [overlayPlacement]=\"placement()\"\n>\n <input\n type=\"text\"\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [value]=\"textInputValue()\"\n [disabled]=\"effectiveDisabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onInputTextChange($any($event.target).value)\"\n (blur)=\"onInputBlur()\"\n (click)=\"toggle($event)\"\n (keydown.enter)=\"toggle($event)\"\n (keydown.escape)=\"open.set(false)\"\n />\n\n <div class=\"affix\">\n @if (clearable() && value() && !effectiveDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"st-icon-btn\"\n (click)=\"clear($event)\"\n aria-label=\"Clear date\"\n >\n <st-icon name=\"close\" size=\"xs\"></st-icon>\n </button>\n }\n\n <span class=\"st-trigger-icon\" (click)=\"toggle($event)\">\n <st-icon name=\"calendar\" size=\"xs\"></st-icon>\n </span>\n </div>\n</div>\n\n@if (message()) {\n <div class=\"st-input-field-footer\">\n <span\n class=\"st-input-field-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </span>\n </div>\n}\n\n<ng-template #calendarOverlay>\n <div class=\"st-datepicker-dropdown\" [class.st-datepicker-with-time]=\"showTime()\">\n <st-calendar\n mode=\"single\"\n [size]=\"calendarSize()\"\n [locale]=\"locale()\"\n [value]=\"value()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [disabledDates]=\"disabledDates()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n (dateSelected)=\"onCalendarDateSelected($event)\"\n ></st-calendar>\n @if (showTime()) {\n <div class=\"st-datepicker-time-side\">\n <st-time-stepper\n [value]=\"value()\"\n [format]=\"timeFormat()\"\n [showSeconds]=\"showSeconds()\"\n [minuteStep]=\"minuteStep()\"\n [disabled]=\"effectiveDisabled()\"\n (valueChange)=\"onTimeSelected($event)\"\n ></st-time-stepper>\n </div>\n }\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%}:host label{margin-bottom:var(--st-space-2)}.st-input-wrapper{display:flex;align-items:center;box-sizing:border-box;height:var(--st-interactive-element-height-md);background-color:var(--st-color-bg-raised);border:1px solid var(--st-border-muted);border-radius:var(--st-border-radius-md);overflow:hidden;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast)}.st-input-wrapper:hover{background-color:var(--st-color-input-hover);border-color:var(--st-color-border-strong)}.st-input-wrapper:focus-within,.st-input-wrapper.open{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}:host(.st-size-sm) .st-input-wrapper{height:var(--st-interactive-element-height-sm);border-radius:var(--st-border-radius-sm)}:host(.st-size-sm) input{padding:0 var(--st-size-xxs);font-size:var(--st-font-sm)}:host(.st-size-sm) .affix{padding-right:var(--st-size-xxs)}:host(.st-size-lg) .st-input-wrapper{height:var(--st-interactive-element-height-lg)}:host(.st-state-error) .st-input-wrapper,:host(.st-error) .st-input-wrapper{border-color:var(--st-color-feedback-error-default);outline-color:var(--st-color-feedback-error-default)}:host(.st-state-success) .st-input-wrapper{border-color:var(--st-color-feedback-success-default);outline-color:var(--st-color-feedback-success-default)}:host(.st-state-warning) .st-input-wrapper{border-color:var(--st-color-feedback-warning-default);outline-color:var(--st-color-feedback-warning-default)}:host(.st-disabled){opacity:.55;pointer-events:none;cursor:not-allowed}input{border:none;background:none;width:100%;padding:0 var(--st-size-xs);color:var(--st-color-text-primary);font-size:var(--st-font-md);font-family:inherit;height:100%;cursor:pointer;outline:none}input::placeholder{color:var(--st-color-text-tertiary)}.affix{display:flex;align-items:center;padding-right:var(--st-size-xs);gap:var(--st-space-1);color:var(--st-color-text-tertiary)}.st-icon-btn,.st-trigger-icon{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);transition:color var(--st-transition-fast)}.st-icon-btn:hover,.st-trigger-icon:hover{color:var(--st-color-text-primary)}.st-input-field-footer{display:flex;margin-top:var(--st-space-1);line-height:1.25}.st-input-field-message{font-size:var(--st-font-sm);color:var(--st-color-text-secondary)}.st-input-field-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-input-field-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-input-field-message.st-message-warning{color:var(--st-color-feedback-warning-text)}.st-datepicker-dropdown{border:1px solid var(--st-border);border-radius:var(--st-border-radius-lg);background-color:var(--st-color-bg-raised);box-shadow:var(--st-shadow-2);padding:var(--st-space-3);overflow:hidden;animation:st-popover-in var(--st-transition-fast) ease-out}.st-datepicker-dropdown.st-datepicker-with-time{display:flex;align-items:stretch;gap:0;padding:0}.st-datepicker-dropdown.st-datepicker-with-time>st-calendar{padding:var(--st-space-3)}.st-datepicker-time-side{display:flex;align-items:center;justify-content:center;padding:var(--st-space-3) var(--st-space-4);border-left:1px solid var(--st-border-subtle)}\n"] }]
2655
3157
  }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], timeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeFormat", required: false }] }], showSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSeconds", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], colorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorMessage", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], disabledDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDates", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], dateSelected: [{ type: i0.Output, args: ["dateSelected"] }], overlayDirective: [{ type: i0.ViewChild, args: [i0.forwardRef(() => StrataOverlayDirective), { isSignal: true }] }] } });
2656
3158
 
2657
3159
  let nextUniqueDateRangePickerId = 0;
@@ -2916,7 +3418,7 @@ class StrataDateRangePickerComponent {
2916
3418
  useExisting: forwardRef(() => StrataDateRangePickerComponent),
2917
3419
  multi: true
2918
3420
  }
2919
- ], viewQueries: [{ propertyName: "overlayDirective", first: true, predicate: StrataOverlayDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <label class=\"st-label\" [for]=\"effectiveId()\">{{ label() }}</label>\n}\n\n<div\n class=\"st-input-wrapper\"\n [class.full-width]=\"fullWidth()\"\n [class.disabled]=\"effectiveDisabled()\"\n [class.open]=\"open()\"\n [stOverlay]=\"rangeCalendarOverlay\"\n [overlayOpen]=\"open()\"\n [overlayPlacement]=\"placement()\"\n>\n <input\n type=\"text\"\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [value]=\"textInputValue()\"\n [disabled]=\"effectiveDisabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onInputTextChange($any($event.target).value)\"\n (blur)=\"onInputBlur()\"\n (click)=\"toggle($event)\"\n (keydown.enter)=\"toggle($event)\"\n (keydown.escape)=\"open.set(false)\"\n />\n\n <div class=\"affix\">\n @if (clearable() && value() && !effectiveDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"st-icon-btn\"\n (click)=\"clear($event)\"\n aria-label=\"Clear date range\"\n >\n <st-icon name=\"close\" size=\"xs\"></st-icon>\n </button>\n }\n\n <span class=\"st-trigger-icon\" (click)=\"toggle($event)\">\n <st-icon name=\"calendar\" size=\"xs\"></st-icon>\n </span>\n </div>\n</div>\n\n@if (message()) {\n <div class=\"st-input-field-footer\">\n <span\n class=\"st-input-field-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </span>\n </div>\n}\n\n<ng-template #rangeCalendarOverlay>\n <div class=\"st-date-range-dropdown\">\n @if (showPresets() && presets().length > 0) {\n <div class=\"st-date-range-presets\">\n <div class=\"st-presets-title\">Presets</div>\n @for (preset of presets(); track preset.label) {\n <button\n type=\"button\"\n class=\"st-preset-btn\"\n (click)=\"applyPreset(preset)\"\n >\n {{ preset.label }}\n </button>\n }\n </div>\n }\n\n <div class=\"st-date-range-calendars\">\n <st-calendar\n mode=\"range\"\n [size]=\"calendarSize()\"\n [locale]=\"locale()\"\n [rangeValue]=\"value()\"\n [viewDate]=\"calendarViewDate()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [disabledDates]=\"disabledDates()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n (rangeSelected)=\"onCalendarRangeSelected($event)\"\n (viewDateChange)=\"calendarViewDate.set($event)\"\n ></st-calendar>\n\n @if (numberOfMonths() >= 2) {\n <st-calendar\n mode=\"range\"\n [size]=\"calendarSize()\"\n [locale]=\"locale()\"\n [rangeValue]=\"value()\"\n [viewDate]=\"secondCalendarViewDate()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [disabledDates]=\"disabledDates()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n (rangeSelected)=\"onCalendarRangeSelected($event)\"\n (viewDateChange)=\"onSecondCalendarViewDateChange($event)\"\n ></st-calendar>\n }\n </div>\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%}:host label{margin-bottom:var(--st-space-2)}.st-input-wrapper{display:flex;align-items:center;box-sizing:border-box;height:var(--st-interactive-element-height-md);background-color:var(--st-color-bg-raised);border:1px solid var(--st-border-muted);border-radius:var(--st-border-radius-md);overflow:hidden;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast)}.st-input-wrapper:hover{background-color:var(--st-color-input-hover);border-color:var(--st-color-border-strong)}.st-input-wrapper:focus-within,.st-input-wrapper.open{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}:host(.st-size-sm) .st-input-wrapper{height:var(--st-interactive-element-height-sm);border-radius:var(--st-border-radius-sm)}:host(.st-size-sm) input{padding:0 var(--st-size-xxs);font-size:var(--st-font-sm)}:host(.st-size-sm) .affix{padding-right:var(--st-size-xxs)}:host(.st-size-lg) .st-input-wrapper{height:var(--st-interactive-element-height-lg)}:host(.st-state-error) .st-input-wrapper,:host(.st-error) .st-input-wrapper{border-color:var(--st-color-feedback-error-default);outline-color:var(--st-color-feedback-error-default)}:host(.st-state-success) .st-input-wrapper{border-color:var(--st-color-feedback-success-default);outline-color:var(--st-color-feedback-success-default)}:host(.st-state-warning) .st-input-wrapper{border-color:var(--st-color-feedback-warning-default);outline-color:var(--st-color-feedback-warning-default)}:host(.st-disabled){opacity:.55;pointer-events:none;cursor:not-allowed}input{border:none;background:none;width:100%;padding:0 var(--st-size-xs);color:var(--st-color-text-primary);font-size:var(--st-font-md);font-family:inherit;height:100%;cursor:pointer;outline:none}input::placeholder{color:var(--st-color-text-tertiary)}.affix{display:flex;align-items:center;padding-right:var(--st-size-xs);gap:var(--st-space-1);color:var(--st-color-text-tertiary)}.st-icon-btn,.st-trigger-icon{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);transition:color var(--st-transition-fast)}.st-icon-btn:hover,.st-trigger-icon:hover{color:var(--st-color-text-primary)}.st-input-field-footer{display:flex;margin-top:var(--st-space-1);line-height:1.25}.st-input-field-message{font-size:var(--st-font-sm);color:var(--st-color-text-secondary)}.st-input-field-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-input-field-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-input-field-message.st-message-warning{color:var(--st-color-feedback-warning-text)}.st-date-range-dropdown{display:flex;background-color:var(--st-color-bg-raised);border:1px solid var(--st-border);border-radius:var(--st-border-radius-lg);box-shadow:var(--st-shadow-2);overflow:hidden;animation:st-popover-in var(--st-transition-fast) ease-out}.st-date-range-presets{display:flex;flex-direction:column;padding:var(--st-space-2);border-right:1px solid var(--st-border-subtle);min-width:130px;gap:2px}.st-presets-title{font-size:.75rem;font-weight:var(--st-font-weight-semibold);color:var(--st-color-text-tertiary);padding:4px 8px;text-transform:uppercase;letter-spacing:.05em}.st-preset-btn{background:transparent;border:none;font-family:inherit;font-size:var(--st-font-sm);color:var(--st-color-text-secondary);padding:6px 8px;border-radius:var(--st-border-radius-sm);text-align:left;cursor:pointer;transition:background-color var(--st-transition-fast),color var(--st-transition-fast)}.st-preset-btn:hover{background-color:var(--st-color-control-bg-hover, var(--st-color-bg-default));color:var(--st-color-text-primary)}.st-date-range-calendars{display:flex;gap:var(--st-space-4);padding:var(--st-space-3)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataCalendarComponent, selector: "st-calendar", inputs: ["mode", "size", "locale", "value", "rangeValue", "viewDate", "minDate", "maxDate", "disabledDates", "firstDayOfWeek", "showAdjacentMonths", "disabled"], outputs: ["valueChange", "rangeValueChange", "viewDateChange", "dateSelected", "rangeSelected"] }] });
3421
+ ], viewQueries: [{ propertyName: "overlayDirective", first: true, predicate: StrataOverlayDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <label class=\"st-label\" [for]=\"effectiveId()\">{{ label() }}</label>\n}\n\n<div\n class=\"st-input-wrapper\"\n [class.full-width]=\"fullWidth()\"\n [class.disabled]=\"effectiveDisabled()\"\n [class.open]=\"open()\"\n [stOverlay]=\"rangeCalendarOverlay\"\n [overlayOpen]=\"open()\"\n [overlayPlacement]=\"placement()\"\n>\n <input\n type=\"text\"\n [id]=\"effectiveId()\"\n [placeholder]=\"placeholder()\"\n [value]=\"textInputValue()\"\n [disabled]=\"effectiveDisabled()\"\n [readonly]=\"readonly()\"\n (input)=\"onInputTextChange($any($event.target).value)\"\n (blur)=\"onInputBlur()\"\n (click)=\"toggle($event)\"\n (keydown.enter)=\"toggle($event)\"\n (keydown.escape)=\"open.set(false)\"\n />\n\n <div class=\"affix\">\n @if (clearable() && value() && !effectiveDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"st-icon-btn\"\n (click)=\"clear($event)\"\n aria-label=\"Clear date range\"\n >\n <st-icon name=\"close\" size=\"xs\"></st-icon>\n </button>\n }\n\n <span class=\"st-trigger-icon\" (click)=\"toggle($event)\">\n <st-icon name=\"calendar\" size=\"xs\"></st-icon>\n </span>\n </div>\n</div>\n\n@if (message()) {\n <div class=\"st-input-field-footer\">\n <span\n class=\"st-input-field-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </span>\n </div>\n}\n\n<ng-template #rangeCalendarOverlay>\n <div class=\"st-date-range-dropdown\">\n @if (showPresets() && presets().length > 0) {\n <div class=\"st-date-range-presets\">\n <div class=\"st-presets-title\">Presets</div>\n @for (preset of presets(); track preset.label) {\n <button\n type=\"button\"\n class=\"st-preset-btn\"\n (click)=\"applyPreset(preset)\"\n >\n {{ preset.label }}\n </button>\n }\n </div>\n }\n\n <div class=\"st-date-range-calendars\">\n <st-calendar\n mode=\"range\"\n [size]=\"calendarSize()\"\n [locale]=\"locale()\"\n [rangeValue]=\"value()\"\n [viewDate]=\"calendarViewDate()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [disabledDates]=\"disabledDates()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n (rangeSelected)=\"onCalendarRangeSelected($event)\"\n (viewDateChange)=\"calendarViewDate.set($event)\"\n ></st-calendar>\n\n @if (numberOfMonths() >= 2) {\n <st-calendar\n mode=\"range\"\n [size]=\"calendarSize()\"\n [locale]=\"locale()\"\n [rangeValue]=\"value()\"\n [viewDate]=\"secondCalendarViewDate()\"\n [minDate]=\"minDate()\"\n [maxDate]=\"maxDate()\"\n [disabledDates]=\"disabledDates()\"\n [firstDayOfWeek]=\"firstDayOfWeek()\"\n (rangeSelected)=\"onCalendarRangeSelected($event)\"\n (viewDateChange)=\"onSecondCalendarViewDateChange($event)\"\n ></st-calendar>\n }\n </div>\n </div>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;box-sizing:border-box;width:100%}:host label{margin-bottom:var(--st-space-2)}.st-input-wrapper{display:flex;align-items:center;box-sizing:border-box;height:var(--st-interactive-element-height-md);background-color:var(--st-color-bg-raised);border:1px solid var(--st-border-muted);border-radius:var(--st-border-radius-md);overflow:hidden;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast)}.st-input-wrapper:hover{background-color:var(--st-color-input-hover);border-color:var(--st-color-border-strong)}.st-input-wrapper:focus-within,.st-input-wrapper.open{outline:var(--st-focus-ring-width) var(--st-focus-ring-style) var(--st-focus-ring-color);outline-offset:var(--st-focus-ring-offset);border-color:var(--st-color-border-strong)}:host(.st-size-sm) .st-input-wrapper{height:var(--st-interactive-element-height-sm);border-radius:var(--st-border-radius-sm)}:host(.st-size-sm) input{padding:0 var(--st-size-xxs);font-size:var(--st-font-sm)}:host(.st-size-sm) .affix{padding-right:var(--st-size-xxs)}:host(.st-size-lg) .st-input-wrapper{height:var(--st-interactive-element-height-lg)}:host(.st-state-error) .st-input-wrapper,:host(.st-error) .st-input-wrapper{border-color:var(--st-color-feedback-error-default);outline-color:var(--st-color-feedback-error-default)}:host(.st-state-success) .st-input-wrapper{border-color:var(--st-color-feedback-success-default);outline-color:var(--st-color-feedback-success-default)}:host(.st-state-warning) .st-input-wrapper{border-color:var(--st-color-feedback-warning-default);outline-color:var(--st-color-feedback-warning-default)}:host(.st-disabled){opacity:.55;pointer-events:none;cursor:not-allowed}input{border:none;background:none;width:100%;padding:0 var(--st-size-xs);color:var(--st-color-text-primary);font-size:var(--st-font-md);font-family:inherit;height:100%;cursor:pointer;outline:none}input::placeholder{color:var(--st-color-text-tertiary)}.affix{display:flex;align-items:center;padding-right:var(--st-size-xs);gap:var(--st-space-1);color:var(--st-color-text-tertiary)}.st-icon-btn,.st-trigger-icon{background:transparent;border:none;padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--st-color-text-tertiary);transition:color var(--st-transition-fast)}.st-icon-btn:hover,.st-trigger-icon:hover{color:var(--st-color-text-primary)}.st-input-field-footer{display:flex;margin-top:var(--st-space-1);line-height:1.25}.st-input-field-message{font-size:var(--st-font-sm);color:var(--st-color-text-secondary)}.st-input-field-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-input-field-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-input-field-message.st-message-warning{color:var(--st-color-feedback-warning-text)}.st-date-range-dropdown{display:flex;background-color:var(--st-color-bg-raised);border:1px solid var(--st-border);border-radius:var(--st-border-radius-lg);box-shadow:var(--st-shadow-2);overflow:hidden;animation:st-popover-in var(--st-transition-fast) ease-out}.st-date-range-presets{display:flex;flex-direction:column;padding:var(--st-space-2);border-right:1px solid var(--st-border-subtle);min-width:130px;gap:2px}.st-presets-title{font-size:.75rem;font-weight:var(--st-font-weight-semibold);color:var(--st-color-text-tertiary);padding:4px 8px;text-transform:uppercase;letter-spacing:.05em}.st-preset-btn{background:transparent;border:none;font-family:inherit;font-size:var(--st-font-sm);color:var(--st-color-text-secondary);padding:6px 8px;border-radius:var(--st-border-radius-sm);text-align:left;cursor:pointer;transition:background-color var(--st-transition-fast),color var(--st-transition-fast)}.st-preset-btn:hover{background-color:var(--st-color-control-bg-hover, var(--st-color-bg-default));color:var(--st-color-text-primary)}.st-date-range-calendars{display:flex;gap:var(--st-space-4);padding:var(--st-space-3)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport", "overlayTarget"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataCalendarComponent, selector: "st-calendar", inputs: ["mode", "size", "locale", "value", "rangeValue", "viewDate", "minDate", "maxDate", "disabledDates", "firstDayOfWeek", "showAdjacentMonths", "disabled"], outputs: ["valueChange", "rangeValueChange", "viewDateChange", "dateSelected", "rangeSelected"] }] });
2920
3422
  }
2921
3423
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataDateRangePickerComponent, decorators: [{
2922
3424
  type: Component,
@@ -2964,6 +3466,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
2964
3466
  class StrataFileUploadComponent {
2965
3467
  fileInput = viewChild('fileInput', /* @ts-ignore */
2966
3468
  ...(ngDevMode ? [{ debugName: "fileInput" }] : /* istanbul ignore next */ []));
3469
+ cameraInput = viewChild('cameraInput', /* @ts-ignore */
3470
+ ...(ngDevMode ? [{ debugName: "cameraInput" }] : /* istanbul ignore next */ []));
2967
3471
  accept = input('*', /* @ts-ignore */
2968
3472
  ...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
2969
3473
  multiple = input(false, /* @ts-ignore */
@@ -2976,6 +3480,24 @@ class StrataFileUploadComponent {
2976
3480
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2977
3481
  hint = input(undefined, /* @ts-ignore */
2978
3482
  ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
3483
+ camera = input(undefined, { ...(ngDevMode ? { debugName: "camera" } : /* istanbul ignore next */ {}), transform: (val) => {
3484
+ if (val === undefined || val === null) {
3485
+ return undefined;
3486
+ }
3487
+ if (typeof val === 'string') {
3488
+ if (val === '' || val === 'true') {
3489
+ return true;
3490
+ }
3491
+ if (val === 'false') {
3492
+ return false;
3493
+ }
3494
+ }
3495
+ return Boolean(val);
3496
+ } });
3497
+ choosePhotoLabel = input('Choose Photo', /* @ts-ignore */
3498
+ ...(ngDevMode ? [{ debugName: "choosePhotoLabel" }] : /* istanbul ignore next */ []));
3499
+ takePhotoLabel = input('Take Photo', /* @ts-ignore */
3500
+ ...(ngDevMode ? [{ debugName: "takePhotoLabel" }] : /* istanbul ignore next */ []));
2979
3501
  state = input(undefined, /* @ts-ignore */
2980
3502
  ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
2981
3503
  error = input(false, { ...(ngDevMode ? { debugName: "error" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -2997,6 +3519,29 @@ class StrataFileUploadComponent {
2997
3519
  ...(ngDevMode ? [{ debugName: "isMessageSuccess" }] : /* istanbul ignore next */ []));
2998
3520
  isMessageWarning = computed(() => this.effectiveState() === 'warning' && this.colorMessage(), /* @ts-ignore */
2999
3521
  ...(ngDevMode ? [{ debugName: "isMessageWarning" }] : /* istanbul ignore next */ []));
3522
+ isImageAccept = computed(() => {
3523
+ const acc = this.accept().toLowerCase();
3524
+ if (!acc || acc === '*' || acc === '*/*') {
3525
+ return false;
3526
+ }
3527
+ const rules = acc.split(',').map((r) => r.trim());
3528
+ return rules.some((rule) => {
3529
+ return (rule.startsWith('image/') ||
3530
+ ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.heic', '.heif', '.svg'].some((ext) => rule.endsWith(ext)));
3531
+ });
3532
+ }, /* @ts-ignore */
3533
+ ...(ngDevMode ? [{ debugName: "isImageAccept" }] : /* istanbul ignore next */ []));
3534
+ showCamera = computed(() => {
3535
+ const cam = this.camera();
3536
+ if (cam === false) {
3537
+ return false;
3538
+ }
3539
+ if (cam === true) {
3540
+ return true;
3541
+ }
3542
+ return this.isImageAccept();
3543
+ }, /* @ts-ignore */
3544
+ ...(ngDevMode ? [{ debugName: "showCamera" }] : /* istanbul ignore next */ []));
3000
3545
  fileSelect = output();
3001
3546
  filesSelect = output();
3002
3547
  fileRejected = output();
@@ -3026,12 +3571,19 @@ class StrataFileUploadComponent {
3026
3571
  }
3027
3572
  onClick(event) {
3028
3573
  const target = event.target;
3029
- if (target === this.fileInput()?.nativeElement) {
3574
+ if (target === this.fileInput()?.nativeElement || target === this.cameraInput()?.nativeElement) {
3575
+ return;
3576
+ }
3577
+ if (target.closest('.st-file-upload-actions')) {
3030
3578
  return;
3031
3579
  }
3032
3580
  this.browse();
3033
3581
  }
3034
3582
  onKeydown(event) {
3583
+ const target = event.target;
3584
+ if (target.closest('.st-file-upload-actions')) {
3585
+ return;
3586
+ }
3035
3587
  event.preventDefault();
3036
3588
  this.browse();
3037
3589
  }
@@ -3067,16 +3619,27 @@ class StrataFileUploadComponent {
3067
3619
  this.processFiles(Array.from(inputEl.files));
3068
3620
  inputEl.value = '';
3069
3621
  }
3070
- browse() {
3622
+ browse(event) {
3623
+ event?.stopPropagation();
3071
3624
  if (this.disabled())
3072
3625
  return;
3073
3626
  this.fileInput()?.nativeElement.click();
3074
3627
  }
3628
+ browseCamera(event) {
3629
+ event?.stopPropagation();
3630
+ if (this.disabled())
3631
+ return;
3632
+ this.cameraInput()?.nativeElement.click();
3633
+ }
3075
3634
  clear() {
3076
3635
  const inputEl = this.fileInput()?.nativeElement;
3077
3636
  if (inputEl) {
3078
3637
  inputEl.value = '';
3079
3638
  }
3639
+ const cameraEl = this.cameraInput()?.nativeElement;
3640
+ if (cameraEl) {
3641
+ cameraEl.value = '';
3642
+ }
3080
3643
  }
3081
3644
  processFiles(files) {
3082
3645
  const acceptedFiles = [];
@@ -3119,12 +3682,17 @@ class StrataFileUploadComponent {
3119
3682
  });
3120
3683
  }
3121
3684
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataFileUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3122
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataFileUploadComponent, isStandalone: true, selector: "st-file-upload", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, colorMessage: { classPropertyName: "colorMessage", publicName: "colorMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileSelect: "fileSelect", filesSelect: "filesSelect", fileRejected: "fileRejected" }, host: { listeners: { "click": "onClick($event)", "keydown.enter": "onKeydown($event)", "keydown.space": "onKeydown($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, properties: { "class.st-disabled": "this.hostDisabled", "class.st-state-error": "this.hostError", "class.st-error": "this.hostError", "class.st-state-success": "this.hostSuccess", "class.st-state-warning": "this.hostWarning", "attr.aria-invalid": "this.hostAriaInvalid", "class.st-drag-over": "this.hostDragOver", "attr.role": "this.hostRole", "attr.tabindex": "this.hostTabIndex" } }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<input\n #fileInput\n type=\"file\"\n class=\"st-file-upload-input\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n [disabled]=\"disabled()\"\n (change)=\"onFileChange($event)\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n/>\n\n<div class=\"st-file-upload-content\">\n <div class=\"st-file-upload-icon-wrapper\">\n <ng-content select=\"[uploadIcon]\">\n <svg\n class=\"st-file-upload-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n </ng-content>\n </div>\n\n <div class=\"st-file-upload-text\">\n <span class=\"st-file-upload-label\">{{ label() }}</span>\n @if (displayMessage()) {\n <span\n class=\"st-file-upload-hint\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >{{ displayMessage() }}</span>\n }\n </div>\n\n <ng-content></ng-content>\n</div>\n" });
3685
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataFileUploadComponent, isStandalone: true, selector: "st-file-upload", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, camera: { classPropertyName: "camera", publicName: "camera", isSignal: true, isRequired: false, transformFunction: null }, choosePhotoLabel: { classPropertyName: "choosePhotoLabel", publicName: "choosePhotoLabel", isSignal: true, isRequired: false, transformFunction: null }, takePhotoLabel: { classPropertyName: "takePhotoLabel", publicName: "takePhotoLabel", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, colorMessage: { classPropertyName: "colorMessage", publicName: "colorMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileSelect: "fileSelect", filesSelect: "filesSelect", fileRejected: "fileRejected" }, host: { listeners: { "click": "onClick($event)", "keydown.enter": "onKeydown($event)", "keydown.space": "onKeydown($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, properties: { "class.st-disabled": "this.hostDisabled", "class.st-state-error": "this.hostError", "class.st-error": "this.hostError", "class.st-state-success": "this.hostSuccess", "class.st-state-warning": "this.hostWarning", "attr.aria-invalid": "this.hostAriaInvalid", "class.st-drag-over": "this.hostDragOver", "attr.role": "this.hostRole", "attr.tabindex": "this.hostTabIndex" } }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }, { propertyName: "cameraInput", first: true, predicate: ["cameraInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<input\n #fileInput\n type=\"file\"\n class=\"st-file-upload-input\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n [disabled]=\"disabled()\"\n (change)=\"onFileChange($event)\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n/>\n\n@if (showCamera()) {\n <input\n #cameraInput\n type=\"file\"\n class=\"st-file-upload-input\"\n accept=\"image/*\"\n capture=\"environment\"\n [disabled]=\"disabled()\"\n (change)=\"onFileChange($event)\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n />\n}\n\n<div class=\"st-file-upload-content\">\n <ng-content select=\"[uploadIcon]\">\n <st-avatar size=\"md\" variant=\"rounded\" class=\"st-file-upload-avatar\">\n <st-icon name=\"upload\"></st-icon>\n </st-avatar>\n </ng-content>\n\n <div class=\"st-file-upload-text\">\n <span class=\"st-file-upload-label\">{{ label() }}</span>\n @if (displayMessage()) {\n <span\n class=\"st-file-upload-hint\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >{{ displayMessage() }}</span>\n }\n </div>\n\n @if (showCamera()) {\n <st-button-group justification=\"center\" class=\"st-file-upload-actions\">\n <button\n stButton\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n [disabled]=\"disabled()\"\n (click)=\"browse($event)\"\n >\n <st-icon name=\"image\" size=\"sm\"></st-icon>\n <span>{{ choosePhotoLabel() }}</span>\n </button>\n\n <button\n stButton\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n class=\"st-file-upload-action-camera\"\n [disabled]=\"disabled()\"\n (click)=\"browseCamera($event)\"\n >\n <st-icon name=\"camera\" size=\"sm\"></st-icon>\n <span>{{ takePhotoLabel() }}</span>\n </button>\n </st-button-group>\n }\n\n <ng-content></ng-content>\n</div>\n", styles: [":host{--st-file-upload-bg: var(--st-color-bg-default);--st-file-upload-border: var(--st-color-border-default);--st-file-upload-text: var(--st-color-text-primary);--st-file-upload-hint: var(--st-color-text-secondary);--st-file-upload-hover-bg: var(--st-color-bg-raised);--st-file-upload-hover-border: var(--st-color-accent-default);--st-file-upload-active-border: var(--st-color-accent-default);--st-file-upload-active-bg: var(--st-color-accent-subtle, var(--st-color-bg-raised));--st-file-upload-radius: var(--st-border-radius-xl);display:block;position:relative;box-sizing:border-box;background-color:var(--st-file-upload-bg);border:2px dashed var(--st-file-upload-border);border-radius:var(--st-file-upload-radius);padding:var(--st-space-6) var(--st-space-4);text-align:center;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast),transform var(--st-transition-fast);-webkit-user-select:none;user-select:none;outline:none}:host st-avatar{transition:transform .2s ease}:host:hover:not(.st-disabled){background-color:var(--st-file-upload-hover-bg);border-color:var(--st-file-upload-hover-border)}:host:hover:not(.st-disabled) st-avatar{transform:translateY(-2px)}:host:focus-visible:not(.st-disabled){outline:2px solid var(--st-color-accent-default);outline-offset:2px}:host.st-drag-over{background-color:var(--st-file-upload-active-bg);border-color:var(--st-file-upload-active-border);border-style:solid;transform:scale(1.01)}:host.st-drag-over st-avatar{transform:translateY(-4px) scale(1.05)}:host.st-disabled{opacity:.5;cursor:not-allowed;pointer-events:none}:host .st-file-upload-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host .st-file-upload-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--st-space-3)}:host .st-file-upload-text{display:flex;flex-direction:column;gap:var(--st-space-1)}:host .st-file-upload-label{font-size:.95rem;font-weight:500;color:var(--st-file-upload-text)}:host.st-state-error,:host.st-error{--st-file-upload-border: var(--st-color-feedback-error-default);--st-file-upload-hover-border: var(--st-color-feedback-error-hover, var(--st-color-feedback-error-default))}:host.st-state-error:focus-visible:not(.st-disabled),:host.st-error:focus-visible:not(.st-disabled){outline-color:var(--st-color-feedback-error-default)}:host.st-state-success{--st-file-upload-border: var(--st-color-feedback-success-default);--st-file-upload-hover-border: var(--st-color-feedback-success-hover, var(--st-color-feedback-success-default))}:host.st-state-success:focus-visible:not(.st-disabled){outline-color:var(--st-color-feedback-success-default)}:host.st-state-warning{--st-file-upload-border: var(--st-color-feedback-warning-default);--st-file-upload-hover-border: var(--st-color-feedback-warning-hover, var(--st-color-feedback-warning-default))}:host.st-state-warning:focus-visible:not(.st-disabled){outline-color:var(--st-color-feedback-warning-default)}:host .st-file-upload-hint{font-size:.8rem;color:var(--st-file-upload-hint)}:host .st-file-upload-hint.st-message-error{color:var(--st-color-feedback-error-text)}:host .st-file-upload-hint.st-message-success{color:var(--st-color-feedback-success-text)}:host .st-file-upload-hint.st-message-warning{color:var(--st-color-feedback-warning-text)}:host .st-file-upload-actions{margin-top:var(--st-space-2)}\n"], dependencies: [{ kind: "component", type: StrataAvatarComponent, selector: "st-avatar", inputs: ["src", "alt", "text", "size", "variant"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataButtonDirective, selector: "[stButton]", inputs: ["variant", "size", "fullWidth"] }, { kind: "component", type: StrataButtonGroupComponent, selector: "st-button-group", inputs: ["justification"] }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }] });
3123
3686
  }
3124
3687
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataFileUploadComponent, decorators: [{
3125
3688
  type: Component,
3126
- args: [{ selector: 'st-file-upload', imports: [], template: "<input\n #fileInput\n type=\"file\"\n class=\"st-file-upload-input\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n [disabled]=\"disabled()\"\n (change)=\"onFileChange($event)\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n/>\n\n<div class=\"st-file-upload-content\">\n <div class=\"st-file-upload-icon-wrapper\">\n <ng-content select=\"[uploadIcon]\">\n <svg\n class=\"st-file-upload-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n </ng-content>\n </div>\n\n <div class=\"st-file-upload-text\">\n <span class=\"st-file-upload-label\">{{ label() }}</span>\n @if (displayMessage()) {\n <span\n class=\"st-file-upload-hint\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >{{ displayMessage() }}</span>\n }\n </div>\n\n <ng-content></ng-content>\n</div>\n" }]
3127
- }], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], colorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorMessage", required: false }] }], fileSelect: [{ type: i0.Output, args: ["fileSelect"] }], filesSelect: [{ type: i0.Output, args: ["filesSelect"] }], fileRejected: [{ type: i0.Output, args: ["fileRejected"] }], hostDisabled: [{
3689
+ args: [{ selector: 'st-file-upload', imports: [
3690
+ StrataAvatarComponent,
3691
+ StrataButtonDirective,
3692
+ StrataButtonGroupComponent,
3693
+ StrataIconComponent
3694
+ ], template: "<input\n #fileInput\n type=\"file\"\n class=\"st-file-upload-input\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n [disabled]=\"disabled()\"\n (change)=\"onFileChange($event)\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n/>\n\n@if (showCamera()) {\n <input\n #cameraInput\n type=\"file\"\n class=\"st-file-upload-input\"\n accept=\"image/*\"\n capture=\"environment\"\n [disabled]=\"disabled()\"\n (change)=\"onFileChange($event)\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n />\n}\n\n<div class=\"st-file-upload-content\">\n <ng-content select=\"[uploadIcon]\">\n <st-avatar size=\"md\" variant=\"rounded\" class=\"st-file-upload-avatar\">\n <st-icon name=\"upload\"></st-icon>\n </st-avatar>\n </ng-content>\n\n <div class=\"st-file-upload-text\">\n <span class=\"st-file-upload-label\">{{ label() }}</span>\n @if (displayMessage()) {\n <span\n class=\"st-file-upload-hint\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >{{ displayMessage() }}</span>\n }\n </div>\n\n @if (showCamera()) {\n <st-button-group justification=\"center\" class=\"st-file-upload-actions\">\n <button\n stButton\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n [disabled]=\"disabled()\"\n (click)=\"browse($event)\"\n >\n <st-icon name=\"image\" size=\"sm\"></st-icon>\n <span>{{ choosePhotoLabel() }}</span>\n </button>\n\n <button\n stButton\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n class=\"st-file-upload-action-camera\"\n [disabled]=\"disabled()\"\n (click)=\"browseCamera($event)\"\n >\n <st-icon name=\"camera\" size=\"sm\"></st-icon>\n <span>{{ takePhotoLabel() }}</span>\n </button>\n </st-button-group>\n }\n\n <ng-content></ng-content>\n</div>\n", styles: [":host{--st-file-upload-bg: var(--st-color-bg-default);--st-file-upload-border: var(--st-color-border-default);--st-file-upload-text: var(--st-color-text-primary);--st-file-upload-hint: var(--st-color-text-secondary);--st-file-upload-hover-bg: var(--st-color-bg-raised);--st-file-upload-hover-border: var(--st-color-accent-default);--st-file-upload-active-border: var(--st-color-accent-default);--st-file-upload-active-bg: var(--st-color-accent-subtle, var(--st-color-bg-raised));--st-file-upload-radius: var(--st-border-radius-xl);display:block;position:relative;box-sizing:border-box;background-color:var(--st-file-upload-bg);border:2px dashed var(--st-file-upload-border);border-radius:var(--st-file-upload-radius);padding:var(--st-space-6) var(--st-space-4);text-align:center;cursor:pointer;transition:border-color var(--st-transition-fast),background-color var(--st-transition-fast),transform var(--st-transition-fast);-webkit-user-select:none;user-select:none;outline:none}:host st-avatar{transition:transform .2s ease}:host:hover:not(.st-disabled){background-color:var(--st-file-upload-hover-bg);border-color:var(--st-file-upload-hover-border)}:host:hover:not(.st-disabled) st-avatar{transform:translateY(-2px)}:host:focus-visible:not(.st-disabled){outline:2px solid var(--st-color-accent-default);outline-offset:2px}:host.st-drag-over{background-color:var(--st-file-upload-active-bg);border-color:var(--st-file-upload-active-border);border-style:solid;transform:scale(1.01)}:host.st-drag-over st-avatar{transform:translateY(-4px) scale(1.05)}:host.st-disabled{opacity:.5;cursor:not-allowed;pointer-events:none}:host .st-file-upload-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host .st-file-upload-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--st-space-3)}:host .st-file-upload-text{display:flex;flex-direction:column;gap:var(--st-space-1)}:host .st-file-upload-label{font-size:.95rem;font-weight:500;color:var(--st-file-upload-text)}:host.st-state-error,:host.st-error{--st-file-upload-border: var(--st-color-feedback-error-default);--st-file-upload-hover-border: var(--st-color-feedback-error-hover, var(--st-color-feedback-error-default))}:host.st-state-error:focus-visible:not(.st-disabled),:host.st-error:focus-visible:not(.st-disabled){outline-color:var(--st-color-feedback-error-default)}:host.st-state-success{--st-file-upload-border: var(--st-color-feedback-success-default);--st-file-upload-hover-border: var(--st-color-feedback-success-hover, var(--st-color-feedback-success-default))}:host.st-state-success:focus-visible:not(.st-disabled){outline-color:var(--st-color-feedback-success-default)}:host.st-state-warning{--st-file-upload-border: var(--st-color-feedback-warning-default);--st-file-upload-hover-border: var(--st-color-feedback-warning-hover, var(--st-color-feedback-warning-default))}:host.st-state-warning:focus-visible:not(.st-disabled){outline-color:var(--st-color-feedback-warning-default)}:host .st-file-upload-hint{font-size:.8rem;color:var(--st-file-upload-hint)}:host .st-file-upload-hint.st-message-error{color:var(--st-color-feedback-error-text)}:host .st-file-upload-hint.st-message-success{color:var(--st-color-feedback-success-text)}:host .st-file-upload-hint.st-message-warning{color:var(--st-color-feedback-warning-text)}:host .st-file-upload-actions{margin-top:var(--st-space-2)}\n"] }]
3695
+ }], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], cameraInput: [{ type: i0.ViewChild, args: ['cameraInput', { isSignal: true }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], camera: [{ type: i0.Input, args: [{ isSignal: true, alias: "camera", required: false }] }], choosePhotoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "choosePhotoLabel", required: false }] }], takePhotoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "takePhotoLabel", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], colorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorMessage", required: false }] }], fileSelect: [{ type: i0.Output, args: ["fileSelect"] }], filesSelect: [{ type: i0.Output, args: ["filesSelect"] }], fileRejected: [{ type: i0.Output, args: ["fileRejected"] }], hostDisabled: [{
3128
3696
  type: HostBinding,
3129
3697
  args: ['class.st-disabled']
3130
3698
  }], hostError: [{
@@ -4304,7 +4872,7 @@ class StrataModalComponent {
4304
4872
  }
4305
4873
  ngOnDestroy() {
4306
4874
  if (this.previousActiveElement && typeof this.previousActiveElement.focus === 'function') {
4307
- this.previousActiveElement.focus();
4875
+ this.previousActiveElement.focus({ preventScroll: true });
4308
4876
  }
4309
4877
  }
4310
4878
  ngAfterViewInit() {
@@ -4331,10 +4899,10 @@ class StrataModalComponent {
4331
4899
  focusInitialElement() {
4332
4900
  const autofocus = this.elementRef.nativeElement.querySelector('[autofocus]');
4333
4901
  if (autofocus && typeof autofocus.focus === 'function') {
4334
- autofocus.focus();
4902
+ autofocus.focus({ preventScroll: true });
4335
4903
  return;
4336
4904
  }
4337
- this.elementRef.nativeElement.focus();
4905
+ this.elementRef.nativeElement.focus({ preventScroll: true });
4338
4906
  }
4339
4907
  onCardClick(event) {
4340
4908
  event.stopPropagation();
@@ -4355,7 +4923,7 @@ class StrataModalComponent {
4355
4923
  document.activeElement === this.elementRef.nativeElement ||
4356
4924
  !this.elementRef.nativeElement.contains(document.activeElement)) {
4357
4925
  event.preventDefault();
4358
- last.focus();
4926
+ last.focus({ preventScroll: true });
4359
4927
  }
4360
4928
  }
4361
4929
  else {
@@ -4363,7 +4931,7 @@ class StrataModalComponent {
4363
4931
  document.activeElement === this.elementRef.nativeElement ||
4364
4932
  !this.elementRef.nativeElement.contains(document.activeElement)) {
4365
4933
  event.preventDefault();
4366
- first.focus();
4934
+ first.focus({ preventScroll: true });
4367
4935
  }
4368
4936
  }
4369
4937
  }
@@ -5602,7 +6170,7 @@ class StrataSegmentedControlItemComponent {
5602
6170
  this.onClick();
5603
6171
  }
5604
6172
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataSegmentedControlItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5605
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataSegmentedControlItemComponent, isStandalone: true, selector: "st-segmented-control-item", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, badgeVariant: { classPropertyName: "badgeVariant", publicName: "badgeVariant", isSignal: true, isRequired: false, transformFunction: null }, badgeSize: { classPropertyName: "badgeSize", publicName: "badgeSize", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange", selectionChanged: "selectionChanged" }, host: { attributes: { "role": "tab" }, listeners: { "click": "onClick()", "keydown.space": "onKeydown($event)", "keydown.enter": "onKeydown($event)" }, properties: { "attr.aria-selected": "selected()", "attr.aria-disabled": "effectiveDisabled()", "class.st-disabled": "effectiveDisabled()", "attr.tabindex": "this.tabIndex", "attr.disabled": "this.disabledAttribute" } }, ngImport: i0, template: "<span>{{ text() }}</span>\n@if (badge() !== undefined) {\n <st-badge [value]=\"badge()\" [variant]=\"badgeVariant()\" [size]=\"badgeSize()\"></st-badge>\n}\n<ng-content select=\"st-badge\"></ng-content>\n", styles: [""], dependencies: [{ kind: "component", type: StrataBadgeComponent, selector: "st-badge", inputs: ["value", "icon", "max", "variant", "size", "placement", "visible", "showZero", "ariaLabel"] }] });
6173
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataSegmentedControlItemComponent, isStandalone: true, selector: "st-segmented-control-item", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, badgeVariant: { classPropertyName: "badgeVariant", publicName: "badgeVariant", isSignal: true, isRequired: false, transformFunction: null }, badgeSize: { classPropertyName: "badgeSize", publicName: "badgeSize", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange", selectionChanged: "selectionChanged" }, host: { attributes: { "role": "tab" }, listeners: { "click": "onClick()", "keydown.space": "onKeydown($event)", "keydown.enter": "onKeydown($event)" }, properties: { "attr.aria-selected": "selected()", "attr.aria-disabled": "effectiveDisabled()", "class.st-disabled": "effectiveDisabled()", "attr.tabindex": "this.tabIndex", "attr.disabled": "this.disabledAttribute" } }, ngImport: i0, template: "<span>{{ text() }}</span>\n@if (badge() !== undefined) {\n <st-badge [value]=\"badge()\" [variant]=\"badgeVariant()\" [size]=\"badgeSize()\"></st-badge>\n}\n<ng-content select=\"st-badge\"></ng-content>\n", styles: [":host{display:flex;align-items:center;justify-content:center;gap:var(--st-space-2, 8px);height:var(--st-segmented-control-item-height);padding:0 var(--st-segmented-control-padding-x);border-radius:calc(var(--st-segmented-control-border-radius) - 2px);font-size:var(--st-segmented-control-font-size);font-weight:500;-webkit-user-select:none;user-select:none;transition:background-color var(--st-transition-fast),color var(--st-transition-fast);border:none;color:var(--st-color-text-primary);flex-shrink:0;text-wrap:nowrap;background-color:transparent;position:relative;z-index:1;box-sizing:border-box}:host:hover:not([disabled]):not(.st-disabled):not([aria-selected=true]){cursor:pointer;background-color:var(--st-color-control-bg-hover);color:var(--st-color-text-primary)}:host[aria-selected=true]{color:var(--st-color-control-primary-text);cursor:default}:host[disabled],:host.st-disabled{pointer-events:none;color:var(--st-color-text-tertiary);cursor:unset}:host st-badge{flex-shrink:0}:host-context(.st-segmented-control-full-width){flex:1}\n"], dependencies: [{ kind: "component", type: StrataBadgeComponent, selector: "st-badge", inputs: ["value", "icon", "max", "variant", "size", "placement", "visible", "showZero", "ariaLabel"] }] });
5606
6174
  }
5607
6175
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataSegmentedControlItemComponent, decorators: [{
5608
6176
  type: Component,
@@ -5614,7 +6182,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
5614
6182
  '(click)': 'onClick()',
5615
6183
  '(keydown.space)': 'onKeydown($event)',
5616
6184
  '(keydown.enter)': 'onKeydown($event)'
5617
- }, template: "<span>{{ text() }}</span>\n@if (badge() !== undefined) {\n <st-badge [value]=\"badge()\" [variant]=\"badgeVariant()\" [size]=\"badgeSize()\"></st-badge>\n}\n<ng-content select=\"st-badge\"></ng-content>\n" }]
6185
+ }, template: "<span>{{ text() }}</span>\n@if (badge() !== undefined) {\n <st-badge [value]=\"badge()\" [variant]=\"badgeVariant()\" [size]=\"badgeSize()\"></st-badge>\n}\n<ng-content select=\"st-badge\"></ng-content>\n", styles: [":host{display:flex;align-items:center;justify-content:center;gap:var(--st-space-2, 8px);height:var(--st-segmented-control-item-height);padding:0 var(--st-segmented-control-padding-x);border-radius:calc(var(--st-segmented-control-border-radius) - 2px);font-size:var(--st-segmented-control-font-size);font-weight:500;-webkit-user-select:none;user-select:none;transition:background-color var(--st-transition-fast),color var(--st-transition-fast);border:none;color:var(--st-color-text-primary);flex-shrink:0;text-wrap:nowrap;background-color:transparent;position:relative;z-index:1;box-sizing:border-box}:host:hover:not([disabled]):not(.st-disabled):not([aria-selected=true]){cursor:pointer;background-color:var(--st-color-control-bg-hover);color:var(--st-color-text-primary)}:host[aria-selected=true]{color:var(--st-color-control-primary-text);cursor:default}:host[disabled],:host.st-disabled{pointer-events:none;color:var(--st-color-text-tertiary);cursor:unset}:host st-badge{flex-shrink:0}:host-context(.st-segmented-control-full-width){flex:1}\n"] }]
5618
6186
  }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], badgeVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeVariant", required: false }] }], badgeSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeSize", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], selectionChanged: [{ type: i0.Output, args: ["selectionChanged"] }], tabIndex: [{
5619
6187
  type: HostBinding,
5620
6188
  args: ['attr.tabindex']
@@ -5784,7 +6352,7 @@ class StrataSegmentedControlComponent {
5784
6352
  useExisting: forwardRef(() => StrataSegmentedControlComponent),
5785
6353
  multi: true
5786
6354
  }
5787
- ], queries: [{ propertyName: "segmentItems", predicate: StrataSegmentedControlItemComponent, isSignal: true }, { propertyName: "segmentItemsRefs", predicate: StrataSegmentedControlItemComponent, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div class=\"st-segmented-control-track\">\n <ng-content select=\"st-segmented-control-item\"></ng-content>\n <div class=\"selection-item\" id=\"selection-indicator\" \n [style.left]=\"this.offset() + 'px'\"\n [style.top]=\"this.indicatorTop() + 'px'\"\n [style.width]=\"this.indicatorWidth() + 'px'\"\n [style.height]=\"this.indicatorHeight() + 'px'\"></div>\n</div>\n@if (message()) {\n <div\n class=\"st-segmented-control-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </div>\n}\n\n" });
6355
+ ], queries: [{ propertyName: "segmentItems", predicate: StrataSegmentedControlItemComponent, isSignal: true }, { propertyName: "segmentItemsRefs", predicate: StrataSegmentedControlItemComponent, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div class=\"st-segmented-control-track\">\n <ng-content select=\"st-segmented-control-item\"></ng-content>\n <div class=\"selection-item\" id=\"selection-indicator\" \n [style.left]=\"this.offset() + 'px'\"\n [style.top]=\"this.indicatorTop() + 'px'\"\n [style.width]=\"this.indicatorWidth() + 'px'\"\n [style.height]=\"this.indicatorHeight() + 'px'\"></div>\n</div>\n@if (message()) {\n <div\n class=\"st-segmented-control-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </div>\n}\n\n", styles: [":host{--st-segmented-control-height: var(--st-interactive-element-height-md);--st-segmented-control-item-height: calc(var(--st-segmented-control-height) - 8px);--st-segmented-control-font-size: 14px;--st-segmented-control-padding-x: var(--st-size-xxs);--st-segmented-control-border-radius: var(--st-border-radius-md);--st-segmented-control-border-color: transparent;--st-segmented-control-error-border: var(--st-color-feedback-error-default);--st-segmented-control-success-border: var(--st-color-feedback-success-default);--st-segmented-control-warning-border: var(--st-color-feedback-warning-default);display:inline-flex;flex-direction:column;width:fit-content;max-width:100%;box-sizing:border-box}:host.st-size-sm{--st-segmented-control-height: var(--st-interactive-element-height-sm);--st-segmented-control-item-height: calc(var(--st-segmented-control-height) - 4px);--st-segmented-control-font-size: 12px;--st-segmented-control-padding-x: var(--st-size-xxxs)}:host.st-size-sm .st-segmented-control-track{padding:2px;gap:2px}:host.st-size-md{--st-segmented-control-height: var(--st-interactive-element-height-md);--st-segmented-control-item-height: calc(var(--st-segmented-control-height) - 8px);--st-segmented-control-font-size: 14px;--st-segmented-control-padding-x: var(--st-size-xxs)}:host.st-size-md .st-segmented-control-track{padding:4px;gap:4px}:host.st-size-lg{--st-segmented-control-height: var(--st-interactive-element-height-lg);--st-segmented-control-item-height: calc(var(--st-segmented-control-height) - 8px);--st-segmented-control-font-size: 16px;--st-segmented-control-padding-x: var(--st-size-xs)}:host.st-size-lg .st-segmented-control-track{padding:4px;gap:4px}:host.st-state-error{--st-segmented-control-border-color: var(--st-segmented-control-error-border)}:host.st-state-success{--st-segmented-control-border-color: var(--st-segmented-control-success-border)}:host.st-state-warning{--st-segmented-control-border-color: var(--st-segmented-control-warning-border)}:host.st-segmented-control-full-width{width:100%}:host.st-segmented-control-full-width .st-segmented-control-track{display:flex;width:100%}.st-segmented-control-track{display:inline-flex;flex-direction:row;flex-wrap:nowrap;overflow-x:auto;width:fit-content;max-width:100%;min-width:0;position:relative;border-radius:var(--st-segmented-control-border-radius);border:1px solid var(--st-segmented-control-border-color);box-sizing:border-box;background-color:var(--st-color-bg-raised);height:var(--st-segmented-control-height);padding:4px;gap:4px;transition:border-color var(--st-transition-fast);-ms-overflow-style:none;scrollbar-width:none}.st-segmented-control-track::-webkit-scrollbar{display:none}.selection-item{display:flex;align-items:center;justify-content:center;gap:var(--st-space-2, 8px);height:var(--st-segmented-control-item-height);padding:0 var(--st-segmented-control-padding-x);border-radius:calc(var(--st-segmented-control-border-radius) - 2px);font-size:var(--st-segmented-control-font-size);font-weight:500;-webkit-user-select:none;user-select:none;transition:background-color var(--st-transition-fast),color var(--st-transition-fast)}#selection-indicator{cursor:default;position:absolute;top:0;left:0;z-index:0;pointer-events:none;border-radius:calc(var(--st-segmented-control-border-radius) - 2px);background-color:var(--st-color-control-primary-bg);color:var(--st-color-control-primary-text);text-wrap:nowrap;box-shadow:var(--st-shadow-1);transition:left var(--st-transition-fast),width var(--st-transition-fast)}.st-segmented-control-message{margin-top:var(--st-space-1);font-size:var(--st-font-size-sm, 12px);color:var(--st-color-text-secondary)}.st-segmented-control-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-segmented-control-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-segmented-control-message.st-message-warning{color:var(--st-color-feedback-warning-text)}\n"] });
5788
6356
  }
5789
6357
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataSegmentedControlComponent, decorators: [{
5790
6358
  type: Component,
@@ -5807,7 +6375,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
5807
6375
  '[attr.aria-invalid]': 'effectiveState() === "error" ? "true" : null',
5808
6376
  '[class.st-disabled]': 'effectiveDisabled()',
5809
6377
  '[attr.aria-disabled]': 'effectiveDisabled()'
5810
- }, template: "<div class=\"st-segmented-control-track\">\n <ng-content select=\"st-segmented-control-item\"></ng-content>\n <div class=\"selection-item\" id=\"selection-indicator\" \n [style.left]=\"this.offset() + 'px'\"\n [style.top]=\"this.indicatorTop() + 'px'\"\n [style.width]=\"this.indicatorWidth() + 'px'\"\n [style.height]=\"this.indicatorHeight() + 'px'\"></div>\n</div>\n@if (message()) {\n <div\n class=\"st-segmented-control-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </div>\n}\n\n" }]
6378
+ }, template: "<div class=\"st-segmented-control-track\">\n <ng-content select=\"st-segmented-control-item\"></ng-content>\n <div class=\"selection-item\" id=\"selection-indicator\" \n [style.left]=\"this.offset() + 'px'\"\n [style.top]=\"this.indicatorTop() + 'px'\"\n [style.width]=\"this.indicatorWidth() + 'px'\"\n [style.height]=\"this.indicatorHeight() + 'px'\"></div>\n</div>\n@if (message()) {\n <div\n class=\"st-segmented-control-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </div>\n}\n\n", styles: [":host{--st-segmented-control-height: var(--st-interactive-element-height-md);--st-segmented-control-item-height: calc(var(--st-segmented-control-height) - 8px);--st-segmented-control-font-size: 14px;--st-segmented-control-padding-x: var(--st-size-xxs);--st-segmented-control-border-radius: var(--st-border-radius-md);--st-segmented-control-border-color: transparent;--st-segmented-control-error-border: var(--st-color-feedback-error-default);--st-segmented-control-success-border: var(--st-color-feedback-success-default);--st-segmented-control-warning-border: var(--st-color-feedback-warning-default);display:inline-flex;flex-direction:column;width:fit-content;max-width:100%;box-sizing:border-box}:host.st-size-sm{--st-segmented-control-height: var(--st-interactive-element-height-sm);--st-segmented-control-item-height: calc(var(--st-segmented-control-height) - 4px);--st-segmented-control-font-size: 12px;--st-segmented-control-padding-x: var(--st-size-xxxs)}:host.st-size-sm .st-segmented-control-track{padding:2px;gap:2px}:host.st-size-md{--st-segmented-control-height: var(--st-interactive-element-height-md);--st-segmented-control-item-height: calc(var(--st-segmented-control-height) - 8px);--st-segmented-control-font-size: 14px;--st-segmented-control-padding-x: var(--st-size-xxs)}:host.st-size-md .st-segmented-control-track{padding:4px;gap:4px}:host.st-size-lg{--st-segmented-control-height: var(--st-interactive-element-height-lg);--st-segmented-control-item-height: calc(var(--st-segmented-control-height) - 8px);--st-segmented-control-font-size: 16px;--st-segmented-control-padding-x: var(--st-size-xs)}:host.st-size-lg .st-segmented-control-track{padding:4px;gap:4px}:host.st-state-error{--st-segmented-control-border-color: var(--st-segmented-control-error-border)}:host.st-state-success{--st-segmented-control-border-color: var(--st-segmented-control-success-border)}:host.st-state-warning{--st-segmented-control-border-color: var(--st-segmented-control-warning-border)}:host.st-segmented-control-full-width{width:100%}:host.st-segmented-control-full-width .st-segmented-control-track{display:flex;width:100%}.st-segmented-control-track{display:inline-flex;flex-direction:row;flex-wrap:nowrap;overflow-x:auto;width:fit-content;max-width:100%;min-width:0;position:relative;border-radius:var(--st-segmented-control-border-radius);border:1px solid var(--st-segmented-control-border-color);box-sizing:border-box;background-color:var(--st-color-bg-raised);height:var(--st-segmented-control-height);padding:4px;gap:4px;transition:border-color var(--st-transition-fast);-ms-overflow-style:none;scrollbar-width:none}.st-segmented-control-track::-webkit-scrollbar{display:none}.selection-item{display:flex;align-items:center;justify-content:center;gap:var(--st-space-2, 8px);height:var(--st-segmented-control-item-height);padding:0 var(--st-segmented-control-padding-x);border-radius:calc(var(--st-segmented-control-border-radius) - 2px);font-size:var(--st-segmented-control-font-size);font-weight:500;-webkit-user-select:none;user-select:none;transition:background-color var(--st-transition-fast),color var(--st-transition-fast)}#selection-indicator{cursor:default;position:absolute;top:0;left:0;z-index:0;pointer-events:none;border-radius:calc(var(--st-segmented-control-border-radius) - 2px);background-color:var(--st-color-control-primary-bg);color:var(--st-color-control-primary-text);text-wrap:nowrap;box-shadow:var(--st-shadow-1);transition:left var(--st-transition-fast),width var(--st-transition-fast)}.st-segmented-control-message{margin-top:var(--st-space-1);font-size:var(--st-font-size-sm, 12px);color:var(--st-color-text-secondary)}.st-segmented-control-message.st-message-error{color:var(--st-color-feedback-error-text)}.st-segmented-control-message.st-message-success{color:var(--st-color-feedback-success-text)}.st-segmented-control-message.st-message-warning{color:var(--st-color-feedback-warning-text)}\n"] }]
5811
6379
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], colorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorMessage", required: false }] }], segmentItems: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrataSegmentedControlItemComponent), { isSignal: true }] }], segmentItemsRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrataSegmentedControlItemComponent), { ...{
5812
6380
  read: ElementRef
5813
6381
  }, isSignal: true }] }] } });
@@ -6184,7 +6752,7 @@ class StrataSingleSelectComponent {
6184
6752
  useExisting: forwardRef(() => StrataSingleSelectComponent),
6185
6753
  multi: true
6186
6754
  }
6187
- ], queries: [{ propertyName: "selectItems", predicate: StrataSelectItemComponent, isSignal: true }, { propertyName: "triggerTemplate", first: true, predicate: StrataSelectTriggerDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "inputField", first: true, predicate: StrataInputFieldComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n<label class=\"st-label\" [for]=\"name()\"> {{ label() }}</label>\n}\n<div class=\"single-select-input\" [class.disabled]=\"effectiveDisabled()\" [id]=\"name()\" #singleSelectInput (click)=\"toggle($event)\" (keydown.space)=\"toggle($event)\" (keydown.enter)=\"toggle($event)\" (keydown.escape)=\"open.set(false)\" [attr.data-open]=\"open()\"\n [attr.tabindex]=\"effectiveDisabled() ? -1 : 0\" [stOverlay]=\"selector\" [overlayOpen]=\"open()\" [overlayPlacement]=\"placement()\">\n @if (selectedItem()) {\n @if (triggerTemplate()) {\n <ng-container *ngTemplateOutlet=\"triggerTemplate()!\"></ng-container>\n } @else {\n {{ selectedItem()!.text() }}\n }\n } @else {\n <span class=\"placeholder-text\">{{ placeholder() }}</span>\n }\n\n <st-icon name=\"expand-up-down\"></st-icon>\n</div>\n@if (message()) {\n <div\n class=\"st-select-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </div>\n}\n\n<ng-template #selector>\n <div class=\"single-select-selector\" #singleSelectSelector [class.full-width]=\"fullWidth()\">\n @if (searchable()) {\n <st-input-field>\n <input stInput #searchField type=\"text\" [value]=\"searchQuery() || ''\" (input)=\"searchQuery.set($any($event.target).value); onSearchChange(searchQuery())\" [placeholder]=\"searchPlaceholder()\" />\n <button stButton variant=\"ghost\" [class.visible]=\"searchQuery() !== undefined && searchQuery()!.length > 0\" suffix\n size=\"sm\" (click)=\"searchQuery.set(undefined); onSearchChange(undefined)\">\n x\n </button>\n </st-input-field>\n }\n <div class=\"single-select-items-container\">\n <ng-content select=\"st-select-item\"></ng-content>\n </div>\n </div>\n</ng-template>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataInputFieldComponent, selector: "st-input-field", inputs: ["size", "label", "id", "name", "state", "error", "message", "colorMessage", "disabled", "maxLength", "showCharacterCounter", "characterCounterFormatter"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: StrataNativeInputRefDirective, selector: "input[stInput], textarea[stInput]" }, { kind: "directive", type: StrataButtonDirective, selector: "[stButton]", inputs: ["variant", "size", "fullWidth"] }] });
6755
+ ], queries: [{ propertyName: "selectItems", predicate: StrataSelectItemComponent, isSignal: true }, { propertyName: "triggerTemplate", first: true, predicate: StrataSelectTriggerDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "inputField", first: true, predicate: StrataInputFieldComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n<label class=\"st-label\" [for]=\"name()\"> {{ label() }}</label>\n}\n<div class=\"single-select-input\" [class.disabled]=\"effectiveDisabled()\" [id]=\"name()\" #singleSelectInput (click)=\"toggle($event)\" (keydown.space)=\"toggle($event)\" (keydown.enter)=\"toggle($event)\" (keydown.escape)=\"open.set(false)\" [attr.data-open]=\"open()\"\n [attr.tabindex]=\"effectiveDisabled() ? -1 : 0\" [stOverlay]=\"selector\" [overlayOpen]=\"open()\" [overlayPlacement]=\"placement()\">\n @if (selectedItem()) {\n @if (triggerTemplate()) {\n <ng-container *ngTemplateOutlet=\"triggerTemplate()!\"></ng-container>\n } @else {\n {{ selectedItem()!.text() }}\n }\n } @else {\n <span class=\"placeholder-text\">{{ placeholder() }}</span>\n }\n\n <st-icon name=\"expand-up-down\"></st-icon>\n</div>\n@if (message()) {\n <div\n class=\"st-select-message\"\n [class.st-message-error]=\"isMessageError()\"\n [class.st-message-success]=\"isMessageSuccess()\"\n [class.st-message-warning]=\"isMessageWarning()\"\n [attr.role]=\"isMessageError() ? 'alert' : null\"\n >\n {{ message() }}\n </div>\n}\n\n<ng-template #selector>\n <div class=\"single-select-selector\" #singleSelectSelector [class.full-width]=\"fullWidth()\">\n @if (searchable()) {\n <st-input-field>\n <input stInput #searchField type=\"text\" [value]=\"searchQuery() || ''\" (input)=\"searchQuery.set($any($event.target).value); onSearchChange(searchQuery())\" [placeholder]=\"searchPlaceholder()\" />\n <button stButton variant=\"ghost\" [class.visible]=\"searchQuery() !== undefined && searchQuery()!.length > 0\" suffix\n size=\"sm\" (click)=\"searchQuery.set(undefined); onSearchChange(undefined)\">\n x\n </button>\n </st-input-field>\n }\n <div class=\"single-select-items-container\">\n <ng-content select=\"st-select-item\"></ng-content>\n </div>\n </div>\n</ng-template>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport", "overlayTarget"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataInputFieldComponent, selector: "st-input-field", inputs: ["size", "label", "id", "name", "state", "error", "message", "colorMessage", "disabled", "maxLength", "showCharacterCounter", "characterCounterFormatter"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: StrataNativeInputRefDirective, selector: "input[stInput], textarea[stInput]" }, { kind: "directive", type: StrataButtonDirective, selector: "[stButton]", inputs: ["variant", "size", "fullWidth"] }] });
6188
6756
  }
6189
6757
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataSingleSelectComponent, decorators: [{
6190
6758
  type: Component,
@@ -6645,5 +7213,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
6645
7213
  * Generated bundle index. Do not edit.
6646
7214
  */
6647
7215
 
6648
- export { BreakpointService, CapitalizePipe, DEFAULT_DATE_RANGE_PRESETS, DEFAULT_DURATION, DEFAULT_THEME, DarkmodeService, DeviceService, HotkeyService, HttpIconLoader, IconLoader, IconRegistry, IconRegistryService, ModalService, NotificationService, STRATA_CONFIG, StrataAccordionGroupComponent, StrataAccordionItemComponent, StrataActionMenuComponent, StrataActionMenuItemComponent, StrataActivatableDirective, StrataAlertComponent, StrataAlertContentComponent, StrataAutoResizeDirective, StrataAvatarComponent, StrataAvatarStackComponent, StrataBadgeComponent, StrataBreadcrumbComponent, StrataBreadcrumbItemComponent, StrataButtonDirective, StrataButtonGroupComponent, StrataCalendarComponent, StrataCardComponent, StrataCheckboxComponent, StrataDatePickerComponent, StrataDateRangePickerComponent, StrataDividerComponent, StrataFileUploadComponent, StrataIconComponent, StrataImageCropperComponent, StrataInputFieldComponent, StrataItemComponent, StrataItemListComponent, StrataKbdComponent, StrataMessageStateComponent, StrataModalBodyComponent, StrataModalComponent, StrataModalContainerComponent, StrataModalFooterComponent, StrataModalHeaderComponent, StrataModalRef, StrataNativeInputRefDirective, StrataNotificationComponent, StrataNotificationContainerComponent, StrataNumberDisplayComponent, StrataNumberStepperComponent, StrataOtpComponent, StrataOverlayDirective, StrataPaginationComponent, StrataProgressLinearComponent, StrataProgressRadialComponent, StrataRadioComponent, StrataRadioGroupComponent, StrataSegmentedControlComponent, StrataSegmentedControlItemComponent, StrataSelectItemComponent, StrataSelectTriggerDirective, StrataShellComponent, StrataSidemenuComponent, StrataSidemenuItemDirective, StrataSidemenuItemGroupComponent, StrataSidemenuSectionComponent, StrataSingleSelectComponent, StrataSkeletonComponent, StrataSliderComponent, StrataSpinnerComponent, StrataStepComponent, StrataStepperComponent, StrataTabItemComponent, StrataTabsComponent, StrataTagComponent, StrataTextStackComponent, StrataThemeDirective, StrataTimePickerComponent, StrataToggleComponent, StrataTooltipDirective, addDays, addMonths, addYears, createCalendarGrid, disableDateRange, disableDaysOfWeek, disableFutureDates, disablePastDates, disableWeekends, endOfDay, endOfMonth, formatDate, formatMonthTitle, getDayOfWeek, getDaysInMonth, getDefaultShortcutLabels, getLocaleDefaultDateFormat, getMonthNames, getWeekdayNames, isAfterDay, isApplePlatform, isBeforeDay, isSameDay, isSameMonth, isSameYear, isWeekend, isWithinDayRange, parseDate, provideBaseIcons, provideIcons, provideStrata, resolveIsApple, startOfDay, startOfMonth };
7216
+ export { BreakpointService, CapitalizePipe, DEFAULT_DATE_RANGE_PRESETS, DEFAULT_DURATION, DEFAULT_THEME, DarkmodeService, DeviceService, HotkeyService, HttpIconLoader, IconLoader, IconRegistry, IconRegistryService, ModalService, NotificationService, STRATA_CONFIG, StrataAccordionGroupComponent, StrataAccordionItemComponent, StrataActionMenuComponent, StrataActionMenuItemComponent, StrataActivatableDirective, StrataAlertComponent, StrataAlertContentComponent, StrataAutoResizeDirective, StrataAvatarComponent, StrataAvatarStackComponent, StrataBadgeComponent, StrataBreadcrumbComponent, StrataBreadcrumbItemComponent, StrataButtonDirective, StrataButtonGroupComponent, StrataCalendarComponent, StrataCardComponent, StrataChatComponent, StrataChatGroupComponent, StrataChatMessageComponent, StrataChatSeparatorComponent, StrataChatTypingComponent, StrataCheckboxComponent, StrataContextMenuDirective, StrataDatePickerComponent, StrataDateRangePickerComponent, StrataDividerComponent, StrataFileUploadComponent, StrataIconComponent, StrataImageCropperComponent, StrataInputFieldComponent, StrataItemComponent, StrataItemListComponent, StrataKbdComponent, StrataMessageStateComponent, StrataModalBodyComponent, StrataModalComponent, StrataModalContainerComponent, StrataModalFooterComponent, StrataModalHeaderComponent, StrataModalRef, StrataNativeInputRefDirective, StrataNotificationComponent, StrataNotificationContainerComponent, StrataNumberDisplayComponent, StrataNumberStepperComponent, StrataOtpComponent, StrataOverlayDirective, StrataPaginationComponent, StrataProgressLinearComponent, StrataProgressRadialComponent, StrataRadioComponent, StrataRadioGroupComponent, StrataSegmentedControlComponent, StrataSegmentedControlItemComponent, StrataSelectItemComponent, StrataSelectTriggerDirective, StrataShellComponent, StrataSidemenuComponent, StrataSidemenuItemDirective, StrataSidemenuItemGroupComponent, StrataSidemenuSectionComponent, StrataSingleSelectComponent, StrataSkeletonComponent, StrataSliderComponent, StrataSpinnerComponent, StrataStepComponent, StrataStepperComponent, StrataTabItemComponent, StrataTabsComponent, StrataTagComponent, StrataTextStackComponent, StrataThemeDirective, StrataTimeStepperComponent, StrataTimepickerComponent, StrataToggleComponent, StrataTooltipDirective, addDays, addMonths, addYears, createCalendarGrid, disableDateRange, disableDaysOfWeek, disableFutureDates, disablePastDates, disableWeekends, endOfDay, endOfMonth, formatDate, formatMonthTitle, getDayOfWeek, getDaysInMonth, getDefaultShortcutLabels, getLocaleDefaultDateFormat, getMonthNames, getWeekdayNames, isAfterDay, isApplePlatform, isBeforeDay, isSameDay, isSameMonth, isSameYear, isWeekend, isWithinDayRange, parseDate, provideBaseIcons, provideIcons, provideStrata, resolveIsApple, startOfDay, startOfMonth };
6649
7217
  //# sourceMappingURL=ngx-strata.mjs.map