@ramathibodi/nuxt-commons 4.0.15 → 4.0.17

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/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^4.3.1"
6
6
  },
7
- "version": "4.0.15",
7
+ "version": "4.0.17",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -36,7 +36,7 @@ const module$1 = defineNuxtModule({
36
36
  src: resolver.resolve("runtime/plugins/default"),
37
37
  mode: "client"
38
38
  });
39
- const typeFiles = ["modules", "alert", "menu", "graphqlOperation", "formDialog", "dialogManager", "permission", "clientConfig", "bridge"];
39
+ const typeFiles = ["modules", "alert", "menu", "graphqlOperation", "api", "formDialog", "dialogManager", "permission", "clientConfig", "bridge"];
40
40
  for (const file of typeFiles) {
41
41
  addTypeTemplate({
42
42
  src: resolver.resolve(`runtime/types/${file}.d.ts`),
@@ -70,7 +70,6 @@ const dobFormat = computed(() => {
70
70
  :year-range="birthdateYearRange"
71
71
  :max-date="maxBirthdate"
72
72
  reverse-years
73
- eager
74
73
  >
75
74
  <template #append="{ isReadonly, isDisabled, activatorProps, toggleMenuOpen }">
76
75
  <span
@@ -71,7 +71,7 @@ watch(props.modelValue, () => {
71
71
  :value="item.value"
72
72
  density="compact"
73
73
  hide-details
74
- :error="isValid === false"
74
+ :error="isValid.value === false"
75
75
  :="$attrs"
76
76
  :label="item.label"
77
77
  @update:model-value="onInteract"
@@ -81,7 +81,7 @@ watch(props.modelValue, () => {
81
81
  v-if="computedOther"
82
82
  v-model="valuesOther"
83
83
  hide-details
84
- :error="isValid === false"
84
+ :error="isValid.value === false"
85
85
  :="$attrs"
86
86
  :label="computedOther.label"
87
87
  @update:model-value="onInteract"
@@ -14,7 +14,6 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VTextField['$props
14
14
  defaultDate?: boolean | string;
15
15
  yearRange?: [number, number];
16
16
  reverseYears?: boolean;
17
- eager?: boolean;
18
17
  }
19
18
  declare function resetDatePicker(): void;
20
19
  declare function toggleMenuOpen(trigger: string): void;
@@ -46,7 +45,6 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
46
45
  flow: () => never[];
47
46
  defaultDate: boolean;
48
47
  reverseYears: boolean;
49
- eager: boolean;
50
48
  }>>, {
51
49
  reset: typeof resetDatePicker;
52
50
  validate: typeof validate;
@@ -61,7 +59,6 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
61
59
  flow: () => never[];
62
60
  defaultDate: boolean;
63
61
  reverseYears: boolean;
64
- eager: boolean;
65
62
  }>>> & Readonly<{
66
63
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
67
64
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -19,8 +19,7 @@ const props = defineProps({
19
19
  rules: { type: null, required: false },
20
20
  defaultDate: { type: [Boolean, String], required: false, default: false },
21
21
  yearRange: { type: Array, required: false },
22
- reverseYears: { type: Boolean, required: false, default: false },
23
- eager: { type: Boolean, required: false, default: false }
22
+ reverseYears: { type: Boolean, required: false, default: false }
24
23
  });
25
24
  const emit = defineEmits(["update:modelValue"]);
26
25
  const computedRules = computed(() => {
@@ -170,10 +169,21 @@ defineExpose({
170
169
  </script>
171
170
 
172
171
  <template>
172
+ <!--
173
+ The picker mounts lazily (no `eager`) and the menu opens with no transition.
174
+ @vuepic/vue-datepicker measures the year/month overlay height and computes its
175
+ scroll-to-active position once, in onMounted. If the picker is pre-mounted in a
176
+ hidden menu (eager) or measured mid open-transition, that measurement reads a
177
+ zero-height grid, so the overlay falls back to the fixed `modeHeight` with the
178
+ cells unpainted and only corrects on a later tick — the #248 "year overlay shows
179
+ a few years then waits a while to finish rendering" symptom. Mounting lazily and
180
+ opening with the content already at full size lets the picker measure correctly
181
+ on first paint. (eager pre-mount was the original #248 fix and reintroduced the bug.)
182
+ -->
173
183
  <v-menu
174
184
  v-model="isMenuOpen"
175
185
  :open-on-click="false"
176
- :eager="props.eager"
186
+ :transition="false"
177
187
  >
178
188
  <template #activator="{ props: activatorProps }">
179
189
  <v-text-field
@@ -14,7 +14,6 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VTextField['$props
14
14
  defaultDate?: boolean | string;
15
15
  yearRange?: [number, number];
16
16
  reverseYears?: boolean;
17
- eager?: boolean;
18
17
  }
19
18
  declare function resetDatePicker(): void;
20
19
  declare function toggleMenuOpen(trigger: string): void;
@@ -46,7 +45,6 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
46
45
  flow: () => never[];
47
46
  defaultDate: boolean;
48
47
  reverseYears: boolean;
49
- eager: boolean;
50
48
  }>>, {
51
49
  reset: typeof resetDatePicker;
52
50
  validate: typeof validate;
@@ -61,7 +59,6 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
61
59
  flow: () => never[];
62
60
  defaultDate: boolean;
63
61
  reverseYears: boolean;
64
- eager: boolean;
65
62
  }>>> & Readonly<{
66
63
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
67
64
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -313,5 +313,5 @@ defineExpose({
313
313
  </template>
314
314
 
315
315
  <style>
316
- .form-data-dirty:not(.v-input--error) :not(.v-chip):not(.v-chip *):not(.v-toolbar):not(.v-toolbar *){color:color-mix(in srgb,currentColor 70%,rgb(var(--v-theme-primary)))!important;text-shadow:0 0 .02em currentColor}
316
+ .form-data-dirty:not(.v-input--error) :not(.v-chip):not(.v-chip *):not(.v-toolbar):not(.v-toolbar *):not(.dp__main):not(.dp__main *){color:color-mix(in srgb,currentColor 70%,rgb(var(--v-theme-primary)))!important;text-shadow:0 0 .02em currentColor}
317
317
  </style>
@@ -25,8 +25,8 @@ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, i
25
25
  size: "large" | "medium";
26
26
  label: string;
27
27
  horizontal: boolean;
28
- truncate: boolean;
29
28
  notFoundText: string;
29
+ truncate: boolean;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
31
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
32
32
  declare const _default: typeof __VLS_export;
@@ -25,8 +25,8 @@ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, i
25
25
  size: "large" | "medium";
26
26
  label: string;
27
27
  horizontal: boolean;
28
- truncate: boolean;
29
28
  notFoundText: string;
29
+ truncate: boolean;
30
30
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
31
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
32
32
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,36 @@
1
+ // Self-contained type template surfaced through `#build/types/api` via
2
+ // `addTypeTemplate` in src/module.ts (mirrors runtime/types/graphqlOperation.d.ts).
3
+ //
4
+ // Why a dedicated template instead of relying on `#imports`:
5
+ // `ApiIdempotencyOption` / `ApiFetchOptions` are **type-only** exports of
6
+ // src/runtime/composables/api.ts. In the playground `#imports` resolves them
7
+ // because unimport scans the TypeScript source, but a consumer installing the
8
+ // built package scans the compiled `.js` where interfaces are erased — so the
9
+ // types never land in the consumer's `#imports` and the codegen-generated
10
+ // `graphqlObject.ts` (`import type { ApiIdempotencyOption } from ...`) fails
11
+ // vue-tsc with TS2305 (see issue #253).
12
+ //
13
+ // This file must stay **self-contained** (no relative imports of ../composables/*)
14
+ // because type templates are copied verbatim into `.nuxt/types/`, where a relative
15
+ // path back into `src/` would not resolve. Keep these declarations in sync with
16
+ // src/runtime/composables/api.ts — that composable remains the runtime source of truth.
17
+ import type { UseFetchOptions } from 'nuxt/app'
18
+
19
+ /**
20
+ * Per-call options accepted by useApi alongside Nuxt's UseFetchOptions.
21
+ *
22
+ * `idempotent: false` skips Idempotency-Key header injection for this single call.
23
+ * Default is `true`. See the useApi() docblock for the full idempotency contract.
24
+ */
25
+ export interface ApiIdempotencyOption {
26
+ idempotent?: boolean
27
+ /**
28
+ * Optional discriminator folded as a trailing component into the
29
+ * Idempotency-Key hash: SHA-256(`<second>|<username>|<body>|<salt>`).
30
+ * Lets legitimately-identical payloads (e.g. duplicate bulk-import rows)
31
+ * resolve to distinct keys without weakening dedup elsewhere.
32
+ */
33
+ idempotencySalt?: string | number
34
+ }
35
+
36
+ export type ApiFetchOptions = UseFetchOptions<unknown> & ApiIdempotencyOption
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramathibodi/nuxt-commons",
3
- "version": "4.0.15",
3
+ "version": "4.0.17",
4
4
  "description": "Ramathibodi Nuxt modules for common components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -104,7 +104,7 @@ module.exports = {
104
104
  return `
105
105
  import * as graphQlClass from "~/types/graphql"
106
106
  import { useGraphQlOperation } from "#imports";
107
- import type { ApiIdempotencyOption } from "#imports";
107
+ import type { ApiIdempotencyOption } from "#build/types/api";
108
108
  import type {
109
109
  graphqlInputObject,
110
110
  graphqlOperationObject,