@frigear-nu/ui 0.0.9 → 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.
Files changed (81) hide show
  1. package/README.md +46 -2
  2. package/dist/module.mjs +12 -9
  3. package/dist/runtime/components/ConfirmDialog.d.vue.ts +1 -0
  4. package/dist/runtime/components/ConfirmDialog.vue +4 -2
  5. package/dist/runtime/components/ConfirmDialog.vue.d.ts +1 -0
  6. package/dist/runtime/components/global/DescriptionList.d.vue.ts +28 -0
  7. package/dist/runtime/components/global/DescriptionList.vue +51 -0
  8. package/dist/runtime/components/global/DescriptionList.vue.d.ts +28 -0
  9. package/dist/runtime/components/global/FormSlideover.d.vue.ts +46 -0
  10. package/dist/runtime/components/global/FormSlideover.vue +53 -0
  11. package/dist/runtime/components/global/FormSlideover.vue.d.ts +46 -0
  12. package/dist/runtime/components/global/ListCard.d.vue.ts +29 -0
  13. package/dist/runtime/components/global/ListCard.vue +74 -0
  14. package/dist/runtime/components/global/ListCard.vue.d.ts +29 -0
  15. package/dist/runtime/components/global/PageHeading.d.vue.ts +28 -0
  16. package/dist/runtime/components/global/PageHeading.vue +53 -0
  17. package/dist/runtime/components/global/PageHeading.vue.d.ts +28 -0
  18. package/dist/runtime/components/global/PageTabs.d.vue.ts +19 -0
  19. package/dist/runtime/components/global/PageTabs.vue +28 -0
  20. package/dist/runtime/components/global/PageTabs.vue.d.ts +19 -0
  21. package/dist/runtime/components/global/PageToolbar.d.vue.ts +15 -0
  22. package/dist/runtime/components/global/PageToolbar.vue +15 -0
  23. package/dist/runtime/components/global/PageToolbar.vue.d.ts +15 -0
  24. package/dist/runtime/components/global/RowMenu.d.vue.ts +19 -0
  25. package/dist/runtime/components/global/RowMenu.vue +31 -0
  26. package/dist/runtime/components/global/RowMenu.vue.d.ts +19 -0
  27. package/dist/runtime/components/global/SectionCard.d.vue.ts +31 -0
  28. package/dist/runtime/components/global/SectionCard.vue +68 -0
  29. package/dist/runtime/components/global/SectionCard.vue.d.ts +31 -0
  30. package/dist/runtime/components/global/StatCard.d.vue.ts +26 -0
  31. package/dist/runtime/components/global/StatCard.vue +62 -0
  32. package/dist/runtime/components/global/StatCard.vue.d.ts +26 -0
  33. package/dist/runtime/components/global/TableCard.d.vue.ts +31 -0
  34. package/dist/runtime/components/global/TableCard.vue +46 -0
  35. package/dist/runtime/components/global/TableCard.vue.d.ts +31 -0
  36. package/dist/runtime/components/global/TableIdentity.d.vue.ts +23 -0
  37. package/dist/runtime/components/global/TableIdentity.vue +28 -0
  38. package/dist/runtime/components/global/TableIdentity.vue.d.ts +23 -0
  39. package/dist/runtime/components/global/TablePagination.d.vue.ts +36 -0
  40. package/dist/runtime/components/global/TablePagination.vue +51 -0
  41. package/dist/runtime/components/global/TablePagination.vue.d.ts +36 -0
  42. package/dist/runtime/composables/index.d.ts +8 -0
  43. package/dist/runtime/composables/index.js +8 -0
  44. package/dist/runtime/composables/useAction.d.ts +14 -0
  45. package/dist/runtime/composables/useAction.js +20 -0
  46. package/dist/runtime/composables/useCopyToClipboard.d.ts +4 -0
  47. package/dist/runtime/composables/useCopyToClipboard.js +20 -0
  48. package/dist/runtime/composables/useErrorToast.d.ts +9 -0
  49. package/dist/runtime/composables/useErrorToast.js +9 -0
  50. package/dist/runtime/composables/useFormat.d.ts +23 -0
  51. package/dist/runtime/composables/useFormat.js +19 -0
  52. package/dist/runtime/composables/useLocaleLink.d.ts +13 -0
  53. package/dist/runtime/composables/useLocaleLink.js +19 -0
  54. package/dist/runtime/composables/useNavLinks.d.ts +13 -0
  55. package/dist/runtime/composables/useNavLinks.js +15 -0
  56. package/dist/runtime/composables/useTableQuery.d.ts +34 -0
  57. package/dist/runtime/composables/useTableQuery.js +70 -0
  58. package/dist/runtime/composables/useTableSort.d.ts +21 -0
  59. package/dist/runtime/composables/useTableSort.js +40 -0
  60. package/dist/runtime/i18n/lang/da.json +19 -0
  61. package/dist/runtime/i18n/lang/en.json +19 -0
  62. package/dist/runtime/types.d.ts +34 -0
  63. package/dist/runtime/types.js +0 -0
  64. package/dist/runtime/utils/errors.d.ts +9 -0
  65. package/dist/runtime/utils/errors.js +18 -0
  66. package/dist/runtime/utils/format.d.ts +12 -0
  67. package/dist/runtime/utils/format.js +26 -0
  68. package/dist/runtime/utils/index.d.ts +6 -0
  69. package/dist/runtime/utils/index.js +6 -0
  70. package/dist/runtime/utils/locale.d.ts +8 -0
  71. package/dist/runtime/utils/locale.js +10 -0
  72. package/dist/runtime/utils/status.d.ts +7 -0
  73. package/dist/runtime/utils/status.js +17 -0
  74. package/dist/runtime/utils/surface.d.ts +22 -0
  75. package/dist/runtime/utils/surface.js +10 -0
  76. package/dist/runtime/utils/table.d.ts +28 -0
  77. package/dist/runtime/utils/table.js +17 -0
  78. package/package.json +28 -14
  79. package/dist/runtime/components/App/AppPageHeader.d.vue.ts +0 -23
  80. package/dist/runtime/components/App/AppPageHeader.vue +0 -58
  81. package/dist/runtime/components/App/AppPageHeader.vue.d.ts +0 -23
