@frigear-nu/ui 0.0.8 → 0.1.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/README.md +46 -2
- package/dist/module.mjs +12 -9
- package/dist/runtime/components/ConfirmDialog.d.vue.ts +1 -0
- package/dist/runtime/components/ConfirmDialog.vue +4 -2
- package/dist/runtime/components/ConfirmDialog.vue.d.ts +1 -0
- package/dist/runtime/components/global/DescriptionList.d.vue.ts +28 -0
- package/dist/runtime/components/global/DescriptionList.vue +51 -0
- package/dist/runtime/components/global/DescriptionList.vue.d.ts +28 -0
- package/dist/runtime/components/global/FormSlideover.d.vue.ts +46 -0
- package/dist/runtime/components/global/FormSlideover.vue +53 -0
- package/dist/runtime/components/global/FormSlideover.vue.d.ts +46 -0
- package/dist/runtime/components/global/ListCard.d.vue.ts +29 -0
- package/dist/runtime/components/global/ListCard.vue +74 -0
- package/dist/runtime/components/global/ListCard.vue.d.ts +29 -0
- package/dist/runtime/components/global/PageHeading.d.vue.ts +28 -0
- package/dist/runtime/components/global/PageHeading.vue +53 -0
- package/dist/runtime/components/global/PageHeading.vue.d.ts +28 -0
- package/dist/runtime/components/global/PageTabs.d.vue.ts +19 -0
- package/dist/runtime/components/global/PageTabs.vue +28 -0
- package/dist/runtime/components/global/PageTabs.vue.d.ts +19 -0
- package/dist/runtime/components/global/PageToolbar.d.vue.ts +15 -0
- package/dist/runtime/components/global/PageToolbar.vue +15 -0
- package/dist/runtime/components/global/PageToolbar.vue.d.ts +15 -0
- package/dist/runtime/components/global/RowMenu.d.vue.ts +19 -0
- package/dist/runtime/components/global/RowMenu.vue +31 -0
- package/dist/runtime/components/global/RowMenu.vue.d.ts +19 -0
- package/dist/runtime/components/global/SectionCard.d.vue.ts +31 -0
- package/dist/runtime/components/global/SectionCard.vue +68 -0
- package/dist/runtime/components/global/SectionCard.vue.d.ts +31 -0
- package/dist/runtime/components/global/StatCard.d.vue.ts +26 -0
- package/dist/runtime/components/global/StatCard.vue +62 -0
- package/dist/runtime/components/global/StatCard.vue.d.ts +26 -0
- package/dist/runtime/components/global/TableCard.d.vue.ts +31 -0
- package/dist/runtime/components/global/TableCard.vue +46 -0
- package/dist/runtime/components/global/TableCard.vue.d.ts +31 -0
- package/dist/runtime/components/global/TableIdentity.d.vue.ts +23 -0
- package/dist/runtime/components/global/TableIdentity.vue +28 -0
- package/dist/runtime/components/global/TableIdentity.vue.d.ts +23 -0
- package/dist/runtime/components/global/TablePagination.d.vue.ts +36 -0
- package/dist/runtime/components/global/TablePagination.vue +51 -0
- package/dist/runtime/components/global/TablePagination.vue.d.ts +36 -0
- package/dist/runtime/composables/index.d.ts +8 -0
- package/dist/runtime/composables/index.js +8 -0
- package/dist/runtime/composables/useAction.d.ts +14 -0
- package/dist/runtime/composables/useAction.js +20 -0
- package/dist/runtime/composables/useCopyToClipboard.d.ts +4 -0
- package/dist/runtime/composables/useCopyToClipboard.js +20 -0
- package/dist/runtime/composables/useErrorToast.d.ts +9 -0
- package/dist/runtime/composables/useErrorToast.js +9 -0
- package/dist/runtime/composables/useFormat.d.ts +23 -0
- package/dist/runtime/composables/useFormat.js +19 -0
- package/dist/runtime/composables/useLocaleLink.d.ts +13 -0
- package/dist/runtime/composables/useLocaleLink.js +19 -0
- package/dist/runtime/composables/useNavLinks.d.ts +13 -0
- package/dist/runtime/composables/useNavLinks.js +15 -0
- package/dist/runtime/composables/useTableQuery.d.ts +34 -0
- package/dist/runtime/composables/useTableQuery.js +70 -0
- package/dist/runtime/composables/useTableSort.d.ts +21 -0
- package/dist/runtime/composables/useTableSort.js +40 -0
- package/dist/runtime/i18n/lang/da.json +19 -0
- package/dist/runtime/i18n/lang/en.json +19 -0
- package/dist/runtime/types.d.ts +34 -0
- package/dist/runtime/types.js +0 -0
- package/dist/runtime/utils/errors.d.ts +9 -0
- package/dist/runtime/utils/errors.js +18 -0
- package/dist/runtime/utils/format.d.ts +12 -0
- package/dist/runtime/utils/format.js +26 -0
- package/dist/runtime/utils/index.d.ts +6 -0
- package/dist/runtime/utils/index.js +6 -0
- package/dist/runtime/utils/locale.d.ts +8 -0
- package/dist/runtime/utils/locale.js +10 -0
- package/dist/runtime/utils/status.d.ts +7 -0
- package/dist/runtime/utils/status.js +17 -0
- package/dist/runtime/utils/surface.d.ts +22 -0
- package/dist/runtime/utils/surface.js +10 -0
- package/dist/runtime/utils/table.d.ts +28 -0
- package/dist/runtime/utils/table.js +17 -0
- package/package.json +28 -14
- package/dist/runtime/components/App/AppPageHeader.d.vue.ts +0 -23
- package/dist/runtime/components/App/AppPageHeader.vue +0 -58
- package/dist/runtime/components/App/AppPageHeader.vue.d.ts +0 -23
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
items: { type: Array, required: true }
|
|
4
|
+
});
|
|
5
|
+
const model = defineModel({ type: String });
|
|
6
|
+
const stateMode = computed(() => model.value !== void 0 || props.items.some((item) => item.value !== void 0 && !item.to));
|
|
7
|
+
const links = computed(() => {
|
|
8
|
+
if (!stateMode.value) return props.items;
|
|
9
|
+
const selected = model.value ?? props.items.find((item) => item.value !== void 0)?.value;
|
|
10
|
+
return props.items.map((item) => item.value === void 0 || item.to ? item : {
|
|
11
|
+
...item,
|
|
12
|
+
active: item.value === selected,
|
|
13
|
+
onSelect: (event) => {
|
|
14
|
+
model.value = item.value;
|
|
15
|
+
item.onSelect?.(event);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<UNavigationMenu
|
|
23
|
+
:items="links"
|
|
24
|
+
highlight
|
|
25
|
+
class="-mx-1 overflow-x-auto border-b border-default"
|
|
26
|
+
:ui="{ list: 'min-w-max', link: 'px-3 py-2', linkLeadingIcon: 'max-sm:hidden' }"
|
|
27
|
+
/>
|
|
28
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PageTabItem } from '../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Tabs under a page heading. Link mode: items carry `to` and the route decides which one is active. State mode:
|
|
4
|
+
* bind `v-model` and give items a `value`; clicking one selects it. Icons are hidden on small screens.
|
|
5
|
+
*/
|
|
6
|
+
type __VLS_Props = {
|
|
7
|
+
items: PageTabItem[];
|
|
8
|
+
};
|
|
9
|
+
type __VLS_ModelProps = {
|
|
10
|
+
modelValue?: string;
|
|
11
|
+
};
|
|
12
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
13
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
|
+
"update:modelValue": (value: string | undefined) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
16
|
+
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
17
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare var __VLS_1: {}, __VLS_3: {};
|
|
2
|
+
type __VLS_Slots = {} & {
|
|
3
|
+
default?: (props: typeof __VLS_1) => any;
|
|
4
|
+
} & {
|
|
5
|
+
right?: (props: typeof __VLS_3) => any;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
8
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
11
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
12
|
+
new (): {
|
|
13
|
+
$slots: S;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
7
|
+
<slot />
|
|
8
|
+
<div
|
|
9
|
+
v-if="$slots.right"
|
|
10
|
+
class="ms-auto flex flex-wrap items-center gap-2"
|
|
11
|
+
>
|
|
12
|
+
<slot name="right" />
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare var __VLS_1: {}, __VLS_3: {};
|
|
2
|
+
type __VLS_Slots = {} & {
|
|
3
|
+
default?: (props: typeof __VLS_1) => any;
|
|
4
|
+
} & {
|
|
5
|
+
right?: (props: typeof __VLS_3) => any;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
8
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
11
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
12
|
+
new (): {
|
|
13
|
+
$slots: S;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ButtonProps, DropdownMenuItem } from '@nuxt/ui';
|
|
2
|
+
/**
|
|
3
|
+
* The `⋯` menu at the end of a table row or next to a heading. Order: Open, then edits, then the destructive action
|
|
4
|
+
* in its own group. Stops the click so the row itself does not open.
|
|
5
|
+
*/
|
|
6
|
+
type __VLS_Props = {
|
|
7
|
+
items: DropdownMenuItem[] | DropdownMenuItem[][];
|
|
8
|
+
/** What the menu acts on, for screen readers: "Actions for Spring meetup". */
|
|
9
|
+
subject?: string;
|
|
10
|
+
variant?: 'ghost' | 'outline';
|
|
11
|
+
size?: ButtonProps['size'];
|
|
12
|
+
/** Overrides the accessible name. */
|
|
13
|
+
label?: string;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
16
|
+
variant: "ghost" | "outline";
|
|
17
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
items: { type: Array, required: true },
|
|
4
|
+
subject: { type: String, required: false },
|
|
5
|
+
variant: { type: String, required: false, default: "ghost" },
|
|
6
|
+
size: { type: null, required: false },
|
|
7
|
+
label: { type: String, required: false }
|
|
8
|
+
});
|
|
9
|
+
const t = useUiT("patterns");
|
|
10
|
+
const ariaLabel = computed(() => props.label ?? (props.subject ? t("actionsFor", "Actions for {subject}", { subject: props.subject }) : t("moreActions", "More actions")));
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div
|
|
15
|
+
class="flex justify-end"
|
|
16
|
+
@click.stop
|
|
17
|
+
>
|
|
18
|
+
<UDropdownMenu
|
|
19
|
+
:items="items"
|
|
20
|
+
:content="{ align: 'end' }"
|
|
21
|
+
>
|
|
22
|
+
<UButton
|
|
23
|
+
icon="i-lucide-ellipsis"
|
|
24
|
+
color="neutral"
|
|
25
|
+
:variant="variant"
|
|
26
|
+
:size="size"
|
|
27
|
+
:aria-label="ariaLabel"
|
|
28
|
+
/>
|
|
29
|
+
</UDropdownMenu>
|
|
30
|
+
</div>
|
|
31
|
+
</template>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ButtonProps, DropdownMenuItem } from '@nuxt/ui';
|
|
2
|
+
/**
|
|
3
|
+
* The `⋯` menu at the end of a table row or next to a heading. Order: Open, then edits, then the destructive action
|
|
4
|
+
* in its own group. Stops the click so the row itself does not open.
|
|
5
|
+
*/
|
|
6
|
+
type __VLS_Props = {
|
|
7
|
+
items: DropdownMenuItem[] | DropdownMenuItem[][];
|
|
8
|
+
/** What the menu acts on, for screen readers: "Actions for Spring meetup". */
|
|
9
|
+
subject?: string;
|
|
10
|
+
variant?: 'ghost' | 'outline';
|
|
11
|
+
size?: ButtonProps['size'];
|
|
12
|
+
/** Overrides the accessible name. */
|
|
13
|
+
label?: string;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
16
|
+
variant: "ghost" | "outline";
|
|
17
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A titled card for one section of a page (a form, key facts, a list). Header row with `title`/`description` (or
|
|
3
|
+
* `#header`) and `#actions`, padded body (none with `flush`, e.g. for a table or list), optional `#footer`.
|
|
4
|
+
*/
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
icon?: string;
|
|
9
|
+
loading?: boolean;
|
|
10
|
+
/** Removes the body padding, for content that brings its own (tables, divided lists). */
|
|
11
|
+
flush?: boolean;
|
|
12
|
+
};
|
|
13
|
+
declare var __VLS_1: {}, __VLS_8: {}, __VLS_20: {}, __VLS_22: {};
|
|
14
|
+
type __VLS_Slots = {} & {
|
|
15
|
+
header?: (props: typeof __VLS_1) => any;
|
|
16
|
+
} & {
|
|
17
|
+
actions?: (props: typeof __VLS_8) => any;
|
|
18
|
+
} & {
|
|
19
|
+
default?: (props: typeof __VLS_20) => any;
|
|
20
|
+
} & {
|
|
21
|
+
footer?: (props: typeof __VLS_22) => any;
|
|
22
|
+
};
|
|
23
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { surfaceClass } from "../../utils/surface";
|
|
3
|
+
defineProps({
|
|
4
|
+
title: { type: String, required: false },
|
|
5
|
+
description: { type: String, required: false },
|
|
6
|
+
icon: { type: String, required: false },
|
|
7
|
+
loading: { type: Boolean, required: false },
|
|
8
|
+
flush: { type: Boolean, required: false }
|
|
9
|
+
});
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<section :class="surfaceClass">
|
|
14
|
+
<div
|
|
15
|
+
v-if="title || description || $slots.header || $slots.actions"
|
|
16
|
+
class="border-default flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3.5"
|
|
17
|
+
>
|
|
18
|
+
<slot name="header">
|
|
19
|
+
<div class="flex min-w-0 items-center gap-2">
|
|
20
|
+
<UIcon
|
|
21
|
+
v-if="icon"
|
|
22
|
+
:name="icon"
|
|
23
|
+
class="text-muted size-4 shrink-0"
|
|
24
|
+
/>
|
|
25
|
+
<div class="min-w-0">
|
|
26
|
+
<h2
|
|
27
|
+
v-if="title"
|
|
28
|
+
class="text-highlighted text-sm font-semibold"
|
|
29
|
+
>
|
|
30
|
+
{{ title }}
|
|
31
|
+
</h2>
|
|
32
|
+
<p
|
|
33
|
+
v-if="description"
|
|
34
|
+
class="text-muted text-sm"
|
|
35
|
+
>
|
|
36
|
+
{{ description }}
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</slot>
|
|
41
|
+
<div
|
|
42
|
+
v-if="$slots.actions"
|
|
43
|
+
class="flex items-center gap-2"
|
|
44
|
+
>
|
|
45
|
+
<slot name="actions" />
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div
|
|
49
|
+
v-if="loading"
|
|
50
|
+
class="space-y-2 p-4"
|
|
51
|
+
>
|
|
52
|
+
<USkeleton class="h-5 w-1/2" />
|
|
53
|
+
<USkeleton class="h-5 w-1/3" />
|
|
54
|
+
</div>
|
|
55
|
+
<div
|
|
56
|
+
v-else
|
|
57
|
+
:class="flush ? '' : 'p-4'"
|
|
58
|
+
>
|
|
59
|
+
<slot />
|
|
60
|
+
</div>
|
|
61
|
+
<div
|
|
62
|
+
v-if="$slots.footer"
|
|
63
|
+
class="border-default border-t px-4 py-3"
|
|
64
|
+
>
|
|
65
|
+
<slot name="footer" />
|
|
66
|
+
</div>
|
|
67
|
+
</section>
|
|
68
|
+
</template>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A titled card for one section of a page (a form, key facts, a list). Header row with `title`/`description` (or
|
|
3
|
+
* `#header`) and `#actions`, padded body (none with `flush`, e.g. for a table or list), optional `#footer`.
|
|
4
|
+
*/
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
icon?: string;
|
|
9
|
+
loading?: boolean;
|
|
10
|
+
/** Removes the body padding, for content that brings its own (tables, divided lists). */
|
|
11
|
+
flush?: boolean;
|
|
12
|
+
};
|
|
13
|
+
declare var __VLS_1: {}, __VLS_8: {}, __VLS_20: {}, __VLS_22: {};
|
|
14
|
+
type __VLS_Slots = {} & {
|
|
15
|
+
header?: (props: typeof __VLS_1) => any;
|
|
16
|
+
} & {
|
|
17
|
+
actions?: (props: typeof __VLS_8) => any;
|
|
18
|
+
} & {
|
|
19
|
+
default?: (props: typeof __VLS_20) => any;
|
|
20
|
+
} & {
|
|
21
|
+
footer?: (props: typeof __VLS_22) => any;
|
|
22
|
+
};
|
|
23
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A number with a label (and an optional tinted icon and hint). Links to the list it summarises when `to` is set.
|
|
3
|
+
* The default slot replaces `value`; `empty` shows when there is neither.
|
|
4
|
+
*/
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
label: string;
|
|
7
|
+
value?: string | number;
|
|
8
|
+
hint?: string;
|
|
9
|
+
icon?: string;
|
|
10
|
+
to?: string;
|
|
11
|
+
loading?: boolean;
|
|
12
|
+
empty?: string;
|
|
13
|
+
};
|
|
14
|
+
declare var __VLS_23: {};
|
|
15
|
+
type __VLS_Slots = {} & {
|
|
16
|
+
default?: (props: typeof __VLS_23) => any;
|
|
17
|
+
};
|
|
18
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
20
|
+
declare const _default: typeof __VLS_export;
|
|
21
|
+
export default _default;
|
|
22
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
23
|
+
new (): {
|
|
24
|
+
$slots: S;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { surfaceClass } from "../../utils/surface";
|
|
3
|
+
defineProps({
|
|
4
|
+
label: { type: String, required: true },
|
|
5
|
+
value: { type: [String, Number], required: false },
|
|
6
|
+
hint: { type: String, required: false },
|
|
7
|
+
icon: { type: String, required: false },
|
|
8
|
+
to: { type: String, required: false },
|
|
9
|
+
loading: { type: Boolean, required: false },
|
|
10
|
+
empty: { type: String, required: false }
|
|
11
|
+
});
|
|
12
|
+
const NuxtLink = resolveComponent("NuxtLink");
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<component
|
|
17
|
+
:is="to ? NuxtLink : 'section'"
|
|
18
|
+
:to="to"
|
|
19
|
+
:class="[surfaceClass, 'flex h-full items-start gap-3 p-4', to && 'hover:bg-elevated hover:ring-accented transition-colors focus-visible:outline-2 focus-visible:outline-primary']"
|
|
20
|
+
>
|
|
21
|
+
<span
|
|
22
|
+
v-if="icon"
|
|
23
|
+
class="bg-primary/10 ring-primary/25 text-primary flex shrink-0 items-center justify-center rounded-full p-2.5 ring ring-inset"
|
|
24
|
+
>
|
|
25
|
+
<UIcon
|
|
26
|
+
:name="icon"
|
|
27
|
+
class="size-5"
|
|
28
|
+
/>
|
|
29
|
+
</span>
|
|
30
|
+
<div class="flex min-w-0 flex-1 flex-col gap-1.5">
|
|
31
|
+
<h2 class="text-muted text-xs font-normal uppercase">
|
|
32
|
+
{{ label }}
|
|
33
|
+
</h2>
|
|
34
|
+
<div
|
|
35
|
+
v-if="loading"
|
|
36
|
+
class="space-y-2"
|
|
37
|
+
>
|
|
38
|
+
<USkeleton class="h-5 w-2/3" />
|
|
39
|
+
<USkeleton class="h-4 w-1/3" />
|
|
40
|
+
</div>
|
|
41
|
+
<template v-else-if="$slots.default || value !== void 0 && value !== null && value !== ''">
|
|
42
|
+
<div class="text-highlighted flex flex-wrap items-center gap-2 text-lg font-semibold tabular-nums">
|
|
43
|
+
<slot>
|
|
44
|
+
{{ value }}
|
|
45
|
+
</slot>
|
|
46
|
+
</div>
|
|
47
|
+
<p
|
|
48
|
+
v-if="hint"
|
|
49
|
+
class="text-muted text-sm"
|
|
50
|
+
>
|
|
51
|
+
{{ hint }}
|
|
52
|
+
</p>
|
|
53
|
+
</template>
|
|
54
|
+
<p
|
|
55
|
+
v-else
|
|
56
|
+
class="text-muted text-sm"
|
|
57
|
+
>
|
|
58
|
+
{{ empty }}
|
|
59
|
+
</p>
|
|
60
|
+
</div>
|
|
61
|
+
</component>
|
|
62
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A number with a label (and an optional tinted icon and hint). Links to the list it summarises when `to` is set.
|
|
3
|
+
* The default slot replaces `value`; `empty` shows when there is neither.
|
|
4
|
+
*/
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
label: string;
|
|
7
|
+
value?: string | number;
|
|
8
|
+
hint?: string;
|
|
9
|
+
icon?: string;
|
|
10
|
+
to?: string;
|
|
11
|
+
loading?: boolean;
|
|
12
|
+
empty?: string;
|
|
13
|
+
};
|
|
14
|
+
declare var __VLS_23: {};
|
|
15
|
+
type __VLS_Slots = {} & {
|
|
16
|
+
default?: (props: typeof __VLS_23) => any;
|
|
17
|
+
};
|
|
18
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
20
|
+
declare const _default: typeof __VLS_export;
|
|
21
|
+
export default _default;
|
|
22
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
23
|
+
new (): {
|
|
24
|
+
$slots: S;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The surface a list table sits in: `<TableCard><UTable :ui="tableUi()" … /></TableCard>`. `#header` sits above
|
|
3
|
+
* the table (filters, a title), `#footer` below it (`TablePagination`). A surface only, so the table keeps its
|
|
4
|
+
* typed slots.
|
|
5
|
+
*
|
|
6
|
+
* `loading` is the first load (skeleton rows, nothing to show yet); `refreshing` is every load after that: the
|
|
7
|
+
* current rows stay and are dimmed until the next ones arrive, so paging, sorting and filtering do not flash.
|
|
8
|
+
*/
|
|
9
|
+
type __VLS_Props = {
|
|
10
|
+
/** Shows skeleton rows instead of the default slot. */
|
|
11
|
+
loading?: boolean;
|
|
12
|
+
/** Dims the rows on screen while new ones load. */
|
|
13
|
+
refreshing?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare var __VLS_1: {}, __VLS_18: {}, __VLS_20: {};
|
|
16
|
+
type __VLS_Slots = {} & {
|
|
17
|
+
header?: (props: typeof __VLS_1) => any;
|
|
18
|
+
} & {
|
|
19
|
+
default?: (props: typeof __VLS_18) => any;
|
|
20
|
+
} & {
|
|
21
|
+
footer?: (props: typeof __VLS_20) => any;
|
|
22
|
+
};
|
|
23
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { surfaceClass } from "../../utils/surface";
|
|
3
|
+
defineProps({
|
|
4
|
+
loading: { type: Boolean, required: false },
|
|
5
|
+
refreshing: { type: Boolean, required: false }
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div
|
|
11
|
+
:class="surfaceClass"
|
|
12
|
+
:aria-busy="loading || refreshing ? 'true' : void 0"
|
|
13
|
+
>
|
|
14
|
+
<div
|
|
15
|
+
v-if="$slots.header"
|
|
16
|
+
class="border-default flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3"
|
|
17
|
+
>
|
|
18
|
+
<slot name="header" />
|
|
19
|
+
</div>
|
|
20
|
+
<div
|
|
21
|
+
v-if="loading"
|
|
22
|
+
class="space-y-3 p-4"
|
|
23
|
+
>
|
|
24
|
+
<USkeleton class="h-5 w-full" />
|
|
25
|
+
<USkeleton class="h-5 w-5/6" />
|
|
26
|
+
<USkeleton class="h-5 w-2/3" />
|
|
27
|
+
</div>
|
|
28
|
+
<div
|
|
29
|
+
v-else
|
|
30
|
+
class="relative"
|
|
31
|
+
>
|
|
32
|
+
<slot />
|
|
33
|
+
<div
|
|
34
|
+
class="bg-default/50 pointer-events-none absolute inset-0 transition-opacity duration-150 motion-reduce:transition-none"
|
|
35
|
+
:class="refreshing ? 'opacity-100' : 'opacity-0'"
|
|
36
|
+
aria-hidden="true"
|
|
37
|
+
/>
|
|
38
|
+
</div>
|
|
39
|
+
<div
|
|
40
|
+
v-if="$slots.footer"
|
|
41
|
+
class="border-default text-muted flex flex-wrap items-center justify-between gap-3 border-t px-4 py-3 text-sm"
|
|
42
|
+
>
|
|
43
|
+
<slot name="footer" />
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The surface a list table sits in: `<TableCard><UTable :ui="tableUi()" … /></TableCard>`. `#header` sits above
|
|
3
|
+
* the table (filters, a title), `#footer` below it (`TablePagination`). A surface only, so the table keeps its
|
|
4
|
+
* typed slots.
|
|
5
|
+
*
|
|
6
|
+
* `loading` is the first load (skeleton rows, nothing to show yet); `refreshing` is every load after that: the
|
|
7
|
+
* current rows stay and are dimmed until the next ones arrive, so paging, sorting and filtering do not flash.
|
|
8
|
+
*/
|
|
9
|
+
type __VLS_Props = {
|
|
10
|
+
/** Shows skeleton rows instead of the default slot. */
|
|
11
|
+
loading?: boolean;
|
|
12
|
+
/** Dims the rows on screen while new ones load. */
|
|
13
|
+
refreshing?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare var __VLS_1: {}, __VLS_18: {}, __VLS_20: {};
|
|
16
|
+
type __VLS_Slots = {} & {
|
|
17
|
+
header?: (props: typeof __VLS_1) => any;
|
|
18
|
+
} & {
|
|
19
|
+
default?: (props: typeof __VLS_18) => any;
|
|
20
|
+
} & {
|
|
21
|
+
footer?: (props: typeof __VLS_20) => any;
|
|
22
|
+
};
|
|
23
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AvatarProps } from '@nuxt/ui';
|
|
2
|
+
/**
|
|
3
|
+
* The first cell of a list row: the record's name with a muted second line (an email, a slug, a client id) and an
|
|
4
|
+
* optional avatar. Badges that belong to the name (Admin, Draft) go in `#badges`.
|
|
5
|
+
*/
|
|
6
|
+
type __VLS_Props = {
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string | null;
|
|
9
|
+
/** Shows an avatar; `alt` alone renders initials. */
|
|
10
|
+
avatar?: AvatarProps;
|
|
11
|
+
};
|
|
12
|
+
type __VLS_Slots = {
|
|
13
|
+
badges?: () => unknown;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
20
|
+
new (): {
|
|
21
|
+
$slots: S;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
defineProps({
|
|
3
|
+
title: { type: String, required: true },
|
|
4
|
+
description: { type: [String, null], required: false },
|
|
5
|
+
avatar: { type: Object, required: false }
|
|
6
|
+
});
|
|
7
|
+
defineSlots();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div class="flex min-w-0 items-center gap-3">
|
|
12
|
+
<UAvatar
|
|
13
|
+
v-if="avatar"
|
|
14
|
+
size="sm"
|
|
15
|
+
v-bind="avatar"
|
|
16
|
+
/>
|
|
17
|
+
<div class="flex min-w-0 flex-col">
|
|
18
|
+
<div class="flex min-w-0 items-center gap-2">
|
|
19
|
+
<span class="text-highlighted truncate font-medium">{{ title }}</span>
|
|
20
|
+
<slot name="badges" />
|
|
21
|
+
</div>
|
|
22
|
+
<span
|
|
23
|
+
v-if="description"
|
|
24
|
+
class="text-muted truncate text-xs"
|
|
25
|
+
>{{ description }}</span>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AvatarProps } from '@nuxt/ui';
|
|
2
|
+
/**
|
|
3
|
+
* The first cell of a list row: the record's name with a muted second line (an email, a slug, a client id) and an
|
|
4
|
+
* optional avatar. Badges that belong to the name (Admin, Draft) go in `#badges`.
|
|
5
|
+
*/
|
|
6
|
+
type __VLS_Props = {
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string | null;
|
|
9
|
+
/** Shows an avatar; `alt` alone renders initials. */
|
|
10
|
+
avatar?: AvatarProps;
|
|
11
|
+
};
|
|
12
|
+
type __VLS_Slots = {
|
|
13
|
+
badges?: () => unknown;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
17
|
+
declare const _default: typeof __VLS_export;
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
20
|
+
new (): {
|
|
21
|
+
$slots: S;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The footer of a paginated list, inside `TableCard #footer`: "21–40 of 132", rows per page and the pages. Pages
|
|
3
|
+
* and the page-size select hide while everything fits on one page. Changing the page size goes back to page 1.
|
|
4
|
+
*/
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
total: number;
|
|
7
|
+
pageSizes?: number[];
|
|
8
|
+
};
|
|
9
|
+
type __VLS_ModelProps = {
|
|
10
|
+
'page'?: number;
|
|
11
|
+
'pageSize'?: number;
|
|
12
|
+
};
|
|
13
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
14
|
+
declare var __VLS_1: {
|
|
15
|
+
range: any;
|
|
16
|
+
};
|
|
17
|
+
type __VLS_Slots = {} & {
|
|
18
|
+
default?: (props: typeof __VLS_1) => any;
|
|
19
|
+
};
|
|
20
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
21
|
+
"update:page": (value: number) => any;
|
|
22
|
+
"update:pageSize": (value: number) => any;
|
|
23
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
24
|
+
"onUpdate:page"?: ((value: number) => any) | undefined;
|
|
25
|
+
"onUpdate:pageSize"?: ((value: number) => any) | undefined;
|
|
26
|
+
}>, {
|
|
27
|
+
pageSizes: number[];
|
|
28
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
29
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
30
|
+
declare const _default: typeof __VLS_export;
|
|
31
|
+
export default _default;
|
|
32
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
33
|
+
new (): {
|
|
34
|
+
$slots: S;
|
|
35
|
+
};
|
|
36
|
+
};
|