@revenexx/studio-shared 0.1.2 → 0.3.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 (120) hide show
  1. package/README.md +22 -12
  2. package/dist/module.d.mts +15 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +58 -0
  5. package/dist/runtime/components/DataTable/ColumnsMenu.d.vue.ts +12 -0
  6. package/{components → dist/runtime/components}/DataTable/ColumnsMenu.vue +13 -19
  7. package/dist/runtime/components/DataTable/ColumnsMenu.vue.d.ts +12 -0
  8. package/dist/runtime/components/DataTable/DataTable.d.vue.ts +87 -0
  9. package/dist/runtime/components/DataTable/DataTable.vue +510 -0
  10. package/dist/runtime/components/DataTable/DataTable.vue.d.ts +87 -0
  11. package/dist/runtime/components/DataTable/FilterMenu.d.vue.ts +21 -0
  12. package/dist/runtime/components/DataTable/FilterMenu.vue +46 -0
  13. package/dist/runtime/components/DataTable/FilterMenu.vue.d.ts +21 -0
  14. package/dist/runtime/components/DataTable/SavedViewsMenu.d.vue.ts +6 -0
  15. package/dist/runtime/components/DataTable/SavedViewsMenu.vue +189 -0
  16. package/dist/runtime/components/DataTable/SavedViewsMenu.vue.d.ts +6 -0
  17. package/dist/runtime/components/DataTable/SortMenu.d.vue.ts +13 -0
  18. package/dist/runtime/components/DataTable/SortMenu.vue +47 -0
  19. package/dist/runtime/components/DataTable/SortMenu.vue.d.ts +13 -0
  20. package/dist/runtime/components/DataTable/ViewModeSwitch.d.vue.ts +20 -0
  21. package/dist/runtime/components/DataTable/ViewModeSwitch.vue +26 -0
  22. package/dist/runtime/components/DataTable/ViewModeSwitch.vue.d.ts +20 -0
  23. package/dist/runtime/components/DataTable/types.d.ts +104 -0
  24. package/dist/runtime/components/DataTable/types.js +0 -0
  25. package/dist/runtime/components/Media/MediaFolderTree.d.vue.ts +17 -0
  26. package/dist/runtime/components/Media/MediaFolderTree.vue +65 -0
  27. package/dist/runtime/components/Media/MediaFolderTree.vue.d.ts +17 -0
  28. package/dist/runtime/components/Media/MediaPickerDialog.d.vue.ts +18 -0
  29. package/dist/runtime/components/Media/MediaPickerDialog.vue +163 -0
  30. package/dist/runtime/components/Media/MediaPickerDialog.vue.d.ts +18 -0
  31. package/dist/runtime/components/Media/MediaUploader.d.vue.ts +29 -0
  32. package/dist/runtime/components/Media/MediaUploader.vue +161 -0
  33. package/dist/runtime/components/Media/MediaUploader.vue.d.ts +29 -0
  34. package/dist/runtime/components/Shared/BuildLogsFlyout.d.vue.ts +30 -0
  35. package/{components → dist/runtime/components}/Shared/BuildLogsFlyout.vue +37 -54
  36. package/dist/runtime/components/Shared/BuildLogsFlyout.vue.d.ts +30 -0
  37. package/dist/runtime/components/Shared/GitDeploymentSettings.d.vue.ts +17 -0
  38. package/dist/runtime/components/Shared/GitDeploymentSettings.vue +75 -0
  39. package/dist/runtime/components/Shared/GitDeploymentSettings.vue.d.ts +17 -0
  40. package/dist/runtime/components/Shared/KpiTile.d.vue.ts +13 -0
  41. package/{components → dist/runtime/components}/Shared/KpiTile.vue +11 -19
  42. package/dist/runtime/components/Shared/KpiTile.vue.d.ts +13 -0
  43. package/dist/runtime/components/Shared/ListSurface.d.vue.ts +38 -0
  44. package/dist/runtime/components/Shared/ListSurface.vue +27 -0
  45. package/dist/runtime/components/Shared/ListSurface.vue.d.ts +38 -0
  46. package/dist/runtime/components/Shared/PageHeader.d.vue.ts +23 -0
  47. package/{components → dist/runtime/components}/Shared/PageHeader.vue +6 -8
  48. package/dist/runtime/components/Shared/PageHeader.vue.d.ts +23 -0
  49. package/dist/runtime/components/Shared/RecordLayout.d.vue.ts +52 -0
  50. package/dist/runtime/components/Shared/RecordLayout.vue +63 -0
  51. package/dist/runtime/components/Shared/RecordLayout.vue.d.ts +52 -0
  52. package/dist/runtime/components/Shared/RecordRailCard.d.vue.ts +26 -0
  53. package/dist/runtime/components/Shared/RecordRailCard.vue +20 -0
  54. package/dist/runtime/components/Shared/RecordRailCard.vue.d.ts +26 -0
  55. package/dist/runtime/components/Shared/SidebarNav.d.vue.ts +41 -0
  56. package/dist/runtime/components/Shared/SidebarNav.vue +48 -0
  57. package/dist/runtime/components/Shared/SidebarNav.vue.d.ts +41 -0
  58. package/dist/runtime/components/Shared/SidebarNavLink.d.vue.ts +15 -0
  59. package/dist/runtime/components/Shared/SidebarNavLink.vue +49 -0
  60. package/dist/runtime/components/Shared/SidebarNavLink.vue.d.ts +15 -0
  61. package/dist/runtime/components/Shared/SortHeader.d.vue.ts +23 -0
  62. package/dist/runtime/components/Shared/SortHeader.vue +35 -0
  63. package/dist/runtime/components/Shared/SortHeader.vue.d.ts +23 -0
  64. package/dist/runtime/components/Shared/StateCard.d.vue.ts +32 -0
  65. package/{components → dist/runtime/components}/Shared/StateCard.vue +21 -36
  66. package/dist/runtime/components/Shared/StateCard.vue.d.ts +32 -0
  67. package/dist/runtime/components/Shared/StudioCard.d.vue.ts +15 -0
  68. package/dist/runtime/components/Shared/StudioCard.vue +19 -0
  69. package/dist/runtime/components/Shared/StudioCard.vue.d.ts +15 -0
  70. package/dist/runtime/components/Shared/TabBar.d.vue.ts +23 -0
  71. package/{components → dist/runtime/components}/Shared/TabBar.vue +7 -16
  72. package/dist/runtime/components/Shared/TabBar.vue.d.ts +23 -0
  73. package/dist/runtime/components/Shared/ViewTab.d.vue.ts +7 -0
  74. package/{components → dist/runtime/components}/Shared/ViewTab.vue +7 -9
  75. package/dist/runtime/components/Shared/ViewTab.vue.d.ts +7 -0
  76. package/dist/runtime/components/Shared/Wizard.d.vue.ts +47 -0
  77. package/dist/runtime/components/Shared/Wizard.vue +66 -0
  78. package/dist/runtime/components/Shared/Wizard.vue.d.ts +47 -0
  79. package/dist/runtime/composables/useListRail.d.ts +9 -0
  80. package/dist/runtime/composables/useListRail.js +19 -0
  81. package/dist/runtime/composables/useMediaLibrary.d.ts +41 -0
  82. package/dist/runtime/composables/useMediaLibrary.js +36 -0
  83. package/dist/runtime/composables/usePlatformAuth.d.ts +35 -0
  84. package/dist/runtime/composables/usePlatformAuth.js +17 -0
  85. package/dist/runtime/composables/usePlatformTalkback.d.ts +29 -0
  86. package/dist/runtime/composables/usePlatformTalkback.js +54 -0
  87. package/dist/runtime/composables/usePlatformTenant.d.ts +14 -0
  88. package/dist/runtime/composables/usePlatformTenant.js +18 -0
  89. package/dist/runtime/composables/useT.d.ts +11 -0
  90. package/dist/runtime/composables/useT.js +8 -0
  91. package/dist/runtime/composables/useTalkbackChannels.d.ts +78 -0
  92. package/dist/runtime/composables/useTalkbackChannels.js +52 -0
  93. package/dist/runtime/lib/formatBridge.d.ts +50 -0
  94. package/dist/runtime/lib/formatBridge.js +54 -0
  95. package/dist/runtime/lib/i18nBridge.d.ts +31 -0
  96. package/dist/runtime/lib/i18nBridge.js +17 -0
  97. package/dist/runtime/lib/isoLists.d.ts +61 -0
  98. package/dist/runtime/lib/isoLists.js +62 -0
  99. package/dist/runtime/lib/sidebarNav.d.ts +34 -0
  100. package/dist/runtime/lib/sidebarNav.js +22 -0
  101. package/dist/runtime/lib/talkback.d.ts +59 -0
  102. package/dist/runtime/lib/talkback.js +49 -0
  103. package/dist/runtime/types/nav.d.ts +37 -0
  104. package/dist/runtime/types/nav.js +0 -0
  105. package/dist/runtime/types/storage.d.ts +67 -0
  106. package/dist/runtime/types/storage.js +0 -0
  107. package/dist/types.d.mts +27 -0
  108. package/package.json +41 -13
  109. package/components/DataTable/DataTable.vue +0 -518
  110. package/components/DataTable/FilterMenu.vue +0 -40
  111. package/components/DataTable/types.ts +0 -82
  112. package/components/Shared/GitDeploymentSettings.vue +0 -87
  113. package/components/Shared/SidebarNav.vue +0 -100
  114. package/components/Shared/SortHeader.vue +0 -50
  115. package/components/Shared/StudioCard.vue +0 -24
  116. package/components/Shared/Wizard.vue +0 -80
  117. package/composables/usePlatformAuth.ts +0 -35
  118. package/composables/usePlatformTenant.ts +0 -35
  119. package/index.ts +0 -16
  120. package/nuxt.config.ts +0 -23
