ng-primitives 0.110.2 → 0.111.1

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,11 +1,11 @@
1
1
  import { createOverlay, injectOverlay, coerceOffset, coerceFlip, coerceShift } from 'ng-primitives/portal';
2
2
  export { injectOverlayContext as injectMenuContext } from 'ng-primitives/portal';
3
3
  import * as i0 from '@angular/core';
4
- import { InjectionToken, inject, Injector, ViewContainerRef, signal, computed, effect, input, booleanAttribute, Directive, numberAttribute } from '@angular/core';
4
+ import { InjectionToken, inject, Injector, ViewContainerRef, signal, computed, effect, input, booleanAttribute, Directive, output, numberAttribute } from '@angular/core';
5
5
  import { ngpRovingFocusItem, provideRovingFocusItemState, ngpRovingFocusGroup, provideRovingFocusGroupState } from 'ng-primitives/roving-focus';
6
6
  import { ngpButton } from 'ng-primitives/button';
7
7
  import { injectElementRef } from 'ng-primitives/internal';
8
- import { createPrimitive, controlled, attrBinding, dataBinding, listener, deprecatedSetter, styleBinding } from 'ng-primitives/state';
8
+ import { createPrimitive, controlled, attrBinding, dataBinding, listener, deprecatedSetter, styleBinding, emitter } from 'ng-primitives/state';
9
9
  import { Directionality } from '@angular/cdk/bidi';
10
10
  import { ngpFocusTrap, provideFocusTrapState } from 'ng-primitives/focus-trap';
11
11
  import { Subject } from 'rxjs';
@@ -694,13 +694,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
694
694
  }]
695
695
  }], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTrigger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerDisabled", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerPlacement", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerOffset", required: false }] }], flip: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerFlip", required: false }] }] } });
696
696
 
697
- const [NgpMenuItemStateToken, ngpMenuItem, injectMenuItemState, provideMenuItemState] = createPrimitive('NgpMenuItem', ({ disabled = signal(false) }) => {
697
+ const [NgpMenuItemStateToken, ngpMenuItem, injectMenuItemState, provideMenuItemState] = createPrimitive('NgpMenuItem', ({ disabled = signal(false), closeOnSelect = signal(true), role = 'menuitem', }) => {
698
698
  const element = injectElementRef();
699
699
  const injector = inject(Injector);
700
700
  const parentMenu = injectMenuState({ optional: true });
701
701
  ngpButton({ disabled });
702
702
  // Host bindings
703
- attrBinding(element, 'role', 'menuitem');
703
+ attrBinding(element, 'role', role);
704
704
  // Event listeners
705
705
  listener(element, 'click', onClick);
706
706
  listener(element, 'keydown', handleArrowKey);
@@ -711,7 +711,8 @@ const [NgpMenuItemStateToken, ngpMenuItem, injectMenuItemState, provideMenuItemS
711
711
  const trigger = injector.get(NgpSubmenuTrigger, null, { self: true, optional: true });
712
712
  const origin = event.detail === 0 ? 'keyboard' : 'mouse';
713
713
  // if this is a submenu trigger, we don't want to close the menu, we want to open the submenu
714
- if (!trigger) {
714
+ // if closeOnSelect is false, we don't want to close the menu (e.g., checkbox/radio items)
715
+ if (!trigger && closeOnSelect()) {
715
716
  parentMenu()?.closeAllMenus(origin);
716
717
  }
717
718
  }
@@ -754,11 +755,17 @@ class NgpMenuItem {
754
755
  alias: 'ngpMenuItemDisabled',
755
756
  transform: booleanAttribute,
756
757
  }]));
757
- ngpMenuItem({ disabled: this.disabled });
758
+ /** Whether the menu should close when this item is selected */
759
+ this.closeOnSelect = input(true, ...(ngDevMode ? [{ debugName: "closeOnSelect", alias: 'ngpMenuItemCloseOnSelect',
760
+ transform: booleanAttribute }] : [{
761
+ alias: 'ngpMenuItemCloseOnSelect',
762
+ transform: booleanAttribute,
763
+ }]));
764
+ ngpMenuItem({ disabled: this.disabled, closeOnSelect: this.closeOnSelect });
758
765
  ngpRovingFocusItem({ disabled: this.disabled });
759
766
  }
760
767
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
761
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: NgpMenuItem, isStandalone: true, selector: "[ngpMenuItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "ngpMenuItemDisabled", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideMenuItemState(), provideRovingFocusItemState()], exportAs: ["ngpMenuItem"], ngImport: i0 }); }
768
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: NgpMenuItem, isStandalone: true, selector: "[ngpMenuItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "ngpMenuItemDisabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "ngpMenuItemCloseOnSelect", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideMenuItemState(), provideRovingFocusItemState()], exportAs: ["ngpMenuItem"], ngImport: i0 }); }
762
769
  }