@@ -0,0 +1,6 @@
1
+ export * from "./errors.js";
2
+ export * from "./format.js";
3
+ export * from "./locale.js";
4
+ export * from "./status.js";
5
+ export * from "./surface.js";
6
+ export * from "./table.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Removes a leading `/<locale>` segment (one of `codes`), the query, the hash and a trailing slash from a path, so
3
+ * paths compare the same with and without an `@nuxtjs/i18n` prefix: `stripLocale('/da/admin/', ['en', 'da'])` is
4
+ * `/admin`.
5
+ */
6
+ export declare function stripLocale(path: string, codes: readonly string[]): string;
7
+ /** Whether `to` points outside the app (`https://…`, `mailto:…`, protocol-relative `//…`). */
8
+ export declare function isExternalPath(to: string): boolean;
@@ -0,0 +1,10 @@
1
+ export function stripLocale(path, codes) {
2
+ const pathname = path.split(/[?#]/)[0] || "/";
3
+ const trimmed = pathname.length > 1 ? pathname.replace(/\/+$/, "") || "/" : pathname;
4
+ const first = trimmed.split("/")[1];
5
+ if (!first || !codes.includes(first)) return trimmed;
6
+ return trimmed.slice(first.length + 1) || "/";
7
+ }
8
+ export function isExternalPath(to) {
9
+ return /^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(to);
10
+ }
@@ -0,0 +1,7 @@
1
+ import type { StatusColor } from '../types.js';
2
+ /**
3
+ * The badge colour of a status: green for done or live states (published, active, trialing, paid, succeeded), amber
4
+ * for states that need attention (pending, past_due, incomplete, scheduled), red for failed, neutral otherwise.
5
+ * `overrides` (keyed by lower-case status) win.
6
+ */
7
+ export declare function statusColor(status: string | null | undefined, overrides?: Record<string, StatusColor>): StatusColor;
@@ -0,0 +1,17 @@
1
+ const DEFAULT_STATUS_COLORS = {
2
+ published: "success",
3
+ active: "success",
4
+ trialing: "success",
5
+ paid: "success",
6
+ succeeded: "success",
7
+ pending: "warning",
8
+ past_due: "warning",
9
+ incomplete: "warning",
10
+ scheduled: "warning",
11
+ failed: "error"
12
+ };
13
+ export function statusColor(status, overrides = {}) {
14
+ if (!status) return "neutral";
15
+ const key = status.toLowerCase();
16
+ return overrides[key] ?? DEFAULT_STATUS_COLORS[key] ?? "neutral";
17
+ }
@@ -0,0 +1,22 @@
1
+ /** The surface every card shares (`SectionCard`, `TableCard`, `StatCard`, `ListCard`). */
2
+ export declare const surfaceClass = "bg-elevated/50 ring ring-default rounded-lg overflow-hidden";
3
+ export interface TableUi {
4
+ root?: string;
5
+ th?: string;
6
+ td?: string;
7
+ tr?: string;
8
+ [slot: string]: string | undefined;
9
+ }
10
+ export interface TableUiOptions {
11
+ /**
12
+ * For a `UTable sticky`: the table scrolls inside its card (`max-h-[70vh]`) so the header stays in view. Nuxt UI
13
+ * gives the sticky header its own translucent background.
14
+ */
15
+ sticky?: boolean;
16
+ }
17
+ /**
18
+ * The `:ui` of a `UTable` inside a `TableCard`: small muted headers, compact rows on desktop and taller (touch
19
+ * friendly) rows on mobile, clickable rows. `overrides` replace single slots (`tableUi({ tr: '' })` for rows that do
20
+ * not open anything).
21
+ */
22
+ export declare function tableUi(overrides?: TableUi, options?: TableUiOptions): TableUi;
@@ -0,0 +1,10 @@
1
+ export const surfaceClass = "bg-elevated/50 ring ring-default rounded-lg overflow-hidden";
2
+ export function tableUi(overrides = {}, options = {}) {
3
+ return {
4
+ ...options.sticky ? { root: "max-h-[70vh]" } : {},
5
+ th: "text-muted text-xs font-normal py-2",
6
+ td: "max-md:py-3 md:py-2",
7
+ tr: "cursor-pointer",
8
+ ...overrides
9
+ };
10
+ }
@@ -0,0 +1,28 @@
1
+ /** One sorted column in `UTable`'s shape. */
2
+ export interface TableSortState {
3
+ id: string;
4
+ desc: boolean;
5
+ }
6
+ /** The meta of a column holding numbers: right-aligned, tabular figures so digits line up. */
7
+ export declare const numericColumn: {
8
+ readonly class: {
9
+ readonly th: "text-right";
10
+ readonly td: "text-right tabular-nums";
11
+ };
12
+ };
13
+ /** A dimmed dash for a cell without a value (no date, no role, ...). */
14
+ export declare function emptyCell(): import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
15
+ [key: string]: any;
16
+ }>;
17
+ /** The sort after a click on `id`'s header: ascending, then descending, then unsorted. */
18
+ export declare function nextTableSort(current: TableSortState | null | undefined, id: string): TableSortState | null;
19
+ /** The `sort` / `order` query of a server-sorted list (both `undefined` when unsorted). */
20
+ export declare function tableSortQuery(sort: TableSortState | null | undefined): {
21
+ sort?: string;
22
+ order?: 'asc' | 'desc';
23
+ };
24
+ /** The first and last row number shown on `page` (1-based), `{ from: 0, to: 0 }` when it is empty. */
25
+ export declare function tablePageRange(page: number, pageSize: number, total: number): {
26
+ from: number;
27
+ to: number;
28
+ };
@@ -0,0 +1,17 @@
1
+ import { h } from "vue";
2
+ export const numericColumn = { class: { th: "text-right", td: "text-right tabular-nums" } };
3
+ export function emptyCell() {
4
+ return h("span", { class: "text-dimmed" }, "\u2014");
5
+ }
6
+ export function nextTableSort(current, id) {
7
+ if (current?.id !== id) return { id, desc: false };
8
+ return current.desc ? null : { id, desc: true };
9
+ }
10
+ export function tableSortQuery(sort) {
11
+ return sort ? { sort: sort.id, order: sort.desc ? "desc" : "asc" } : { sort: void 0, order: void 0 };
12
+ }
13
+ export function tablePageRange(page, pageSize, total) {
14
+ const from = (page - 1) * pageSize + 1;
15
+ if (total <= 0 || from > total) return { from: 0, to: 0 };
16
+ return { from, to: Math.min(page * pageSize, total) };
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frigear-nu/ui",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "description": "Shared UI components and composables for Frigear Nuxt applications, built on Nuxt UI.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://docs.frigear.dev/modules/ui",
@@ -22,7 +22,9 @@
22
22
  "./composables/*": "./dist/runtime/composables/*.js",
23
23
  "./translated": "./dist/runtime/translated.js",
24
24
  "./markdown": "./dist/runtime/markdown.js",
25
- "./money": "./dist/runtime/shared/money.js"
25
+ "./money": "./dist/runtime/shared/money.js",
26
+ "./utils": "./dist/runtime/utils/index.js",
27
+ "./types": "./dist/runtime/types.js"
26
28
  },
27
29
  "main": "./dist/module.mjs",
28
30
  "workspaces": [
@@ -32,28 +34,40 @@
32
34
  "dist"
33
35
  ],
34
36
  "dependencies": {
35
- "@nuxt/kit": "^4.6.0",
37
+ "@frigear-nu/module-kit": "1.1.0",
38
+ "@nuxt/kit": "^4.6.1",
36
39
  "@vueuse/core": "^13.5.0",
37
- "defu": "^6.1.4",
38
- "nuxt-monaco-editor": "^1.4.1",
39
- "monaco-editor": "^0.56.0"
40
+ "defu": "^6.1.4"
40
41
  },
41
42
  "devDependencies": {
42
- "@frigear-nu/eslint-config": "0.0.4",
43
+ "@frigear-nu/eslint-config": "0.1.0",
43
44
  "@nuxt/module-builder": "^1.0.3",
44
- "@nuxt/schema": "^4.6.0",
45
- "@nuxt/ui": "^4.10.0",
46
- "eslint": "^10.8.1",
45
+ "@nuxt/schema": "^4.6.1",
46
+ "@nuxt/test-utils": "^4.3.2",
47
+ "@nuxt/ui": "^4.11.2",
48
+ "eslint": "^10.12.0",
49
+ "monaco-editor": "^0.56.0",
47
50
  "nuxt": "^4.6.1",
51
+ "nuxt-monaco-editor": "^1.4.1",
48
52
  "tailwindcss": "^4.3.3",
49
53
  "typescript": "^6.0.3",
50
- "vitest": "^5.0.0",
54
+ "vitest": "^5.0.2",
51
55
  "vue-tsc": "^3.3.11"
52
56
  },
53
57
  "peerDependencies": {
54
- "@nuxt/ui": "^4.10.0",
55
- "nuxt": "^3.0.0 || ^4.0.0",
56
- "vue": "3.x"
58
+ "@nuxt/ui": "^4.11.2",
59
+ "nuxt": "^4.6.1",
60
+ "vue": "3.x",
61
+ "monaco-editor": "^0.56.0",
62
+ "nuxt-monaco-editor": "^1.4.1"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "monaco-editor": {
66
+ "optional": true
67
+ },
68
+ "nuxt-monaco-editor": {
69
+ "optional": true
70
+ }
57
71
  },
58
72
  "scripts": {
59
73
  "postinstall": "nuxt-module-build build --stub && nuxt prepare",
@@ -1,23 +0,0 @@
1
- import type { ButtonProps, PageHeaderProps, BreadcrumbItem } from '@nuxt/ui';
2
- type Props = PageHeaderProps & {
3
- returnButton?: ButtonProps | false;
4
- crumbs?: BreadcrumbItem[];
5
- };
6
- declare var __VLS_9: {}, __VLS_28: string, __VLS_29: {};
7
- type __VLS_Slots = {} & {
8
- [K in NonNullable<typeof __VLS_28>]?: (props: typeof __VLS_29) => any;
9
- } & {
10
- headline?: (props: typeof __VLS_9) => any;
11
- };
12
- declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
13
- returnButton: ButtonProps | false;
14
- crumbs: BreadcrumbItem[];
15
- }, {}, {}, {}, 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
- };
@@ -1,58 +0,0 @@
1
- <script setup>
2
- import { objectOmit } from "@vueuse/core";
3
- import defu from "defu";
4
- defineProps({
5
- as: { type: null, required: false },
6
- headline: { type: String, required: false },
7
- title: { type: String, required: false },
8
- description: { type: String, required: false },
9
- links: { type: Array, required: false },
10
- class: { type: null, required: false },
11
- ui: { type: Object, required: false },
12
- returnButton: { type: [Object, Boolean], required: false, default: () => ({
13
- label: "Dashboard",
14
- to: "/app",
15
- icon: "i-lucide-arrow-left",
16
- variant: "link"
17
- }) },
18
- crumbs: { type: Array, required: false, default: () => [] }
19
- });
20
- const forwardedSlots = ["links", "description"];
21
- </script>
22
-
23
- <template>
24
- <UPageHeader
25
- v-bind="objectOmit($props, ['returnButton'])"
26
- :ui="{ headline: 'flex-1 p-0' }"
27
- >
28
- <!-- Manually handled slot -->
29
- <template #headline>
30
- <slot name="headline">
31
- <div class="flex items-center gap-2">
32
- <UButton
33
- v-if="returnButton !== false && returnButton !== void 0"
34
- class="p-0"
35
- v-bind="defu(returnButton, { variant: 'link' })"
36
- />
37
- <UIcon
38
- v-if="crumbs && crumbs.length > 0"
39
- name="i-lucide-chevron-right"
40
- />
41
- <UBreadcrumb
42
- v-if="crumbs && crumbs.length > 0"
43
- :items="crumbs"
44
- label-key="label"
45
- />
46
- </div>
47
- </slot>
48
- </template>
49
-
50
- <template
51
- v-for="slotName in forwardedSlots"
52
- :key="slotName"
53
- #[slotName]
54
- >
55
- <slot :name="slotName" />
56
- </template>
57
- </UPageHeader>
58
- </template>
@@ -1,23 +0,0 @@
1
- import type { ButtonProps, PageHeaderProps, BreadcrumbItem } from '@nuxt/ui';
2
- type Props = PageHeaderProps & {
3
- returnButton?: ButtonProps | false;
4
- crumbs?: BreadcrumbItem[];
5
- };
6
- declare var __VLS_9: {}, __VLS_28: string, __VLS_29: {};
7
- type __VLS_Slots = {} & {
8
- [K in NonNullable<typeof __VLS_28>]?: (props: typeof __VLS_29) => any;
9
- } & {
10
- headline?: (props: typeof __VLS_9) => any;
11
- };
12
- declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
13
- returnButton: ButtonProps | false;
14
- crumbs: BreadcrumbItem[];
15
- }, {}, {}, {}, 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
- };