@@ -0,0 +1,48 @@
1
+ <script>
2
+
3
+ </script>
4
+
5
+ <script setup>
6
+ import { sidebarItemKey } from "../../lib/sidebarNav";
7
+ import SidebarNavLink from "./SidebarNavLink.vue";
8
+ defineProps({
9
+ title: { type: String, required: true },
10
+ icon: { type: null, required: false },
11
+ sections: { type: Array, required: true },
12
+ minimal: { type: Boolean, required: false }
13
+ });
14
+ </script>
15
+
16
+ <template>
17
+ <aside class="h-full flex flex-col">
18
+ <div class="flex items-center gap-2 px-4 pt-4 pb-3 shrink-0 border-b border-black/[0.06]">
19
+ <slot v-if="!minimal" name="icon">
20
+ <component :is="icon" v-if="icon" :size="18" :stroke-width="2" class="text-foreground/70 shrink-0" />
21
+ </slot>
22
+ <h2 class="text-lg text-[#0B0522] truncate" :class="minimal ? 'font-medium' : 'font-semibold'">
23
+ {{ title }}
24
+ </h2>
25
+ </div>
26
+
27
+ <div class="flex-1 overflow-y-auto pt-3 pb-3">
28
+ <slot name="top" />
29
+
30
+ <template v-for="section in sections" :key="section.key">
31
+ <div v-if="section.label" class="mt-3 px-4 pb-1">
32
+ <div class="text-mono text-muted-foreground">
33
+ {{ section.label }}
34
+ </div>
35
+ </div>
36
+ <nav class="flex flex-col gap-0.5 px-2">
37
+ <SidebarNavLink
38
+ v-for="item in section.items"
39
+ :key="sidebarItemKey(item)"
40
+ :item="item"
41
+ />
42
+ </nav>
43
+ </template>
44
+
45
+ <slot name="notice" />
46
+ </div>
47
+ </aside>
48
+ </template>
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shared studio sidebar.
3
+ *
4
+ * Header (icon + title) + a sectioned, link list driven by data. Every
5
+ * studio sidebar (Settings, Integrations, Commerce, Apps, …) renders
6
+ * through this so spacing, active state, badges and "soon" tags stay
7
+ * identical. Pass `sections`; use `#notice` for loading/empty hints.
8
+ *
9
+ * Items may declare `children`. Those are **tabs of the page the item opens**,
10
+ * not sub-navigation: every item is exactly one row, and it stays highlighted
11
+ * while the route is on any of its tabs. A surface that should stand on its
12
+ * own in the sidebar is declared as its own item.
13
+ */
14
+ import type { Component } from 'vue';
15
+ import type { SidebarNavSection } from '../../types/nav.js';
16
+ export type { SidebarNavItem, SidebarNavSection } from '../../types/nav.js';
17
+ declare const _default: __VLS_WithSlots<import("vue").DefineComponent<{
18
+ title: string;
19
+ icon?: Component;
20
+ sections: SidebarNavSection[];
21
+ /** Hide the header icon and use a lighter header title weight. */
22
+ minimal?: boolean;
23
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
24
+ title: string;
25
+ icon?: Component;
26
+ sections: SidebarNavSection[];
27
+ /** Hide the header icon and use a lighter header title weight. */
28
+ minimal?: boolean;
29
+ }> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
30
+ icon?: (props: {}) => any;
31
+ } & {
32
+ top?: (props: {}) => any;
33
+ } & {
34
+ notice?: (props: {}) => any;
35
+ }>;
36
+ export default _default;
37
+ type __VLS_WithSlots<T, S> = T & {
38
+ new (): {
39
+ $slots: S;
40
+ };
41
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * One row of a `SidebarNav` section — always exactly one link, never a group.
3
+ *
4
+ * An item's `children` are the **tabs of the page this row opens**, not rows
5
+ * of their own (see `lib/sidebarNav.ts`), so there is nothing to expand here:
6
+ * the row links to the item's route, or — for a pure container that nominates
7
+ * no landing page — to its first tab, and stays highlighted while the route is
8
+ * on any of them.
9
+ */
10
+ import type { SidebarNavItem } from '../../types/nav.js';
11
+ type __VLS_Props = {
12
+ item: SidebarNavItem;
13
+ };
14
+ declare const _default: 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>;
15
+ export default _default;
@@ -0,0 +1,49 @@
1
+ <script setup>
2
+ import { sidebarItemIsCurrent, sidebarItemTarget } from "../../lib/sidebarNav";
3
+ const props = defineProps({
4
+ item: { type: Object, required: true }
5
+ });
6
+ const t = useT();
7
+ const route = useRoute();
8
+ const target = computed(() => sidebarItemTarget(props.item));
9
+ const current = computed(() => sidebarItemIsCurrent(props.item, route.path));
10
+ const rowClass = computed(() => [
11
+ "group flex w-full items-center gap-2.5 rounded-md px-2 py-1.5 text-sm transition-colors hover:text-primary",
12
+ current.value ? "bg-primary/10 text-[#0B0522] font-medium" : "text-foreground/80 hover:bg-primary/5",
13
+ props.item.preview ? "opacity-70" : ""
14
+ ]);
15
+ </script>
16
+
17
+ <template>
18
+ <NuxtLink v-if="target" :to="target" :class="rowClass">
19
+ <component :is="item.icon" v-if="item.icon" :size="14" :stroke-width="2" class="shrink-0 text-foreground/60 group-hover:text-primary" />
20
+ <span class="min-w-0 flex-1 truncate flex items-center gap-1.5">
21
+ {{ item.label }}
22
+ <span
23
+ v-if="item.preview"
24
+ class="rounded bg-muted px-1 text-mono text-muted-foreground"
25
+ :title="t('shared.nav.badge.comingsoon.tooltip')"
26
+ >
27
+ {{ t("shared.nav.badge.comingsoon.label") }}
28
+ </span>
29
+ </span>
30
+ <!--
31
+ What is waiting behind the entry. A count sits at the end of the row so
32
+ the labels stay left-aligned and scannable; a dot only says "something",
33
+ which is the honest rendering when the source cannot be counted.
34
+ Resolved upstream — an item with nothing pending carries no badge at all
35
+ rather than a zero, because a zero reads as a queue worth opening.
36
+ -->
37
+ <span
38
+ v-if="item.badge === 'dot'"
39
+ class="size-1.5 shrink-0 rounded-full bg-primary"
40
+ aria-hidden="true"
41
+ />
42
+ <span
43
+ v-else-if="item.badge !== null && item.badge !== void 0"
44
+ class="shrink-0 rounded-full bg-muted px-1.5 text-[11px] font-medium tabular-nums text-muted-foreground"
45
+ >
46
+ {{ item.badge }}
47
+ </span>
48
+ </NuxtLink>
49
+ </template>
@@ -0,0 +1,15 @@
1
+ /**
2
+ * One row of a `SidebarNav` section — always exactly one link, never a group.
3
+ *
4
+ * An item's `children` are the **tabs of the page this row opens**, not rows
5
+ * of their own (see `lib/sidebarNav.ts`), so there is nothing to expand here:
6
+ * the row links to the item's route, or — for a pure container that nominates
7
+ * no landing page — to its first tab, and stays highlighted while the route is
8
+ * on any of them.
9
+ */
10
+ import type { SidebarNavItem } from '../../types/nav.js';
11
+ type __VLS_Props = {
12
+ item: SidebarNavItem;
13
+ };
14
+ declare const _default: 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>;
15
+ export default _default;
@@ -0,0 +1,23 @@
1
+ type __VLS_Props = {
2
+ column: string;
3
+ active: string | null;
4
+ direction: 'asc' | 'desc' | null;
5
+ /** Right-align the indicator for numeric columns. */
6
+ alignRight?: boolean;
7
+ };
8
+ declare var __VLS_1: {};
9
+ type __VLS_Slots = {} & {
10
+ default?: (props: typeof __VLS_1) => any;
11
+ };
12
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
+ toggle: (column: string) => any;
14
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
15
+ onToggle?: ((column: string) => any) | undefined;
16
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,35 @@
1
+ <script setup>
2
+ import { RoundSortVertical, SortFromBottomToTop, SortFromTopToBottom } from "#solar-icons";
3
+ const props = defineProps({
4
+ column: { type: String, required: true },
5
+ active: { type: [String, null], required: true },
6
+ direction: { type: [String, null], required: true },
7
+ alignRight: { type: Boolean, required: false }
8
+ });
9
+ const emit = defineEmits(["toggle"]);
10
+ const isActive = computed(() => props.active === props.column && !!props.direction);
11
+ const sortIcon = computed(() => {
12
+ if (isActive.value && props.direction === "asc") return SortFromBottomToTop;
13
+ if (isActive.value && props.direction === "desc") return SortFromTopToBottom;
14
+ return RoundSortVertical;
15
+ });
16
+ </script>
17
+
18
+ <template>
19
+ <button
20
+ type="button"
21
+ class="group inline-flex cursor-pointer items-center gap-1.5 -m-1 p-1 rounded-md text-left transition-colors hover:text-primary"
22
+ :class="alignRight ? 'flex-row-reverse w-full justify-end' : ''"
23
+ @click="emit('toggle', column)"
24
+ >
25
+ <slot />
26
+ <component
27
+ :is="sortIcon"
28
+ weight="Linear"
29
+ :size="14"
30
+ class="shrink-0 transition-colors"
31
+ :class="isActive ? 'text-primary' : 'text-foreground/30 group-hover:text-primary'"
32
+ aria-hidden="true"
33
+ />
34
+ </button>
35
+ </template>
@@ -0,0 +1,23 @@
1
+ type __VLS_Props = {
2
+ column: string;
3
+ active: string | null;
4
+ direction: 'asc' | 'desc' | null;
5
+ /** Right-align the indicator for numeric columns. */
6
+ alignRight?: boolean;
7
+ };
8
+ declare var __VLS_1: {};
9
+ type __VLS_Slots = {} & {
10
+ default?: (props: typeof __VLS_1) => any;
11
+ };
12
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
+ toggle: (column: string) => any;
14
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
15
+ onToggle?: ((column: string) => any) | undefined;
16
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Shared empty / loading / error / not-found state.
3
+ *
4
+ * One calm centered card used across the studios so every "nothing here
5
+ * yet", "still loading" and "something broke" surface looks the same.
6
+ * Pass copy via props; put a CTA in the `#actions` slot.
7
+ */
8
+ import type { Component } from 'vue';
9
+ type Variant = 'empty' | 'loading' | 'error' | 'notfound';
10
+ type __VLS_Props = {
11
+ variant?: Variant;
12
+ /** Override the default icon for the variant. */
13
+ icon?: Component;
14
+ title: string;
15
+ description?: string;
16
+ };
17
+ declare var __VLS_22: {}, __VLS_28: {};
18
+ type __VLS_Slots = {} & {
19
+ description?: (props: typeof __VLS_22) => any;
20
+ } & {
21
+ actions?: (props: typeof __VLS_28) => any;
22
+ };
23
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
24
+ variant: Variant;
25
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
27
+ export default _default;
28
+ type __VLS_WithSlots<T, S> = T & {
29
+ new (): {
30
+ $slots: S;
31
+ };
32
+ };
@@ -1,43 +1,28 @@
1
- <script setup lang="ts">
2
- /**
3
- * Shared empty / loading / error / not-found state.
4
- *
5
- * One calm centered card used across the studios so every "nothing here
6
- * yet", "still loading" and "something broke" surface looks the same.
7
- * Pass copy via props; put a CTA in the `#actions` slot.
8
- */
9
- import type { Component } from 'vue'
1
+ <script setup>
10
2
  import {
11
- Card, CardContent, CardDescription, CardHeader, CardTitle,
12
- } from '@revenexx/studio'
13
- import { Box as Boxes, DangerTriangle as AlertTriangle, MagniferZoomIn as Magnifier } from '#solar-icons'
14
-
15
- type Variant = 'empty' | 'loading' | 'error' | 'notfound'
16
-
17
- const props = withDefaults(defineProps<{
18
- variant?: Variant
19
- /** Override the default icon for the variant. */
20
- icon?: Component
21
- title: string
22
- description?: string
23
- }>(), {
24
- variant: 'empty',
25
- })
26
-
27
- const defaultIcon: Record<Variant, Component> = {
3
+ Card,
4
+ CardContent,
5
+ CardDescription,
6
+ CardHeader,
7
+ CardTitle
8
+ } from "@revenexx/studio";
9
+ import { Box as Boxes, DangerTriangle as AlertTriangle, MagniferZoomIn as Magnifier } from "#solar-icons";
10
+ const props = defineProps({
11
+ variant: { type: String, required: false, default: "empty" },
12
+ icon: { type: null, required: false },
13
+ title: { type: String, required: true },
14
+ description: { type: String, required: false }
15
+ });
16
+ const defaultIcon = {
28
17
  empty: Boxes,
29
18
  loading: Boxes,
30
19
  error: AlertTriangle,
31
- notfound: Magnifier,
32
- }
33
-
34
- const resolvedIcon = computed(() => props.icon ?? defaultIcon[props.variant])
35
-
36
- const tileClass = computed(() =>
37
- props.variant === 'error'
38
- ? 'bg-rose-500/10 text-rose-600'
39
- : 'bg-primary/10 text-primary',
40
- )
20
+ notfound: Magnifier
21
+ };
22
+ const resolvedIcon = computed(() => props.icon ?? defaultIcon[props.variant]);
23
+ const tileClass = computed(
24
+ () => props.variant === "error" ? "bg-rose-500/10 text-rose-600" : "bg-primary/10 text-primary"
25
+ );
41
26
  </script>
