@ojiepermana/angular 0.1.1 → 21.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 +41 -249
- package/fesm2022/ojiepermana-angular-chart.mjs +3714 -0
- package/fesm2022/ojiepermana-angular-chart.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-component.mjs +3463 -0
- package/fesm2022/ojiepermana-angular-component.mjs.map +1 -0
- package/fesm2022/ojiepermana-angular-layout.mjs +276 -408
- package/fesm2022/ojiepermana-angular-layout.mjs.map +1 -1
- package/fesm2022/ojiepermana-angular-navigation.mjs +2198 -404
- package/fesm2022/ojiepermana-angular-navigation.mjs.map +1 -1
- package/fesm2022/ojiepermana-angular-theme.mjs +381 -1
- package/fesm2022/ojiepermana-angular-theme.mjs.map +1 -1
- package/fesm2022/ojiepermana-angular.mjs +15 -1
- package/fesm2022/ojiepermana-angular.mjs.map +1 -1
- package/package.json +49 -36
- package/theme/styles/etos.css +38 -0
- package/theme/styles/index.css +32 -8
- package/theme/styles/themes/brand/etos/color.css +21 -0
- package/theme/styles/themes/brand/etos/style.css +50 -0
- package/theme/styles/themes/library/_components.css +63 -0
- package/theme/styles/themes/library/_layers.css +15 -0
- package/theme/styles/themes/library/_material-overrides.css +254 -0
- package/theme/styles/themes/library/_tokens.css +54 -0
- package/theme/styles/themes/library/color/amber.css +18 -0
- package/theme/styles/themes/library/color/blue.css +23 -0
- package/theme/styles/themes/library/color/green.css +18 -0
- package/theme/styles/themes/library/color/index.css +9 -0
- package/theme/styles/themes/library/color/purple.css +18 -0
- package/theme/styles/themes/library/color/red.css +18 -0
- package/theme/styles/themes/library/style/brutal.css +47 -0
- package/theme/styles/themes/library/style/default.css +51 -0
- package/theme/styles/themes/library/style/index.css +8 -0
- package/theme/styles/themes/library/style/sharp.css +47 -0
- package/theme/styles/themes/library/style/soft.css +47 -0
- package/theme/styles/themes/mode/dark.css +20 -0
- package/theme/styles/themes/mode/index.css +6 -0
- package/theme/styles/themes/mode/light.css +24 -0
- package/theme/styles/themes/taildwind.css +109 -0
- package/types/ojiepermana-angular-chart.d.ts +1094 -0
- package/types/ojiepermana-angular-component.d.ts +1174 -0
- package/types/ojiepermana-angular-layout.d.ts +123 -76
- package/types/ojiepermana-angular-navigation.d.ts +256 -116
- package/types/ojiepermana-angular-theme.d.ts +170 -1
- package/types/ojiepermana-angular.d.ts +2 -1
- package/fesm2022/ojiepermana-angular-internal.mjs +0 -489
- package/fesm2022/ojiepermana-angular-internal.mjs.map +0 -1
- package/fesm2022/ojiepermana-angular-navigation-horizontal.mjs +0 -721
- package/fesm2022/ojiepermana-angular-navigation-horizontal.mjs.map +0 -1
- package/fesm2022/ojiepermana-angular-navigation-vertical.mjs +0 -1647
- package/fesm2022/ojiepermana-angular-navigation-vertical.mjs.map +0 -1
- package/fesm2022/ojiepermana-angular-shell.mjs +0 -19
- package/fesm2022/ojiepermana-angular-shell.mjs.map +0 -1
- package/fesm2022/ojiepermana-angular-theme-component.mjs +0 -235
- package/fesm2022/ojiepermana-angular-theme-component.mjs.map +0 -1
- package/fesm2022/ojiepermana-angular-theme-directive.mjs +0 -29
- package/fesm2022/ojiepermana-angular-theme-directive.mjs.map +0 -1
- package/fesm2022/ojiepermana-angular-theme-service.mjs +0 -241
- package/fesm2022/ojiepermana-angular-theme-service.mjs.map +0 -1
- package/layout/README.md +0 -144
- package/layout/src/component/horizontal/horizontal.css +0 -130
- package/layout/src/component/vertical/vertical.css +0 -75
- package/layout/src/layout.css +0 -16
- package/navigation/README.md +0 -301
- package/navigation/horizontal/README.md +0 -49
- package/shell/README.md +0 -41
- package/styles/index.css +0 -2
- package/styles/resets.css +0 -22
- package/theme/README.md +0 -379
- package/theme/styles/adapters/material-ui/index.css +0 -205
- package/theme/styles/modes/dark.css +0 -84
- package/theme/styles/presets/colors/blue.css +0 -45
- package/theme/styles/presets/colors/brand.css +0 -52
- package/theme/styles/presets/colors/cyan.css +0 -45
- package/theme/styles/presets/colors/green.css +0 -45
- package/theme/styles/presets/colors/index.css +0 -7
- package/theme/styles/presets/colors/orange.css +0 -45
- package/theme/styles/presets/colors/purple.css +0 -45
- package/theme/styles/presets/colors/red.css +0 -45
- package/theme/styles/presets/styles/flat.css +0 -61
- package/theme/styles/presets/styles/glass.css +0 -28
- package/theme/styles/presets/styles/index.css +0 -2
- package/theme/styles/roles/index.css +0 -67
- package/theme/styles/tokens/foundation.css +0 -136
- package/theme/styles/tokens/semantic.css +0 -87
- package/theme/styles/utilities/index.css +0 -88
- package/types/ojiepermana-angular-internal.d.ts +0 -90
- package/types/ojiepermana-angular-navigation-horizontal.d.ts +0 -81
- package/types/ojiepermana-angular-navigation-vertical.d.ts +0 -262
- package/types/ojiepermana-angular-shell.d.ts +0 -14
- package/types/ojiepermana-angular-theme-component.d.ts +0 -46
- package/types/ojiepermana-angular-theme-directive.d.ts +0 -10
- package/types/ojiepermana-angular-theme-service.d.ts +0 -68
- /package/{navigation/vertical → chart}/README.md +0 -0
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, DestroyRef, PLATFORM_ID, signal, computed, effect, Injectable, isDevMode, makeEnvironmentProviders } from '@angular/core';
|
|
3
|
-
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
|
|
4
|
-
import { LocalStorageStateAdapter } from '@ojiepermana/angular/internal';
|
|
5
|
-
|
|
6
|
-
const DEFAULT_NG_THEME_CONFIG = {
|
|
7
|
-
defaultScheme: 'system',
|
|
8
|
-
defaultColor: 'brand',
|
|
9
|
-
defaultStyle: 'flat',
|
|
10
|
-
};
|
|
11
|
-
const NG_THEME_CONFIG = new InjectionToken('NG_THEME_CONFIG', {
|
|
12
|
-
providedIn: 'root',
|
|
13
|
-
factory: () => ({ ...DEFAULT_NG_THEME_CONFIG }),
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const THEME_SCHEMES = ['light', 'dark', 'system'];
|
|
17
|
-
const THEME_COLORS = ['brand', 'blue', 'green', 'red', 'cyan', 'purple', 'orange'];
|
|
18
|
-
const THEME_STYLES = ['flat', 'glass'];
|
|
19
|
-
const THEME_SCHEME_SET = new Set(THEME_SCHEMES);
|
|
20
|
-
const THEME_COLOR_SET = new Set(THEME_COLORS);
|
|
21
|
-
const THEME_STYLE_SET = new Set(THEME_STYLES);
|
|
22
|
-
function isThemeScheme(value) {
|
|
23
|
-
return typeof value === 'string' && THEME_SCHEME_SET.has(value);
|
|
24
|
-
}
|
|
25
|
-
function isThemeColor(value) {
|
|
26
|
-
return typeof value === 'string' && THEME_COLOR_SET.has(value);
|
|
27
|
-
}
|
|
28
|
-
function isThemeStyle(value) {
|
|
29
|
-
return typeof value === 'string' && THEME_STYLE_SET.has(value);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const THEME_COLOR_OPTIONS = [
|
|
33
|
-
{ value: 'brand', label: 'Brand' },
|
|
34
|
-
{ value: 'blue', label: 'Blue' },
|
|
35
|
-
{ value: 'green', label: 'Green' },
|
|
36
|
-
{ value: 'red', label: 'Red' },
|
|
37
|
-
{ value: 'cyan', label: 'Cyan' },
|
|
38
|
-
{ value: 'purple', label: 'Purple' },
|
|
39
|
-
{ value: 'orange', label: 'Orange' },
|
|
40
|
-
];
|
|
41
|
-
function createThemeColorOptions(allowedColors, colorLabels) {
|
|
42
|
-
const allowedSet = allowedColors ? new Set(allowedColors) : null;
|
|
43
|
-
return THEME_COLOR_OPTIONS.filter((option) => !allowedSet || allowedSet.has(option.value)).map((option) => ({
|
|
44
|
-
value: option.value,
|
|
45
|
-
label: colorLabels?.[option.value] ?? option.label,
|
|
46
|
-
}));
|
|
47
|
-
}
|
|
48
|
-
const STORAGE_KEYS = {
|
|
49
|
-
scheme: 'theme-scheme',
|
|
50
|
-
color: 'theme-color',
|
|
51
|
-
style: 'theme-style',
|
|
52
|
-
};
|
|
53
|
-
const LEGACY_STORAGE_PREFIX = 'ng-theme:v2';
|
|
54
|
-
class ThemeService {
|
|
55
|
-
config = inject(NG_THEME_CONFIG);
|
|
56
|
-
document = inject(DOCUMENT);
|
|
57
|
-
destroyRef = inject(DestroyRef);
|
|
58
|
-
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
59
|
-
storage = new LocalStorageStateAdapter({
|
|
60
|
-
isBrowser: this.isBrowser,
|
|
61
|
-
storage: this.document.defaultView?.localStorage ?? null,
|
|
62
|
-
keys: STORAGE_KEYS,
|
|
63
|
-
legacyPrefix: LEGACY_STORAGE_PREFIX,
|
|
64
|
-
});
|
|
65
|
-
mediaQuery = this.isBrowser
|
|
66
|
-
? typeof this.document.defaultView?.matchMedia === 'function'
|
|
67
|
-
? this.document.defaultView.matchMedia('(prefers-color-scheme: dark)')
|
|
68
|
-
: null
|
|
69
|
-
: null;
|
|
70
|
-
systemPrefersDark = signal(this.mediaQuery?.matches ?? false, ...(ngDevMode ? [{ debugName: "systemPrefersDark" }] : /* istanbul ignore next */ []));
|
|
71
|
-
availableColorOptions = createThemeColorOptions(this.config.colors, this.config.colorLabels);
|
|
72
|
-
scheme = signal(this.storage.read('scheme', this.config.defaultScheme, isThemeScheme), ...(ngDevMode ? [{ debugName: "scheme" }] : /* istanbul ignore next */ []));
|
|
73
|
-
color = signal(this.storage.read('color', this.config.defaultColor, isThemeColor), ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
74
|
-
style = signal(this.storage.read('style', this.config.defaultStyle, isThemeStyle), ...(ngDevMode ? [{ debugName: "style" }] : /* istanbul ignore next */ []));
|
|
75
|
-
colorOptions = computed(() => this.availableColorOptions, ...(ngDevMode ? [{ debugName: "colorOptions" }] : /* istanbul ignore next */ []));
|
|
76
|
-
resolvedScheme = computed(() => {
|
|
77
|
-
if (this.scheme() !== 'system')
|
|
78
|
-
return this.scheme();
|
|
79
|
-
return this.systemPrefersDark() ? 'dark' : 'light';
|
|
80
|
-
}, ...(ngDevMode ? [{ debugName: "resolvedScheme" }] : /* istanbul ignore next */ []));
|
|
81
|
-
constructor() {
|
|
82
|
-
if (this.mediaQuery) {
|
|
83
|
-
const syncSystemPreference = (event) => {
|
|
84
|
-
this.systemPrefersDark.set(event.matches);
|
|
85
|
-
};
|
|
86
|
-
this.mediaQuery.addEventListener('change', syncSystemPreference);
|
|
87
|
-
this.destroyRef.onDestroy(() => {
|
|
88
|
-
this.mediaQuery?.removeEventListener('change', syncSystemPreference);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
effect(() => {
|
|
92
|
-
if (this.isBrowser) {
|
|
93
|
-
this.applyToDOM();
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Updates the selected theme scheme and persists the choice for future sessions.
|
|
99
|
-
*/
|
|
100
|
-
setScheme(value) {
|
|
101
|
-
this.storage.persist('scheme', value);
|
|
102
|
-
this.scheme.set(value);
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Updates the active theme color when it is part of the configured preset list.
|
|
106
|
-
*/
|
|
107
|
-
setColor(value) {
|
|
108
|
-
if (!this.colorOptions().some((option) => option.value === value)) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
this.storage.persist('color', value);
|
|
112
|
-
this.color.set(value);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Updates the active style preset and persists it to local storage.
|
|
116
|
-
*/
|
|
117
|
-
setStyle(value) {
|
|
118
|
-
this.storage.persist('style', value);
|
|
119
|
-
this.style.set(value);
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Cycles the scheme through light, dark, and system while keeping the DOM contract in sync.
|
|
123
|
-
*/
|
|
124
|
-
toggleScheme() {
|
|
125
|
-
const next = this.scheme() === 'light' ? 'dark' : this.scheme() === 'dark' ? 'system' : 'light';
|
|
126
|
-
this.setScheme(next);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Clears persisted theme state and restores the configured defaults for all theme axes.
|
|
130
|
-
*/
|
|
131
|
-
reset() {
|
|
132
|
-
this.storage.clear('scheme');
|
|
133
|
-
this.storage.clear('color');
|
|
134
|
-
this.storage.clear('style');
|
|
135
|
-
this.scheme.set(this.config.defaultScheme);
|
|
136
|
-
this.color.set(this.config.defaultColor);
|
|
137
|
-
this.style.set(this.config.defaultStyle);
|
|
138
|
-
}
|
|
139
|
-
applyToDOM() {
|
|
140
|
-
const element = this.document.documentElement;
|
|
141
|
-
element.classList.toggle('dark', this.resolvedScheme() === 'dark');
|
|
142
|
-
element.dataset['themeScheme'] = this.scheme();
|
|
143
|
-
element.dataset['themeColor'] = this.color();
|
|
144
|
-
element.dataset['themeStyle'] = this.style();
|
|
145
|
-
element.style.colorScheme = this.resolvedScheme();
|
|
146
|
-
}
|
|
147
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
148
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ThemeService, providedIn: 'root' });
|
|
149
|
-
}
|
|
150
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ThemeService, decorators: [{
|
|
151
|
-
type: Injectable,
|
|
152
|
-
args: [{ providedIn: 'root' }]
|
|
153
|
-
}], ctorParameters: () => [] });
|
|
154
|
-
|
|
155
|
-
function warnInvalidThemeConfig(message) {
|
|
156
|
-
if (isDevMode()) {
|
|
157
|
-
console.warn(`[provideNgTheme] ${message}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
function normalizeThemeScheme(value) {
|
|
161
|
-
if (typeof value === 'undefined' || isThemeScheme(value)) {
|
|
162
|
-
return value ?? DEFAULT_NG_THEME_CONFIG.defaultScheme;
|
|
163
|
-
}
|
|
164
|
-
warnInvalidThemeConfig(`Ignoring invalid defaultScheme ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultScheme)}.`);
|
|
165
|
-
return DEFAULT_NG_THEME_CONFIG.defaultScheme;
|
|
166
|
-
}
|
|
167
|
-
function normalizeThemeColor(value) {
|
|
168
|
-
if (typeof value === 'undefined' || isThemeColor(value)) {
|
|
169
|
-
return value ?? DEFAULT_NG_THEME_CONFIG.defaultColor;
|
|
170
|
-
}
|
|
171
|
-
warnInvalidThemeConfig(`Ignoring invalid defaultColor ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultColor)}.`);
|
|
172
|
-
return DEFAULT_NG_THEME_CONFIG.defaultColor;
|
|
173
|
-
}
|
|
174
|
-
function normalizeThemeStyle(value) {
|
|
175
|
-
if (typeof value === 'undefined' || isThemeStyle(value)) {
|
|
176
|
-
return value ?? DEFAULT_NG_THEME_CONFIG.defaultStyle;
|
|
177
|
-
}
|
|
178
|
-
warnInvalidThemeConfig(`Ignoring invalid defaultStyle ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultStyle)}.`);
|
|
179
|
-
return DEFAULT_NG_THEME_CONFIG.defaultStyle;
|
|
180
|
-
}
|
|
181
|
-
function normalizeThemeColors(value) {
|
|
182
|
-
if (typeof value === 'undefined') {
|
|
183
|
-
return undefined;
|
|
184
|
-
}
|
|
185
|
-
if (!Array.isArray(value)) {
|
|
186
|
-
warnInvalidThemeConfig('Ignoring invalid colors config because it is not an array.');
|
|
187
|
-
return undefined;
|
|
188
|
-
}
|
|
189
|
-
const normalizedColors = Array.from(new Set(value.filter(isThemeColor)));
|
|
190
|
-
if (normalizedColors.length !== value.length) {
|
|
191
|
-
warnInvalidThemeConfig('Ignoring unsupported values in colors config.');
|
|
192
|
-
}
|
|
193
|
-
return normalizedColors.length > 0 ? normalizedColors : undefined;
|
|
194
|
-
}
|
|
195
|
-
function normalizeThemeColorLabels(value) {
|
|
196
|
-
if (typeof value === 'undefined') {
|
|
197
|
-
return undefined;
|
|
198
|
-
}
|
|
199
|
-
if (!value || Array.isArray(value) || typeof value !== 'object') {
|
|
200
|
-
warnInvalidThemeConfig('Ignoring invalid colorLabels config because it is not an object map.');
|
|
201
|
-
return undefined;
|
|
202
|
-
}
|
|
203
|
-
const entries = Object.entries(value);
|
|
204
|
-
const normalizedEntries = entries.flatMap(([color, label]) => {
|
|
205
|
-
if (isThemeColor(color) && typeof label === 'string' && label.trim().length > 0) {
|
|
206
|
-
return [[color, label.trim()]];
|
|
207
|
-
}
|
|
208
|
-
return [];
|
|
209
|
-
});
|
|
210
|
-
if (normalizedEntries.length !== entries.length) {
|
|
211
|
-
warnInvalidThemeConfig('Ignoring unsupported entries in colorLabels config.');
|
|
212
|
-
}
|
|
213
|
-
return normalizedEntries.length > 0 ? Object.fromEntries(normalizedEntries) : undefined;
|
|
214
|
-
}
|
|
215
|
-
function normalizeThemeConfig(config) {
|
|
216
|
-
const colors = normalizeThemeColors(config.colors);
|
|
217
|
-
const colorLabels = normalizeThemeColorLabels(config.colorLabels);
|
|
218
|
-
let defaultColor = normalizeThemeColor(config.defaultColor);
|
|
219
|
-
if (colors && !colors.includes(defaultColor)) {
|
|
220
|
-
warnInvalidThemeConfig(`Adjusting defaultColor ${JSON.stringify(defaultColor)} to ${JSON.stringify(colors[0])} so it stays within the configured colors list.`);
|
|
221
|
-
defaultColor = colors[0];
|
|
222
|
-
}
|
|
223
|
-
return {
|
|
224
|
-
...DEFAULT_NG_THEME_CONFIG,
|
|
225
|
-
defaultScheme: normalizeThemeScheme(config.defaultScheme),
|
|
226
|
-
defaultColor,
|
|
227
|
-
defaultStyle: normalizeThemeStyle(config.defaultStyle),
|
|
228
|
-
...(colors ? { colors } : {}),
|
|
229
|
-
...(colorLabels ? { colorLabels } : {}),
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
function provideNgTheme(config = {}) {
|
|
233
|
-
return makeEnvironmentProviders([{ provide: NG_THEME_CONFIG, useValue: normalizeThemeConfig(config) }]);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Generated bundle index. Do not edit.
|
|
238
|
-
*/
|
|
239
|
-
|
|
240
|
-
export { NG_THEME_CONFIG, ThemeService, provideNgTheme };
|
|
241
|
-
//# sourceMappingURL=ojiepermana-angular-theme-service.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ojiepermana-angular-theme-service.mjs","sources":["../../../projects/library/theme/service/src/theme.token.ts","../../../projects/library/theme/service/src/theme.types.ts","../../../projects/library/theme/service/src/theme.service.ts","../../../projects/library/theme/service/src/theme.provider.ts","../../../projects/library/theme/service/ojiepermana-angular-theme-service.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { NgThemeConfig } from './theme.types';\n\nexport const DEFAULT_NG_THEME_CONFIG: NgThemeConfig = {\n defaultScheme: 'system',\n defaultColor: 'brand',\n defaultStyle: 'flat',\n};\n\nexport const NG_THEME_CONFIG = new InjectionToken<NgThemeConfig>('NG_THEME_CONFIG', {\n providedIn: 'root',\n factory: () => ({ ...DEFAULT_NG_THEME_CONFIG }),\n});\n","export const THEME_SCHEMES = ['light', 'dark', 'system'] as const;\nexport type ThemeScheme = (typeof THEME_SCHEMES)[number];\n\nexport const THEME_COLORS = ['brand', 'blue', 'green', 'red', 'cyan', 'purple', 'orange'] as const;\nexport type ThemeColor = (typeof THEME_COLORS)[number];\n\nexport const THEME_STYLES = ['flat', 'glass'] as const;\nexport type ThemeStyle = (typeof THEME_STYLES)[number];\n\nconst THEME_SCHEME_SET = new Set<ThemeScheme>(THEME_SCHEMES);\nconst THEME_COLOR_SET = new Set<ThemeColor>(THEME_COLORS);\nconst THEME_STYLE_SET = new Set<ThemeStyle>(THEME_STYLES);\n\nexport function isThemeScheme(value: unknown): value is ThemeScheme {\n return typeof value === 'string' && THEME_SCHEME_SET.has(value as ThemeScheme);\n}\n\nexport function isThemeColor(value: unknown): value is ThemeColor {\n return typeof value === 'string' && THEME_COLOR_SET.has(value as ThemeColor);\n}\n\nexport function isThemeStyle(value: unknown): value is ThemeStyle {\n return typeof value === 'string' && THEME_STYLE_SET.has(value as ThemeStyle);\n}\n\nexport interface ThemeColorOption {\n readonly value: ThemeColor;\n readonly label: string;\n}\n\nexport type ThemeColorLabels = Partial<Record<ThemeColor, string>>;\n\nexport interface NgThemeConfig {\n defaultScheme: ThemeScheme;\n defaultColor: ThemeColor;\n defaultStyle: ThemeStyle;\n colors?: readonly ThemeColor[];\n colorLabels?: ThemeColorLabels;\n}\n","import { DestroyRef, Injectable, PLATFORM_ID, computed, effect, inject, signal } from '@angular/core';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { LocalStorageStateAdapter } from '@ojiepermana/angular/internal';\nimport { NG_THEME_CONFIG } from './theme.token';\nimport {\n isThemeColor,\n isThemeScheme,\n isThemeStyle,\n NgThemeConfig,\n ThemeStyle,\n ThemeColor,\n ThemeColorLabels,\n ThemeColorOption,\n ThemeScheme,\n} from './theme.types';\n\nconst THEME_COLOR_OPTIONS: readonly ThemeColorOption[] = [\n { value: 'brand', label: 'Brand' },\n { value: 'blue', label: 'Blue' },\n { value: 'green', label: 'Green' },\n { value: 'red', label: 'Red' },\n { value: 'cyan', label: 'Cyan' },\n { value: 'purple', label: 'Purple' },\n { value: 'orange', label: 'Orange' },\n] as const;\n\nfunction createThemeColorOptions(\n allowedColors: readonly ThemeColor[] | undefined,\n colorLabels: ThemeColorLabels | undefined,\n): readonly ThemeColorOption[] {\n const allowedSet = allowedColors ? new Set(allowedColors) : null;\n\n return THEME_COLOR_OPTIONS.filter((option) => !allowedSet || allowedSet.has(option.value)).map((option) => ({\n value: option.value,\n label: colorLabels?.[option.value] ?? option.label,\n }));\n}\n\nconst STORAGE_KEYS = {\n scheme: 'theme-scheme',\n color: 'theme-color',\n style: 'theme-style',\n} as const;\n\ntype ThemeStorageAxis = keyof typeof STORAGE_KEYS;\n\nconst LEGACY_STORAGE_PREFIX = 'ng-theme:v2';\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n private readonly config = inject(NG_THEME_CONFIG);\n private readonly document = inject(DOCUMENT);\n private readonly destroyRef = inject(DestroyRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly storage = new LocalStorageStateAdapter<ThemeStorageAxis>({\n isBrowser: this.isBrowser,\n storage: this.document.defaultView?.localStorage ?? null,\n keys: STORAGE_KEYS,\n legacyPrefix: LEGACY_STORAGE_PREFIX,\n });\n private readonly mediaQuery = this.isBrowser\n ? typeof this.document.defaultView?.matchMedia === 'function'\n ? this.document.defaultView.matchMedia('(prefers-color-scheme: dark)')\n : null\n : null;\n private readonly systemPrefersDark = signal(this.mediaQuery?.matches ?? false);\n private readonly availableColorOptions = createThemeColorOptions(this.config.colors, this.config.colorLabels);\n\n readonly scheme = signal<ThemeScheme>(this.storage.read('scheme', this.config.defaultScheme, isThemeScheme));\n readonly color = signal<ThemeColor>(this.storage.read('color', this.config.defaultColor, isThemeColor));\n readonly style = signal<ThemeStyle>(this.storage.read('style', this.config.defaultStyle, isThemeStyle));\n readonly colorOptions = computed<readonly ThemeColorOption[]>(() => this.availableColorOptions);\n\n readonly resolvedScheme = computed<'light' | 'dark'>(() => {\n if (this.scheme() !== 'system') return this.scheme() as 'light' | 'dark';\n return this.systemPrefersDark() ? 'dark' : 'light';\n });\n\n constructor() {\n if (this.mediaQuery) {\n const syncSystemPreference = (event: MediaQueryListEvent): void => {\n this.systemPrefersDark.set(event.matches);\n };\n\n this.mediaQuery.addEventListener('change', syncSystemPreference);\n this.destroyRef.onDestroy(() => {\n this.mediaQuery?.removeEventListener('change', syncSystemPreference);\n });\n }\n\n effect(() => {\n if (this.isBrowser) {\n this.applyToDOM();\n }\n });\n }\n\n /**\n * Updates the selected theme scheme and persists the choice for future sessions.\n */\n setScheme(value: ThemeScheme): void {\n this.storage.persist('scheme', value);\n this.scheme.set(value);\n }\n\n /**\n * Updates the active theme color when it is part of the configured preset list.\n */\n setColor(value: ThemeColor): void {\n if (!this.colorOptions().some((option) => option.value === value)) {\n return;\n }\n\n this.storage.persist('color', value);\n this.color.set(value);\n }\n\n /**\n * Updates the active style preset and persists it to local storage.\n */\n setStyle(value: ThemeStyle): void {\n this.storage.persist('style', value);\n this.style.set(value);\n }\n\n /**\n * Cycles the scheme through light, dark, and system while keeping the DOM contract in sync.\n */\n toggleScheme(): void {\n const next: ThemeScheme = this.scheme() === 'light' ? 'dark' : this.scheme() === 'dark' ? 'system' : 'light';\n this.setScheme(next);\n }\n\n /**\n * Clears persisted theme state and restores the configured defaults for all theme axes.\n */\n reset(): void {\n this.storage.clear('scheme');\n this.storage.clear('color');\n this.storage.clear('style');\n this.scheme.set(this.config.defaultScheme);\n this.color.set(this.config.defaultColor);\n this.style.set(this.config.defaultStyle);\n }\n\n private applyToDOM(): void {\n const element = this.document.documentElement;\n\n element.classList.toggle('dark', this.resolvedScheme() === 'dark');\n element.dataset['themeScheme'] = this.scheme();\n element.dataset['themeColor'] = this.color();\n element.dataset['themeStyle'] = this.style();\n element.style.colorScheme = this.resolvedScheme();\n }\n}\n","import { EnvironmentProviders, isDevMode, makeEnvironmentProviders } from '@angular/core';\nimport { DEFAULT_NG_THEME_CONFIG, NG_THEME_CONFIG } from './theme.token';\nimport {\n isThemeColor,\n isThemeScheme,\n isThemeStyle,\n NgThemeConfig,\n ThemeColor,\n ThemeColorLabels,\n ThemeScheme,\n ThemeStyle,\n} from './theme.types';\n\nfunction warnInvalidThemeConfig(message: string): void {\n if (isDevMode()) {\n console.warn(`[provideNgTheme] ${message}`);\n }\n}\n\nfunction normalizeThemeScheme(value: unknown): ThemeScheme {\n if (typeof value === 'undefined' || isThemeScheme(value)) {\n return value ?? DEFAULT_NG_THEME_CONFIG.defaultScheme;\n }\n\n warnInvalidThemeConfig(\n `Ignoring invalid defaultScheme ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultScheme)}.`,\n );\n\n return DEFAULT_NG_THEME_CONFIG.defaultScheme;\n}\n\nfunction normalizeThemeColor(value: unknown): ThemeColor {\n if (typeof value === 'undefined' || isThemeColor(value)) {\n return value ?? DEFAULT_NG_THEME_CONFIG.defaultColor;\n }\n\n warnInvalidThemeConfig(\n `Ignoring invalid defaultColor ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultColor)}.`,\n );\n\n return DEFAULT_NG_THEME_CONFIG.defaultColor;\n}\n\nfunction normalizeThemeStyle(value: unknown): ThemeStyle {\n if (typeof value === 'undefined' || isThemeStyle(value)) {\n return value ?? DEFAULT_NG_THEME_CONFIG.defaultStyle;\n }\n\n warnInvalidThemeConfig(\n `Ignoring invalid defaultStyle ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_THEME_CONFIG.defaultStyle)}.`,\n );\n\n return DEFAULT_NG_THEME_CONFIG.defaultStyle;\n}\n\nfunction normalizeThemeColors(value: unknown): readonly ThemeColor[] | undefined {\n if (typeof value === 'undefined') {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n warnInvalidThemeConfig('Ignoring invalid colors config because it is not an array.');\n return undefined;\n }\n\n const normalizedColors = Array.from(new Set(value.filter(isThemeColor)));\n\n if (normalizedColors.length !== value.length) {\n warnInvalidThemeConfig('Ignoring unsupported values in colors config.');\n }\n\n return normalizedColors.length > 0 ? normalizedColors : undefined;\n}\n\nfunction normalizeThemeColorLabels(value: unknown): ThemeColorLabels | undefined {\n if (typeof value === 'undefined') {\n return undefined;\n }\n\n if (!value || Array.isArray(value) || typeof value !== 'object') {\n warnInvalidThemeConfig('Ignoring invalid colorLabels config because it is not an object map.');\n return undefined;\n }\n\n const entries = Object.entries(value);\n const normalizedEntries = entries.flatMap(([color, label]) => {\n if (isThemeColor(color) && typeof label === 'string' && label.trim().length > 0) {\n return [[color, label.trim()] as const];\n }\n\n return [];\n });\n\n if (normalizedEntries.length !== entries.length) {\n warnInvalidThemeConfig('Ignoring unsupported entries in colorLabels config.');\n }\n\n return normalizedEntries.length > 0 ? (Object.fromEntries(normalizedEntries) as ThemeColorLabels) : undefined;\n}\n\nfunction normalizeThemeConfig(config: Partial<NgThemeConfig>): NgThemeConfig {\n const colors = normalizeThemeColors(config.colors);\n const colorLabels = normalizeThemeColorLabels(config.colorLabels);\n let defaultColor = normalizeThemeColor(config.defaultColor);\n\n if (colors && !colors.includes(defaultColor)) {\n warnInvalidThemeConfig(\n `Adjusting defaultColor ${JSON.stringify(defaultColor)} to ${JSON.stringify(colors[0])} so it stays within the configured colors list.`,\n );\n defaultColor = colors[0];\n }\n\n return {\n ...DEFAULT_NG_THEME_CONFIG,\n defaultScheme: normalizeThemeScheme(config.defaultScheme),\n defaultColor,\n defaultStyle: normalizeThemeStyle(config.defaultStyle),\n ...(colors ? { colors } : {}),\n ...(colorLabels ? { colorLabels } : {}),\n };\n}\n\nexport function provideNgTheme(config: Partial<NgThemeConfig> = {}): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: NG_THEME_CONFIG, useValue: normalizeThemeConfig(config) }]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/layout/README.md
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# Layout Library
|
|
2
|
-
|
|
3
|
-
Runtime layout state, shell components, layout controls, and shell selectors for `@ojiepermana/angular/layout`.
|
|
4
|
-
|
|
5
|
-
## Package Shape
|
|
6
|
-
|
|
7
|
-
Import the public API from:
|
|
8
|
-
|
|
9
|
-
- `@ojiepermana/angular/layout`
|
|
10
|
-
|
|
11
|
-
If you want one convenience provider that wires layout and theme together, use `@ojiepermana/angular/shell`.
|
|
12
|
-
|
|
13
|
-
For styles in consumer applications, use `@ojiepermana/angular/styles/index.css`.
|
|
14
|
-
If a consumer wants the library's optional application-level reset helpers, they can additionally import `@ojiepermana/angular/styles/resets.css`.
|
|
15
|
-
|
|
16
|
-
## What This Library Owns
|
|
17
|
-
|
|
18
|
-
- Global layout state with Angular signals through `LayoutService`
|
|
19
|
-
- Layout runtime DOM contract on `document.documentElement`
|
|
20
|
-
- Optional subtree mirroring through `LayoutHostDirective`
|
|
21
|
-
- Reusable vertical and horizontal shell components
|
|
22
|
-
- Standalone layout controls for mode and container width
|
|
23
|
-
- Layout-owned shell selectors and layout state selectors
|
|
24
|
-
|
|
25
|
-
## Runtime Contract
|
|
26
|
-
|
|
27
|
-
When `LayoutService` is active, it writes the current state to `document.documentElement`.
|
|
28
|
-
|
|
29
|
-
- `data-layout-mode` stores the active shell mode.
|
|
30
|
-
- `data-layout-container` stores the active width mode.
|
|
31
|
-
|
|
32
|
-
`LayoutHostDirective` mirrors the same contract onto any host element with `ngtLayoutHost`.
|
|
33
|
-
|
|
34
|
-
## Supported Values
|
|
35
|
-
|
|
36
|
-
- `LayoutMode`: `vertical`, `horizontal`, `empty`
|
|
37
|
-
- `LayoutContainer`: `full`, `boxed`
|
|
38
|
-
|
|
39
|
-
## Public API
|
|
40
|
-
|
|
41
|
-
Import from `@ojiepermana/angular/layout`.
|
|
42
|
-
|
|
43
|
-
- `LayoutService`
|
|
44
|
-
- `provideNgLayout`
|
|
45
|
-
- `NG_LAYOUT_CONFIG`
|
|
46
|
-
- `LayoutMode`
|
|
47
|
-
- `LayoutContainer`
|
|
48
|
-
- `NgLayoutConfig`
|
|
49
|
-
- `LayoutHostDirective`
|
|
50
|
-
- `LayoutVerticalComponent`
|
|
51
|
-
- `LayoutHorizontalComponent`
|
|
52
|
-
- `LayoutContainerSwitcherComponent`
|
|
53
|
-
- `LayoutModeSwitcherComponent`
|
|
54
|
-
|
|
55
|
-
`provideNgLayout()` currently defaults to:
|
|
56
|
-
|
|
57
|
-
- `defaultMode: 'vertical'`
|
|
58
|
-
- `defaultContainer: 'full'`
|
|
59
|
-
|
|
60
|
-
Persistence keys are fixed by the runtime. Deprecated config fields such as `storageKey` and `storageVersion` have been removed from `NgLayoutConfig`.
|
|
61
|
-
|
|
62
|
-
`LayoutService` also exposes `reset()` to clear persisted layout state and restore the configured defaults.
|
|
63
|
-
|
|
64
|
-
`LayoutModeSwitcherComponent` intentionally exposes only `vertical` and `horizontal`. The `empty` mode remains programmatic so consuming applications can opt into a content-only shell state without presenting it as a primary end-user toggle.
|
|
65
|
-
|
|
66
|
-
## Styles
|
|
67
|
-
|
|
68
|
-
The layout-wide stylesheet source is `projects/library/layout/src/layout.css` inside this workspace.
|
|
69
|
-
|
|
70
|
-
It owns the `data-layout-*` selectors that are global to the runtime.
|
|
71
|
-
The horizontal shell rules now live beside `src/component/horizontal/horizontal.ts`, and the vertical shell rules live beside `src/component/vertical/vertical.ts` through component-level CSS metadata.
|
|
72
|
-
|
|
73
|
-
Layout styles consume theme tokens. For application usage, prefer the aggregate stylesheet entry at `projects/library/styles/index.css` in this workspace or `@ojiepermana/angular/styles/index.css` from the published package.
|
|
74
|
-
The shared bundle now includes reduced-motion-aware transitions for shell chrome colors, shadows, and radii while keeping structural mode changes immediate to avoid layout jank.
|
|
75
|
-
|
|
76
|
-
Application-level resets are intentionally opt-in. If a consumer wants them, import `projects/library/styles/resets.css` in this workspace or `@ojiepermana/angular/styles/resets.css` from the published package in addition to the aggregate bundle.
|
|
77
|
-
|
|
78
|
-
Internally, the shell templates now prefer `<shell-content>` instead of the deprecated HTML `<content>` element name. A legacy `content` selector remains supported for compatibility inside the library's internal shell marker directives.
|
|
79
|
-
|
|
80
|
-
## SSR Notes
|
|
81
|
-
|
|
82
|
-
- Providers can be registered on the server safely.
|
|
83
|
-
- Layout DOM writes and `localStorage` persistence remain no-op until the browser runtime is available.
|
|
84
|
-
- `empty` mode can still be set programmatically on the server or client; the switcher simply does not render it as a menu choice.
|
|
85
|
-
|
|
86
|
-
## Troubleshooting
|
|
87
|
-
|
|
88
|
-
- If layout state does not appear to update, verify that the aggregate stylesheet bundle is imported and that the consuming shell actually renders `vertical` or `horizontal`.
|
|
89
|
-
- If a consuming application needs a content-only shell, set `LayoutService.setMode('empty')` or configure `defaultMode: 'empty'`; this is supported even though the switcher UI does not display that option.
|
|
90
|
-
|
|
91
|
-
## Usage
|
|
92
|
-
|
|
93
|
-
```ts
|
|
94
|
-
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
|
|
95
|
-
import { provideRouter } from '@angular/router';
|
|
96
|
-
import { provideNgLayout } from '@ojiepermana/angular/layout';
|
|
97
|
-
import { provideNgTheme } from '@ojiepermana/angular/theme/service';
|
|
98
|
-
|
|
99
|
-
import { routes } from './app.routes';
|
|
100
|
-
|
|
101
|
-
export const appConfig: ApplicationConfig = {
|
|
102
|
-
providers: [
|
|
103
|
-
provideBrowserGlobalErrorListeners(),
|
|
104
|
-
provideRouter(routes),
|
|
105
|
-
provideNgTheme(),
|
|
106
|
-
provideNgLayout({ defaultMode: 'vertical', defaultContainer: 'boxed' }),
|
|
107
|
-
],
|
|
108
|
-
};
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
113
|
-
import {
|
|
114
|
-
LayoutContainerSwitcherComponent,
|
|
115
|
-
LayoutModeSwitcherComponent,
|
|
116
|
-
LayoutVerticalComponent,
|
|
117
|
-
} from '@ojiepermana/angular/layout';
|
|
118
|
-
|
|
119
|
-
@Component({
|
|
120
|
-
selector: 'app-shell',
|
|
121
|
-
imports: [LayoutContainerSwitcherComponent, LayoutModeSwitcherComponent, LayoutVerticalComponent],
|
|
122
|
-
template: `
|
|
123
|
-
<vertical>
|
|
124
|
-
<nav navigation class="flex h-full w-full flex-col gap-3 px-4 py-5">
|
|
125
|
-
<div class="flex items-center gap-1">
|
|
126
|
-
<layout-mode-switcher />
|
|
127
|
-
<layout-container-switcher />
|
|
128
|
-
</div>
|
|
129
|
-
</nav>
|
|
130
|
-
</vertical>
|
|
131
|
-
`,
|
|
132
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
133
|
-
})
|
|
134
|
-
export class AppShellComponent {}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Persistence
|
|
138
|
-
|
|
139
|
-
Layout state is persisted in `localStorage` using these flat keys:
|
|
140
|
-
|
|
141
|
-
- `layout-mode`
|
|
142
|
-
- `layout-container`
|
|
143
|
-
|
|
144
|
-
Legacy `ng-theme:v2:layout-mode` and `ng-theme:v2:layout-container` entries are migrated automatically when they are read.
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
:host {
|
|
2
|
-
display: block;
|
|
3
|
-
block-size: 100dvh;
|
|
4
|
-
min-block-size: 100dvh;
|
|
5
|
-
overflow: hidden;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
:host > layout {
|
|
9
|
-
display: block;
|
|
10
|
-
block-size: 100dvh;
|
|
11
|
-
min-block-size: 100dvh;
|
|
12
|
-
padding: var(--layout-shell-padding);
|
|
13
|
-
background: var(--background);
|
|
14
|
-
color: var(--foreground);
|
|
15
|
-
overflow: hidden;
|
|
16
|
-
transition: var(--ngt-chrome-transition);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
:host > layout > :is(content, shell-content) {
|
|
20
|
-
display: flex;
|
|
21
|
-
flex-direction: column;
|
|
22
|
-
inline-size: min(100%, var(--layout-shell-max-width));
|
|
23
|
-
block-size: calc(100dvh - (var(--layout-shell-padding) * 2));
|
|
24
|
-
min-block-size: 0;
|
|
25
|
-
margin-inline: auto;
|
|
26
|
-
border: 1px solid var(--container-border);
|
|
27
|
-
border-radius: var(--layout-shell-radius);
|
|
28
|
-
background: var(--container-surface);
|
|
29
|
-
color: var(--container-foreground);
|
|
30
|
-
box-shadow: var(--container-shadow);
|
|
31
|
-
backdrop-filter: var(--container-backdrop);
|
|
32
|
-
-webkit-backdrop-filter: var(--container-backdrop);
|
|
33
|
-
overflow: hidden;
|
|
34
|
-
transition: var(--ngt-shell-transition);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
:host > layout > :is(content, shell-content) > header {
|
|
38
|
-
display: var(--layout-header-display);
|
|
39
|
-
grid-template-areas: 'brand navigation action';
|
|
40
|
-
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
41
|
-
align-items: center;
|
|
42
|
-
gap: 1rem;
|
|
43
|
-
min-block-size: var(--layout-header-height);
|
|
44
|
-
padding: 0.875rem 1rem;
|
|
45
|
-
border-bottom: 1px solid var(--nav-border);
|
|
46
|
-
background: var(--nav-surface);
|
|
47
|
-
color: var(--nav-foreground);
|
|
48
|
-
transition: var(--ngt-chrome-transition);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
:host > layout > :is(content, shell-content) > header > brand,
|
|
52
|
-
:host > layout > :is(content, shell-content) > header > action {
|
|
53
|
-
display: flex;
|
|
54
|
-
min-inline-size: 0;
|
|
55
|
-
align-items: center;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
:host > layout > :is(content, shell-content) > header > brand {
|
|
59
|
-
grid-area: brand;
|
|
60
|
-
justify-content: flex-start;
|
|
61
|
-
justify-self: start;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
:host > layout > :is(content, shell-content) > header > navigation {
|
|
65
|
-
grid-area: navigation;
|
|
66
|
-
display: flex;
|
|
67
|
-
inline-size: 100%;
|
|
68
|
-
min-inline-size: 0;
|
|
69
|
-
align-items: center;
|
|
70
|
-
justify-self: stretch;
|
|
71
|
-
justify-content: center;
|
|
72
|
-
gap: 0.75rem;
|
|
73
|
-
flex-wrap: wrap;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
:host > layout > :is(content, shell-content) > header > navigation > .layout-horizontal-navigation-slot {
|
|
77
|
-
flex: 0 1 auto;
|
|
78
|
-
display: block;
|
|
79
|
-
min-inline-size: 0;
|
|
80
|
-
max-inline-size: 100%;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
:host > layout > :is(content, shell-content) > header > action {
|
|
84
|
-
grid-area: action;
|
|
85
|
-
justify-content: flex-end;
|
|
86
|
-
justify-self: end;
|
|
87
|
-
gap: 0.5rem;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
:host > layout > :is(content, shell-content) > main {
|
|
91
|
-
flex: 1 1 auto;
|
|
92
|
-
block-size: 100%;
|
|
93
|
-
min-inline-size: 0;
|
|
94
|
-
min-block-size: 0;
|
|
95
|
-
overflow: auto;
|
|
96
|
-
background-color: var(--background);
|
|
97
|
-
background-image: linear-gradient(180deg, color-mix(in oklab, var(--background) 94%, white 6%), var(--background));
|
|
98
|
-
color: var(--foreground);
|
|
99
|
-
transition:
|
|
100
|
-
background-color var(--ngt-motion-duration-medium) var(--ngt-motion-ease-standard),
|
|
101
|
-
color var(--ngt-motion-duration-fast) var(--ngt-motion-ease-standard);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
@media (max-width: 60rem) {
|
|
105
|
-
:host > layout > :is(content, shell-content) > header {
|
|
106
|
-
grid-template-areas:
|
|
107
|
-
'brand action'
|
|
108
|
-
'navigation navigation';
|
|
109
|
-
grid-template-columns: minmax(0, 1fr) auto;
|
|
110
|
-
align-items: flex-start;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
:host > layout > :is(content, shell-content) > header > navigation {
|
|
114
|
-
justify-content: center;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
@media (max-width: 40rem) {
|
|
119
|
-
:host > layout > :is(content, shell-content) > header {
|
|
120
|
-
grid-template-areas:
|
|
121
|
-
'brand'
|
|
122
|
-
'navigation'
|
|
123
|
-
'action';
|
|
124
|
-
grid-template-columns: 1fr;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
:host > layout > :is(content, shell-content) > header > action {
|
|
128
|
-
justify-content: flex-end;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
:host {
|
|
2
|
-
display: block;
|
|
3
|
-
block-size: 100dvh;
|
|
4
|
-
min-block-size: 100dvh;
|
|
5
|
-
overflow: hidden;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
:host > layout {
|
|
9
|
-
display: block;
|
|
10
|
-
block-size: 100dvh;
|
|
11
|
-
min-block-size: 100dvh;
|
|
12
|
-
padding: var(--layout-shell-padding);
|
|
13
|
-
background: var(--background);
|
|
14
|
-
color: var(--foreground);
|
|
15
|
-
overflow: hidden;
|
|
16
|
-
transition: var(--ngt-chrome-transition);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
:host > layout > :is(content, shell-content) {
|
|
20
|
-
display: flex;
|
|
21
|
-
flex-direction: column;
|
|
22
|
-
inline-size: min(100%, var(--layout-shell-max-width));
|
|
23
|
-
block-size: calc(100dvh - (var(--layout-shell-padding) * 2));
|
|
24
|
-
min-block-size: 0;
|
|
25
|
-
margin-inline: auto;
|
|
26
|
-
border: 1px solid var(--container-border);
|
|
27
|
-
border-radius: var(--layout-shell-radius);
|
|
28
|
-
background: var(--container-surface);
|
|
29
|
-
color: var(--container-foreground);
|
|
30
|
-
box-shadow: var(--container-shadow);
|
|
31
|
-
backdrop-filter: var(--container-backdrop);
|
|
32
|
-
-webkit-backdrop-filter: var(--container-backdrop);
|
|
33
|
-
overflow: hidden;
|
|
34
|
-
transition: var(--ngt-shell-transition);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
:host > layout > :is(content, shell-content) > aside {
|
|
38
|
-
display: var(--layout-sidebar-display);
|
|
39
|
-
flex-direction: column;
|
|
40
|
-
inline-size: 100%;
|
|
41
|
-
min-block-size: 0;
|
|
42
|
-
border-bottom: 1px solid var(--sidebar-chrome-border);
|
|
43
|
-
background: var(--sidebar-chrome-surface);
|
|
44
|
-
color: var(--sidebar-chrome-foreground);
|
|
45
|
-
overflow: auto;
|
|
46
|
-
transition: var(--ngt-chrome-transition);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
:host > layout > :is(content, shell-content) > main {
|
|
50
|
-
flex: 1 1 auto;
|
|
51
|
-
block-size: 100%;
|
|
52
|
-
min-inline-size: 0;
|
|
53
|
-
min-block-size: 0;
|
|
54
|
-
overflow: auto;
|
|
55
|
-
background-color: var(--background);
|
|
56
|
-
background-image: linear-gradient(180deg, color-mix(in oklab, var(--background) 94%, white 6%), var(--background));
|
|
57
|
-
color: var(--foreground);
|
|
58
|
-
transition:
|
|
59
|
-
background-color var(--ngt-motion-duration-medium) var(--ngt-motion-ease-standard),
|
|
60
|
-
color var(--ngt-motion-duration-fast) var(--ngt-motion-ease-standard);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
@media (min-width: 48rem) {
|
|
64
|
-
:host > layout > :is(content, shell-content) {
|
|
65
|
-
flex-direction: row;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
:host > layout > :is(content, shell-content) > aside {
|
|
69
|
-
flex: 0 0 var(--layout-sidebar-width);
|
|
70
|
-
inline-size: var(--layout-sidebar-width);
|
|
71
|
-
min-inline-size: var(--layout-sidebar-width);
|
|
72
|
-
border-bottom: 0;
|
|
73
|
-
border-right: 1px solid var(--sidebar-chrome-border);
|
|
74
|
-
}
|
|
75
|
-
}
|
package/layout/src/layout.css
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
[data-layout-container='full'] {
|
|
2
|
-
--layout-shell-max-width: 100%;
|
|
3
|
-
--layout-shell-padding: 0rem;
|
|
4
|
-
--layout-shell-radius: 0rem;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
[data-layout-container='boxed'] {
|
|
8
|
-
--layout-shell-max-width: 82rem;
|
|
9
|
-
--layout-shell-padding: clamp(1rem, 2vw, 2rem);
|
|
10
|
-
--layout-shell-radius: var(--radius-xl);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
[data-layout-mode='empty'] {
|
|
14
|
-
--layout-header-display: none;
|
|
15
|
-
--layout-sidebar-display: none;
|
|
16
|
-
}
|