@sneat/space-components 0.27.6 → 0.27.8

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 +1 @@
1
- {"version":3,"file":"spaces-list.component.js","sourceRoot":"","sources":["../../../../../../../libs/space/components/src/lib/spaces-list/spaces-list.component.ts","../../../../../../../libs/space/components/src/lib/spaces-list/spaces-list.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,YAAY,EACZ,MAAM,EACN,MAAM,EACN,KAAK,EACN,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,OAAO,EACP,OAAO,EACP,QAAQ,EACR,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAG3D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;;AAwB7B,MAAM,OAAO,mBAAoB,SAAQ,kBAAkB;IAtB3D;;QAuBkB,gBAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACtC,oBAAe,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;QAC1C,iBAAY,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;QACpC,8BAAyB,GAAG,MAAM,CACjD,yBAAyB,CAC1B,CAAC;QAEF,SAAS;QACA,WAAM,GAAG,KAAK,CAAC,QAAQ;mFAAsB,CAAC;QAC9C,WAAM,GAAG,KAAK,CAAC,QAAQ;mFAA+B,CAAC;QACvD,eAAU,GAAG,KAAK,CAAC,QAAQ;uFAAC,CAAC;QACtC,sEAAsE;QACtE,8DAA8D;QACrD,eAAU,GAAG,KAAK,CAAC,KAAK;uFAAC,CAAC;QAEnC,UAAU;QACS,0BAAqB,GAAG,IAAI,YAAY,EAAiB,CAAC;QAC1D,cAAS,GAAG,IAAI,YAAY,EAAiB,CAAC;KA6FlE;IA3FW,OAAO,CAAC,KAAY,EAAE,KAAoB;QAClD,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACb,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,eAAe,CAAC,KAAoB;QAC1C,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,eAAe;aACjB,eAAe,CAAC,KAAK,CAAC;aACtB,KAAK,CACJ,IAAI,CAAC,WAAW,CAAC,eAAe,CAC9B,2DAA2D,CAC5D,CACF,CAAC;IACN,CAAC;IAES,cAAc,CAAC,IAAe;QACtC,MAAM,OAAO,GAAwB;YACnC,IAAI;SACL,CAAC;QAEF,IAAI,CAAC,WAAW,CAAC,SAAS;aACvB,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;aACxC,SAAS,CAAC;YACT,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE;gBAClB,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;oBACrB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,yBAAyB;yBAC3B,IAAI,EAAE;yBACN,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE;wBACpB,IAAI,WAAW,EAAE,CAAC;4BAChB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;wBAC5B,CAAC;oBACH,CAAC,CAAC;yBACD,KAAK,CACJ,IAAI,CAAC,WAAW,CAAC,eAAe,CAC9B,2CAA2C,CAC5C,CACF,CAAC;gBACN,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QACL,oBAAoB;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,WAAW,CAAC,OAA4B;QAC9C,IAAI,CAAC,YAAY;aACd,WAAW,CAAC,OAAO,CAAC;aACpB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;aAC/B,SAAS,CAAC;YACT,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;gBACd,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;YACD,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,eAAe,CACrC,oCAAoC,CACrC;SACF,CAAC,CAAC;IACP,CAAC;IAED,6EAA6E;IAC7E,2EAA2E;IACjE,UAAU,CAAC,KAAoB,EAAE,KAAa;QACtD,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,mCAAmC,KAAK,IAAI,CAAC,EAAE,CAAC;YAC3D,OAAO;QACT,CAAC;QACD,IAAI,CAAC,YAAY;aACd,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;aACjC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;aAC/B,SAAS,CAAC;YACT,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;YACtC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,eAAe,CACrC,0BAA0B,KAAK,EAAE,CAClC;SACF,CAAC,CAAC;IACP,CAAC;8GA9GU,mBAAmB;kGAAnB,mBAAmB,mqBARnB;YACT;gBACE,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,qBAAqB;aAChC;SACF,iDC9CH,mrCAwCA,4CDTI,UAAU,kPAEV,OAAO,0NACP,OAAO,2JACP,QAAQ,6FACR,QAAQ,iFACR,UAAU,yGACV,UAAU,8EACV,SAAS,iRAPT,aAAa;;2FAiBJ,mBAAmB;kBAtB/B,SAAS;+BACE,mBAAmB,WAEpB;wBACP,UAAU;wBACV,aAAa;wBACb,OAAO;wBACP,OAAO;wBACP,QAAQ;wBACR,QAAQ;wBACR,UAAU;wBACV,UAAU;wBACV,SAAS;qBACV,aACU;wBACT;4BACE,OAAO,EAAE,SAAS;4BAClB,QAAQ,EAAE,qBAAqB;yBAChC;qBACF,mBACgB,uBAAuB,CAAC,MAAM;;sBAmB9C,MAAM;;sBACN,MAAM","sourcesContent":["import { TitleCasePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Output,\n inject,\n input\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport {\n IonBadge,\n IonButton,\n IonButtons,\n IonIcon,\n IonItem,\n IonLabel,\n IonSpinner,\n} from '@ionic/angular';\nimport { UserRequiredFieldsService } from '@sneat/auth-ui';\nimport { SpaceType } from '@sneat/core';\nimport { ICreateSpaceRequest, ISpaceContext } from '@sneat/space-models';\nimport { SpaceNavService, SpaceService } from '@sneat/space-services';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { ClassName, SneatBaseComponent } from '@sneat/ui';\nimport { first } from 'rxjs';\n\n@Component({\n selector: 'sneat-spaces-list',\n templateUrl: 'spaces-list.component.html',\n imports: [\n RouterLink,\n TitleCasePipe,\n IonItem,\n IonIcon,\n IonLabel,\n IonBadge,\n IonSpinner,\n IonButtons,\n IonButton,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'SpacesListComponent',\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SpacesListComponent extends SneatBaseComponent {\n public readonly userService = inject(SneatUserService);\n private readonly spaceNavService = inject(SpaceNavService);\n private readonly spaceService = inject(SpaceService);\n private readonly userRequiredFieldsService = inject(\n UserRequiredFieldsService,\n );\n\n // Inputs\n readonly userID = input.required<string | undefined>();\n readonly spaces = input.required<ISpaceContext[] | undefined>();\n readonly pathPrefix = input('/space');\n // Opt-in: render a per-row \"leave\" button. Off by default so existing\n // consumers (spaces menu, for-space-type-card) are unchanged.\n readonly allowLeave = input(false);\n\n // Outputs\n @Output() readonly beforeNavigateToSpace = new EventEmitter<ISpaceContext>();\n @Output() readonly leftSpace = new EventEmitter<ISpaceContext>();\n\n protected goSpace(event: Event, space: ISpaceContext): boolean {\n event.stopPropagation();\n event.preventDefault();\n if (space.id) {\n this.navigateToSpace(space);\n } else if (space.type) {\n this.createNewSpace(space.type);\n }\n return false;\n }\n\n private navigateToSpace(space: ISpaceContext): void {\n this.beforeNavigateToSpace.emit(space);\n this.spaceNavService\n .navigateToSpace(space)\n .catch(\n this.errorLogger.logErrorHandler(\n 'Failed to navigate to teams overview page from teams menu',\n ),\n );\n }\n\n protected createNewSpace(type: SpaceType): boolean {\n const request: ICreateSpaceRequest = {\n type,\n };\n\n this.userService.userState\n .pipe(first(), this.takeUntilDestroyed())\n .subscribe({\n next: (userState) => {\n if (userState.record) {\n this.createSpace(request);\n } else {\n this.userRequiredFieldsService\n .open()\n .then((modalResult) => {\n if (modalResult) {\n this.createSpace(request);\n }\n })\n .catch(\n this.errorLogger.logErrorHandler(\n 'Failed to open user required fields modal',\n ),\n );\n }\n },\n });\n // this.closeMenu();\n return false;\n }\n\n private createSpace(request: ICreateSpaceRequest): void {\n this.spaceService\n .createSpace(request)\n .pipe(this.takeUntilDestroyed())\n .subscribe({\n next: (value) => {\n this.navigateToSpace(value);\n },\n error: this.errorLogger.logErrorHandler(\n 'failed to create a new family team',\n ),\n });\n }\n\n // Only reachable when [allowLeave]=\"true\". Stops the row's navigate handler,\n // confirms, then leaves the space; the user record update removes the row.\n protected leaveSpace(space: ISpaceContext, event?: Event): void {\n if (event) {\n event.stopPropagation();\n event.preventDefault();\n }\n if (!space.id) {\n return;\n }\n const title = space.brief?.title || space.id;\n if (!confirm(`Are you sure you want to leave \"${title}\"?`)) {\n return;\n }\n this.spaceService\n .leaveSpace({ spaceID: space.id })\n .pipe(this.takeUntilDestroyed())\n .subscribe({\n next: () => this.leftSpace.emit(space),\n error: this.errorLogger.logErrorHandler(\n `Failed to leave space: ${title}`,\n ),\n });\n }\n}\n","@for (space of spaces(); track space.id; let last = $last) {\n <ion-item\n tappable=\"true\"\n [disabled]=\"!space.brief\"\n [lines]=\"last ? 'full' : 'inset'\"\n routerLink=\"{{ pathPrefix() }}/{{ space.type }}/{{ space.id }}\"\n (click)=\"goSpace($event, space)\"\n >\n <ion-icon\n [name]=\"\n space.type === 'family'\n ? 'people-outline'\n : space.type === 'personal'\n ? 'person-circle-outline'\n : 'people-outline'\n \"\n slot=\"start\"\n />\n <ion-label class=\"ion-text-wrap\">\n {{ space.brief?.title || (space.type | titlecase) || space.id }}\n @if (!space.id && space.brief) {\n <ion-badge color=\"light\">(new)</ion-badge>\n }\n </ion-label>\n @if (!space.id && !space.brief) {\n <ion-spinner name=\"lines-small\" />\n }\n @if (allowLeave() && space.id) {\n <ion-buttons slot=\"end\">\n <ion-button\n color=\"medium\"\n title=\"Leave\"\n (click)=\"leaveSpace(space, $event)\"\n >\n <ion-icon name=\"close-outline\" slot=\"icon-only\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n}\n"]}
1
+ {"version":3,"file":"spaces-list.component.js","sourceRoot":"","sources":["../../../../../../../libs/space/components/src/lib/spaces-list/spaces-list.component.ts","../../../../../../../libs/space/components/src/lib/spaces-list/spaces-list.component.html"],"names":[],"mappings":"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","sourcesContent":["import { TitleCasePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Output,\n inject,\n input\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport {\n IonBadge,\n IonButton,\n IonButtons,\n IonIcon,\n IonItem,\n IonLabel,\n IonSpinner,\n} from '@ionic/angular';\nimport { UserRequiredFieldsService } from '@sneat/auth-ui';\nimport { SpaceType } from '@sneat/core';\nimport { ICreateSpaceRequest, ISpaceContext } from '@sneat/space-models';\nimport { SpaceNavService, SpaceService } from '@sneat/space-services';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { ClassName, SneatBaseComponent } from '@sneat/ui';\nimport { first } from 'rxjs';\n\n@Component({\n selector: 'sneat-spaces-list',\n templateUrl: 'spaces-list.component.html',\n imports: [\n RouterLink,\n TitleCasePipe,\n IonItem,\n IonIcon,\n IonLabel,\n IonBadge,\n IonSpinner,\n IonButtons,\n IonButton,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'SpacesListComponent',\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SpacesListComponent extends SneatBaseComponent {\n public readonly userService = inject(SneatUserService);\n private readonly spaceNavService = inject(SpaceNavService);\n private readonly spaceService = inject(SpaceService);\n private readonly userRequiredFieldsService = inject(\n UserRequiredFieldsService,\n );\n\n // Inputs\n readonly userID = input.required<string | undefined>();\n readonly spaces = input.required<ISpaceContext[] | undefined>();\n readonly pathPrefix = input('/space');\n // Opt-in: render a per-row \"leave\" button. Off by default so existing\n // consumers (spaces menu, for-space-type-card) are unchanged.\n readonly allowLeave = input(false);\n\n // Outputs\n @Output() readonly beforeNavigateToSpace = new EventEmitter<ISpaceContext>();\n @Output() readonly leftSpace = new EventEmitter<ISpaceContext>();\n\n protected goSpace(event: Event, space: ISpaceContext): boolean {\n event.stopPropagation();\n event.preventDefault();\n if (space.id) {\n this.navigateToSpace(space);\n } else if (space.type) {\n this.createNewSpace(space.type);\n }\n return false;\n }\n\n private navigateToSpace(space: ISpaceContext): void {\n this.beforeNavigateToSpace.emit(space);\n this.spaceNavService\n .navigateToSpace(space)\n .catch(\n this.errorLogger.logErrorHandler(\n 'Failed to navigate to teams overview page from teams menu',\n ),\n );\n }\n\n protected createNewSpace(type: SpaceType): boolean {\n const request: ICreateSpaceRequest = {\n type,\n };\n\n this.userService.userState\n .pipe(first(), this.takeUntilDestroyed())\n .subscribe({\n next: (userState) => {\n if (userState.record) {\n this.createSpace(request);\n } else {\n this.userRequiredFieldsService\n .open()\n .then((modalResult) => {\n if (modalResult) {\n this.createSpace(request);\n }\n })\n .catch(\n this.errorLogger.logErrorHandler(\n 'Failed to open user required fields modal',\n ),\n );\n }\n },\n });\n // this.closeMenu();\n return false;\n }\n\n private createSpace(request: ICreateSpaceRequest): void {\n this.spaceService\n .createSpace(request)\n .pipe(this.takeUntilDestroyed())\n .subscribe({\n next: (value) => {\n this.navigateToSpace(value);\n },\n error: this.errorLogger.logErrorHandler(\n 'failed to create a new family team',\n ),\n });\n }\n\n // Only reachable when [allowLeave]=\"true\". Stops the row's navigate handler,\n // confirms, then leaves the space; the user record update removes the row.\n protected leaveSpace(space: ISpaceContext, event?: Event): void {\n if (event) {\n event.stopPropagation();\n event.preventDefault();\n }\n if (!space.id) {\n return;\n }\n const title = space.brief?.title || space.id;\n if (!confirm(`Are you sure you want to leave \"${title}\"?`)) {\n return;\n }\n this.spaceService\n .leaveSpace({ spaceID: space.id })\n .pipe(this.takeUntilDestroyed())\n .subscribe({\n next: () => this.leftSpace.emit(space),\n error: this.errorLogger.logErrorHandler(\n `Failed to leave space: ${title}`,\n ),\n });\n }\n}\n","@for (space of spaces(); track space.id; let last = $last) {\n <ion-item\n tappable=\"true\"\n [disabled]=\"!space.brief\"\n [lines]=\"last ? 'none' : 'inset'\"\n routerLink=\"{{ pathPrefix() }}/{{ space.type }}/{{ space.id }}\"\n (click)=\"goSpace($event, space)\"\n >\n <ion-icon\n [name]=\"\n space.type === 'family'\n ? 'people-outline'\n : space.type === 'personal'\n ? 'person-circle-outline'\n : 'people-outline'\n \"\n slot=\"start\"\n />\n <ion-label class=\"ion-text-wrap\">\n {{ space.brief?.title || (space.type | titlecase) || space.id }}\n @if (!space.id && space.brief) {\n <ion-badge color=\"light\">(new)</ion-badge>\n }\n </ion-label>\n @if (!space.id && !space.brief) {\n <ion-spinner name=\"lines-small\" />\n }\n @if (allowLeave() && space.id) {\n <ion-buttons slot=\"end\">\n <ion-button\n color=\"medium\"\n title=\"Leave\"\n (click)=\"leaveSpace(space, $event)\"\n >\n <ion-icon name=\"close-outline\" slot=\"icon-only\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n}\n"]}
package/lib/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './avatar/avatar.component';
2
2
  export * from './space-menu';
3
+ export * from './space-selector';
3
4
  export * from './space-extension-links';
4
5
  export * from './spaces-menu';
5
6
  export * from './space-page-title/space-page-title.component';
@@ -1,9 +1,6 @@
1
- import { IUserSpaceBrief } from '@sneat/auth-models';
2
- import { IIdAndBrief } from '@sneat/core';
3
1
  import { SpaceBaseComponent } from '../space-base-component.directive';
4
2
  import * as i0 from "@angular/core";
5
3
  export declare class SpaceMenuComponent extends SpaceBaseComponent {
6
- protected readonly $spaces: import("@angular/core").WritableSignal<readonly IIdAndBrief<IUserSpaceBrief>[] | undefined>;
7
4
  protected readonly $disabled: import("@angular/core").Signal<boolean>;
8
5
  protected readonly $currentPage: import("@angular/core").WritableSignal<string>;
9
6
  private readonly activatedRoute;
@@ -12,8 +9,6 @@ export declare class SpaceMenuComponent extends SpaceBaseComponent {
12
9
  protected goOverview(): boolean;
13
10
  protected goSpacePage(event: Event, _p: string): boolean;
14
11
  protected closeMenu(): void;
15
- protected onSpaceSelected(event: Event): void;
16
- private readonly onUserStateChanged;
17
12
  static ɵfac: i0.ɵɵFactoryDeclaration<SpaceMenuComponent, never>;
18
13
  static ɵcmp: i0.ɵɵComponentDeclaration<SpaceMenuComponent, "sneat-space-menu", never, {}, {}, never, never, true, never>;
19
14
  }
@@ -0,0 +1 @@
1
+ export * from './space-selector.component';
@@ -0,0 +1,28 @@
1
+ import { IUserSpaceBrief } from '@sneat/auth-models';
2
+ import { IIdAndBrief } from '@sneat/core';
3
+ import { SpaceBaseComponent } from '../space-base-component.directive';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Switches the active space and, by default, navigates to that space's default
7
+ * page. Hosts that need to preserve their own sub-route can handle selection
8
+ * through `spaceSelected` and turn off the default navigation.
9
+ *
10
+ * It is deliberately presentation-only: callers place it in a menu section,
11
+ * a card header, or another Ionic item and opt into closing a surrounding menu.
12
+ */
13
+ export declare class SpaceSelectorComponent extends SpaceBaseComponent {
14
+ /** Whether a containing Ionic menu should close after a space is selected. */
15
+ readonly closeMenuOnSelection: import("@angular/core").InputSignal<boolean>;
16
+ /** Align the label and selected space within the enclosing item. */
17
+ readonly justify: import("@angular/core").InputSignal<"start" | "end" | "space-between">;
18
+ /** Whether selection should navigate to the selected space's default page. */
19
+ readonly navigateOnSelection: import("@angular/core").InputSignal<boolean>;
20
+ /** Emits the selected space so a host can preserve its contextual sub-route. */
21
+ readonly spaceSelected: import("@angular/core").OutputEmitterRef<IIdAndBrief<IUserSpaceBrief>>;
22
+ protected readonly $spaces: import("@angular/core").WritableSignal<readonly IIdAndBrief<IUserSpaceBrief>[] | undefined>;
23
+ private readonly menuCtrl;
24
+ constructor();
25
+ protected onSpaceSelected(event: Event): void;
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<SpaceSelectorComponent, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpaceSelectorComponent, "sneat-space-selector", never, { "closeMenuOnSelection": { "alias": "closeMenuOnSelection"; "required": false; "isSignal": true; }; "justify": { "alias": "justify"; "required": false; "isSignal": true; }; "navigateOnSelection": { "alias": "navigateOnSelection"; "required": false; "isSignal": true; }; }, { "spaceSelected": "spaceSelected"; }, never, never, true, never>;
28
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sneat/space-components",
3
- "version": "0.27.6",
3
+ "version": "0.27.8",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },