vueless 0.0.5 → 0.0.6
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/.eslintrc.js +7 -0
- package/package.json +3 -2
- package/postcss.config.js +1 -1
- package/src/service.tailwind/index.js +1 -1
- package/src/service.ui/index.js +1 -1
- package/src/ui.button/index.vue +2 -3
- package/src/ui.button-link/index.vue +2 -2
- package/src/ui.button-toggle/index.vue +2 -2
- package/src/ui.button-toggle-item/index.vue +1 -1
- package/src/ui.container-modal/index.vue +1 -0
- package/src/ui.container-page/index.vue +4 -0
- package/src/ui.data-list/index.vue +1 -0
- package/src/ui.data-table/index.vue +5 -0
- package/src/ui.dropdown-badge/index.vue +1 -0
- package/src/ui.dropdown-button/index.vue +3 -3
- package/src/ui.dropdown-link/index.vue +1 -0
- package/src/ui.dropdown-list/index.vue +6 -4
- package/src/ui.form-calendar/index.vue +6 -1
- package/src/ui.form-checkbox/index.vue +3 -2
- package/src/ui.form-checkbox-group/index.vue +2 -0
- package/src/ui.form-checkbox-multi-state/index.vue +1 -0
- package/src/ui.form-color-picker/index.vue +3 -0
- package/src/ui.form-date-picker/index.vue +7 -4
- package/src/ui.form-date-picker-range/index.vue +19 -11
- package/src/ui.form-input/index.vue +3 -0
- package/src/ui.form-input-file/index.vue +2 -0
- package/src/ui.form-input-money/index.vue +3 -4
- package/src/ui.form-input-number/index.vue +3 -0
- package/src/ui.form-input-rating/index.vue +1 -0
- package/src/ui.form-input-search/index.vue +3 -0
- package/src/ui.form-radio/index.vue +2 -1
- package/src/ui.form-radio-card/index.vue +1 -0
- package/src/ui.form-select/index.vue +3 -0
- package/src/ui.form-switch/index.vue +1 -0
- package/src/ui.form-textarea/index.vue +2 -2
- package/src/ui.navigation-pagination/index.vue +2 -1
- package/src/ui.navigation-stepper/index.vue +1 -3
- package/src/ui.navigation-tabs/index.vue +1 -1
- package/src/ui.text-alert/index.vue +2 -1
- package/src/ui.text-empty/index.vue +1 -0
- package/src/ui.text-files/index.vue +1 -1
- package/vite.config.mjs +5 -4
- package/web-types.json +1 -1
- package/.web-types-gen/package.json +0 -3
- package/src/library.web-types-gen/index.js +0 -17
- package/src/library.web-types-gen/lib/build.js +0 -252
- package/src/library.web-types-gen/lib/config.js +0 -32
- package/src/library.web-types-gen/package.json +0 -3
- package/src/plugin.vite/index.js +0 -59
- package/src/plugin.vite/services/iconResolver.service.js +0 -291
- package/src/plugin.vite/services/svgLoader.service.js +0 -76
- package/src/plugin.vite/services/tailwindSafelist.service.js +0 -195
- package/src/plugin.vite/services/unpluginComponentsResolver.js +0 -172
package/vite.config.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import path from "path";
|
|
|
3
3
|
|
|
4
4
|
import Vue from "@vitejs/plugin-vue";
|
|
5
5
|
import Eslint from "vite-plugin-eslint";
|
|
6
|
-
import { Vueless, VuelessUnpluginComponents } from "vite-plugin
|
|
6
|
+
import { Vueless, VuelessUnpluginComponents } from "@vueless/vite-plugin";
|
|
7
7
|
|
|
8
8
|
export default defineConfig({
|
|
9
9
|
plugins: [
|
|
@@ -15,7 +15,7 @@ export default defineConfig({
|
|
|
15
15
|
resolve: {
|
|
16
16
|
extensions: [".vue", ".mjs", ".js", ".ts", ".mdx"],
|
|
17
17
|
alias: {
|
|
18
|
-
vueless: path.resolve(__dirname, "./src"),
|
|
18
|
+
"vueless/src": path.resolve(__dirname, "./src"),
|
|
19
19
|
},
|
|
20
20
|
},
|
|
21
21
|
optimizeDeps: {
|
|
@@ -27,13 +27,14 @@ export default defineConfig({
|
|
|
27
27
|
"@uppy/core",
|
|
28
28
|
"@uppy/vue/src/drag-drop",
|
|
29
29
|
//"@kyvg/vue3-notification",
|
|
30
|
-
"@storybook/theming/create",
|
|
31
30
|
//"@tailwindcss/forms",
|
|
32
|
-
"tailwindcss/colors",
|
|
31
|
+
"tailwindcss/colors.js",
|
|
33
32
|
"cva",
|
|
34
33
|
"tailwind-merge",
|
|
35
34
|
"prettier2",
|
|
36
35
|
"prettier2/parser-html",
|
|
36
|
+
"@storybook/blocks",
|
|
37
|
+
"@storybook/theming/create",
|
|
37
38
|
],
|
|
38
39
|
},
|
|
39
40
|
});
|
package/web-types.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import minimist from "minimist";
|
|
3
|
-
import { extractConfig } from "./lib/config.js";
|
|
4
|
-
import build from "./lib/build.js";
|
|
5
|
-
|
|
6
|
-
const {
|
|
7
|
-
_: pathArray,
|
|
8
|
-
configFile,
|
|
9
|
-
watch,
|
|
10
|
-
cwd,
|
|
11
|
-
} = minimist(process.argv.slice(2), {
|
|
12
|
-
alias: { c: "configFile", w: "watch" },
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
const conf = await extractConfig(cwd || process.cwd(), watch, configFile, pathArray);
|
|
16
|
-
|
|
17
|
-
build(conf);
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { globbySync } from "globby";
|
|
3
|
-
import * as chokidar from "chokidar";
|
|
4
|
-
import { parse } from "vue-docgen-api";
|
|
5
|
-
import * as fs from "fs";
|
|
6
|
-
import mkdirp from "mkdirp";
|
|
7
|
-
import _ from "lodash-es";
|
|
8
|
-
import { merge } from "lodash-es";
|
|
9
|
-
|
|
10
|
-
export default async function build(config) {
|
|
11
|
-
config.componentsRoot = path.resolve(config.cwd, config.componentsRoot);
|
|
12
|
-
config.outFile = path.resolve(config.cwd, config.outFile);
|
|
13
|
-
|
|
14
|
-
// then create the watcher if necessary
|
|
15
|
-
const { watcher, componentFiles } = getSources(config.components, config.componentsRoot);
|
|
16
|
-
|
|
17
|
-
// eslint-disable-next-line no-console
|
|
18
|
-
console.log("Building web-types to " + config.outFile);
|
|
19
|
-
|
|
20
|
-
const cache = {};
|
|
21
|
-
const buildWebTypesBound = rebuild.bind(null, config, componentFiles, cache, watcher);
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
await buildWebTypesBound();
|
|
25
|
-
} catch (e) {
|
|
26
|
-
// eslint-disable-next-line no-console
|
|
27
|
-
console.error("Error building web-types: " + e.message);
|
|
28
|
-
await watcher.close();
|
|
29
|
-
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (config.watch) {
|
|
34
|
-
watcher
|
|
35
|
-
.on("add", buildWebTypesBound)
|
|
36
|
-
.on("change", buildWebTypesBound)
|
|
37
|
-
.on("unlink", async (filePath) => {
|
|
38
|
-
// eslint-disable-next-line no-console
|
|
39
|
-
console.log("Rebuilding on file removal " + filePath);
|
|
40
|
-
delete cache[filePath];
|
|
41
|
-
await writeDownWebTypesFile(config, Object.values(cache), config.outFile);
|
|
42
|
-
});
|
|
43
|
-
} else {
|
|
44
|
-
await watcher.close();
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function getSources(components, cwd) {
|
|
49
|
-
const watcher = chokidar.watch(components, { cwd });
|
|
50
|
-
|
|
51
|
-
const allComponentFiles = globbySync(components, { cwd });
|
|
52
|
-
|
|
53
|
-
return { watcher, componentFiles: allComponentFiles };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async function rebuild(config, files, cachedContent, watcher, changedFilePath) {
|
|
57
|
-
const cacheWebTypesContent = async (filePath) => {
|
|
58
|
-
cachedContent[filePath.replace(/\\/g, "/")] = await extractInformation(
|
|
59
|
-
path.join(config.componentsRoot, filePath),
|
|
60
|
-
config,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
return true;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
if (changedFilePath) {
|
|
67
|
-
// eslint-disable-next-line no-console
|
|
68
|
-
console.log("Rebuilding on update file " + changedFilePath);
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
// if in chokidar mode (watch), the path of the file that was just changed
|
|
72
|
-
// is passed as an argument. We only affect the changed file and avoid re-parsing the rest
|
|
73
|
-
await cacheWebTypesContent(changedFilePath);
|
|
74
|
-
} catch (e) {
|
|
75
|
-
throw new Error(
|
|
76
|
-
`Error building file ${config.outFile} when file ${changedFilePath} has changed: ${e.message}`,
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
try {
|
|
81
|
-
// if we are initializing the current file, parse all components
|
|
82
|
-
await Promise.all(files.map(cacheWebTypesContent));
|
|
83
|
-
} catch (e) {
|
|
84
|
-
throw new Error(`Error building file ${config.outFile}: ${e.message}`);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// and finally save all concatenated values to the markdown file
|
|
89
|
-
await writeDownWebTypesFile(config, Object.values(cachedContent), config.outFile);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async function writeDownWebTypesFile(config, definitions, destFilePath) {
|
|
93
|
-
const destFolder = path.dirname(destFilePath);
|
|
94
|
-
|
|
95
|
-
await mkdirp(destFolder);
|
|
96
|
-
let writeStream = fs.createWriteStream(destFilePath);
|
|
97
|
-
const contents = {
|
|
98
|
-
framework: "vue",
|
|
99
|
-
name: config.packageName,
|
|
100
|
-
version: config.packageVersion,
|
|
101
|
-
contributions: {
|
|
102
|
-
html: {
|
|
103
|
-
"description-markup": config.descriptionMarkup,
|
|
104
|
-
"types-syntax": config.typesSyntax,
|
|
105
|
-
tags: _(definitions)
|
|
106
|
-
.flatMap((d) => d.tags || [])
|
|
107
|
-
.orderBy("name", "asc")
|
|
108
|
-
.value(),
|
|
109
|
-
attributes: _(definitions)
|
|
110
|
-
.flatMap((d) => d.attributes || [])
|
|
111
|
-
.orderBy("name", "asc")
|
|
112
|
-
.value(),
|
|
113
|
-
"vue-filters": _(definitions)
|
|
114
|
-
.flatMap((d) => d["vue-filters"] || [])
|
|
115
|
-
.orderBy("name", "asc")
|
|
116
|
-
.value(),
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const html = contents.contributions.html;
|
|
122
|
-
|
|
123
|
-
if (html.tags?.length == 0) html.tags = undefined;
|
|
124
|
-
if (html.attributes?.length == 0) html.attributes = undefined;
|
|
125
|
-
if (html["vue-filters"]?.length == 0) html["vue-filters"] = undefined;
|
|
126
|
-
|
|
127
|
-
writeStream.write(JSON.stringify(contents, null, 2));
|
|
128
|
-
|
|
129
|
-
// close the stream
|
|
130
|
-
writeStream.close();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function ensureRelative(path) {
|
|
134
|
-
// The .replace() is a fix for paths that end up like "./src\\components\\General\\VerticalButton.vue" on windows machines.
|
|
135
|
-
return (path.startsWith("./") || path.startsWith("../") ? path : "./" + path).replace(/\\/g, "/");
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async function extractInformation(absolutePath, config) {
|
|
139
|
-
const doc = await parse(absolutePath, config.apiOptions);
|
|
140
|
-
const name = doc.name || doc.displayName;
|
|
141
|
-
let description = doc.description?.trim() ?? "";
|
|
142
|
-
|
|
143
|
-
// Get default component config
|
|
144
|
-
const configPath = path.join(path.dirname(absolutePath), "configs/default.config.js");
|
|
145
|
-
let globalConfig = null;
|
|
146
|
-
let defaultConfig = null;
|
|
147
|
-
let defaultValues = null;
|
|
148
|
-
|
|
149
|
-
if (fs.existsSync(configPath)) {
|
|
150
|
-
const defaultConfigFile = fs.readFileSync(configPath).toString();
|
|
151
|
-
const globalConfigFile = fs.readFileSync(config.cwd + "/vueless.config.js").toString();
|
|
152
|
-
|
|
153
|
-
defaultConfig = getDefaultConfigJson(defaultConfigFile);
|
|
154
|
-
globalConfig = getGlobalConfigJson(globalConfigFile, name);
|
|
155
|
-
defaultValues = merge(defaultConfig.defaultVariants, globalConfig[name]?.defaultVariants);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function getDefaultConfigJson(fileContents) {
|
|
159
|
-
const objectStartIndex = fileContents.indexOf("{");
|
|
160
|
-
const variablePattern = /([^:]+):\s*(?!true|false|undefined)([a-zA-Z_]\w*)/g;
|
|
161
|
-
let objectString = fileContents
|
|
162
|
-
.substring(objectStartIndex)
|
|
163
|
-
.replace("};", "}")
|
|
164
|
-
.replace(/undefined/g, '"undefined"')
|
|
165
|
-
.replace(variablePattern, (match, key) => key + ": {}");
|
|
166
|
-
|
|
167
|
-
return eval("(" + objectString + ")"); // Converting into JS object
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function getGlobalConfigJson(fileContents, componentName) {
|
|
171
|
-
const startIndex = fileContents.indexOf(`${componentName}:`);
|
|
172
|
-
|
|
173
|
-
// find index of the last closing bracket
|
|
174
|
-
let endIndex = -1;
|
|
175
|
-
let braceCount = 0;
|
|
176
|
-
|
|
177
|
-
for (let i = startIndex; i < fileContents.length; i++) {
|
|
178
|
-
if (fileContents[i] === "{") {
|
|
179
|
-
braceCount++;
|
|
180
|
-
} else if (fileContents[i] === "}") {
|
|
181
|
-
braceCount--;
|
|
182
|
-
|
|
183
|
-
if (braceCount === 0) {
|
|
184
|
-
endIndex = i;
|
|
185
|
-
break;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Get component config raw string
|
|
191
|
-
const rawString = fileContents.slice(startIndex, endIndex);
|
|
192
|
-
|
|
193
|
-
// If the stings are present in config but commented - remove them
|
|
194
|
-
const stringWithoutComments = rawString.replace(/\/\/.*$/gm, "");
|
|
195
|
-
|
|
196
|
-
// Check if final JSON string is valid: TODO: find better solution
|
|
197
|
-
if (!stringWithoutComments.includes("}")) return {};
|
|
198
|
-
|
|
199
|
-
const jsonString = `{${stringWithoutComments}\n}}`
|
|
200
|
-
.replace(/[`']/g, '"')
|
|
201
|
-
.replace(/(\w+)\s*: /g, '"$1":')
|
|
202
|
-
.replace(/,\s*}/g, "}");
|
|
203
|
-
|
|
204
|
-
return JSON.parse(jsonString);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
doc.docsBlocks?.forEach((block) => {
|
|
208
|
-
if (description.length > 0) {
|
|
209
|
-
if (config.descriptionMarkup === "html") {
|
|
210
|
-
description += "<br/><br/>";
|
|
211
|
-
} else {
|
|
212
|
-
description += "\n\n";
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
description += block;
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
return {
|
|
220
|
-
tags: [
|
|
221
|
-
{
|
|
222
|
-
name,
|
|
223
|
-
description,
|
|
224
|
-
attributes: doc.props?.map((prop) => ({
|
|
225
|
-
name: prop.name,
|
|
226
|
-
required: prop.required,
|
|
227
|
-
description: prop.tags?.ignore ? "@ignore: " + prop.description : prop.description,
|
|
228
|
-
value: {
|
|
229
|
-
kind: "expression",
|
|
230
|
-
type: prop.values ? `'${prop.values.join("' | '")}'` : prop.type?.name ?? "any",
|
|
231
|
-
},
|
|
232
|
-
default:
|
|
233
|
-
defaultValues && prop.name in defaultValues
|
|
234
|
-
? defaultValues[prop.name].toString()
|
|
235
|
-
: prop.defaultValue?.value.toString(),
|
|
236
|
-
})),
|
|
237
|
-
events: doc.events?.map((event) => ({
|
|
238
|
-
name: event.name,
|
|
239
|
-
description: event.description,
|
|
240
|
-
})),
|
|
241
|
-
slots: doc.slots?.map((slot) => ({
|
|
242
|
-
name: slot.name,
|
|
243
|
-
description: slot.description,
|
|
244
|
-
})),
|
|
245
|
-
source: {
|
|
246
|
-
module: ensureRelative(path.relative(config.cwd, absolutePath)).substring(1), // TODO: maybe substring should be removed when it turns to package
|
|
247
|
-
symbol: doc.exportName,
|
|
248
|
-
},
|
|
249
|
-
},
|
|
250
|
-
],
|
|
251
|
-
};
|
|
252
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import { readFile } from "fs/promises";
|
|
4
|
-
|
|
5
|
-
export async function extractConfig(cwd, watch = false, configFileFromCmd, pathArray = []) {
|
|
6
|
-
const configFilePath = configFileFromCmd
|
|
7
|
-
? path.resolve(cwd, configFileFromCmd)
|
|
8
|
-
: path.join(cwd, "web-types.config.js");
|
|
9
|
-
const [componentsFromCmd, outFileFromCmd] = pathArray;
|
|
10
|
-
|
|
11
|
-
const fileContent = await readFile(path.join(cwd, "package.json"), "utf-8");
|
|
12
|
-
const packageJson = JSON.parse(fileContent);
|
|
13
|
-
|
|
14
|
-
let additionalConfig = {};
|
|
15
|
-
|
|
16
|
-
if (fs.existsSync(configFilePath)) {
|
|
17
|
-
additionalConfig = await import(configFilePath);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
cwd,
|
|
22
|
-
watch,
|
|
23
|
-
componentsRoot: configFilePath ? path.dirname(configFilePath) : cwd,
|
|
24
|
-
components: componentsFromCmd || "(.vueless/**/*.vue|src/components/**/*.vue)",
|
|
25
|
-
outFile: outFileFromCmd || packageJson["web-types"] || "./web-types.json",
|
|
26
|
-
packageName: packageJson["name"],
|
|
27
|
-
packageVersion: packageJson["version"],
|
|
28
|
-
typesSyntax: "typescript",
|
|
29
|
-
descriptionMarkup: "markdown",
|
|
30
|
-
...additionalConfig,
|
|
31
|
-
};
|
|
32
|
-
}
|
package/src/plugin.vite/index.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
|
|
3
|
-
import UnpluginVueComponents from "unplugin-vue-components/vite";
|
|
4
|
-
import unpluginComponentsResolver from "./services/unpluginComponentsResolver";
|
|
5
|
-
import { copyIcons, removeIcons } from "./services/iconResolver.service";
|
|
6
|
-
import { loadSvg } from "./services/svgLoader.service";
|
|
7
|
-
import { createTailwindSafelist } from "./services/tailwindSafelist.service";
|
|
8
|
-
|
|
9
|
-
/* Automatically importing Vueless components on demand */
|
|
10
|
-
export const VuelessUnpluginComponents = (options) =>
|
|
11
|
-
UnpluginVueComponents({
|
|
12
|
-
resolvers: [unpluginComponentsResolver],
|
|
13
|
-
dts: false,
|
|
14
|
-
...options,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
/*
|
|
18
|
-
– Creates tailwind colors safelist (collect only used on the project colors).
|
|
19
|
-
– Collects SVG icons for build (UIcon bundle size optimization).
|
|
20
|
-
– Loads SVG images as a Vue components.
|
|
21
|
-
*/
|
|
22
|
-
export const Vueless = function (options = {}) {
|
|
23
|
-
/* remove icons if server stopped */
|
|
24
|
-
process.on("SIGINT", () => {
|
|
25
|
-
removeIcons(options.debug);
|
|
26
|
-
process.exit(0);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
name: "vite-plugin-vue-vueless",
|
|
31
|
-
enforce: "pre",
|
|
32
|
-
|
|
33
|
-
config: () => ({
|
|
34
|
-
define: {
|
|
35
|
-
"process.env": {},
|
|
36
|
-
},
|
|
37
|
-
}),
|
|
38
|
-
|
|
39
|
-
configResolved: (config) => {
|
|
40
|
-
if (config.command === "build") {
|
|
41
|
-
/* collect used in project colors for tailwind safelist */
|
|
42
|
-
createTailwindSafelist();
|
|
43
|
-
/* dynamically copy icons before build */
|
|
44
|
-
copyIcons(options.mode, options.debug);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (config.command === "dev" || config.command === "serve") {
|
|
48
|
-
/* remove dynamically copied icons after build */
|
|
49
|
-
removeIcons(options.debug);
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
/* remove dynamically copied icons after build */
|
|
54
|
-
buildEnd: () => removeIcons(options.debug),
|
|
55
|
-
|
|
56
|
-
/* load SVG images as a Vue components */
|
|
57
|
-
load: async (id) => await loadSvg(id, options),
|
|
58
|
-
};
|
|
59
|
-
};
|