@reforgium/presentia 1.0.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
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# @reforgium/presentia
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@reforgium/presentia)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
**Signals-first state stores and caching utilities for Angular (20+).**
|
|
7
|
+
|
|
8
|
+
Presentia Contents:
|
|
9
|
+
- Providers and initialization: [`provideReInit`](`src/providers/init.provider.ts`) (locale, themes, breakpoints).
|
|
10
|
+
- Localization: [`LangService`](`src/lang/lang.service.ts`), [`LangPipe`](`src/lang/lang.pipe.ts`), [`LangDirective`](`src/lang/lang.directive.ts`).
|
|
11
|
+
- Themes: [`ThemeService`](`src/theme/theme.service.ts`).
|
|
12
|
+
- Adaptivity: [`AdaptiveService`](`src/adaptive/adaptive.service.ts`), [`IfDeviceDirective`](`src/adaptive/device-type.directive.ts`).
|
|
13
|
+
|
|
14
|
+
Designed for **application infrastructure**.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @reforgium/presentia
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The provider factory [`provideReInit(config: AppConfig)`](`src/providers/init.provider.ts`) performs basic application setup: localization, adaptive breakpoints, store config, and DI tokens for validation messages.
|
|
25
|
+
Location: [`init.provider.ts`](`src/providers/init.provider.ts`).
|
|
26
|
+
|
|
27
|
+
What it does:
|
|
28
|
+
- Registers DI tokens:
|
|
29
|
+
- `DEVICE_BREAKPOINTS` (breakpoints for AdaptiveService).
|
|
30
|
+
- `THEME_CONFIG` (theme configuration and dark theme prefix).
|
|
31
|
+
- `LANG_CONFIG`, `LOCALE_ID` (languages and dictionaries for `LangService`).
|
|
32
|
+
|
|
33
|
+
Example integration in the root application:
|
|
34
|
+
```ts
|
|
35
|
+
bootstrapApplication(AppComponent, {
|
|
36
|
+
providers: [
|
|
37
|
+
provideReInit({
|
|
38
|
+
locale: {
|
|
39
|
+
isFromAssets: true,
|
|
40
|
+
defaultLang: 'ru',
|
|
41
|
+
},
|
|
42
|
+
theme: {
|
|
43
|
+
defaultTheme: 'dark',
|
|
44
|
+
darkThemePrefix: 're-dark',
|
|
45
|
+
},
|
|
46
|
+
breakpoints: {
|
|
47
|
+
'mobile': '(max-width: 719px)',
|
|
48
|
+
'tablet': '(min-width: 720px) and (max-width: 1399px)',
|
|
49
|
+
'desktop-s': '(min-width: 1400px) and (max-width: 1919px)',
|
|
50
|
+
'desktop': '(min-width: 1920px)',
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Package Structure
|
|
60
|
+
|
|
61
|
+
- **seo** — SEO management (title, meta, open graph, twitter, json-ld) with route tracking.
|
|
62
|
+
- **lang** — signals-based localization with dynamic dictionary loading.
|
|
63
|
+
- **theme** — light/dark theme management with system sync.
|
|
64
|
+
- **adaptive** — responsive breakpoints tracking and device-specific rendering.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Localization: LangService, LangPipe, LangDirective
|
|
69
|
+
|
|
70
|
+
- [`LangService`](`src/lang/lang.service.ts`) — manages current language and dictionaries (static/dynamic), provides signal selectors for translation by key.
|
|
71
|
+
- [`LangPipe`](`src/lang/lang.pipe.ts`), `pure: false` — dynamically translates strings by key and parameters: `{{ 'app.hello' | lang:{ name: userName } }}`.
|
|
72
|
+
- [`LangDirective`](`src/lang/lang.directive.ts`) — directive for automatic translation of attributes (`title`, `label`, `placeholder`). Usage: `<input placeholder="common.search" reLang />`.
|
|
73
|
+
- [`LANG_CONFIG`] — InjectionToken with translation source configuration.
|
|
74
|
+
- Types: `Langs`, `LangParams`, `LangModel`, `LangDto`, `LocaleConfig`.
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
```ts
|
|
78
|
+
import { Component, computed, inject } from '@angular/core';
|
|
79
|
+
import { LangPipe, LangService } from '.../lang';
|
|
80
|
+
|
|
81
|
+
@Component({
|
|
82
|
+
selector: 'app-hello',
|
|
83
|
+
standalone: true,
|
|
84
|
+
imports: [LangPipe],
|
|
85
|
+
template: `
|
|
86
|
+
<h1>{{ 'common.hello' | lang }}</h1>
|
|
87
|
+
<p>{{ 'users.welcome' | lang: { name: userName } }}</p>
|
|
88
|
+
<button (click)="switch()">RU/KG</button>
|
|
89
|
+
`,
|
|
90
|
+
})
|
|
91
|
+
export class HelloComponent {
|
|
92
|
+
private lang = inject(LangService);
|
|
93
|
+
userName = 'Vasya';
|
|
94
|
+
|
|
95
|
+
switch() {
|
|
96
|
+
this.lang.setLang(this.lang.currentLang() === 'ru' ? 'kg' : 'ru');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Theming: ThemeService
|
|
104
|
+
|
|
105
|
+
- [`ThemeService`](`src/theme/theme.service.ts`) — manages light/dark theme.
|
|
106
|
+
- Methods: `switch()`, `isLight()`, etc.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Adaptivity: AdaptiveService and IfDeviceDirective
|
|
111
|
+
|
|
112
|
+
- [`AdaptiveService`](`src/adaptive/adaptive.service.ts`) — tracks sizes, device type (mobile/tablet/desktop), supports signals for width/height/orientation.
|
|
113
|
+
- [`IfDeviceDirective`](`src/adaptive/device-type.directive.ts`) — structural directive for conditional display by device type.
|
|
114
|
+
|
|
115
|
+
How `IfDeviceDirective` works:
|
|
116
|
+
- Selector: `[reIfDevice]` (standalone).
|
|
117
|
+
- Inputs:
|
|
118
|
+
- `reIfDevice: Devices | Devices[]` — allowed device types (one or list).
|
|
119
|
+
- `inverse?: boolean` — invert condition (show everywhere except specified devices).
|
|
120
|
+
- Reactively tracks current device type from `AdaptiveService.device`, creates/clears embedded view.
|
|
121
|
+
|
|
122
|
+
Usage examples:
|
|
123
|
+
```html
|
|
124
|
+
<!-- 1) Mobile only -->
|
|
125
|
+
<div *reIfDevice="'mobile'">Mobile phones only</div>
|
|
126
|
+
|
|
127
|
+
<!-- 2) Tablets and desktops -->
|
|
128
|
+
<div *reIfDevice="['tablet', 'desktop']">Tablet and desktop</div>
|
|
129
|
+
|
|
130
|
+
<!-- 3) Hide on desktop (inverse) -->
|
|
131
|
+
<div *reIfDevice="'desktop'; inverse: true">Visible everywhere except desktop</div>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## SEO: SeoService and SeoRouteListener
|
|
137
|
+
- [`SeoService`](`src/seo/seo.service.ts`) — service for working with SEO
|
|
138
|
+
|
|
139
|
+
Example:
|
|
140
|
+
```ts
|
|
141
|
+
const service = inject(SeoService);
|
|
142
|
+
|
|
143
|
+
service.setTitle('My page');
|
|
144
|
+
service.setDescription('My page description');
|
|
145
|
+
service.setKeywords(['angular', 'signals', 'seo', 'meta']);
|
|
146
|
+
service.setCanonical('https://example.com/page');
|
|
147
|
+
service.setTwitter({ card: 'summary_large_image', site: '@myapp' });
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
- [`SeoRouteListener`](`src/seo/seo-route.listener.ts`) — service for working with SEO, with route tracking
|
|
151
|
+
|
|
152
|
+
Example:
|
|
153
|
+
```ts
|
|
154
|
+
bootstrapApplication(AppComponent, {
|
|
155
|
+
providers: [provideRouter(routes)],
|
|
156
|
+
}).then(ref => {
|
|
157
|
+
// base site URL
|
|
158
|
+
ref.injector.get(SeoRouteListener).init('https://example.com');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
export default [
|
|
162
|
+
{
|
|
163
|
+
path: '',
|
|
164
|
+
loadComponent: () => import('./pages/home.page').then(m => m.HomePage),
|
|
165
|
+
data: {
|
|
166
|
+
title: 'Home — MyApp',
|
|
167
|
+
description: 'Home page description',
|
|
168
|
+
og: { image: 'https://example.com/og/home.png', type: 'website', site_name: 'MyApp' },
|
|
169
|
+
twitter: { card: 'summary_large_image', site: '@myapp' },
|
|
170
|
+
jsonld: {
|
|
171
|
+
'@context': 'https://schema.org',
|
|
172
|
+
'@type': 'WebSite',
|
|
173
|
+
name: 'MyApp',
|
|
174
|
+
url: 'https://example.com'
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
]
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Compatibility
|
|
184
|
+
|
|
185
|
+
- Angular: 18+
|
|
186
|
+
- Signals: required
|
|
187
|
+
- Zone.js: optional
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT
|