@brickflow/ui 0.0.33 → 0.0.35
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/dist/module.json +1 -1
- package/dist/module.mjs +291 -30
- package/dist/runtime/components/Button/index.d.vue.ts +31 -25
- package/dist/runtime/components/Button/index.vue +10 -62
- package/dist/runtime/components/Button/index.vue.d.ts +31 -25
- package/dist/runtime/components/Button/variants.demo.vue +25 -181
- package/dist/runtime/config.d.ts +24 -1
- package/dist/runtime/tailwind.d.ts +37 -5
- package/dist/runtime/tailwind.js +47 -1
- package/package.json +1 -1
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, resolvePath, addTemplate, updateTemplates, addImportsDir, addComponentsDir } from '@nuxt/kit';
|
|
1
|
+
import { defineNuxtModule, createResolver, resolvePath, addTypeTemplate, addTemplate, updateTemplates, addImportsDir, addComponentsDir } from '@nuxt/kit';
|
|
2
2
|
import tailwindcss from '@tailwindcss/vite';
|
|
3
3
|
import { createJiti } from 'jiti';
|
|
4
4
|
import { readdir, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
5
|
-
import { join,
|
|
6
|
-
import {
|
|
5
|
+
import { join, basename, extname, dirname, resolve, relative } from 'node:path';
|
|
6
|
+
import { isBrickflowUiStyleReference, getBrickflowUiStyleReferencePath, defineBrickflowUi } from '../dist/runtime/tailwind.js';
|
|
7
7
|
import { generateFonts, FontAssetType, OtherAssetType } from 'fantasticon';
|
|
8
8
|
|
|
9
9
|
const ICON_FILE_PATTERN = /\.svg$/i;
|
|
@@ -85,6 +85,8 @@ ${CUSTOM_DARK_VARIANT}${code.slice(index)}`,
|
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
const UI_STYLE_PATTERN = /\bUI_STYLE((?:\.[A-Za-z_$][\w$]*)+)/g;
|
|
88
|
+
const UI_CONFIG_PATTERN = /\bUI_CONFIG((?:\.[A-Za-z_$][\w$]*)+)/g;
|
|
89
|
+
const UI_CONFIG_MACRO = "defineUiConfig";
|
|
88
90
|
const SCRIPT_FILE_PATTERN = /\.(?:[cm]?[jt]sx?|vue)(?:\?.*)?$/;
|
|
89
91
|
const TYPE_INDENT = " ";
|
|
90
92
|
const refreshUiStyleModules = (server) => {
|
|
@@ -109,7 +111,7 @@ const resolveUiStyleConfigPath = (id, path) => {
|
|
|
109
111
|
return path;
|
|
110
112
|
}
|
|
111
113
|
const componentName = basename(cleanId, extname(cleanId));
|
|
112
|
-
const configName = componentName === "index" ? basename(dirname(cleanId)) : componentName;
|
|
114
|
+
const configName = componentName === "index" || componentName.endsWith(".demo") ? basename(dirname(cleanId)) : componentName;
|
|
113
115
|
return [toCamelCase(configName), ...path];
|
|
114
116
|
};
|
|
115
117
|
const resolveStyleValue = (styles, id, path) => {
|
|
@@ -123,6 +125,73 @@ const resolveStyleValue = (styles, id, path) => {
|
|
|
123
125
|
}
|
|
124
126
|
return configPathValue ?? globalValue;
|
|
125
127
|
};
|
|
128
|
+
const resolveUiConfigValue = (config, id, path) => {
|
|
129
|
+
const configPathValue = readPath(config, resolveUiStyleConfigPath(id, path));
|
|
130
|
+
return configPathValue ?? readPath(config, path);
|
|
131
|
+
};
|
|
132
|
+
const resolveUiConfigStyleReferences = (value, styles, id) => {
|
|
133
|
+
if (isBrickflowUiStyleReference(value)) {
|
|
134
|
+
const stylePath = getBrickflowUiStyleReferencePath(value);
|
|
135
|
+
const styleValue = resolveStyleValue(styles, id, [...stylePath]);
|
|
136
|
+
if (typeof styleValue !== "string") {
|
|
137
|
+
throw new TypeError(`UI_STYLE.${stylePath.join(".")} does not resolve to a string in ${id}.`);
|
|
138
|
+
}
|
|
139
|
+
return styleValue;
|
|
140
|
+
}
|
|
141
|
+
if (typeof value === "string") {
|
|
142
|
+
return value;
|
|
143
|
+
}
|
|
144
|
+
return Object.fromEntries(
|
|
145
|
+
Object.entries(value).map(([key, childValue]) => [
|
|
146
|
+
key,
|
|
147
|
+
resolveUiConfigStyleReferences(childValue, styles, id)
|
|
148
|
+
])
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
const replaceUiConfigMacros = (code, config, styles, id, error) => {
|
|
152
|
+
let result = "";
|
|
153
|
+
let cursor = 0;
|
|
154
|
+
while (cursor < code.length) {
|
|
155
|
+
const start = code.indexOf(UI_CONFIG_MACRO, cursor);
|
|
156
|
+
if (start === -1) {
|
|
157
|
+
return result + code.slice(cursor);
|
|
158
|
+
}
|
|
159
|
+
const genericStart = start + UI_CONFIG_MACRO.length;
|
|
160
|
+
let callStart = genericStart;
|
|
161
|
+
if (code[genericStart] === "<") {
|
|
162
|
+
let depth = 0;
|
|
163
|
+
let index = genericStart;
|
|
164
|
+
for (; index < code.length; index += 1) {
|
|
165
|
+
if (code[index] === "<") {
|
|
166
|
+
depth += 1;
|
|
167
|
+
}
|
|
168
|
+
if (code[index] === ">") {
|
|
169
|
+
depth -= 1;
|
|
170
|
+
}
|
|
171
|
+
if (depth === 0) {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
callStart = index + 1;
|
|
176
|
+
}
|
|
177
|
+
while (/\s/u.test(code[callStart] ?? "")) {
|
|
178
|
+
callStart += 1;
|
|
179
|
+
}
|
|
180
|
+
if (code.slice(callStart, callStart + 2) !== "()") {
|
|
181
|
+
result += code.slice(cursor, callStart);
|
|
182
|
+
cursor = callStart;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const value = resolveUiConfigValue(config, id, []);
|
|
186
|
+
if (value === void 0) {
|
|
187
|
+
error(`defineUiConfig() in ${id} has no matching uiConfig entry.`);
|
|
188
|
+
}
|
|
189
|
+
result += code.slice(cursor, start);
|
|
190
|
+
result += JSON.stringify(resolveUiConfigStyleReferences(value, styles, id));
|
|
191
|
+
cursor = callStart + 2;
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
};
|
|
126
195
|
const createUiStylePathTree = () => ({
|
|
127
196
|
children: /* @__PURE__ */ new Map()
|
|
128
197
|
});
|
|
@@ -134,16 +203,18 @@ const addPathToTree = (tree, path) => {
|
|
|
134
203
|
currentTree = childTree;
|
|
135
204
|
}
|
|
136
205
|
};
|
|
137
|
-
const renderTypeTree = (tree, level, objectType) => {
|
|
206
|
+
const renderTypeTree = (tree, level, objectType, leafType = "string", path = []) => {
|
|
138
207
|
const lines = [];
|
|
139
208
|
const indent = TYPE_INDENT.repeat(level);
|
|
140
209
|
for (const [key, childTree] of [...tree.children.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
141
210
|
if (childTree.children.size === 0) {
|
|
142
|
-
|
|
211
|
+
const childPath = [...path, key];
|
|
212
|
+
const childLeafType = typeof leafType === "function" ? leafType(childPath) : leafType;
|
|
213
|
+
lines.push(`${indent}readonly ${key}: ${childLeafType}`);
|
|
143
214
|
continue;
|
|
144
215
|
}
|
|
145
216
|
lines.push(objectType ? `${indent}readonly ${key}: ${objectType} & {` : `${indent}readonly ${key}: {`);
|
|
146
|
-
lines.push(...renderTypeTree(childTree, level + 1, objectType));
|
|
217
|
+
lines.push(...renderTypeTree(childTree, level + 1, objectType, leafType, [...path, key]));
|
|
147
218
|
lines.push(`${indent}}`);
|
|
148
219
|
}
|
|
149
220
|
return lines;
|
|
@@ -156,18 +227,111 @@ const collectUiStylePathsFromCode = (code) => {
|
|
|
156
227
|
return paths.filter((path) => path.length > 0);
|
|
157
228
|
};
|
|
158
229
|
const collectUiStyleConfigPathsFromCode = (code, id) => collectUiStylePathsFromCode(code).map((path) => resolveUiStyleConfigPath(id, path));
|
|
159
|
-
const
|
|
230
|
+
const collectUiConfigValuePaths = (value, prefix) => {
|
|
231
|
+
if (typeof value === "string" || isBrickflowUiStyleReference(value)) {
|
|
232
|
+
return [prefix];
|
|
233
|
+
}
|
|
234
|
+
return Object.entries(value).flatMap(
|
|
235
|
+
([key, childValue]) => collectUiConfigValuePaths(childValue, [...prefix, key])
|
|
236
|
+
);
|
|
237
|
+
};
|
|
238
|
+
const collectUiConfigPathsFromCode = (code, id, config) => {
|
|
239
|
+
const paths = [];
|
|
240
|
+
for (const match of code.matchAll(UI_CONFIG_PATTERN)) {
|
|
241
|
+
const path = match[1]?.slice(1).split(".") ?? [];
|
|
242
|
+
const value = resolveUiConfigValue(config, id, path);
|
|
243
|
+
paths.push(...value === void 0 ? [path] : collectUiConfigValuePaths(value, path));
|
|
244
|
+
}
|
|
245
|
+
return paths.filter((path) => path.length > 0);
|
|
246
|
+
};
|
|
247
|
+
const collectUiConfigComponentPathsFromCode = (code, id, config) => {
|
|
248
|
+
const paths = [];
|
|
249
|
+
for (const match of code.matchAll(UI_CONFIG_PATTERN)) {
|
|
250
|
+
const path = match[1]?.slice(1).split(".") ?? [];
|
|
251
|
+
const componentPath = resolveUiStyleConfigPath(id, path);
|
|
252
|
+
const value = readPath(config, componentPath);
|
|
253
|
+
paths.push(
|
|
254
|
+
...value === void 0 ? [componentPath] : collectUiConfigValuePaths(value, componentPath)
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
if (code.includes(UI_CONFIG_MACRO)) {
|
|
258
|
+
const componentPath = resolveUiStyleConfigPath(id, []);
|
|
259
|
+
const value = readPath(config, componentPath);
|
|
260
|
+
if (value !== void 0) {
|
|
261
|
+
paths.push(...collectUiConfigValuePaths(value, componentPath));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return paths.filter((path) => path.length > 0);
|
|
265
|
+
};
|
|
266
|
+
const collectUiConfigSchemaEntriesFromCode = (code, id) => {
|
|
267
|
+
const entries = [];
|
|
268
|
+
let cursor = 0;
|
|
269
|
+
while (cursor < code.length) {
|
|
270
|
+
const start = code.indexOf(UI_CONFIG_MACRO, cursor);
|
|
271
|
+
if (start === -1) {
|
|
272
|
+
return entries;
|
|
273
|
+
}
|
|
274
|
+
const genericStart = start + UI_CONFIG_MACRO.length;
|
|
275
|
+
if (code[genericStart] !== "<") {
|
|
276
|
+
cursor = genericStart;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
let depth = 0;
|
|
280
|
+
let genericEnd = genericStart;
|
|
281
|
+
for (; genericEnd < code.length; genericEnd += 1) {
|
|
282
|
+
if (code[genericEnd] === "<") {
|
|
283
|
+
depth += 1;
|
|
284
|
+
}
|
|
285
|
+
if (code[genericEnd] === ">") {
|
|
286
|
+
depth -= 1;
|
|
287
|
+
}
|
|
288
|
+
if (depth === 0) {
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
let callStart = genericEnd + 1;
|
|
293
|
+
while (/\s/u.test(code[callStart] ?? "")) {
|
|
294
|
+
callStart += 1;
|
|
295
|
+
}
|
|
296
|
+
if (code.slice(callStart, callStart + 2) !== "()") {
|
|
297
|
+
cursor = callStart;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
const schema = code.slice(genericStart + 1, genericEnd).trim();
|
|
301
|
+
const path = resolveUiStyleConfigPath(id, []);
|
|
302
|
+
if (schema.startsWith("{") && path.length > 0) {
|
|
303
|
+
entries.push({ path, schema });
|
|
304
|
+
}
|
|
305
|
+
cursor = callStart + 2;
|
|
306
|
+
}
|
|
307
|
+
return entries;
|
|
308
|
+
};
|
|
309
|
+
const collectUiConfigStyleReferencePathsFromValue = (value, componentPath) => {
|
|
310
|
+
if (isBrickflowUiStyleReference(value)) {
|
|
311
|
+
return [[...componentPath, ...getBrickflowUiStyleReferencePath(value)]];
|
|
312
|
+
}
|
|
313
|
+
if (typeof value === "string") {
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
return Object.values(value).flatMap(
|
|
317
|
+
(childValue) => collectUiConfigStyleReferencePathsFromValue(childValue, componentPath)
|
|
318
|
+
);
|
|
319
|
+
};
|
|
320
|
+
const collectUiConfigStyleReferencePaths = (config) => Object.entries(config).flatMap(([key, value]) => collectUiConfigStyleReferencePathsFromValue(value, [key]));
|
|
321
|
+
const renderInterfaceDeclaration = (name, paths, objectType, leafType = "string") => {
|
|
160
322
|
const tree = createUiStylePathTree();
|
|
161
323
|
for (const path of paths) {
|
|
162
324
|
addPathToTree(tree, path);
|
|
163
325
|
}
|
|
164
|
-
return [` interface ${name} {`, ...renderTypeTree(tree, 2, objectType), " }"];
|
|
326
|
+
return [` interface ${name} {`, ...renderTypeTree(tree, 2, objectType, leafType), " }"];
|
|
165
327
|
};
|
|
166
328
|
const createUiStyleTypeDeclaration = (options) => {
|
|
167
329
|
return [
|
|
168
330
|
"declare global {",
|
|
169
331
|
...renderInterfaceDeclaration("BrickflowUiConfigStylePaths", options.configPaths),
|
|
170
332
|
"",
|
|
333
|
+
...renderInterfaceDeclaration("BrickflowUiConfigPaths", options.uiConfigPaths),
|
|
334
|
+
"",
|
|
171
335
|
...renderInterfaceDeclaration("BrickflowUiStylePaths", options.paths, "BrickflowUiStyleValue"),
|
|
172
336
|
"}",
|
|
173
337
|
"",
|
|
@@ -175,6 +339,39 @@ const createUiStyleTypeDeclaration = (options) => {
|
|
|
175
339
|
""
|
|
176
340
|
].join("\n");
|
|
177
341
|
};
|
|
342
|
+
const createUiConfigLiteralTypeDeclaration = (paths, config) => [
|
|
343
|
+
"declare global {",
|
|
344
|
+
...renderInterfaceDeclaration("BrickflowUiConfigLiteralPaths", paths, void 0, (path) => {
|
|
345
|
+
const value = config ? readPath(config, path) : void 0;
|
|
346
|
+
return typeof value === "string" ? toStringLiteral(value) : "string";
|
|
347
|
+
}),
|
|
348
|
+
"}",
|
|
349
|
+
"",
|
|
350
|
+
"export {}",
|
|
351
|
+
""
|
|
352
|
+
].join("\n");
|
|
353
|
+
const createUiConfigSchemaTypeDeclaration = (entries) => {
|
|
354
|
+
const schemasByPath = /* @__PURE__ */ new Map();
|
|
355
|
+
for (const { path, schema } of entries) {
|
|
356
|
+
const pathKey = path.join(".");
|
|
357
|
+
const schemas = schemasByPath.get(pathKey) ?? [];
|
|
358
|
+
schemas.push(schema);
|
|
359
|
+
schemasByPath.set(pathKey, schemas);
|
|
360
|
+
}
|
|
361
|
+
return [
|
|
362
|
+
"declare global {",
|
|
363
|
+
" interface BrickflowUiConfigSchema {",
|
|
364
|
+
...[...schemasByPath.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([path, schemas]) => {
|
|
365
|
+
const [componentName] = path.split(".");
|
|
366
|
+
return ` readonly ${componentName}: ${schemas.map((schema) => `(${schema})`).join(" & ")}`;
|
|
367
|
+
}),
|
|
368
|
+
" }",
|
|
369
|
+
"}",
|
|
370
|
+
"",
|
|
371
|
+
"export {}",
|
|
372
|
+
""
|
|
373
|
+
].join("\n");
|
|
374
|
+
};
|
|
178
375
|
const brickflowUiStylePlugin = (options) => ({
|
|
179
376
|
buildStart: {
|
|
180
377
|
handler() {
|
|
@@ -197,13 +394,42 @@ const brickflowUiStylePlugin = (options) => ({
|
|
|
197
394
|
},
|
|
198
395
|
name: "brickflow-ui-style",
|
|
199
396
|
async transform(code, id) {
|
|
200
|
-
|
|
397
|
+
const cleanId = id.split("?")[0] ?? id;
|
|
398
|
+
const isVirtualModule = cleanId.startsWith("\0") || cleanId.startsWith("virtual:");
|
|
399
|
+
const isVueSubmodule = cleanId.endsWith(".vue") && id.includes("?vue");
|
|
400
|
+
if (isVirtualModule || isVueSubmodule && !code.includes(UI_CONFIG_MACRO) || !SCRIPT_FILE_PATTERN.test(id) || !code.includes("UI_STYLE.") && !code.includes("UI_CONFIG.") && !code.includes(UI_CONFIG_MACRO)) {
|
|
201
401
|
return null;
|
|
202
402
|
}
|
|
203
403
|
this.addWatchFile?.(options.configPath);
|
|
204
404
|
const styles = await options.getStyles();
|
|
405
|
+
const config = await options.getConfig();
|
|
406
|
+
const isConfigFile = normalizePath(cleanId) === normalizePath(options.configPath);
|
|
407
|
+
const hasUiConfigMacro = cleanId.endsWith(".vue") && code.includes(UI_CONFIG_MACRO);
|
|
205
408
|
let changed = false;
|
|
206
|
-
const
|
|
409
|
+
const codeWithUiConfigMacros = hasUiConfigMacro ? replaceUiConfigMacros(code, config, styles, id, this.error.bind(this)) : code;
|
|
410
|
+
if (codeWithUiConfigMacros !== code) {
|
|
411
|
+
changed = true;
|
|
412
|
+
}
|
|
413
|
+
const transformedCode = codeWithUiConfigMacros.replace(UI_CONFIG_PATTERN, (match, rawPath) => {
|
|
414
|
+
if (hasUiConfigMacro) {
|
|
415
|
+
return match;
|
|
416
|
+
}
|
|
417
|
+
const path = rawPath.slice(1).split(".");
|
|
418
|
+
const value = resolveUiConfigValue(config, id, path);
|
|
419
|
+
changed = true;
|
|
420
|
+
if (value === void 0) {
|
|
421
|
+
return "undefined";
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
const resolvedValue = resolveUiConfigStyleReferences(value, styles, id);
|
|
425
|
+
return typeof resolvedValue === "string" ? toStringLiteral(resolvedValue) : JSON.stringify(resolvedValue);
|
|
426
|
+
} catch (error) {
|
|
427
|
+
this.error(error instanceof Error ? error.message : String(error));
|
|
428
|
+
}
|
|
429
|
+
}).replace(UI_STYLE_PATTERN, (match, rawPath) => {
|
|
430
|
+
if (isConfigFile) {
|
|
431
|
+
return match;
|
|
432
|
+
}
|
|
207
433
|
const path = rawPath.slice(1).split(".");
|
|
208
434
|
const value = resolveStyleValue(styles, id, path);
|
|
209
435
|
if (typeof value === "string") {
|
|
@@ -453,14 +679,13 @@ const module$1 = defineNuxtModule({
|
|
|
453
679
|
);
|
|
454
680
|
};
|
|
455
681
|
const loadUiConfig = async () => {
|
|
456
|
-
const validateConfig =
|
|
682
|
+
const validateConfig = defineBrickflowUi;
|
|
457
683
|
return validateConfig(
|
|
458
684
|
await loadConfig.import(resolvedConfigPath).catch(() => ({}))
|
|
459
685
|
);
|
|
460
686
|
};
|
|
461
687
|
await loadUiConfig();
|
|
462
|
-
const
|
|
463
|
-
const generateUiStyleTypes = async () => {
|
|
688
|
+
const getUiStyleTypeContents = async () => {
|
|
464
689
|
const files = await scanUiStyleFiles(runtimePath);
|
|
465
690
|
const fileContents = await Promise.all(
|
|
466
691
|
files.map(async (file) => ({
|
|
@@ -468,19 +693,55 @@ const module$1 = defineNuxtModule({
|
|
|
468
693
|
file
|
|
469
694
|
}))
|
|
470
695
|
);
|
|
471
|
-
const
|
|
696
|
+
const uiConfig = (await loadUiConfig()).uiConfig;
|
|
697
|
+
const uiConfigStyleReferencePaths = collectUiConfigStyleReferencePaths(uiConfig);
|
|
698
|
+
const paths = [
|
|
699
|
+
...fileContents.flatMap(({ content }) => collectUiStylePathsFromCode(content)),
|
|
700
|
+
...uiConfigStyleReferencePaths.map((path) => path.slice(1))
|
|
701
|
+
];
|
|
472
702
|
const configPaths = fileContents.flatMap(
|
|
473
703
|
({ content, file }) => collectUiStyleConfigPathsFromCode(content, file)
|
|
474
704
|
);
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
createUiStyleTypeDeclaration({
|
|
479
|
-
configPaths,
|
|
480
|
-
paths
|
|
481
|
-
})
|
|
705
|
+
configPaths.push(...uiConfigStyleReferencePaths);
|
|
706
|
+
const uiConfigPaths = fileContents.flatMap(
|
|
707
|
+
({ content, file }) => collectUiConfigPathsFromCode(content, file, uiConfig)
|
|
482
708
|
);
|
|
709
|
+
return createUiStyleTypeDeclaration({
|
|
710
|
+
configPaths,
|
|
711
|
+
paths,
|
|
712
|
+
uiConfigPaths
|
|
713
|
+
});
|
|
483
714
|
};
|
|
715
|
+
const uiStyleTypeTemplate = addTypeTemplate({
|
|
716
|
+
filename: "types/brickflow-ui-style.d.ts",
|
|
717
|
+
getContents: getUiStyleTypeContents
|
|
718
|
+
});
|
|
719
|
+
const uiConfigLiteralTypeTemplate = addTypeTemplate({
|
|
720
|
+
filename: "types/brickflow-ui-config-literals.d.ts",
|
|
721
|
+
getContents: async () => {
|
|
722
|
+
const files = await scanUiStyleFiles(runtimePath);
|
|
723
|
+
const uiConfig = (await loadUiConfig()).uiConfig;
|
|
724
|
+
const paths = await Promise.all(
|
|
725
|
+
files.map(
|
|
726
|
+
async (file) => collectUiConfigComponentPathsFromCode(await readFile(file, "utf8"), file, uiConfig)
|
|
727
|
+
)
|
|
728
|
+
);
|
|
729
|
+
return createUiConfigLiteralTypeDeclaration(paths.flat(), uiConfig);
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
const uiConfigSchemaTypeTemplate = addTypeTemplate({
|
|
733
|
+
filename: "types/brickflow-ui-config-contract.d.ts",
|
|
734
|
+
getContents: async () => {
|
|
735
|
+
const files = await scanUiStyleFiles(componentsDirectory);
|
|
736
|
+
const entries = await Promise.all(
|
|
737
|
+
files.map(async (file) => collectUiConfigSchemaEntriesFromCode(await readFile(file, "utf8"), file))
|
|
738
|
+
);
|
|
739
|
+
return createUiConfigSchemaTypeDeclaration(entries.flat());
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
nuxt.hook("prepare:types", ({ references }) => {
|
|
743
|
+
references.push({ path: resolver.resolve("./runtime/config.d.ts") });
|
|
744
|
+
});
|
|
484
745
|
const iconFontTemplate = addTemplate({
|
|
485
746
|
filename: "brickflow/brickflow-ui-icons.mjs",
|
|
486
747
|
getContents: async () => {
|
|
@@ -495,12 +756,14 @@ const module$1 = defineNuxtModule({
|
|
|
495
756
|
const uiConfigTemplate = addTemplate({
|
|
496
757
|
filename: "brickflow/brickflow-ui-config.mjs",
|
|
497
758
|
getContents: () => [
|
|
759
|
+
`import { defineBrickflowUi } from ${JSON.stringify(resolver.resolve("./runtime/tailwind").replaceAll("\\", "/"))}`,
|
|
498
760
|
`import rawConfig from ${JSON.stringify(resolvedConfigPath.replaceAll("\\", "/"))}`,
|
|
499
|
-
`import { defineBrickflowUiConfig } from ${JSON.stringify(resolver.resolve("./runtime/tailwind").replaceAll("\\", "/"))}`,
|
|
500
761
|
"",
|
|
501
|
-
"const config =
|
|
762
|
+
"const config = defineBrickflowUi(rawConfig)",
|
|
502
763
|
"",
|
|
503
764
|
"export const UI_STYLE = config.uiStyles",
|
|
765
|
+
"export const UI_CONFIG = config.uiConfig",
|
|
766
|
+
"export const uiConfig = config.uiConfig",
|
|
504
767
|
"export const uiStyles = config.uiStyles",
|
|
505
768
|
"export default config",
|
|
506
769
|
""
|
|
@@ -615,17 +878,14 @@ const module$1 = defineNuxtModule({
|
|
|
615
878
|
path: "/ui"
|
|
616
879
|
});
|
|
617
880
|
});
|
|
618
|
-
await generateUiStyleTypes();
|
|
619
|
-
nuxt.hook("prepare:types", async ({ references }) => {
|
|
620
|
-
await generateUiStyleTypes();
|
|
621
|
-
references.push({ path: uiStyleTypePath });
|
|
622
|
-
});
|
|
623
881
|
nuxt.hook("builder:watch", async (_event, path) => {
|
|
624
882
|
const absolutePath = resolve(nuxt.options.srcDir, path);
|
|
625
883
|
if (relative(runtimePath, absolutePath).startsWith("..") || !UI_STYLE_FILE_PATTERN.test(path)) {
|
|
626
884
|
return;
|
|
627
885
|
}
|
|
628
|
-
await
|
|
886
|
+
await updateTemplates({
|
|
887
|
+
filter: (template) => template.filename === uiStyleTypeTemplate.filename || template.filename === uiConfigLiteralTypeTemplate.filename || template.filename === uiConfigSchemaTypeTemplate.filename
|
|
888
|
+
});
|
|
629
889
|
if (!relative(componentsDirectory, absolutePath).startsWith("..") && (UI_COMPONENT_FILE_PATTERN.test(path) || UI_DEMO_FILE_PATTERN.test(path))) {
|
|
630
890
|
await updateTemplates({ filter: (template) => template.filename === uiCatalogTemplate.filename });
|
|
631
891
|
}
|
|
@@ -644,6 +904,7 @@ const module$1 = defineNuxtModule({
|
|
|
644
904
|
viteConfig.plugins.push(
|
|
645
905
|
brickflowUiStylePlugin({
|
|
646
906
|
configPath: resolvedConfigPath,
|
|
907
|
+
getConfig: async () => (await loadUiConfig()).uiConfig,
|
|
647
908
|
getStyles: async () => (await loadUiConfig()).uiStyles
|
|
648
909
|
})
|
|
649
910
|
);
|
|
@@ -1,42 +1,48 @@
|
|
|
1
1
|
import type { RouteLocationRaw } from 'vue-router';
|
|
2
|
-
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
3
5
|
block?: boolean;
|
|
4
|
-
color?:
|
|
6
|
+
color?: string;
|
|
5
7
|
disabled?: boolean;
|
|
6
8
|
icon?: string;
|
|
7
9
|
loading?: boolean;
|
|
8
10
|
rounded?: boolean;
|
|
9
|
-
size?:
|
|
11
|
+
size?: string;
|
|
10
12
|
square?: boolean;
|
|
11
13
|
to?: RouteLocationRaw;
|
|
12
14
|
trailingIcon?: string;
|
|
13
|
-
type?:
|
|
14
|
-
variant?:
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
type?: "button" | "reset" | "submit";
|
|
16
|
+
variant?: string;
|
|
17
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
|
|
18
|
+
block?: boolean;
|
|
19
|
+
color?: string;
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
icon?: string;
|
|
22
|
+
loading?: boolean;
|
|
23
|
+
rounded?: boolean;
|
|
24
|
+
size?: string;
|
|
25
|
+
square?: boolean;
|
|
26
|
+
to?: RouteLocationRaw;
|
|
27
|
+
trailingIcon?: string;
|
|
28
|
+
type?: "button" | "reset" | "submit";
|
|
29
|
+
variant?: string;
|
|
30
|
+
}> & Readonly<{}>, {
|
|
31
|
+
size: string;
|
|
29
32
|
type: "button" | "reset" | "submit";
|
|
30
|
-
color:
|
|
33
|
+
color: string;
|
|
31
34
|
to: RouteLocationRaw;
|
|
32
35
|
icon: string;
|
|
33
36
|
rounded: boolean;
|
|
34
37
|
trailingIcon: string;
|
|
35
|
-
variant:
|
|
36
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
variant: string;
|
|
39
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
40
|
+
leading?: (props: {}) => any;
|
|
41
|
+
} & {
|
|
42
|
+
default?: (props: {}) => any;
|
|
43
|
+
} & {
|
|
44
|
+
trailing?: (props: {}) => any;
|
|
45
|
+
}>;
|
|
40
46
|
type __VLS_WithSlots<T, S> = T & {
|
|
41
47
|
new (): {
|
|
42
48
|
$slots: S;
|
|
@@ -1,28 +1,27 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
const UI_CONFIG = defineUiConfig();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
1
5
|
<script setup>
|
|
2
6
|
import { computed, shallowRef } from "vue";
|
|
3
7
|
import Icon from "../Icon/index.vue";
|
|
4
8
|
import BaseLink from "../Link/index.vue";
|
|
5
9
|
const props = defineProps({
|
|
6
10
|
block: { type: Boolean, required: false },
|
|
7
|
-
color: { type: String, required: false, default:
|
|
11
|
+
color: { type: String, required: false, default: UI_CONFIG.colorDefault },
|
|
8
12
|
disabled: { type: Boolean, required: false },
|
|
9
13
|
icon: { type: String, required: false, default: void 0 },
|
|
10
14
|
loading: { type: Boolean, required: false },
|
|
11
15
|
rounded: { type: Boolean, required: false, default: false },
|
|
12
|
-
size: { type: String, required: false, default:
|
|
16
|
+
size: { type: String, required: false, default: UI_CONFIG.sizeDefault },
|
|
13
17
|
square: { type: Boolean, required: false },
|
|
14
18
|
to: { type: null, required: false, default: void 0 },
|
|
15
19
|
trailingIcon: { type: String, required: false, default: void 0 },
|
|
16
20
|
type: { type: String, required: false, default: "button" },
|
|
17
|
-
variant: { type: String, required: false, default:
|
|
21
|
+
variant: { type: String, required: false, default: UI_CONFIG.variantDefault }
|
|
18
22
|
});
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
md: UI_STYLE.size.md,
|
|
22
|
-
sm: UI_STYLE.size.sm,
|
|
23
|
-
xl: UI_STYLE.size.xl,
|
|
24
|
-
xs: UI_STYLE.size.xs
|
|
25
|
-
};
|
|
23
|
+
const colorClasses = UI_CONFIG.colorClasses;
|
|
24
|
+
const sizeClasses = UI_CONFIG.sizeClasses;
|
|
26
25
|
const sizeIconClasses = {
|
|
27
26
|
lg: UI_STYLE.size.lgIcon,
|
|
28
27
|
md: UI_STYLE.size.mdIcon,
|
|
@@ -30,57 +29,6 @@ const sizeIconClasses = {
|
|
|
30
29
|
xl: UI_STYLE.size.xlIcon,
|
|
31
30
|
xs: UI_STYLE.size.xsIcon
|
|
32
31
|
};
|
|
33
|
-
const colorClasses = {
|
|
34
|
-
alt: {
|
|
35
|
-
ghost: UI_STYLE.color.alt.ghost,
|
|
36
|
-
mist: UI_STYLE.color.alt.mist,
|
|
37
|
-
soft: UI_STYLE.color.alt.soft,
|
|
38
|
-
solid: UI_STYLE.color.alt.solid,
|
|
39
|
-
subtle: UI_STYLE.color.alt.subtle
|
|
40
|
-
},
|
|
41
|
-
danger: {
|
|
42
|
-
ghost: UI_STYLE.color.danger.ghost,
|
|
43
|
-
mist: UI_STYLE.color.danger.mist,
|
|
44
|
-
soft: UI_STYLE.color.danger.soft,
|
|
45
|
-
solid: UI_STYLE.color.danger.solid,
|
|
46
|
-
subtle: UI_STYLE.color.danger.subtle
|
|
47
|
-
},
|
|
48
|
-
info: {
|
|
49
|
-
ghost: UI_STYLE.color.info.ghost,
|
|
50
|
-
mist: UI_STYLE.color.info.mist,
|
|
51
|
-
soft: UI_STYLE.color.info.soft,
|
|
52
|
-
solid: UI_STYLE.color.info.solid,
|
|
53
|
-
subtle: UI_STYLE.color.info.subtle
|
|
54
|
-
},
|
|
55
|
-
main: {
|
|
56
|
-
ghost: UI_STYLE.color.main.ghost,
|
|
57
|
-
mist: UI_STYLE.color.main.mist,
|
|
58
|
-
soft: UI_STYLE.color.main.soft,
|
|
59
|
-
solid: UI_STYLE.color.main.solid,
|
|
60
|
-
subtle: UI_STYLE.color.main.subtle
|
|
61
|
-
},
|
|
62
|
-
plain: {
|
|
63
|
-
ghost: UI_STYLE.color.plain.ghost,
|
|
64
|
-
mist: UI_STYLE.color.plain.mist,
|
|
65
|
-
soft: UI_STYLE.color.plain.soft,
|
|
66
|
-
solid: UI_STYLE.color.plain.solid,
|
|
67
|
-
subtle: UI_STYLE.color.plain.subtle
|
|
68
|
-
},
|
|
69
|
-
warn: {
|
|
70
|
-
ghost: UI_STYLE.color.warn.ghost,
|
|
71
|
-
mist: UI_STYLE.color.warn.mist,
|
|
72
|
-
soft: UI_STYLE.color.warn.soft,
|
|
73
|
-
solid: UI_STYLE.color.warn.solid,
|
|
74
|
-
subtle: UI_STYLE.color.warn.subtle
|
|
75
|
-
},
|
|
76
|
-
win: {
|
|
77
|
-
ghost: UI_STYLE.color.win.ghost,
|
|
78
|
-
mist: UI_STYLE.color.win.mist,
|
|
79
|
-
soft: UI_STYLE.color.win.soft,
|
|
80
|
-
solid: UI_STYLE.color.win.solid,
|
|
81
|
-
subtle: UI_STYLE.color.win.subtle
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
32
|
const component = computed(() => props.to === void 0 ? "button" : BaseLink);
|
|
85
33
|
const disabled = computed(() => props.disabled || props.loading);
|
|
86
34
|
const isButton = computed(() => props.to === void 0);
|
|
@@ -126,7 +74,7 @@ function handleTap() {
|
|
|
126
74
|
<slot name="leading">
|
|
127
75
|
<Icon
|
|
128
76
|
v-if="props.loading"
|
|
129
|
-
:name="
|
|
77
|
+
:name="UI_CONFIG.loadingIconName"
|
|
130
78
|
:class="UI_STYLE.state.loading"
|
|
131
79
|
aria-hidden="true"
|
|
132
80
|
/>
|
|
@@ -1,42 +1,48 @@
|
|
|
1
1
|
import type { RouteLocationRaw } from 'vue-router';
|
|
2
|
-
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
3
5
|
block?: boolean;
|
|
4
|
-
color?:
|
|
6
|
+
color?: string;
|
|
5
7
|
disabled?: boolean;
|
|
6
8
|
icon?: string;
|
|
7
9
|
loading?: boolean;
|
|
8
10
|
rounded?: boolean;
|
|
9
|
-
size?:
|
|
11
|
+
size?: string;
|
|
10
12
|
square?: boolean;
|
|
11
13
|
to?: RouteLocationRaw;
|
|
12
14
|
trailingIcon?: string;
|
|
13
|
-
type?:
|
|
14
|
-
variant?:
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
15
|
+
type?: "button" | "reset" | "submit";
|
|
16
|
+
variant?: string;
|
|
17
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
|
|
18
|
+
block?: boolean;
|
|
19
|
+
color?: string;
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
icon?: string;
|
|
22
|
+
loading?: boolean;
|
|
23
|
+
rounded?: boolean;
|
|
24
|
+
size?: string;
|
|
25
|
+
square?: boolean;
|
|
26
|
+
to?: RouteLocationRaw;
|
|
27
|
+
trailingIcon?: string;
|
|
28
|
+
type?: "button" | "reset" | "submit";
|
|
29
|
+
variant?: string;
|
|
30
|
+
}> & Readonly<{}>, {
|
|
31
|
+
size: string;
|
|
29
32
|
type: "button" | "reset" | "submit";
|
|
30
|
-
color:
|
|
33
|
+
color: string;
|
|
31
34
|
to: RouteLocationRaw;
|
|
32
35
|
icon: string;
|
|
33
36
|
rounded: boolean;
|
|
34
37
|
trailingIcon: string;
|
|
35
|
-
variant:
|
|
36
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
variant: string;
|
|
39
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
40
|
+
leading?: (props: {}) => any;
|
|
41
|
+
} & {
|
|
42
|
+
default?: (props: {}) => any;
|
|
43
|
+
} & {
|
|
44
|
+
trailing?: (props: {}) => any;
|
|
45
|
+
}>;
|
|
40
46
|
type __VLS_WithSlots<T, S> = T & {
|
|
41
47
|
new (): {
|
|
42
48
|
$slots: S;
|
|
@@ -6,199 +6,43 @@ export const uiDemo = {
|
|
|
6
6
|
|
|
7
7
|
<script setup>
|
|
8
8
|
import Button from "./index.vue";
|
|
9
|
+
const UI_CONFIG = defineUiConfig();
|
|
10
|
+
const colors = Object.entries(UI_CONFIG.colorClasses).map(([name, classes]) => ({
|
|
11
|
+
name,
|
|
12
|
+
variants: Object.keys(classes)
|
|
13
|
+
}));
|
|
14
|
+
const variants = colors[0]?.variants ?? [];
|
|
9
15
|
</script>
|
|
10
16
|
|
|
11
17
|
<template>
|
|
12
|
-
<div class="relative flex w-fit flex-col
|
|
18
|
+
<div class="relative flex w-fit flex-col items-start gap-3 pl-13">
|
|
13
19
|
<div class="absolute top-0 left-0 z-0 size-full object-cover pt-7 pl-13">
|
|
14
20
|
<img
|
|
15
|
-
src="https://
|
|
21
|
+
src="https://images.unsplash.com/photo-1545346315-f4c47e3e1b55?ixid=M3w4MjcwNjd8MHwxfHNlYXJjaHwyfHxzdHJvbmclMjBtYW58ZW58MHx8fHwxNzg4MjIyNTU1fDA&ixlib=rb-4.1.0&w=1000&h=1000&fit=max&q=80"
|
|
16
22
|
class="top-0 z-0 size-full rounded-xl object-cover opacity-50"
|
|
17
23
|
/>
|
|
18
24
|
</div>
|
|
19
25
|
<div class="flex w-full flex-wrap items-center justify-around gap-3 text-xs text-slate-600">
|
|
20
|
-
<span
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
<span
|
|
27
|
+
v-for="variant in variants"
|
|
28
|
+
:key="variant"
|
|
29
|
+
>
|
|
30
|
+
{{ variant }}
|
|
31
|
+
</span>
|
|
25
32
|
</div>
|
|
26
33
|
<div
|
|
27
|
-
|
|
34
|
+
v-for="color in colors"
|
|
35
|
+
:key="color.name"
|
|
36
|
+
class="relative flex w-full flex-wrap items-center gap-3 p-2"
|
|
28
37
|
>
|
|
29
|
-
<span>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<div class="flex flex-wrap items-center gap-3 p-2">
|
|
38
|
-
<Button>Button</Button>
|
|
39
|
-
<Button variant="ghost">Button</Button>
|
|
40
|
-
<Button variant="mist">Button</Button>
|
|
41
|
-
<Button variant="soft">Button</Button>
|
|
42
|
-
<Button variant="subtle">Button</Button>
|
|
43
|
-
</div>
|
|
44
|
-
<div class="flex flex-wrap items-center gap-3 p-2">
|
|
45
|
-
<Button color="plain">Button</Button>
|
|
46
|
-
<Button
|
|
47
|
-
color="plain"
|
|
48
|
-
variant="ghost"
|
|
49
|
-
>
|
|
50
|
-
Button
|
|
51
|
-
</Button>
|
|
52
|
-
<Button
|
|
53
|
-
color="plain"
|
|
54
|
-
variant="mist"
|
|
55
|
-
>
|
|
56
|
-
Button
|
|
57
|
-
</Button>
|
|
58
|
-
<Button
|
|
59
|
-
color="plain"
|
|
60
|
-
variant="soft"
|
|
61
|
-
>
|
|
62
|
-
Button
|
|
63
|
-
</Button>
|
|
64
|
-
<Button
|
|
65
|
-
color="plain"
|
|
66
|
-
variant="subtle"
|
|
67
|
-
>
|
|
68
|
-
Button
|
|
69
|
-
</Button>
|
|
70
|
-
</div>
|
|
71
|
-
<div class="flex flex-wrap items-center gap-3 p-2">
|
|
72
|
-
<Button color="alt">Button</Button>
|
|
73
|
-
<Button
|
|
74
|
-
color="alt"
|
|
75
|
-
variant="ghost"
|
|
76
|
-
>
|
|
77
|
-
Button
|
|
78
|
-
</Button>
|
|
79
|
-
<Button
|
|
80
|
-
color="alt"
|
|
81
|
-
variant="mist"
|
|
82
|
-
>
|
|
83
|
-
Button
|
|
84
|
-
</Button>
|
|
85
|
-
<Button
|
|
86
|
-
color="alt"
|
|
87
|
-
variant="soft"
|
|
88
|
-
>
|
|
89
|
-
Button
|
|
90
|
-
</Button>
|
|
91
|
-
<Button
|
|
92
|
-
color="alt"
|
|
93
|
-
variant="subtle"
|
|
94
|
-
>
|
|
95
|
-
Button
|
|
96
|
-
</Button>
|
|
97
|
-
</div>
|
|
98
|
-
<div class="flex flex-wrap items-center gap-3 p-2">
|
|
99
|
-
<Button color="danger">Button</Button>
|
|
100
|
-
<Button
|
|
101
|
-
color="danger"
|
|
102
|
-
variant="ghost"
|
|
103
|
-
>
|
|
104
|
-
Button
|
|
105
|
-
</Button>
|
|
106
|
-
<Button
|
|
107
|
-
color="danger"
|
|
108
|
-
variant="mist"
|
|
109
|
-
>
|
|
110
|
-
Button
|
|
111
|
-
</Button>
|
|
112
|
-
<Button
|
|
113
|
-
color="danger"
|
|
114
|
-
variant="soft"
|
|
115
|
-
>
|
|
116
|
-
Button
|
|
117
|
-
</Button>
|
|
118
|
-
<Button
|
|
119
|
-
color="danger"
|
|
120
|
-
variant="subtle"
|
|
121
|
-
>
|
|
122
|
-
Button
|
|
123
|
-
</Button>
|
|
124
|
-
</div>
|
|
125
|
-
<div class="flex flex-wrap items-center gap-3 p-2">
|
|
126
|
-
<Button color="info">Button</Button>
|
|
127
|
-
<Button
|
|
128
|
-
color="info"
|
|
129
|
-
variant="ghost"
|
|
130
|
-
>
|
|
131
|
-
Button
|
|
132
|
-
</Button>
|
|
133
|
-
<Button
|
|
134
|
-
color="info"
|
|
135
|
-
variant="mist"
|
|
136
|
-
>
|
|
137
|
-
Button
|
|
138
|
-
</Button>
|
|
139
|
-
<Button
|
|
140
|
-
color="info"
|
|
141
|
-
variant="soft"
|
|
142
|
-
>
|
|
143
|
-
Button
|
|
144
|
-
</Button>
|
|
145
|
-
<Button
|
|
146
|
-
color="info"
|
|
147
|
-
variant="subtle"
|
|
148
|
-
>
|
|
149
|
-
Button
|
|
150
|
-
</Button>
|
|
151
|
-
</div>
|
|
152
|
-
<div class="flex flex-wrap items-center gap-3 p-2">
|
|
153
|
-
<Button color="warn">Button</Button>
|
|
154
|
-
<Button
|
|
155
|
-
color="warn"
|
|
156
|
-
variant="ghost"
|
|
157
|
-
>
|
|
158
|
-
Button
|
|
159
|
-
</Button>
|
|
160
|
-
<Button
|
|
161
|
-
color="warn"
|
|
162
|
-
variant="mist"
|
|
163
|
-
>
|
|
164
|
-
Button
|
|
165
|
-
</Button>
|
|
166
|
-
<Button
|
|
167
|
-
color="warn"
|
|
168
|
-
variant="soft"
|
|
169
|
-
>
|
|
170
|
-
Button
|
|
171
|
-
</Button>
|
|
172
|
-
<Button
|
|
173
|
-
color="warn"
|
|
174
|
-
variant="subtle"
|
|
175
|
-
>
|
|
176
|
-
Button
|
|
177
|
-
</Button>
|
|
178
|
-
</div>
|
|
179
|
-
<div class="flex flex-wrap items-center gap-3 p-2">
|
|
180
|
-
<Button color="win">Button</Button>
|
|
181
|
-
<Button
|
|
182
|
-
color="win"
|
|
183
|
-
variant="ghost"
|
|
184
|
-
>
|
|
185
|
-
Button
|
|
186
|
-
</Button>
|
|
187
|
-
<Button
|
|
188
|
-
color="win"
|
|
189
|
-
variant="mist"
|
|
190
|
-
>
|
|
191
|
-
Button
|
|
192
|
-
</Button>
|
|
193
|
-
<Button
|
|
194
|
-
color="win"
|
|
195
|
-
variant="soft"
|
|
196
|
-
>
|
|
197
|
-
Button
|
|
198
|
-
</Button>
|
|
199
|
-
<Button
|
|
200
|
-
color="win"
|
|
201
|
-
variant="subtle"
|
|
38
|
+
<span class="absolute top-1/2 right-full mr-3 -translate-y-1/2 text-xs text-slate-600">
|
|
39
|
+
{{ color.name }}
|
|
40
|
+
</span>
|
|
41
|
+
<Button
|
|
42
|
+
v-for="variant in color.variants"
|
|
43
|
+
:key="variant"
|
|
44
|
+
:color="color.name"
|
|
45
|
+
:variant="variant"
|
|
202
46
|
>
|
|
203
47
|
Button
|
|
204
48
|
</Button>
|
package/dist/runtime/config.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ export {}
|
|
|
3
3
|
declare module '#brickflow-ui-config' {
|
|
4
4
|
import type { BrickflowUiConfig } from './tailwind'
|
|
5
5
|
|
|
6
|
-
export const
|
|
6
|
+
export const UI_CONFIG: BrickflowUiConfigType
|
|
7
|
+
export const UI_STYLE: BrickflowUiStyleType
|
|
8
|
+
export const uiConfig: BrickflowUiConfig['uiConfig']
|
|
7
9
|
export const uiStyles: BrickflowUiConfig['uiStyles']
|
|
8
10
|
|
|
9
11
|
const config: BrickflowUiConfig
|
|
@@ -12,6 +14,22 @@ declare module '#brickflow-ui-config' {
|
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
declare global {
|
|
17
|
+
type BrickflowUiConfigFor<TExpected extends BrickflowUiConfigObject> = {
|
|
18
|
+
[TKey in keyof BrickflowUiConfigLiteralPaths]: BrickflowUiConfigLiteralPaths[TKey] extends TExpected
|
|
19
|
+
? BrickflowUiConfigLiteralPaths[TKey]
|
|
20
|
+
: never
|
|
21
|
+
}[keyof BrickflowUiConfigLiteralPaths] extends infer TMatched
|
|
22
|
+
? [TMatched] extends [never]
|
|
23
|
+
? TExpected
|
|
24
|
+
: TMatched
|
|
25
|
+
: never
|
|
26
|
+
|
|
27
|
+
interface BrickflowUiConfigLiteralPaths {}
|
|
28
|
+
|
|
29
|
+
interface BrickflowUiConfigPaths {}
|
|
30
|
+
|
|
31
|
+
type BrickflowUiConfigType = BrickflowUiConfigPaths & Record<string, unknown>
|
|
32
|
+
|
|
15
33
|
interface BrickflowUiStylePaths {}
|
|
16
34
|
|
|
17
35
|
type BrickflowUiStyleType = BrickflowUiStylePaths & BrickflowUiStyleValue
|
|
@@ -21,10 +39,15 @@ declare global {
|
|
|
21
39
|
}
|
|
22
40
|
|
|
23
41
|
const UI_STYLE: BrickflowUiStyleType
|
|
42
|
+
|
|
43
|
+
const UI_CONFIG: BrickflowUiConfigType
|
|
44
|
+
|
|
45
|
+
function defineUiConfig<TConfig extends BrickflowUiConfigObject>(): BrickflowUiConfigFor<TConfig>
|
|
24
46
|
}
|
|
25
47
|
|
|
26
48
|
declare module '@vue/runtime-core' {
|
|
27
49
|
interface ComponentCustomProperties {
|
|
50
|
+
readonly UI_CONFIG: BrickflowUiConfigType
|
|
28
51
|
readonly UI_STYLE: BrickflowUiStyleType
|
|
29
52
|
}
|
|
30
53
|
}
|
|
@@ -1,14 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
declare const UI_STYLE_REFERENCE: unique symbol;
|
|
2
|
+
export interface BrickflowUiConfig<TStyles = BrickflowUiStyles, TConfig = BrickflowUiConfigObject> {
|
|
3
|
+
uiConfig: TConfig;
|
|
2
4
|
uiStyles: TStyles;
|
|
3
5
|
}
|
|
6
|
+
export type BrickflowUiConfigObject = {
|
|
7
|
+
readonly [key: string]: BrickflowUiConfigValue;
|
|
8
|
+
};
|
|
9
|
+
export type BrickflowUiConfigValue = BrickflowUiConfigObject | BrickflowUiStyleReference | string;
|
|
10
|
+
export interface BrickflowUiStyleReference {
|
|
11
|
+
readonly [UI_STYLE_REFERENCE]: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
/** A chainable compile-time reference to a string in `uiStyles`. */
|
|
14
|
+
export type BrickflowUiStyleReferenceValue = string & {
|
|
15
|
+
readonly [key: string]: any;
|
|
16
|
+
};
|
|
4
17
|
declare global {
|
|
18
|
+
interface BrickflowUiConfigSchema {
|
|
19
|
+
}
|
|
5
20
|
interface BrickflowUiConfigStylePaths {
|
|
6
21
|
}
|
|
7
22
|
type BrickflowUiStyleObject = {
|
|
8
23
|
readonly [key: string]: BrickflowUiStyleObject | string;
|
|
9
24
|
};
|
|
10
25
|
}
|
|
11
|
-
export type BrickflowUiConfigInput<TStyles extends BrickflowUiStyleObject = BrickflowUiStyles> = {
|
|
26
|
+
export type BrickflowUiConfigInput<TStyles extends BrickflowUiStyleObject = BrickflowUiStyles, TConfig extends BrickflowUiConfigObject = BrickflowUiConfigObject> = BrickflowUiConfigInputConfig<TConfig> & {
|
|
12
27
|
readonly uiStyles?: TStyles;
|
|
13
28
|
};
|
|
14
29
|
export type BrickflowUiNoExtraKeys<TValue, TShape> = TValue extends string ? TShape extends string ? TValue : never : TShape extends string ? never : {
|
|
@@ -16,10 +31,27 @@ export type BrickflowUiNoExtraKeys<TValue, TShape> = TValue extends string ? TSh
|
|
|
16
31
|
};
|
|
17
32
|
export type BrickflowUiStrictStyles<TStyles extends BrickflowUiConfigStylePaths> = BrickflowUiNoExtraKeys<TStyles, BrickflowUiConfigStylePaths> & TStyles;
|
|
18
33
|
export type BrickflowUiStyles = BrickflowUiStyleObject;
|
|
34
|
+
type BrickflowUiConfigContext = keyof BrickflowUiConfigSchema extends never ? unknown : {
|
|
35
|
+
readonly uiConfig: BrickflowUiConfigSchema;
|
|
36
|
+
};
|
|
37
|
+
type BrickflowUiConfigInputConfig<TConfig extends BrickflowUiConfigObject> = keyof BrickflowUiConfigSchema extends never ? {
|
|
38
|
+
readonly uiConfig?: TConfig;
|
|
39
|
+
} : {
|
|
40
|
+
readonly uiConfig: TConfig;
|
|
41
|
+
};
|
|
42
|
+
type BrickflowUiConfigValidation<TConfig extends BrickflowUiConfigObject> = keyof BrickflowUiConfigSchema extends never ? unknown : TConfig extends BrickflowUiConfigSchema ? unknown : {
|
|
43
|
+
readonly __brickflowUiConfigError: 'uiConfig does not satisfy a component config schema';
|
|
44
|
+
};
|
|
19
45
|
export declare const emptyUiStyles: {};
|
|
20
|
-
export declare const
|
|
21
|
-
export declare
|
|
22
|
-
export declare function
|
|
46
|
+
export declare const emptyUiConfig: {};
|
|
47
|
+
export declare const emptyBrickflowUiConfig: BrickflowUiConfig<typeof emptyUiStyles, typeof emptyUiConfig>;
|
|
48
|
+
export declare function defineBrickflowUi(): BrickflowUiConfig<typeof emptyUiStyles, typeof emptyUiConfig>;
|
|
49
|
+
export declare function defineBrickflowUi<const TStyles extends BrickflowUiConfigStylePaths, const TConfig extends BrickflowUiConfigObject>(config: BrickflowUiConfigContext & BrickflowUiConfigInput<BrickflowUiStrictStyles<TStyles>, TConfig> & BrickflowUiConfigValidation<TConfig>): BrickflowUiConfig<TStyles, TConfig>;
|
|
23
50
|
export declare const uiStyles: {};
|
|
51
|
+
export declare const uiConfig: {};
|
|
52
|
+
/** A compile-time reference to a value in `uiStyles`, for use inside `uiConfig`. */
|
|
53
|
+
export declare const UI_STYLE: BrickflowUiStyleReferenceValue;
|
|
54
|
+
export declare const isBrickflowUiStyleReference: (value: unknown) => value is BrickflowUiStyleReference;
|
|
55
|
+
export declare const getBrickflowUiStyleReferencePath: (value: BrickflowUiStyleReference) => readonly string[];
|
|
24
56
|
export default emptyBrickflowUiConfig;
|
|
25
57
|
//# sourceMappingURL=tailwind.d.ts.map
|
package/dist/runtime/tailwind.js
CHANGED
|
@@ -1,22 +1,68 @@
|
|
|
1
|
+
const UI_STYLE_REFERENCE = Symbol.for("@brickflow/ui/style-reference");
|
|
1
2
|
export const emptyUiStyles = {};
|
|
3
|
+
export const emptyUiConfig = {};
|
|
2
4
|
export const emptyBrickflowUiConfig = {
|
|
5
|
+
uiConfig: emptyUiConfig,
|
|
3
6
|
uiStyles: emptyUiStyles
|
|
4
7
|
};
|
|
5
|
-
export function
|
|
8
|
+
export function defineBrickflowUi(config = {}) {
|
|
9
|
+
const uiConfig2 = config.uiConfig ?? emptyUiConfig;
|
|
6
10
|
const uiStyles2 = config.uiStyles ?? emptyUiStyles;
|
|
11
|
+
validateUiConfig(uiConfig2);
|
|
7
12
|
validateUiStyles(uiStyles2);
|
|
8
13
|
return {
|
|
14
|
+
uiConfig: uiConfig2,
|
|
9
15
|
uiStyles: uiStyles2
|
|
10
16
|
};
|
|
11
17
|
}
|
|
12
18
|
export const uiStyles = emptyBrickflowUiConfig.uiStyles;
|
|
19
|
+
export const uiConfig = emptyBrickflowUiConfig.uiConfig;
|
|
20
|
+
const createUiStyleReference = (path = []) => new Proxy(
|
|
21
|
+
{ [UI_STYLE_REFERENCE]: path },
|
|
22
|
+
{
|
|
23
|
+
get(target, key) {
|
|
24
|
+
if (key === UI_STYLE_REFERENCE) {
|
|
25
|
+
return target[UI_STYLE_REFERENCE];
|
|
26
|
+
}
|
|
27
|
+
return typeof key === "string" ? createUiStyleReference([...path, key]) : void 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
export const UI_STYLE = createUiStyleReference();
|
|
32
|
+
export const isBrickflowUiStyleReference = (value) => Boolean(value && typeof value === "object" && UI_STYLE_REFERENCE in value);
|
|
33
|
+
export const getBrickflowUiStyleReferencePath = (value) => value[UI_STYLE_REFERENCE];
|
|
34
|
+
if (!("UI_STYLE" in globalThis)) {
|
|
35
|
+
Object.defineProperty(globalThis, "UI_STYLE", {
|
|
36
|
+
configurable: true,
|
|
37
|
+
value: UI_STYLE
|
|
38
|
+
});
|
|
39
|
+
}
|
|
13
40
|
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41
|
+
function validateUiConfig(value, path = "uiConfig") {
|
|
42
|
+
if (!isRecord(value)) {
|
|
43
|
+
throw new TypeError(`${path} must be an object.`);
|
|
44
|
+
}
|
|
45
|
+
for (const [key, childValue] of Object.entries(value)) {
|
|
46
|
+
const childPath = `${path}.${key}`;
|
|
47
|
+
if (typeof childValue === "string" || isBrickflowUiStyleReference(childValue)) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (isRecord(childValue)) {
|
|
51
|
+
validateUiConfig(childValue, childPath);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
throw new TypeError(`${childPath} must be a string, UI_STYLE reference, or an object.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
14
57
|
function validateUiStyles(value, path = "uiStyles") {
|
|
15
58
|
if (!isRecord(value)) {
|
|
16
59
|
throw new TypeError(`${path} must be an object.`);
|
|
17
60
|
}
|
|
18
61
|
for (const [key, childValue] of Object.entries(value)) {
|
|
19
62
|
const childPath = `${path}.${key}`;
|
|
63
|
+
if (isBrickflowUiStyleReference(childValue)) {
|
|
64
|
+
throw new TypeError(`${childPath} cannot reference UI_STYLE.`);
|
|
65
|
+
}
|
|
20
66
|
if (typeof childValue === "string") {
|
|
21
67
|
continue;
|
|
22
68
|
}
|