@ship-ui/core 0.17.21 → 0.18.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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, computed, ElementRef, Renderer2, input, ChangeDetectionStrategy, Component, viewChild, effect, HostListener, NgModule, signal, Injectable, DOCUMENT, model, output, ApplicationRef, createComponent, isSignal, OutputEmitterRef, DestroyRef, PLATFORM_ID, ViewChild, contentChild, contentChildren, afterNextRender, Injector, HostBinding, TemplateRef, runInInjectionContext, Directive, ChangeDetectorRef, viewChildren, untracked, ViewContainerRef, EnvironmentInjector } from '@angular/core';
2
+ import { InjectionToken, inject, computed, ElementRef, Renderer2, input, ChangeDetectionStrategy, Component, viewChild, effect, HostListener, NgModule, signal, Injectable, DOCUMENT, model, output, ApplicationRef, OutputEmitterRef, TemplateRef, createComponent, isSignal, DestroyRef, PLATFORM_ID, ViewChild, Directive, contentChild, contentChildren, afterNextRender, Injector, HostBinding, runInInjectionContext, ChangeDetectorRef, viewChildren, untracked, ViewContainerRef, EnvironmentInjector } from '@angular/core';
3
3
  import { isPlatformBrowser, JsonPipe, DatePipe, isPlatformServer, NgTemplateOutlet } from '@angular/common';
4
4
  import { NgModel } from '@angular/forms';
5
5
  import { SIGNAL } from '@angular/core/primitives/signals';
@@ -524,56 +524,22 @@ class ShipDialogService {
524
524
  this.#appRef = inject(ApplicationRef);
525
525
  this.compRef = null;
526
526
  this.insertedCompRef = null;
527
+ this.insertedTemplateRef = null;
527
528
  this.closedFieldSub = null;
528
529
  this.compClosedSub = null;
529
530
  }
530
531
  #document;
531
532
  #bodyEl;
532
533
  #appRef;
533
- open(component, options) {
534
+ open(componentOrTemplate, options) {
534
535
  const environmentInjector = this.#appRef.injector;
535
536
  const hostElement = this.#createEl();
536
537
  let closingCalled = false;
538
+ let closedField;
537
539
  const { data, closed, ...rest } = options || {};
538
540
  if (this.compRef) {
539
541
  this.#cleanupRefs(true);
540
542
  }
541
- this.insertedCompRef = createComponent(component, {
542
- environmentInjector,
543
- });
544
- this.compRef = createComponent(ShipDialog, {
545
- hostElement,
546
- environmentInjector,
547
- projectableNodes: [[this.insertedCompRef.location.nativeElement]],
548
- });
549
- const insertedInstance = this.insertedCompRef.instance;
550
- const dataField = insertedInstance.data;
551
- const closedField = insertedInstance.closed;
552
- if (data) {
553
- if (isSignal(dataField)) {
554
- this.insertedCompRef.setInput('data', data);
555
- }
556
- else if (!isSignal(dataField)) {
557
- throw new Error('data is not an input signal on the passed component');
558
- }
559
- }
560
- if (closedField instanceof OutputEmitterRef) {
561
- this.closedFieldSub = closedField.subscribe((arg) => {
562
- this.#cleanupRefs();
563
- if (closingCalled)
564
- return;
565
- closingCalled = true;
566
- closed?.(arg);
567
- (this.compRef?.instance.closed).emit(arg);
568
- });
569
- }
570
- this.#appRef.attachView(this.insertedCompRef.hostView);
571
- this.#appRef.attachView(this.compRef.hostView);
572
- this.insertedCompRef.changeDetectorRef.detectChanges();
573
- this.compRef.changeDetectorRef.detectChanges();
574
- this.compRef.instance.isOpen.set(true);
575
- this.compRef.setInput('options', rest);
576
- this.compClosedSub = this.compRef.instance.closed.subscribe(() => closeAction());
577
543
  const _self = this;
578
544
  function closeAction(arg = undefined) {
579
545
  _self.#cleanupRefs();
@@ -585,8 +551,61 @@ class ShipDialogService {
585
551
  }
586
552
  closed?.(arg);
587
553
  }
554
+ let projectableNodes = [];
555
+ if (componentOrTemplate instanceof TemplateRef) {
556
+ this.insertedTemplateRef = componentOrTemplate.createEmbeddedView({
557
+ $implicit: data,
558
+ close: (res) => closeAction(res),
559
+ });
560
+ projectableNodes = [this.insertedTemplateRef.rootNodes];
561
+ }
562
+ else {
563
+ this.insertedCompRef = createComponent(componentOrTemplate, {
564
+ environmentInjector,
565
+ });
566
+ projectableNodes = [[this.insertedCompRef.location.nativeElement]];
567
+ const insertedInstance = this.insertedCompRef.instance;
568
+ const dataField = insertedInstance.data;
569
+ closedField = insertedInstance.closed;
570
+ if (data) {
571
+ if (isSignal(dataField)) {
572
+ this.insertedCompRef.setInput('data', data);
573
+ }
574
+ else if (!isSignal(dataField)) {
575
+ throw new Error('data is not an input signal on the passed component');
576
+ }
577
+ }
578
+ if (closedField && closedField instanceof OutputEmitterRef) {
579
+ this.closedFieldSub = closedField.subscribe((arg) => {
580
+ this.#cleanupRefs();
581
+ if (closingCalled)
582
+ return;
583
+ closingCalled = true;
584
+ closed?.(arg);
585
+ (this.compRef?.instance.closed).emit(arg);
586
+ });
587
+ }
588
+ }
589
+ this.compRef = createComponent(ShipDialog, {
590
+ hostElement,
591
+ environmentInjector,
592
+ projectableNodes,
593
+ });
594
+ if (this.insertedCompRef) {
595
+ this.#appRef.attachView(this.insertedCompRef.hostView);
596
+ this.insertedCompRef.changeDetectorRef.detectChanges();
597
+ }
598
+ if (this.insertedTemplateRef) {
599
+ this.#appRef.attachView(this.insertedTemplateRef);
600
+ this.insertedTemplateRef.detectChanges();
601
+ }
602
+ this.#appRef.attachView(this.compRef.hostView);
603
+ this.compRef.changeDetectorRef.detectChanges();
604
+ this.compRef.instance.isOpen.set(true);
605
+ this.compRef.setInput('options', rest);
606
+ this.compClosedSub = this.compRef.instance.closed.subscribe(() => closeAction());
588
607
  return {
589
- component: this.insertedCompRef.instance,
608
+ component: this.insertedCompRef?.instance,
590
609
  close: closeAction,
591
610
  closed: this.compRef.instance.closed,
592
611
  };
@@ -607,6 +626,12 @@ class ShipDialogService {
607
626
  _self.#appRef.detachView(_self.insertedCompRef.hostView);
608
627
  _self.closedFieldSub?.unsubscribe();
609
628
  _self.insertedCompRef.destroy();
629
+ _self.insertedCompRef = null;
630
+ }
631
+ if (_self.insertedTemplateRef) {
632
+ _self.#appRef.detachView(_self.insertedTemplateRef);
633
+ _self.insertedTemplateRef.destroy();
634
+ _self.insertedTemplateRef = null;
610
635
  }
611
636
  if (!_self.compRef)
612
637
  return;
@@ -1762,8 +1787,110 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1762
1787
  args: ['document:touchend', ['$event']]
1763
1788
  }] } });
