@stackonward/cli 1.5.3 → 1.6.0

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.
Files changed (74) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/index.js.map +1 -1
  3. package/dist/resources/components/nuxt/site-source/app/assets/css/site-shell.css +112 -56
  4. package/dist/resources/components/nuxt/site-source/app/assets/icons/brand/android.svg +10 -0
  5. package/dist/resources/components/nuxt/site-source/app/assets/icons/brand/apple.svg +3 -0
  6. package/dist/resources/components/nuxt/site-source/app/assets/icons/brand/whatsapp.svg +5 -0
  7. package/dist/resources/components/nuxt/site-source/app/components/app/Sidebar.vue +1 -1
  8. package/dist/resources/components/nuxt/site-source/app/components/checkout/Status.vue +3 -3
  9. package/dist/resources/components/nuxt/site-source/app/components/consent/Banner.vue +23 -8
  10. package/dist/resources/components/nuxt/site-source/app/components/content/CallToAction.vue +59 -0
  11. package/dist/resources/components/nuxt/site-source/app/components/content/Card.vue +35 -0
  12. package/dist/resources/components/nuxt/site-source/app/components/content/Compatibility.vue +10 -0
  13. package/dist/resources/components/nuxt/site-source/app/components/content/Faq.vue +56 -0
  14. package/dist/resources/components/nuxt/site-source/app/components/content/Features.vue +8 -0
  15. package/dist/resources/components/nuxt/site-source/app/components/content/List.vue +1 -8
  16. package/dist/resources/components/nuxt/site-source/app/components/content/Reviews.vue +93 -0
  17. package/dist/resources/components/nuxt/site-source/app/components/countdown/Timer.vue +112 -0
  18. package/dist/resources/components/nuxt/site-source/app/components/locale/Menu.vue +3 -3
  19. package/dist/resources/components/nuxt/site-source/app/components/site/BackToTop.vue +30 -23
  20. package/dist/resources/components/nuxt/site-source/app/components/site/Header.vue +2 -2
  21. package/dist/resources/components/nuxt/site-source/app/components/steps/Progress.vue +36 -0
  22. package/dist/resources/components/nuxt/site-source/app/components/steps/Showcase.vue +340 -0
  23. package/dist/resources/components/nuxt/site-source/app/components/theme/Menu.vue +4 -4
  24. package/dist/resources/components/nuxt/site-source/app/components/ui/Button.vue +28 -2
  25. package/dist/resources/components/nuxt/site-source/app/components/ui/GradientBorder.vue +5 -5
  26. package/dist/resources/components/nuxt/site-source/app/components/ui/Icon.vue +14 -0
  27. package/dist/resources/components/nuxt/site-source/app/components/ui/Image.vue +126 -0
  28. package/dist/resources/components/nuxt/site-source/app/components/ui/Marquee.vue +99 -0
  29. package/dist/resources/components/nuxt/site-source/app/components/ui/Modal.vue +26 -88
  30. package/dist/resources/components/nuxt/site-source/app/components/ui/Popover.vue +87 -93
  31. package/dist/resources/components/nuxt/site-source/app/components/ui/Text.vue +84 -12
  32. package/dist/resources/components/nuxt/site-source/app/components/ui/Video.vue +105 -0
  33. package/dist/resources/components/nuxt/site-source/app/components/whatsapp/Chat.vue +126 -0
  34. package/dist/resources/components/nuxt/site-source/app/components/youtube/Embed.vue +286 -73
  35. package/dist/resources/components/nuxt/site-source/app/composables/useFloatingBottomStack.ts +44 -0
  36. package/dist/resources/components/nuxt/site-source/app/composables/useNavigation.ts +6 -8
  37. package/dist/resources/components/nuxt/site-source/app/consent/types.ts +1 -4
  38. package/dist/resources/components/nuxt/site-source/app/content/types.ts +3 -0
  39. package/dist/resources/components/nuxt/site-source/app/theme/accordion.ts +5 -4
  40. package/dist/resources/components/nuxt/site-source/app/theme/breadcrumb.ts +14 -4
  41. package/dist/resources/components/nuxt/site-source/app/theme/button.ts +138 -28
  42. package/dist/resources/components/nuxt/site-source/app/theme/carousel.ts +11 -7
  43. package/dist/resources/components/nuxt/site-source/app/theme/checkbox.ts +9 -3
  44. package/dist/resources/components/nuxt/site-source/app/theme/drawer.ts +6 -0
  45. package/dist/resources/components/nuxt/site-source/app/theme/form-field.ts +8 -0
  46. package/dist/resources/components/nuxt/site-source/app/theme/icon.ts +6 -0
  47. package/dist/resources/components/nuxt/site-source/app/theme/index.ts +8 -1
  48. package/dist/resources/components/nuxt/site-source/app/theme/input.ts +34 -18
  49. package/dist/resources/components/nuxt/site-source/app/theme/modal.ts +9 -5
  50. package/dist/resources/components/nuxt/site-source/app/theme/pagination.ts +9 -2
  51. package/dist/resources/components/nuxt/site-source/app/theme/radio-group.ts +7 -0
  52. package/dist/resources/components/nuxt/site-source/app/theme/select.ts +19 -7
  53. package/dist/resources/components/nuxt/site-source/app/theme/stepper.ts +15 -6
  54. package/dist/resources/components/nuxt/site-source/app/theme/textarea.ts +6 -0
  55. package/dist/resources/components/nuxt/site-source/app/theme/toast.ts +1 -4
  56. package/dist/resources/components/nuxt/site-source/app/theme/tooltip.ts +5 -1
  57. package/dist/resources/components/registry.json +133 -45
  58. package/dist/resources/components/vue/ui/BottomSheet.vue +5 -1
  59. package/dist/resources/components/vue/ui/ScrollArea.vue +2 -1
  60. package/dist/resources/registry.json +1 -1
  61. package/dist/resources/templates/base/.claude/docs/architecture-template.md +2 -1
  62. package/dist/resources/templates/base/AGENTS.md +7 -0
  63. package/dist/resources/templates/base/CLAUDE.md +7 -0
  64. package/dist/resources/templates/nuxt/.claude/docs/stack.md +14 -1
  65. package/dist/resources/templates/nuxt/DESIGN.md +146 -0
  66. package/dist/resources/templates/nuxt/app/app.config.ts +2 -0
  67. package/dist/resources/templates/nuxt/app/pages/app/index.vue +9 -7
  68. package/dist/resources/templates/nuxt/app/pages/index.vue +12 -27
  69. package/dist/resources/templates/nuxt/app/pages/ui/index.vue +219 -3
  70. package/dist/resources/templates/nuxt/nuxt.config.ts +2 -4
  71. package/dist/resources/templates/nuxt/package.json +2 -1
  72. package/dist/resources/templates/nuxt/stylelint.config.mjs +12 -0
  73. package/package.json +3 -3
  74. package/dist/resources/components/nuxt/site-source/app/assets/icons/common/.gitkeep +0 -0
