nuxt-unified-ui 0.5.15 → 0.5.16

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,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-unified-ui",
3
3
  "type": "module",
4
- "version": "0.5.15",
4
+ "version": "0.5.16",
5
5
  "main": "./nuxt.config.ts",
6
6
  "types": "./index.d.ts",
7
7
  "exports": {
@@ -20,7 +20,7 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "@formkit/tempo": "1.1.0",
23
- "@iconify-json/lucide": "1.2.135",
23
+ "@iconify-json/lucide": "1.2.136",
24
24
  "@nuxt/kit": "4.5.2",
25
25
  "@nuxt/ui": "4.11.2",
26
26
  "@nuxtjs/i18n": "10.6.0",
@@ -70,7 +70,7 @@ Absolute highlights:
70
70
  - Kebab-case tags (`u-button`, `un-card`)
71
71
  - `v-if` / `v-for` on `<template>` wrappers — not on rendered nodes
72
72
  - If a condition changes several component attributes, prefer explicit `<template v-if>` / `v-else` component variants over nested ternaries and overly dynamic bindings
73
- - **2+ attributes → one per line** except structural **`template` wrappers** and **`u-modal`** (keep either on one line); attribute order + default omissions (`variant="subtle"`, **Cancel only → `ghost`**, omit neutral `color`, `loading-auto`); non-self-closing `>` on same line as last attr; multi-line self-closing `/>` on its own line
73
+ - Tags with children keep all attributes on one line with the opening tag unless a multiline attribute (multi-line array/object/function binding) forces a split — then the opening tag goes on its own line, one attribute per line, value styled like JS; childless tags are self-closing — one single-line attribute stays inline, otherwise tag and attributes each go on their own line with `/>` on its own line; attribute order + default omissions (`variant="subtle"`, **Cancel only → `ghost`**, omit neutral `color`, `loading-auto`); split non-self-closing `>` on same line as last attr; split self-closing `/>` on its own line
74
74
  - `{{ ... }}` on its own line (static + dynamic text may mix)
75
75
  - `/* section */` comments; imports co-located under the section that uses them
76
76
  - Light naming: `handleXxx` handlers, `it` in short callbacks, descriptive `for...of`, computeds use block + `return`
@@ -19,8 +19,8 @@ Write code so a reader can **scan vertically** and see structure before details.
19
19
  3. **One idea per line in structured data.**
20
20
  Object/array literals in script are multi-line with trailing commas — even single-property objects passed to helpers (`toastSuccess`, `ufetch` options, etc.). Compact one-liners hide diffs and force horizontal reading.
21
21
 
22
- 4. **Templates are layout, not mini-scripts.**
23
- Structural directives live on one-line `<template>` wrappers so the rendered node stays a clean component/element. Rendered component attributes wrap predictably (`u-modal` stays one line); closing `>` / `/>` placement is consistent; interpolations sit on their own line (static + dynamic text may share one `{{ ... }}` or surrounding text).
22
+ 4. **Templates stay single-line unless a multiline attribute — or a childless multi-attribute tag — forces a split.**
23
+ A tag with children keeps all attributes on the same single line as the opening tag — no wrapping for length or attribute count. Only a multiline attribute (an array, object, or function literal bound to an attribute that spans multiple lines) forces such a tag to split: then the opening tag goes on its own line, every other attribute gets its own line, and the multiline value is formatted like a JS literal. Childless tags follow their own exception (self-closing; split when they carry more than one attribute or a multiline attribute). Closing `>` / `/>` placement is consistent; interpolations sit on their own line (static + dynamic text may share one `{{ ... }}` or surrounding text).
24
24
 
25
25
  5. **Section comments are the map.**
26
26
  `/* section */` labels define logical domains, while declaration-kind spacing exposes the structure inside each domain. Imports sit in the section that needs them, not in a hoisted pile at the top.
@@ -49,6 +49,7 @@ When editing an existing file, **absolute rules below always win**. For choices
49
49
  | Braces | always for `if` / `else` / `for` / `while` — no brace-less single-liners |
50
50
  | `else` / `catch` | on their **own line** after `}` |
51
51
  | `.js` / `.ts` file start | **two** blank lines at the top, **unless** the file starts with imports — then **no** blank lines before the first `import` |
52
+ | **Single-line principle (JS/TS only)** | **Do not wrap JS/TS code solely because it has grown long**; keep every statement on a single line unless the explicit JS/TS wrapping rules below dictate otherwise. The default is single-statement-per-line; only break across lines when a specific rule permits or requires it. Template sections have their own rule (single-line attributes unless a multiline attribute forces a split) — see Template rules. |
52
53
 
53
54
  ---
54
55
 
@@ -296,9 +297,9 @@ const response = await ufetch(
296
297
 
297
298
  ### Template bindings — compactness
298
299
 
299
- - Single-key object binding may stay inline: `:ui="{ content: 'max-w-7xl' }"`
300
- - Multi-key template object/array bindings are multi-line
301
- - Simple scalars and simple ternaries stay inline; break only when branches become objects/arrays or nested structure
300
+ - A bound array, object, or function literal that spans multiple lines is a **multiline attribute** and forces the tag to split (see Attribute wrapping). A single-pair object with scalar values stays inline and does **not** trigger a split: `:ui="{ content: 'max-w-7xl' }"`
301
+ - Multi-key or nested template object/array bindings are multiline attributes: split the tag and format the value like a JS literal
302
+ - Simple scalars and simple ternaries stay inline; break only when a branch becomes a multiline object/array or nested structure
302
303
  - When one condition changes several attributes, labels/icons, or an object-shaped binding such as `to`, use adjacent `<template v-if>` / `v-else-if` / `v-else` branches with explicit component variants. Prefer small markup duplication over nested ternaries and overly dynamic attributes.
303
304
 
304
305
  ```vue
@@ -508,40 +509,69 @@ Keep tight `v-if` / `v-else` chains adjacent (no blank line between matching bra
508
509
 
509
510
  ### Attribute wrapping (hard rule)
510
511
 
511
- - **0–1 attributes:** may stay on one line with the tag
512
- - **Structural `<template>` wrappers:** keep the opening tag on one line, even with several directives, keys, or dynamic slot bindings
513
- - **2+ attributes on rendered elements/components:** one attribute per line — **except `u-modal`**
514
- - **`u-modal` only:** keep **all** attributes on the **same single line** as the tag (do not wrap), even when there are many
512
+ - **Childless tags must be self-closing:** a tag with no children is written `<tag ... />` — never an empty open/close pair (`<tag ...></tag>`).
513
+ - **Tags with children — single line unless multiline:** all attributes stay on the **same single line** as the opening tag, regardless of attribute count or line length. Never wrap only because the line got long or because there are 2+ attributes. This applies equally to rendered elements, components, `u-modal`, and structural `<template>` wrappers.
514
+ - **Only trigger for tags with children — multiline attribute:** such a tag splits only when one of its attributes is a **multiline attribute**: an array, object, or function literal bound to the attribute that spans multiple lines (e.g. `:class="{\n … \n}"`, `:items="[\n … \n]"`). References, calls, and scalar expressions (`:field="field"`, `v-bind="radOmit(action, [...])"`, `:is="elementsMap[x]"`, `@click="handleSave"`) are **not** multiline attributes, even when their runtime value is an object. A single-pair object with scalar values (`:ui="{ content: 'max-w-5xl' }"`) stays inline and does **not** trigger a split.
515
+ - **Childless exception:** a childless (self-closing) tag with a single single-line attribute stays on one line with the tag (`<u-icon name="lucide:check" />`). When it has more than one attribute **or** at least one multiline attribute, the tag and its attributes each go on their own line: the opening tag on its own line (`<tag`), one attribute per line in attribute order, and `/>` on its own line.
516
+ - **Split shape (tags with children):** when a multiline attribute triggers the split, the opening tag goes on its **own line** (`<tag`), every other attribute gets **its own line** in attribute order, and the multiline attribute's value is formatted **like a JS value** (one entry per line, trailing commas). Closing `>` / `/>` placement follows [`>` and `/>` placement](#-and--placement).
515
517
 
516
518
  ```vue
517
- <!-- ✅ 0–1 attributes — inline OK -->
518
- <div class="space-y-3">
519
- <u-form-field label="Captcha">
519
+ <!-- ✅ tag with children, no multiline attribute — one line, however many attributes -->
520
+ <u-modal :ui="{ content: 'max-w-5xl' }" scrollable @update:open="!$event && emit('close')">
520
521
  ...
521
- </u-form-field>
522
- <u-icon name="lucide:check" />
522
+ </u-modal>
523
523
 
524
- <!-- ✅ structural template wrappers stay on one line -->
524
+ <!-- ✅ structural template wrappers follow the same rule -->
525
525
  <template v-for="column in columns" :key="column.accessorKey" #[column.accessorKey+'-cell']="{ row }">
526
526
  ...
527
527
  </template>
528
528
 
529
- <!-- ✅ u-modal — always one line (exception) -->
530
- <u-modal :ui="{ content: 'max-w-5xl' }" scrollable @update:open="!$event && emit('close')">
529
+ <!-- ✅ tag with children + multiline attribute — splits, value styled like JS -->
530
+ <div
531
+ v-if="show"
532
+ :class="{
533
+ 'p-3': !fluidBody,
534
+ }">
531
535
  ...
532
- </u-modal>
536
+ </div>
537
+
538
+ <!-- ✅ childless, single single-line attribute — one line -->
539
+ <u-icon name="lucide:check" />
533
540
 
534
- <!-- ✅ other components — 2+ attributes, one per line -->
541
+ <!-- ✅ childless, more than one attribute — tag and attributes each on their own line -->
535
542
  <u-button
536
543
  variant="subtle"
537
544
  icon="lucide:refresh-ccw"
538
545
  @click="refresh"
539
546
  />
547
+
548
+ <!-- ✅ childless with a multiline attribute — same split shape -->
549
+ <component
550
+ :is="elementsMap[field.identifier]"
551
+ :field="field"
552
+ :class="{
553
+ 'p-2': true,
554
+ }"
555
+ />
556
+
557
+ <!-- ❌ childless multi-attribute tag on one line -->
558
+ <u-button variant="subtle" icon="lucide:refresh-ccw" @click="refresh" />
559
+
560
+ <!-- ❌ empty open/close pair — self-close instead -->
561
+ <div class="grow"></div>
562
+
563
+ <!-- ❌ splitting a tag with children that has no multiline attribute -->
564
+ <un-card
565
+ icon="lucide:key"
566
+ :title="title"
567
+ fluid-body>
568
+ ...
569
+ </un-card>
540
570
  ```
541
571
 
542
572
  ### Attribute order
543
573
 
544
- When wrapping, order attributes as:
574
+ When a multiline attribute forces a split, order attributes as:
545
575
 
546
576
  1. Refs / identity: `ref`, `id`, `name`
547
577
  2. Component visual props: `variant`, `color`, `size`, `icon`, static `label`
@@ -606,27 +636,30 @@ Prefer defaults by **omitting** props rather than restating them:
606
636
  ```
