@nons-dev/uikit 0.1.6 → 0.1.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nons-dev/uikit",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "license": "BUSL-1.1",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,6 +20,7 @@
20
20
  "files": [
21
21
  "dist",
22
22
  "generated/components.json",
23
+ "locales",
23
24
  "scripts/cli.mjs",
24
25
  "readme.md"
25
26
  ],
@@ -36,9 +37,8 @@
36
37
  },
37
38
  "scripts": {
38
39
  "dev": "vite",
39
- "build": "npm run generate && vue-tsc -b && vite build && node scripts/copy-fonts.mjs",
40
- "preview": "vite preview",
41
- "generate": "tsx scripts/generate.ts"
40
+ "build": "vue-tsc -b && vite build && node scripts/copy-fonts.mjs",
41
+ "preview": "vite preview"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "vue": "^3.5.0"
@@ -48,10 +48,8 @@
48
48
  "js-yaml": "^5.1.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@types/js-yaml": "^4.0.9",
52
51
  "@types/node": "^26.0.1",
53
52
  "@vitejs/plugin-vue": "^5.2.3",
54
- "tsx": "^4.22.4",
55
53
  "typescript": "~5.7.3",
56
54
  "vite": "^6.3.3",
57
55
  "vite-plugin-dts": "^5.0.3",
package/scripts/cli.mjs CHANGED
@@ -40,17 +40,6 @@ font:
40
40
  family: IRANSansX
41
41
  en:
42
42
  family: Satoshi
43
- # Faces loaded automatically from @nons-dev/uikit/dist/font/
44
- # Uncomment and customize src to use your own font files:
45
- # faces:
46
- # - family: Satoshi
47
- # weight: 400
48
- # src: fonts/Satoshi-Regular.woff2
49
- # format: woff2
50
- # - family: IRANSansX
51
- # weight: 400
52
- # src: fonts/IRANSansX-Regular.woff
53
- # format: woff
54
43
 
55
44
  tokens:
56
45
  colors:
@@ -204,6 +193,20 @@ theme-mappings:
204
193
  --overlay-bg: rgba(0, 0, 0, 0.6)
205
194
  `
206
195
 
196
+ const LOCALE_FA = JSON.stringify({
197
+ app: { name: 'نونز', footer: 'پنل مدیریت' },
198
+ nav: { dashboard: 'داشبورد', users: 'کاربران', stores: 'فروشگاه‌ها', products: 'محصولات', orders: 'سفارشات', chat: 'گفتگو', reports: 'گزارشات', stats: 'آمار', components: 'کامپوننت‌ها' },
199
+ table: { empty: 'هیچ داده‌ای یافت نشد.' },
200
+ loading: { text: 'در حال بارگذاری...' },
201
+ }, null, 2)
202
+
203
+ const LOCALE_EN = JSON.stringify({
204
+ app: { name: 'Nons', footer: 'Admin Panel' },
205
+ nav: { dashboard: 'Dashboard', users: 'Users', stores: 'Stores', products: 'Products', orders: 'Orders', chat: 'Chat', reports: 'Reports', stats: 'Stats', components: 'Components' },
206
+ table: { empty: 'No data found.' },
207
+ loading: { text: 'Loading...' },
208
+ }, null, 2)
209
+
207
210
  // ── Data ──
208
211
 
209
212
  function loadComponents() {
@@ -231,147 +234,82 @@ function searchComponents(data, query) {
231
234
  )
232
235
  }
233
236
 
234
- // ── Generate helpers ──
235
-
236
- function writeTokenBlock(tokens, indent) {
237
- return Object.entries(tokens || {}).map(([k, v]) => `${indent}${k}: ${v};`).join('\n')
238
- }
239
-
240
- function generateFontCSS(config) {
241
- const faces = config.font?.faces
242
- if (!faces || !faces.length) return ''
243
- const lines = []
244
- for (const face of faces) {
245
- lines.push('@font-face {')
246
- lines.push(` font-family: '${face.family}';`)
247
- lines.push(` src: url('./${face.src}') format('${face.format}');`)
248
- lines.push(` font-weight: ${face.weight};`)
249
- lines.push(' font-style: normal;')
250
- lines.push(' font-display: swap;')
251
- lines.push('}')
252
- lines.push('')
253
- }
254
- return lines.join('\n')
255
- }
256
-
257
- function generateTokensCSS(config) {
258
- const lines = []
259
- const fonts = generateFontCSS(config)
260
- if (fonts) lines.push(fonts)
261
-
262
- const t = config.tokens || {}
263
-
264
- // Light & dark color schemes
265
- const hasLight = t.colors?.light && Object.keys(t.colors.light).length
266
- const hasDark = t.colors?.dark && Object.keys(t.colors.dark).length
237
+ // ── Commands ──
267
238
 
268
- if (hasLight) {
269
- lines.push(':root {')
270
- lines.push(' color-scheme: light;')
271
- lines.push(writeTokenBlock(t.colors.light, ' '))
272
- lines.push('}')
273
- lines.push('')
239
+ function cmdInit() {
240
+ const configDest = path.join(CWD, 'nons.config.yaml')
241
+ if (fs.existsSync(configDest)) {
242
+ console.log(`${YELLOW}⚠${RESET} nons.config.yaml already exists — skipping.`)
243
+ return
274
244
  }
245
+ fs.writeFileSync(configDest, DEFAULT_CONFIG, 'utf-8')
246
+ console.log(`${GREEN}✓${RESET} nons.config.yaml created`)
275
247
 
276
- if (hasDark) {
277
- lines.push('[data-theme="dark"] {')
278
- lines.push(' color-scheme: dark;')
279
- lines.push(writeTokenBlock(t.colors.dark, ' '))
280
- lines.push('}')
281
- lines.push('')
248
+ const localesDir = path.join(CWD, 'locales')
249
+ if (!fs.existsSync(localesDir)) {
250
+ fs.mkdirSync(localesDir, { recursive: true })
251
+ console.log(`${GREEN}✓${RESET} locales/ directory created`)
282
252
  }
283
253
 
284
- // Flat token sections (no light/dark split)
285
- const flatSections = {
286
- spacing: 'Spacing', typography: 'Typography', radius: 'Border Radius',
287
- 'z-index': 'Z-Index', opacity: 'Opacity', button: 'Button', alert: 'Alert',
288
- }
289
- for (const [section, label] of Object.entries(flatSections)) {
290
- const tokens = t[section]
291
- if (!tokens || !Object.keys(tokens).length) continue
292
- lines.push(`/* ${label} */`)
293
- lines.push(':root {')
294
- lines.push(writeTokenBlock(tokens, ' '))
295
- lines.push('}')
296
- lines.push('')
254
+ const faPath = path.join(localesDir, 'fa.json')
255
+ if (!fs.existsSync(faPath)) {
256
+ fs.writeFileSync(faPath, LOCALE_FA, 'utf-8')
257
+ console.log(`${GREEN}✓${RESET} locales/fa.json created`)
297
258
  }
298
259
 
299
- // Shadows (light + dark)
300
- const hasShadowLight = t.shadows?.light && Object.keys(t.shadows.light).length
301
- const hasShadowDark = t.shadows?.dark && Object.keys(t.shadows.dark).length
302
- if (hasShadowLight) {
303
- lines.push(':root {')
304
- lines.push(' color-scheme: light;')
305
- lines.push(writeTokenBlock(t.shadows.light, ' '))
306
- lines.push('}')
307
- lines.push('')
308
- }
309
- if (hasShadowDark) {
310
- lines.push('[data-theme="dark"] {')
311
- lines.push(' color-scheme: dark;')
312
- lines.push(writeTokenBlock(t.shadows.dark, ' '))
313
- lines.push('}')
314
- lines.push('')
260
+ const enPath = path.join(localesDir, 'en.json')
261
+ if (!fs.existsSync(enPath)) {
262
+ fs.writeFileSync(enPath, LOCALE_EN, 'utf-8')
263
+ console.log(`${GREEN}✓${RESET} locales/en.json created`)
315
264
  }
316
265
 
317
- return lines.join('\n')
266
+ console.log(`\n${YELLOW}ℹ${RESET} Install a Vite plugin or adapter to load config automatically:`)
267
+ console.log(` npm install @nons-dev/vite-plugin\n`)
318
268
  }
319
269
 
320
- function generateThemeCSS(config) {
321
- const m = config['theme-mappings']
322
- if (!m) return ''
323
- const lines = []
324
-
325
- lines.push(':root {')
326
- lines.push(' color-scheme: light;')
327
- if (m.light) lines.push(writeTokenBlock(m.light, ' '))
328
- lines.push('}')
329
-
330
- lines.push('')
331
- lines.push('[data-theme="dark"] {')
332
- lines.push(' color-scheme: dark;')
333
- if (m.dark) lines.push(writeTokenBlock(m.dark, ' '))
334
- lines.push('}')
335
-
336
- return lines.join('\n')
337
- }
338
-
339
- // ── Commands ──
340
-
341
- function cmdInit() {
342
- const dest = path.join(CWD, 'nons.config.yaml')
343
- if (fs.existsSync(dest)) {
344
- console.log(`${YELLOW}⚠${RESET} nons.config.yaml already exists — skipping.`)
345
- return
346
- }
347
- fs.writeFileSync(dest, DEFAULT_CONFIG, 'utf-8')
348
- console.log(`${GREEN}✓${RESET} nons.config.yaml created in`, CWD)
349
- }
350
-
351
- function cmdGenerate() {
270
+ function cmdValidate() {
352
271
  const configPath = path.join(CWD, 'nons.config.yaml')
353
272
  if (!fs.existsSync(configPath)) {
354
273
  console.error(`${RED}✗${RESET} nons.config.yaml not found. Run \`nons init\` first.`)