1764
1789
 
1765
- class ShipButtonGroup {
1790
+ function contentProjectionSignal(querySelector, options = { childList: true }) {
1791
+ const hostElement = inject((ElementRef)).nativeElement;
1792
+ const destroyRef = inject(DestroyRef);
1793
+ const projectedElementsSignal = signal([], ...(ngDevMode ? [{ debugName: "projectedElementsSignal" }] : []));
1794
+ const updateElements = () => {
1795
+ projectedElementsSignal.set(Array.from(hostElement.querySelectorAll(querySelector)));
1796
+ };
1797
+ updateElements();
1798
+ if (typeof MutationObserver === 'undefined')
1799
+ return projectedElementsSignal.asReadonly();
1800
+ const observer = new MutationObserver((mutations) => {
1801
+ const hasChildListChanges = mutations.some((mutation) => mutation.type === 'childList');
1802
+ if (hasChildListChanges) {
1803
+ updateElements();
1804
+ }
1805
+ });
1806
+ observer.observe(hostElement, options);
1807
+ destroyRef.onDestroy(() => observer.disconnect());
1808
+ return projectedElementsSignal.asReadonly();
1809
+ }
1810
+
1811
+ class ShipSelectionGroup {
1812
+ constructor(itemSelector, activeClass) {
1813
+ this.itemSelector = itemSelector;
1814
+ this.activeClass = activeClass;
1815
+ this.hostElement = inject((ElementRef)).nativeElement;
1816
+ this.value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
1817
+ this.items = contentProjectionSignal(this.itemSelector, {
1818
+ childList: true,
1819
+ subtree: true,
1820
+ attributes: true,
1821
+ });
1822
+ effect(() => {
1823
+ const selectedValue = this.value();
1824
+ const activeClass = this.activeClass;
1825
+ this.items().forEach((item) => {
1826
+ const itemValue = item.getAttribute('value');
1827
+ // If the item doesn't have a value attribute, it's not participate in the selection
1828
+ if (itemValue === null && !item.hasAttribute('value'))
1829
+ return;
1830
+ // Exact match or handle empty string matching properly
1831
+ if (itemValue === String(selectedValue) || (itemValue === '' && (selectedValue === null || selectedValue === ''))) {
1832
+ item.classList.add(activeClass);
1833
+ }
1834
+ else {
1835
+ item.classList.remove(activeClass);
1836
+ }
1837
+ });
1838
+ });
1839
+ }
1840
+ onClick(target) {
1841
+ const targetEl = target;
1842
+ if (!targetEl || !targetEl.closest)
1843
+ return;
1844
+ const item = targetEl.closest(this.itemSelector);
1845
+ if (item && this.hostElement.contains(item)) {
1846
+ if (item.hasAttribute('value')) {
1847
+ const value = item.getAttribute('value');
1848
+ this.value.set(value);
1849
+ }
1850
+ }
1851
+ }
1852
+ onKeyDown(event) {
1853
+ const items = this.items().filter(item => item.hasAttribute('value'));
1854
+ if (!items.length)
1855
+ return;
1856
+ const currentIndex = items.findIndex((item) => item.classList.contains(this.activeClass));
1857
+ let nextIndex = currentIndex;
1858
+ switch (event.key) {
1859
+ case 'ArrowRight':
1860
+ case 'ArrowDown':
1861
+ nextIndex = currentIndex >= items.length - 1 ? 0 : currentIndex + 1;
1862
+ break;
1863
+ case 'ArrowLeft':
1864
+ case 'ArrowUp':
1865
+ nextIndex = currentIndex <= 0 ? items.length - 1 : currentIndex - 1;
1866
+ break;
1867
+ default:
1868
+ return; // Let other keys propagate natively
1869
+ }
1870
+ event.preventDefault();
1871
+ const nextItem = items[nextIndex];
1872
+ if (nextItem) {
1873
+ const value = nextItem.getAttribute('value');
1874
+ this.value.set(value);
1875
+ nextItem.focus();
1876
+ }
1877
+ }
1878
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipSelectionGroup, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive }); }
1879
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.5", type: ShipSelectionGroup, isStandalone: true, inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "click": "onClick($event.target)", "keydown": "onKeyDown($event)" } }, ngImport: i0 }); }
1880
+ }
1881
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipSelectionGroup, decorators: [{
1882
+ type: Directive
1883
+ }], ctorParameters: () => [{ type: undefined }, { type: undefined }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], onClick: [{
1884
+ type: HostListener,
1885
+ args: ['click', ['$event.target']]
1886
+ }], onKeyDown: [{
1887
+ type: HostListener,
1888
+ args: ['keydown', ['$event']]
1889
+ }] } });
1890
+
1891
+ class ShipButtonGroup extends ShipSelectionGroup {
1766
1892
  constructor() {
1893
+ super('button', 'active');
1767
1894
  this.id = '--' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 12);
1768
1895
  this.color = input(null, ...(ngDevMode ? [{ debugName: "color" }] : []));
1769
1896
  this.variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : []));
@@ -1775,7 +1902,7 @@ class ShipButtonGroup {
1775
1902
  });