607
637
  ### `>` and `/>` placement
608
638
 
609
- **Non-self-closing**, multi-attribute: `>` on the **same line** as the last attribute:
639
+ Single-line tags keep their closer on the same line (`<u-icon name="lucide:check" />`, `<div class="space-y-3">`).
640
+
641
+ **Split (multiline-attribute) non-self-closing:** `>` on the **same line** as the last attribute:
610
642
 
611
643
  ```vue
612
- <un-card
613
- icon="lucide:key"
614
- :title="title"
615
- fluid-body>
644
+ <div
645
+ v-if="show"
646
+ :class="{
647
+ 'p-3': !fluidBody,
648
+ }">
616
649
  ...
617
- </un-card>
650
+ </div>
618
651
  ```
619
652
 
620
- **Self-closing**, multi-attribute: `/>` on its **own line**; always a space before `/>`:
653
+ **Split self-closing (childless multi-attribute or multiline attribute):** `/>` on its **own line**; always a space before `/>`:
621
654
 
622
655
  ```vue
623
- <u-button
624
- variant="subtle"
625
- icon="lucide:refresh-ccw"
626
- @click="refresh"
656
+ <component
657
+ :is="elementsMap[field.identifier]"
658
+ :field="field"
659
+ :class="{
660
+ 'p-2': true,
661
+ }"
627
662
  />
628
-
629
- <u-icon name="lucide:check" />
630
663
  ```
