@brickflow/ui 0.0.33 → 0.0.34
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 +288 -28
- 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 +33 -5
- package/dist/runtime/tailwind.js +46 -0
- 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 { defineBrickflowUiConfig } from '../dist/runtime/tailwind.js';
|
|
5
|
+
import { join, basename, extname, dirname, resolve, relative } from 'node:path';
|
|
6
|
+
import { isBrickflowUiStyleReference, getBrickflowUiStyleReferencePath, defineBrickflowUiConfig } 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,75 @@ 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
|
+
if (code[genericStart] !== "<") {
|
|
161
|
+
result += code.slice(cursor, genericStart);
|
|
162
|
+
cursor = genericStart;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
let depth = 0;
|
|
166
|
+
let index = genericStart;
|
|
167
|
+
for (; index < code.length; index += 1) {
|
|
168
|
+
if (code[index] === "<") {
|
|
169
|
+
depth += 1;
|
|
170
|
+
}
|
|
171
|
+
if (code[index] === ">") {
|
|
172
|
+
depth -= 1;
|
|
173
|
+
}
|
|
174
|
+
if (depth === 0) {
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
let callStart = index + 1;
|
|
179
|
+
while (/\s/u.test(code[callStart] ?? "")) {
|
|
180
|
+
callStart += 1;
|
|
181
|
+
}
|
|
182
|
+
if (code.slice(callStart, callStart + 2) !== "()") {
|
|
183
|
+
result += code.slice(cursor, callStart);
|
|
184
|
+
cursor = callStart;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const value = resolveUiConfigValue(config, id, []);
|
|
188
|
+
if (value === void 0) {
|
|
189
|
+
error(`defineUiConfig() in ${id} has no matching uiConfig entry.`);
|
|
190
|
+
}
|
|
191
|
+
result += code.slice(cursor, start);
|
|
192
|
+
result += JSON.stringify(resolveUiConfigStyleReferences(value, styles, id));
|
|
193
|
+
cursor = callStart + 2;
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
};
|
|
126
197
|
const createUiStylePathTree = () => ({
|
|
127
198
|
children: /* @__PURE__ */ new Map()
|
|
128
199
|
});
|
|
@@ -134,16 +205,18 @@ const addPathToTree = (tree, path) => {
|
|
|
134
205
|
currentTree = childTree;
|
|
135
206
|
}
|
|
136
207
|
};
|
|
137
|
-
const renderTypeTree = (tree, level, objectType) => {
|
|
208
|
+
const renderTypeTree = (tree, level, objectType, leafType = "string", path = []) => {
|
|
138
209
|
const lines = [];
|
|
139
210
|
const indent = TYPE_INDENT.repeat(level);
|
|
140
211
|
for (const [key, childTree] of [...tree.children.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
141
212
|
if (childTree.children.size === 0) {
|
|
142
|
-
|
|
213
|
+
const childPath = [...path, key];
|
|
214
|
+
const childLeafType = typeof leafType === "function" ? leafType(childPath) : leafType;
|
|
215
|
+
lines.push(`${indent}readonly ${key}: ${childLeafType}`);
|
|
143
216
|
continue;
|
|
144
217
|
}
|
|
145
218
|
lines.push(objectType ? `${indent}readonly ${key}: ${objectType} & {` : `${indent}readonly ${key}: {`);
|
|
146
|
-
lines.push(...renderTypeTree(childTree, level + 1, objectType));
|
|
219
|
+
lines.push(...renderTypeTree(childTree, level + 1, objectType, leafType, [...path, key]));
|
|
147
220
|
lines.push(`${indent}}`);
|
|
148
221
|
}
|
|
149
222
|
return lines;
|
|
@@ -156,18 +229,111 @@ const collectUiStylePathsFromCode = (code) => {
|
|
|
156
229
|
return paths.filter((path) => path.length > 0);
|
|
157
230
|
};
|
|
158
231
|
const collectUiStyleConfigPathsFromCode = (code, id) => collectUiStylePathsFromCode(code).map((path) => resolveUiStyleConfigPath(id, path));
|
|
159
|
-
const
|
|
232
|
+
const collectUiConfigValuePaths = (value, prefix) => {
|
|
233
|
+
if (typeof value === "string" || isBrickflowUiStyleReference(value)) {
|
|
234
|
+
return [prefix];
|
|
235
|
+
}
|
|
236
|
+
return Object.entries(value).flatMap(
|
|
237
|
+
([key, childValue]) => collectUiConfigValuePaths(childValue, [...prefix, key])
|
|
238
|
+
);
|
|
239
|
+
};
|
|
240
|
+
const collectUiConfigPathsFromCode = (code, id, config) => {
|
|
241
|
+
const paths = [];
|
|
242
|
+
for (const match of code.matchAll(UI_CONFIG_PATTERN)) {
|
|
243
|
+
const path = match[1]?.slice(1).split(".") ?? [];
|
|
244
|
+
const value = resolveUiConfigValue(config, id, path);
|
|
245
|
+
paths.push(...value === void 0 ? [path] : collectUiConfigValuePaths(value, path));
|
|
246
|
+
}
|
|
247
|
+
return paths.filter((path) => path.length > 0);
|
|
248
|
+
};
|
|
249
|
+
const collectUiConfigComponentPathsFromCode = (code, id, config) => {
|
|
250
|
+
const paths = [];
|
|
251
|
+
for (const match of code.matchAll(UI_CONFIG_PATTERN)) {
|
|
252
|
+
const path = match[1]?.slice(1).split(".") ?? [];
|
|
253
|
+
const componentPath = resolveUiStyleConfigPath(id, path);
|
|
254
|
+
const value = readPath(config, componentPath);
|
|
255
|
+
paths.push(
|
|
256
|
+
...value === void 0 ? [componentPath] : collectUiConfigValuePaths(value, componentPath)
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
if (code.includes(UI_CONFIG_MACRO)) {
|
|
260
|
+
const componentPath = resolveUiStyleConfigPath(id, []);
|
|
261
|
+
const value = readPath(config, componentPath);
|
|
262
|
+
if (value !== void 0) {
|
|
263
|
+
paths.push(...collectUiConfigValuePaths(value, componentPath));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return paths.filter((path) => path.length > 0);
|
|
267
|
+
};
|
|
268
|
+
const collectUiConfigSchemaEntriesFromCode = (code, id) => {
|
|
269
|
+
const entries = [];
|
|
270
|
+
let cursor = 0;
|
|
271
|
+
while (cursor < code.length) {
|
|
272
|
+
const start = code.indexOf(UI_CONFIG_MACRO, cursor);
|
|
273
|
+
if (start === -1) {
|
|
274
|
+
return entries;
|
|
275
|
+
}
|
|
276
|
+
const genericStart = start + UI_CONFIG_MACRO.length;
|
|
277
|
+
if (code[genericStart] !== "<") {
|
|
278
|
+
cursor = genericStart;
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
let depth = 0;
|
|
282
|
+
let genericEnd = genericStart;
|
|
283
|
+
for (; genericEnd < code.length; genericEnd += 1) {
|
|
284
|
+
if (code[genericEnd] === "<") {
|
|
285
|
+
depth += 1;
|
|
286
|
+
}
|
|
287
|
+
if (code[genericEnd] === ">") {
|
|
288
|
+
depth -= 1;
|
|
289
|
+
}
|
|
290
|
+
if (depth === 0) {
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
let callStart = genericEnd + 1;
|
|
295
|
+
while (/\s/u.test(code[callStart] ?? "")) {
|
|
296
|
+
callStart += 1;
|
|
297
|
+
}
|
|
298
|
+
if (code.slice(callStart, callStart + 2) !== "()") {
|
|
299
|
+
cursor = callStart;
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
const schema = code.slice(genericStart + 1, genericEnd).trim();
|
|
303
|
+
const path = resolveUiStyleConfigPath(id, []);
|
|
304
|
+
if (schema.startsWith("{") && path.length > 0) {
|
|
305
|
+
entries.push({ path, schema });
|
|
306
|
+
}
|
|
307
|
+
cursor = callStart + 2;
|
|
308
|
+
}
|
|
309
|
+
return entries;
|
|
310
|
+
};
|
|
311
|
+
const collectUiConfigStyleReferencePathsFromValue = (value, componentPath) => {
|
|
312
|
+
if (isBrickflowUiStyleReference(value)) {
|
|
313
|
+
return [[...componentPath, ...getBrickflowUiStyleReferencePath(value)]];
|
|
314
|
+
}
|
|
315
|
+
if (typeof value === "string") {
|
|
316
|
+
return [];
|
|
317
|
+
}
|
|
318
|
+
return Object.values(value).flatMap(
|
|
319
|
+
(childValue) => collectUiConfigStyleReferencePathsFromValue(childValue, componentPath)
|
|
320
|
+
);
|
|
321
|
+
};
|
|
322
|
+
const collectUiConfigStyleReferencePaths = (config) => Object.entries(config).flatMap(([key, value]) => collectUiConfigStyleReferencePathsFromValue(value, [key]));
|
|
323
|
+
const renderInterfaceDeclaration = (name, paths, objectType, leafType = "string") => {
|
|
160
324
|
const tree = createUiStylePathTree();
|
|
161
325
|
for (const path of paths) {
|
|
162
326
|
addPathToTree(tree, path);
|
|
163
327
|
}
|
|
164
|
-
return [` interface ${name} {`, ...renderTypeTree(tree, 2, objectType), " }"];
|
|
328
|
+
return [` interface ${name} {`, ...renderTypeTree(tree, 2, objectType, leafType), " }"];
|
|
165
329
|
};
|
|
166
330
|
const createUiStyleTypeDeclaration = (options) => {
|
|
167
331
|
return [
|
|
168
332
|
"declare global {",
|
|
169
333
|
...renderInterfaceDeclaration("BrickflowUiConfigStylePaths", options.configPaths),
|
|
170
334
|
"",
|
|
335
|
+
...renderInterfaceDeclaration("BrickflowUiConfigPaths", options.uiConfigPaths),
|
|
336
|
+
"",
|
|
171
337
|
...renderInterfaceDeclaration("BrickflowUiStylePaths", options.paths, "BrickflowUiStyleValue"),
|
|
172
338
|
"}",
|
|
173
339
|
"",
|
|
@@ -175,6 +341,39 @@ const createUiStyleTypeDeclaration = (options) => {
|
|
|
175
341
|
""
|
|
176
342
|
].join("\n");
|
|
177
343
|
};
|
|
344
|
+
const createUiConfigLiteralTypeDeclaration = (paths, config) => [
|
|
345
|
+
"declare global {",
|
|
346
|
+
...renderInterfaceDeclaration("BrickflowUiConfigLiteralPaths", paths, void 0, (path) => {
|
|
347
|
+
const value = config ? readPath(config, path) : void 0;
|
|
348
|
+
return typeof value === "string" ? toStringLiteral(value) : "string";
|
|
349
|
+
}),
|
|
350
|
+
"}",
|
|
351
|
+
"",
|
|
352
|
+
"export {}",
|
|
353
|
+
""
|
|
354
|
+
].join("\n");
|
|
355
|
+
const createUiConfigSchemaTypeDeclaration = (entries) => {
|
|
356
|
+
const schemasByPath = /* @__PURE__ */ new Map();
|
|
357
|
+
for (const { path, schema } of entries) {
|
|
358
|
+
const pathKey = path.join(".");
|
|
359
|
+
const schemas = schemasByPath.get(pathKey) ?? [];
|
|
360
|
+
schemas.push(schema);
|
|
361
|
+
schemasByPath.set(pathKey, schemas);
|
|
362
|
+
}
|
|
363
|
+
return [
|
|
364
|
+
"declare global {",
|
|
365
|
+
" interface BrickflowUiConfigSchema {",
|
|
366
|
+
...[...schemasByPath.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([path, schemas]) => {
|
|
367
|
+
const [componentName] = path.split(".");
|
|
368
|
+
return ` readonly ${componentName}: ${schemas.map((schema) => `(${schema})`).join(" & ")}`;
|
|
369
|
+
}),
|
|
370
|
+
" }",
|
|
371
|
+
"}",
|
|
372
|
+
"",
|
|
373
|
+
"export {}",
|
|
374
|
+
""
|
|
375
|
+
].join("\n");
|
|
376
|
+
};
|
|
178
377
|
const brickflowUiStylePlugin = (options) => ({
|
|
179
378
|
buildStart: {
|
|
180
379
|
handler() {
|
|
@@ -197,13 +396,39 @@ const brickflowUiStylePlugin = (options) => ({
|
|
|
197
396
|
},
|
|
198
397
|
name: "brickflow-ui-style",
|
|
199
398
|
async transform(code, id) {
|
|
200
|
-
if (!SCRIPT_FILE_PATTERN.test(id) || !code.includes("UI_STYLE.")) {
|
|
399
|
+
if (!SCRIPT_FILE_PATTERN.test(id) || !code.includes("UI_STYLE.") && !code.includes("UI_CONFIG.") && !code.includes(UI_CONFIG_MACRO)) {
|
|
201
400
|
return null;
|
|
202
401
|
}
|
|
203
402
|
this.addWatchFile?.(options.configPath);
|
|
204
403
|
const styles = await options.getStyles();
|
|
404
|
+
const config = await options.getConfig();
|
|
405
|
+
const isConfigFile = normalizePath(id.split("?")[0] ?? id) === normalizePath(options.configPath);
|
|
406
|
+
const hasUiConfigMacro = code.includes(UI_CONFIG_MACRO);
|
|
205
407
|
let changed = false;
|
|
206
|
-
const
|
|
408
|
+
const codeWithUiConfigMacros = hasUiConfigMacro ? replaceUiConfigMacros(code, config, styles, id, this.error.bind(this)) : code;
|
|
409
|
+
if (codeWithUiConfigMacros !== code) {
|
|
410
|
+
changed = true;
|
|
411
|
+
}
|
|
412
|
+
const transformedCode = codeWithUiConfigMacros.replace(UI_CONFIG_PATTERN, (match, rawPath) => {
|
|
413
|
+
if (hasUiConfigMacro) {
|
|
414
|
+
return match;
|
|
415
|
+
}
|
|
416
|
+
const path = rawPath.slice(1).split(".");
|
|
417
|
+
const value = resolveUiConfigValue(config, id, path);
|
|
418
|
+
changed = true;
|
|
419
|
+
if (value === void 0) {
|
|
420
|
+
return "undefined";
|
|
421
|
+
}
|
|
422
|
+
try {
|
|
423
|
+
const resolvedValue = resolveUiConfigStyleReferences(value, styles, id);
|
|
424
|
+
return typeof resolvedValue === "string" ? toStringLiteral(resolvedValue) : JSON.stringify(resolvedValue);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
this.error(error instanceof Error ? error.message : String(error));
|
|
427
|
+
}
|
|
428
|
+
}).replace(UI_STYLE_PATTERN, (match, rawPath) => {
|
|
429
|
+
if (isConfigFile) {
|
|
430
|
+
return match;
|
|
431
|
+
}
|
|
207
432
|
const path = rawPath.slice(1).split(".");
|
|
208
433
|
const value = resolveStyleValue(styles, id, path);
|
|
209
434
|
if (typeof value === "string") {
|
|
@@ -459,8 +684,7 @@ const module$1 = defineNuxtModule({
|
|
|
459
684
|
);
|
|
460
685
|
};
|
|
461
686
|
await loadUiConfig();
|
|
462
|
-
const
|
|
463
|
-
const generateUiStyleTypes = async () => {
|
|
687
|
+
const getUiStyleTypeContents = async () => {
|
|
464
688
|
const files = await scanUiStyleFiles(runtimePath);
|
|
465
689
|
const fileContents = await Promise.all(
|
|
466
690
|
files.map(async (file) => ({
|
|
@@ -468,19 +692,55 @@ const module$1 = defineNuxtModule({
|
|
|
468
692
|
file
|
|
469
693
|
}))
|
|
470
694
|
);
|
|
471
|
-
const
|
|
695
|
+
const uiConfig = (await loadUiConfig()).uiConfig;
|
|
696
|
+
const uiConfigStyleReferencePaths = collectUiConfigStyleReferencePaths(uiConfig);
|
|
697
|
+
const paths = [
|
|
698
|
+
...fileContents.flatMap(({ content }) => collectUiStylePathsFromCode(content)),
|
|
699
|
+
...uiConfigStyleReferencePaths.map((path) => path.slice(1))
|
|
700
|
+
];
|
|
472
701
|
const configPaths = fileContents.flatMap(
|
|
473
702
|
({ content, file }) => collectUiStyleConfigPathsFromCode(content, file)
|
|
474
703
|
);
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
createUiStyleTypeDeclaration({
|
|
479
|
-
configPaths,
|
|
480
|
-
paths
|
|
481
|
-
})
|
|
704
|
+
configPaths.push(...uiConfigStyleReferencePaths);
|
|
705
|
+
const uiConfigPaths = fileContents.flatMap(
|
|
706
|
+
({ content, file }) => collectUiConfigPathsFromCode(content, file, uiConfig)
|
|
482
707
|
);
|
|
708
|
+
return createUiStyleTypeDeclaration({
|
|
709
|
+
configPaths,
|
|
710
|
+
paths,
|
|
711
|
+
uiConfigPaths
|
|
712
|
+
});
|
|
483
713
|
};
|
|
714
|
+
const uiStyleTypeTemplate = addTypeTemplate({
|
|
715
|
+
filename: "types/brickflow-ui-style.d.ts",
|
|
716
|
+
getContents: getUiStyleTypeContents
|
|
717
|
+
});
|
|
718
|
+
const uiConfigLiteralTypeTemplate = addTypeTemplate({
|
|
719
|
+
filename: "types/brickflow-ui-config-literals.d.ts",
|
|
720
|
+
getContents: async () => {
|
|
721
|
+
const files = await scanUiStyleFiles(runtimePath);
|
|
722
|
+
const uiConfig = (await loadUiConfig()).uiConfig;
|
|
723
|
+
const paths = await Promise.all(
|
|
724
|
+
files.map(
|
|
725
|
+
async (file) => collectUiConfigComponentPathsFromCode(await readFile(file, "utf8"), file, uiConfig)
|
|
726
|
+
)
|
|
727
|
+
);
|
|
728
|
+
return createUiConfigLiteralTypeDeclaration(paths.flat(), uiConfig);
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
const uiConfigSchemaTypeTemplate = addTypeTemplate({
|
|
732
|
+
filename: "types/brickflow-ui-config-contract.d.ts",
|
|
733
|
+
getContents: async () => {
|
|
734
|
+
const files = await scanUiStyleFiles(componentsDirectory);
|
|
735
|
+
const entries = await Promise.all(
|
|
736
|
+
files.map(async (file) => collectUiConfigSchemaEntriesFromCode(await readFile(file, "utf8"), file))
|
|
737
|
+
);
|
|
738
|
+
return createUiConfigSchemaTypeDeclaration(entries.flat());
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
nuxt.hook("prepare:types", ({ references }) => {
|
|
742
|
+
references.push({ path: resolver.resolve("./runtime/config.d.ts") });
|
|
743
|
+
});
|
|
484
744
|
const iconFontTemplate = addTemplate({
|
|
485
745
|
filename: "brickflow/brickflow-ui-icons.mjs",
|
|
486
746
|
getContents: async () => {
|
|
@@ -495,12 +755,14 @@ const module$1 = defineNuxtModule({
|
|
|
495
755
|
const uiConfigTemplate = addTemplate({
|
|
496
756
|
filename: "brickflow/brickflow-ui-config.mjs",
|
|
497
757
|
getContents: () => [
|
|
498
|
-
`import rawConfig from ${JSON.stringify(resolvedConfigPath.replaceAll("\\", "/"))}`,
|
|
499
758
|
`import { defineBrickflowUiConfig } from ${JSON.stringify(resolver.resolve("./runtime/tailwind").replaceAll("\\", "/"))}`,
|
|
759
|
+
`import rawConfig from ${JSON.stringify(resolvedConfigPath.replaceAll("\\", "/"))}`,
|
|
500
760
|
"",
|
|
501
761
|
"const config = defineBrickflowUiConfig(rawConfig)",
|
|
502
762
|
"",
|
|
503
763
|
"export const UI_STYLE = config.uiStyles",
|
|
764
|
+
"export const UI_CONFIG = config.uiConfig",
|
|
765
|
+
"export const uiConfig = config.uiConfig",
|
|
504
766
|
"export const uiStyles = config.uiStyles",
|
|
505
767
|
"export default config",
|
|
506
768
|
""
|
|
@@ -615,17 +877,14 @@ const module$1 = defineNuxtModule({
|
|
|
615
877
|
path: "/ui"
|
|
616
878
|
});
|
|
617
879
|
});
|
|
618
|
-
await generateUiStyleTypes();
|
|
619
|
-
nuxt.hook("prepare:types", async ({ references }) => {
|
|
620
|
-
await generateUiStyleTypes();
|
|
621
|
-
references.push({ path: uiStyleTypePath });
|
|
622
|
-
});
|
|
623
880
|
nuxt.hook("builder:watch", async (_event, path) => {
|
|
624
881
|
const absolutePath = resolve(nuxt.options.srcDir, path);
|
|
625
882
|
if (relative(runtimePath, absolutePath).startsWith("..") || !UI_STYLE_FILE_PATTERN.test(path)) {
|
|
626
883
|
return;
|
|
627
884
|
}
|
|
628
|
-
await
|
|
885
|
+
await updateTemplates({
|
|
886
|
+
filter: (template) => template.filename === uiStyleTypeTemplate.filename || template.filename === uiConfigLiteralTypeTemplate.filename || template.filename === uiConfigSchemaTypeTemplate.filename
|
|
887
|
+
});
|
|
629
888
|
if (!relative(componentsDirectory, absolutePath).startsWith("..") && (UI_COMPONENT_FILE_PATTERN.test(path) || UI_DEMO_FILE_PATTERN.test(path))) {
|
|
630
889
|
await updateTemplates({ filter: (template) => template.filename === uiCatalogTemplate.filename });
|
|
631
890
|
}
|
|
@@ -644,6 +903,7 @@ const module$1 = defineNuxtModule({
|
|
|
644
903
|
viteConfig.plugins.push(
|
|
645
904
|
brickflowUiStylePlugin({
|
|
646
905
|
configPath: resolvedConfigPath,
|
|
906
|
+
getConfig: async () => (await loadUiConfig()).uiConfig,
|
|
647
907
|
getStyles: async () => (await loadUiConfig()).uiStyles
|
|
648
908
|
})
|
|
649
909
|
);
|
|
@@ -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;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
const UI_CONFIG = defineUiConfig();
|
|
2
3
|
export const uiDemo = {
|
|
3
4
|
title: "Color & Variants"
|
|
4
5
|
};
|
|
@@ -6,199 +7,42 @@ export const uiDemo = {
|
|
|
6
7
|
|
|
7
8
|
<script setup>
|
|
8
9
|
import Button from "./index.vue";
|
|
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,25 @@
|
|
|
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
|
+
}
|
|
4
13
|
declare global {
|
|
14
|
+
interface BrickflowUiConfigSchema {
|
|
15
|
+
}
|
|
5
16
|
interface BrickflowUiConfigStylePaths {
|
|
6
17
|
}
|
|
7
18
|
type BrickflowUiStyleObject = {
|
|
8
19
|
readonly [key: string]: BrickflowUiStyleObject | string;
|
|
9
20
|
};
|
|
10
21
|
}
|
|
11
|
-
export type BrickflowUiConfigInput<TStyles extends BrickflowUiStyleObject = BrickflowUiStyles> = {
|
|
22
|
+
export type BrickflowUiConfigInput<TStyles extends BrickflowUiStyleObject = BrickflowUiStyles, TConfig extends BrickflowUiConfigObject = BrickflowUiConfigObject> = BrickflowUiConfigInputConfig<TConfig> & {
|
|
12
23
|
readonly uiStyles?: TStyles;
|
|
13
24
|
};
|
|
14
25
|
export type BrickflowUiNoExtraKeys<TValue, TShape> = TValue extends string ? TShape extends string ? TValue : never : TShape extends string ? never : {
|
|
@@ -16,10 +27,27 @@ export type BrickflowUiNoExtraKeys<TValue, TShape> = TValue extends string ? TSh
|
|
|
16
27
|
};
|
|
17
28
|
export type BrickflowUiStrictStyles<TStyles extends BrickflowUiConfigStylePaths> = BrickflowUiNoExtraKeys<TStyles, BrickflowUiConfigStylePaths> & TStyles;
|
|
18
29
|
export type BrickflowUiStyles = BrickflowUiStyleObject;
|
|
30
|
+
type BrickflowUiConfigContext = keyof BrickflowUiConfigSchema extends never ? unknown : {
|
|
31
|
+
readonly uiConfig: BrickflowUiConfigSchema;
|
|
32
|
+
};
|
|
33
|
+
type BrickflowUiConfigInputConfig<TConfig extends BrickflowUiConfigObject> = keyof BrickflowUiConfigSchema extends never ? {
|
|
34
|
+
readonly uiConfig?: TConfig;
|
|
35
|
+
} : {
|
|
36
|
+
readonly uiConfig: TConfig;
|
|
37
|
+
};
|
|
38
|
+
type BrickflowUiConfigValidation<TConfig extends BrickflowUiConfigObject> = keyof BrickflowUiConfigSchema extends never ? unknown : TConfig extends BrickflowUiConfigSchema ? unknown : {
|
|
39
|
+
readonly __brickflowUiConfigError: 'uiConfig does not satisfy a component config schema';
|
|
40
|
+
};
|
|
19
41
|
export declare const emptyUiStyles: {};
|
|
20
|
-
export declare const
|
|
21
|
-
export declare
|
|
22
|
-
export declare function defineBrickflowUiConfig
|
|
42
|
+
export declare const emptyUiConfig: {};
|
|
43
|
+
export declare const emptyBrickflowUiConfig: BrickflowUiConfig<typeof emptyUiStyles, typeof emptyUiConfig>;
|
|
44
|
+
export declare function defineBrickflowUiConfig(): BrickflowUiConfig<typeof emptyUiStyles, typeof emptyUiConfig>;
|
|
45
|
+
export declare function defineBrickflowUiConfig<const TStyles extends BrickflowUiConfigStylePaths, const TConfig extends BrickflowUiConfigObject>(config: BrickflowUiConfigContext & BrickflowUiConfigInput<BrickflowUiStrictStyles<TStyles>, TConfig> & BrickflowUiConfigValidation<TConfig>): BrickflowUiConfig<TStyles, TConfig>;
|
|
23
46
|
export declare const uiStyles: {};
|
|
47
|
+
export declare const uiConfig: {};
|
|
48
|
+
/** A compile-time reference to a value in `uiStyles`, for use inside `uiConfig`. */
|
|
49
|
+
export declare const UI_STYLE: BrickflowUiStyleReference;
|
|
50
|
+
export declare const isBrickflowUiStyleReference: (value: unknown) => value is BrickflowUiStyleReference;
|
|
51
|
+
export declare const getBrickflowUiStyleReferencePath: (value: BrickflowUiStyleReference) => readonly string[];
|
|
24
52
|
export default emptyBrickflowUiConfig;
|
|
25
53
|
//# 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
8
|
export function defineBrickflowUiConfig(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
|
}
|