@lyda/kilo-ui 0.1.4 → 0.1.5

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/README.md CHANGED
@@ -12,11 +12,11 @@ After you **publish** this project to npm, install the **exact** `name` from its
12
12
  **Do not** run `npm install -D kilo-ui` expecting this Vue CLI — the public npm name `kilo-ui` is already used by a different project.
13
13
 
14
14
  ```bash
15
- npm install -D @lyda/kilo-ui
15
+ npm install -D @lyda/kilo-ui@latest
16
16
  npx kilo-ui add data-table
17
17
  ```
18
18
 
19
- **First install in a new project:** the package **postinstall** runs `kilo-ui init` once (unless `kilo.config.ts` already exists). That creates **`kilo.config.ts` in your app root** (next to `package.json`) — not inside `node_modules`. Edit it for **aliases**, **`ui.componentsDir`** (folder prefix under `src/components`, default `ui`), and **Tailwind CSS path**. An annotated example ships with the library at **`node_modules/@lyda/kilo-ui/config/kilo.config.example.ts`**. If install used **`--ignore-scripts`**, run **`npx kilo-ui init`** once yourself.
19
+ **First install in a new project:** the package **postinstall** runs `kilo-ui init` once (unless `kilo.config.ts` already exists). That creates **`kilo.config.ts` in your app root** (next to `package.json`) — not inside `node_modules`. Edit **`ui.componentsDir`** (or **`componentsPrefix`**) for the install folder (e.g. `ki` `src/components/ki/...`). If the folder is not `ui`, **`kilo-ui add`** injects **`defineOptions({ name: "KiCardBox" })`** so you can use **`<KiCardBox />`** (prefix + file name). Use **`ui.componentTagPrefix: false`** to skip that. An annotated example ships at **`node_modules/@lyda/kilo-ui/config/kilo.config.example.ts`**. If install used **`--ignore-scripts`**, run **`npx kilo-ui init`** once yourself.
20
20
 
21
21
  You can still run **`npx kilo-ui init`** anytime to add missing scaffold files; use **`init --force`** to reset **`kilo.config.ts`** to defaults (back up first if you customized it).
22
22
 
package/bin/kilo-ui.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createJiti } from 'jiti'
3
3
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
4
- import { dirname, join, relative, resolve } from 'node:path'
4
+ import { basename, dirname, join, relative, resolve } from 'node:path'
5
5
  import { fileURLToPath } from 'node:url'
6
6
 
7
7
  const __dirname = dirname(fileURLToPath(import.meta.url))
@@ -92,6 +92,45 @@ function normalizeConfig(raw) {
92
92
  return c
93
93
  }
94
94
 