1776
1903
  }
1777
1904
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipButtonGroup, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1778
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipButtonGroup, isStandalone: true, selector: "sh-button-group", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "style.--btng-id": "id" } }, ngImport: i0, template: `
1905
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipButtonGroup, isStandalone: true, selector: "sh-button-group", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "style.--btng-id": "id" } }, usesInheritance: true, ngImport: i0, template: `
1779
1906
  <ng-content />
1780
1907
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1781
1908
  }
@@ -1793,7 +1920,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1793
1920
  '[style.--btng-id]': 'id',
1794
1921
  },
1795
1922
  }]
1796
- }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
1923
+ }], ctorParameters: () => [], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
1797
1924
 
1798
1925
  class ShipButton {
1799
1926
  constructor() {
@@ -1856,18 +1983,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1856
1983
 
1857
1984
  class ShipCheckbox {
1858
1985
  constructor() {
1986
+ this._elementRef = inject(ElementRef);
1987
+ this.internalInput = viewChild('internalInput', ...(ngDevMode ? [{ debugName: "internalInput" }] : []));
1988
+ this.projectedInputs = contentProjectionSignal('input:not(.internal-input)', {
1989
+ childList: true,
1990
+ attributes: true,
1991
+ });
1992
+ this.checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
1859
1993
  this.currentClassList = classMutationSignal();
1860
1994
  this.color = input(null, ...(ngDevMode ? [{ debugName: "color" }] : []));
1861
1995
  this.variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : []));
1862
1996
  this.readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
1997
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1998
+ this.noInternalInput = input(false, ...(ngDevMode ? [{ debugName: "noInternalInput" }] : []));
1863
1999
  this.hostClasses = shipComponentClasses('checkbox', {
1864
2000
  color: this.color,
1865
2001
  variant: this.variant,
1866
2002
  readonly: this.readonly,
1867
2003
  });
1868
2004
  }
2005
+ onInternalInputChange(event) {
2006
+ if (this.disabled())
2007
+ return;
2008
+ const input = event.target;
2009
+ this.checked.set(input.checked);
2010
+ }
2011
+ onEnter(event) {
2012
+ const inputEl = this.internalInput()?.nativeElement;
2013
+ if (inputEl && getComputedStyle(inputEl).display !== 'none') {
2014
+ inputEl.click();
2015
+ }
2016
+ else {
2017
+ this._elementRef.nativeElement.click();
2018
+ }
2019
+ event.preventDefault();
2020
+ }
1869
2021
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1870
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipCheckbox, isStandalone: true, selector: "sh-checkbox", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
2022
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ShipCheckbox, isStandalone: true, selector: "sh-checkbox", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, noInternalInput: { classPropertyName: "noInternalInput", publicName: "noInternalInput", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, host: { listeners: { "keydown.enter": "onEnter($event)" }, properties: { "class": "hostClasses()", "attr.disabled": "disabled() ? \"\" : null" } }, viewQueries: [{ propertyName: "internalInput", first: true, predicate: ["internalInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
1871
2023
  <div class="box sh-sheet" [class]="currentClassList()">
1872
2024
  <sh-icon class="inherit default-indicator">check-bold</sh-icon>
1873
2025
  <sh-icon class="inherit indeterminate-indicator">minus-bold</sh-icon>
@@ -1876,6 +2028,16 @@ class ShipCheckbox {
1876
2028
  <div class="label">
1877
2029
  <ng-content />
1878
2030
  </div>
2031
+
2032
+ @if (projectedInputs().length === 0 && !noInternalInput()) {
2033
+ <input
2034
+ #internalInput
2035
+ type="checkbox"
2036
+ class="internal-input"
2037
+ [attr.disabled]="disabled() ? '' : null"
2038
+ [checked]="checked()"
2039
+ (change)="onInternalInputChange($event)" />
2040
+ }
1879
2041
  `, isInline: true, dependencies: [{ kind: "component", type: ShipIcon, selector: "sh-icon", inputs: ["color", "variant", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1880
2042
  }
1881
2043
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipCheckbox, decorators: [{
@@ -1892,13 +2054,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1892
2054
  <div class="label">
1893
2055
  <ng-content />
1894
2056
  </div>
2057
+
2058
+ @if (projectedInputs().length === 0 && !noInternalInput()) {
2059
+ <input
2060
+ #internalInput
2061
+ type="checkbox"
2062
+ class="internal-input"
2063
+ [attr.disabled]="disabled() ? '' : null"
2064
+ [checked]="checked()"
2065
+ (change)="onInternalInputChange($event)" />
2066
+ }
1895
2067
  `,
1896
2068
  changeDetection: ChangeDetectionStrategy.OnPush,
1897
2069
  host: {
1898
2070
  '[class]': 'hostClasses()',
2071
+ '[attr.disabled]': 'disabled() ? "" : null',
1899
2072
  },
1900
2073
  }]
1901
- }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }] } });
2074
+ }], propDecorators: { internalInput: [{ type: i0.ViewChild, args: ['internalInput', { isSignal: true }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], noInternalInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "noInternalInput", required: false }] }], onEnter: [{
2075
+ type: HostListener,
2076
+ args: ['keydown.enter', ['$event']]
2077
+ }] } });
1902
2078
 
