@nubisco/ui 1.7.0 → 1.7.2

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.
@@ -0,0 +1,40 @@
1
+ import fs from 'fs';
2
+ import { resolve as resolver } from 'path';
3
+ import str2kebab from '../utils/str2kebab.helper';
4
+ import kebab2camel from '../utils/kebab2camel.helper';
5
+ // Inline type helper to avoid esbuild resolution issues during config loading
6
+ const VitePlugin = (p) => p;
7
+ const virtualModuleId = 'virtual:flags';
8
+ const resolvedVirtualModuleId = '\0' + virtualModuleId;
9
+ export const flags = (basePath) => VitePlugin({
10
+ name: 'flags',
11
+ resolveId(id) {
12
+ if (id === virtualModuleId) {
13
+ return resolvedVirtualModuleId;
14
+ }
15
+ },
16
+ load(id) {
17
+ if (id !== resolvedVirtualModuleId)
18
+ return;
19
+ const result = [`import { defineAsyncComponent } from 'vue'\n`];
20
+ const names = [];
21
+ const flagsDir = resolver(basePath, 'src/assets/flags');
22
+ if (!fs.existsSync(flagsDir)) {
23
+ return `export default {}`;
24
+ }
25
+ fs.readdirSync(flagsDir)
26
+ .filter((file) => file !== 'index.js')
27
+ .filter((file) => file.toLowerCase().endsWith('.svg'))
28
+ .map((file) => {
29
+ const [fileName] = file.split('.');
30
+ return fileName;
31
+ })
32
+ .forEach((file) => {
33
+ const varName = kebab2camel(str2kebab(`f-${file}`));
34
+ result.push(`const ${varName} = defineAsyncComponent(() => import('@/assets/flags/${file}.svg'))`);
35
+ names.push(varName);
36
+ });
37
+ result.push(`\nexport default {\n${names.join(',\n')}\n}`);
38
+ return result.join('\n');
39
+ },
40
+ });
@@ -0,0 +1,16 @@
1
+ import Unfonts from 'unplugin-fonts/vite';
2
+ export const fonts = () => Unfonts({
3
+ google: {
4
+ injectTo: 'head-prepend',
5
+ families: [
6
+ {
7
+ name: 'Plus+Jakarta+Sans',
8
+ styles: 'ital,wght@0,200..800;1,200..800',
9
+ },
10
+ {
11
+ name: 'Fira+Code',
12
+ styles: 'wght@300..700',
13
+ },
14
+ ],
15
+ },
16
+ });
@@ -0,0 +1,59 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ /**
4
+ * Vite plugin that auto-generates src/global.d.ts by scanning src/components/*.vue.
5
+ * Runs at build start and in watch mode so the file is always up to date.
6
+ */
7
+ export function globalTypes(basePath) {
8
+ function generate() {
9
+ const componentsDir = path.resolve(basePath, 'src/components');
10
+ const outFile = path.resolve(basePath, 'src/global.d.ts');
11
+ const files = fs
12
+ .readdirSync(componentsDir)
13
+ .filter((f) => f.endsWith('.vue'))
14
+ .sort();
15
+ const imports = files
16
+ .map((f) => {
17
+ const name = f.replace('.vue', '');
18
+ return `import ${name} from './components/${f}'`;
19
+ })
20
+ .join('\n');
21
+ const entries = files
22
+ .map((f) => {
23
+ const name = f.replace('.vue', '');
24
+ return ` Nb${name}: typeof ${name}`;
25
+ })
26
+ .join('\n');
27
+ const content = `// AUTO-GENERATED: do not edit by hand
28
+ // Re-run the build to update this file when components change
29
+ ${imports}
30
+
31
+ declare module 'vue' {
32
+ interface IGlobalComponents {
33
+ ${entries}
34
+ }
35
+ }
36
+
37
+ export {}
38
+ `;
39
+ fs.writeFileSync(outFile, content, 'utf8');
40
+ console.log(`[globalTypes] wrote src/global.d.ts (${files.length} components)`);
41
+ }
42
+ return {
43
+ name: 'global-types',
44
+ buildStart() {
45
+ generate();
46
+ },
47
+ configureServer(server) {
48
+ // Regenerate on component add/remove in dev mode
49
+ server.watcher.on('add', (f) => {
50
+ if (f.includes('/components/') && f.endsWith('.vue'))
51
+ generate();
52
+ });
53
+ server.watcher.on('unlink', (f) => {
54
+ if (f.includes('/components/') && f.endsWith('.vue'))
55
+ generate();
56
+ });
57
+ },
58
+ };
59
+ }
@@ -0,0 +1,56 @@
1
+ import path from 'path';
2
+ import { createRequire } from 'module';
3
+ // Inline type helper to avoid esbuild resolution issues during config loading
4
+ const VitePlugin = (p) => p;
5
+ const virtualModuleId = 'virtual:icons';
6
+ const resolvedVirtualModuleId = '\0' + virtualModuleId;
7
+ const WEIGHTS = ['bold', 'duotone', 'fill', 'light', 'regular', 'thin'];
8
+ export const icons = () => VitePlugin({
9
+ name: 'icons',
10
+ resolveId(id) {
11
+ if (id === virtualModuleId) {
12
+ return resolvedVirtualModuleId;
13
+ }
14
+ },
15
+ load(id) {
16
+ if (id === resolvedVirtualModuleId) {
17
+ const _require = createRequire(import.meta.url);
18
+ const { icons: phosphorIcons } = _require('@phosphor-icons/core');
19
+ const phosphorAssetsPath = path.resolve(process.cwd(), 'node_modules/@phosphor-icons/core/assets');
20
+ const lines = ['import { defineAsyncComponent } from "vue"'];
21
+ const iconVariables = {};
22
+ const catalogEntries = [];
23
+ phosphorIcons.forEach((icon) => {
24
+ const iconKey = `i${icon.pascal_name}`;
25
+ iconVariables[iconKey] = {};
26
+ WEIGHTS.forEach((weight) => {
27
+ const varName = `${iconKey}_${weight}`;
28
+ const filename = weight === 'regular'
29
+ ? `${icon.name}.svg`
30
+ : `${icon.name}-${weight}.svg`;
31
+ const filePath = path.resolve(phosphorAssetsPath, weight, filename);
32
+ lines.push(`const ${varName} = defineAsyncComponent(() => import("${filePath}"))`);
33
+ iconVariables[iconKey][weight] = varName;
34
+ });
35
+ // Strip meta-tags (wrapped in asterisks like *new*, *updated*)
36
+ const tags = icon.tags.filter((t) => !t.startsWith('*'));
37
+ catalogEntries.push(` "${iconKey}": { name: ${JSON.stringify(icon.name)}, tags: ${JSON.stringify(tags)}, categories: ${JSON.stringify([...icon.categories])} }`);
38
+ });
39
+ // Named export: static metadata for each icon (name, tags, categories)
40
+ lines.push(`\nexport const catalog = {`);
41
+ lines.push(catalogEntries.join(',\n'));
42
+ lines.push(`}`);
43
+ // Default export: component map
44
+ const componentEntries = Object.entries(iconVariables).map(([iconKey, weights]) => {
45
+ const weightLines = Object.entries(weights)
46
+ .map(([weight, varName]) => ` "${weight}": ${varName}`)
47
+ .join(',\n');
48
+ return ` "${iconKey}": {\n${weightLines}\n }`;
49
+ });
50
+ lines.push(`\nexport default {`);
51
+ lines.push(componentEntries.join(',\n'));
52
+ lines.push(`}`);
53
+ return lines.join('\n');
54
+ }
55
+ },
56
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Converts kebab-case tokens to lower camelCase.
3
+ */
4
+ export function kebab2camel(str) {
5
+ return str.toLowerCase().replace(/-([a-z0-9])/g, (g) => {
6
+ return g[1].toUpperCase();
7
+ });
8
+ }
9
+ export default kebab2camel;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Normalizes an identifier-like string into kebab-case.
3
+ * Handles camelCase, PascalCase, snake_case, and whitespace-delimited input.
4
+ */
5
+ export function str2kebab(source) {
6
+ return source
7
+ .replace(/(?<=[A-Z0-9])([A-Z])(?=[a-z])/g, ' $1')
8
+ .replace(/_/g, ' ')
9
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
10
+ .replace(/\s+/g, '-')
11
+ .toLowerCase();
12
+ }
13
+ export default str2kebab;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nubisco/ui",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "Vue 3 UI component library",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,7 +41,7 @@
41
41
  "./dist/ui.css": "./dist/ui.css",
42
42
  "./plugins/*": {
43
43
  "types": "./dist/plugins/*.d.ts",
44
- "import": "./src/plugins/*"
44
+ "import": "./dist/plugins/*.js"
45
45
  },
46
46
  "./components/*": {
47
47
  "types": "./dist/components/*.d.ts",
@@ -76,9 +76,10 @@
76
76
  "scripts": {
77
77
  "clean": "rm -rf dist",
78
78
  "prebuild": "pnpm run clean",
79
- "build": "pnpm run build:lib && pnpm run build:types",
79
+ "build": "pnpm run build:lib && pnpm run build:types && pnpm run build:plugins",
80
80
  "build:lib": "vite build",
81
81
  "build:types": "vue-tsc --noEmit false --declaration --emitDeclarationOnly --outDir dist",
82
+ "build:plugins": "tsc --project tsconfig.plugins.json",
82
83
  "dev": "vite build --watch",
83
84
  "prepublishOnly": "pnpm run build",
84
85
  "test": "vitest run",
@@ -1,8 +1,8 @@
1
1
  import fs from 'fs'
2
2
  import { resolve as resolver } from 'path'
3
3
  import type { Plugin } from 'vite'
4
- import str2kebab from '../utils/str2kebab.helper.ts'
5
- import kebab2camel from '../utils/kebab2camel.helper.ts'
4
+ import str2kebab from '../utils/str2kebab.helper'
5
+ import kebab2camel from '../utils/kebab2camel.helper'
6
6
 
7
7
  // Inline type helper to avoid esbuild resolution issues during config loading
8
8
  const VitePlugin = <T extends Plugin>(p: T): Plugin & T => p