@nexdom/uimed-vue 2.0.0-beta.32 → 2.0.0-beta.34
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/AGENTS.md
CHANGED
|
@@ -205,7 +205,7 @@ Use an existing composable (e.g. `use-toast`) as the reference, and deliver in t
|
|
|
205
205
|
- Component layout: `src/components/<name>/<name>.vue`, `types.ts` for prop/option types, `__tests__/<name>.test.ts` for unit tests. Components that belong to a group live in the group's folder (e.g. the internal `src/components/dialogs/toast.vue`).
|
|
206
206
|
- Composables live in a group folder: `src/composables/<group>/<name>.ts`, with `types.ts` and `__tests__/` in the group folder (e.g. `src/composables/dialogs/use-toast.ts`). A composable (`use-*.ts`) must depend on `vue` or `vue-router`, directly or through other modules (enforced by dependency-cruiser's `composables-use-vue` rule).
|
|
207
207
|
- Library-wide configuration constants that aren't components or composables live in `src/consts/<name>.ts` (e.g. `src/consts/locale.ts`, the language set by `createUimed()` and `vueTestUtilsPluginUimed()`).
|
|
208
|
-
- Pure helpers that don't use Vue live in `src/utils/<name>.ts`, with tests in `src/utils/__tests__
|
|
208
|
+
- Pure helpers that don't use Vue live in `src/utils/<name>.ts`, with tests in `src/utils/__tests__/`. Generic helpers that any TypeScript project could use (e.g. `isDeepEqual`) belong in `@nexdom/shared` instead.
|
|
209
209
|
- Public components/composables are re-exported from `src/components/index.ts` and `src/composables/index.ts`. Prop types stay internal (`types.ts` is not re-exported); consumers derive them with `ComponentProps` (see [Usage](#usage)).
|
|
210
210
|
- Every publicly exported component must use the `U` prefix on its export identifier (e.g., `UButton`, `UMain`), while internal file names and component names remain unprefixed.
|
|
211
211
|
- Use [JSDoc](https://jsdoc.app/about-getting-started) on every method/prop/type intended to be part of the public API — it's the primary documentation surface and supports markdown/code examples.
|
package/dist/components.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ButtonProps } from "./types-
|
|
1
|
+
import { t as ButtonProps } from "./types-CjaJ2WAC.js";
|
|
2
2
|
import { RouteLocationRaw } from "vue-router";
|
|
3
3
|
//#region src/components/app-bar/types.d.ts
|
|
4
4
|
/**
|
|
@@ -961,7 +961,8 @@ interface SectionAction extends ButtonProps {
|
|
|
961
961
|
*/
|
|
962
962
|
label: string;
|
|
963
963
|
/**
|
|
964
|
-
* Called when the action button is clicked.
|
|
964
|
+
* Called when the action button is clicked. Not called while the action is `disabled` or
|
|
965
|
+
* `loading`.
|
|
965
966
|
*/
|
|
966
967
|
onClick?: (event: MouseEvent) => void;
|
|
967
968
|
}
|
|
@@ -1406,7 +1407,8 @@ interface DialogButtonAction extends ButtonProps {
|
|
|
1406
1407
|
*/
|
|
1407
1408
|
label: string;
|
|
1408
1409
|
/**
|
|
1409
|
-
* Called when the action button is clicked.
|
|
1410
|
+
* Called when the action button is clicked. Not called while the action is `disabled` or
|
|
1411
|
+
* `loading`. The dialog stays open.
|
|
1410
1412
|
*/
|
|
1411
1413
|
onClick?: (event: MouseEvent) => void;
|
|
1412
1414
|
}
|
package/dist/components.js
CHANGED
|
@@ -333,7 +333,11 @@ var app_bar_default = /* @__PURE__ */ defineComponent({
|
|
|
333
333
|
class: "py-2 ml-5 mr-n3",
|
|
334
334
|
cover: ""
|
|
335
335
|
}, null, 8, ["src"])) : createCommentVNode("v-if", true),
|
|
336
|
-
props.title ? (openBlock(), createBlock(unref(VAppBarTitle), {
|
|
336
|
+
props.title ? (openBlock(), createBlock(unref(VAppBarTitle), {
|
|
337
|
+
key: 2,
|
|
338
|
+
role: "heading",
|
|
339
|
+
"aria-level": "1"
|
|
340
|
+
}, {
|
|
337
341
|
default: withCtx(() => [createTextVNode(toDisplayString(props.title), 1)]),
|
|
338
342
|
_: 1
|
|
339
343
|
})) : createCommentVNode("v-if", true)
|
|
@@ -818,12 +822,13 @@ var button_default = /* @__PURE__ */ defineComponent({
|
|
|
818
822
|
const type = useButtonType(() => props.type);
|
|
819
823
|
const form = useButtonForm(() => props.form);
|
|
820
824
|
const widthClass = useFullWidth(() => props.fullWidth);
|
|
825
|
+
const isDisabled = computed(() => props.disabled || props.loading);
|
|
821
826
|
function onClick(event) {
|
|
822
827
|
emit("click", event);
|
|
823
828
|
}
|
|
824
829
|
return (_ctx, _cache) => {
|
|
825
830
|
return openBlock(), createBlock(unref(VBtn), {
|
|
826
|
-
disabled:
|
|
831
|
+
disabled: isDisabled.value,
|
|
827
832
|
loading: props.loading,
|
|
828
833
|
"data-testid": props.dataTestid,
|
|
829
834
|
variant: unref(variant),
|
|
@@ -1080,7 +1085,6 @@ var dialog_host_default = /* @__PURE__ */ defineComponent({
|
|
|
1080
1085
|
show();
|
|
1081
1086
|
}
|
|
1082
1087
|
async function select(current, action) {
|
|
1083
|
-
if (isRunning.value) return;
|
|
1084
1088
|
requests.value.shift();
|
|
1085
1089
|
selected.value = action;
|
|
1086
1090
|
await current.select(action?.value);
|
package/dist/composables.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as FeedbackColorVariant, n as ButtonVariant, r as ColorVariant } from "./types-
|
|
1
|
+
import { i as FeedbackColorVariant, n as ButtonVariant, r as ColorVariant } from "./types-CjaJ2WAC.js";
|
|
2
2
|
import { ComputedRef, MaybeRefOrGetter } from "vue";
|
|
3
3
|
//#region src/composables/dialogs/types.d.ts
|
|
4
4
|
interface ToastOptions {
|
package/dist/composables.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { i as useDialog, o as useToast, t as openDialog } from "./use-dialog-Ck2_ZW7T.js";
|
|
2
2
|
import { computed, onActivated, onDeactivated, onMounted, onUnmounted, ref, toValue, watch } from "vue";
|
|
3
|
+
import { isDeepEqual } from "@nexdom/shared/utils";
|
|
3
4
|
import { onBeforeRouteLeave } from "vue-router";
|
|
4
5
|
//#region src/composables/dialogs/use-run-or-toast.ts
|
|
5
6
|
const { toast } = useToast();
|
|
@@ -115,32 +116,6 @@ function useConfirm() {
|
|
|
115
116
|
};
|
|
116
117
|
}
|
|
117
118
|
//#endregion
|
|
118
|
-
//#region src/utils/is-deep-equal.ts
|
|
119
|
-
/**
|
|
120
|
-
* Compares two values in depth, as a form would: key order doesn't matter, a key holding
|
|
121
|
-
* `undefined` equals a missing key, dates are compared by their time and arrays item by item, in
|
|
122
|
-
* order. Only plain objects are compared by their keys: other objects (e.g. `File`, `Map`, `Set`
|
|
123
|
-
* or class instances) and the remaining values are compared with `Object.is`, so `NaN` equals
|
|
124
|
-
* `NaN`, `0` differs from `-0`, and `null`, `""` and `undefined` differ from each other.
|
|
125
|
-
*/
|
|
126
|
-
function isDeepEqual(a, b) {
|
|
127
|
-
if (Object.is(a, b)) return true;
|
|
128
|
-
if (a instanceof Date && b instanceof Date) return Object.is(a.getTime(), b.getTime());
|
|
129
|
-
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((item, index) => isDeepEqual(item, b[index]));
|
|
130
|
-
if (!isPlainObject(a) || !isPlainObject(b)) return false;
|
|
131
|
-
return [.../* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])].every((key) => isDeepEqual(a[key], b[key]));
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Whether the value is an object literal or an object without prototype. Checks the prototype's
|
|
135
|
-
* prototype instead of comparing it to `Object.prototype`, since objects from other realms (e.g.
|
|
136
|
-
* iframes, or `structuredClone` in some test environments) have their own `Object.prototype`.
|
|
137
|
-
*/
|
|
138
|
-
function isPlainObject(value) {
|
|
139
|
-
if (value == null) return false;
|
|
140
|
-
const prototype = Object.getPrototypeOf(value);
|
|
141
|
-
return prototype === null || Object.getPrototypeOf(prototype) === null;
|
|
142
|
-
}
|
|
143
|
-
//#endregion
|
|
144
119
|
//#region src/composables/navigation/use-unsaved-changes.ts
|
|
145
120
|
/**
|
|
146
121
|
* Calls whose page is on display with unsaved changes. The `beforeunload` listener is registered
|
|
@@ -32,8 +32,11 @@ type ButtonProps = {
|
|
|
32
32
|
*/
|
|
33
33
|
disabled?: boolean;
|
|
34
34
|
/**
|
|
35
|
-
* Displays a loading indicator on the button,
|
|
36
|
-
*
|
|
35
|
+
* Displays a loading indicator on the button and disables it while active, as `disabled` does:
|
|
36
|
+
* it can't be clicked or focused, `click` isn't emitted and its form isn't submitted, including
|
|
37
|
+
* by pressing `Enter` in one of the form's fields when it's the form's first submit button. It
|
|
38
|
+
* looks disabled, with the indicator, and loses focus if focused when loading starts, as any
|
|
39
|
+
* disabled button does. The button keeps its text as accessible name and is marked as busy, and
|
|
37
40
|
* assistive technologies ignore the indicator.
|
|
38
41
|
* @default false
|
|
39
42
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexdom/uimed-vue",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.34",
|
|
4
4
|
"description": "A ui framework for NEXDOM applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lib",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@commitlint/cli": "^21.2.1",
|
|
56
56
|
"@commitlint/config-conventional": "^21.2.0",
|
|
57
57
|
"@mdi/font": "^7.4.47",
|
|
58
|
-
"@nexdom/shared": "^2.
|
|
58
|
+
"@nexdom/shared": "^2.3.0",
|
|
59
59
|
"@playwright/test": "^1.62.1",
|
|
60
60
|
"@sonar/scan": "^5.0.0",
|
|
61
61
|
"@stryker-mutator/core": "^10.0.0",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
},
|
|
88
88
|
"peerDependencies": {
|
|
89
89
|
"@mdi/font": "^7.4.47",
|
|
90
|
-
"@nexdom/shared": "^2.
|
|
90
|
+
"@nexdom/shared": "^2.3.0",
|
|
91
91
|
"resize-observer-polyfill": "^1.5.1",
|
|
92
92
|
"sass-embedded": "^1.103.1",
|
|
93
93
|
"vite-plus": "^1.0.0",
|