@@ -64,12 +64,12 @@ useSeo({
64
64
  to="/ui"
65
65
  >
66
66
  View workflow
67
- <UIcon name="i-lucide-play" />
67
+ <UiIcon name="i-lucide-play" class="size-icon-sm" />
68
68
  </NuxtLink>
69
69
  </div>
70
70
  <div class="proof-list" aria-label="Product proof">
71
71
  <div v-for="item in proofItems" :key="item.label" class="proof-list__item">
72
- <UIcon :name="item.icon" />
72
+ <UiIcon :name="item.icon" class="text-secondary" />
73
73
  <span>{{ item.label }}</span>
74
74
  </div>
75
75
  </div>
@@ -91,11 +91,11 @@ useSeo({
91
91
  {{ panel.label }}
92
92
  </span>
93
93
  <span class="hero-gallery__video hero-gallery__video--vertical">
94
- <UIcon name="i-lucide-play" />
94
+ <UiIcon name="i-lucide-play" class="size-icon-sm" />
95
95
  0:15
96
96
  </span>
97
97
  <span class="hero-gallery__video hero-gallery__video--wide">
98
- <UIcon name="i-lucide-play" />
98
+ <UiIcon name="i-lucide-play" class="size-icon-sm" />
99
99
  0:08
100
100
  </span>
101
101
  </div>
@@ -105,7 +105,7 @@ useSeo({
105
105
  {{ ratio }}
106
106
  </button>
107
107
  <button type="button" aria-label="Add ratio">
108
- <UIcon name="i-lucide-plus" />
108
+ <UiIcon name="i-lucide-plus" />
109
109
  </button>
110
110
  </div>
111
111
  </div>
@@ -219,15 +219,10 @@ useSeo({
219
219
  }
220
220
 
221
221
  .hero-section__secondary-action {
222
- border-color: rgb(168 101 80 / 42%);
222
+ border-color: color-mix(in srgb, var(--site-color-primary) 42%, transparent);
223
223
  color: var(--site-color-accent-warm);
224
224
  }
225
225
 
226
- .hero-section__secondary-action svg {
227
- width: 16px;
228
- height: 16px;
229
- }
230
-
231
226
  .proof-list {
232
227
  display: grid;
233
228
  max-width: 560px;
@@ -253,12 +248,6 @@ useSeo({
253
248
  padding-left: 0;
254
249
  }
255
250
 
256
- .proof-list__item svg {
257
- width: 22px;
258
- height: 22px;
259
- color: var(--site-color-accent);
260
- }
261
-
262
251
  .hero-section__media {
263
252
  display: grid;
264
253
  min-width: 0;
@@ -308,11 +297,6 @@ useSeo({
308
297
  backdrop-filter: blur(10px);
309
298
  }
310
299
 
311
- .hero-gallery__video svg {
312
- width: 16px;
313
- height: 16px;
314
- }
315
-
316
300
  .hero-gallery__label--before {
317
301
  top: 4%;
318
302
  left: 2%;
@@ -375,7 +359,7 @@ useSeo({
375
359
  min-height: 34px;
376
360
  align-items: center;
377
361
  justify-content: center;
378
- border: 1px solid rgb(168 101 80 / 28%);
362
+ border: 1px solid color-mix(in srgb, var(--site-color-primary) 28%, transparent);
379
363
  border-radius: var(--site-radius-sm);
380
364
  background: rgb(255 255 255 / 82%);
381
365
  color: var(--site-color-primary);
@@ -384,13 +368,14 @@ useSeo({
384
368
  }
385
369
 
386
370
  .ratio-toolbar button:hover {
387
- border-color: rgb(168 101 80 / 44%);
388
- background: rgb(168 101 80 / 6%);
371
+ border-color: color-mix(in srgb, var(--site-color-primary) 44%, transparent);
372
+ background: color-mix(in srgb, var(--site-color-primary) 6%, transparent);
389
373
  color: var(--site-color-primary-hover);
390
374
  }
391
375
 
392
376
  .ratio-toolbar button:last-child {
393
- min-width: 34px;
377
+ min-width: 44px;
378
+ min-height: 44px;
394
379
  border-radius: 50%;
395
380
  }
396
381
 
@@ -503,7 +488,7 @@ useSeo({
503
488
  background: var(--site-color-primary);
504
489
  color: var(--site-color-primary-contrast);
505
490
  font-weight: 700;
506
- box-shadow: 0 18px 44px rgb(168 101 80 / 22%);
491
+ box-shadow: 0 18px 44px color-mix(in srgb, var(--site-color-primary) 22%, transparent);
507
492
  }
508
493
 
509
494
  @media (width <= 1100px) {
@@ -6,6 +6,55 @@ const analytics = useAnalytics();
6
6
  const visibleItems = ref(4);
7
7
  const infiniteLoading = ref(false);
8
8
  const checkoutUrlPreview = ref("");
9
+ const previewPage = ref(1);
10
+ const previewRatio = ref("4:5");
11
+ const drawerOpen = ref(false);
12
+ const previewIcons = [
13
+ "i-lucide-house",
14
+ "i-lucide-menu",
15
+ "i-lucide-search",
16
+ "i-lucide-plus",
17
+ "i-lucide-minus",
18
+ "i-lucide-x",
19
+ "i-lucide-check",
20
+ "i-lucide-chevron-down",
21
+ "i-lucide-circle-user",
22
+ "i-lucide-loader-circle",
23
+ "i-lucide-play",
24
+ "i-lucide-pause",
25
+ "i-lucide-headset",
26
+ "i-lucide-message-circle",
27
+ "i-lucide-star",
28
+ "i-lucide-arrow-up",
29
+ "i-lucide-triangle-alert",
30
+ "i-lucide-settings-2",
31
+ "i-lucide-image",
32
+ "i-lucide-shield-check",
33
+ ];
34
+ const previewIconSizes = [
35
+ { label: "16 · Inline", class: "size-icon-sm" },
36
+ { label: "20 · Default", class: "size-icon-md" },
37
+ { label: "24 · Prominent", class: "size-icon-lg" },
38
+ { label: "32 · Status", class: "size-icon-xl" },
39
+ ];
40
+ const previewSteps = [
41
+ {
42
+ title: "Add a source",
43
+ description: "Choose the image you want to work with.",
44
+ icon: "i-lucide-image",
45
+ },
46
+ {
47
+ title: "Describe the result",
48
+ description: "Set the scene, light, and output format.",
49
+ icon: "i-lucide-pencil",
50
+ },
51
+ {
52
+ title: "Review your work",
53
+ description: "Compare the results and choose a direction.",
54
+ icon: "i-lucide-check",
55
+ },
56
+ ];
57
+ const previewImages = previewSteps.map((step) => ({ src: "/favicon.svg", alt: step.title }));
9
58
 
10
59
  const infiniteItems = Array.from({ length: 10 }, (_, index) => ({
11
60
  id: `asset-${index + 1}`,
@@ -121,7 +170,7 @@ useSeo({
121
170
  title="Approve campaign set"
122
171
  description="Use slots for business-specific body and footer content."
123
172
  >
124
- <template #content>
173
+ <template #body>
125
174
  <UiText as="p" tone="muted">
126
175
  Campaign output is ready for review. The consuming product owns approval rules and
127
176
  provider fulfillment.
@@ -230,7 +279,166 @@ useSeo({
230
279
  Multi-line campaign summaries can be clamped by the reusable text component so compact
231
280
  cards, popovers, and tables remain stable.
232
281
  </UiText>
282
+ <UiText auto-shrink class="block max-w-48" :min-font-size="10"
283
+ >Automatically fitted text keeps its full label visible.</UiText
284
+ >
285
+ </div>
286
+ </section>
287
+
288
+ <section class="system-lab__panel system-lab__panel--wide">
289
+ <UiText as="h2" size="xl" weight="bold">Complete theme controls</UiText>
290
+ <div class="flex flex-wrap items-center gap-4">
291
+ <UiButton
292
+ v-for="size in ['xs', 'sm', 'md', 'lg', 'xl', '2xl'] as const"
293
+ :key="size"
294
+ :size="size"
295
+ >{{ size }}</UiButton
296
+ >
297
+ </div>
298
+ <UBreadcrumb :items="[{ label: 'Home', to: '/' }, { label: 'Components' }]" />
299
+ <UFormField label="Output notes"
300
+ ><UTextarea placeholder="Describe the output"
301
+ /></UFormField>
302
+ <URadioGroup
303
+ v-model="previewRatio"
304
+ :items="['4:5', '1:1', '16:9']"
305
+ orientation="horizontal"
306
+ variant="card"
307
+ />
308
+ <UPagination v-model:page="previewPage" :total="100" />
309
+ <UTooltip text="Shared tooltip theme"
310
+ ><UiButton color="neutral" variant="outline">Tooltip example</UiButton></UTooltip
311
+ >
312
+ <UiButton color="neutral" variant="outline" @click="drawerOpen = true"
313
+ >Open drawer</UiButton
314
+ >
315
+ <UDrawer
316
+ v-model:open="drawerOpen"
317
+ title="Output settings"
318
+ description="Responsive drawer controls"
319
+ >
320
+ <template #body
321
+ ><UFormField label="File name"><UInput placeholder="Product image" /></UFormField
322
+ ></template>
323
+ <template #footer
324
+ ><UiButton block @click="drawerOpen = false">Apply settings</UiButton></template
325
+ >
326
+ </UDrawer>
327
+ </section>
328
+
329
+ <section class="system-lab__panel">
330
+ <UiText as="h2" size="xl" weight="bold">Media and icons</UiText>
331
+ <p class="text-sm text-muted">
332
+ Lucide · 24 × 24 canvas · 2-unit round stroke · 20px default
333
+ </p>
334
+ <div class="grid grid-cols-4 items-end gap-3 text-center text-xs" data-icon-sizes>
335
+ <div
336
+ v-for="item in previewIconSizes"
337
+ :key="item.label"
338
+ class="flex flex-col items-center gap-2"
339
+ >
340
+ <UiIcon name="i-lucide-image" :class="item.class" />
341
+ <span>{{ item.label }}</span>
342
+ </div>
343
+ </div>
344
+ <div class="flex flex-wrap items-center gap-4 text-sm" data-icon-overrides>
345
+ <span class="inline-flex items-center gap-2"
346
+ ><UiIcon name="i-lucide-image" />Default</span
347
+ >
348
+ <span class="inline-flex items-center gap-2"
349
+ ><UiIcon name="i-lucide-image" :size="24" />size=24</span
350
+ >
351
+ <span class="inline-flex items-center gap-2"
352
+ ><UiIcon name="i-lucide-image" size="2rem" />size=2rem</span
353
+ >
354
+ <UiIcon name="i-lucide-circle-check" label="Ready" class="text-success" />
355
+ </div>
356
+ <div class="grid grid-cols-4 gap-4 text-center text-xs" data-icon-catalog>
357
+ <div
358
+ v-for="icon in previewIcons"
359
+ :key="icon"
360
+ class="flex min-w-0 flex-col items-center gap-2"
361
+ >
362
+ <UiIcon :name="icon" class="text-primary" />
363
+ <span class="break-words">{{ icon.replace("i-lucide-", "") }}</span>
364
+ </div>
365
+ </div>
366
+ <div class="flex items-center gap-4" data-brand-icons>
367
+ <UiIcon name="brand:apple" label="Apple" class="size-icon-lg" />
368
+ <UiIcon name="brand:android" label="Android" class="size-icon-lg" />
369
+ <UiIcon name="brand:whatsapp" label="WhatsApp" class="size-icon-lg" />
370
+ <span class="text-sm text-muted">Brand proportions and colors</span>
233
371
  </div>
372
+ <UiVideo
373
+ src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
374
+ :autoplay="false"
375
+ :loop="false"
376
+ :muted="true"
377
+ class="aspect-video"
378
+ />
379
+ </section>
380
+
381
+ <section class="system-lab__panel">
382
+ <UiText as="h2" size="xl" weight="bold">Countdown and progress</UiText>
383
+ <CountdownTimer
384
+ :duration="600"
385
+ storage-key="component-countdown"
386
+ :show-milliseconds="true"
387
+ :update-interval="100"
388
+ />
389
+ <StepsProgress :items="['Source', 'Settings', 'Review']" :current-step="2" />
390
+ <ContentCompatibility :icons="['brand:apple', 'brand:android']" label="Platform icons" />
391
+ </section>
392
+
393
+ <section class="system-lab__panel system-lab__panel--wide">
394
+ <ContentFaq
395
+ title="Questions and answers"
396
+ :items="[
397
+ {
398
+ question: 'Can several answers stay open?',
399
+ answer: 'Yes. Each column supports multiple expanded answers.',
400
+ },
401
+ {
402
+ question: 'Does it work with a keyboard?',
403
+ answer: 'Use Tab to reach a question and Enter or Space to expand it.',
404
+ },
405
+ {
406
+ question: 'Can answers include custom content?',
407
+ answer: 'The answer slot accepts links, images, and other components.',
408
+ },
409
+ ]"
410
+ />
411
+ <StepsShowcase
412
+ title="Three steps"
413
+ :steps="previewSteps"
414
+ :images="previewImages"
415
+ :autoplay="false"
416
+ />
417
+ <ContentReviews
418
+ title="Review cards"
419
+ :reviews="[
420
+ [
421
+ {
422
+ author: 'Sample author, Design team',
423
+ avatar: '/favicon.svg',
424
+ description:
425
+ 'Example review text for verifying card dimensions, typography, and motion.',
426
+ },
427
+ {
428
+ author: 'Sample reviewer',
429
+ avatar: '/favicon.svg',
430
+ description: 'Hover or focus the row to pause its movement.',
431
+ },
432
+ ],
433
+ ]"
434
+ />
435
+ <ContentCallToAction
436
+ title="Bring your next idea to life"
437
+ description="A reusable section with project-owned copy, logo, and destination."
438
+ button-label="Back to Home"
439
+ to="/"
440
+ :logo="{ src: '/favicon.svg', alt: 'Application icon' }"
441
+ />
234
442
  </section>
235
443
  </div>
236
444
  </section>
@@ -285,7 +493,13 @@ useSeo({
285
493
  gap: 18px;
286
494
  border: 1px solid var(--site-color-border);
287
495
  border-radius: var(--site-radius-lg);
288
- background: linear-gradient(180deg, rgb(168 101 80 / 4%), transparent), var(--site-color-surface);
496
+ background:
497
+ linear-gradient(
498
+ 180deg,
499
+ color-mix(in srgb, var(--site-color-primary) 4%, transparent),
500
+ transparent
501
+ ),
502
+ var(--site-color-surface);
289
503
  padding: 22px;
290
504
  }
291
505
 
@@ -321,11 +535,13 @@ useSeo({
321
535
  }
322
536
 
323
537
  .system-lab__actions {
324
- grid-template-columns: repeat(3, minmax(0, max-content));
538
+ display: flex;
539
+ flex-wrap: wrap;
325
540
  align-items: center;
326
541
  }
327
542
 
328
543
  .system-lab__actions--stacked {
544
+ display: grid;
329
545
  grid-template-columns: 1fr;
330
546
  justify-items: start;
331
547
  }
@@ -45,11 +45,9 @@ export default defineNuxtConfig({
45
45
  },
46
46
  },
47
47
  icon: {
48
+ serverBundle: { collections: ["lucide"] },
49
+ fallbackToApi: false,
48
50
  customCollections: [
49
- {
50
- prefix: "common",
51
- dir: "./app/assets/icons/common",
52
- },
53
51
  {
54
52
  prefix: "brand",
55
53
  dir: "./app/assets/icons/brand",
@@ -31,7 +31,8 @@
31
31
  "@stackonward/api-client": "^0.0.3",
32
32
  "@stackonward/google-tag-manager-nuxt": "^0.3.3",
33
33
  "@stackonward/nuxt-layer-base": "^0.0.4",
34
- "@stackonward/nuxt-site-shell": "^0.3.2"
34
+ "@stackonward/nuxt-site-shell": "^0.3.2",
35
+ "@stackonward/composables": "^0.0.2"
35
36
  },
36
37
  "devDependencies": {
37
38
  "@commitlint/cli": "^21.2.2",
@@ -1,3 +1,15 @@
1
1
  export default {
2
2
  extends: ["@stackonward/stylelint-config"],
3
+ overrides: [
4
+ {
5
+ files: ["app/**/*.vue"],
6
+ customSyntax: "postcss-html",
7
+ rules: {
8
+ "selector-pseudo-class-no-unknown": [
9
+ true,
10
+ { ignorePseudoClasses: ["deep", "global", "slotted"] },
11
+ ],
12
+ },
13
+ },
14
+ ],
3
15
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackonward/cli",
3
- "version": "1.5.3",
3
+ "version": "1.6.0",
4
4
  "description": "StackOnward CLI for creating projects and installing reusable components and snippets",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,9 +37,9 @@
37
37
  "prompts": "^2.4.2",
38
38
  "zod": "4",
39
39
  "@stackonward/api-client": "0.0.3",
40
- "@stackonward/onedev-provisioning": "0.1.0",
40
+ "@stackonward/google-tag-manager": "0.3.0",
41
41
  "@stackonward/provisioning": "0.1.0",
42
- "@stackonward/google-tag-manager": "0.3.0"
42
+ "@stackonward/onedev-provisioning": "0.1.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/fs-extra": "^11.0.4",