631
664
 
632
665
  Closing tags for block components (`</un-card>`, `</u-modal>`, …) always on their own line.
@@ -799,8 +832,10 @@ export default defineEventHandler(async event => {
799
832
  | `if (!x) return;` | braced block |
800
833
  | `} else {` | `}\nelse {` |
801
834
  | `toastSuccess({ title: 'x' })` one-liner object | multi-line object + trailing comma |
802
- | 3 attrs on one line (rendered element/component other than `u-modal`) | one attr per line |
803
- | Multi-line `u-modal` attrs | keep `u-modal` attrs on one line |
835
+ | Splitting a tag with children that has no multiline attribute (wrapping for count/length) | keep all attributes on one line with the opening tag |
836
+ | Childless multi-attribute tag on one line | split: opening tag on its own line, one attribute per line, `/>` on its own line |
837
+ | Empty open/close pair (`<div ...></div>`) | self-close (`<div ... />`) |
838
+ | Keeping a tag single-line when it has a multiline attribute | split: opening tag on its own line, one attribute per line, value like JS |
804
839
  | `>` on its own line after attrs | `>` after last attr |
805
840
  | `{{ x }}` glued to tags | interpolation on its own line (static + dynamic mix OK) |
806
841
  | `ghost` on non-Cancel buttons | `ghost` only for Cancel |
@@ -833,11 +868,11 @@ export default defineEventHandler(async event => {
833
868
  - [ ] Tiny helpers stay tight
834
869
  - [ ] Return-only multi-criteria functions use a compact exhaustive `if` / `else if` / `else`; broader functions may use early returns
835
870
  - [ ] `else` / `catch` on new line
836
- - [ ] Script objects multi-line; template single-key objects may be inline
871
+ - [ ] Script objects multi-line (the JS/TS single-line principle does not cover templates); template tags stay single-line unless a multiline attribute (multi-line array/object/function binding) forces a split; single-pair scalar objects (e.g. `:ui="{ content: '...' }"`) stay inline
837
872
  - [ ] Kebab-case component tags
838
873
  - [ ] `v-if` / `v-for` on `<template>` wrappers
839
874
  - [ ] Conditional states that change several attributes use explicit `<template v-if>` component variants, not nested ternaries
840
- - [ ] Structural `<template>` wrappers stay on one line; rendered elements/components with 2+ attributes wrap one per line (**`u-modal` stays on one line**); closing `>` / `/>` placement is correct
875
+ - [ ] Tags with children keep all attributes on one line with the opening tag unless a multiline attribute forces a split (opening tag on its own line, one attribute per line, value like JS); childless tags are self-closing — single single-line attribute stays inline, otherwise tag and attributes each go on their own line with `/>` on its own line; closing `>` / `/>` placement is correct
841
876
  - [ ] Attribute order + default-value omissions respected (`subtle`, **Cancel → `ghost` only**, no neutral color noise, `loading-auto`)
842
877
  - [ ] `{{ }}` on own line (static + dynamic mix OK)
843
878
  - [ ] Every section is named; imports are co-located with the section that uses them
@@ -156,7 +156,7 @@ Action entries support `actionType: 'spacer'` (flex grow) and optional `tooltip`
156
156
 
157
157
  Cancel / dismiss actions use `variant: 'ghost'` (or `variant="ghost"`). Do **not** use `ghost` on primary/submit/other actions — prefer omit / `subtle`.
158
158
 
159
- Hand-rolled dialog shells keep **`u-modal` attributes on one line** (see [code-style.md](code-style.md)):
159
+ Hand-rolled dialog shells follow the template single-line rule — this shell has no multiline attribute, so it stays on one line (see [code-style.md](code-style.md)):
160
160
 
161
161
  ```vue
162
162
  <u-modal :ui="{ content: 'max-w-5xl' }" scrollable @update:open="!$event && emit('close')">
@@ -169,7 +169,7 @@ Hand-rolled dialog shells keep **`u-modal` attributes on one line** (see [code-s
169
169
  - Prefer `launchFormPickerDialog` / `launchChoicePickerDialog` over hand-rolled `u-modal` for these flows
170
170
  - Handle actions in button / submit `onClick`
171
171
  - Keep field lists consistent with `un-form` (`identifier`, not `type`, for element kind)
172
- - Mark Cancel with `variant: 'ghost'`; keep `u-modal` attrs on one line
172
+ - Mark Cancel with `variant: 'ghost'`; keep dialog shells single-line unless a multiline attribute forces a split
173
173
 
174
174
  **Don’t**
175
175
 
@@ -57,7 +57,7 @@ Omit unused props. When present, write them in this order:
57
57
  13. `:extra-actions`
58
58
  14. `:meta`
59
59
 
60
- Models are always **page size, then page**. Closing `>` sits on the same line as the last attribute.
60
+ Models are always **page size, then page**. Attributes stay on one line with the opening tag (a multiline attribute is the only split trigger — see [code-style.md](code-style.md)).
61
61
 
62
62
  ### Paged table
63
63
 
@@ -84,10 +84,7 @@ Models are always **page size, then page**. Closing `>` sits on the same line as
84
84
  No footer, no page models, no `total-items`:
85
85
 
86
86
  ```vue
87
- <un-card
88
- :icon="icon"
89
- :title="title"
90
- fluid-body>
87
+ <un-card :icon="icon" :title="title" fluid-body>
91
88
  <un-table
92
89
  :columns="columns"
93
90
  :data="rows"
@@ -298,10 +295,7 @@ const currentPage = ref(1);
298
295
  Prefer an `un-card` with `fluid-body` so the table and footer are edge-to-edge:
299
296
 
300
297
  ```vue
301
- <un-card
302
- :title="`Manage ${titlePlural}`"
303
- fluid-body
304
- :append-actions="toolbarActions">
298
+ <un-card :title="`Manage ${titlePlural}`" fluid-body :append-actions="toolbarActions">
305
299
  <un-table
306
300
  :columns="columns"
307
301
  :loading="isItemsLoading"
@@ -60,7 +60,10 @@ Action buttons: `loading-auto`, props via `radOmit` excluding `actionType` / `to
60
60
  ## `un-spinner` — `app/components/un-spinner.vue`
61
61
 
62
62
  ```vue
63
- <u-icon name="lucide:loader-circle" class="animate-spin" />
63
+ <u-icon
64
+ name="lucide:loader-circle"
65
+ class="animate-spin"
66
+ />
64
67
  ```
65
68
 
66
69
  No props.