nuxt-unified-ui 0.5.12 → 0.5.13
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.
|
@@ -74,6 +74,20 @@ const tableUi = computed(() => {
|
|
|
74
74
|
|
|
75
75
|
/* actions */
|
|
76
76
|
|
|
77
|
+
const actionButtonOmitKeys = [
|
|
78
|
+
'actionType',
|
|
79
|
+
'vIf',
|
|
80
|
+
'tooltip',
|
|
81
|
+
'warning',
|
|
82
|
+
'to',
|
|
83
|
+
'href',
|
|
84
|
+
'disabled',
|
|
85
|
+
'onClick',
|
|
86
|
+
'label',
|
|
87
|
+
'items',
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
|
|
77
91
|
function resolveActionValue(value, row) {
|
|
78
92
|
if (typeof value === 'function') {
|
|
79
93
|
return value(row.original);
|
|
@@ -83,6 +97,23 @@ function resolveActionValue(value, row) {
|
|
|
83
97
|
}
|
|
84
98
|
}
|
|
85
99
|
|
|
100
|
+
function getActionWarning(action, row) {
|
|
101
|
+
return resolveActionValue(action.warning, row);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function getSplitActionItems(action, row) {
|
|
105
|
+
return (resolveActionValue(action.items, row) || []).map(it => {
|
|
106
|
+
return {
|
|
107
|
+
...radOmit(it, [
|
|
108
|
+
'onClick',
|
|
109
|
+
'onSelect',
|
|
110
|
+
]),
|
|
111
|
+
label: resolveActionValue(it.label, row),
|
|
112
|
+
onSelect: () => it.onSelect?.(row.original),
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
86
117
|
function getExtraActionItems(row) {
|
|
87
118
|
return (props.extraActions || [])
|
|
88
119
|
.filter(it => !it.vIf || it.vIf(row.original))
|
|
@@ -92,6 +123,7 @@ function getExtraActionItems(row) {
|
|
|
92
123
|
'vIf',
|
|
93
124
|
'actionType',
|
|
94
125
|
'tooltip',
|
|
126
|
+
'warning',
|
|
95
127
|
'to',
|
|
96
128
|
'href',
|
|
97
129
|
'disabled',
|
|
@@ -145,17 +177,61 @@ const pageSizeItems = [
|
|
|
145
177
|
<template v-if="!action.vIf || action.vIf(row.original)">
|
|
146
178
|
|
|
147
179
|
<template v-if="!action.actionType || action.actionType === 'button'">
|
|
148
|
-
<
|
|
149
|
-
<u-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
180
|
+
<div class="flex flex-col items-end gap-1.5">
|
|
181
|
+
<u-tooltip :text="resolveActionValue(action.tooltip, row)">
|
|
182
|
+
<span class="inline-flex">
|
|
183
|
+
<u-button
|
|
184
|
+
variant="subtle"
|
|
185
|
+
v-bind="radOmit(action, actionButtonOmitKeys)"
|
|
186
|
+
:label="resolveActionValue(action.label, row)"
|
|
187
|
+
:to="resolveActionValue(action.to, row)"
|
|
188
|
+
:href="resolveActionValue(action.href, row)"
|
|
189
|
+
:disabled="resolveActionValue(action.disabled, row)"
|
|
190
|
+
loading-auto
|
|
191
|
+
@click.stop="action.onClick?.(row.original)"
|
|
192
|
+
/>
|
|
193
|
+
</span>
|
|
194
|
+
</u-tooltip>
|
|
195
|
+
<template v-if="getActionWarning(action, row)">
|
|
196
|
+
<span class="flex items-center gap-1.5 text-sm text-warning max-w-sm">
|
|
197
|
+
<u-icon
|
|
198
|
+
name="lucide:triangle-alert"
|
|
199
|
+
class="shrink-0 size-4"
|
|
200
|
+
/>
|
|
201
|
+
<span>
|
|
202
|
+
{{ getActionWarning(action, row) }}
|
|
203
|
+
</span>
|
|
204
|
+
</span>
|
|
205
|
+
</template>
|
|
206
|
+
</div>
|
|
207
|
+
</template>
|
|
208
|
+
|
|
209
|
+
<template v-else-if="action.actionType === 'split'">
|
|
210
|
+
<div class="flex">
|
|
211
|
+
<u-tooltip :text="resolveActionValue(action.tooltip, row)">
|
|
212
|
+
<span class="inline-flex">
|
|
213
|
+
<u-button
|
|
214
|
+
variant="subtle"
|
|
215
|
+
v-bind="radOmit(action, actionButtonOmitKeys)"
|
|
216
|
+
class="rounded-e-none"
|
|
217
|
+
:label="resolveActionValue(action.label, row)"
|
|
218
|
+
:disabled="resolveActionValue(action.disabled, row)"
|
|
219
|
+
loading-auto
|
|
220
|
+
@click.stop="action.onClick?.(row.original)"
|
|
221
|
+
/>
|
|
222
|
+
</span>
|
|
223
|
+
</u-tooltip>
|
|
224
|
+
<u-dropdown-menu :items="getSplitActionItems(action, row)">
|
|
225
|
+
<u-button
|
|
226
|
+
variant="subtle"
|
|
227
|
+
:color="action.color"
|
|
228
|
+
icon="lucide:chevron-down"
|
|
229
|
+
class="rounded-s-none"
|
|
230
|
+
:disabled="resolveActionValue(action.disabled, row)"
|
|
231
|
+
@click.stop
|
|
232
|
+
/>
|
|
233
|
+
</u-dropdown-menu>
|
|
234
|
+
</div>
|
|
159
235
|
</template>
|
|
160
236
|
|
|
161
237
|
<template v-else-if="action.actionType === 'separator'">
|
|
@@ -181,6 +257,7 @@ const pageSizeItems = [
|
|
|
181
257
|
<u-button
|
|
182
258
|
variant="subtle"
|
|
183
259
|
icon="lucide:ellipsis-vertical"
|
|
260
|
+
@click.stop
|
|
184
261
|
/>
|
|
185
262
|
</u-dropdown-menu>
|
|
186
263
|
|
package/package.json
CHANGED
|
@@ -522,7 +522,7 @@ Practical shortcuts:
|
|
|
522
522
|
|
|
523
523
|
- `u-button`: `variant` → `color` → `size` → `icon` → label/value → `block` → `disabled` → `loading-auto` → events
|
|
524
524
|
- `u-input` / `u-select*`: user-facing props (`:placeholder`, `:label`) → transient state (`:loading`, `:disabled`) → data source (`:items`) → `class` → `v-model` → events
|
|
525
|
-
- Action objects (`:actions`, `:append-actions`, table row actions): `vIf` → `actionType` → `color` → `icon` → `label` → `tooltip` → `disabled` → `to` → `href` → `onClick`
|
|
525
|
+
- Action objects (`:actions`, `:append-actions`, table row actions): `vIf` → `actionType` → `color` → `icon` → `label` → `tooltip` → `warning` → `disabled` → `to` → `href` → `onClick` → `items`
|
|
526
526
|
- `un-table`: `:columns` → `class` / `:ui` → `:loading` → `:data` → `hide-pagination` → `:total-items` → `v-model:items-per-page` → `v-model:current-page` → `sticky-actions` → `:actions` → `:extra-actions` → `:meta` (omit unused). Full table rules → [tables.md](tables.md)
|
|
527
527
|
- Tab / select item objects: `value` → `icon` → `label`
|
|
528
528
|
|
|
@@ -12,7 +12,7 @@ Reference components in **kebab-case** in templates.
|
|
|
12
12
|
| `un-card` | `un-card.vue` | Card + typography + action rows |
|
|
13
13
|
| `un-typography` | `un-typography.vue` | Icon / title / subtitle / text / append |
|
|
14
14
|
| `un-spinner` | `un-spinner.vue` | Spinning Lucide loader icon |
|
|
15
|
-
| `un-table` | `un-table.vue` | `u-table` + row actions + pagination footer → [tables.md](tables.md) |
|
|
15
|
+
| `un-table` | `un-table.vue` | `u-table` + row actions (button / split / warning) + pagination footer → [tables.md](tables.md) |
|
|
16
16
|
|
|
17
17
|
## Composables
|
|
18
18
|
|
|
@@ -34,7 +34,7 @@ Do **not** add sort, filter, or selection props to `un-table`. Resource dashboar
|
|
|
34
34
|
|
|
35
35
|
The actions column is added when **either** `actions` or `extraActions` has length. `#actions-cell` is then owned by the wrapper — do not override it.
|
|
36
36
|
|
|
37
|
-
`to` / `href` / `disabled` on an action may be a value or `(row) => …`. `vIf(row)` hides the item. `onClick(row)` receives the original row. Buttons use `loading-auto`.
|
|
37
|
+
`to` / `href` / `disabled` / `label` / `tooltip` / `warning` on an action may be a value or `(row) => …`. `vIf(row)` hides the item. `onClick(row)` receives the original row. Action clicks use `@click.stop` so they do not select the row. Buttons use `loading-auto`.
|
|
38
38
|
|
|
39
39
|
## Attribute order on `<un-table>`
|
|
40
40
|
|
|
@@ -160,9 +160,19 @@ Two channels:
|
|
|
160
160
|
|
|
161
161
|
Use `actions` for the one or two primary row operations (view, edit, delete). Use `extraActions` for the rest (assign, revoke, copy, archive). A vertical separator is inserted between the two groups automatically.
|
|
162
162
|
|
|
163
|
+
`actionType` values on `actions`:
|
|
164
|
+
|
|
165
|
+
| `actionType` | UI |
|
|
166
|
+
|--------------|----|
|
|
167
|
+
| omitted / `'button'` | Inline `u-button` |
|
|
168
|
+
| `'split'` | Primary button plus a chevron `u-dropdown-menu` |
|
|
169
|
+
| `'separator'` | Vertical rule between button groups |
|
|
170
|
+
|
|
171
|
+
`warning` is a string or `(row) => string | undefined` rendered under the button (triangle + text). Split `items` may be an array or `(row) => array`. Each item uses `label` (value or `(row) => …`) and `onSelect(row)` — do not put `onClick` on split items.
|
|
172
|
+
|
|
163
173
|
Field order on **every** action object (omit unused):
|
|
164
174
|
|
|
165
|
-
`vIf` → `actionType` → `color` → `icon` → `label` → `tooltip` → `disabled` → `to` → `href` → `onClick`
|
|
175
|
+
`vIf` → `actionType` → `color` → `icon` → `label` → `tooltip` → `warning` → `disabled` → `to` → `href` → `onClick` → `items`
|
|
166
176
|
|
|
167
177
|
```js
|
|
168
178
|
const itemActions = computed(() => {
|
|
@@ -180,11 +190,30 @@ const itemActions = computed(() => {
|
|
|
180
190
|
{
|
|
181
191
|
actionType: 'separator',
|
|
182
192
|
},
|
|
193
|
+
{
|
|
194
|
+
actionType: 'split',
|
|
195
|
+
icon: 'lucide:download',
|
|
196
|
+
tooltip: 'Download',
|
|
197
|
+
onClick: handleItemDownloadFile,
|
|
198
|
+
items: [
|
|
199
|
+
{
|
|
200
|
+
icon: 'lucide:file-text',
|
|
201
|
+
label: 'Download file',
|
|
202
|
+
onSelect: handleItemDownloadFile,
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
icon: 'lucide:file-archive',
|
|
206
|
+
label: 'Download archive',
|
|
207
|
+
onSelect: handleItemDownloadArchive,
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
},
|
|
183
211
|
{
|
|
184
212
|
vIf: it => it.status !== 'archived',
|
|
185
213
|
color: 'error',
|
|
186
214
|
icon: 'lucide:trash',
|
|
187
|
-
tooltip: 'Delete',
|
|
215
|
+
tooltip: it => it.role === 'admin' ? 'Admins cannot be deleted' : 'Delete',
|
|
216
|
+
warning: it => it.role === 'admin' ? 'Admins cannot be deleted' : undefined,
|
|
188
217
|
disabled: it => it.role === 'admin',
|
|
189
218
|
onClick: handleItemDelete,
|
|
190
219
|
},
|
|
@@ -216,8 +245,9 @@ Rules:
|
|
|
216
245
|
- Destructive: `color: 'error'` before `icon`.
|
|
217
246
|
- Emphasized extra action: `color: 'primary'` before `icon`.
|
|
218
247
|
- `{ actionType: 'separator' }` is a lone-key object between visual groups in `actions`.
|
|
248
|
+
- `{ actionType: 'split', items, onClick }` is a default click plus overflow choices; item handlers are `onSelect`.
|
|
219
249
|
- Omit `variant: 'subtle'` — that is the button default.
|
|
220
|
-
- `vIf` / `disabled` / `to` / `href` take `(row) => …` when they depend on the row.
|
|
250
|
+
- `vIf` / `disabled` / `to` / `href` / `label` / `tooltip` / `warning` take `(row) => …` when they depend on the row.
|
|
221
251
|
- Do not put toolbar Create / Refresh on the row. Those belong on the parent `un-card` (`:actions` / `:append-actions`).
|
|
222
252
|
|
|
223
253
|
Resource managers prepend custom row actions, then default Edit / Delete:
|