vueless 1.2.5-beta.4 → 1.2.5-beta.6
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/index.d.ts +2 -1
- package/index.ts +2 -1
- package/package.json +1 -1
- package/ui.container-accordion/tests/UAccordion.test.ts +5 -5
- package/ui.container-accordion-item/UAccordionItem.vue +5 -8
- package/ui.container-accordion-item/tests/UAccordionItem.test.ts +8 -8
- package/utils/helper.ts +32 -0
- package/utils/theme.ts +53 -78
package/index.d.ts
CHANGED
|
@@ -7,13 +7,14 @@ export {
|
|
|
7
7
|
isSSR,
|
|
8
8
|
isCSR,
|
|
9
9
|
setTitle,
|
|
10
|
+
getStored,
|
|
10
11
|
getRandomId,
|
|
11
12
|
createDebounce,
|
|
12
13
|
hasSlotContent
|
|
13
14
|
} from "./utils/helper";
|
|
14
15
|
export { isMac, isPWA, isIOS, isAndroid, isMobileApp, isWindows } from "./utils/platform";
|
|
15
16
|
export { cx, cva, compose, getDefaults, setVuelessConfig, setColor, vuelessConfig } from "./utils/ui";
|
|
16
|
-
export { getTheme, setTheme, resetTheme, normalizeThemeConfig,
|
|
17
|
+
export { getTheme, setTheme, resetTheme, normalizeThemeConfig, cssVar } from "./utils/theme";
|
|
17
18
|
export { getArgTypes, getSlotNames, getSlotsFragment, getSource, getDocsDescription } from "./utils/storybook";
|
|
18
19
|
/* adapters */
|
|
19
20
|
export { default as defaultEnLocale } from "./adapter.locale/locales/en";
|
package/index.ts
CHANGED
|
@@ -13,13 +13,14 @@ export {
|
|
|
13
13
|
isSSR,
|
|
14
14
|
isCSR,
|
|
15
15
|
setTitle,
|
|
16
|
+
getStored,
|
|
16
17
|
getRandomId,
|
|
17
18
|
createDebounce,
|
|
18
19
|
hasSlotContent
|
|
19
20
|
} from "./utils/helper";
|
|
20
21
|
export { isMac, isPWA, isIOS, isAndroid, isMobileApp, isWindows } from "./utils/platform";
|
|
21
22
|
export { cx, cva, compose, getDefaults, setVuelessConfig, setColor, vuelessConfig } from "./utils/ui";
|
|
22
|
-
export { getTheme, setTheme, resetTheme, normalizeThemeConfig,
|
|
23
|
+
export { getTheme, setTheme, resetTheme, normalizeThemeConfig, cssVar } from "./utils/theme";
|
|
23
24
|
export { getArgTypes, getSlotNames, getSlotsFragment, getSource, getDocsDescription } from "./utils/storybook";
|
|
24
25
|
/* adapters */
|
|
25
26
|
export { default as defaultEnLocale } from "./adapter.locale/locales/en";
|
package/package.json
CHANGED
|
@@ -73,14 +73,14 @@ describe("UAccordion", () => {
|
|
|
73
73
|
|
|
74
74
|
const firstItem = component.findAllComponents(UAccordionItem)[0];
|
|
75
75
|
|
|
76
|
-
await firstItem.trigger("click");
|
|
76
|
+
await firstItem.find("[vl-child-key='title']").trigger("click");
|
|
77
77
|
|
|
78
78
|
const updates = component.emitted("update:modelValue");
|
|
79
79
|
|
|
80
80
|
expect(updates).toBeTruthy();
|
|
81
81
|
expect(updates?.[0]).toEqual(["a"]);
|
|
82
82
|
|
|
83
|
-
await firstItem.trigger("click");
|
|
83
|
+
await firstItem.find("[vl-child-key='title']").trigger("click");
|
|
84
84
|
const updates2 = component.emitted("update:modelValue");
|
|
85
85
|
|
|
86
86
|
expect(updates2?.[1]).toEqual([null]);
|
|
@@ -103,14 +103,14 @@ describe("UAccordion", () => {
|
|
|
103
103
|
|
|
104
104
|
const [firstItem, secondItem] = component.findAllComponents(UAccordionItem);
|
|
105
105
|
|
|
106
|
-
await firstItem.trigger("click");
|
|
107
|
-
await secondItem.trigger("click");
|
|
106
|
+
await firstItem.find("[vl-child-key='title']").trigger("click");
|
|
107
|
+
await secondItem.find("[vl-child-key='title']").trigger("click");
|
|
108
108
|
const updates = component.emitted("update:modelValue");
|
|
109
109
|
|
|
110
110
|
expect(updates?.[0]).toEqual([["a"]]);
|
|
111
111
|
expect(updates?.[1]).toEqual([["a", "b"]]);
|
|
112
112
|
|
|
113
|
-
await firstItem.trigger("click");
|
|
113
|
+
await firstItem.find("[vl-child-key='title']").trigger("click");
|
|
114
114
|
const updates2 = component.emitted("update:modelValue");
|
|
115
115
|
|
|
116
116
|
expect(updates2?.[2]).toEqual([["b"]]);
|
|
@@ -42,8 +42,7 @@ const emit = defineEmits([
|
|
|
42
42
|
]);
|
|
43
43
|
|
|
44
44
|
const wrapperRef = useTemplateRef<HTMLDivElement>("wrapper");
|
|
45
|
-
const
|
|
46
|
-
const contentRef = useTemplateRef<HTMLDivElement>("content");
|
|
45
|
+
const titleRef = useTemplateRef<HTMLDivElement>("title");
|
|
47
46
|
|
|
48
47
|
const accordionSize = ref(toValue(getAccordionSize) || props.size);
|
|
49
48
|
const accordionDisabled = ref(toValue(getAccordionDisabled) || props.disabled);
|
|
@@ -79,10 +78,9 @@ const toggleIconName = computed(() => {
|
|
|
79
78
|
});
|
|
80
79
|
|
|
81
80
|
function onClickItem(event: MouseEvent) {
|
|
82
|
-
const
|
|
83
|
-
const clickedDescription = descriptionRef.value?.contains(event.target as Node);
|
|
81
|
+
const clickedOnTitle = titleRef.value?.contains(event.target as Node);
|
|
84
82
|
|
|
85
|
-
if (props.disabled
|
|
83
|
+
if (!clickedOnTitle || props.disabled) return;
|
|
86
84
|
|
|
87
85
|
emit("click", elementId, !isOpened.value);
|
|
88
86
|
|
|
@@ -123,7 +121,7 @@ const {
|
|
|
123
121
|
<template>
|
|
124
122
|
<div ref="wrapper" v-bind="wrapperAttrs" :data-test="getDataTest()" @click="onClickItem">
|
|
125
123
|
<div v-bind="bodyAttrs">
|
|
126
|
-
<div v-bind="titleAttrs">
|
|
124
|
+
<div v-bind="titleAttrs" ref="title">
|
|
127
125
|
{{ title }}
|
|
128
126
|
<!--
|
|
129
127
|
@slot Use it to add something instead of the toggle icon.
|
|
@@ -144,12 +142,11 @@ const {
|
|
|
144
142
|
<div
|
|
145
143
|
v-if="description"
|
|
146
144
|
:id="`description-${elementId}`"
|
|
147
|
-
ref="description"
|
|
148
145
|
v-bind="descriptionAttrs"
|
|
149
146
|
v-text="description"
|
|
150
147
|
/>
|
|
151
148
|
|
|
152
|
-
<div v-if="isOpened && hasSlotContent(slots['default'])"
|
|
149
|
+
<div v-if="isOpened && hasSlotContent(slots['default'])" v-bind="contentAttrs">
|
|
153
150
|
<!-- @slot Use it to add accordion content. -->
|
|
154
151
|
<slot />
|
|
155
152
|
</div>
|
|
@@ -171,7 +171,7 @@ describe("UAccordionItem", () => {
|
|
|
171
171
|
expect(toggleElement.attributes("data-opened")).toBe("false");
|
|
172
172
|
|
|
173
173
|
// Click to toggle
|
|
174
|
-
await component.trigger("click");
|
|
174
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
175
175
|
|
|
176
176
|
expect(toggleElement.attributes("data-opened")).toBe("true");
|
|
177
177
|
});
|
|
@@ -190,12 +190,12 @@ describe("UAccordionItem", () => {
|
|
|
190
190
|
|
|
191
191
|
expect(component.find(`.${slotClass}`).exists()).toBe(false);
|
|
192
192
|
|
|
193
|
-
await component.trigger("click");
|
|
193
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
194
194
|
|
|
195
195
|
expect(component.find(`.${slotClass}`).exists()).toBe(true);
|
|
196
196
|
expect(component.find(`.${slotClass}`).text()).toBe(slotContent);
|
|
197
197
|
|
|
198
|
-
await component.trigger("click");
|
|
198
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
199
199
|
|
|
200
200
|
expect(component.find(`.${slotClass}`).exists()).toBe(false);
|
|
201
201
|
});
|
|
@@ -217,7 +217,7 @@ describe("UAccordionItem", () => {
|
|
|
217
217
|
it("does not render content wrapper when default slot is empty", async () => {
|
|
218
218
|
const component = mount(UAccordionItem, { props: { name: "test" } });
|
|
219
219
|
|
|
220
|
-
await component.trigger("click");
|
|
220
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
221
221
|
|
|
222
222
|
expect(component.find("[vl-key='content']").exists()).toBe(false);
|
|
223
223
|
});
|
|
@@ -235,7 +235,7 @@ describe("UAccordionItem", () => {
|
|
|
235
235
|
},
|
|
236
236
|
});
|
|
237
237
|
|
|
238
|
-
await component.trigger("click");
|
|
238
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
239
239
|
|
|
240
240
|
const emitted = component.emitted("click");
|
|
241
241
|
|
|
@@ -243,7 +243,7 @@ describe("UAccordionItem", () => {
|
|
|
243
243
|
expect(emitted?.[0]).toEqual([id, true]);
|
|
244
244
|
|
|
245
245
|
// Click again to toggle back
|
|
246
|
-
await component.trigger("click");
|
|
246
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
247
247
|
|
|
248
248
|
const emittedAgain = component.emitted("click");
|
|
249
249
|
|
|
@@ -281,13 +281,13 @@ describe("UAccordionItem", () => {
|
|
|
281
281
|
expect(descriptionElement.classes()).not.toContain(openedClass);
|
|
282
282
|
|
|
283
283
|
// Click to open
|
|
284
|
-
await component.trigger("click");
|
|
284
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
285
285
|
|
|
286
286
|
// Should be opened
|
|
287
287
|
expect(descriptionElement.classes()).toContain(openedClass);
|
|
288
288
|
|
|
289
289
|
// Click to close
|
|
290
|
-
await component.trigger("click");
|
|
290
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
291
291
|
|
|
292
292
|
// Should be closed again
|
|
293
293
|
expect(descriptionElement.classes()).not.toContain(openedClass);
|
package/utils/helper.ts
CHANGED
|
@@ -184,3 +184,35 @@ export function isEmptyValue(value: object | null | undefined | string | unknown
|
|
|
184
184
|
(typeof value === "object" && !Object.keys(value).length)
|
|
185
185
|
);
|
|
186
186
|
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Converts the given value to a number if possible.
|
|
190
|
+
*
|
|
191
|
+
* @param {unknown} value - The value to be converted to a number. Can be of any data type.
|
|
192
|
+
* @return {number | undefined} The numeric representation of the value if conversion is successful; otherwise, undefined.
|
|
193
|
+
*/
|
|
194
|
+
export function toNumber(value: unknown): number | undefined {
|
|
195
|
+
if (typeof value === "number") {
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
200
|
+
const number = Number(value);
|
|
201
|
+
|
|
202
|
+
if (!Number.isNaN(number)) {
|
|
203
|
+
return number;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get a stored value from local storage.
|
|
212
|
+
* @return string | undefined
|
|
213
|
+
*/
|
|
214
|
+
export function getStored(key: string) {
|
|
215
|
+
if (isSSR) return;
|
|
216
|
+
|
|
217
|
+
return localStorage.getItem(key) ?? undefined;
|
|
218
|
+
}
|
package/utils/theme.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { cloneDeep, merge } from "lodash-es";
|
|
2
2
|
|
|
3
3
|
import { vuelessConfig } from "./ui";
|
|
4
|
-
import { isCSR,
|
|
4
|
+
import { isCSR, getStored, getCookie, setCookie, deleteCookie, toNumber } from "./helper";
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
PX_IN_REM,
|
|
8
|
+
AUTO_MODE_KEY,
|
|
8
9
|
COLOR_MODE_KEY,
|
|
9
10
|
LIGHT_MODE_CLASS,
|
|
10
11
|
DARK_MODE_CLASS,
|
|
@@ -34,7 +35,6 @@ import {
|
|
|
34
35
|
DEFAULT_DISABLED_OPACITY,
|
|
35
36
|
LETTER_SPACING,
|
|
36
37
|
DEFAULT_LETTER_SPACING,
|
|
37
|
-
AUTO_MODE_KEY,
|
|
38
38
|
} from "../constants";
|
|
39
39
|
|
|
40
40
|
import type {
|
|
@@ -75,7 +75,7 @@ function toggleColorModeClass() {
|
|
|
75
75
|
const colorMode = prefersColorSchemeDark.matches ? ColorMode.Dark : ColorMode.Light;
|
|
76
76
|
|
|
77
77
|
setCookie(COLOR_MODE_KEY, colorMode);
|
|
78
|
-
|
|
78
|
+
setCookie(AUTO_MODE_KEY, String(Number(true)));
|
|
79
79
|
|
|
80
80
|
document.documentElement.classList.toggle(DARK_MODE_CLASS, prefersColorSchemeDark.matches);
|
|
81
81
|
document.documentElement.classList.toggle(LIGHT_MODE_CLASS, !prefersColorSchemeDark.matches);
|
|
@@ -92,8 +92,8 @@ function toggleColorModeClass() {
|
|
|
92
92
|
* - `isColorModeAuto` {boolean}: Indicates whether the color mode is set to auto.
|
|
93
93
|
*/
|
|
94
94
|
function setCSRColorMode(mode: `${ColorMode}`): SetColorMode {
|
|
95
|
-
const colorMode = mode ||
|
|
96
|
-
const isCachedAutoMode = !!Number(
|
|
95
|
+
const colorMode = mode || getCookie(COLOR_MODE_KEY) || vuelessConfig.colorMode || ColorMode.Light;
|
|
96
|
+
const isCachedAutoMode = !!Number(getCookie(AUTO_MODE_KEY) ?? 0);
|
|
97
97
|
|
|
98
98
|
const isAutoMode = colorMode === ColorMode.Auto;
|
|
99
99
|
const isSystemDarkMode = isAutoMode && prefersColorSchemeDark && prefersColorSchemeDark?.matches;
|
|
@@ -123,12 +123,14 @@ function setCSRColorMode(mode: `${ColorMode}`): SetColorMode {
|
|
|
123
123
|
currentColorMode = isDarkMode ? ColorMode.Dark : ColorMode.Light;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
/* Define color mode cookies to be used in both CSR and SSR */
|
|
127
|
+
if (mode || getCookie(AUTO_MODE_KEY) === null) {
|
|
127
128
|
setCookie(COLOR_MODE_KEY, currentColorMode);
|
|
128
129
|
setCookie(AUTO_MODE_KEY, String(Number(isAutoMode)));
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
if (mode !== ColorMode.Auto && prefersColorSchemeDark) {
|
|
132
|
+
prefersColorSchemeDark.removeEventListener("change", toggleColorModeClass);
|
|
133
|
+
}
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
return {
|
|
@@ -164,16 +166,6 @@ export function cssVar(name: string) {
|
|
|
164
166
|
return (isCSR && getComputedStyle(document.documentElement).getPropertyValue(name)) || undefined;
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
/**
|
|
168
|
-
* Get a stored value from local storage.
|
|
169
|
-
* @return string | undefined
|
|
170
|
-
*/
|
|
171
|
-
export function getStored(key: string) {
|
|
172
|
-
if (isSSR) return;
|
|
173
|
-
|
|
174
|
-
return localStorage.getItem(key) ?? undefined;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
169
|
/**
|
|
178
170
|
* Resets all theme data by clearing cookies and localStorage.
|
|
179
171
|
* This removes all stored theme preferences including color mode, colors, text sizes,
|
|
@@ -207,40 +199,6 @@ export function resetTheme() {
|
|
|
207
199
|
});
|
|
208
200
|
}
|
|
209
201
|
|
|
210
|
-
/**
|
|
211
|
-
* Normalizes the provided theme configuration object into a structured format.
|
|
212
|
-
*
|
|
213
|
-
* @param {object} theme - The theme configuration object to normalize.
|
|
214
|
-
* @return {MergedThemeConfig}
|
|
215
|
-
*/
|
|
216
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
217
|
-
export function normalizeThemeConfig(theme: any): MergedThemeConfig {
|
|
218
|
-
return {
|
|
219
|
-
colorMode: theme.colorMode,
|
|
220
|
-
isColorModeAuto: theme.isColorModeAuto,
|
|
221
|
-
primary: theme.primary,
|
|
222
|
-
neutral: theme.neutral,
|
|
223
|
-
text: {
|
|
224
|
-
xs: toNumber(theme.text?.xs),
|
|
225
|
-
sm: toNumber(theme.text?.sm),
|
|
226
|
-
md: toNumber(theme.text?.md),
|
|
227
|
-
lg: toNumber(theme.text?.lg),
|
|
228
|
-
},
|
|
229
|
-
outline: {
|
|
230
|
-
sm: toNumber(theme.outline?.sm),
|
|
231
|
-
md: toNumber(theme.outline?.md),
|
|
232
|
-
lg: toNumber(theme.outline?.lg),
|
|
233
|
-
},
|
|
234
|
-
rounding: {
|
|
235
|
-
sm: toNumber(theme.rounding?.sm),
|
|
236
|
-
md: toNumber(theme.rounding?.md),
|
|
237
|
-
lg: toNumber(theme.rounding?.lg),
|
|
238
|
-
},
|
|
239
|
-
letterSpacing: toNumber(theme.letterSpacing),
|
|
240
|
-
disabledOpacity: toNumber(theme.disabledOpacity),
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
|
|
244
202
|
/**
|
|
245
203
|
* Retrieves the current theme configuration.
|
|
246
204
|
* @return ThemeConfig - current theme configuration
|
|
@@ -363,6 +321,45 @@ export function setTheme(config: ThemeConfig = {}) {
|
|
|
363
321
|
});
|
|
364
322
|
}
|
|
365
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Normalizes the provided theme configuration object into a structured format.
|
|
326
|
+
*
|
|
327
|
+
* @param {object} theme - The theme configuration object to normalize.
|
|
328
|
+
* @return {MergedThemeConfig}
|
|
329
|
+
*/
|
|
330
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
331
|
+
export function normalizeThemeConfig(theme: any): MergedThemeConfig {
|
|
332
|
+
return {
|
|
333
|
+
colorMode: theme.colorMode,
|
|
334
|
+
isColorModeAuto: theme.isColorModeAuto,
|
|
335
|
+
primary: theme.primary,
|
|
336
|
+
neutral: theme.neutral,
|
|
337
|
+
text: {
|
|
338
|
+
xs: toNumber(theme.text?.xs),
|
|
339
|
+
sm: toNumber(theme.text?.sm),
|
|
340
|
+
md: toNumber(theme.text?.md),
|
|
341
|
+
lg: toNumber(theme.text?.lg),
|
|
342
|
+
},
|
|
343
|
+
outline: {
|
|
344
|
+
sm: toNumber(theme.outline?.sm),
|
|
345
|
+
md: toNumber(theme.outline?.md),
|
|
346
|
+
lg: toNumber(theme.outline?.lg),
|
|
347
|
+
},
|
|
348
|
+
rounding: {
|
|
349
|
+
sm: toNumber(theme.rounding?.sm),
|
|
350
|
+
md: toNumber(theme.rounding?.md),
|
|
351
|
+
lg: toNumber(theme.rounding?.lg),
|
|
352
|
+
},
|
|
353
|
+
letterSpacing: toNumber(theme.letterSpacing),
|
|
354
|
+
disabledOpacity: toNumber(theme.disabledOpacity),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Determines if the provided color mode configuration has a primary color
|
|
360
|
+
* that differs from the default color mode configuration.
|
|
361
|
+
* @return {boolean}
|
|
362
|
+
*/
|
|
366
363
|
function hasPrimaryColor(
|
|
367
364
|
colorModeConfig: Partial<VuelessCssVariables> | undefined,
|
|
368
365
|
defaultColorModeConfig: Partial<VuelessCssVariables>,
|
|
@@ -639,14 +636,6 @@ function getDisabledOpacity(disabledOpacity?: ThemeConfig["disabledOpacity"]) {
|
|
|
639
636
|
return mergedOpacity;
|
|
640
637
|
}
|
|
641
638
|
|
|
642
|
-
/**
|
|
643
|
-
* Converts a primitive value into an object with the primitive value assigned to a key "md".
|
|
644
|
-
* If the provided value is already an object, it returns a deeply cloned copy of that object.
|
|
645
|
-
*/
|
|
646
|
-
function primitiveToObject(value: unknown): object {
|
|
647
|
-
return typeof value === "object" ? cloneDeep(value as object) : { md: value };
|
|
648
|
-
}
|
|
649
|
-
|
|
650
639
|
/**
|
|
651
640
|
* Generate and apply Vueless CSS variables.
|
|
652
641
|
* @return string - Vueless CSS variables string.
|
|
@@ -745,23 +734,9 @@ function setCSSVariables(
|
|
|
745
734
|
}
|
|
746
735
|
|
|
747
736
|
/**
|
|
748
|
-
* Converts the
|
|
749
|
-
*
|
|
750
|
-
* @param {unknown} value - The value to be converted to a number. Can be of any data type.
|
|
751
|
-
* @return {number | undefined} The numeric representation of the value if conversion is successful; otherwise, undefined.
|
|
737
|
+
* Converts a primitive value into an object with the primitive value assigned to a key "md".
|
|
738
|
+
* If the provided value is already an object, it returns a deeply cloned copy of that object.
|
|
752
739
|
*/
|
|
753
|
-
function
|
|
754
|
-
|
|
755
|
-
return value;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
if (typeof value === "string" && value.trim() !== "") {
|
|
759
|
-
const number = Number(value);
|
|
760
|
-
|
|
761
|
-
if (!Number.isNaN(number)) {
|
|
762
|
-
return number;
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
return;
|
|
740
|
+
function primitiveToObject(value: unknown): object {
|
|
741
|
+
return typeof value === "object" ? cloneDeep(value as object) : { md: value };
|
|
767
742
|
}
|