1903
2079
  class ShipChip {
1904
2080
  constructor() {
@@ -2285,7 +2461,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
2285
2461
 
2286
2462
  class ShipDatepicker {
2287
2463
  constructor() {
2288
- this.#INIT_DATE = this.#getUTCDate(new Date());
2464
+ this.#INIT_DATE = new Date(new Date().setHours(0, 0, 0, 0));
2289
2465
  this.date = model(null, ...(ngDevMode ? [{ debugName: "date" }] : []));
2290
2466
  this.endDate = model(null, ...(ngDevMode ? [{ debugName: "endDate" }] : []));
2291
2467
  this.asRange = input(false, ...(ngDevMode ? [{ debugName: "asRange" }] : []));
@@ -2351,26 +2527,25 @@ class ShipDatepicker {
2351
2527
  });
2352
2528
  }
2353
2529
  #generateMonthDates(date, startOfWeek) {
2354
- const year = date.getUTCFullYear();
2355
- const month = date.getUTCMonth();
2356
- const firstDay = new Date(Date.UTC(year, month)).getUTCDay();
2357
- const daysInMonth = 32 - new Date(Date.UTC(year, month, 32)).getUTCDate();
2530
+ const year = date.getFullYear();
2531
+ const month = date.getMonth();
2532
+ const firstDay = new Date(year, month, 1).getDay();
2533
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
2358
2534
  const dates = [];
2359
2535
  let offset = firstDay - startOfWeek;
2360
2536
  if (offset < 0) {
2361
2537
  offset += 7;
2362
2538
  }
2363
- const lastDayOfPrevMonth = new Date(Date.UTC(year, month, 0)).getUTCDate();
2539
+ const lastDayOfPrevMonth = new Date(year, month, 0).getDate();
2364
2540
  for (let i = offset - 1; i >= 0; i--) {
2365
- const prevMonthDate = new Date(Date.UTC(year, month - 1, lastDayOfPrevMonth - i));
2366
- dates.push(prevMonthDate);
2541
+ dates.push(new Date(year, month - 1, lastDayOfPrevMonth - i, 0, 0, 0, 0));
2367
2542
  }
2368
2543
  for (let i = 1; i <= daysInMonth; i++) {
2369
- dates.push(new Date(Date.UTC(year, month, i)));
2544
+ dates.push(new Date(year, month, i, 0, 0, 0, 0));
2370
2545
  }
2371
2546
  let nextMonthDay = 1;
2372
2547
  while (dates.length % 7 !== 0) {
2373
- dates.push(new Date(Date.UTC(year, month + 1, nextMonthDay++)));
2548
+ dates.push(new Date(year, month + 1, nextMonthDay++, 0, 0, 0, 0));
2374
2549
  }
2375
2550
  return dates;
2376
2551
  }
@@ -2392,11 +2567,11 @@ class ShipDatepicker {
2392
2567
  }
2393
2568
  setDate(newDate, selectedElement) {
2394
2569
  const createDateWithExistingTime = (newDate, existingDate) => {
2395
- const hours = existingDate?.getUTCHours() ?? 0;
2396
- const minutes = existingDate?.getUTCMinutes() ?? 0;
2397
- const seconds = existingDate?.getUTCSeconds() ?? 0;
2398
- const milliseconds = existingDate?.getUTCMilliseconds() ?? 0;
2399
- return this.#getUTCDate(new Date(Date.UTC(newDate.getUTCFullYear(), newDate.getUTCMonth(), newDate.getUTCDate(), hours, minutes, seconds, milliseconds)));
2570
+ const hours = existingDate?.getHours() ?? 0;
2571
+ const minutes = existingDate?.getMinutes() ?? 0;
2572
+ const seconds = existingDate?.getSeconds() ?? 0;
2573
+ const milliseconds = existingDate?.getMilliseconds() ?? 0;
2574
+ return new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), hours, minutes, seconds, milliseconds);
2400
2575
  };
2401
2576
  if (!this.asRange()) {
2402
2577
  this.date.set(createDateWithExistingTime(newDate, this.date()));
@@ -2433,10 +2608,10 @@ class ShipDatepicker {
2433
2608
  if (startDate === null)
2434
2609
  return null;
2435
2610
  const startOfDay = (date) => {
2436
- return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0, 0));
2611
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
2437
2612
  };
2438
2613
  const endOfDay = (date) => {
2439
- return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 23, 59, 59, 999));
2614
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);
2440
2615
  };
2441
2616
  const currentDate = startOfDay(date);
2442
2617
  const rangeStart = startOfDay(startDate);
@@ -2457,7 +2632,7 @@ class ShipDatepicker {
2457
2632
  }