355
274
  process.exit(1)
356
275
  }
357
- const raw = fs.readFileSync(configPath, 'utf-8')
358
- const config = yaml.load(raw)
359
- const generatedDir = path.join(CWD, 'generated')
360
- if (!fs.existsSync(generatedDir)) fs.mkdirSync(generatedDir, { recursive: true })
361
-
362
- // tokens.css
363
- const tokensCSS = generateTokensCSS(config)
364
- fs.writeFileSync(path.join(generatedDir, 'tokens.css'), tokensCSS, 'utf-8')
365
- console.log(`${GREEN}✓${RESET} generated/tokens.css`)
366
-
367
- // theme.css
368
- const themeCSS = generateThemeCSS(config)
369
- if (themeCSS) {
370
- fs.writeFileSync(path.join(generatedDir, 'theme.css'), themeCSS, 'utf-8')
371
- console.log(`${GREEN}✓${RESET} generated/theme.css`)
372
- }
373
276
 
374
- console.log(`${YELLOW}ℹ${RESET} Import in your app:\n import './generated/tokens.css'\n import './generated/theme.css'`)
277
+ try {
278
+ const raw = fs.readFileSync(configPath, 'utf-8')
279
+ const config = yaml.load(raw)
280
+
281
+ const errors = []
282
+ const warnings = []
283
+
284
+ if (!config || typeof config !== 'object') {
285
+ errors.push('Config must be a non-null object')
286
+ } else {
287
+ const c = config
288
+ if (!c.theme || !c.theme.preset) errors.push('Missing theme.preset')
289
+ if (!c.brand || !c.brand.name) errors.push('Missing brand.name')
290
+ if (!c.direction || (c.direction.default !== 'rtl' && c.direction.default !== 'ltr')) errors.push('direction.default must be "rtl" or "ltr"')
291
+ if (!c.locale || !c.locale.default) errors.push('Missing locale.default')
292
+ if (!Array.isArray(c.locale?.supported) || c.locale.supported.length === 0) errors.push('locale.supported must be a non-empty array')
293
+ if (!c.tokens || typeof c.tokens !== 'object') warnings.push('No tokens section found — using defaults')
294
+ }
295
+
296
+ if (errors.length === 0) {
297
+ console.log(`\n${GREEN}✓${RESET} Config is valid\n`)
298
+ } else {
299
+ console.log(`\n${RED}✗${RESET} Config has errors:\n`)
300
+ for (const e of errors) console.log(` ${RED}•${RESET} ${e}`)
301
+ console.log('')
302
+ }
303
+ if (warnings.length) {
304
+ for (const w of warnings) console.log(` ${YELLOW}•${RESET} ${w}`)
305
+ console.log('')
306
+ }
307
+
308
+ if (errors.length) process.exit(1)
309
+ } catch (err) {
310
+ console.error(`\n${RED}✗${RESET} Invalid YAML: ${err.message}\n`)
311
+ process.exit(1)
312
+ }
375
313
  }
