@omnitend/dashboard-for-laravel 0.22.0 → 0.24.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.
- package/dist/components/extended/DXDashboard.vue.d.ts +12 -1
- package/dist/components/extended/DXDashboardNavbar.vue.d.ts +7 -2
- package/dist/components/extended/DXField.vue.d.ts +4 -4
- package/dist/components/extended/DXTable.vue.d.ts +55 -2
- package/dist/components/extended/DXUserAvatar.vue.d.ts +40 -0
- package/dist/dashboard-for-laravel.js +9578 -9410
- package/dist/dashboard-for-laravel.js.map +1 -1
- package/dist/dashboard-for-laravel.umd.cjs +8 -8
- package/dist/dashboard-for-laravel.umd.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +44 -0
- package/docs/public/api-reference.json +120 -6
- package/docs/public/docs-map.md +3 -2
- package/docs/public/llms.txt +3 -2
- package/package.json +1 -1
- package/resources/js/components/extended/DXDashboard.vue +42 -4
- package/resources/js/components/extended/DXDashboardNavbar.vue +5 -18
- package/resources/js/components/extended/DXField.vue +153 -26
- package/resources/js/components/extended/DXTable.vue +516 -193
- package/resources/js/components/extended/DXUserAvatar.vue +104 -0
- package/resources/js/index.ts +1 -0
- package/resources/js/types/index.ts +48 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@component
|
|
3
|
+
The circular user avatar shown in the dashboard navbar's user menu: a single
|
|
4
|
+
initial on a solid disc, with an optional notification dot.
|
|
5
|
+
|
|
6
|
+
It exists as its own component because `DXDashboardNavbar`'s `user-icon` slot
|
|
7
|
+
is one consumers routinely *decorate* rather than replace — adding an unread
|
|
8
|
+
badge, wrapping it in a link. The navbar's styles are scoped, so slot content
|
|
9
|
+
(compiled in the consumer's scope) can't reuse them; without this component
|
|
10
|
+
every override starts by re-implementing the avatar's CSS, which then drifts
|
|
11
|
+
from the theme. Rendering it here means an override is one line and stays on
|
|
12
|
+
theme.
|
|
13
|
+
-->
|
|
14
|
+
<template>
|
|
15
|
+
<div class="dx-user-avatar">
|
|
16
|
+
<!-- `.user-avatar` (not a `dx-`-prefixed name) because it's the documented
|
|
17
|
+
theming hook consumers already override — see the theming guide. -->
|
|
18
|
+
<span class="user-avatar">
|
|
19
|
+
<!-- @slot Replaces the initial inside the disc (e.g. a photo or an icon). -->
|
|
20
|
+
<slot>{{ resolvedInitial }}</slot>
|
|
21
|
+
</span>
|
|
22
|
+
|
|
23
|
+
<span
|
|
24
|
+
v-if="badge"
|
|
25
|
+
class="dx-user-avatar__badge"
|
|
26
|
+
:class="`bg-${badgeVariant}`"
|
|
27
|
+
>
|
|
28
|
+
<span class="visually-hidden">{{ badgeLabel }}</span>
|
|
29
|
+
</span>
|
|
30
|
+
</div>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
import { computed } from "vue";
|
|
35
|
+
import type { ColorVariant } from "bootstrap-vue-next";
|
|
36
|
+
|
|
37
|
+
const props = withDefaults(
|
|
38
|
+
defineProps<{
|
|
39
|
+
/** The user whose initial is shown. The first letter of `name` is used. */
|
|
40
|
+
user?: { name: string; [key: string]: any } | null;
|
|
41
|
+
|
|
42
|
+
/** Overrides the initial derived from `user.name` (e.g. two-letter initials). */
|
|
43
|
+
initial?: string;
|
|
44
|
+
|
|
45
|
+
/** Show a notification dot on the avatar (e.g. unread updates). */
|
|
46
|
+
badge?: boolean;
|
|
47
|
+
|
|
48
|
+
/** Colour of the notification dot. */
|
|
49
|
+
badgeVariant?: ColorVariant;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Accessible text for the notification dot, announced to screen readers
|
|
53
|
+
* (the dot itself is a colour-only signal). Ignored unless `badge` is set.
|
|
54
|
+
*/
|
|
55
|
+
badgeLabel?: string;
|
|
56
|
+
}>(),
|
|
57
|
+
{
|
|
58
|
+
user: null,
|
|
59
|
+
initial: "",
|
|
60
|
+
badge: false,
|
|
61
|
+
badgeVariant: "danger",
|
|
62
|
+
badgeLabel: "Unread notifications",
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const resolvedInitial = computed(() => {
|
|
67
|
+
if (props.initial) return props.initial;
|
|
68
|
+
return props.user?.name?.charAt(0).toUpperCase() ?? "";
|
|
69
|
+
});
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<style scoped>
|
|
73
|
+
/* The disc, not the root, carries the size: the root is a positioning context
|
|
74
|
+
for the badge, and giving it the disc's dimensions would clip the dot. */
|
|
75
|
+
.dx-user-avatar {
|
|
76
|
+
position: relative;
|
|
77
|
+
display: inline-flex;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.user-avatar {
|
|
81
|
+
width: 32px;
|
|
82
|
+
height: 32px;
|
|
83
|
+
border-radius: 50%;
|
|
84
|
+
background-color: var(--bs-dark);
|
|
85
|
+
color: var(--bs-white);
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: center;
|
|
88
|
+
justify-content: center;
|
|
89
|
+
font-weight: 600;
|
|
90
|
+
font-size: 14px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.dx-user-avatar__badge {
|
|
94
|
+
position: absolute;
|
|
95
|
+
top: 0;
|
|
96
|
+
right: 0;
|
|
97
|
+
width: 10px;
|
|
98
|
+
height: 10px;
|
|
99
|
+
border-radius: 50%;
|
|
100
|
+
/* Ring the dot in the bar's own background so it reads as a separate mark
|
|
101
|
+
rather than a bite out of the disc's edge. */
|
|
102
|
+
box-shadow: 0 0 0 2px var(--bs-body-bg);
|
|
103
|
+
}
|
|
104
|
+
</style>
|
package/resources/js/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ export { default as DXBasicForm } from "./components/extended/DXBasicForm.vue";
|
|
|
24
24
|
export { default as DXTable } from "./components/extended/DXTable.vue";
|
|
25
25
|
export { default as DXDashboardSidebar } from "./components/extended/DXDashboardSidebar.vue";
|
|
26
26
|
export { default as DXDashboardNavbar } from "./components/extended/DXDashboardNavbar.vue";
|
|
27
|
+
export { default as DXUserAvatar } from "./components/extended/DXUserAvatar.vue";
|
|
27
28
|
|
|
28
29
|
// Base components (wrapped Bootstrap with theming)
|
|
29
30
|
export { default as DAccordion } from "./components/base/DAccordion.vue";
|
|
@@ -118,6 +118,17 @@ export interface FieldDefinition {
|
|
|
118
118
|
/** Re-run `optionsLoader` whenever the form model changes. */
|
|
119
119
|
reloadOptionsOnChange?: boolean;
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* For `select` fields: render a **searchable** select — type to filter a
|
|
123
|
+
* long option list, while the model still holds `option.value` (an id).
|
|
124
|
+
*
|
|
125
|
+
* A plain `select` is fine for ten options and unusable for hundreds; the
|
|
126
|
+
* `autocomplete` type filters but models the *typed text*, so it can't back
|
|
127
|
+
* a foreign key (picking "Tesco" gives you `"Tesco"`, not `37`). This is the
|
|
128
|
+
* combination high-frequency data entry against a long list needs.
|
|
129
|
+
*/
|
|
130
|
+
searchable?: boolean;
|
|
131
|
+
|
|
121
132
|
/** Number of rows for textarea (default: 3) */
|
|
122
133
|
rows?: number;
|
|
123
134
|
|
|
@@ -293,6 +304,43 @@ export interface FieldDefinition {
|
|
|
293
304
|
*/
|
|
294
305
|
readonly?: MaybeFn<boolean>;
|
|
295
306
|
|
|
307
|
+
/**
|
|
308
|
+
* Display the value as static text instead of a control — no border, no
|
|
309
|
+
* input box (Bootstrap's `.form-control-plaintext`). For values a
|
|
310
|
+
* profile/settings page shows but never lets you edit, where a `readonly`
|
|
311
|
+
* input still reads as "you could edit this, but can't".
|
|
312
|
+
*
|
|
313
|
+
* Implies read-only, for every field type. Anything backed by a real input
|
|
314
|
+
* — the text family, textarea, currency, percentage, autocomplete — renders
|
|
315
|
+
* as static text; control types with no native readonly state
|
|
316
|
+
* (select/radio/checkbox/switch/file) are disabled instead, exactly as they
|
|
317
|
+
* are for `readonly`.
|
|
318
|
+
*
|
|
319
|
+
* Enforced over `inputProps`: unlike the field's other bindings, which
|
|
320
|
+
* `inputProps` may override, a plaintext field cannot be made editable
|
|
321
|
+
* again through it.
|
|
322
|
+
*/
|
|
323
|
+
plaintext?: MaybeFn<boolean>;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Only for `type: "password"`. Show the reveal (eye) toggle that switches
|
|
327
|
+
* the input between masked and plain text. Defaults to `true` — set
|
|
328
|
+
* `false` to render a bare password input.
|
|
329
|
+
*/
|
|
330
|
+
revealable?: boolean;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Include this field's value in the submitted payload. Default `true`.
|
|
334
|
+
*
|
|
335
|
+
* Set `false` for a **presentational** field — a header, an alert, an
|
|
336
|
+
* explanatory block rendered via `span` — that exists to lay out the form,
|
|
337
|
+
* not to hold data. Without it, `DXTable`'s edit modal seeds its form from
|
|
338
|
+
* every `editFields` key, so those decorative fields are POSTed alongside
|
|
339
|
+
* the real ones (an empty string, an empty array) purely because they were
|
|
340
|
+
* declared.
|
|
341
|
+
*/
|
|
342
|
+
submit?: boolean;
|
|
343
|
+
|
|
296
344
|
/**
|
|
297
345
|
* Conditionally show or hide this field. When omitted the field is
|
|
298
346
|
* always visible. Boolean or a function of the form model; evaluated
|