2458
2633
  if (currentDate >= rangeStart && currentDate <= rangeEnd) {
2459
2634
  classes.push('sel');
2460
- const dayOfWeek = currentDate.getUTCDay();
2635
+ const dayOfWeek = currentDate.getDay();
2461
2636
  const startOfWeek = this.startOfWeek();
2462
2637
  if (dayOfWeek === startOfWeek) {
2463
2638
  classes.push('week-start');
@@ -2468,11 +2643,11 @@ class ShipDatepicker {
2468
2643
  }
2469
2644
  }
2470
2645
  const nextDate = new Date(currentDate);
2471
- nextDate.setUTCDate(currentDate.getUTCDate() + 1);
2646
+ nextDate.setDate(currentDate.getDate() + 1);
2472
2647
  const prevDate = new Date(currentDate);
2473
- prevDate.setUTCDate(currentDate.getUTCDate() - 1);
2474
- const isFirstOfMonth = currentDate.getUTCDate() === 1;
2475
- const isLastOfMonth = nextDate.getUTCMonth() !== currentDate.getUTCMonth();
2648
+ prevDate.setDate(currentDate.getDate() - 1);
2649
+ const isFirstOfMonth = currentDate.getDate() === 1;
2650
+ const isLastOfMonth = nextDate.getMonth() !== currentDate.getMonth();
2476
2651
  if (isFirstOfMonth) {
2477
2652
  classes.push('month-start');
2478
2653
  }
@@ -2505,11 +2680,6 @@ class ShipDatepicker {
2505
2680
  const offsetDate = this.getOffsetDate(monthOffset);
2506
2681
  return date.getMonth() === offsetDate.getMonth();
2507
2682
  }
2508
- #getUTCDate(date) {
2509
- const offsetMinutes = date.getTimezoneOffset();
2510
- const timeDiffMillis = offsetMinutes * 60 * 1000;
2511
- return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()) + timeDiffMillis);
2512
- }
2513
2683
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipDatepicker, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2514
2684
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ShipDatepicker, isStandalone: true, selector: "sh-datepicker", inputs: { date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, endDate: { classPropertyName: "endDate", publicName: "endDate", isSignal: true, isRequired: false, transformFunction: null }, asRange: { classPropertyName: "asRange", publicName: "asRange", isSignal: true, isRequired: false, transformFunction: null }, monthsToShow: { classPropertyName: "monthsToShow", publicName: "monthsToShow", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, startOfWeek: { classPropertyName: "startOfWeek", publicName: "startOfWeek", isSignal: true, isRequired: false, transformFunction: null }, weekdayLabels: { classPropertyName: "weekdayLabels", publicName: "weekdayLabels", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { date: "dateChange", endDate: "endDateChange" }, host: { properties: { "class.as-range": "asRange()", "class": "\"columns-\" + monthsToShow()", "class.disabled": "disabled()" } }, viewQueries: [{ propertyName: "daysRef", first: true, predicate: ["daysRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
2515
2685
  <header>
@@ -2916,32 +3086,31 @@ class ShipFormFieldPopover {
2916
3086
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipFormFieldPopover, isStandalone: true, selector: "sh-form-field-popover", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpen: "isOpenChange", closed: "closed" }, host: { listeners: { "click": "onClick()" } }, ngImport: i0, template: `
2917
3087
  <ng-content select="label"></ng-content>
2918
3088
 
2919
- <div class="input-wrap">
2920
- <div class="prefix">
2921
- <ng-content select="[prefix]"></ng-content>
2922
- <ng-content select="[textPrefix]"></ng-content>
2923
- </div>
2924
-
2925
- <div class="prefix-space"></div>
3089
+ <sh-popover
3090
+ [(isOpen)]="isOpen"
3091
+ (closed)="close()"
3092
+ [options]="{
3093
+ closeOnButton: false,
3094
+ closeOnEsc: true,
3095
+ }">
3096
+ <div trigger class="input-wrap">
3097
+ <div class="prefix">
3098
+ <ng-content select="[prefix]"></ng-content>
3099
+ <ng-content select="[textPrefix]"></ng-content>
3100
+ </div>
2926
3101
 
2927
- <sh-popover
2928
- [(isOpen)]="isOpen"
2929
- (closed)="close()"
2930
- [options]="{
2931
- closeOnButton: false,
2932
- closeOnEsc: true,
2933
- }">
2934
- <ng-content trigger select="input"></ng-content>
3102
+ <div class="prefix-space"></div>
2935
3103
 
2936
- <ng-content select="[popoverContent]"></ng-content>
2937
- </sh-popover>
3104
+ <ng-content select="input"></ng-content>
2938
3105
 
2939
- <ng-content select="textarea"></ng-content>
3106
+ <ng-content select="textarea"></ng-content>
2940
3107
 
2941
- <ng-content select="[textSuffix]"></ng-content>
2942
- <div class="suffix-space"></div>
2943
- <ng-content select="[suffix]"></ng-content>
2944
- </div>
3108
+ <ng-content select="[textSuffix]"></ng-content>
3109
+ <div class="suffix-space"></div>
3110
+ <ng-content select="[suffix]"></ng-content>
3111
+ </div>
3112
+ <ng-content select="[popoverContent]"></ng-content>
3113
+ </sh-popover>
2945
3114
 
2946
3115
  <div class="helpers">
2947
3116
  <div class="error-wrap">
@@ -2962,32 +3131,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
2962
3131
  template: `
2963
3132
  <ng-content select="label"></ng-content>
2964
3133
 
2965
- <div class="input-wrap">
2966
- <div class="prefix">
2967
- <ng-content select="[prefix]"></ng-content>
2968
- <ng-content select="[textPrefix]"></ng-content>
2969
- </div>
3134
+ <sh-popover
3135
+ [(isOpen)]="isOpen"
3136
+ (closed)="close()"
3137
+ [options]="{
3138
+ closeOnButton: false,
3139
+ closeOnEsc: true,
3140
+ }">
3141
+ <div trigger class="input-wrap">
3142
+ <div class="prefix">
3143
+ <ng-content select="[prefix]"></ng-content>
3144
+ <ng-content select="[textPrefix]"></ng-content>
3145
+ </div>
2970
3146
 
2971
- <div class="prefix-space"></div>
3147
+ <div class="prefix-space"></div>
2972
3148
 
2973
- <sh-popover
2974
- [(isOpen)]="isOpen"
2975
- (closed)="close()"
2976
- [options]="{
2977
- closeOnButton: false,
2978
- closeOnEsc: true,
2979
- }">
2980
- <ng-content trigger select="input"></ng-content>
3149
+ <ng-content select="input"></ng-content>
2981
3150
 
2982
- <ng-content select="[popoverContent]"></ng-content>
2983
- </sh-popover>
3151
+ <ng-content select="textarea"></ng-content>
2984
3152
 
2985
- <ng-content select="textarea"></ng-content>
2986
-
2987
- <ng-content select="[textSuffix]"></ng-content>
2988
- <div class="suffix-space"></div>
2989
- <ng-content select="[suffix]"></ng-content>
2990
- </div>
3153
+ <ng-content select="[textSuffix]"></ng-content>
3154
+ <div class="suffix-space"></div>
3155
+ <ng-content select="[suffix]"></ng-content>
3156
+ </div>
3157
+ <ng-content select="[popoverContent]"></ng-content>
3158
+ </sh-popover>
2991
3159
 
2992
3160
  <div class="helpers">
2993
3161
  <div class="error-wrap">
@@ -3006,27 +3174,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
3006
3174
  args: ['click']
3007
3175
  }] } });
3008
3176
 