376
314
 
377
315
  function cmdList() {
@@ -493,8 +431,8 @@ function cmdSearch(query) {
493
431
  function printHelp() {
494
432
  console.log(`\n${BOLD}${CYAN}Nons UIKit CLI${RESET}\n`)
495
433
  console.log(`${BOLD}Commands:${RESET}\n`)
496
- console.log(` ${GREEN}init${RESET} Create nons.config.yaml in current directory`)
497
- console.log(` ${GREEN}generate${RESET} Generate tokens.css + theme.css from config`)
434
+ console.log(` ${GREEN}init${RESET} Create nons.config.yaml + locales/ in current directory`)
435
+ console.log(` ${GREEN}validate${RESET} Validate nons.config.yaml`)
498
436
  console.log(` ${GREEN}list${RESET} List all components`)
499
437
  console.log(` ${GREEN}show${RESET} ${DIM}<name>${RESET} Show full detail for a component`)
500
438
  console.log(` ${GREEN}schema${RESET} ${DIM}<name>${RESET} Show schema JSON for a component`)
@@ -502,7 +440,7 @@ function printHelp() {
502
440
  console.log(` ${GREEN}help${RESET} Show this help\n`)
503
441
  console.log(`${BOLD}Usage:${RESET}\n`)
504
442
  console.log(` ${DIM}npx @nons-dev/uikit init${RESET}`)
505
- console.log(` ${DIM}npx @nons-dev/uikit generate${RESET}`)
443
+ console.log(` ${DIM}npx @nons-dev/uikit validate${RESET}`)
506
444
  console.log(` ${DIM}npx @nons-dev/uikit list${RESET}`)
507
445
  console.log(` ${DIM}npx @nons-dev/uikit show Button${RESET}`)
508
446
  console.log(` ${DIM}npx @nons-dev/uikit schema Input${RESET}`)
@@ -516,7 +454,7 @@ const param = process.argv[3]
516
454
 
517
455
  switch (command) {
518
456
  case 'init': cmdInit(); break
519
- case 'generate': cmdGenerate(); break
457
+ case 'validate': cmdValidate(); break
520
458
  case 'list': cmdList(); break
521
459
  case 'show': param ? cmdShow(param) : (console.error(`${RED}✗${RESET} Missing component name.`), process.exit(1)); break
522
460
  case 'schema': param ? cmdSchema(param) : (console.error(`${RED}✗${RESET} Missing component name.`), process.exit(1)); break