vueless 0.0.478-beta.3 → 0.0.479
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/composables/useBreakpoint.js +1 -1
- package/composables/useUI.js +1 -204
- package/constants.js +1 -2
- package/directives/clickOutside/vClickOutside.js +2 -2
- package/directives/tooltip/storybook/stories.js +5 -5
- package/{index.ts → index.js} +7 -10
- package/package.json +18 -28
- package/preset.tailwind.js +7 -16
- package/ui.button/config.js +0 -12
- package/ui.button/storybook/stories.js +2 -2
- package/ui.button-link/ULink.vue +1 -1
- package/ui.button-link/config.js +0 -9
- package/ui.button-link/storybook/stories.js +1 -1
- package/ui.button-toggle/storybook/stories.js +1 -1
- package/ui.container-divider/storybook/stories.js +1 -1
- package/ui.container-modal/storybook/stories.js +1 -1
- package/ui.container-modal-confirm/storybook/stories.js +1 -1
- package/ui.container-row/storybook/stories.js +1 -1
- package/ui.data-list/UDataList.vue +4 -4
- package/ui.data-table/UTable.vue +1 -1
- package/ui.dropdown-badge/config.js +0 -1
- package/ui.dropdown-badge/storybook/stories.js +1 -1
- package/ui.dropdown-button/config.js +0 -1
- package/ui.dropdown-button/storybook/stories.js +2 -2
- package/ui.dropdown-link/storybook/stories.js +1 -1
- package/ui.dropdown-list/storybook/stories.js +1 -1
- package/ui.form-checkbox/config.js +0 -9
- package/ui.form-checkbox/storybook/stories.js +1 -1
- package/ui.form-checkbox-group/storybook/stories.js +1 -1
- package/ui.form-checkbox-multi-state/storybook/stories.js +1 -1
- package/ui.form-color-picker/config.js +0 -7
- package/ui.form-color-picker/storybook/stories.js +1 -1
- package/ui.form-date-picker/storybook/stories.js +2 -2
- package/ui.form-date-picker-range/storybook/stories.js +1 -1
- package/ui.form-input/UInput.vue +1 -1
- package/ui.form-input/storybook/stories.js +1 -1
- package/ui.form-input-file/storybook/stories.js +1 -1
- package/ui.form-input-money/storybook/stories.js +1 -1
- package/ui.form-input-money/useFormatCurrency.js +1 -1
- package/ui.form-input-number/UInputNumber.vue +3 -4
- package/ui.form-input-number/storybook/stories.js +1 -1
- package/ui.form-input-rating/storybook/stories.js +1 -1
- package/ui.form-input-search/storybook/stories.js +1 -1
- package/ui.form-label/config.js +2 -2
- package/ui.form-label/storybook/stories.js +1 -1
- package/ui.form-radio/config.js +0 -6
- package/ui.form-radio-group/storybook/stories.js +1 -1
- package/ui.form-select/storybook/stories.js +1 -1
- package/ui.form-switch/config.js +0 -6
- package/ui.form-switch/storybook/stories.js +1 -1
- package/ui.form-textarea/storybook/stories.js +1 -1
- package/ui.image-avatar/config.js +0 -5
- package/ui.image-avatar/storybook/stories.js +1 -1
- package/ui.image-icon/UIcon.vue +14 -5
- package/ui.image-icon/config.js +0 -5
- package/ui.image-icon/storybook/stories.js +1 -1
- package/ui.loader/config.js +0 -1
- package/ui.loader/storybook/stories.js +1 -1
- package/ui.loader-overlay/config.js +0 -1
- package/ui.loader-progress/config.js +0 -1
- package/ui.loader-progress/storybook/stories.js +1 -1
- package/ui.navigation-progress/config.js +0 -9
- package/ui.navigation-progress/storybook/stories.js +1 -1
- package/ui.navigation-tabs/storybook/stories.js +1 -1
- package/ui.other-dot/config.js +0 -1
- package/ui.other-dot/storybook/stories.js +1 -1
- package/ui.text-alert/config.js +0 -7
- package/ui.text-alert/storybook/stories.js +1 -1
- package/ui.text-badge/config.js +0 -8
- package/ui.text-badge/storybook/stories.js +2 -10
- package/ui.text-block/UText.vue +62 -18
- package/ui.text-block/storybook/Docs.mdx +3 -3
- package/ui.text-block/storybook/{stories.ts → stories.js} +8 -13
- package/ui.text-block/useAttrs.js +15 -0
- package/ui.text-empty/storybook/stories.js +1 -1
- package/ui.text-file/UFile.vue +15 -12
- package/ui.text-file/config.js +2 -12
- package/ui.text-files/config.js +1 -1
- package/ui.text-header/config.js +0 -1
- package/ui.text-header/storybook/stories.js +1 -1
- package/ui.text-money/config.js +0 -1
- package/ui.text-money/storybook/stories.js +1 -1
- package/ui.text-money/utilMoney.js +2 -2
- package/{utilsTs/utilTheme.ts → utils/utilTheme.js} +27 -31
- package/utils/utilUI.js +205 -1
- package/web-types.json +9580 -0
- package/composablesTs/useAutoPosition.ts +0 -115
- package/composablesTs/useBreakpoint.ts +0 -106
- package/composablesTs/useLocale.ts +0 -25
- package/composablesTs/useMutationObserver.ts +0 -50
- package/composablesTs/useUI.ts +0 -557
- package/constants.ts +0 -73
- package/types.ts +0 -223
- package/ui.text-block/types.ts +0 -33
- package/ui.text-block/useAttrs.ts +0 -20
- package/utilsTs/utilHelper.ts +0 -68
- package/utilsTs/utilPlatform.ts +0 -53
- package/utilsTs/utilStorybook.ts +0 -296
- package/utilsTs/utilTailwind.ts +0 -38
- package/utilsTs/utilUI.ts +0 -143
- /package/ui.text-block/{config.ts → config.js} +0 -0
- /package/ui.text-block/{constants.ts → constants.js} +0 -0
package/ui.text-block/UText.vue
CHANGED
|
@@ -1,27 +1,71 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<div v-bind="wrapperAttrs" :data-test="dataTest">
|
|
3
|
+
<!-- @slot Use it to add something inside. -->
|
|
4
|
+
<div v-if="!hasSlotContent($slots['default'])" v-bind="htmlAttrs" v-html="html" />
|
|
5
|
+
<slot />
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import useAttrs from "./useAttrs.ts";
|
|
9
|
+
<script setup>
|
|
10
|
+
import { getDefault } from "../utils/utilUI.js";
|
|
7
11
|
|
|
8
|
-
import
|
|
12
|
+
import { UText } from "./constants.js";
|
|
13
|
+
import defaultConfig from "./config.js";
|
|
14
|
+
import useAttrs from "./useAttrs.js";
|
|
9
15
|
|
|
10
16
|
defineOptions({ inheritAttrs: false });
|
|
11
17
|
|
|
12
|
-
const props =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
const props = defineProps({
|
|
19
|
+
/**
|
|
20
|
+
* НTML markdown or plain text.
|
|
21
|
+
*/
|
|
22
|
+
html: {
|
|
23
|
+
type: String,
|
|
24
|
+
default: undefined,
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Text size.
|
|
29
|
+
* @values sm, md, lg
|
|
30
|
+
*/
|
|
31
|
+
size: {
|
|
32
|
+
type: String,
|
|
33
|
+
default: getDefault(defaultConfig, UText).size,
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Text align.
|
|
38
|
+
* @values left, center, right
|
|
39
|
+
*/
|
|
40
|
+
align: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: getDefault(defaultConfig, UText).align,
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Remove line height (useful for 1-line text).
|
|
47
|
+
*/
|
|
48
|
+
line: {
|
|
49
|
+
type: Boolean,
|
|
50
|
+
default: getDefault(defaultConfig, UText).line,
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Component config object.
|
|
55
|
+
*/
|
|
56
|
+
config: {
|
|
57
|
+
type: Object,
|
|
58
|
+
default: () => ({}),
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Data-test attribute for automated testing.
|
|
63
|
+
*/
|
|
64
|
+
dataTest: {
|
|
65
|
+
type: String,
|
|
66
|
+
default: "",
|
|
67
|
+
},
|
|
16
68
|
});
|
|
17
69
|
|
|
18
70
|
const { wrapperAttrs, htmlAttrs, hasSlotContent } = useAttrs(props);
|
|
19
71
|
</script>
|
|
20
|
-
|
|
21
|
-
<template>
|
|
22
|
-
<div v-bind="wrapperAttrs" :data-test="dataTest">
|
|
23
|
-
<!-- @slot Use it to add something inside. -->
|
|
24
|
-
<div v-if="!hasSlotContent($slots['default'])" v-bind="htmlAttrs" v-html="html" />
|
|
25
|
-
<slot />
|
|
26
|
-
</div>
|
|
27
|
-
</template>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
|
|
2
|
-
import { getSource } from "../../
|
|
2
|
+
import { getSource } from "../../utils/utilStorybook.js";
|
|
3
3
|
|
|
4
|
-
import * as stories from "./stories.
|
|
5
|
-
import defaultConfig from "../config.
|
|
4
|
+
import * as stories from "./stories.js";
|
|
5
|
+
import defaultConfig from "../config.js?raw"
|
|
6
6
|
|
|
7
7
|
<Meta of={stories} />
|
|
8
8
|
<Title of={stories} />
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { getArgTypes, getSlotNames, getSlotsFragment } from "../../utilsTs/utilStorybook.ts";
|
|
1
|
+
import { getArgTypes, getSlotNames, getSlotsFragment } from "../../utils/utilStorybook.js";
|
|
3
2
|
|
|
4
3
|
import UText from "../../ui.text-block/UText.vue";
|
|
5
4
|
import URow from "../../ui.container-row/URow.vue";
|
|
6
5
|
|
|
7
|
-
import type { UTextProps } from "../types.ts";
|
|
8
|
-
|
|
9
|
-
interface UTextArgs extends UTextProps {
|
|
10
|
-
slotTemplate?: string;
|
|
11
|
-
enum: "size";
|
|
12
|
-
}
|
|
13
|
-
|
|
14
6
|
/**
|
|
15
7
|
* The `UText` component. | [View on GitHub](https://github.com/vuelessjs/vueless/tree/main/src/ui.text-block)
|
|
16
8
|
*/
|
|
@@ -22,7 +14,7 @@ export default {
|
|
|
22
14
|
...getArgTypes(UText.__name),
|
|
23
15
|
},
|
|
24
16
|
args: {},
|
|
25
|
-
}
|
|
17
|
+
};
|
|
26
18
|
|
|
27
19
|
const defaultTemplate = `
|
|
28
20
|
<p>
|
|
@@ -32,7 +24,7 @@ const defaultTemplate = `
|
|
|
32
24
|
</p>
|
|
33
25
|
`;
|
|
34
26
|
|
|
35
|
-
const DefaultTemplate
|
|
27
|
+
const DefaultTemplate = (args) => ({
|
|
36
28
|
components: { UText, URow },
|
|
37
29
|
setup() {
|
|
38
30
|
const slots = getSlotNames(UText.__name);
|
|
@@ -46,12 +38,12 @@ const DefaultTemplate: StoryFn<UTextArgs> = (args: UTextArgs) => ({
|
|
|
46
38
|
`,
|
|
47
39
|
});
|
|
48
40
|
|
|
49
|
-
const EnumVariantTemplate
|
|
41
|
+
const EnumVariantTemplate = (args, { argTypes } = {}) => ({
|
|
50
42
|
components: { UText, URow },
|
|
51
43
|
setup() {
|
|
52
44
|
return {
|
|
53
45
|
args,
|
|
54
|
-
options: argTypes
|
|
46
|
+
options: argTypes[args.enum].options,
|
|
55
47
|
};
|
|
56
48
|
},
|
|
57
49
|
template: `
|
|
@@ -96,6 +88,7 @@ Paragraphs.args = {
|
|
|
96
88
|
rapidly changing landscape and emerge stronger and more competitive.
|
|
97
89
|
</p>
|
|
98
90
|
</template>
|
|
91
|
+
|
|
99
92
|
`,
|
|
100
93
|
};
|
|
101
94
|
|
|
@@ -109,6 +102,8 @@ List.args = {
|
|
|
109
102
|
<li>Update your profile information</li>
|
|
110
103
|
<li>Check your email for updates</li>
|
|
111
104
|
</ul>
|
|
105
|
+
|
|
106
|
+
|
|
112
107
|
<ol>
|
|
113
108
|
<li>Create an account by signing up</li>
|
|
114
109
|
<li>Verify your email address</li>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import useUI from "../composables/useUI.js";
|
|
2
|
+
|
|
3
|
+
import defaultConfig from "./config.js";
|
|
4
|
+
|
|
5
|
+
export default function useAttrs(props) {
|
|
6
|
+
const { config, getKeysAttrs, hasSlotContent } = useUI(defaultConfig, () => props.config);
|
|
7
|
+
|
|
8
|
+
const keysAttrs = getKeysAttrs();
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
config,
|
|
12
|
+
...keysAttrs,
|
|
13
|
+
hasSlotContent,
|
|
14
|
+
};
|
|
15
|
+
}
|
package/ui.text-file/UFile.vue
CHANGED
|
@@ -23,14 +23,16 @@
|
|
|
23
23
|
</slot>
|
|
24
24
|
|
|
25
25
|
<slot name="right" :file="{ elementId, label, url, imageUrl }">
|
|
26
|
-
<
|
|
26
|
+
<UButton
|
|
27
27
|
v-if="removable"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
round
|
|
29
|
+
filled
|
|
30
|
+
square
|
|
31
|
+
no-ring
|
|
32
|
+
variant="thirdary"
|
|
33
|
+
:size="removeButtonSize"
|
|
34
|
+
:icon="config.defaults.removeIcon"
|
|
35
|
+
v-bind="removeButtonAttrs"
|
|
34
36
|
:data-test="`${dataTest}-remove-item`"
|
|
35
37
|
@click.stop.prevent="onRemove"
|
|
36
38
|
/>
|
|
@@ -43,6 +45,7 @@ import { computed, ref, useId } from "vue";
|
|
|
43
45
|
|
|
44
46
|
import ULink from "../ui.button-link/ULink.vue";
|
|
45
47
|
import UIcon from "../ui.image-icon/UIcon.vue";
|
|
48
|
+
import UButton from "../ui.button/UButton.vue";
|
|
46
49
|
|
|
47
50
|
import { getDefault } from "../utils/utilUI.js";
|
|
48
51
|
|
|
@@ -138,20 +141,20 @@ const {
|
|
|
138
141
|
fileIconAttrs,
|
|
139
142
|
fileLabelAttrs,
|
|
140
143
|
fileImageAttrs,
|
|
141
|
-
|
|
144
|
+
removeButtonAttrs,
|
|
142
145
|
} = useAttrs(props);
|
|
143
146
|
|
|
144
147
|
const iconSize = computed(() => {
|
|
145
148
|
const sizes = {
|
|
146
|
-
sm: "
|
|
147
|
-
md: "
|
|
148
|
-
lg: "
|
|
149
|
+
sm: "2xs",
|
|
150
|
+
md: "xs",
|
|
151
|
+
lg: "sm",
|
|
149
152
|
};
|
|
150
153
|
|
|
151
154
|
return sizes[props.size];
|
|
152
155
|
});
|
|
153
156
|
|
|
154
|
-
const
|
|
157
|
+
const removeButtonSize = computed(() => {
|
|
155
158
|
const sizes = {
|
|
156
159
|
sm: "2xs",
|
|
157
160
|
md: "xs",
|
package/ui.text-file/config.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
export default /*tw*/ {
|
|
2
|
-
file: {
|
|
3
|
-
component: "{ULink}",
|
|
4
|
-
base: "flex items-center",
|
|
5
|
-
variants: {
|
|
6
|
-
size: {
|
|
7
|
-
sm: "gap-0.5",
|
|
8
|
-
md: "gap-1",
|
|
9
|
-
lg: "gap-1.5",
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
},
|
|
2
|
+
file: "{ULink}",
|
|
13
3
|
body: {
|
|
14
4
|
base: "flex items-center",
|
|
15
5
|
variants: {
|
|
@@ -23,7 +13,7 @@ export default /*tw*/ {
|
|
|
23
13
|
fileImage: "rounded-sm max-w-7",
|
|
24
14
|
fileIcon: "{UIcon}",
|
|
25
15
|
fileLabel: "{ULink}",
|
|
26
|
-
|
|
16
|
+
removeButton: "{UButton} ml-2",
|
|
27
17
|
defaults: {
|
|
28
18
|
size: "md",
|
|
29
19
|
/* icons */
|
package/ui.text-files/config.js
CHANGED
package/ui.text-header/config.js
CHANGED
package/ui.text-money/config.js
CHANGED
|
@@ -46,7 +46,7 @@ const DefaultTemplate = (args) => ({
|
|
|
46
46
|
`,
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
const EnumVariantTemplate = (args, { argTypes }) => ({
|
|
49
|
+
const EnumVariantTemplate = (args, { argTypes } = {}) => ({
|
|
50
50
|
components: { UMoney, URow },
|
|
51
51
|
setup() {
|
|
52
52
|
const slots = getSlotNames(UMoney.__name);
|
|
@@ -16,8 +16,8 @@ export function separatedMoney(
|
|
|
16
16
|
thousandsSeparator = " ",
|
|
17
17
|
) {
|
|
18
18
|
const options = {
|
|
19
|
-
minimumFractionDigits:
|
|
20
|
-
maximumFractionDigits:
|
|
19
|
+
minimumFractionDigits: minFractionDigits,
|
|
20
|
+
maximumFractionDigits: maxFractionDigits,
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const formattedMoney =
|
|
@@ -1,26 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { vuelessConfig } from "./utilUI.
|
|
1
|
+
import colors from "tailwindcss/colors.js";
|
|
2
|
+
|
|
3
|
+
import { vuelessConfig } from "./utilUI.js";
|
|
4
|
+
import { isSSR, isCSR } from "./utilHelper.js";
|
|
4
5
|
import {
|
|
6
|
+
GRAY_COLOR,
|
|
7
|
+
COOL_COLOR,
|
|
5
8
|
BRAND_COLORS,
|
|
6
9
|
GRAYSCALE_COLOR,
|
|
7
10
|
DEFAULT_RING,
|
|
8
11
|
DEFAULT_RING_OFFSET,
|
|
12
|
+
DEFAULT_RING_OFFSET_COLOR_LIGHT,
|
|
13
|
+
DEFAULT_RING_OFFSET_COLOR_DARK,
|
|
9
14
|
DEFAULT_ROUNDING,
|
|
10
15
|
DEFAULT_BRAND_COLOR,
|
|
11
16
|
DEFAULT_GRAY_COLOR,
|
|
12
|
-
DEFAULT_RING_OFFSET_COLOR_LIGHT,
|
|
13
|
-
DEFAULT_RING_OFFSET_COLOR_DARK,
|
|
14
17
|
DARK_MODE_SELECTOR,
|
|
15
18
|
GRAY_COLORS,
|
|
16
19
|
PX_IN_REM,
|
|
17
|
-
} from "../constants.
|
|
18
|
-
|
|
19
|
-
import type { ThemeConfig, GrayColors, BrandColors, VuelessCssVariables } from "../types.ts";
|
|
20
|
-
|
|
21
|
-
interface InternalThemeConfig extends ThemeConfig {
|
|
22
|
-
systemDarkMode?: boolean;
|
|
23
|
-
}
|
|
20
|
+
} from "../constants.js";
|
|
24
21
|
|
|
25
22
|
export function themeInit() {
|
|
26
23
|
if (isSSR) return;
|
|
@@ -34,12 +31,8 @@ export function themeInit() {
|
|
|
34
31
|
);
|
|
35
32
|
}
|
|
36
33
|
|
|
37
|
-
export function setTheme(config
|
|
34
|
+
export function setTheme(config = {}) {
|
|
38
35
|
const isDarkMode = setDarkMode(config);
|
|
39
|
-
const rounding = config?.rounding ?? vuelessConfig.rounding ?? DEFAULT_ROUNDING;
|
|
40
|
-
let brand: BrandColors | GrayColors = config?.brand ?? vuelessConfig.brand ?? DEFAULT_BRAND_COLOR;
|
|
41
|
-
const gray = config?.gray ?? vuelessConfig.gray ?? DEFAULT_GRAY_COLOR;
|
|
42
|
-
|
|
43
36
|
const ring = config?.ring ?? vuelessConfig.ring ?? DEFAULT_RING;
|
|
44
37
|
const ringOffset = config?.ringOffset ?? vuelessConfig.ringOffset ?? DEFAULT_RING_OFFSET;
|
|
45
38
|
|
|
@@ -53,7 +46,10 @@ export function setTheme(config: InternalThemeConfig = {}) {
|
|
|
53
46
|
vuelessConfig.ringOffsetColorLight ??
|
|
54
47
|
DEFAULT_RING_OFFSET_COLOR_LIGHT;
|
|
55
48
|
|
|
56
|
-
const
|
|
49
|
+
const rounding = config?.rounding ?? vuelessConfig.rounding ?? DEFAULT_ROUNDING;
|
|
50
|
+
let brand = config?.brand ?? vuelessConfig.brand ?? DEFAULT_BRAND_COLOR;
|
|
51
|
+
let gray = config?.gray ?? vuelessConfig.gray ?? DEFAULT_GRAY_COLOR;
|
|
52
|
+
|
|
57
53
|
const isBrandColor = BRAND_COLORS.some((color) => color === brand);
|
|
58
54
|
const isGrayColor = GRAY_COLORS.some((color) => color === gray);
|
|
59
55
|
|
|
@@ -73,29 +69,29 @@ export function setTheme(config: InternalThemeConfig = {}) {
|
|
|
73
69
|
? defaultRingOffsetColorDark
|
|
74
70
|
: defaultRingOffsetColorLight;
|
|
75
71
|
|
|
72
|
+
if (gray === COOL_COLOR) {
|
|
73
|
+
gray = GRAY_COLOR;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
76
|
if (brand === GRAYSCALE_COLOR) {
|
|
77
77
|
brand = gray;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
const variables
|
|
81
|
-
"--vl-rounding": `${Number(rounding) / PX_IN_REM}rem`,
|
|
80
|
+
const variables = {
|
|
82
81
|
"--vl-ring": `${ring}px`,
|
|
83
82
|
"--vl-ring-offset": `${ringOffset}px`,
|
|
84
|
-
"--vl-ring-offset-color": convertHexInRgb(defaultRingOffsetColor)
|
|
83
|
+
"--vl-ring-offset-color": `rgb(${convertHexInRgb(defaultRingOffsetColor)})`,
|
|
84
|
+
"--vl-rounding": `${Number(rounding) / PX_IN_REM}rem`,
|
|
85
85
|
"--vl-color-gray-default": convertHexInRgb(colors[gray][defaultBrandShade]),
|
|
86
86
|
"--vl-color-brand-default": convertHexInRgb(colors[brand][defaultGrayShade]),
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
for (const key in colors[gray]) {
|
|
90
|
-
variables[`--vl-color-gray-${key}`
|
|
91
|
-
colors[gray][key],
|
|
92
|
-
);
|
|
90
|
+
variables[`--vl-color-gray-${key}`] = convertHexInRgb(colors[gray][key]);
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
for (const key in colors[brand]) {
|
|
96
|
-
variables[`--vl-color-brand-${key}`
|
|
97
|
-
colors[brand][key],
|
|
98
|
-
);
|
|
94
|
+
variables[`--vl-color-brand-${key}`] = convertHexInRgb(colors[brand][key]);
|
|
99
95
|
}
|
|
100
96
|
|
|
101
97
|
const stringVariables = Object.entries(variables)
|
|
@@ -114,14 +110,14 @@ export function setTheme(config: InternalThemeConfig = {}) {
|
|
|
114
110
|
return rootVariables;
|
|
115
111
|
}
|
|
116
112
|
|
|
117
|
-
function setDarkMode(config
|
|
113
|
+
function setDarkMode(config) {
|
|
118
114
|
config?.darkMode === undefined
|
|
119
115
|
? isCSR && localStorage.removeItem(DARK_MODE_SELECTOR)
|
|
120
|
-
: isCSR && localStorage.setItem(DARK_MODE_SELECTOR, Number(config?.darkMode)
|
|
116
|
+
: isCSR && localStorage.setItem(DARK_MODE_SELECTOR, Number(!!config?.darkMode));
|
|
121
117
|
|
|
122
118
|
const storedDarkMode = isCSR ? localStorage.getItem(DARK_MODE_SELECTOR) : null;
|
|
123
119
|
|
|
124
|
-
|
|
120
|
+
let isDarkMode =
|
|
125
121
|
storedDarkMode !== null
|
|
126
122
|
? !!Number(storedDarkMode)
|
|
127
123
|
: !!(config?.darkMode ?? vuelessConfig.darkMode ?? config?.systemDarkMode);
|
|
@@ -133,7 +129,7 @@ function setDarkMode(config: InternalThemeConfig) {
|
|
|
133
129
|
return isDarkMode;
|
|
134
130
|
}
|
|
135
131
|
|
|
136
|
-
export function convertHexInRgb(hex
|
|
132
|
+
export function convertHexInRgb(hex) {
|
|
137
133
|
const color = hex.replace(/#/g, "");
|
|
138
134
|
|
|
139
135
|
let r, g, b;
|
package/utils/utilUI.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
GRAYSCALE_COLOR,
|
|
8
8
|
DEFAULT_BRAND_COLOR,
|
|
9
9
|
NESTED_COMPONENT_REG_EXP,
|
|
10
|
+
SYSTEM_CONFIG_KEY,
|
|
10
11
|
} from "../constants.js";
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -27,7 +28,7 @@ if (isSSR) {
|
|
|
27
28
|
if (!vuelessConfig) {
|
|
28
29
|
vuelessConfig = (await import(/* @vite-ignore */ `${filePath}.ts`)).default;
|
|
29
30
|
}
|
|
30
|
-
} catch {
|
|
31
|
+
} catch (error) {
|
|
31
32
|
vuelessConfig = {};
|
|
32
33
|
}
|
|
33
34
|
})();
|
|
@@ -40,6 +41,209 @@ if (isCSR) {
|
|
|
40
41
|
)[0] || {};
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Recursively merge config objects with removing tailwind classes duplicates.
|
|
46
|
+
* @param {Object} defaultConfig
|
|
47
|
+
* @param {Object} globalConfig
|
|
48
|
+
* @param {Object} propsConfig
|
|
49
|
+
* @param {Object} config - final merged config.
|
|
50
|
+
* @param {boolean} isReplace - enables class replacement instead of merge.
|
|
51
|
+
* @param {boolean} isVarinants - if true, prevents adding a "base" key into nested objects.
|
|
52
|
+
*
|
|
53
|
+
* @returns {Object}
|
|
54
|
+
*/
|
|
55
|
+
export function mergeConfigs({
|
|
56
|
+
defaultConfig,
|
|
57
|
+
globalConfig,
|
|
58
|
+
propsConfig,
|
|
59
|
+
config = {},
|
|
60
|
+
isReplace = false,
|
|
61
|
+
isVariants = false,
|
|
62
|
+
}) {
|
|
63
|
+
globalConfig = cloneDeep(globalConfig || {});
|
|
64
|
+
propsConfig = cloneDeep(propsConfig || {});
|
|
65
|
+
|
|
66
|
+
const isGlobalConfig = Object.keys(globalConfig).length;
|
|
67
|
+
const isPropsConfig = Object.keys(propsConfig).length;
|
|
68
|
+
|
|
69
|
+
// Add unique keys from defaultConfig to composedConfig
|
|
70
|
+
let composedConfig = cloneDeep(defaultConfig);
|
|
71
|
+
|
|
72
|
+
// Add unique keys from globalConfig to composedConfig
|
|
73
|
+
for (let key in globalConfig) {
|
|
74
|
+
if (!Object.keys(composedConfig).includes(key)) {
|
|
75
|
+
composedConfig[key] = globalConfig[key];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Add unique keys from propsConfig to composedConfig
|
|
80
|
+
for (let key in propsConfig) {
|
|
81
|
+
if (!Object.keys(composedConfig).includes(key)) {
|
|
82
|
+
composedConfig[key] = propsConfig[key];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const {
|
|
87
|
+
i18n,
|
|
88
|
+
defaults,
|
|
89
|
+
strategy,
|
|
90
|
+
safelist,
|
|
91
|
+
component,
|
|
92
|
+
safelistColors,
|
|
93
|
+
defaultVariants,
|
|
94
|
+
compoundVariants,
|
|
95
|
+
} = SYSTEM_CONFIG_KEY;
|
|
96
|
+
|
|
97
|
+
for (let key in composedConfig) {
|
|
98
|
+
if (isGlobalConfig || isPropsConfig) {
|
|
99
|
+
if (key === safelist || key === safelistColors) {
|
|
100
|
+
if (propsConfig[key]) {
|
|
101
|
+
// eslint-disable-next-line no-console
|
|
102
|
+
console.warn(`Passing '${key}' key in 'config' prop is not allowed.`);
|
|
103
|
+
}
|
|
104
|
+
} else if (key === component) {
|
|
105
|
+
config[key] = propsConfig[key] || defaultConfig[key];
|
|
106
|
+
|
|
107
|
+
if (globalConfig[key]) {
|
|
108
|
+
// eslint-disable-next-line no-console
|
|
109
|
+
console.warn(`Passing '${key}' key in 'config' prop or by global config is not allowed.`);
|
|
110
|
+
}
|
|
111
|
+
} else if (key === strategy) {
|
|
112
|
+
config[key] = propsConfig[key] || globalConfig[key] || defaultConfig[key];
|
|
113
|
+
} else if (key === defaults || key === defaultVariants) {
|
|
114
|
+
config[key] = { ...defaultConfig[key], ...globalConfig[key], ...propsConfig[key] };
|
|
115
|
+
} else if (key === compoundVariants) {
|
|
116
|
+
config[key] = mergeCompoundVariants({
|
|
117
|
+
defaultConfig: composedConfig,
|
|
118
|
+
globalConfig,
|
|
119
|
+
propsConfig,
|
|
120
|
+
isReplace,
|
|
121
|
+
key,
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
const isObjectComposedConfig = typeof composedConfig[key] === "object";
|
|
125
|
+
const isObjectGlobalConfig = typeof globalConfig[key] === "object";
|
|
126
|
+
const isObjectPropsConfig = typeof propsConfig[key] === "object";
|
|
127
|
+
|
|
128
|
+
const isObject = isObjectComposedConfig || isObjectGlobalConfig || isObjectPropsConfig;
|
|
129
|
+
const isEmpty = composedConfig[key] === null;
|
|
130
|
+
const isI18n = key === i18n;
|
|
131
|
+
|
|
132
|
+
if (key === "variants" && !isVariants) {
|
|
133
|
+
isVariants = true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
config[key] =
|
|
137
|
+
isObject && !isEmpty && !isI18n
|
|
138
|
+
? mergeConfigs({
|
|
139
|
+
defaultConfig: stringToObject(composedConfig[key], { addBase: !isVariants }),
|
|
140
|
+
globalConfig: stringToObject(globalConfig[key], { addBase: !isVariants }),
|
|
141
|
+
propsConfig: stringToObject(propsConfig[key], { addBase: !isVariants }),
|
|
142
|
+
config: stringToObject(composedConfig[key], { addBase: !isVariants }),
|
|
143
|
+
isReplace,
|
|
144
|
+
isVariants,
|
|
145
|
+
})
|
|
146
|
+
: isReplace || isI18n
|
|
147
|
+
? propsConfig[key] || globalConfig[key] || defaultConfig[key]
|
|
148
|
+
: cx([defaultConfig[key], globalConfig[key], propsConfig[key]]);
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
config[key] = composedConfig[key];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return config;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
Turn simplified nested component config to regular config.
|
|
160
|
+
@param {Object | String} value
|
|
161
|
+
@param {Boolean} addBase
|
|
162
|
+
@returns {Object}
|
|
163
|
+
*/
|
|
164
|
+
function stringToObject(value, { addBase = false }) {
|
|
165
|
+
if (value === undefined) value = "";
|
|
166
|
+
|
|
167
|
+
return typeof value !== "object" ? addBase && { base: value } : value;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Merge CVA compound variants arrays.
|
|
172
|
+
* @param {Object} defaultConfig
|
|
173
|
+
* @param {Object} globalConfig
|
|
174
|
+
* @param {Object} propsConfig
|
|
175
|
+
* @param {string} key
|
|
176
|
+
* @param {boolean} isReplace - enables class replacement instead of merge.
|
|
177
|
+
*
|
|
178
|
+
* @returns {Array}
|
|
179
|
+
*/
|
|
180
|
+
function mergeCompoundVariants({ defaultConfig, globalConfig, propsConfig, key, isReplace }) {
|
|
181
|
+
if (
|
|
182
|
+
(globalConfig[key] && !Array.isArray(globalConfig[key])) ||
|
|
183
|
+
(propsConfig[key] && !Array.isArray(propsConfig[key])) ||
|
|
184
|
+
(defaultConfig[key] && !Array.isArray(defaultConfig[key]))
|
|
185
|
+
) {
|
|
186
|
+
// eslint-disable-next-line no-console
|
|
187
|
+
console.error("CompoundVariants should be an array.");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
let globalConfigUniqueItems = cloneDeep(globalConfig[key] || []);
|
|
191
|
+
let propsConfigUniqueItems = cloneDeep(propsConfig[key] || []);
|
|
192
|
+
|
|
193
|
+
const config = defaultConfig[key].map((defaultConfigItem) => {
|
|
194
|
+
/**
|
|
195
|
+
* Compare two objects by keys for match.
|
|
196
|
+
* @param {Object} configItem
|
|
197
|
+
* @returns {Boolean}
|
|
198
|
+
*/
|
|
199
|
+
function isSameItem(configItem) {
|
|
200
|
+
const hasConfigItemKeys = Object.keys(defaultConfigItem)
|
|
201
|
+
.map((key) => defaultConfigItem[key] === configItem[key] || key === "class")
|
|
202
|
+
.every((item) => !!item);
|
|
203
|
+
|
|
204
|
+
const hasDefaultConfigItemKeys = Object.keys(configItem)
|
|
205
|
+
.map((key) => defaultConfigItem[key] === configItem[key] || key === "class")
|
|
206
|
+
.every((item) => !!item);
|
|
207
|
+
|
|
208
|
+
return hasConfigItemKeys && hasDefaultConfigItemKeys;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Find the same compound variant item in custom config if exist.
|
|
213
|
+
* @param {Object} config
|
|
214
|
+
* @returns {Object|undefined}
|
|
215
|
+
*/
|
|
216
|
+
function findItem(config = []) {
|
|
217
|
+
const globalConfigUniqueItemIndex = globalConfigUniqueItems.findIndex(isSameItem);
|
|
218
|
+
const propsConfigUniqueItemIndex = propsConfigUniqueItems.findIndex(isSameItem);
|
|
219
|
+
|
|
220
|
+
if (~globalConfigUniqueItemIndex) {
|
|
221
|
+
globalConfigUniqueItems.splice(globalConfigUniqueItemIndex, 1);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (~propsConfigUniqueItemIndex) {
|
|
225
|
+
propsConfigUniqueItems.splice(propsConfigUniqueItemIndex, 1);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return config.find(isSameItem);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const globalConfigItem = findItem(globalConfig[key]);
|
|
232
|
+
const propsConfigItem = findItem(propsConfig[key]);
|
|
233
|
+
|
|
234
|
+
return globalConfigItem || propsConfigItem
|
|
235
|
+
? {
|
|
236
|
+
...defaultConfigItem,
|
|
237
|
+
class: isReplace
|
|
238
|
+
? propsConfigItem?.class || globalConfigItem?.class || defaultConfigItem.class
|
|
239
|
+
: cx([defaultConfigItem.class, globalConfigItem?.class, propsConfigItem?.class]),
|
|
240
|
+
}
|
|
241
|
+
: defaultConfigItem;
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
return [...config, ...globalConfigUniqueItems, ...propsConfigUniqueItems];
|
|
245
|
+
}
|
|
246
|
+
|
|
43
247
|
/**
|
|
44
248
|
* Extend twMerge (tailwind merge) by vueless and user config:
|
|
45
249
|
* All list of rules available here:
|