@frame-ui-ng/foundation 0.4.2-beta.0 → 0.5.1-beta.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 +62 -20
- package/fesm2022/frame-ui-ng-foundation.mjs +40 -18
- package/fesm2022/frame-ui-ng-foundation.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/foundation.css +153 -12
- package/types/frame-ui-ng-foundation.d.ts +17 -11
package/README.md
CHANGED
|
@@ -6,16 +6,16 @@ Documentation: https://frame-ui.com
|
|
|
6
6
|
|
|
7
7
|
Current scope:
|
|
8
8
|
|
|
9
|
-
- CSS
|
|
9
|
+
- CSS variables
|
|
10
10
|
- Angular theme switching via `data-theme` or a shared `.dark` class
|
|
11
11
|
- class merge helpers for future slot-based primitives
|
|
12
12
|
- Vitest unit tests
|
|
13
13
|
|
|
14
14
|
No primitives or complex components are included here.
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Tokens
|
|
17
17
|
|
|
18
|
-
The foundation
|
|
18
|
+
The foundation tokens are intentionally semantic and small.
|
|
19
19
|
|
|
20
20
|
### Color tokens
|
|
21
21
|
|
|
@@ -29,6 +29,14 @@ The foundation token contract is intentionally semantic and small.
|
|
|
29
29
|
- `--frame-primary-foreground`: readable text on `primary`
|
|
30
30
|
- `--frame-accent`: secondary emphasis or selection highlight
|
|
31
31
|
- `--frame-accent-foreground`: readable text on `accent`
|
|
32
|
+
- `--frame-destructive`: destructive or error emphasis
|
|
33
|
+
- `--frame-destructive-foreground`: readable text on `destructive`
|
|
34
|
+
- `--frame-success`: success emphasis
|
|
35
|
+
- `--frame-success-foreground`: readable text on `success`
|
|
36
|
+
- `--frame-warning`: warning emphasis
|
|
37
|
+
- `--frame-warning-foreground`: readable text on `warning`
|
|
38
|
+
- `--frame-info`: informational emphasis
|
|
39
|
+
- `--frame-info-foreground`: readable text on `info`
|
|
32
40
|
- `--frame-border`: default border color
|
|
33
41
|
- `--frame-input`: input field chrome
|
|
34
42
|
- `--frame-ring`: focus ring color
|
|
@@ -38,13 +46,26 @@ The foundation token contract is intentionally semantic and small.
|
|
|
38
46
|
- `--frame-radius-sm`
|
|
39
47
|
- `--frame-radius-md`
|
|
40
48
|
- `--frame-radius-lg`
|
|
49
|
+
- `--frame-radius-full`
|
|
50
|
+
|
|
51
|
+
The default FrameUI theme keeps `sm`, `md`, and `lg` at `0px` for the technical square look.
|
|
52
|
+
Override these tokens in the host app when a rounder theme is wanted.
|
|
41
53
|
|
|
42
54
|
### Elevation tokens
|
|
43
55
|
|
|
44
56
|
- `--frame-shadow-sm`
|
|
45
57
|
- `--frame-shadow-md`
|
|
58
|
+
- `--frame-shadow-lg`
|
|
59
|
+
|
|
60
|
+
Use `shadow` in `provideFrameUI` when the whole app should be flatter or more raised:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
provideFrameUI({
|
|
64
|
+
shadow: 'flat', // 'flat' | 'default' | 'raised'
|
|
65
|
+
});
|
|
66
|
+
```
|
|
46
67
|
|
|
47
|
-
##
|
|
68
|
+
## Token Rules
|
|
48
69
|
|
|
49
70
|
- Tokens must describe purpose, not implementation.
|
|
50
71
|
- Components should consume semantic tokens, never hardcoded theme colors.
|
|
@@ -87,49 +108,70 @@ Brand, product, or campaign differences should be handled by the host app's toke
|
|
|
87
108
|
|
|
88
109
|
## Theme Ownership
|
|
89
110
|
|
|
90
|
-
The foundation layer should expose
|
|
111
|
+
The foundation layer should expose CSS tokens, not force itself to be the only dark mode owner.
|
|
91
112
|
|
|
92
|
-
There are two
|
|
113
|
+
There are two questions:
|
|
93
114
|
|
|
94
|
-
-
|
|
95
|
-
-
|
|
115
|
+
- Who controls light/dark: FrameUI or the app?
|
|
116
|
+
- Which root selector is used: `data-theme` or `.dark`?
|
|
96
117
|
|
|
97
|
-
###
|
|
118
|
+
### FrameUI controls `data-theme`
|
|
98
119
|
|
|
99
120
|
This is the current default:
|
|
100
121
|
|
|
101
122
|
```ts
|
|
102
123
|
provideFrameUI({
|
|
103
124
|
defaultTheme: 'light',
|
|
125
|
+
theme: {
|
|
126
|
+
controlledBy: 'frame',
|
|
127
|
+
using: 'data-theme',
|
|
128
|
+
},
|
|
104
129
|
});
|
|
105
130
|
```
|
|
106
131
|
|
|
107
|
-
|
|
132
|
+
`ThemeService.setTheme('dark')` writes `html[data-theme="dark"]`.
|
|
108
133
|
|
|
109
|
-
|
|
134
|
+
### FrameUI controls `.dark`
|
|
135
|
+
|
|
136
|
+
Use this when FrameUI should control the theme, but the app expects a shared `.dark` selector:
|
|
110
137
|
|
|
111
138
|
```ts
|
|
112
139
|
provideFrameUI({
|
|
113
|
-
|
|
114
|
-
|
|
140
|
+
theme: {
|
|
141
|
+
controlledBy: 'frame',
|
|
142
|
+
using: 'class',
|
|
143
|
+
},
|
|
115
144
|
});
|
|
116
145
|
```
|
|
117
146
|
|
|
118
|
-
`ThemeService.setTheme('dark')`
|
|
147
|
+
`ThemeService.setTheme('dark')` adds `.dark` to the root element, so both FrameUI tokens and Tailwind `dark:` utilities can react to the same switch.
|
|
119
148
|
|
|
120
|
-
###
|
|
149
|
+
### App controls `.dark`
|
|
121
150
|
|
|
122
|
-
|
|
151
|
+
Use this when Tailwind, an app shell, or another design layer already owns dark mode:
|
|
123
152
|
|
|
124
153
|
```ts
|
|
125
154
|
provideFrameUI({
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
155
|
+
theme: {
|
|
156
|
+
controlledBy: 'app',
|
|
157
|
+
using: 'class',
|
|
158
|
+
},
|
|
129
159
|
});
|
|
130
160
|
```
|
|
131
161
|
|
|
132
|
-
In this
|
|
162
|
+
In this setup, FrameUI does not write light/dark state. It reads `html.dark` and keeps `ThemeService.theme()` in sync. Calling `ThemeService.setTheme()` throws because the app owns the switch.
|
|
163
|
+
|
|
164
|
+
### Bootstrap
|
|
165
|
+
|
|
166
|
+
Bootstrap apps usually use `data-bs-theme`. FrameUI does not need to observe that attribute for visual theming. Map FrameUI tokens to Bootstrap variables in CSS instead:
|
|
167
|
+
|
|
168
|
+
```css
|
|
169
|
+
:root {
|
|
170
|
+
--frame-background: var(--bs-body-bg);
|
|
171
|
+
--frame-foreground: var(--bs-body-color);
|
|
172
|
+
--frame-border: var(--bs-border-color);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
133
175
|
|
|
134
176
|
## Global Appearance Options
|
|
135
177
|
|
|
@@ -36,14 +36,18 @@ function withClassOverrides(slots, overrides) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
const DEFAULT_CONFIG = {
|
|
39
|
-
attribute: 'data-theme',
|
|
40
|
-
className: 'dark',
|
|
41
39
|
defaultTheme: 'light',
|
|
40
|
+
density: null,
|
|
42
41
|
disableCornerHandles: false,
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
shadow: null,
|
|
43
|
+
theme: {
|
|
44
|
+
controlledBy: 'frame',
|
|
45
|
+
using: 'data-theme',
|
|
46
|
+
},
|
|
45
47
|
};
|
|
46
48
|
const CORNER_HANDLES_ATTRIBUTE = 'data-frame-corner-handles';
|
|
49
|
+
const DENSITY_ATTRIBUTE = 'data-density';
|
|
50
|
+
const SHADOW_ATTRIBUTE = 'data-shadow';
|
|
47
51
|
const FRAME_UI_CONFIG = new InjectionToken('FRAME_UI_CONFIG', {
|
|
48
52
|
factory: () => DEFAULT_CONFIG,
|
|
49
53
|
});
|
|
@@ -66,12 +70,14 @@ function provideFrameUI(options = {}) {
|
|
|
66
70
|
function createFrameUIConfig(options = {}) {
|
|
67
71
|
const defaultTheme = options.defaultTheme ?? DEFAULT_CONFIG.defaultTheme;
|
|
68
72
|
return {
|
|
69
|
-
attribute: options.attribute ?? DEFAULT_CONFIG.attribute,
|
|
70
|
-
className: options.className ?? DEFAULT_CONFIG.className,
|
|
71
73
|
defaultTheme,
|
|
74
|
+
density: options.density ?? DEFAULT_CONFIG.density,
|
|
72
75
|
disableCornerHandles: options.disableCornerHandles ?? DEFAULT_CONFIG.disableCornerHandles,
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
shadow: options.shadow ?? DEFAULT_CONFIG.shadow,
|
|
77
|
+
theme: {
|
|
78
|
+
controlledBy: options.theme?.controlledBy ?? DEFAULT_CONFIG.theme.controlledBy,
|
|
79
|
+
using: options.theme?.using ?? DEFAULT_CONFIG.theme.using,
|
|
80
|
+
},
|
|
75
81
|
};
|
|
76
82
|
}
|
|
77
83
|
class ThemeService {
|
|
@@ -83,7 +89,9 @@ class ThemeService {
|
|
|
83
89
|
isDark = computed(() => this.activeTheme() === 'dark', ...(ngDevMode ? [{ debugName: "isDark" }] : /* istanbul ignore next */ []));
|
|
84
90
|
constructor() {
|
|
85
91
|
this.applyCornerHandlesPreference();
|
|
86
|
-
|
|
92
|
+
this.applyDensityPreference();
|
|
93
|
+
this.applyShadowPreference();
|
|
94
|
+
if (this.config.theme.controlledBy === 'app') {
|
|
87
95
|
this.syncFromDom();
|
|
88
96
|
this.observeThemeChanges();
|
|
89
97
|
return;
|
|
@@ -94,8 +102,8 @@ class ThemeService {
|
|
|
94
102
|
if (!isFrameUITheme(name)) {
|
|
95
103
|
throw new Error(`Unknown theme "${name}".`);
|
|
96
104
|
}
|
|
97
|
-
if (this.config.
|
|
98
|
-
throw new Error('ThemeService is configured to
|
|
105
|
+
if (this.config.theme.controlledBy === 'app') {
|
|
106
|
+
throw new Error('ThemeService is configured to read app-controlled theme state and cannot set the theme.');
|
|
99
107
|
}
|
|
100
108
|
this.activeTheme.set(name);
|
|
101
109
|
this.applyTheme(name);
|
|
@@ -114,11 +122,11 @@ class ThemeService {
|
|
|
114
122
|
if (!root) {
|
|
115
123
|
return;
|
|
116
124
|
}
|
|
117
|
-
if (this.config.
|
|
118
|
-
root.classList.toggle(
|
|
125
|
+
if (this.config.theme.using === 'class') {
|
|
126
|
+
root.classList.toggle('dark', name === 'dark');
|
|
119
127
|
return;
|
|
120
128
|
}
|
|
121
|
-
root.setAttribute(
|
|
129
|
+
root.setAttribute('data-theme', name);
|
|
122
130
|
}
|
|
123
131
|
applyCornerHandlesPreference() {
|
|
124
132
|
const root = this.document?.documentElement;
|
|
@@ -131,12 +139,26 @@ class ThemeService {
|
|
|
131
139
|
}
|
|
132
140
|
root.removeAttribute(CORNER_HANDLES_ATTRIBUTE);
|
|
133
141
|
}
|
|
142
|
+
applyDensityPreference() {
|
|
143
|
+
const root = this.document?.documentElement;
|
|
144
|
+
if (!root || !this.config.density) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
root.setAttribute(DENSITY_ATTRIBUTE, this.config.density);
|
|
148
|
+
}
|
|
149
|
+
applyShadowPreference() {
|
|
150
|
+
const root = this.document?.documentElement;
|
|
151
|
+
if (!root || !this.config.shadow) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
root.setAttribute(SHADOW_ATTRIBUTE, this.config.shadow);
|
|
155
|
+
}
|
|
134
156
|
observeThemeChanges() {
|
|
135
157
|
const root = this.document?.documentElement;
|
|
136
158
|
if (!root || typeof MutationObserver === 'undefined') {
|
|
137
159
|
return;
|
|
138
160
|
}
|
|
139
|
-
const attributeFilter = this.config.
|
|
161
|
+
const attributeFilter = this.config.theme.using === 'class' ? ['class'] : ['data-theme'];
|
|
140
162
|
this.observer = new MutationObserver(() => {
|
|
141
163
|
this.syncFromDom();
|
|
142
164
|
});
|
|
@@ -153,10 +175,10 @@ class ThemeService {
|
|
|
153
175
|
this.activeTheme.set(this.readThemeFromDom(root));
|
|
154
176
|
}
|
|
155
177
|
readThemeFromDom(root) {
|
|
156
|
-
if (this.config.
|
|
157
|
-
return root.classList.contains(
|
|
178
|
+
if (this.config.theme.using === 'class') {
|
|
179
|
+
return root.classList.contains('dark') ? 'dark' : 'light';
|
|
158
180
|
}
|
|
159
|
-
const theme = root.getAttribute(
|
|
181
|
+
const theme = root.getAttribute('data-theme');
|
|
160
182
|
return isFrameUITheme(theme) ? theme : this.config.defaultTheme;
|
|
161
183
|
}
|
|
162
184
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-ui-ng-foundation.mjs","sources":["../../../projects/foundation/src/lib/class-names.ts","../../../projects/foundation/src/lib/frame-ui.ts","../../../projects/foundation/src/frame-ui-ng-foundation.ts"],"sourcesContent":["export type ClassDictionary = Readonly<Record<string, boolean | null | undefined>>;\nexport type ClassValue =\n | ClassDictionary\n | ClassValue[]\n | false\n | null\n | string\n | undefined;\n\nexport type SlotClasses<TSlot extends string> = Readonly<Record<TSlot, string>>;\nexport type SlotClassOverrides<TSlot extends string> = Partial<Record<TSlot, ClassValue>>;\n\nexport function cx(...values: readonly ClassValue[]): string {\n const classNames: string[] = [];\n\n for (const value of values) {\n if (!value) {\n continue;\n }\n\n if (typeof value === 'string') {\n classNames.push(value);\n continue;\n }\n\n if (Array.isArray(value)) {\n const nested = cx(...value);\n\n if (nested) {\n classNames.push(nested);\n }\n\n continue;\n }\n\n for (const [className, enabled] of Object.entries(value)) {\n if (enabled) {\n classNames.push(className);\n }\n }\n }\n\n return classNames.join(' ');\n}\n\nexport function withClassOverrides<TSlot extends string>(\n slots: SlotClasses<TSlot>,\n overrides?: SlotClassOverrides<TSlot>,\n): Record<TSlot, string> {\n const mergedSlots = {} as Record<TSlot, string>;\n\n for (const slot of Object.keys(slots) as TSlot[]) {\n mergedSlots[slot] = cx(slots[slot], overrides?.[slot]);\n }\n\n return mergedSlots;\n}\n","import { DOCUMENT } from '@angular/common';\r\nimport {\r\n EnvironmentProviders,\r\n ENVIRONMENT_INITIALIZER,\r\n Injectable,\r\n InjectionToken,\r\n OnDestroy,\r\n Signal,\r\n computed,\r\n inject,\r\n makeEnvironmentProviders,\r\n signal,\r\n} from '@angular/core';\r\n\r\nexport type ThemeBindingStrategy = 'attribute' | 'class';\r\nexport type ThemeSyncMode = 'managed' | 'observe';\r\nexport type FrameUITheme = 'light' | 'dark';\r\n\r\nexport interface FrameUIConfig {\r\n attribute: string;\r\n className: string;\r\n defaultTheme: FrameUITheme;\r\n disableCornerHandles: boolean;\r\n mode: ThemeSyncMode;\r\n strategy: ThemeBindingStrategy;\r\n}\r\n\r\nconst DEFAULT_CONFIG: FrameUIConfig = {\r\n attribute: 'data-theme',\r\n className: 'dark',\r\n defaultTheme: 'light',\r\n disableCornerHandles: false,\r\n mode: 'managed',\r\n strategy: 'attribute',\r\n};\r\n\r\nconst CORNER_HANDLES_ATTRIBUTE = 'data-frame-corner-handles';\r\n\r\nexport const FRAME_UI_CONFIG = new InjectionToken<FrameUIConfig>(\r\n 'FRAME_UI_CONFIG',\r\n {\r\n factory: () => DEFAULT_CONFIG,\r\n },\r\n);\r\n\r\nexport interface FrameUIOptions {\r\n attribute?: string;\r\n className?: string;\r\n defaultTheme?: FrameUITheme;\r\n disableCornerHandles?: boolean;\r\n mode?: ThemeSyncMode;\r\n strategy?: ThemeBindingStrategy;\r\n}\r\n\r\nexport function provideFrameUI(\r\n options: FrameUIOptions = {},\r\n): EnvironmentProviders {\r\n return makeEnvironmentProviders([\r\n {\r\n provide: FRAME_UI_CONFIG,\r\n useValue: createFrameUIConfig(options),\r\n },\r\n ThemeService,\r\n {\r\n provide: ENVIRONMENT_INITIALIZER,\r\n multi: true,\r\n useValue: () => {\r\n inject(ThemeService);\r\n },\r\n },\r\n ]);\r\n}\r\n\r\nexport function createFrameUIConfig(\r\n options: FrameUIOptions = {},\r\n): FrameUIConfig {\r\n const defaultTheme = options.defaultTheme ?? DEFAULT_CONFIG.defaultTheme;\r\n\r\n return {\r\n attribute: options.attribute ?? DEFAULT_CONFIG.attribute,\r\n className: options.className ?? DEFAULT_CONFIG.className,\r\n defaultTheme,\r\n disableCornerHandles:\r\n options.disableCornerHandles ?? DEFAULT_CONFIG.disableCornerHandles,\r\n mode: options.mode ?? DEFAULT_CONFIG.mode,\r\n strategy: options.strategy ?? DEFAULT_CONFIG.strategy,\r\n };\r\n}\r\n\r\n@Injectable()\r\nexport class ThemeService implements OnDestroy {\r\n private readonly document = inject(DOCUMENT);\r\n private readonly config = inject(FRAME_UI_CONFIG);\r\n private readonly activeTheme = signal(this.config.defaultTheme);\r\n private observer: MutationObserver | null = null;\r\n\r\n readonly theme: Signal<FrameUITheme> = this.activeTheme.asReadonly();\r\n\r\n readonly isDark = computed(() => this.activeTheme() === 'dark');\r\n\r\n constructor() {\r\n this.applyCornerHandlesPreference();\r\n\r\n if (this.config.mode === 'observe') {\r\n this.syncFromDom();\r\n this.observeThemeChanges();\r\n return;\r\n }\r\n\r\n this.applyTheme(this.activeTheme());\r\n }\r\n\r\n setTheme(name: FrameUITheme): void {\r\n if (!isFrameUITheme(name)) {\r\n throw new Error(`Unknown theme \"${name}\".`);\r\n }\r\n\r\n if (this.config.mode === 'observe') {\r\n throw new Error(\r\n 'ThemeService is configured to observe external theme state and cannot set the theme.',\r\n );\r\n }\r\n\r\n this.activeTheme.set(name);\r\n this.applyTheme(name);\r\n }\r\n\r\n toggleTheme(): FrameUITheme {\r\n const nextTheme = this.activeTheme() === 'dark' ? 'light' : 'dark';\r\n\r\n this.setTheme(nextTheme);\r\n\r\n return nextTheme;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.observer?.disconnect();\r\n this.observer = null;\r\n }\r\n\r\n private applyTheme(name: FrameUITheme): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root) {\r\n return;\r\n }\r\n\r\n if (this.config.strategy === 'class') {\r\n root.classList.toggle(this.config.className, name === 'dark');\r\n return;\r\n }\r\n\r\n root.setAttribute(this.config.attribute, name);\r\n }\r\n\r\n private applyCornerHandlesPreference(): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root) {\r\n return;\r\n }\r\n\r\n if (this.config.disableCornerHandles) {\r\n root.setAttribute(CORNER_HANDLES_ATTRIBUTE, 'false');\r\n return;\r\n }\r\n\r\n root.removeAttribute(CORNER_HANDLES_ATTRIBUTE);\r\n }\r\n\r\n private observeThemeChanges(): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root || typeof MutationObserver === 'undefined') {\r\n return;\r\n }\r\n\r\n const attributeFilter =\r\n this.config.strategy === 'class' ? ['class'] : [this.config.attribute];\r\n\r\n this.observer = new MutationObserver(() => {\r\n this.syncFromDom();\r\n });\r\n this.observer.observe(root, {\r\n attributeFilter,\r\n attributes: true,\r\n });\r\n }\r\n\r\n private syncFromDom(): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root) {\r\n return;\r\n }\r\n\r\n this.activeTheme.set(this.readThemeFromDom(root));\r\n }\r\n\r\n private readThemeFromDom(root: HTMLElement): FrameUITheme {\r\n if (this.config.strategy === 'class') {\r\n return root.classList.contains(this.config.className) ? 'dark' : 'light';\r\n }\r\n\r\n const theme = root.getAttribute(this.config.attribute);\r\n\r\n return isFrameUITheme(theme) ? theme : this.config.defaultTheme;\r\n }\r\n}\r\n\r\nfunction isFrameUITheme(value: unknown): value is FrameUITheme {\r\n return value === 'light' || value === 'dark';\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAYM,SAAU,EAAE,CAAC,GAAG,MAA6B,EAAA;IACjD,MAAM,UAAU,GAAa,EAAE;AAE/B,IAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;QAC1B,IAAI,CAAC,KAAK,EAAE;YACV;QACF;AAEA,QAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,YAAA,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;YACtB;QACF;AAEA,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AACxB,YAAA,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;YAE3B,IAAI,MAAM,EAAE;AACV,gBAAA,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;YACzB;YAEA;QACF;AAEA,QAAA,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACxD,IAAI,OAAO,EAAE;AACX,gBAAA,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;YAC5B;QACF;IACF;AAEA,IAAA,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7B;AAEM,SAAU,kBAAkB,CAChC,KAAyB,EACzB,SAAqC,EAAA;IAErC,MAAM,WAAW,GAAG,EAA2B;IAE/C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAY,EAAE;AAChD,QAAA,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IACxD;AAEA,IAAA,OAAO,WAAW;AACpB;;AC7BA,MAAM,cAAc,GAAkB;AACpC,IAAA,SAAS,EAAE,YAAY;AACvB,IAAA,SAAS,EAAE,MAAM;AACjB,IAAA,YAAY,EAAE,OAAO;AACrB,IAAA,oBAAoB,EAAE,KAAK;AAC3B,IAAA,IAAI,EAAE,SAAS;AACf,IAAA,QAAQ,EAAE,WAAW;CACtB;AAED,MAAM,wBAAwB,GAAG,2BAA2B;MAE/C,eAAe,GAAG,IAAI,cAAc,CAC/C,iBAAiB,EACjB;AACE,IAAA,OAAO,EAAE,MAAM,cAAc;AAC9B,CAAA;AAYG,SAAU,cAAc,CAC5B,OAAA,GAA0B,EAAE,EAAA;AAE5B,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA;AACE,YAAA,OAAO,EAAE,eAAe;AACxB,YAAA,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC;AACvC,SAAA;QACD,YAAY;AACZ,QAAA;AACE,YAAA,OAAO,EAAE,uBAAuB;AAChC,YAAA,KAAK,EAAE,IAAI;YACX,QAAQ,EAAE,MAAK;gBACb,MAAM,CAAC,YAAY,CAAC;YACtB,CAAC;AACF,SAAA;AACF,KAAA,CAAC;AACJ;AAEM,SAAU,mBAAmB,CACjC,OAAA,GAA0B,EAAE,EAAA;IAE5B,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,cAAc,CAAC,YAAY;IAExE,OAAO;AACL,QAAA,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,cAAc,CAAC,SAAS;AACxD,QAAA,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,cAAc,CAAC,SAAS;QACxD,YAAY;AACZ,QAAA,oBAAoB,EAClB,OAAO,CAAC,oBAAoB,IAAI,cAAc,CAAC,oBAAoB;AACrE,QAAA,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,cAAc,CAAC,IAAI;AACzC,QAAA,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ;KACtD;AACH;MAGa,YAAY,CAAA;AACN,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC3B,IAAA,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC;IAChC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;IACvD,QAAQ,GAA4B,IAAI;AAEvC,IAAA,KAAK,GAAyB,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;AAE3D,IAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,6EAAC;AAE/D,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,4BAA4B,EAAE;QAEnC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;YAClC,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,mBAAmB,EAAE;YAC1B;QACF;QAEA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC;AAEA,IAAA,QAAQ,CAAC,IAAkB,EAAA;AACzB,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;AACzB,YAAA,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAA,EAAA,CAAI,CAAC;QAC7C;QAEA,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;AAClC,YAAA,MAAM,IAAI,KAAK,CACb,sFAAsF,CACvF;QACH;AAEA,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;IACvB;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,GAAG,OAAO,GAAG,MAAM;AAElE,QAAA,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;AAExB,QAAA,OAAO,SAAS;IAClB;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE;AAC3B,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;IACtB;AAEQ,IAAA,UAAU,CAAC,IAAkB,EAAA;AACnC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe;QAE3C,IAAI,CAAC,IAAI,EAAE;YACT;QACF;QAEA,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE;AACpC,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,KAAK,MAAM,CAAC;YAC7D;QACF;QAEA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC;IAChD;IAEQ,4BAA4B,GAAA;AAClC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe;QAE3C,IAAI,CAAC,IAAI,EAAE;YACT;QACF;AAEA,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE;AACpC,YAAA,IAAI,CAAC,YAAY,CAAC,wBAAwB,EAAE,OAAO,CAAC;YACpD;QACF;AAEA,QAAA,IAAI,CAAC,eAAe,CAAC,wBAAwB,CAAC;IAChD;IAEQ,mBAAmB,GAAA;AACzB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe;QAE3C,IAAI,CAAC,IAAI,IAAI,OAAO,gBAAgB,KAAK,WAAW,EAAE;YACpD;QACF;QAEA,MAAM,eAAe,GACnB,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;AAExE,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,gBAAgB,CAAC,MAAK;YACxC,IAAI,CAAC,WAAW,EAAE;AACpB,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE;YAC1B,eAAe;AACf,YAAA,UAAU,EAAE,IAAI;AACjB,SAAA,CAAC;IACJ;IAEQ,WAAW,GAAA;AACjB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe;QAE3C,IAAI,CAAC,IAAI,EAAE;YACT;QACF;AAEA,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACnD;AAEQ,IAAA,gBAAgB,CAAC,IAAiB,EAAA;QACxC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE;YACpC,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,OAAO;QAC1E;AAEA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;AAEtD,QAAA,OAAO,cAAc,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY;IACjE;wGArHW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;4GAAZ,YAAY,EAAA,CAAA;;4FAAZ,YAAY,EAAA,UAAA,EAAA,CAAA;kBADxB;;AAyHD,SAAS,cAAc,CAAC,KAAc,EAAA;AACpC,IAAA,OAAO,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM;AAC9C;;ACpNA;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"frame-ui-ng-foundation.mjs","sources":["../../../projects/foundation/src/lib/class-names.ts","../../../projects/foundation/src/lib/frame-ui.ts","../../../projects/foundation/src/frame-ui-ng-foundation.ts"],"sourcesContent":["export type ClassDictionary = Readonly<Record<string, boolean | null | undefined>>;\nexport type ClassValue =\n | ClassDictionary\n | ClassValue[]\n | false\n | null\n | string\n | undefined;\n\nexport type SlotClasses<TSlot extends string> = Readonly<Record<TSlot, string>>;\nexport type SlotClassOverrides<TSlot extends string> = Partial<Record<TSlot, ClassValue>>;\n\nexport function cx(...values: readonly ClassValue[]): string {\n const classNames: string[] = [];\n\n for (const value of values) {\n if (!value) {\n continue;\n }\n\n if (typeof value === 'string') {\n classNames.push(value);\n continue;\n }\n\n if (Array.isArray(value)) {\n const nested = cx(...value);\n\n if (nested) {\n classNames.push(nested);\n }\n\n continue;\n }\n\n for (const [className, enabled] of Object.entries(value)) {\n if (enabled) {\n classNames.push(className);\n }\n }\n }\n\n return classNames.join(' ');\n}\n\nexport function withClassOverrides<TSlot extends string>(\n slots: SlotClasses<TSlot>,\n overrides?: SlotClassOverrides<TSlot>,\n): Record<TSlot, string> {\n const mergedSlots = {} as Record<TSlot, string>;\n\n for (const slot of Object.keys(slots) as TSlot[]) {\n mergedSlots[slot] = cx(slots[slot], overrides?.[slot]);\n }\n\n return mergedSlots;\n}\n","import { DOCUMENT } from '@angular/common';\r\nimport {\r\n EnvironmentProviders,\r\n ENVIRONMENT_INITIALIZER,\r\n Injectable,\r\n InjectionToken,\r\n OnDestroy,\r\n Signal,\r\n computed,\r\n inject,\r\n makeEnvironmentProviders,\r\n signal,\r\n} from '@angular/core';\r\n\r\nexport type FrameUIThemeController = 'frame' | 'app';\r\nexport type FrameUIThemeSelector = 'data-theme' | 'class';\r\nexport type FrameUITheme = 'light' | 'dark';\r\nexport type FrameUIDensity = 'compact' | 'default' | 'comfortable';\r\nexport type FrameUIShadow = 'flat' | 'default' | 'raised';\r\n\r\nexport interface FrameUIThemeConfig {\r\n controlledBy: FrameUIThemeController;\r\n using: FrameUIThemeSelector;\r\n}\r\n\r\nexport interface FrameUIConfig {\r\n defaultTheme: FrameUITheme;\r\n density: FrameUIDensity | null;\r\n disableCornerHandles: boolean;\r\n shadow: FrameUIShadow | null;\r\n theme: FrameUIThemeConfig;\r\n}\r\n\r\nconst DEFAULT_CONFIG: FrameUIConfig = {\r\n defaultTheme: 'light',\r\n density: null,\r\n disableCornerHandles: false,\r\n shadow: null,\r\n theme: {\r\n controlledBy: 'frame',\r\n using: 'data-theme',\r\n },\r\n};\r\n\r\nconst CORNER_HANDLES_ATTRIBUTE = 'data-frame-corner-handles';\r\nconst DENSITY_ATTRIBUTE = 'data-density';\r\nconst SHADOW_ATTRIBUTE = 'data-shadow';\r\n\r\nexport const FRAME_UI_CONFIG = new InjectionToken<FrameUIConfig>(\r\n 'FRAME_UI_CONFIG',\r\n {\r\n factory: () => DEFAULT_CONFIG,\r\n },\r\n);\r\n\r\nexport interface FrameUIOptions {\r\n defaultTheme?: FrameUITheme;\r\n density?: FrameUIDensity;\r\n disableCornerHandles?: boolean;\r\n shadow?: FrameUIShadow;\r\n theme?: Partial<FrameUIThemeConfig>;\r\n}\r\n\r\nexport function provideFrameUI(\r\n options: FrameUIOptions = {},\r\n): EnvironmentProviders {\r\n return makeEnvironmentProviders([\r\n {\r\n provide: FRAME_UI_CONFIG,\r\n useValue: createFrameUIConfig(options),\r\n },\r\n ThemeService,\r\n {\r\n provide: ENVIRONMENT_INITIALIZER,\r\n multi: true,\r\n useValue: () => {\r\n inject(ThemeService);\r\n },\r\n },\r\n ]);\r\n}\r\n\r\nexport function createFrameUIConfig(\r\n options: FrameUIOptions = {},\r\n): FrameUIConfig {\r\n const defaultTheme = options.defaultTheme ?? DEFAULT_CONFIG.defaultTheme;\r\n\r\n return {\r\n defaultTheme,\r\n density: options.density ?? DEFAULT_CONFIG.density,\r\n disableCornerHandles:\r\n options.disableCornerHandles ?? DEFAULT_CONFIG.disableCornerHandles,\r\n shadow: options.shadow ?? DEFAULT_CONFIG.shadow,\r\n theme: {\r\n controlledBy:\r\n options.theme?.controlledBy ?? DEFAULT_CONFIG.theme.controlledBy,\r\n using: options.theme?.using ?? DEFAULT_CONFIG.theme.using,\r\n },\r\n };\r\n}\r\n\r\n@Injectable()\r\nexport class ThemeService implements OnDestroy {\r\n private readonly document = inject(DOCUMENT);\r\n private readonly config = inject(FRAME_UI_CONFIG);\r\n private readonly activeTheme = signal(this.config.defaultTheme);\r\n private observer: MutationObserver | null = null;\r\n\r\n readonly theme: Signal<FrameUITheme> = this.activeTheme.asReadonly();\r\n\r\n readonly isDark = computed(() => this.activeTheme() === 'dark');\r\n\r\n constructor() {\r\n this.applyCornerHandlesPreference();\r\n this.applyDensityPreference();\r\n this.applyShadowPreference();\r\n\r\n if (this.config.theme.controlledBy === 'app') {\r\n this.syncFromDom();\r\n this.observeThemeChanges();\r\n return;\r\n }\r\n\r\n this.applyTheme(this.activeTheme());\r\n }\r\n\r\n setTheme(name: FrameUITheme): void {\r\n if (!isFrameUITheme(name)) {\r\n throw new Error(`Unknown theme \"${name}\".`);\r\n }\r\n\r\n if (this.config.theme.controlledBy === 'app') {\r\n throw new Error(\r\n 'ThemeService is configured to read app-controlled theme state and cannot set the theme.',\r\n );\r\n }\r\n\r\n this.activeTheme.set(name);\r\n this.applyTheme(name);\r\n }\r\n\r\n toggleTheme(): FrameUITheme {\r\n const nextTheme = this.activeTheme() === 'dark' ? 'light' : 'dark';\r\n\r\n this.setTheme(nextTheme);\r\n\r\n return nextTheme;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.observer?.disconnect();\r\n this.observer = null;\r\n }\r\n\r\n private applyTheme(name: FrameUITheme): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root) {\r\n return;\r\n }\r\n\r\n if (this.config.theme.using === 'class') {\r\n root.classList.toggle('dark', name === 'dark');\r\n return;\r\n }\r\n\r\n root.setAttribute('data-theme', name);\r\n }\r\n\r\n private applyCornerHandlesPreference(): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root) {\r\n return;\r\n }\r\n\r\n if (this.config.disableCornerHandles) {\r\n root.setAttribute(CORNER_HANDLES_ATTRIBUTE, 'false');\r\n return;\r\n }\r\n\r\n root.removeAttribute(CORNER_HANDLES_ATTRIBUTE);\r\n }\r\n\r\n private applyDensityPreference(): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root || !this.config.density) {\r\n return;\r\n }\r\n\r\n root.setAttribute(DENSITY_ATTRIBUTE, this.config.density);\r\n }\r\n\r\n private applyShadowPreference(): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root || !this.config.shadow) {\r\n return;\r\n }\r\n\r\n root.setAttribute(SHADOW_ATTRIBUTE, this.config.shadow);\r\n }\r\n\r\n private observeThemeChanges(): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root || typeof MutationObserver === 'undefined') {\r\n return;\r\n }\r\n\r\n const attributeFilter =\r\n this.config.theme.using === 'class' ? ['class'] : ['data-theme'];\r\n\r\n this.observer = new MutationObserver(() => {\r\n this.syncFromDom();\r\n });\r\n this.observer.observe(root, {\r\n attributeFilter,\r\n attributes: true,\r\n });\r\n }\r\n\r\n private syncFromDom(): void {\r\n const root = this.document?.documentElement;\r\n\r\n if (!root) {\r\n return;\r\n }\r\n\r\n this.activeTheme.set(this.readThemeFromDom(root));\r\n }\r\n\r\n private readThemeFromDom(root: HTMLElement): FrameUITheme {\r\n if (this.config.theme.using === 'class') {\r\n return root.classList.contains('dark') ? 'dark' : 'light';\r\n }\r\n\r\n const theme = root.getAttribute('data-theme');\r\n\r\n return isFrameUITheme(theme) ? theme : this.config.defaultTheme;\r\n }\r\n}\r\n\r\nfunction isFrameUITheme(value: unknown): value is FrameUITheme {\r\n return value === 'light' || value === 'dark';\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/styles/foundation.css
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
:root,
|
|
2
|
-
[data-theme='light'] {
|
|
1
|
+
:where(:root, [data-theme='light']) {
|
|
3
2
|
/* Theme metadata */
|
|
4
3
|
color-scheme: light;
|
|
5
4
|
|
|
@@ -21,6 +20,12 @@
|
|
|
21
20
|
--frame-accent-foreground: oklch(0.205 0 0);
|
|
22
21
|
--frame-destructive: oklch(55.205% 0.18114 25.384);
|
|
23
22
|
--frame-destructive-foreground: oklch(100% 0.00011 271.152);
|
|
23
|
+
--frame-success: oklch(0.62 0.18 149);
|
|
24
|
+
--frame-success-foreground: oklch(0.985 0 0);
|
|
25
|
+
--frame-warning: oklch(0.68 0.16 65);
|
|
26
|
+
--frame-warning-foreground: oklch(0.145 0 0);
|
|
27
|
+
--frame-info: oklch(0.58 0.19 255);
|
|
28
|
+
--frame-info-foreground: oklch(0.985 0 0);
|
|
24
29
|
|
|
25
30
|
/* Structure and focus */
|
|
26
31
|
--frame-border: oklch(0.87 0.006 247);
|
|
@@ -29,7 +34,7 @@
|
|
|
29
34
|
--frame-ring: #d71920;
|
|
30
35
|
--frame-frame-line: color-mix(in srgb, var(--frame-border-strong) 48%, transparent);
|
|
31
36
|
--frame-frame-line-muted: color-mix(in srgb, var(--frame-border) 54%, transparent);
|
|
32
|
-
--frame-frame-accent:
|
|
37
|
+
--frame-frame-accent: var(--frame-ring);
|
|
33
38
|
--frame-frame-tick-size: 0.375rem;
|
|
34
39
|
--frame-frame-tick-inset: 0;
|
|
35
40
|
|
|
@@ -40,21 +45,52 @@
|
|
|
40
45
|
--frame-spacing-lg: 1rem;
|
|
41
46
|
--frame-spacing-xl: 1.25rem;
|
|
42
47
|
|
|
48
|
+
/* Density */
|
|
49
|
+
--frame-density-gap-xs: 0.125rem;
|
|
50
|
+
--frame-density-gap-sm: 0.25rem;
|
|
51
|
+
--frame-density-gap-md: 0.5rem;
|
|
52
|
+
--frame-density-gap-lg: 0.75rem;
|
|
53
|
+
--frame-density-gap-xl: 1rem;
|
|
54
|
+
--frame-density-control-height-sm: 2rem;
|
|
55
|
+
--frame-density-control-height-md: 2.25rem;
|
|
56
|
+
--frame-density-control-height-lg: 2.5rem;
|
|
57
|
+
--frame-density-control-height-xl: 2.875rem;
|
|
58
|
+
--frame-density-control-padding-x-sm: 0.75rem;
|
|
59
|
+
--frame-density-control-padding-x-md: 0.875rem;
|
|
60
|
+
--frame-density-control-padding-x-lg: 1rem;
|
|
61
|
+
--frame-density-inline-height: 1.375rem;
|
|
62
|
+
--frame-density-inline-padding-block: 0.1875rem;
|
|
63
|
+
--frame-density-inline-padding-inline: 0.625rem;
|
|
64
|
+
--frame-density-item-height: 2rem;
|
|
65
|
+
--frame-density-item-padding: 0.375rem 0.5rem;
|
|
66
|
+
--frame-density-file-padding-block: 0.375rem;
|
|
67
|
+
--frame-density-overlay-padding-block: 0.375rem;
|
|
68
|
+
--frame-density-overlay-padding-inline: 0.625rem;
|
|
69
|
+
--frame-density-shortcut-padding-block: 0.0625rem;
|
|
70
|
+
--frame-density-shortcut-padding-inline: 0.3125rem;
|
|
71
|
+
--frame-density-panel-padding-sm: 0.25rem;
|
|
72
|
+
--frame-density-panel-padding-md: 1rem;
|
|
73
|
+
--frame-density-panel-padding-lg: 1.5rem;
|
|
74
|
+
--frame-density-table-cell-padding-block: 0.75rem;
|
|
75
|
+
--frame-density-table-cell-padding-inline: 1rem;
|
|
76
|
+
--frame-density-table-cell-padding-block-sm: 0.5rem;
|
|
77
|
+
--frame-density-table-cell-padding-inline-sm: 0.75rem;
|
|
78
|
+
--frame-density-table-cell-padding-block-lg: 1rem;
|
|
79
|
+
--frame-density-table-cell-padding-inline-lg: 1.125rem;
|
|
80
|
+
|
|
43
81
|
/* Shape */
|
|
44
|
-
--frame-radius-
|
|
45
|
-
--frame-radius-
|
|
46
|
-
--frame-radius-
|
|
47
|
-
--frame-radius-lg: 0.75rem;
|
|
82
|
+
--frame-radius-sm: 0px;
|
|
83
|
+
--frame-radius-md: 0px;
|
|
84
|
+
--frame-radius-lg: 0px;
|
|
48
85
|
--frame-radius-full: 9999px;
|
|
49
86
|
|
|
50
87
|
/* Elevation */
|
|
51
88
|
--frame-shadow-sm: none;
|
|
52
89
|
--frame-shadow-md: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
|
53
|
-
--frame-shadow-
|
|
90
|
+
--frame-shadow-lg: 0 24px 80px rgb(0 0 0 / 0.18), 0 8px 24px rgb(0 0 0 / 0.12);
|
|
54
91
|
}
|
|
55
92
|
|
|
56
|
-
[data-theme='dark'],
|
|
57
|
-
.dark {
|
|
93
|
+
:where([data-theme='dark'], .dark) {
|
|
58
94
|
/* Theme metadata */
|
|
59
95
|
color-scheme: dark;
|
|
60
96
|
|
|
@@ -74,6 +110,14 @@
|
|
|
74
110
|
--frame-primary-foreground: oklch(0.205 0 0);
|
|
75
111
|
--frame-accent: oklch(0.269 0 0);
|
|
76
112
|
--frame-accent-foreground: oklch(0.985 0 0);
|
|
113
|
+
--frame-destructive: oklch(0.704 0.191 22.216);
|
|
114
|
+
--frame-destructive-foreground: oklch(0.985 0 0);
|
|
115
|
+
--frame-success: oklch(0.72 0.17 149);
|
|
116
|
+
--frame-success-foreground: oklch(0.145 0 0);
|
|
117
|
+
--frame-warning: oklch(0.78 0.16 75);
|
|
118
|
+
--frame-warning-foreground: oklch(0.145 0 0);
|
|
119
|
+
--frame-info: oklch(0.72 0.15 255);
|
|
120
|
+
--frame-info-foreground: oklch(0.145 0 0);
|
|
77
121
|
|
|
78
122
|
/* Structure and focus */
|
|
79
123
|
--frame-border: oklch(1 0 0 / 0.08);
|
|
@@ -82,10 +126,107 @@
|
|
|
82
126
|
--frame-ring: #ff4a4f;
|
|
83
127
|
--frame-frame-line: color-mix(in srgb, var(--frame-border-strong) 54%, transparent);
|
|
84
128
|
--frame-frame-line-muted: color-mix(in srgb, var(--frame-border) 62%, transparent);
|
|
85
|
-
--frame-frame-accent:
|
|
129
|
+
--frame-frame-accent: var(--frame-ring);
|
|
86
130
|
|
|
87
131
|
/* Elevation */
|
|
88
132
|
--frame-shadow-sm: none;
|
|
89
133
|
--frame-shadow-md: 0 10px 15px -3px rgb(0 0 0 / 0.35);
|
|
90
|
-
--frame-shadow-
|
|
134
|
+
--frame-shadow-lg: 0 24px 80px rgb(0 0 0 / 0.38), 0 8px 24px rgb(0 0 0 / 0.24);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
:where([data-shadow='flat']) {
|
|
138
|
+
--frame-shadow-sm: none;
|
|
139
|
+
--frame-shadow-md: none;
|
|
140
|
+
--frame-shadow-lg: none;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
:where([data-shadow='default']) {
|
|
144
|
+
--frame-shadow-sm: none;
|
|
145
|
+
--frame-shadow-md: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
|
146
|
+
--frame-shadow-lg: 0 24px 80px rgb(0 0 0 / 0.18), 0 8px 24px rgb(0 0 0 / 0.12);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
:where([data-theme='dark'], .dark):where([data-shadow='default']) {
|
|
150
|
+
--frame-shadow-md: 0 10px 15px -3px rgb(0 0 0 / 0.35);
|
|
151
|
+
--frame-shadow-lg: 0 24px 80px rgb(0 0 0 / 0.38), 0 8px 24px rgb(0 0 0 / 0.24);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
:where([data-shadow='raised']) {
|
|
155
|
+
--frame-shadow-sm: 0 2px 8px rgb(0 0 0 / 0.1);
|
|
156
|
+
--frame-shadow-md: 0 16px 32px -12px rgb(0 0 0 / 0.22);
|
|
157
|
+
--frame-shadow-lg: 0 32px 90px rgb(0 0 0 / 0.24), 0 12px 32px rgb(0 0 0 / 0.16);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
:where([data-theme='dark'], .dark):where([data-shadow='raised']) {
|
|
161
|
+
--frame-shadow-sm: 0 2px 8px rgb(0 0 0 / 0.32);
|
|
162
|
+
--frame-shadow-md: 0 16px 32px -12px rgb(0 0 0 / 0.52);
|
|
163
|
+
--frame-shadow-lg: 0 32px 90px rgb(0 0 0 / 0.58), 0 12px 32px rgb(0 0 0 / 0.36);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
:where([data-density='compact']) {
|
|
167
|
+
--frame-density-gap-xs: 0.0625rem;
|
|
168
|
+
--frame-density-gap-sm: 0.1875rem;
|
|
169
|
+
--frame-density-gap-md: 0.375rem;
|
|
170
|
+
--frame-density-gap-lg: 0.5rem;
|
|
171
|
+
--frame-density-gap-xl: 0.75rem;
|
|
172
|
+
--frame-density-control-height-sm: 1.75rem;
|
|
173
|
+
--frame-density-control-height-md: 2rem;
|
|
174
|
+
--frame-density-control-height-lg: 2.25rem;
|
|
175
|
+
--frame-density-control-height-xl: 2.5rem;
|
|
176
|
+
--frame-density-control-padding-x-sm: 0.5rem;
|
|
177
|
+
--frame-density-control-padding-x-md: 0.75rem;
|
|
178
|
+
--frame-density-control-padding-x-lg: 0.875rem;
|
|
179
|
+
--frame-density-inline-height: 1.25rem;
|
|
180
|
+
--frame-density-inline-padding-block: 0.125rem;
|
|
181
|
+
--frame-density-inline-padding-inline: 0.5rem;
|
|
182
|
+
--frame-density-item-height: 1.75rem;
|
|
183
|
+
--frame-density-item-padding: 0.25rem 0.5rem;
|
|
184
|
+
--frame-density-file-padding-block: 0.25rem;
|
|
185
|
+
--frame-density-overlay-padding-block: 0.25rem;
|
|
186
|
+
--frame-density-overlay-padding-inline: 0.5rem;
|
|
187
|
+
--frame-density-shortcut-padding-block: 0.0625rem;
|
|
188
|
+
--frame-density-shortcut-padding-inline: 0.25rem;
|
|
189
|
+
--frame-density-panel-padding-sm: 0.1875rem;
|
|
190
|
+
--frame-density-panel-padding-md: 0.75rem;
|
|
191
|
+
--frame-density-panel-padding-lg: 1rem;
|
|
192
|
+
--frame-density-table-cell-padding-block: 0.5rem;
|
|
193
|
+
--frame-density-table-cell-padding-inline: 0.75rem;
|
|
194
|
+
--frame-density-table-cell-padding-block-sm: 0.375rem;
|
|
195
|
+
--frame-density-table-cell-padding-inline-sm: 0.5rem;
|
|
196
|
+
--frame-density-table-cell-padding-block-lg: 0.75rem;
|
|
197
|
+
--frame-density-table-cell-padding-inline-lg: 0.875rem;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
:where([data-density='comfortable']) {
|
|
201
|
+
--frame-density-gap-xs: 0.1875rem;
|
|
202
|
+
--frame-density-gap-sm: 0.375rem;
|
|
203
|
+
--frame-density-gap-md: 0.625rem;
|
|
204
|
+
--frame-density-gap-lg: 0.875rem;
|
|
205
|
+
--frame-density-gap-xl: 1.25rem;
|
|
206
|
+
--frame-density-control-height-sm: 2.25rem;
|
|
207
|
+
--frame-density-control-height-md: 2.5rem;
|
|
208
|
+
--frame-density-control-height-lg: 2.75rem;
|
|
209
|
+
--frame-density-control-height-xl: 3.125rem;
|
|
210
|
+
--frame-density-control-padding-x-sm: 0.875rem;
|
|
211
|
+
--frame-density-control-padding-x-md: 1rem;
|
|
212
|
+
--frame-density-control-padding-x-lg: 1.125rem;
|
|
213
|
+
--frame-density-inline-height: 1.5rem;
|
|
214
|
+
--frame-density-inline-padding-block: 0.25rem;
|
|
215
|
+
--frame-density-inline-padding-inline: 0.75rem;
|
|
216
|
+
--frame-density-item-height: 2.25rem;
|
|
217
|
+
--frame-density-item-padding: 0.5rem 0.625rem;
|
|
218
|
+
--frame-density-file-padding-block: 0.5rem;
|
|
219
|
+
--frame-density-overlay-padding-block: 0.5rem;
|
|
220
|
+
--frame-density-overlay-padding-inline: 0.75rem;
|
|
221
|
+
--frame-density-shortcut-padding-block: 0.125rem;
|
|
222
|
+
--frame-density-shortcut-padding-inline: 0.375rem;
|
|
223
|
+
--frame-density-panel-padding-sm: 0.375rem;
|
|
224
|
+
--frame-density-panel-padding-md: 1.25rem;
|
|
225
|
+
--frame-density-panel-padding-lg: 1.75rem;
|
|
226
|
+
--frame-density-table-cell-padding-block: 1rem;
|
|
227
|
+
--frame-density-table-cell-padding-inline: 1.125rem;
|
|
228
|
+
--frame-density-table-cell-padding-block-sm: 0.625rem;
|
|
229
|
+
--frame-density-table-cell-padding-inline-sm: 0.875rem;
|
|
230
|
+
--frame-density-table-cell-padding-block-lg: 1.125rem;
|
|
231
|
+
--frame-density-table-cell-padding-inline-lg: 1.25rem;
|
|
91
232
|
}
|
|
@@ -8,25 +8,29 @@ type SlotClassOverrides<TSlot extends string> = Partial<Record<TSlot, ClassValue
|
|
|
8
8
|
declare function cx(...values: readonly ClassValue[]): string;
|
|
9
9
|
declare function withClassOverrides<TSlot extends string>(slots: SlotClasses<TSlot>, overrides?: SlotClassOverrides<TSlot>): Record<TSlot, string>;
|
|
10
10
|
|
|
11
|
-
type
|
|
12
|
-
type
|
|
11
|
+
type FrameUIThemeController = 'frame' | 'app';
|
|
12
|
+
type FrameUIThemeSelector = 'data-theme' | 'class';
|
|
13
13
|
type FrameUITheme = 'light' | 'dark';
|
|
14
|
+
type FrameUIDensity = 'compact' | 'default' | 'comfortable';
|
|
15
|
+
type FrameUIShadow = 'flat' | 'default' | 'raised';
|
|
16
|
+
interface FrameUIThemeConfig {
|
|
17
|
+
controlledBy: FrameUIThemeController;
|
|
18
|
+
using: FrameUIThemeSelector;
|
|
19
|
+
}
|
|
14
20
|
interface FrameUIConfig {
|
|
15
|
-
attribute: string;
|
|
16
|
-
className: string;
|
|
17
21
|
defaultTheme: FrameUITheme;
|
|
22
|
+
density: FrameUIDensity | null;
|
|
18
23
|
disableCornerHandles: boolean;
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
shadow: FrameUIShadow | null;
|
|
25
|
+
theme: FrameUIThemeConfig;
|
|
21
26
|
}
|
|
22
27
|
declare const FRAME_UI_CONFIG: InjectionToken<FrameUIConfig>;
|
|
23
28
|
interface FrameUIOptions {
|
|
24
|
-
attribute?: string;
|
|
25
|
-
className?: string;
|
|
26
29
|
defaultTheme?: FrameUITheme;
|
|
30
|
+
density?: FrameUIDensity;
|
|
27
31
|
disableCornerHandles?: boolean;
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
shadow?: FrameUIShadow;
|
|
33
|
+
theme?: Partial<FrameUIThemeConfig>;
|
|
30
34
|
}
|
|
31
35
|
declare function provideFrameUI(options?: FrameUIOptions): EnvironmentProviders;
|
|
32
36
|
declare function createFrameUIConfig(options?: FrameUIOptions): FrameUIConfig;
|
|
@@ -43,6 +47,8 @@ declare class ThemeService implements OnDestroy {
|
|
|
43
47
|
ngOnDestroy(): void;
|
|
44
48
|
private applyTheme;
|
|
45
49
|
private applyCornerHandlesPreference;
|
|
50
|
+
private applyDensityPreference;
|
|
51
|
+
private applyShadowPreference;
|
|
46
52
|
private observeThemeChanges;
|
|
47
53
|
private syncFromDom;
|
|
48
54
|
private readThemeFromDom;
|
|
@@ -51,4 +57,4 @@ declare class ThemeService implements OnDestroy {
|
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
export { FRAME_UI_CONFIG, ThemeService, createFrameUIConfig, cx, provideFrameUI, withClassOverrides };
|
|
54
|
-
export type { ClassDictionary, ClassValue, FrameUIConfig, FrameUIOptions, FrameUITheme,
|
|
60
|
+
export type { ClassDictionary, ClassValue, FrameUIConfig, FrameUIDensity, FrameUIOptions, FrameUIShadow, FrameUITheme, FrameUIThemeConfig, FrameUIThemeController, FrameUIThemeSelector, SlotClassOverrides, SlotClasses };
|