763
770
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItem, decorators: [{
764
771
  type: Directive,
@@ -767,7 +774,200 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
767
774
  exportAs: 'ngpMenuItem',
768
775
  providers: [provideMenuItemState(), provideRovingFocusItemState()],
769
776
  }]
770
- }], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpMenuItemDisabled", required: false }] }] } });
777
+ }], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpMenuItemDisabled", required: false }] }], closeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpMenuItemCloseOnSelect", required: false }] }] } });
778
+
779
+ const [NgpMenuItemCheckboxStateToken, ngpMenuItemCheckbox, injectMenuItemCheckboxState, provideMenuItemCheckboxState,] = createPrimitive('NgpMenuItemCheckbox', ({ checked: _checked = signal(false), disabled = signal(false), onCheckedChange, }) => {
780
+ const element = injectElementRef();
781
+ const checked = controlled(_checked);
782
+ const checkedChange = emitter();
783
+ // Use base menu item behavior but don't close on select
784
+ ngpMenuItem({ disabled, closeOnSelect: signal(false), role: 'menuitemcheckbox' });
785
+ // Host bindings
786
+ attrBinding(element, 'aria-checked', checked);
787
+ dataBinding(element, 'data-checked', checked);
788
+ // Toggle on click
789
+ listener(element, 'click', () => toggle());
790
+ function toggle() {
791
+ if (disabled()) {
792
+ return;
793
+ }
794
+ const nextChecked = !checked();
795
+ checked.set(nextChecked);
796
+ onCheckedChange?.(nextChecked);
797
+ checkedChange.emit(nextChecked);
798
+ }
799
+ return {
800
+ checked,
801
+ checkedChange: checkedChange.asObservable(),
802
+ toggle,
803
+ };
804
+ });
805
+
806
+ /**
807
+ * The `NgpMenuItemCheckbox` directive represents a menu item that can be toggled on and off.
808
+ */
809
+ class NgpMenuItemCheckbox {
810
+ constructor() {
811
+ /** Whether the checkbox is checked */
812
+ this.checked = input(false, ...(ngDevMode ? [{ debugName: "checked", alias: 'ngpMenuItemCheckboxChecked',
813
+ transform: booleanAttribute }] : [{
814
+ alias: 'ngpMenuItemCheckboxChecked',
815
+ transform: booleanAttribute,
816
+ }]));
817
+ /** Event emitted when the checked state changes */
818
+ this.checkedChange = output({
819
+ alias: 'ngpMenuItemCheckboxCheckedChange',
820
+ });
821
+ /** Whether the menu item checkbox is disabled */
822
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", alias: 'ngpMenuItemCheckboxDisabled',
823
+ transform: booleanAttribute }] : [{
824
+ alias: 'ngpMenuItemCheckboxDisabled',
825
+ transform: booleanAttribute,
826
+ }]));
827
+ ngpMenuItemCheckbox({
828
+ checked: this.checked,
829
+ disabled: this.disabled,
830
+ onCheckedChange: value => this.checkedChange.emit(value),
831
+ });
832
+ ngpRovingFocusItem({ disabled: this.disabled });
833
+ }
834
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItemCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
835
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: NgpMenuItemCheckbox, isStandalone: true, selector: "[ngpMenuItemCheckbox]", inputs: { checked: { classPropertyName: "checked", publicName: "ngpMenuItemCheckboxChecked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpMenuItemCheckboxDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "ngpMenuItemCheckboxCheckedChange" }, providers: [provideMenuItemCheckboxState(), provideRovingFocusItemState()], exportAs: ["ngpMenuItemCheckbox"], ngImport: i0 }); }
836
+ }
837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItemCheckbox, decorators: [{
838
+ type: Directive,
839
+ args: [{
840
+ selector: '[ngpMenuItemCheckbox]',
841
+ exportAs: 'ngpMenuItemCheckbox',
842
+ providers: [provideMenuItemCheckboxState(), provideRovingFocusItemState()],
843
+ }]
844
+ }], ctorParameters: () => [], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpMenuItemCheckboxChecked", required: false }] }], checkedChange: [{ type: i0.Output, args: ["ngpMenuItemCheckboxCheckedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpMenuItemCheckboxDisabled", required: false }] }] } });
845
+
846
+ const [NgpMenuItemRadioGroupStateToken, ngpMenuItemRadioGroup, injectMenuItemRadioGroupState, provideMenuItemRadioGroupState,] = createPrimitive('NgpMenuItemRadioGroup', ({ value: _value = signal(null), onValueChange, }) => {
847
+ const element = injectElementRef();
848
+ const value = controlled(_value);
849
+ const valueChange = emitter();
850
+ // Host bindings
851
+ attrBinding(element, 'role', 'group');
852
+ function select(newValue) {
853
+ if (value() === newValue) {
854
+ return;
855
+ }
856
+ value.set(newValue);
857
+ onValueChange?.(newValue);
858
+ valueChange.emit(newValue);
859
+ }
860
+ return {
861
+ value,
862
+ valueChange: valueChange.asObservable(),
863
+ select,
864
+ };
865
+ });
866
+
867
+ const [NgpMenuItemRadioStateToken, ngpMenuItemRadio, injectMenuItemRadioState, provideMenuItemRadioState,] = createPrimitive('NgpMenuItemRadio', ({ value, disabled = signal(false) }) => {
868
+ const element = injectElementRef();
869
+ const radioGroup = injectMenuItemRadioGroupState();
870
+ // Use base menu item behavior but don't close on select
871
+ ngpMenuItem({ disabled, closeOnSelect: signal(false), role: 'menuitemradio' });
872
+ // Computed checked state
873
+ const checked = computed(() => radioGroup()?.value() === value(), ...(ngDevMode ? [{ debugName: "checked" }] : []));
874
+ // Host bindings
875
+ attrBinding(element, 'aria-checked', checked);
876
+ dataBinding(element, 'data-checked', checked);
877
+ // Select on click
878
+ listener(element, 'click', () => {
879
+ if (disabled()) {
880
+ return;
881
+ }
882
+ radioGroup()?.select(value());
883
+ });
884
+ return {
885
+ checked,
886
+ };
887
+ });
888
+
889
+ /**
890
+ * The `NgpMenuItemIndicator` directive renders inside a checkbox or radio menu item
891
+ * and exposes `data-checked` based on the parent item's checked state.
892
+ */
893
+ class NgpMenuItemIndicator {
894
+ constructor() {
895
+ const element = injectElementRef();
896
+ const checkboxState = injectMenuItemCheckboxState({ optional: true });
897
+ const radioState = injectMenuItemRadioState({ optional: true });
898
+ const checked = computed(() => checkboxState()?.checked() ?? radioState()?.checked() ?? false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
899
+ dataBinding(element, 'data-checked', checked);
900
+ }
901
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItemIndicator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
902
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.9", type: NgpMenuItemIndicator, isStandalone: true, selector: "[ngpMenuItemIndicator]", exportAs: ["ngpMenuItemIndicator"], ngImport: i0 }); }
903
+ }
904
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItemIndicator, decorators: [{
905
+ type: Directive,
906
+ args: [{
907
+ selector: '[ngpMenuItemIndicator]',
908
+ exportAs: 'ngpMenuItemIndicator',
909
+ }]
910
+ }], ctorParameters: () => [] });
911
+
912
+ /**
913
+ * The `NgpMenuItemRadioGroup` directive represents a group of radio menu items.
914
+ */
915
+ class NgpMenuItemRadioGroup {
916
+ constructor() {
917
+ /** The current value of the radio group */
918
+ this.value = input(null, ...(ngDevMode ? [{ debugName: "value", alias: 'ngpMenuItemRadioGroupValue' }] : [{
919
+ alias: 'ngpMenuItemRadioGroupValue',
920
+ }]));
921
+ /** Event emitted when the value changes */
922
+ this.valueChange = output({
923
+ alias: 'ngpMenuItemRadioGroupValueChange',
924
+ });
925
+ ngpMenuItemRadioGroup({
926
+ value: this.value,
927
+ onValueChange: value => this.valueChange.emit(value),
928
+ });
929
+ }
930
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItemRadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
931
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: NgpMenuItemRadioGroup, isStandalone: true, selector: "[ngpMenuItemRadioGroup]", inputs: { value: { classPropertyName: "value", publicName: "ngpMenuItemRadioGroupValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "ngpMenuItemRadioGroupValueChange" }, providers: [provideMenuItemRadioGroupState()], exportAs: ["ngpMenuItemRadioGroup"], ngImport: i0 }); }
932
+ }
933
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItemRadioGroup, decorators: [{
934
+ type: Directive,
935
+ args: [{
936
+ selector: '[ngpMenuItemRadioGroup]',
937
+ exportAs: 'ngpMenuItemRadioGroup',
938
+ providers: [provideMenuItemRadioGroupState()],
939
+ }]
940
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpMenuItemRadioGroupValue", required: false }] }], valueChange: [{ type: i0.Output, args: ["ngpMenuItemRadioGroupValueChange"] }] } });
941
+
942
+ /**
943
+ * The `NgpMenuItemRadio` directive represents a radio menu item within a radio group.
944
+ */
945
+ class NgpMenuItemRadio {
946
+ constructor() {
947
+ /** The value this radio item represents */
948
+ this.value = input.required(...(ngDevMode ? [{ debugName: "value", alias: 'ngpMenuItemRadioValue' }] : [{
949
+ alias: 'ngpMenuItemRadioValue',
950
+ }]));
951
+ /** Whether the radio item is disabled */
952
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", alias: 'ngpMenuItemRadioDisabled',
953
+ transform: booleanAttribute }] : [{
954
+ alias: 'ngpMenuItemRadioDisabled',
955
+ transform: booleanAttribute,
956
+ }]));
957
+ ngpMenuItemRadio({ value: this.value, disabled: this.disabled });
958
+ ngpRovingFocusItem({ disabled: this.disabled });
959
+ }
960
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItemRadio, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
961
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.9", type: NgpMenuItemRadio, isStandalone: true, selector: "[ngpMenuItemRadio]", inputs: { value: { classPropertyName: "value", publicName: "ngpMenuItemRadioValue", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpMenuItemRadioDisabled", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideMenuItemRadioState(), provideRovingFocusItemState()], exportAs: ["ngpMenuItemRadio"], ngImport: i0 }); }
962
+ }
963
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: NgpMenuItemRadio, decorators: [{
964
+ type: Directive,
965
+ args: [{
966
+ selector: '[ngpMenuItemRadio]',
967
+ exportAs: 'ngpMenuItemRadio',
968
+ providers: [provideMenuItemRadioState(), provideRovingFocusItemState()],
969
+ }]
970
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpMenuItemRadioValue", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpMenuItemRadioDisabled", required: false }] }] } });
771
971
 