42
27
 
43
28
  <template>
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Shared empty / loading / error / not-found state.
3
+ *
4
+ * One calm centered card used across the studios so every "nothing here
5
+ * yet", "still loading" and "something broke" surface looks the same.
6
+ * Pass copy via props; put a CTA in the `#actions` slot.
7
+ */
8
+ import type { Component } from 'vue';
9
+ type Variant = 'empty' | 'loading' | 'error' | 'notfound';
10
+ type __VLS_Props = {
11
+ variant?: Variant;
12
+ /** Override the default icon for the variant. */
13
+ icon?: Component;
14
+ title: string;
15
+ description?: string;
16
+ };
17
+ declare var __VLS_22: {}, __VLS_28: {};
18
+ type __VLS_Slots = {} & {
19
+ description?: (props: typeof __VLS_22) => any;
20
+ } & {
21
+ actions?: (props: typeof __VLS_28) => any;
22
+ };
23
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
24
+ variant: Variant;
25
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
27
+ export default _default;
28
+ type __VLS_WithSlots<T, S> = T & {
29
+ new (): {
30
+ $slots: S;
31
+ };
32
+ };
@@ -0,0 +1,15 @@
1
+ type __VLS_Props = {
2
+ to?: string;
3
+ };
4
+ declare var __VLS_6: {};
5
+ type __VLS_Slots = {} & {
6
+ default?: (props: typeof __VLS_6) => any;
7
+ };
8
+ declare const __VLS_component: 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>;
9
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
10
+ export default _default;
11
+ type __VLS_WithSlots<T, S> = T & {
12
+ new (): {
13
+ $slots: S;
14
+ };
15
+ };
@@ -0,0 +1,19 @@
1
+ <script setup>
2
+ import { NuxtLink } from "#components";
3
+ defineProps({
4
+ to: { type: String, required: false }
5
+ });
6
+ </script>
7
+
8
+ <template>
9
+ <component
10
+ :is="to ? NuxtLink : 'div'"
11
+ :to="to"
12
+ class="block rounded-lg border border-gray-400/10 outline-1 outline-white/30"
13
+ :class="to ? 'transition-transform hover:-translate-y-0.5' : ''"
14
+ >
15
+ <div class="relative h-full overflow-hidden rounded-lg bg-white">
16
+ <slot />
17
+ </div>
18
+ </component>
19
+ </template>
@@ -0,0 +1,15 @@
1
+ type __VLS_Props = {
2
+ to?: string;
3
+ };
4
+ declare var __VLS_6: {};
5
+ type __VLS_Slots = {} & {
6
+ default?: (props: typeof __VLS_6) => any;
7
+ };
8
+ declare const __VLS_component: 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>;
9
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
10
+ export default _default;
11
+ type __VLS_WithSlots<T, S> = T & {
12
+ new (): {
13
+ $slots: S;
14
+ };
15
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Underline tab bar — the standard cockpit detail-page tabs. A full-width
3
+ * hairline sits behind the row; the active/hover indicator is a 2px bar that
4
+ * spans exactly the label width (inset-x-3 = the px-3 padding), sitting on the
5
+ * baseline over the hairline. Active = primary; hover = soft primary. Tabs
6
+ * scroll horizontally on overflow. To bleed the line to the panel edges, pass
7
+ * e.g. `class="-mx-4 px-4"` from a padded page.
8
+ */
9
+ export interface TabItem {
10
+ key: string;
11
+ label: string;
12
+ badge?: number | string | null;
13
+ }
14
+ type __VLS_Props = {
15
+ tabs: TabItem[];
16
+ modelValue: string;
17
+ };
18
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:modelValue": (key: string) => any;
20
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
21
+ "onUpdate:modelValue"?: ((key: string) => any) | undefined;
22
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ export default _default;
@@ -1,16 +1,9 @@
1
- <script setup lang="ts">
2
- /**
3
- * Underline tab bar — the standard cockpit detail-page tabs. A full-width
4
- * hairline sits behind the row; the active/hover indicator is a 2px bar that
5
- * spans exactly the label width (inset-x-3 = the px-3 padding), sitting on the
6
- * baseline over the hairline. Active = primary; hover = soft primary. Tabs
7
- * scroll horizontally on overflow. To bleed the line to the panel edges, pass
8
- * e.g. `class="-mx-4 px-4"` from a padded page.
9
- */
10
- export interface TabItem { key: string, label: string, badge?: number | string | null }
11
-
12
- defineProps<{ tabs: TabItem[], modelValue: string }>()
13
- defineEmits<{ 'update:modelValue': [key: string] }>()
1
+ <script setup>
2
+ defineProps({
3
+ tabs: { type: Array, required: true },
4
+ modelValue: { type: String, required: true }
5
+ });
6
+ defineEmits(["update:modelValue"]);
14
7
  </script>
15
8
 
16
9
  <template>
@@ -27,9 +20,7 @@ defineEmits<{ 'update:modelValue': [key: string] }>()
27
20
  :key="t.key"
28
21
  type="button"
29
22
  class="group relative shrink-0 cursor-pointer whitespace-nowrap px-2.5 py-2 text-sm font-medium transition-colors"
30
- :class="modelValue === t.key
31
- ? 'text-[#0B0522] hover:text-primary'
32
- : 'text-[#0B0522]/80 hover:text-primary'"
23
+ :class="modelValue === t.key ? 'text-[#0B0522] hover:text-primary' : 'text-[#0B0522]/80 hover:text-primary'"
33
24
  @click="$emit('update:modelValue', t.key)"
34
25
  >
35
26
  {{ t.label }}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Underline tab bar — the standard cockpit detail-page tabs. A full-width
3
+ * hairline sits behind the row; the active/hover indicator is a 2px bar that
4
+ * spans exactly the label width (inset-x-3 = the px-3 padding), sitting on the
5
+ * baseline over the hairline. Active = primary; hover = soft primary. Tabs
6
+ * scroll horizontally on overflow. To bleed the line to the panel edges, pass
7
+ * e.g. `class="-mx-4 px-4"` from a padded page.
8
+ */
9
+ export interface TabItem {
10
+ key: string;
11
+ label: string;
12
+ badge?: number | string | null;
13
+ }
14
+ type __VLS_Props = {
15
+ tabs: TabItem[];
16
+ modelValue: string;
17
+ };
18
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:modelValue": (key: string) => any;
20
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
21
+ "onUpdate:modelValue"?: ((key: string) => any) | undefined;
22
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
+ export default _default;
@@ -0,0 +1,7 @@
1
+ type __VLS_Props = {
2
+ active?: boolean;
3
+ icon?: unknown;
4
+ label: string;
5
+ };
6
+ declare const _default: 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>;
7
+ export default _default;
@@ -1,18 +1,16 @@
1
- <script setup lang="ts">
2
- defineProps<{
3
- active?: boolean
4
- icon?: unknown
5
- label: string
6
- }>()
1
+ <script setup>
2
+ defineProps({
3
+ active: { type: Boolean, required: false },
4
+ icon: { type: null, required: false },
5
+ label: { type: String, required: true }
6
+ });
7
7
  </script>
8
8
 
9
9
  <template>
10
10
  <button
11
11
  type="button"
12
12
  class="group flex items-center gap-1.5 rounded-md px-2 py-1 text-sm font-medium transition-colors"
13
- :class="active
14
- ? 'bg-[#f3f1fa] text-[#0B0522]'
15
- : 'text-foreground/70 hover:bg-muted/50 hover:text-foreground'"
13
+ :class="active ? 'bg-[#f3f1fa] text-[#0B0522]' : 'text-foreground/70 hover:bg-muted/50 hover:text-foreground'"
16
14
  >
17
15
  <component
18
16
  :is="icon"
@@ -0,0 +1,7 @@
1
+ type __VLS_Props = {
2
+ active?: boolean;
3
+ icon?: unknown;
4
+ label: string;
5
+ };
6
+ declare const _default: 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>;
7
+ export default _default;
@@ -0,0 +1,47 @@
1
+ interface Step {
2
+ key: string;
3
+ title: string;
4
+ description?: string;
5
+ }
6
+ type __VLS_Props = {
7
+ steps: Step[];
8
+ modelValue?: number;
9
+ /** Gate the Next/Finish button for the current step. */
10
+ canAdvance?: boolean;
11
+ busy?: boolean;
12
+ };
13
+ declare var __VLS_1: {
14
+ step: any;
15
+ index: any;
16
+ }, __VLS_3: {
17
+ back: any;
18
+ next: any;
19
+ isFirst: any;
20
+ isLast: any;
21
+ canAdvance: any;
22
+ busy: any;
23
+ index: any;
24
+ };
25
+ type __VLS_Slots = {} & {
26
+ default?: (props: typeof __VLS_1) => any;
27
+ } & {
28
+ footer?: (props: typeof __VLS_3) => any;
29
+ };
30
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
31
+ "update:modelValue": (args_0: number) => any;
32
+ finish: () => any;
33
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
34
+ "onUpdate:modelValue"?: ((args_0: number) => any) | undefined;
35
+ onFinish?: (() => any) | undefined;
36
+ }>, {
37
+ modelValue: number;
38
+ canAdvance: boolean;
39
+ busy: boolean;
40
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
41
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
42
+ export default _default;
43
+ type __VLS_WithSlots<T, S> = T & {
44
+ new (): {
45
+ $slots: S;
46
+ };
47
+ };