3009
- function contentProjectionSignal(querySelector) {
3010
- const hostElement = inject((ElementRef)).nativeElement;
3011
- const destroyRef = inject(DestroyRef);
3012
- const projectedElementsSignal = signal([], ...(ngDevMode ? [{ debugName: "projectedElementsSignal" }] : []));
3013
- const updateElements = () => {
3014
- projectedElementsSignal.set(Array.from(hostElement.querySelectorAll(querySelector)));
3015
- };
3016
- updateElements();
3017
- if (typeof MutationObserver === 'undefined')
3018
- return projectedElementsSignal.asReadonly();
3019
- const observer = new MutationObserver((mutations) => {
3020
- const hasChildListChanges = mutations.some((mutation) => mutation.type === 'childList');
3021
- if (hasChildListChanges) {
3022
- updateElements();
3023
- }
3024
- });
3025
- observer.observe(hostElement, { childList: true });
3026
- destroyRef.onDestroy(() => observer.disconnect());
3027
- return projectedElementsSignal.asReadonly();
3028
- }
3029
-
3030
3177
  class ShipDatepickerInput {
3031
3178
  constructor() {
3032
3179
  // #INIT_DATE = this.#getUTCDate(new Date());
@@ -3057,7 +3204,7 @@ class ShipDatepickerInput {
3057
3204
  return;
3058
3205
  this.#createCustomInputEventListener(input);
3059
3206
  input.addEventListener('inputValueChanged', (event) => {
3060
- this.internalDate.set(event.detail.value ? this.#getUTCDate(new Date(event.detail.value)) : null);
3207
+ this.internalDate.set(event.detail.value ? new Date(event.detail.value) : null);
3061
3208
  });
3062
3209
  input.addEventListener('focus', () => {
3063
3210
  this.isOpen.set(true);
@@ -3066,7 +3213,7 @@ class ShipDatepickerInput {
3066
3213
  this.#inputRef.set(input);
3067
3214
  input.autocomplete = 'off';
3068
3215
  if (typeof input.value === 'string') {
3069
- this.internalDate.set(input.value ? this.#getUTCDate(new Date(input.value)) : null);
3216
+ this.internalDate.set(input.value ? new Date(input.value) : null);
3070
3217
  }
3071
3218
  }, ...(ngDevMode ? [{ debugName: "#inputRefEffect" }] : []));
3072
3219
  }
@@ -3108,11 +3255,6 @@ class ShipDatepickerInput {
3108
3255
  });
3109
3256
  return input;
3110
3257
  }
3111
- #getUTCDate(date) {
3112
- const offsetMinutes = date.getTimezoneOffset();
3113
- const timeDiffMillis = offsetMinutes * 60 * 1000;
3114
- return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()) + timeDiffMillis);
3115
- }
3116
3258
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipDatepickerInput, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3117
3259
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ShipDatepickerInput, isStandalone: true, selector: "sh-datepicker-input", inputs: { masking: { classPropertyName: "masking", publicName: "masking", isSignal: true, isRequired: false, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", isOpen: "isOpenChange" }, providers: [DatePipe], queries: [{ propertyName: "ngModels", first: true, predicate: NgModel, descendants: true, isSignal: true }], ngImport: i0, template: `
3118
3260
  <sh-form-field-popover (closed)="close()" [(isOpen)]="isOpen">
@@ -3927,13 +4069,39 @@ class ShipMenu {
3927
4069
  }
3928
4070
  else {
3929
4071
  el.click();
3930
- queueMicrotask(() => this.close('active'));
4072
+ if (!el.querySelector('sh-checkbox')) {
4073
+ queueMicrotask(() => this.close('active'));
4074
+ }
3931
4075
  }
3932
4076
  }
3933
4077
  }
3934
4078
  else if (e.key === 'Tab') {
3935
- e.preventDefault();
3936
- this.close('closed');
4079
+ let optionElements = this.activeElements();
4080
+ if (!optionElements.length) {
4081
+ const newOptionElements = this.optionsEl();
4082
+ this.activeElements.set(newOptionElements);
4083
+ optionElements = newOptionElements;
4084
+ }
4085
+ if (e.shiftKey) {
4086
+ if (activeOptionIndex <= 0) {
4087
+ e.preventDefault();
4088
+ this.close('closed');
4089
+ }
4090
+ else {
4091
+ e.preventDefault();
4092
+ this.activeOptionIndex.set(this.prevActiveIndex(activeOptionIndex));
4093
+ }
4094
+ }
4095
+ else {
4096
+ if (activeOptionIndex >= optionElements.length - 1) {
4097
+ e.preventDefault();
4098
+ this.close('closed');
4099
+ }
4100
+ else {
4101
+ e.preventDefault();
4102
+ this.activeOptionIndex.set(this.nextActiveIndex(activeOptionIndex));
4103
+ }
4104
+ }
3937
4105
  }
3938
4106
  };
3939
4107
  this._lastElementList = [];
@@ -4106,6 +4274,10 @@ class ShipMenu {
4106
4274
  }
