@roblawn/devtool-runtime 0.1.0-alpha.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/LICENSE.md +11 -0
- package/README.md +7 -0
- package/dist/ak/ak.cssState.transform.d.ts +2 -0
- package/dist/ak/ak.cssState.transform.js +60 -0
- package/dist/ak/ak.cssState.types.d.ts +2 -0
- package/dist/ak/ak.cssState.types.js +1 -0
- package/dist/ak/ak.responsive.types.d.ts +18 -0
- package/dist/ak/ak.responsive.types.js +1 -0
- package/dist/ak/ak.tokens.d.ts +10 -0
- package/dist/ak/ak.tokens.js +10 -0
- package/dist/ak/ak.tokens.registry.d.ts +10 -0
- package/dist/ak/ak.tokens.registry.js +45 -0
- package/dist/ak/authoring-surface.shared.d.ts +31 -0
- package/dist/ak/authoring-surface.shared.js +185 -0
- package/dist/ak/configured-core.shared.d.ts +7 -0
- package/dist/ak/configured-core.shared.js +16 -0
- package/dist/ak/configured-surfaces.shared.d.ts +67 -0
- package/dist/ak/configured-surfaces.shared.js +144 -0
- package/dist/ak/index.d.ts +16 -0
- package/dist/ak/index.js +16 -0
- package/dist/ak/project-entry.d.ts +57 -0
- package/dist/ak/project-entry.js +260 -0
- package/dist/ak/project-surface-adapters.shared.d.ts +33 -0
- package/dist/ak/project-surface-adapters.shared.js +83 -0
- package/dist/ak/public-entry.shared.d.ts +16 -0
- package/dist/ak/public-entry.shared.js +18 -0
- package/dist/ak/resolved-layout-marker.shared.d.ts +3 -0
- package/dist/ak/resolved-layout-marker.shared.js +19 -0
- package/dist/ak/runtime-surface.shared.d.ts +31 -0
- package/dist/ak/runtime-surface.shared.js +221 -0
- package/dist/ak/style-execution.d.ts +13 -0
- package/dist/ak/style-execution.js +91 -0
- package/dist/ak/style-schema.d.ts +16 -0
- package/dist/ak/style-schema.js +6 -0
- package/dist/ak/useAk.shared.d.ts +3 -0
- package/dist/ak/useAk.shared.js +36 -0
- package/dist/authoring/authoringEffectKinds.d.ts +2 -0
- package/dist/authoring/authoringEffectKinds.js +48 -0
- package/dist/authoring/index.d.ts +1 -0
- package/dist/authoring/index.js +1 -0
- package/dist/cms/CMSPresenterSchemaTypes.d.ts +108 -0
- package/dist/cms/CMSPresenterSchemaTypes.js +6 -0
- package/dist/cms/CMSSchema.d.ts +27 -0
- package/dist/cms/CMSSchema.js +89 -0
- package/dist/cms/CMSSchemaTypes.d.ts +141 -0
- package/dist/cms/CMSSchemaTypes.js +1 -0
- package/dist/cms/index.d.ts +3 -0
- package/dist/cms/index.js +1 -0
- package/dist/design-system/DesignSystemSnapshotFactory.d.ts +34 -0
- package/dist/design-system/DesignSystemSnapshotFactory.js +38 -0
- package/dist/design-system/ProjectDesignSystemFactory.d.ts +39 -0
- package/dist/design-system/ProjectDesignSystemFactory.js +32 -0
- package/dist/design-system/index.d.ts +8 -0
- package/dist/design-system/index.js +7 -0
- package/dist/design-system/ops/ops.types.d.ts +22 -0
- package/dist/design-system/ops/ops.types.js +1 -0
- package/dist/design-system/resolvers/ds.resolvers.d.ts +3 -0
- package/dist/design-system/resolvers/ds.resolvers.js +24 -0
- package/dist/design-system/resolvers/ds.responsive.d.ts +12 -0
- package/dist/design-system/resolvers/ds.responsive.js +28 -0
- package/dist/design-system/tokens/TokenSchemas.types.d.ts +48 -0
- package/dist/design-system/tokens/TokenSchemas.types.js +3 -0
- package/dist/design-system/tokens/coreTokenFamilies.types.d.ts +2 -0
- package/dist/design-system/tokens/coreTokenFamilies.types.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.js +1 -0
- package/dist/layout/layoutRuntime.d.ts +12 -0
- package/dist/layout/layoutRuntime.js +88 -0
- package/dist/schema/LayoutBindingEditorPolicyMetadata.d.ts +7 -0
- package/dist/schema/LayoutBindingEditorPolicyMetadata.js +19 -0
- package/dist/schema/LayoutBindingEditorSectionMetadata.d.ts +7 -0
- package/dist/schema/LayoutBindingEditorSectionMetadata.js +19 -0
- package/dist/schema/LayoutDefinitionMeta.d.ts +54 -0
- package/dist/schema/LayoutDefinitionMeta.js +1 -0
- package/dist/schema/LayoutFieldIntentMetadata.d.ts +22 -0
- package/dist/schema/LayoutFieldIntentMetadata.js +38 -0
- package/dist/schema/LayoutFieldUiMetadata.d.ts +30 -0
- package/dist/schema/LayoutFieldUiMetadata.js +19 -0
- package/dist/schema/LayoutSchema.d.ts +39 -0
- package/dist/schema/LayoutSchema.js +53 -0
- package/dist/schema/LayoutVariantBindings.d.ts +55 -0
- package/dist/schema/LayoutVariantBindings.js +107 -0
- package/dist/schema/SlotSchema.d.ts +10 -0
- package/dist/schema/SlotSchema.js +3 -0
- package/dist/schema/StyleSchema.d.ts +16 -0
- package/dist/schema/StyleSchema.js +6 -0
- package/dist/schema/index.d.ts +9 -0
- package/dist/schema/index.js +9 -0
- package/dist/theme-contract/CompositeFieldOpByFamily.d.ts +126 -0
- package/dist/theme-contract/CompositeFieldOpByFamily.js +126 -0
- package/dist/theme-contract/index.d.ts +7 -0
- package/dist/theme-contract/index.js +7 -0
- package/dist/theme-contract/ops/coreOps.d.ts +697 -0
- package/dist/theme-contract/ops/coreOps.js +748 -0
- package/dist/theme-contract/ops/delegateValidation.types.d.ts +46 -0
- package/dist/theme-contract/ops/delegateValidation.types.js +4 -0
- package/dist/theme-contract/ops/emitters.d.ts +24 -0
- package/dist/theme-contract/ops/emitters.js +151 -0
- package/dist/theme-contract/ops/op.config.d.ts +711 -0
- package/dist/theme-contract/ops/op.config.js +15 -0
- package/dist/theme-contract/tokens/coreTokenFamilies.d.ts +9 -0
- package/dist/theme-contract/tokens/coreTokenFamilies.js +6 -0
- package/dist/theme-contract/tokens/cssLengthConversion.d.ts +2 -0
- package/dist/theme-contract/tokens/cssLengthConversion.js +39 -0
- package/dist/theme-contract/tokens/defineProjectTokenFamilySchema.d.ts +1 -0
- package/dist/theme-contract/tokens/defineProjectTokenFamilySchema.js +1 -0
- package/dist/theme-contract/tokens/defineTokenFamilySchema.d.ts +3 -0
- package/dist/theme-contract/tokens/defineTokenFamilySchema.js +5 -0
- package/dist/theme-contract/tokens/runtimeTokenFamilies.types.d.ts +5 -0
- package/dist/theme-contract/tokens/runtimeTokenFamilies.types.js +1 -0
- package/dist/theme-contract/tokens/schemas/aspect.token.schema.d.ts +20 -0
- package/dist/theme-contract/tokens/schemas/aspect.token.schema.js +19 -0
- package/dist/theme-contract/tokens/schemas/blur.token.schema.d.ts +21 -0
- package/dist/theme-contract/tokens/schemas/blur.token.schema.js +19 -0
- package/dist/theme-contract/tokens/schemas/border.token.schema.d.ts +54 -0
- package/dist/theme-contract/tokens/schemas/border.token.schema.js +43 -0
- package/dist/theme-contract/tokens/schemas/breakpoint.token.schema.d.ts +19 -0
- package/dist/theme-contract/tokens/schemas/breakpoint.token.schema.js +18 -0
- package/dist/theme-contract/tokens/schemas/color.token.schema.d.ts +24 -0
- package/dist/theme-contract/tokens/schemas/color.token.schema.js +23 -0
- package/dist/theme-contract/tokens/schemas/container.token.schema.d.ts +26 -0
- package/dist/theme-contract/tokens/schemas/container.token.schema.js +30 -0
- package/dist/theme-contract/tokens/schemas/font.token.schema.d.ts +17 -0
- package/dist/theme-contract/tokens/schemas/font.token.schema.js +15 -0
- package/dist/theme-contract/tokens/schemas/fontWeight.token.schema.d.ts +24 -0
- package/dist/theme-contract/tokens/schemas/fontWeight.token.schema.js +22 -0
- package/dist/theme-contract/tokens/schemas/leading.token.schema.d.ts +20 -0
- package/dist/theme-contract/tokens/schemas/leading.token.schema.js +18 -0
- package/dist/theme-contract/tokens/schemas/radius.token.schema.d.ts +23 -0
- package/dist/theme-contract/tokens/schemas/radius.token.schema.js +22 -0
- package/dist/theme-contract/tokens/schemas/shadow.token.schema.d.ts +108 -0
- package/dist/theme-contract/tokens/schemas/shadow.token.schema.js +73 -0
- package/dist/theme-contract/tokens/schemas/size.token.schema.d.ts +20 -0
- package/dist/theme-contract/tokens/schemas/size.token.schema.js +19 -0
- package/dist/theme-contract/tokens/schemas/spacing.token.schema.d.ts +21 -0
- package/dist/theme-contract/tokens/schemas/spacing.token.schema.js +20 -0
- package/dist/theme-contract/tokens/schemas/text.token.schema.d.ts +87 -0
- package/dist/theme-contract/tokens/schemas/text.token.schema.js +30 -0
- package/dist/theme-contract/tokens/schemas/textSize.token.schema.d.ts +28 -0
- package/dist/theme-contract/tokens/schemas/textSize.token.schema.js +27 -0
- package/dist/theme-contract/tokens/schemas/title.token.schema.d.ts +85 -0
- package/dist/theme-contract/tokens/schemas/title.token.schema.js +30 -0
- package/dist/theme-contract/tokens/schemas/tracking.token.schema.d.ts +20 -0
- package/dist/theme-contract/tokens/schemas/tracking.token.schema.js +18 -0
- package/dist/theme-contract/tokens/schemas/zIndex.token.schema.d.ts +18 -0
- package/dist/theme-contract/tokens/schemas/zIndex.token.schema.js +17 -0
- package/dist/theme-contract/tokens/tokens.schema.d.ts +531 -0
- package/dist/theme-contract/tokens/tokens.schema.js +32 -0
- package/dist/types/LayoutResolvedTs.types.d.ts +18 -0
- package/dist/types/LayoutResolvedTs.types.js +1 -0
- package/dist/types/authoredTree.types.d.ts +112 -0
- package/dist/types/authoredTree.types.js +1 -0
- package/dist/types/blockRegistry.types.d.ts +37 -0
- package/dist/types/blockRegistry.types.js +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +1 -0
- package/dist/types/layout.types.d.ts +30 -0
- package/dist/types/layout.types.js +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { computed, shallowRef, unref } from 'vue';
|
|
2
|
+
import { applyCssStateToClassString } from './ak.cssState.transform.js';
|
|
3
|
+
export function makeRuntimeLayoutGetter(layoutRef) {
|
|
4
|
+
return (field) => {
|
|
5
|
+
const raw = layoutRef.value;
|
|
6
|
+
if (typeof raw !== 'object' || raw === null) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
return raw[field];
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function makeRuntimeAkValue(mode, getter) {
|
|
13
|
+
if (mode === 'static') {
|
|
14
|
+
return getter();
|
|
15
|
+
}
|
|
16
|
+
return computed(getter);
|
|
17
|
+
}
|
|
18
|
+
export function makeRuntimeAkRef(mode, getter) {
|
|
19
|
+
if (mode === 'static') {
|
|
20
|
+
return shallowRef(getter());
|
|
21
|
+
}
|
|
22
|
+
return computed(getter);
|
|
23
|
+
}
|
|
24
|
+
export function cx(...parts) {
|
|
25
|
+
return parts
|
|
26
|
+
.map((part) => {
|
|
27
|
+
if (part == null || part === false)
|
|
28
|
+
return '';
|
|
29
|
+
return unref(part).trim();
|
|
30
|
+
})
|
|
31
|
+
.filter((s) => s.length > 0)
|
|
32
|
+
.join(' ');
|
|
33
|
+
}
|
|
34
|
+
function createPassthroughCssApiRuntime(getValue, mode) {
|
|
35
|
+
const factoryCache = new Map();
|
|
36
|
+
const makeFactory = (_opKey) => {
|
|
37
|
+
return ((field, _def, _meta) => {
|
|
38
|
+
return makeRuntimeAkValue(mode, () => {
|
|
39
|
+
const raw = getValue(field);
|
|
40
|
+
return typeof raw === 'string' ? raw : '';
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
return new Proxy({}, {
|
|
45
|
+
get(_target, prop) {
|
|
46
|
+
if (typeof prop !== 'string')
|
|
47
|
+
return undefined;
|
|
48
|
+
let factory = factoryCache.get(prop);
|
|
49
|
+
if (!factory) {
|
|
50
|
+
factory = makeFactory(prop);
|
|
51
|
+
factoryCache.set(prop, factory);
|
|
52
|
+
}
|
|
53
|
+
return factory;
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export function createCssApiRuntime(getValue, mode) {
|
|
58
|
+
return createPassthroughCssApiRuntime(getValue, mode);
|
|
59
|
+
}
|
|
60
|
+
function normalizeCssStateInput(state) {
|
|
61
|
+
const list = Array.isArray(state) ? state : [state];
|
|
62
|
+
return list.map((entry) => String(entry).trim()).filter((entry) => entry.length > 0);
|
|
63
|
+
}
|
|
64
|
+
const didWarnUnsupportedCssStateOpRuntime = new Set();
|
|
65
|
+
function warnUnsupportedCssStateOpRuntimeOnce(op) {
|
|
66
|
+
const isDev = Boolean(import.meta.env?.DEV);
|
|
67
|
+
if (!isDev)
|
|
68
|
+
return;
|
|
69
|
+
if (didWarnUnsupportedCssStateOpRuntime.has(op))
|
|
70
|
+
return;
|
|
71
|
+
didWarnUnsupportedCssStateOpRuntime.add(op);
|
|
72
|
+
console.warn('[ak.cssState] unsupported op in cssState chain; falling back to empty class', { op });
|
|
73
|
+
}
|
|
74
|
+
export function createCssStateApiRuntime(css, mode, enabledOps) {
|
|
75
|
+
const stateApiCache = new Map();
|
|
76
|
+
const allowed = enabledOps ? new Set(enabledOps) : null;
|
|
77
|
+
return (stateInput) => {
|
|
78
|
+
const states = normalizeCssStateInput(stateInput);
|
|
79
|
+
const cacheKey = states.join('\u001f');
|
|
80
|
+
const cachedSurface = stateApiCache.get(cacheKey);
|
|
81
|
+
if (cachedSurface) {
|
|
82
|
+
return cachedSurface;
|
|
83
|
+
}
|
|
84
|
+
const opFactoryCache = new Map();
|
|
85
|
+
const noOpFactoryCache = new Map();
|
|
86
|
+
const getFallbackFactory = (op) => {
|
|
87
|
+
let fallback = noOpFactoryCache.get(op);
|
|
88
|
+
if (!fallback) {
|
|
89
|
+
fallback = ((_field) => {
|
|
90
|
+
warnUnsupportedCssStateOpRuntimeOnce(op);
|
|
91
|
+
return makeRuntimeAkValue(mode, () => '');
|
|
92
|
+
});
|
|
93
|
+
noOpFactoryCache.set(op, fallback);
|
|
94
|
+
}
|
|
95
|
+
return fallback;
|
|
96
|
+
};
|
|
97
|
+
const wrapped = new Proxy({}, {
|
|
98
|
+
get(_target, prop) {
|
|
99
|
+
if (typeof prop !== 'string')
|
|
100
|
+
return undefined;
|
|
101
|
+
if (allowed && !allowed.has(prop))
|
|
102
|
+
return getFallbackFactory(prop);
|
|
103
|
+
let factory = opFactoryCache.get(prop);
|
|
104
|
+
if (!factory) {
|
|
105
|
+
const baseFactory = css[prop];
|
|
106
|
+
if (typeof baseFactory !== 'function')
|
|
107
|
+
return getFallbackFactory(prop);
|
|
108
|
+
factory = ((field, def) => {
|
|
109
|
+
const baseValue = baseFactory(field, def);
|
|
110
|
+
return makeRuntimeAkValue(mode, () => applyCssStateToClassString(String(unref(baseValue) ?? ''), states));
|
|
111
|
+
});
|
|
112
|
+
opFactoryCache.set(prop, factory);
|
|
113
|
+
}
|
|
114
|
+
return factory;
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
stateApiCache.set(cacheKey, wrapped);
|
|
118
|
+
return wrapped;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export function makeDeclare(getValue, tokenFamilies, mode) {
|
|
122
|
+
const baseFor = (kind, field, defaultKey, resolver, _meta) => {
|
|
123
|
+
void kind;
|
|
124
|
+
return makeRuntimeAkValue(mode, () => {
|
|
125
|
+
const raw = getValue(field);
|
|
126
|
+
const rawString = typeof raw === 'string' ? raw : undefined;
|
|
127
|
+
const value = rawString ?? defaultKey;
|
|
128
|
+
return resolver(value);
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const apiBase = {
|
|
132
|
+
for: baseFor,
|
|
133
|
+
enum(field, values, defaultValue, resolver, _meta) {
|
|
134
|
+
return makeRuntimeAkValue(mode, () => {
|
|
135
|
+
const raw = getValue(field);
|
|
136
|
+
if (typeof raw === 'string' && !values.includes(raw)) {
|
|
137
|
+
return raw;
|
|
138
|
+
}
|
|
139
|
+
const value = pickEnumValue(raw, values, defaultValue);
|
|
140
|
+
return resolver(value);
|
|
141
|
+
});
|
|
142
|
+
},
|
|
143
|
+
boolean(field, defaultValue, resolver, _meta) {
|
|
144
|
+
return makeRuntimeAkValue(mode, () => {
|
|
145
|
+
const raw = getValue(field);
|
|
146
|
+
const value = pickBoolean(raw, defaultValue);
|
|
147
|
+
return resolver(value);
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
const api = apiBase;
|
|
152
|
+
const record = api;
|
|
153
|
+
for (const kind of tokenFamilies) {
|
|
154
|
+
record[kind] = (field, defaultKey, resolver, meta) => baseFor(kind, field, defaultKey, resolver, meta);
|
|
155
|
+
}
|
|
156
|
+
return api;
|
|
157
|
+
}
|
|
158
|
+
function pickEnumValue(raw, values, fallback) {
|
|
159
|
+
if (typeof raw === 'string' && values.includes(raw)) {
|
|
160
|
+
return raw;
|
|
161
|
+
}
|
|
162
|
+
return fallback;
|
|
163
|
+
}
|
|
164
|
+
function pickBoolean(raw, fallback) {
|
|
165
|
+
if (typeof raw === 'boolean')
|
|
166
|
+
return raw;
|
|
167
|
+
if (typeof raw === 'string') {
|
|
168
|
+
if (raw === 'true')
|
|
169
|
+
return true;
|
|
170
|
+
if (raw === 'false')
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
return fallback;
|
|
174
|
+
}
|
|
175
|
+
function pickString(raw, fallback) {
|
|
176
|
+
if (typeof raw === 'string')
|
|
177
|
+
return raw;
|
|
178
|
+
return fallback;
|
|
179
|
+
}
|
|
180
|
+
function pickNumber(raw, fallback) {
|
|
181
|
+
if (typeof raw === 'number')
|
|
182
|
+
return raw;
|
|
183
|
+
if (typeof raw === 'string') {
|
|
184
|
+
const parsed = Number(raw);
|
|
185
|
+
if (!Number.isNaN(parsed))
|
|
186
|
+
return parsed;
|
|
187
|
+
}
|
|
188
|
+
return fallback;
|
|
189
|
+
}
|
|
190
|
+
export function makeValue(getValue, mode) {
|
|
191
|
+
const booleanValue = (field, defaultValue, _meta) => {
|
|
192
|
+
return makeRuntimeAkRef(mode, () => {
|
|
193
|
+
const raw = getValue(field);
|
|
194
|
+
return pickBoolean(raw, defaultValue);
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
const stringValue = (field, defaultValue, _meta) => {
|
|
198
|
+
return makeRuntimeAkRef(mode, () => {
|
|
199
|
+
const raw = getValue(field);
|
|
200
|
+
return pickString(raw, defaultValue);
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
const numberValue = (field, defaultValue, _meta) => {
|
|
204
|
+
return makeRuntimeAkRef(mode, () => {
|
|
205
|
+
const raw = getValue(field);
|
|
206
|
+
return pickNumber(raw, defaultValue);
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
const enumValue = (field, values, defaultValue, _meta) => {
|
|
210
|
+
return makeRuntimeAkRef(mode, () => {
|
|
211
|
+
const raw = getValue(field);
|
|
212
|
+
return pickEnumValue(raw, values, defaultValue);
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
return {
|
|
216
|
+
boolean: booleanValue,
|
|
217
|
+
string: stringValue,
|
|
218
|
+
number: numberValue,
|
|
219
|
+
enum: enumValue,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SetupStyleDefinition, StyleSetupResolvers } from './style-schema.js';
|
|
2
|
+
export type StyleExecutionResolvedValue = string | string[];
|
|
3
|
+
export interface StyleExecutionEntry {
|
|
4
|
+
readonly slotKeys: readonly string[];
|
|
5
|
+
resolveAll(props: Record<string, unknown>): Record<string, StyleExecutionResolvedValue>;
|
|
6
|
+
}
|
|
7
|
+
export type StyleExecutionDefinition = SetupStyleDefinition<StyleSetupResolvers>;
|
|
8
|
+
type StyleExecutionRegistryInput = Record<string, StyleExecutionDefinition>;
|
|
9
|
+
export declare function createStyleExecutionEntry(name: string, definition: StyleExecutionDefinition): StyleExecutionEntry;
|
|
10
|
+
export declare function createStyleExecutionRegistry<TRegistry extends StyleExecutionRegistryInput>(definitions: TRegistry): {
|
|
11
|
+
readonly [Name in keyof TRegistry]: StyleExecutionEntry;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { ref, unref } from 'vue';
|
|
2
|
+
import { withScopedAkLayoutRef } from './useAk.shared.js';
|
|
3
|
+
const EXECUTOR_CACHE = new WeakMap();
|
|
4
|
+
function isObject(value) {
|
|
5
|
+
return typeof value === 'object' && value !== null;
|
|
6
|
+
}
|
|
7
|
+
function normalizeResolvedValue(value) {
|
|
8
|
+
const unwrapped = unref(value);
|
|
9
|
+
if (typeof unwrapped === 'string') {
|
|
10
|
+
return unwrapped.trim();
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(unwrapped)) {
|
|
13
|
+
const values = unwrapped
|
|
14
|
+
.map((entry) => {
|
|
15
|
+
const resolved = unref(entry);
|
|
16
|
+
return typeof resolved === 'string' ? resolved.trim() : '';
|
|
17
|
+
})
|
|
18
|
+
.filter((entry) => entry.length > 0);
|
|
19
|
+
return values.length > 0 ? values : '';
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
function readSetupResolvers(name, definition, initialProps) {
|
|
24
|
+
const layoutRef = ref(initialProps);
|
|
25
|
+
const rawResolvers = withScopedAkLayoutRef(layoutRef, () => definition.setup());
|
|
26
|
+
if (!isObject(rawResolvers) || Array.isArray(rawResolvers)) {
|
|
27
|
+
throw new Error(`Style "${name}" setup did not return an object of resolvers.`);
|
|
28
|
+
}
|
|
29
|
+
const resolvers = {};
|
|
30
|
+
for (const [key, value] of Object.entries(rawResolvers)) {
|
|
31
|
+
if (typeof value !== 'function') {
|
|
32
|
+
throw new Error(`Style "${name}" output "${key}" was not a function.`);
|
|
33
|
+
}
|
|
34
|
+
resolvers[key] = value;
|
|
35
|
+
}
|
|
36
|
+
return resolvers;
|
|
37
|
+
}
|
|
38
|
+
function createSetupExecutor(name, definition) {
|
|
39
|
+
const slotKeys = Object.keys(readSetupResolvers(name, definition, {}));
|
|
40
|
+
return {
|
|
41
|
+
slotKeys,
|
|
42
|
+
resolveAll(props) {
|
|
43
|
+
const resolvers = readSetupResolvers(name, definition, props);
|
|
44
|
+
const resolved = {};
|
|
45
|
+
for (const [key, resolver] of Object.entries(resolvers)) {
|
|
46
|
+
const value = normalizeResolvedValue(resolver(props));
|
|
47
|
+
if (value === null)
|
|
48
|
+
continue;
|
|
49
|
+
resolved[key] = value;
|
|
50
|
+
}
|
|
51
|
+
return resolved;
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function getOrCreateExecutor(name, definition) {
|
|
56
|
+
if (typeof definition !== 'object' || definition === null) {
|
|
57
|
+
throw new Error(`Style "${name}" did not export a valid style definition object.`);
|
|
58
|
+
}
|
|
59
|
+
const cached = EXECUTOR_CACHE.get(definition);
|
|
60
|
+
if (cached) {
|
|
61
|
+
return cached;
|
|
62
|
+
}
|
|
63
|
+
const executor = typeof definition.setup === 'function'
|
|
64
|
+
? createSetupExecutor(name, definition)
|
|
65
|
+
: (() => {
|
|
66
|
+
throw new Error(`Style "${name}" must export defineStyle(() => { ... }). Legacy config-style definitions are not supported.`);
|
|
67
|
+
})();
|
|
68
|
+
EXECUTOR_CACHE.set(definition, executor);
|
|
69
|
+
return executor;
|
|
70
|
+
}
|
|
71
|
+
export function createStyleExecutionEntry(name, definition) {
|
|
72
|
+
return {
|
|
73
|
+
get slotKeys() {
|
|
74
|
+
return getOrCreateExecutor(name, definition).slotKeys;
|
|
75
|
+
},
|
|
76
|
+
resolveAll(props) {
|
|
77
|
+
return getOrCreateExecutor(name, definition).resolveAll(props);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export function createStyleExecutionRegistry(definitions) {
|
|
82
|
+
const entries = {};
|
|
83
|
+
for (const [name, definition] of Object.entries(definitions)) {
|
|
84
|
+
Object.defineProperty(entries, name, {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
configurable: false,
|
|
87
|
+
value: createStyleExecutionEntry(name, definition),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return entries;
|
|
91
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
export type StyleClassValue = string | Ref<string>;
|
|
3
|
+
export type StyleClassList = string[] | ReadonlyArray<StyleClassValue>;
|
|
4
|
+
export type StyleResolverReturn = StyleClassValue | StyleClassList;
|
|
5
|
+
export type OneArgStyleResolver<TStyle> = (style: TStyle) => StyleResolverReturn;
|
|
6
|
+
export type StyleResolverLike<TStyle> = OneArgStyleResolver<TStyle>;
|
|
7
|
+
export type StyleResolvers<TStyle> = Record<string, StyleResolverLike<TStyle>>;
|
|
8
|
+
export type StyleSetupResolvers = Record<string, StyleResolverLike<any>>;
|
|
9
|
+
export type SetupStyleDefinition<TResolvers extends StyleSetupResolvers = StyleSetupResolvers> = {
|
|
10
|
+
setup: () => TResolvers;
|
|
11
|
+
__stylePropsBrand: unknown;
|
|
12
|
+
};
|
|
13
|
+
export type InferStyleProps<T> = T extends {
|
|
14
|
+
__stylePropsBrand?: infer P;
|
|
15
|
+
} ? P : never;
|
|
16
|
+
export declare function defineStyle<TResolvers extends StyleSetupResolvers>(setup: () => TResolvers): SetupStyleDefinition<TResolvers>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getCurrentInstance, isRef, ref, toRef } from 'vue';
|
|
2
|
+
const scopedLayoutRefStack = [];
|
|
3
|
+
export function withScopedAkLayoutRef(layoutRef, run) {
|
|
4
|
+
scopedLayoutRefStack.push(layoutRef);
|
|
5
|
+
try {
|
|
6
|
+
return run();
|
|
7
|
+
}
|
|
8
|
+
finally {
|
|
9
|
+
const current = scopedLayoutRefStack.pop();
|
|
10
|
+
if (current !== layoutRef) {
|
|
11
|
+
throw new Error('AK scoped layout ref stack became unbalanced.');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function resolveLayoutRef(layoutInput) {
|
|
16
|
+
if (isRef(layoutInput)) {
|
|
17
|
+
return layoutInput;
|
|
18
|
+
}
|
|
19
|
+
if (layoutInput === undefined) {
|
|
20
|
+
const scoped = scopedLayoutRefStack[scopedLayoutRefStack.length - 1];
|
|
21
|
+
if (scoped) {
|
|
22
|
+
return scoped;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const instance = getCurrentInstance();
|
|
26
|
+
if (!instance) {
|
|
27
|
+
throw new Error('useAk() must be called inside setup()');
|
|
28
|
+
}
|
|
29
|
+
if (layoutInput === undefined) {
|
|
30
|
+
return toRef(instance.props, 'layout');
|
|
31
|
+
}
|
|
32
|
+
if (typeof layoutInput === 'object' && layoutInput !== null && 'layout' in layoutInput) {
|
|
33
|
+
return toRef(layoutInput, 'layout');
|
|
34
|
+
}
|
|
35
|
+
return ref(layoutInput);
|
|
36
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const AUTHORING_EFFECT_KINDS: readonly ["element", "text", "text-style", "title-style", "text-alignment", "divide", "divide-x", "divide-y", "margin", "margin-top", "margin-right", "margin-bottom", "margin-left", "margin-x", "margin-y", "padding", "padding-top", "padding-right", "padding-bottom", "padding-left", "padding-x", "padding-y", "gap", "gap-x", "gap-y", "background", "color", "border", "border-top", "border-right", "border-bottom", "border-left", "ring", "shadow", "radius", "radius-top", "radius-right", "radius-bottom", "radius-left", "width", "height", "min-width", "min-height", "max-width", "max-height", "alignment"];
|
|
2
|
+
export type AuthoringEffectKind = (typeof AUTHORING_EFFECT_KINDS)[number];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const AUTHORING_EFFECT_KINDS = [
|
|
2
|
+
'element',
|
|
3
|
+
'text',
|
|
4
|
+
'text-style',
|
|
5
|
+
'title-style',
|
|
6
|
+
'text-alignment',
|
|
7
|
+
'divide',
|
|
8
|
+
'divide-x',
|
|
9
|
+
'divide-y',
|
|
10
|
+
'margin',
|
|
11
|
+
'margin-top',
|
|
12
|
+
'margin-right',
|
|
13
|
+
'margin-bottom',
|
|
14
|
+
'margin-left',
|
|
15
|
+
'margin-x',
|
|
16
|
+
'margin-y',
|
|
17
|
+
'padding',
|
|
18
|
+
'padding-top',
|
|
19
|
+
'padding-right',
|
|
20
|
+
'padding-bottom',
|
|
21
|
+
'padding-left',
|
|
22
|
+
'padding-x',
|
|
23
|
+
'padding-y',
|
|
24
|
+
'gap',
|
|
25
|
+
'gap-x',
|
|
26
|
+
'gap-y',
|
|
27
|
+
'background',
|
|
28
|
+
'color',
|
|
29
|
+
'border',
|
|
30
|
+
'border-top',
|
|
31
|
+
'border-right',
|
|
32
|
+
'border-bottom',
|
|
33
|
+
'border-left',
|
|
34
|
+
'ring',
|
|
35
|
+
'shadow',
|
|
36
|
+
'radius',
|
|
37
|
+
'radius-top',
|
|
38
|
+
'radius-right',
|
|
39
|
+
'radius-bottom',
|
|
40
|
+
'radius-left',
|
|
41
|
+
'width',
|
|
42
|
+
'height',
|
|
43
|
+
'min-width',
|
|
44
|
+
'min-height',
|
|
45
|
+
'max-width',
|
|
46
|
+
'max-height',
|
|
47
|
+
'alignment',
|
|
48
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './authoringEffectKinds.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './authoringEffectKinds.js';
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { CMSFieldPreview, CMSSchema } from './CMSSchemaTypes.js';
|
|
2
|
+
export interface PresenterGroup {
|
|
3
|
+
name: string;
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
export type PresenterIcon = {
|
|
7
|
+
kind: 'emoji';
|
|
8
|
+
value: string;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'lucide';
|
|
11
|
+
name: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'url';
|
|
14
|
+
src: string;
|
|
15
|
+
alt?: string;
|
|
16
|
+
};
|
|
17
|
+
export interface PresenterMeta {
|
|
18
|
+
title: string;
|
|
19
|
+
subtitle?: string;
|
|
20
|
+
icon?: PresenterIcon;
|
|
21
|
+
previewRepresentative?: PreviewRepresentitive;
|
|
22
|
+
groups?: PresenterGroup[];
|
|
23
|
+
}
|
|
24
|
+
export type PresenterInlineFieldPatch = {
|
|
25
|
+
label?: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
hidden?: boolean;
|
|
28
|
+
readOnly?: boolean;
|
|
29
|
+
group?: string;
|
|
30
|
+
preview?: Partial<CMSFieldPreview>;
|
|
31
|
+
required?: boolean;
|
|
32
|
+
setDefaultValue?: boolean;
|
|
33
|
+
defaultValue?: unknown;
|
|
34
|
+
hardCoded?: boolean;
|
|
35
|
+
};
|
|
36
|
+
export type PresenterWrapperPatch = {
|
|
37
|
+
label?: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
group?: string;
|
|
40
|
+
collapsible?: boolean;
|
|
41
|
+
collapsed?: boolean;
|
|
42
|
+
};
|
|
43
|
+
export type PresenterFieldOverride = {
|
|
44
|
+
kind: 'omit';
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'patch';
|
|
47
|
+
patch: PresenterInlineFieldPatch;
|
|
48
|
+
};
|
|
49
|
+
export interface PresenterBlockInstance {
|
|
50
|
+
kind: 'block';
|
|
51
|
+
instanceId: string;
|
|
52
|
+
schemaRef: string;
|
|
53
|
+
displayMode?: 'block' | 'inline';
|
|
54
|
+
wrapper?: PresenterWrapperPatch;
|
|
55
|
+
overrides?: Record<string, PresenterFieldOverride>;
|
|
56
|
+
}
|
|
57
|
+
export interface PresenterModuleInstance {
|
|
58
|
+
kind: 'module';
|
|
59
|
+
instanceId: string;
|
|
60
|
+
moduleRef: {
|
|
61
|
+
subType: 'layout' | 'global' | 'collectionItem';
|
|
62
|
+
slug: string;
|
|
63
|
+
};
|
|
64
|
+
wrapper?: PresenterWrapperPatch;
|
|
65
|
+
}
|
|
66
|
+
export type PresenterInstance = PresenterBlockInstance | PresenterModuleInstance;
|
|
67
|
+
export type MetaPreviewToken = 'meta:title' | 'meta:subtitle';
|
|
68
|
+
export type PreviewRepresentitive = {
|
|
69
|
+
titleInstanceId?: string | MetaPreviewToken;
|
|
70
|
+
subtitleInstanceId?: string | MetaPreviewToken;
|
|
71
|
+
mediaInstanceId?: string;
|
|
72
|
+
};
|
|
73
|
+
export interface PresenterModuleRoot {
|
|
74
|
+
kind: 'module-root';
|
|
75
|
+
instanceId: string;
|
|
76
|
+
moduleRef: {
|
|
77
|
+
subType: 'layout' | 'global' | 'collectionItem';
|
|
78
|
+
slug: string;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export interface PresenterPageRoot {
|
|
82
|
+
kind: 'page-root';
|
|
83
|
+
instanceId: string;
|
|
84
|
+
}
|
|
85
|
+
export type PresenterDoc = {
|
|
86
|
+
scope: 'page';
|
|
87
|
+
name: string;
|
|
88
|
+
meta: PresenterMeta;
|
|
89
|
+
root?: PresenterPageRoot;
|
|
90
|
+
blocks: PresenterInstance[];
|
|
91
|
+
__deprecated?: Record<string, unknown>;
|
|
92
|
+
} | {
|
|
93
|
+
scope: 'module';
|
|
94
|
+
name: string;
|
|
95
|
+
meta: PresenterMeta;
|
|
96
|
+
root: PresenterModuleRoot;
|
|
97
|
+
blocks: PresenterInstance[];
|
|
98
|
+
__deprecated?: Record<string, unknown>;
|
|
99
|
+
};
|
|
100
|
+
export interface CMSSchemaRegistry {
|
|
101
|
+
get(schemaName: string): CMSSchema | undefined;
|
|
102
|
+
}
|
|
103
|
+
export declare function isPagePresenter(doc: PresenterDoc): doc is Extract<PresenterDoc, {
|
|
104
|
+
scope: 'page';
|
|
105
|
+
}>;
|
|
106
|
+
export declare function isModulePresenter(doc: PresenterDoc): doc is Extract<PresenterDoc, {
|
|
107
|
+
scope: 'module';
|
|
108
|
+
}>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type CMSSchema, type CMSSchemaField, type CMSSchemaMeta, type TextCMSField, type NumberCMSField, type CheckboxCMSField, type SelectCMSField, type GroupCMSField, type ArrayCMSField, type TextArrayCMSField, type NumberArrayCMSField, type ImageCMSField, type IconCMSField, type RichTextField } from './CMSSchemaTypes.js';
|
|
2
|
+
export type InferCmsFields<T> = T extends {
|
|
3
|
+
__fieldsBrand?: infer F;
|
|
4
|
+
} ? F : never;
|
|
5
|
+
export declare const cms: {
|
|
6
|
+
text: (label: string, init?: Partial<TextCMSField>) => TextCMSField;
|
|
7
|
+
textarea: (label: string, init?: Partial<TextCMSField>) => TextCMSField;
|
|
8
|
+
richtext: (label: string, init?: Partial<RichTextField>) => RichTextField;
|
|
9
|
+
number: (label: string, init?: Partial<NumberCMSField>) => NumberCMSField;
|
|
10
|
+
checkbox: (label: string, init?: Partial<CheckboxCMSField>) => CheckboxCMSField;
|
|
11
|
+
select: (label: string, options: SelectCMSField["options"], init?: Partial<SelectCMSField>) => SelectCMSField;
|
|
12
|
+
group: (label: string, fields: Record<string, CMSSchemaField>, init?: Partial<GroupCMSField>) => GroupCMSField;
|
|
13
|
+
array: (label: string, itemFields: Record<string, CMSSchemaField>, init?: Partial<ArrayCMSField>) => ArrayCMSField;
|
|
14
|
+
textArray: (label: string, init?: Partial<TextArrayCMSField>) => TextArrayCMSField;
|
|
15
|
+
numberArray: (label: string, init?: Partial<NumberArrayCMSField>) => NumberArrayCMSField;
|
|
16
|
+
image: (label: string, init?: Partial<ImageCMSField>) => ImageCMSField;
|
|
17
|
+
icon: (label: string, init?: Partial<IconCMSField>) => IconCMSField;
|
|
18
|
+
};
|
|
19
|
+
export declare function defineCMSSchema<const F extends Record<string, CMSSchemaField>>(config: {
|
|
20
|
+
name: string;
|
|
21
|
+
meta: CMSSchemaMeta;
|
|
22
|
+
fields: F & Record<string, CMSSchemaField>;
|
|
23
|
+
__deprecated?: Record<string, CMSSchemaField>;
|
|
24
|
+
omit?: boolean;
|
|
25
|
+
}): CMSSchema & {
|
|
26
|
+
__fieldsBrand: F;
|
|
27
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {} from './CMSSchemaTypes.js';
|
|
2
|
+
function validateField(key, field, issues, path = key) {
|
|
3
|
+
if ('omit' in field && field.omit === true)
|
|
4
|
+
return;
|
|
5
|
+
switch (field.type) {
|
|
6
|
+
case 'select': {
|
|
7
|
+
if (!field.options || field.options.length === 0) {
|
|
8
|
+
issues.push(`"${path}": select requires non-empty options.`);
|
|
9
|
+
}
|
|
10
|
+
break;
|
|
11
|
+
}
|
|
12
|
+
case 'group': {
|
|
13
|
+
if (!field.fields || Object.keys(field.fields).length === 0) {
|
|
14
|
+
issues.push(`"${path}": group requires nested fields.`);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
for (const sub of Object.keys(field.fields)) {
|
|
18
|
+
validateField(sub, field.fields[sub], issues, `${path}.${sub}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
case 'array': {
|
|
24
|
+
if (!field.fields || Object.keys(field.fields).length === 0) {
|
|
25
|
+
issues.push(`"${path}": array (of objects) requires nested fields (the item shape).`);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
for (const sub of Object.keys(field.fields)) {
|
|
29
|
+
validateField(sub, field.fields[sub], issues, `${path}[].${sub}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
default:
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function validateSchema(_name, fields) {
|
|
39
|
+
const issues = [];
|
|
40
|
+
for (const key of Object.keys(fields)) {
|
|
41
|
+
validateField(key, fields[key], issues, key);
|
|
42
|
+
}
|
|
43
|
+
return issues;
|
|
44
|
+
}
|
|
45
|
+
export const cms = {
|
|
46
|
+
text: (label, init) => ({
|
|
47
|
+
type: 'text',
|
|
48
|
+
label,
|
|
49
|
+
input: init?.input ?? 'text',
|
|
50
|
+
...init,
|
|
51
|
+
}),
|
|
52
|
+
textarea: (label, init) => cms.text(label, { ...init, input: 'textarea' }),
|
|
53
|
+
richtext: (label, init) => ({
|
|
54
|
+
type: 'richtext',
|
|
55
|
+
label,
|
|
56
|
+
...init,
|
|
57
|
+
}),
|
|
58
|
+
number: (label, init) => ({ type: 'number', label, ...init }),
|
|
59
|
+
checkbox: (label, init) => ({ type: 'checkbox', label, ...init }),
|
|
60
|
+
select: (label, options, init) => ({
|
|
61
|
+
type: 'select',
|
|
62
|
+
label,
|
|
63
|
+
options,
|
|
64
|
+
display: init?.display ?? 'select',
|
|
65
|
+
...init,
|
|
66
|
+
}),
|
|
67
|
+
group: (label, fields, init) => ({ type: 'group', label, fields, ...init }),
|
|
68
|
+
array: (label, itemFields, init) => ({
|
|
69
|
+
type: 'array',
|
|
70
|
+
label,
|
|
71
|
+
fields: itemFields,
|
|
72
|
+
...init,
|
|
73
|
+
}),
|
|
74
|
+
textArray: (label, init) => ({ type: 'text-array', label, ...init }),
|
|
75
|
+
numberArray: (label, init) => ({ type: 'number-array', label, ...init }),
|
|
76
|
+
image: (label, init) => ({ type: 'image', label, ...init }),
|
|
77
|
+
icon: (label, init) => ({ type: 'icon', label, ...init }),
|
|
78
|
+
};
|
|
79
|
+
export function defineCMSSchema(config) {
|
|
80
|
+
const { name, meta, fields, __deprecated, omit } = config;
|
|
81
|
+
const issues = validateSchema(name, fields);
|
|
82
|
+
if (issues.length) {
|
|
83
|
+
console.warn(`[CMSSchema:${name}] Validation warnings:\n- ${issues.join('\n- ')}`);
|
|
84
|
+
}
|
|
85
|
+
const schema = { name, meta, fields, ...(omit ? { omit: true } : {}) };
|
|
86
|
+
if (__deprecated)
|
|
87
|
+
schema.__deprecated = __deprecated;
|
|
88
|
+
return Object.assign(schema, { __fieldsBrand: null });
|
|
89
|
+
}
|