772
972
  /**
773
973
  * The `NgpMenuTrigger` directive allows you to turn an element into a menu trigger.
@@ -986,5 +1186,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImpor
986
1186
  * Generated bundle index. Do not edit.
987
1187
  */
988
1188
 
989
- export { NgpMenu, NgpMenuItem, NgpMenuTrigger, NgpSubmenuTrigger, injectMenuItemState, injectMenuState, injectMenuTriggerState, injectSubmenuTriggerState, provideMenuConfig, provideMenuItemState, provideMenuState, provideMenuTriggerState, provideSubmenuTriggerState };
1189
+ export { NgpMenu, NgpMenuItem, NgpMenuItemCheckbox, NgpMenuItemIndicator, NgpMenuItemRadio, NgpMenuItemRadioGroup, NgpMenuTrigger, NgpSubmenuTrigger, injectMenuItemCheckboxState, injectMenuItemRadioGroupState, injectMenuItemRadioState, injectMenuItemState, injectMenuState, injectMenuTriggerState, injectSubmenuTriggerState, provideMenuConfig, provideMenuItemCheckboxState, provideMenuItemRadioGroupState, provideMenuItemRadioState, provideMenuItemState, provideMenuState, provideMenuTriggerState, provideSubmenuTriggerState };
990
1190
  //# sourceMappingURL=ng-primitives-menu.mjs.map