95
+ /** "ki" → "Ki", "my-kit" → "MyKit" */
96
+ function segmentToPascal(segment) {
97
+ return String(segment)
98
+ .split(/[^a-zA-Z0-9]+/)
99
+ .filter(Boolean)
100
+ .map((p) => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase())
101
+ .join('')
102
+ }
103
+
104
+ /** Pascal prefix for defineOptions name, or null if disabled / default ui folder. */
105
+ function effectiveDevTagPrefix(config) {
106
+ const v = config.ui?.componentTagPrefix
107
+ if (v === false) return null
108
+ if (typeof v === 'string' && v.trim().length) return segmentToPascal(v.trim())
109
+
110
+ const segs = componentDirSegments(config)
111
+ const first = segs[0]
112
+ if (!first) return null
113
+ if (first.toLowerCase() === 'ui') return null
114
+ return segmentToPascal(first)
115
+ }
116
+
117
+ function vueResolvedComponentName(config, fileBaseNoExt) {
118
+ const prefix = effectiveDevTagPrefix(config)
119
+ if (!prefix) return null
120
+ return `${prefix}${fileBaseNoExt}`
121
+ }
122
+
123
+ function injectVueComponentName(content, name) {
124
+ if (/\bdefineOptions\s*\(/.test(content)) return content
125
+ const safe = String(name).replace(/[^A-Za-z0-9_]/g, '')
126
+ if (!safe) return content
127
+ const injectLine = `defineOptions({ name: '${safe}' })\n`
128
+ const m = content.match(/<script setup[^>]*>/)
129
+ if (!m || m.index === undefined) return content
130
+ const end = m.index + m[0].length
131
+ return `${content.slice(0, end)}\n${injectLine}${content.slice(end)}`
132
+ }
133
+
95
134
  function hasKiloModuleConfig(cwd) {
96
135
  return CONFIG_MODULES.some((name) => existsSync(join(cwd, name)))
97
136
  }
@@ -166,11 +205,18 @@ function componentFilePath(config, componentName, fileName) {
166
205
  function copyRegistryFile(sourceRelative, targetPath, config, force) {
167
206
  const sourcePath = join(registryRoot, sourceRelative)
168
207
  if (!existsSync(sourcePath)) fail(`Registry file not found: ${sourceRelative}`)
169
- const content = readFileSync(sourcePath, 'utf8')
208
+ let content = readFileSync(sourcePath, 'utf8')
170
209
  .replaceAll('__COMPONENTS_ALIAS__', config.aliases.components)
171
210
  .replaceAll('__COMPOSABLES_ALIAS__', config.aliases.composables)
172
211
  .replaceAll('__LIB_ALIAS__', config.aliases.lib)
173
212
  .replaceAll('__TYPES_ALIAS__', config.aliases.types)
213
+
214
+ if (targetPath.endsWith('.vue')) {
215
+ const base = basename(targetPath, '.vue')
216
+ const devName = vueResolvedComponentName(config, base)
217
+ if (devName) content = injectVueComponentName(content, devName)
218
+ }
219
+
174
220
  writeFile(targetPath, content, force)
175
221
  }
176
222
 
@@ -192,7 +238,7 @@ function kiloConfigSerializable(config) {
192
238
  function buildKiloConfigFileContent(config) {
193
239
  const obj = kiloConfigSerializable(config)
194
240
  const body = JSON.stringify(obj, null, 2)
195
- const header = `// Kilo UI — app config (generated in your project root by ${pkgName}, not inside the library package)\n// ui.componentsDir = folder prefix under aliases.components (default "ui" → …/components/ui/<component>/)\n// Use "" for no prefix: …/components/<component>/\n\n`
241
+ const header = `// Kilo UI — app config (generated in your project root by ${pkgName}, not inside the library package)\n// ui.componentsDir / componentsPrefix = folder under aliases.components (default "ui")\n// If folder is not "ui", copied .vue files get defineOptions({ name: "<Prefix><FileName>" }) for <PrefixFileName /> in templates (override with ui.componentTagPrefix: false or a string).\n\n`
196
242
  return `${header}import { defineConfig } from '${pkgName}/config'\n\nexport default defineConfig(${body})\n`
197
243
  }
198
244
 
@@ -306,6 +352,11 @@ function init(args) {
306
352
 
307
353
  writeKiloConfigTs(cwd, config, force)
308
354
 
355
+ // Create the base folder for installed components so users can see it immediately after install/init.
356
+ // Actual component subfolders are created by `kilo-ui add`.
357
+ const baseComponents = join(cwd, aliasPath(config, 'components'), ...componentDirSegments(config))
358
+ if (baseComponents) ensureDir(baseComponents)
359
+
309
360
  copyRegistryFile('styles/teamwork-ui.css', join(process.cwd(), config.tailwind.css), config, force)
310
361
  copyRegistryFile('lib/utils.ts', resolveTarget(config, 'lib', 'utils.ts'), config, force)
311
362
  copyRegistryFile('vue/env.d.ts', join(process.cwd(), 'env.d.ts'), config, force)
@@ -11,6 +11,12 @@ export interface KiloUiUserConfig {
11
11
  componentsDir?: string
12
12
  /** Same as `componentsDir` if you prefer the name “prefix”. */
13
13
  componentsPrefix?: string
14
+ /**
15
+ * Pascal prefix for Vue `defineOptions({ name })` on copied `.vue` files so you can use
16
+ * `<KiCardBox />` in templates when folder prefix is `ki` (auto: from first folder segment unless it is `ui`).
17
+ * Set a string to force (e.g. `"Ki"`). Set `false` to disable injection.
18
+ */
19
+ componentTagPrefix?: string | false
14
20
  }
15
21
  tailwind?: {
16
22
  css: string
@@ -7,6 +7,9 @@
7
7
  *
8
8
  * Change **`ui.componentsDir`** to set the folder prefix under your components path
9
9
  * (e.g. `"ui"` → src/components/ui/data-table/…). Use `componentsPrefix` as an alias.
10
+ *
11
+ * With a non-`ui` folder (e.g. `"ki"`), `kilo-ui add` injects `defineOptions({ name: "KiCardBox" })`
12
+ * so you can use `<KiCardBox />` in templates. Override with `ui.componentTagPrefix` (`string` or `false`).
10
13
  */
11
14
  import { defineConfig } from '@lyda/kilo-ui/config'
12
15
 
@@ -16,6 +19,8 @@ export default defineConfig({
16
19
  ui: {
17
20
  /** Folder prefix under `aliases.components` for copied registry components */
18
21
  componentsDir: 'ui',
22
+ /** Set `false` to skip defineOptions name injection; set a string to force tag prefix */
23
+ // componentTagPrefix: false,
19
24
  },
20
25
  tailwind: {
21
26
  css: 'src/styles/teamwork-ui.css',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lyda/kilo-ui",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "shadcn-style Vue component registry for team CRUD apps",
5
5
  "type": "module",
6
6
  "repository": {