4107
4275
  close(action = 'closed', event) {
4108
4276
  this.inputValue.set('');
4277
+ const inputEl = this.inputRef()?.nativeElement;
4278
+ if (inputEl) {
4279
+ inputEl.value = '';
4280
+ }
4109
4281
  if (this.closeOnClick()) {
4110
4282
  (!this.keepClickedOptionActive() || action === 'closed') && this.#resetActiveOption();
4111
4283
  this.isOpen.set(false);
@@ -4287,21 +4459,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
4287
4459
 
4288
4460
  class ShipRadio {
4289
4461
  constructor() {
4462
+ this._elementRef = inject(ElementRef);
4463
+ this.internalInput = viewChild('internalInput', ...(ngDevMode ? [{ debugName: "internalInput" }] : []));
4464
+ this.projectedInputs = contentProjectionSignal('input:not(.internal-input)', {
4465
+ childList: true,
4466
+ attributes: true,
4467
+ });
4468
+ this.checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
4290
4469
  this.currentClassList = classMutationSignal();
4291
4470
  this.color = input(null, ...(ngDevMode ? [{ debugName: "color" }] : []));
4292
4471
  this.variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : []));
4293
4472
  this.readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
4473
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
4474
+ this.noInternalInput = input(false, ...(ngDevMode ? [{ debugName: "noInternalInput" }] : []));
4294
4475
  this.hostClasses = shipComponentClasses('radio', {
4295
4476
  color: this.color,
4296
4477
  variant: this.variant,
4297
4478
  readonly: this.readonly,
4298
4479
  });
4299
4480
  }
4481
+ onInternalInputChange(event) {
4482
+ if (this.disabled())
4483
+ return;
4484
+ const input = event.target;
4485
+ this.checked.set(input.checked);
4486
+ }
4487
+ onEnter(event) {
4488
+ const inputEl = this.internalInput()?.nativeElement;
4489
+ if (inputEl && getComputedStyle(inputEl).display !== 'none') {
4490
+ inputEl.click();
4491
+ }
4492
+ else {
4493
+ this._elementRef.nativeElement.click();
4494
+ }
4495
+ event.preventDefault();
4496
+ }
4300
4497
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipRadio, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4301
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipRadio, isStandalone: true, selector: "sh-radio", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
4498
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ShipRadio, isStandalone: true, selector: "sh-radio", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, noInternalInput: { classPropertyName: "noInternalInput", publicName: "noInternalInput", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, host: { listeners: { "keydown.enter": "onEnter($event)" }, properties: { "class": "hostClasses()", "attr.disabled": "disabled() ? \"\" : null" } }, viewQueries: [{ propertyName: "internalInput", first: true, predicate: ["internalInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
4302
4499
  <div class="radio sh-sheet" [class]="currentClassList()"></div>
4303
4500
 
4304
4501
  <ng-content />
4502
+
4503
+ @if (projectedInputs().length === 0 && !noInternalInput()) {
4504
+ <input
4505
+ #internalInput
4506
+ type="radio"
4507
+ class="internal-input"
4508
+ [attr.disabled]="disabled() ? '' : null"
4509
+ [checked]="checked()"
4510
+ (change)="onInternalInputChange($event)" />
4511
+ }
4305
4512
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4306
4513
  }
4307
4514
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipRadio, decorators: [{
@@ -4313,13 +4520,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
4313
4520
  <div class="radio sh-sheet" [class]="currentClassList()"></div>
4314
4521
 
4315
4522
  <ng-content />
4523
+
4524
+ @if (projectedInputs().length === 0 && !noInternalInput()) {
4525
+ <input
4526
+ #internalInput
4527
+ type="radio"
4528
+ class="internal-input"
4529
+ [attr.disabled]="disabled() ? '' : null"
4530
+ [checked]="checked()"
4531
+ (change)="onInternalInputChange($event)" />
4532
+ }
4316
4533
  `,
4317
4534
  changeDetection: ChangeDetectionStrategy.OnPush,
4318
4535
  host: {
4319
4536
  '[class]': 'hostClasses()',
4537
+ '[attr.disabled]': 'disabled() ? "" : null',
4320
4538
  },
4321
4539
  }]
4322
- }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }] } });
4540
+ }], propDecorators: { internalInput: [{ type: i0.ViewChild, args: ['internalInput', { isSignal: true }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], noInternalInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "noInternalInput", required: false }] }], onEnter: [{
4541
+ type: HostListener,
4542
+ args: ['keydown.enter', ['$event']]
4543
+ }] } });
4323
4544
 
4324
4545
  class ShipRangeSlider {
4325
4546
  constructor() {
@@ -5294,7 +5515,7 @@ class ShipSelect {
5294
5515
  [class.selected]="isSelected($index)"
5295
5516
  [class.focused]="$index === focusedOptionIndex()">
5296
5517
  @if (selectMultiple()) {
5297
- <sh-checkbox [class]="selectClasses()" [class.active]="isSelected($index)" />
5518
+ <sh-checkbox [class]="selectClasses()" [checked]="isSelected($index)" />
5298
5519
  }
5299
5520
 
5300
5521
  @if (_listOptionTemplate) {
@@ -5306,7 +5527,7 @@ class ShipSelect {
5306
5527
  }
5307
5528
  </div>
5308
5529
  </sh-popover>
5309
- `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ShipPopover, selector: "sh-popover", inputs: ["asMultiLayer", "disableOpenByClick", "isOpen", "options"], outputs: ["isOpenChange", "closed"] }, { kind: "component", type: ShipFormField, selector: "sh-form-field", inputs: ["color", "variant", "size", "readonly"] }, { kind: "component", type: ShipIcon, selector: "sh-icon", inputs: ["color", "variant", "size"] }, { kind: "component", type: ShipCheckbox, selector: "sh-checkbox", inputs: ["color", "variant", "readonly"] }, { kind: "component", type: ShipSpinner, selector: "sh-spinner", inputs: ["color"] }, { kind: "component", type: ShipChip, selector: "sh-chip", inputs: ["color", "variant", "size", "sharp", "dynamic", "readonly"] }, { kind: "component", type: ShipDivider, selector: "sh-divider" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5530
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ShipPopover, selector: "sh-popover", inputs: ["asMultiLayer", "disableOpenByClick", "isOpen", "options"], outputs: ["isOpenChange", "closed"] }, { kind: "component", type: ShipFormField, selector: "sh-form-field", inputs: ["color", "variant", "size", "readonly"] }, { kind: "component", type: ShipIcon, selector: "sh-icon", inputs: ["color", "variant", "size"] }, { kind: "component", type: ShipCheckbox, selector: "sh-checkbox", inputs: ["checked", "color", "variant", "readonly", "disabled", "noInternalInput"], outputs: ["checkedChange"] }, { kind: "component", type: ShipSpinner, selector: "sh-spinner", inputs: ["color"] }, { kind: "component", type: ShipChip, selector: "sh-chip", inputs: ["color", "variant", "size", "sharp", "dynamic", "readonly"] }, { kind: "component", type: ShipDivider, selector: "sh-divider" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5310
5531
  }
5311
5532
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipSelect, decorators: [{
5312
5533
  type: Component,
@@ -5454,7 +5675,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
5454
5675
  [class.selected]="isSelected($index)"
5455
5676
  [class.focused]="$index === focusedOptionIndex()">
5456
5677
  @if (selectMultiple()) {
5457
- <sh-checkbox [class]="selectClasses()" [class.active]="isSelected($index)" />
5678
+ <sh-checkbox [class]="selectClasses()" [checked]="isSelected($index)" />
5458
5679
  }
5459
5680
 
5460
5681
  @if (_listOptionTemplate) {
@@ -6000,15 +6221,28 @@ function moveIndex(array, event) {
6000
6221
  return newArray;
6001
6222
  }
6002
6223
 
6003
- class ShipStepper {
6224
+ class ShipStepper extends ShipSelectionGroup {
6004
6225
  constructor() {
6226
+ super('[value], [step], [routerLinkActive], button, a', 'active');
6005
6227
  this.color = input(null, ...(ngDevMode ? [{ debugName: "color" }] : []));
6006
6228
  this.hostClasses = shipComponentClasses('stepper', {
6007
6229
  color: this.color,
6008
6230
  });
6231
+ effect(() => {
6232
+ this.items().forEach((item) => {
6233
+ if (!item.querySelector('.sh-radio')) {
6234
+ const shRadio = document.createElement('div');
6235
+ shRadio.className = 'sh-radio';
6236
+ const shRadioContent = document.createElement('div');
6237
+ shRadioContent.className = 'radio sh-sheet';
6238
+ shRadio.append(shRadioContent);
6239
+ item.prepend(shRadio);
6240
+ }
6241
+ });
6242
+ });
6009
6243
  }
6010
6244
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipStepper, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6011
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipStepper, isStandalone: true, selector: "sh-stepper", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
6245
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipStepper, isStandalone: true, selector: "sh-stepper", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, usesInheritance: true, ngImport: i0, template: `
6012
6246
  <ng-content />
6013
6247
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6014
6248
  }
@@ -6025,7 +6259,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
6025
6259
  '[class]': 'hostClasses()',
6026
6260
  },
6027
6261
  }]
6028
- }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
6262
+ }], ctorParameters: () => [], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
6029
6263
 
6030
6264
  class ShipResize {
6031
6265
  constructor() {
@@ -6420,8 +6654,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
6420
6654
  args: ['window:resize', ['$event']]
6421
6655
  }] } });
6422
6656
 
6423
- class ShipTabs {
6657
+ class ShipTabs extends ShipSelectionGroup {
6424
6658
  constructor() {
6659
+ super('[value], [tab], button, a', 'active');
6425
6660
  this.id = '--' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 12);
6426
6661
  this.color = input(null, ...(ngDevMode ? [{ debugName: "color" }] : []));
6427
6662
  this.variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : []));
@@ -6431,7 +6666,7 @@ class ShipTabs {
6431
6666
  });
6432
6667
  }
6433
6668
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipTabs, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6434
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipTabs, isStandalone: true, selector: "sh-tabs", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "style.--tabs-id": "id" } }, ngImport: i0, template: `
6669
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipTabs, isStandalone: true, selector: "sh-tabs", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "style.--tabs-id": "id" } }, usesInheritance: true, ngImport: i0, template: `
6435
6670
  <ng-content />
6436
6671
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6437
6672
  }
@@ -6449,7 +6684,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
6449
6684
  '[style.--tabs-id]': 'id',
6450
6685
  },
6451
6686
  }]
6452
- }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }] } });
6687
+ }], ctorParameters: () => [], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }] } });
6453
6688
 
6454
6689
  const THEME_ORDER = ['light', 'dark', null];
6455
6690
  const WINDOW = new InjectionToken('WindowToken', {
@@ -6628,22 +6863,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
6628
6863
 
6629
6864
  class ShipToggle {
6630
6865
  constructor() {
6866
+ this._elementRef = inject(ElementRef);
6867
+ this.internalInput = viewChild('internalInput', ...(ngDevMode ? [{ debugName: "internalInput" }] : []));
6868
+ this.projectedInputs = contentProjectionSignal('input:not(.internal-input)', {
6869
+ childList: true,
6870
+ attributes: true,
6871
+ });
6872
+ this.checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
6631
6873
  this.color = input(null, ...(ngDevMode ? [{ debugName: "color" }] : []));
6632
6874
  this.variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : []));
6633
6875
  this.readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
6876
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
6877
+ this.noInternalInput = input(false, ...(ngDevMode ? [{ debugName: "noInternalInput" }] : []));
6634
6878
  this.hostClasses = shipComponentClasses('toggle', {
6635
6879
  color: this.color,
6636
6880
  variant: this.variant,
6637
6881
  readonly: this.readonly,
6638
6882
  });
6639
6883
  }
6884
+ onInternalInputChange(event) {
6885
+ if (this.disabled())
6886
+ return;
6887
+ const input = event.target;
6888
+ this.checked.set(input.checked);
6889
+ }
6890
+ onEnter(event) {
6891
+ const inputEl = this.internalInput()?.nativeElement;
6892
+ if (inputEl && getComputedStyle(inputEl).display !== 'none') {
6893
+ inputEl.click();
6894
+ }
6895
+ else {
6896
+ this._elementRef.nativeElement.click();
6897
+ }
6898
+ event.preventDefault();
6899
+ }
6640
6900
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipToggle, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6641
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: ShipToggle, isStandalone: true, selector: "sh-toggle", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
6901
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: ShipToggle, isStandalone: true, selector: "sh-toggle", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, noInternalInput: { classPropertyName: "noInternalInput", publicName: "noInternalInput", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, host: { listeners: { "keydown.enter": "onEnter($event)" }, properties: { "class": "hostClasses()", "attr.disabled": "disabled() ? \"\" : null" } }, viewQueries: [{ propertyName: "internalInput", first: true, predicate: ["internalInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
6642
6902
  <div class="box">
6643
6903
  <div class="knob"></div>
6644
6904
  </div>
6645
6905
 
6646
6906
  <ng-content />
6907
+
6908
+ @if (projectedInputs().length === 0 && !noInternalInput()) {
6909
+ <input
6910
+ #internalInput
6911
+ type="checkbox"
6912
+ class="internal-input"
6913
+ [attr.disabled]="disabled() ? '' : null"
6914
+ [checked]="checked()"
6915
+ (change)="onInternalInputChange($event)" />
6916
+ }
6647
6917
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6648
6918
  }
6649
6919
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ShipToggle, decorators: [{
@@ -6657,13 +6927,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
6657
6927
  </div>
6658
6928
 
6659
6929
  <ng-content />
6930
+
6931
+ @if (projectedInputs().length === 0 && !noInternalInput()) {
6932
+ <input
6933
+ #internalInput
6934
+ type="checkbox"
6935
+ class="internal-input"
6936
+ [attr.disabled]="disabled() ? '' : null"
6937
+ [checked]="checked()"
6938
+ (change)="onInternalInputChange($event)" />
6939
+ }
6660
6940
  `,
6661
6941
  changeDetection: ChangeDetectionStrategy.OnPush,
6662
6942
  host: {
6663
6943
  '[class]': 'hostClasses()',
6944
+ '[attr.disabled]': 'disabled() ? "" : null',
6664
6945
  },
6665
6946
  }]
6666
- }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }] } });
6947
+ }], propDecorators: { internalInput: [{ type: i0.ViewChild, args: ['internalInput', { isSignal: true }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], noInternalInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "noInternalInput", required: false }] }], onEnter: [{
6948
+ type: HostListener,
6949
+ args: ['keydown.enter', ['$event']]
6950
+ }] } });
6667
6951
 
6668
6952
  class ShipVirtualScroll {
6669
6953
  constructor() {