ngx-fixed-footer 3.1.0 → 3.2.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.
package/README.md CHANGED
@@ -141,7 +141,7 @@ _None_
141
141
 
142
142
  ## 🪪 License
143
143
 
144
- Copyright © 2021 - 2024 [Dominik Hladik](https://github.com/Celtian)
144
+ Copyright © 2021 - 2025 [Dominik Hladik](https://github.com/Celtian)
145
145
 
146
146
  All contents are licensed under the [MIT license].
147
147
 
@@ -21,33 +21,40 @@ const provideFixedFooter = (options) => {
21
21
  };
22
22
 
23
23
  class NgxFixedFooterDirective {
24
+ document = inject(DOCUMENT);
25
+ el = inject(ElementRef);
26
+ render = inject(Renderer2);
27
+ options = inject(APP_FIXED_FOOTER_OPTIONS_TOKEN, { optional: true }) || DEFAULT_FIXED_FOOTER_OPTIONS;
28
+ hasResizeObserver = typeof ResizeObserver !== 'undefined';
29
+ resizeObserver;
30
+ offsetHeight = signal(undefined);
31
+ prevContainerSelector = signal(undefined);
32
+ containerSelector = input(this.options.containerSelector);
33
+ cssAttribute = input(this.options.cssAttribute);
34
+ container = computed(() => {
35
+ const selector = this.containerSelector() || this.options.containerSelector;
36
+ return this.document.body.querySelector(selector);
37
+ });
24
38
  constructor() {
25
- this.document = inject(DOCUMENT);
26
- this.el = inject(ElementRef);
27
- this.render = inject(Renderer2);
28
- this.options = inject(APP_FIXED_FOOTER_OPTIONS_TOKEN, { optional: true }) || DEFAULT_FIXED_FOOTER_OPTIONS;
29
- this.hasResizeObserver = typeof ResizeObserver !== 'undefined';
30
- this.offsetHeight = signal(undefined);
31
- this.resizeObserver = signal(undefined);
32
- this.prevContainerSelector = signal(undefined);
33
- this.containerSelector = input(this.options.containerSelector);
34
- this.cssAttribute = input(this.options.cssAttribute);
35
- this.container = computed(() => {
36
- const selector = this.containerSelector() || this.options.containerSelector;
37
- return this.document.body.querySelector(selector);
38
- });
39
39
  // swap selector
40
40
  effect(() => {
41
41
  if (!this.hasResizeObserver || !this.document)
42
42
  return;
43
- const cssAttribute = this.cssAttribute();
44
43
  const containerSelector = this.containerSelector();
45
- if (containerSelector) {
46
- const prevContainerSelector = this.prevContainerSelector();
47
- if (prevContainerSelector && prevContainerSelector !== containerSelector) {
48
- this.removeStyle(this.document.body.querySelector(prevContainerSelector), cssAttribute);
44
+ const offsetHeight = this.offsetHeight();
45
+ if (!containerSelector || typeof offsetHeight !== 'number')
46
+ return;
47
+ const cssAttribute = this.cssAttribute();
48
+ const prevContainerSelector = this.prevContainerSelector();
49
+ if (prevContainerSelector && prevContainerSelector !== containerSelector) {
50
+ const prevContainer = this.document.body.querySelector(prevContainerSelector);
51
+ if (prevContainer) {
52
+ this.removeStyle(prevContainer, cssAttribute);
49
53
  }
50
- this.setStyle(this.document.body.querySelector(containerSelector), cssAttribute, this.offsetHeight());
54
+ }
55
+ const container = this.document.body.querySelector(containerSelector);
56
+ if (container) {
57
+ this.setStyle(container, cssAttribute, offsetHeight);
51
58
  this.prevContainerSelector.set(containerSelector);
52
59
  }
53
60
  });
@@ -55,30 +62,33 @@ class NgxFixedFooterDirective {
55
62
  effect(() => {
56
63
  if (!this.hasResizeObserver || !this.document)
57
64
  return;
65
+ const container = this.container();
66
+ const offsetHeight = this.offsetHeight();
67
+ if (!container || typeof offsetHeight !== 'number')
68
+ return;
58
69
  const cssAttribute = this.cssAttribute();
59
- if (cssAttribute) {
60
- const container = this.container();
61
- this.removeStyle(container, cssAttribute === 'padding' ? 'margin' : 'padding');
62
- this.setStyle(container, cssAttribute, this.offsetHeight());
63
- }
70
+ this.removeStyle(container, cssAttribute === 'padding' ? 'margin' : 'padding');
71
+ this.setStyle(container, cssAttribute, offsetHeight);
64
72
  });
65
73
  }
66
74
  ngOnInit() {
67
75
  if (this.hasResizeObserver && this.document) {
68
- const resizeObserver = new ResizeObserver(() => this.checkHeight());
69
- resizeObserver.observe(this.html);
76
+ this.resizeObserver = new ResizeObserver(() => this.checkHeight());
77
+ this.resizeObserver.observe(this.html);
70
78
  }
71
79
  }
72
80
  ngOnDestroy() {
73
- if (this.resizeObserver() && this.document) {
74
- this.removeStyle(this.container(), this.cssAttribute());
75
- this.resizeObserver().unobserve(this.html);
81
+ const container = this.container();
82
+ if (this.resizeObserver && this.document && container) {
83
+ this.removeStyle(container, this.cssAttribute());
84
+ this.resizeObserver.unobserve(this.html);
76
85
  }
77
86
  }
78
87
  checkHeight() {
79
88
  const height = this.html.offsetHeight;
80
- if (this.offsetHeight() !== height) {
81
- this.setStyle(this.container(), this.cssAttribute(), height);
89
+ const container = this.container();
90
+ if (this.offsetHeight() !== height && container) {
91
+ this.setStyle(container, this.cssAttribute(), height);
82
92
  this.offsetHeight.set(height);
83
93
  }
84
94
  }
@@ -97,10 +107,10 @@ class NgxFixedFooterDirective {
97
107
  get html() {
98
108
  return this.el.nativeElement;
99
109
  }
100
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NgxFixedFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
101
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.1", type: NgxFixedFooterDirective, isStandalone: true, selector: "[ngxFixedFooter]", inputs: { containerSelector: { classPropertyName: "containerSelector", publicName: "containerSelector", isSignal: true, isRequired: false, transformFunction: null }, cssAttribute: { classPropertyName: "cssAttribute", publicName: "cssAttribute", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
110
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: NgxFixedFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
111
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.1.6", type: NgxFixedFooterDirective, isStandalone: true, selector: "[ngxFixedFooter]", inputs: { containerSelector: { classPropertyName: "containerSelector", publicName: "containerSelector", isSignal: true, isRequired: false, transformFunction: null }, cssAttribute: { classPropertyName: "cssAttribute", publicName: "cssAttribute", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
102
112
  }
103
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: NgxFixedFooterDirective, decorators: [{
113
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: NgxFixedFooterDirective, decorators: [{
104
114
  type: Directive,
105
115
  args: [{
106
116
  selector: '[ngxFixedFooter]',
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-fixed-footer.mjs","sources":["../../../projects/ngx-fixed-footer/src/lib/ngx-fixed-footer.constants.ts","../../../projects/ngx-fixed-footer/src/lib/ngx-fixed-footer.provider.ts","../../../projects/ngx-fixed-footer/src/lib/ngx-fixed-footer.directive.ts","../../../projects/ngx-fixed-footer/src/public-api.ts","../../../projects/ngx-fixed-footer/src/ngx-fixed-footer.ts"],"sourcesContent":["import { NgxFixedFooterOptions } from './ngx-fixed-footer.interface';\n\nexport const DEFAULT_CSS_ATTRIBUTE = 'padding';\nexport const DEFAULT_CONTAINER_SELECTOR = '[role=\"main\"]';\nexport const DEFAULT_FIXED_FOOTER_OPTIONS: NgxFixedFooterOptions = {\n containerSelector: DEFAULT_CONTAINER_SELECTOR,\n cssAttribute: DEFAULT_CSS_ATTRIBUTE\n};\n","import { InjectionToken, Provider } from '@angular/core';\nimport { DEFAULT_CONTAINER_SELECTOR, DEFAULT_CSS_ATTRIBUTE } from './ngx-fixed-footer.constants';\nimport { NgxFixedFooterOptions } from './ngx-fixed-footer.interface';\n\nexport const APP_FIXED_FOOTER_OPTIONS_TOKEN = new InjectionToken<NgxFixedFooterOptions>('[ngxFixedFooter] Options');\n\nexport const provideFixedFooter = (options: Partial<NgxFixedFooterOptions>): Provider => {\n return {\n provide: APP_FIXED_FOOTER_OPTIONS_TOKEN,\n useValue: {\n cssAttribute: options.cssAttribute || DEFAULT_CSS_ATTRIBUTE,\n containerSelector: options.containerSelector || DEFAULT_CONTAINER_SELECTOR\n }\n };\n};\n","import { DOCUMENT } from '@angular/common';\nimport {\n Directive,\n ElementRef,\n OnDestroy,\n OnInit,\n Renderer2,\n computed,\n effect,\n inject,\n input,\n signal\n} from '@angular/core';\nimport { DEFAULT_FIXED_FOOTER_OPTIONS } from './ngx-fixed-footer.constants';\nimport { NgxFixedFooterCssAttribute, NgxFixedFooterOptions } from './ngx-fixed-footer.interface';\nimport { APP_FIXED_FOOTER_OPTIONS_TOKEN } from './ngx-fixed-footer.provider';\n\n@Directive({\n selector: '[ngxFixedFooter]',\n standalone: true\n})\nexport class NgxFixedFooterDirective implements OnDestroy, OnInit {\n private readonly document = inject(DOCUMENT);\n private readonly el = inject(ElementRef);\n private readonly render = inject(Renderer2);\n private options: NgxFixedFooterOptions =\n inject(APP_FIXED_FOOTER_OPTIONS_TOKEN, { optional: true }) || DEFAULT_FIXED_FOOTER_OPTIONS;\n private readonly hasResizeObserver = typeof ResizeObserver !== 'undefined';\n\n private offsetHeight = signal<number | undefined>(undefined);\n private resizeObserver = signal<ResizeObserver | undefined>(undefined);\n private prevContainerSelector = signal<string | undefined>(undefined);\n\n public containerSelector = input<string>(this.options.containerSelector);\n public cssAttribute = input<NgxFixedFooterCssAttribute>(this.options.cssAttribute);\n\n private container = computed<HTMLElement>(() => {\n const selector = this.containerSelector() || this.options.containerSelector;\n return this.document.body.querySelector<HTMLElement>(selector);\n });\n\n constructor() {\n // swap selector\n effect(() => {\n if (!this.hasResizeObserver || !this.document) return;\n const cssAttribute = this.cssAttribute();\n const containerSelector = this.containerSelector();\n if (containerSelector) {\n const prevContainerSelector = this.prevContainerSelector();\n if (prevContainerSelector && prevContainerSelector !== containerSelector) {\n this.removeStyle(this.document.body.querySelector(prevContainerSelector), cssAttribute);\n }\n this.setStyle(this.document.body.querySelector(containerSelector), cssAttribute, this.offsetHeight());\n this.prevContainerSelector.set(containerSelector);\n }\n });\n\n // swap css attribute\n effect(() => {\n if (!this.hasResizeObserver || !this.document) return;\n const cssAttribute = this.cssAttribute();\n if (cssAttribute) {\n const container = this.container();\n this.removeStyle(container, cssAttribute === 'padding' ? 'margin' : 'padding');\n this.setStyle(container, cssAttribute, this.offsetHeight());\n }\n });\n }\n\n public ngOnInit(): void {\n if (this.hasResizeObserver && this.document) {\n const resizeObserver = new ResizeObserver(() => this.checkHeight());\n resizeObserver.observe(this.html);\n }\n }\n\n public ngOnDestroy(): void {\n if (this.resizeObserver() && this.document) {\n this.removeStyle(this.container(), this.cssAttribute());\n this.resizeObserver().unobserve(this.html);\n }\n }\n\n private checkHeight(): void {\n const height = this.html.offsetHeight;\n if (this.offsetHeight() !== height) {\n this.setStyle(this.container(), this.cssAttribute(), height);\n this.offsetHeight.set(height);\n }\n }\n\n private removeStyle(container: HTMLElement, cssAttribute: NgxFixedFooterCssAttribute): void {\n if (!container) {\n throw new Error(`Cannot removeStyle to undefined container`);\n }\n this.render.setStyle(container, `${cssAttribute}-bottom`, '');\n }\n\n private setStyle(container: HTMLElement, cssAttribute: NgxFixedFooterCssAttribute, height: number): void {\n if (!container) {\n throw new Error(`Cannot setStyle to undefined container`);\n }\n this.render.setStyle(container, `${cssAttribute}-bottom`, height === 0 ? '' : `${height}px`);\n }\n\n private get html(): HTMLElement {\n return this.el.nativeElement;\n }\n}\n","/*\n * Public API Surface of ngx-fixed-footer\n */\n\nexport * from './lib/ngx-fixed-footer.constants';\nexport * from './lib/ngx-fixed-footer.directive';\nexport * from './lib/ngx-fixed-footer.interface';\nexport * from './lib/ngx-fixed-footer.provider';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-fixed-footer.mjs","sources":["../../../projects/ngx-fixed-footer/src/lib/ngx-fixed-footer.constants.ts","../../../projects/ngx-fixed-footer/src/lib/ngx-fixed-footer.provider.ts","../../../projects/ngx-fixed-footer/src/lib/ngx-fixed-footer.directive.ts","../../../projects/ngx-fixed-footer/src/public-api.ts","../../../projects/ngx-fixed-footer/src/ngx-fixed-footer.ts"],"sourcesContent":["import { NgxFixedFooterOptions } from './ngx-fixed-footer.interface';\n\nexport const DEFAULT_CSS_ATTRIBUTE = 'padding';\nexport const DEFAULT_CONTAINER_SELECTOR = '[role=\"main\"]';\nexport const DEFAULT_FIXED_FOOTER_OPTIONS: NgxFixedFooterOptions = {\n containerSelector: DEFAULT_CONTAINER_SELECTOR,\n cssAttribute: DEFAULT_CSS_ATTRIBUTE\n};\n","import { InjectionToken, Provider } from '@angular/core';\nimport { DEFAULT_CONTAINER_SELECTOR, DEFAULT_CSS_ATTRIBUTE } from './ngx-fixed-footer.constants';\nimport { NgxFixedFooterOptions } from './ngx-fixed-footer.interface';\n\nexport const APP_FIXED_FOOTER_OPTIONS_TOKEN = new InjectionToken<NgxFixedFooterOptions>('[ngxFixedFooter] Options');\n\nexport const provideFixedFooter = (options: Partial<NgxFixedFooterOptions>): Provider => {\n return {\n provide: APP_FIXED_FOOTER_OPTIONS_TOKEN,\n useValue: {\n cssAttribute: options.cssAttribute || DEFAULT_CSS_ATTRIBUTE,\n containerSelector: options.containerSelector || DEFAULT_CONTAINER_SELECTOR\n }\n };\n};\n","import { DOCUMENT } from '@angular/common';\nimport {\n Directive,\n ElementRef,\n OnDestroy,\n OnInit,\n Renderer2,\n computed,\n effect,\n inject,\n input,\n signal\n} from '@angular/core';\nimport { DEFAULT_FIXED_FOOTER_OPTIONS } from './ngx-fixed-footer.constants';\nimport { NgxFixedFooterCssAttribute, NgxFixedFooterOptions } from './ngx-fixed-footer.interface';\nimport { APP_FIXED_FOOTER_OPTIONS_TOKEN } from './ngx-fixed-footer.provider';\n\n@Directive({\n selector: '[ngxFixedFooter]',\n standalone: true\n})\nexport class NgxFixedFooterDirective implements OnDestroy, OnInit {\n private readonly document = inject(DOCUMENT);\n private readonly el = inject(ElementRef);\n private readonly render = inject(Renderer2);\n private options: NgxFixedFooterOptions =\n inject(APP_FIXED_FOOTER_OPTIONS_TOKEN, { optional: true }) || DEFAULT_FIXED_FOOTER_OPTIONS;\n private readonly hasResizeObserver = typeof ResizeObserver !== 'undefined';\n private resizeObserver?: ResizeObserver;\n\n private offsetHeight = signal<number | undefined>(undefined);\n private prevContainerSelector = signal<string | undefined>(undefined);\n\n public containerSelector = input<string>(this.options.containerSelector);\n public cssAttribute = input<NgxFixedFooterCssAttribute>(this.options.cssAttribute);\n\n private container = computed(() => {\n const selector = this.containerSelector() || this.options.containerSelector;\n return this.document.body.querySelector<HTMLElement>(selector);\n });\n\n constructor() {\n // swap selector\n effect(() => {\n if (!this.hasResizeObserver || !this.document) return;\n const containerSelector = this.containerSelector();\n const offsetHeight = this.offsetHeight();\n if (!containerSelector || typeof offsetHeight !== 'number') return;\n const cssAttribute = this.cssAttribute();\n const prevContainerSelector = this.prevContainerSelector();\n if (prevContainerSelector && prevContainerSelector !== containerSelector) {\n const prevContainer = this.document.body.querySelector<HTMLElement>(prevContainerSelector);\n if (prevContainer) {\n this.removeStyle(prevContainer, cssAttribute);\n }\n }\n const container = this.document.body.querySelector<HTMLElement>(containerSelector);\n if (container) {\n this.setStyle(container, cssAttribute, offsetHeight);\n this.prevContainerSelector.set(containerSelector);\n }\n });\n\n // swap css attribute\n effect(() => {\n if (!this.hasResizeObserver || !this.document) return;\n const container = this.container();\n const offsetHeight = this.offsetHeight();\n if (!container || typeof offsetHeight !== 'number') return;\n const cssAttribute = this.cssAttribute();\n this.removeStyle(container, cssAttribute === 'padding' ? 'margin' : 'padding');\n this.setStyle(container, cssAttribute, offsetHeight);\n });\n }\n\n public ngOnInit(): void {\n if (this.hasResizeObserver && this.document) {\n this.resizeObserver = new ResizeObserver(() => this.checkHeight());\n this.resizeObserver.observe(this.html);\n }\n }\n\n public ngOnDestroy(): void {\n const container = this.container();\n if (this.resizeObserver && this.document && container) {\n this.removeStyle(container, this.cssAttribute());\n this.resizeObserver.unobserve(this.html);\n }\n }\n\n private checkHeight(): void {\n const height = this.html.offsetHeight;\n const container = this.container();\n if (this.offsetHeight() !== height && container) {\n this.setStyle(container, this.cssAttribute(), height);\n this.offsetHeight.set(height);\n }\n }\n\n private removeStyle(container: HTMLElement, cssAttribute: NgxFixedFooterCssAttribute): void {\n if (!container) {\n throw new Error(`Cannot removeStyle to undefined container`);\n }\n this.render.setStyle(container, `${cssAttribute}-bottom`, '');\n }\n\n private setStyle(container: HTMLElement, cssAttribute: NgxFixedFooterCssAttribute, height: number): void {\n if (!container) {\n throw new Error(`Cannot setStyle to undefined container`);\n }\n this.render.setStyle(container, `${cssAttribute}-bottom`, height === 0 ? '' : `${height}px`);\n }\n\n private get html(): HTMLElement {\n return this.el.nativeElement;\n }\n}\n","/*\n * Public API Surface of ngx-fixed-footer\n */\n\nexport * from './lib/ngx-fixed-footer.constants';\nexport * from './lib/ngx-fixed-footer.directive';\nexport * from './lib/ngx-fixed-footer.interface';\nexport * from './lib/ngx-fixed-footer.provider';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -7,8 +7,8 @@ export declare class NgxFixedFooterDirective implements OnDestroy, OnInit {
7
7
  private readonly render;
8
8
  private options;
9
9
  private readonly hasResizeObserver;
10
+ private resizeObserver?;
10
11
  private offsetHeight;
11
- private resizeObserver;
12
12
  private prevContainerSelector;
13
13
  containerSelector: import("@angular/core").InputSignal<string>;
14
14
  cssAttribute: import("@angular/core").InputSignal<NgxFixedFooterCssAttribute>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-fixed-footer",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "author": {
5
5
  "name": "Dominik Hladík",
6
6
  "email": "dominik.hladik@seznam.cz",