vueless 0.0.668 → 0.0.670
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/useUI.ts +18 -18
- package/constants.js +1 -1
- package/package.json +1 -1
- package/types.ts +4 -4
- package/ui.form-date-picker/UDatePicker.vue +3 -4
- package/ui.form-date-picker/storybook/stories.ts +3 -3
- package/ui.form-date-picker/types.ts +1 -1
- package/ui.navigation-progress/UStepperProgress.vue +0 -1
- package/ui.other-theme-color-toggle/UThemeColorToggle.vue +123 -0
- package/ui.other-theme-color-toggle/config.ts +20 -0
- package/{ui.form-color-picker → ui.other-theme-color-toggle}/constants.ts +1 -1
- package/ui.other-theme-color-toggle/storybook/stories.ts +111 -0
- package/ui.other-theme-color-toggle/types.ts +52 -0
- package/utils/node/dynamicProps.js +8 -3
- package/utils/node/mergeConfigs.js +8 -6
- package/utils/node/tailwindSafelist.js +0 -14
- package/utils/theme.ts +58 -46
- package/utils/ui.ts +6 -3
- package/ui.form-color-picker/UColorPicker.vue +0 -118
- package/ui.form-color-picker/config.ts +0 -63
- package/ui.form-color-picker/storybook/stories.ts +0 -86
- package/ui.form-color-picker/types.ts +0 -62
- /package/{ui.form-color-picker → ui.other-theme-color-toggle}/storybook/docs.mdx +0 -0
package/composables/useUI.ts
CHANGED
|
@@ -123,24 +123,6 @@ export default function useUI<T>(
|
|
|
123
123
|
const vuelessAttrs = ref({});
|
|
124
124
|
|
|
125
125
|
const attrs = useAttrs() as KeyAttrs;
|
|
126
|
-
const isDev = isCSR && import.meta.env?.DEV;
|
|
127
|
-
const isTopLevelKey = (topLevelClassKey || firstClassKey) === configKey;
|
|
128
|
-
|
|
129
|
-
const extendsKeyConfig = getExtendsKeyConfig(configKey);
|
|
130
|
-
const extendsKeyNestedComponent = getNestedComponent(extendsKeyConfig);
|
|
131
|
-
const keyNestedComponent = getNestedComponent(config.value[configKey]);
|
|
132
|
-
const nestedComponent = extendsKeyNestedComponent || keyNestedComponent || componentName;
|
|
133
|
-
|
|
134
|
-
const commonAttrs: KeyAttrs = {
|
|
135
|
-
...(isTopLevelKey ? attrs : {}),
|
|
136
|
-
"vl-component": isDev ? attrs["vl-component"] || componentName || null : null,
|
|
137
|
-
"vl-key": isDev ? attrs["vl-key"] || configKey || null : null,
|
|
138
|
-
"vl-child-component": isDev && attrs["vl-component"] ? nestedComponent : null,
|
|
139
|
-
"vl-child-key": isDev && attrs["vl-component"] ? configKey : null,
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
/* Delete value key to prevent v-model overwrite. */
|
|
143
|
-
delete commonAttrs.value;
|
|
144
126
|
|
|
145
127
|
const reactiveProps = computed(() => ({ ...props }));
|
|
146
128
|
|
|
@@ -156,8 +138,25 @@ export default function useUI<T>(
|
|
|
156
138
|
keyConfig = config.value[configKey] as NestedComponent;
|
|
157
139
|
}
|
|
158
140
|
|
|
141
|
+
const isDev = isCSR && import.meta.env?.DEV;
|
|
142
|
+
const isTopLevelKey = (topLevelClassKey || firstClassKey) === configKey;
|
|
143
|
+
|
|
159
144
|
const extendsClasses = getExtendsClasses(configKey);
|
|
160
145
|
const extendsKeyConfig = getExtendsKeyConfig(configKey);
|
|
146
|
+
const extendsKeyNestedComponent = getNestedComponent(extendsKeyConfig);
|
|
147
|
+
const keyNestedComponent = getNestedComponent(config.value[configKey]);
|
|
148
|
+
const nestedComponent = extendsKeyNestedComponent || keyNestedComponent || componentName;
|
|
149
|
+
|
|
150
|
+
const commonAttrs: KeyAttrs = {
|
|
151
|
+
...(isTopLevelKey ? attrs : {}),
|
|
152
|
+
"vl-component": isDev ? attrs["vl-component"] || componentName || null : null,
|
|
153
|
+
"vl-key": isDev ? attrs["vl-key"] || configKey || null : null,
|
|
154
|
+
"vl-child-component": isDev && attrs["vl-component"] ? nestedComponent : null,
|
|
155
|
+
"vl-child-key": isDev && attrs["vl-component"] ? configKey : null,
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/* Delete value key to prevent v-model overwrite. */
|
|
159
|
+
delete commonAttrs.value;
|
|
161
160
|
|
|
162
161
|
vuelessAttrs.value = {
|
|
163
162
|
...commonAttrs,
|
|
@@ -165,6 +164,7 @@ export default function useUI<T>(
|
|
|
165
164
|
config: getMergedConfig({
|
|
166
165
|
defaultConfig: extendsKeyConfig,
|
|
167
166
|
globalConfig: keyConfig,
|
|
167
|
+
propsConfig: attrs["config"] || {},
|
|
168
168
|
}),
|
|
169
169
|
...getDefaults({
|
|
170
170
|
...(extendsKeyConfig.defaults || {}),
|
package/constants.js
CHANGED
|
@@ -108,7 +108,6 @@ export const COMPONENTS = {
|
|
|
108
108
|
UDatePicker: "ui.form-date-picker",
|
|
109
109
|
UDatePickerRange: "ui.form-date-picker-range",
|
|
110
110
|
ULabel: "ui.form-label",
|
|
111
|
-
UColorPicker: "ui.form-color-picker",
|
|
112
111
|
|
|
113
112
|
/* Text & Content */
|
|
114
113
|
UHeader: "ui.text-header",
|
|
@@ -154,6 +153,7 @@ export const COMPONENTS = {
|
|
|
154
153
|
|
|
155
154
|
/* Other */
|
|
156
155
|
UDot: "ui.other-dot",
|
|
156
|
+
UThemeColorToggle: "ui.other-theme-color-toggle",
|
|
157
157
|
};
|
|
158
158
|
|
|
159
159
|
/**
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -46,7 +46,7 @@ import URadioGroupConfig from "./ui.form-radio-group/config.ts";
|
|
|
46
46
|
import USwitchConfig from "./ui.form-switch/config.ts";
|
|
47
47
|
import UTextareaConfig from "./ui.form-textarea/config.ts";
|
|
48
48
|
import ULabelConfig from "./ui.form-label/config.ts";
|
|
49
|
-
import UColorPickerConfig from "./ui.
|
|
49
|
+
import UColorPickerConfig from "./ui.other-theme-color-toggle/config.ts";
|
|
50
50
|
import UInputConfig from "./ui.form-input/config.ts";
|
|
51
51
|
import UInputNumberConfig from "./ui.form-input-number/config.ts";
|
|
52
52
|
import UInputRatingConfig from "./ui.form-input-rating/config.ts";
|
|
@@ -159,8 +159,7 @@ export type UnknownType = string | number | boolean | UnknownObject | undefined
|
|
|
159
159
|
export type ComponentNames = keyof Components & string; // keys union
|
|
160
160
|
export type Strategies = "merge" | "replace" | "override";
|
|
161
161
|
|
|
162
|
-
export type
|
|
163
|
-
export type GrayColors = "slate" | "cool" | "zinc" | "neutral" | "stone";
|
|
162
|
+
export type GrayColors = "slate" | "cool" | "zinc" | "neutral" | "stone" | string;
|
|
164
163
|
export type BrandColors =
|
|
165
164
|
| "grayscale"
|
|
166
165
|
| "red"
|
|
@@ -179,7 +178,8 @@ export type BrandColors =
|
|
|
179
178
|
| "purple"
|
|
180
179
|
| "fuchsia"
|
|
181
180
|
| "pink"
|
|
182
|
-
| "rose"
|
|
181
|
+
| "rose"
|
|
182
|
+
| string;
|
|
183
183
|
|
|
184
184
|
export interface Directives {
|
|
185
185
|
tooltip?: Partial<Props>;
|
|
@@ -23,16 +23,15 @@ import { COMPONENT_NAME } from "./constants.ts";
|
|
|
23
23
|
import { vClickOutside } from "../directives";
|
|
24
24
|
|
|
25
25
|
import type { ComputedRef } from "vue";
|
|
26
|
-
import type {
|
|
26
|
+
import type { Props, Config, Locale } from "./types.ts";
|
|
27
27
|
import type { ComponentExposed } from "../types.ts";
|
|
28
28
|
import type { Config as UCalendarConfig } from "../ui.form-calendar/types.ts";
|
|
29
29
|
import type { DateLocale } from "../ui.form-calendar/utilFormatting.ts";
|
|
30
30
|
|
|
31
31
|
defineOptions({ inheritAttrs: false });
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
|
|
33
|
+
const props = withDefaults(defineProps<Props<TModelValue>>(), {
|
|
34
|
+
...getDefaults<Props<TModelValue>, Config>(defaultConfig, COMPONENT_NAME),
|
|
36
35
|
modelValue: undefined,
|
|
37
36
|
minDate: undefined,
|
|
38
37
|
maxDate: undefined,
|
|
@@ -12,13 +12,13 @@ import URow from "../../ui.container-row/URow.vue";
|
|
|
12
12
|
|
|
13
13
|
import { COMPONENT_NAME } from "../constants.ts";
|
|
14
14
|
|
|
15
|
-
import type {
|
|
15
|
+
import type { Props } from "../types.ts";
|
|
16
16
|
|
|
17
|
-
interface DefaultUDatePickerArgs extends
|
|
17
|
+
interface DefaultUDatePickerArgs extends Props<unknown> {
|
|
18
18
|
slotTemplate?: string;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
interface EnumUDatePickerArgs extends
|
|
21
|
+
interface EnumUDatePickerArgs extends Props<unknown> {
|
|
22
22
|
slotTemplate?: string;
|
|
23
23
|
enum: "size";
|
|
24
24
|
}
|
|
@@ -5,7 +5,7 @@ import type { ComponentConfig } from "../types.ts";
|
|
|
5
5
|
export type Locale = typeof defaultConfig.i18n;
|
|
6
6
|
export type Config = typeof defaultConfig;
|
|
7
7
|
|
|
8
|
-
export interface
|
|
8
|
+
export interface Props<TModelValue> {
|
|
9
9
|
/**
|
|
10
10
|
* Calendar value (JavaScript Date object or string formatted in given `dateFormat` or object when `range` enabled).
|
|
11
11
|
*/
|
|
@@ -17,7 +17,6 @@ const props = withDefaults(defineProps<StepperProgressProps>(), {
|
|
|
17
17
|
|
|
18
18
|
const stepperColor = computed(() => {
|
|
19
19
|
const isValidColor = (color: string): color is keyof typeof colors => color in colors;
|
|
20
|
-
|
|
21
20
|
const isGrayColor = (color: string): color is keyof typeof colors => GRAY_COLORS.includes(color);
|
|
22
21
|
|
|
23
22
|
if (isValidColor(props.color)) {
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, useId, watch } from "vue";
|
|
3
|
+
|
|
4
|
+
import { vTooltip } from "../directives";
|
|
5
|
+
import useUI from "../composables/useUI.ts";
|
|
6
|
+
import { getDefaults } from "../utils/ui.ts";
|
|
7
|
+
import { setTheme, getSelectedBrandColor, getSelectedGrayColor } from "../utils/theme.ts";
|
|
8
|
+
import { GRAYSCALE_COLOR } from "../constants.js";
|
|
9
|
+
|
|
10
|
+
import UDivider from "../ui.container-divider/UDivider.vue";
|
|
11
|
+
import UButton from "../ui.button/UButton.vue";
|
|
12
|
+
|
|
13
|
+
import { COMPONENT_NAME } from "./constants.ts";
|
|
14
|
+
import defaultConfig from "./config.ts";
|
|
15
|
+
|
|
16
|
+
import type { BrandColors, GrayColors } from "../types.ts";
|
|
17
|
+
import type { Props, Config } from "./types.ts";
|
|
18
|
+
|
|
19
|
+
defineOptions({ inheritAttrs: false });
|
|
20
|
+
|
|
21
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
22
|
+
...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
|
|
23
|
+
modelValue: () => ["", ""],
|
|
24
|
+
brandColors: () => ({}),
|
|
25
|
+
grayColors: () => ({}),
|
|
26
|
+
brandLabels: () => ({}),
|
|
27
|
+
grayLabels: () => ({}),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const emit = defineEmits([
|
|
31
|
+
/**
|
|
32
|
+
* Triggers when color value changes.
|
|
33
|
+
* @property {string} value
|
|
34
|
+
*/
|
|
35
|
+
"update:modelValue",
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
const elementId = props.id || useId();
|
|
39
|
+
|
|
40
|
+
const selectedBrand = getSelectedBrandColor();
|
|
41
|
+
const selectedGray = getSelectedGrayColor();
|
|
42
|
+
|
|
43
|
+
const selectedItem = computed({
|
|
44
|
+
get: () => {
|
|
45
|
+
const [brand, gray] = props.modelValue;
|
|
46
|
+
|
|
47
|
+
return [brand || selectedBrand, gray || selectedGray];
|
|
48
|
+
},
|
|
49
|
+
set: (value) => emit("update:modelValue", value),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
watch(selectedItem, (newValue, oldValue) => {
|
|
53
|
+
const [oldBrand, oldGray] = oldValue;
|
|
54
|
+
const [brand, gray] = newValue;
|
|
55
|
+
|
|
56
|
+
if (oldBrand === brand && oldGray === gray) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setTheme({ brand, gray });
|
|
61
|
+
|
|
62
|
+
if (oldBrand !== brand && (brand === GRAYSCALE_COLOR || oldBrand === GRAYSCALE_COLOR)) {
|
|
63
|
+
window.location.reload();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
function onClickBrandColor(brand: BrandColors) {
|
|
68
|
+
const [, gray] = selectedItem.value;
|
|
69
|
+
|
|
70
|
+
selectedItem.value = [brand, gray];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function onClickGrayColor(gray: GrayColors) {
|
|
74
|
+
const [brand] = selectedItem.value;
|
|
75
|
+
|
|
76
|
+
selectedItem.value = [brand, gray];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get element / nested component attributes for each config token ✨
|
|
81
|
+
* Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
|
|
82
|
+
*/
|
|
83
|
+
const { listAttrs, colorButtonAttrs, circleAttrs, colorDividerAttrs } =
|
|
84
|
+
useUI<Config>(defaultConfig);
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<template>
|
|
88
|
+
<div :id="elementId" v-bind="listAttrs">
|
|
89
|
+
<UButton
|
|
90
|
+
v-for="(brandColorClass, color) in brandColors"
|
|
91
|
+
:key="color"
|
|
92
|
+
v-tooltip="brandLabels?.[color] || color"
|
|
93
|
+
square
|
|
94
|
+
size="xs"
|
|
95
|
+
:ring="false"
|
|
96
|
+
color="grayscale"
|
|
97
|
+
variant="thirdary"
|
|
98
|
+
:filled="selectedItem[0] === color"
|
|
99
|
+
v-bind="colorButtonAttrs"
|
|
100
|
+
@click="onClickBrandColor(color)"
|
|
101
|
+
>
|
|
102
|
+
<div :class="brandColorClass" v-bind="circleAttrs" />
|
|
103
|
+
</UButton>
|
|
104
|
+
|
|
105
|
+
<UDivider size="xs" v-bind="colorDividerAttrs" />
|
|
106
|
+
|
|
107
|
+
<UButton
|
|
108
|
+
v-for="(grayColorClass, color) in grayColors"
|
|
109
|
+
:key="color"
|
|
110
|
+
v-tooltip="brandLabels?.[color] || color"
|
|
111
|
+
square
|
|
112
|
+
size="xs"
|
|
113
|
+
:ring="false"
|
|
114
|
+
color="grayscale"
|
|
115
|
+
variant="thirdary"
|
|
116
|
+
:filled="selectedItem[1] === color"
|
|
117
|
+
v-bind="colorButtonAttrs"
|
|
118
|
+
@click="onClickGrayColor(color)"
|
|
119
|
+
>
|
|
120
|
+
<div :class="grayColorClass" v-bind="circleAttrs" />
|
|
121
|
+
</UButton>
|
|
122
|
+
</div>
|
|
123
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export default /*tw*/ {
|
|
2
|
+
list: "flex flex-wrap gap-0.5",
|
|
3
|
+
colorButton: {
|
|
4
|
+
base: "{UButton}",
|
|
5
|
+
button: {
|
|
6
|
+
compoundVariants: [
|
|
7
|
+
{
|
|
8
|
+
filled: true,
|
|
9
|
+
variant: "thirdary",
|
|
10
|
+
class: "!bg-gray-800/10 dark:!bg-gray-200/10",
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
circle: "size-5 rounded-full",
|
|
16
|
+
colorDivider: "{UDivider}",
|
|
17
|
+
defaults: {
|
|
18
|
+
size: "md",
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getArgTypes,
|
|
3
|
+
getSlotNames,
|
|
4
|
+
getSlotsFragment,
|
|
5
|
+
getDocsDescription,
|
|
6
|
+
} from "../../utils/storybook.ts";
|
|
7
|
+
|
|
8
|
+
import UThemeColorToggle from "../UThemeColorToggle.vue";
|
|
9
|
+
import UCol from "../../ui.container-col/UCol.vue";
|
|
10
|
+
import UButton from "../../ui.button/UButton.vue";
|
|
11
|
+
|
|
12
|
+
import type { Meta, StoryFn } from "@storybook/vue3";
|
|
13
|
+
import type { Props } from "../types.ts";
|
|
14
|
+
|
|
15
|
+
interface UThemeColorToggleArgs extends Props {
|
|
16
|
+
slotTemplate?: string;
|
|
17
|
+
enum: "size";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default {
|
|
21
|
+
id: "100020",
|
|
22
|
+
title: "Other / Theme Color Switcher",
|
|
23
|
+
component: UThemeColorToggle,
|
|
24
|
+
args: {
|
|
25
|
+
modelValue: ["", ""],
|
|
26
|
+
brandColors: {
|
|
27
|
+
grayscale: "bg-gray-900",
|
|
28
|
+
gray: "bg-gray-600",
|
|
29
|
+
red: "bg-red-600",
|
|
30
|
+
orange: "bg-orange-600",
|
|
31
|
+
amber: "bg-amber-600",
|
|
32
|
+
yellow: "bg-yellow-600",
|
|
33
|
+
lime: "bg-lime-600",
|
|
34
|
+
green: "bg-green-600",
|
|
35
|
+
emerald: "bg-emerald-600",
|
|
36
|
+
teal: "bg-teal-600",
|
|
37
|
+
cyan: "bg-cyan-600",
|
|
38
|
+
sky: "bg-sky-600",
|
|
39
|
+
blue: "bg-blue-600",
|
|
40
|
+
indigo: "bg-indigo-600",
|
|
41
|
+
violet: "bg-violet-600",
|
|
42
|
+
purple: "bg-purple-600",
|
|
43
|
+
fuchsia: "bg-fuchsia-600",
|
|
44
|
+
pink: "bg-pink-600",
|
|
45
|
+
rose: "bg-rose-600",
|
|
46
|
+
},
|
|
47
|
+
grayColors: {
|
|
48
|
+
slate: "bg-slate-600",
|
|
49
|
+
cool: "bg-cool-600",
|
|
50
|
+
zinc: "bg-zinc-600",
|
|
51
|
+
neutral: "bg-neutral-600",
|
|
52
|
+
stone: "bg-stone-600",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
argTypes: {
|
|
56
|
+
...getArgTypes(UThemeColorToggle.__name),
|
|
57
|
+
},
|
|
58
|
+
parameters: {
|
|
59
|
+
docs: {
|
|
60
|
+
...getDocsDescription(UThemeColorToggle.__name),
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
} as Meta;
|
|
64
|
+
|
|
65
|
+
const DefaultTemplate: StoryFn<UThemeColorToggleArgs> = (args: UThemeColorToggleArgs) => ({
|
|
66
|
+
components: { UThemeColorToggle, UButton, UCol },
|
|
67
|
+
setup() {
|
|
68
|
+
const slots = getSlotNames(UThemeColorToggle.__name);
|
|
69
|
+
|
|
70
|
+
return { args, slots };
|
|
71
|
+
},
|
|
72
|
+
template: `
|
|
73
|
+
<UCol>
|
|
74
|
+
<UThemeColorToggle v-bind="args" v-model="args.modelValue">
|
|
75
|
+
${args.slotTemplate || getSlotsFragment("")}
|
|
76
|
+
</UThemeColorToggle>
|
|
77
|
+
|
|
78
|
+
<UButton label="Brand button" color="brand"/>
|
|
79
|
+
</UCol>
|
|
80
|
+
`,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const EnumVariantTemplate: StoryFn<UThemeColorToggleArgs> = (
|
|
84
|
+
args: UThemeColorToggleArgs,
|
|
85
|
+
{ argTypes },
|
|
86
|
+
) => ({
|
|
87
|
+
components: { UCol, UThemeColorToggle },
|
|
88
|
+
setup() {
|
|
89
|
+
return {
|
|
90
|
+
args,
|
|
91
|
+
options: argTypes?.[args.enum]?.options,
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
template: `
|
|
95
|
+
<UCol>
|
|
96
|
+
<UThemeColorToggle
|
|
97
|
+
v-for="(option, index) in options"
|
|
98
|
+
:key="index"
|
|
99
|
+
v-bind="args"
|
|
100
|
+
v-model="args.modelValue"
|
|
101
|
+
:[args.enum]="option"
|
|
102
|
+
/>
|
|
103
|
+
</UCol>
|
|
104
|
+
`,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export const Default = DefaultTemplate.bind({});
|
|
108
|
+
Default.args = {};
|
|
109
|
+
|
|
110
|
+
export const Sizes = EnumVariantTemplate.bind({});
|
|
111
|
+
Sizes.args = { enum: "size" };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import defaultConfig from "./config.ts";
|
|
2
|
+
|
|
3
|
+
import type { BrandColors, GrayColors, ComponentConfig } from "../types.ts";
|
|
4
|
+
|
|
5
|
+
export type Config = typeof defaultConfig;
|
|
6
|
+
|
|
7
|
+
export interface Props {
|
|
8
|
+
/**
|
|
9
|
+
* Selected values.
|
|
10
|
+
*/
|
|
11
|
+
modelValue: [BrandColors, GrayColors];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Component size.
|
|
15
|
+
*/
|
|
16
|
+
size?: "sm" | "md" | "lg";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Brand color list.
|
|
20
|
+
*/
|
|
21
|
+
brandColors?: Record<BrandColors, string>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Gray color list.
|
|
25
|
+
*/
|
|
26
|
+
grayColors?: Record<GrayColors, string>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Brand color labels.
|
|
30
|
+
*/
|
|
31
|
+
brandLabels?: Record<BrandColors, string>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Gray color labels.
|
|
35
|
+
*/
|
|
36
|
+
grayLabels?: Record<GrayColors, string>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Unique element id.
|
|
40
|
+
*/
|
|
41
|
+
id?: string;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Component config object.
|
|
45
|
+
*/
|
|
46
|
+
config?: ComponentConfig<Config>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Data-test attribute for automated testing.
|
|
50
|
+
*/
|
|
51
|
+
dataTest?: string;
|
|
52
|
+
}
|
|
@@ -11,7 +11,7 @@ const CLOSING_BRACKET = "}";
|
|
|
11
11
|
const IGNORE_PROP = "@ignore";
|
|
12
12
|
const CUSTOM_PROP = "@custom";
|
|
13
13
|
|
|
14
|
-
const PROPS_INTERFACE_REG_EXP = /export\s+interface\s+Props
|
|
14
|
+
const PROPS_INTERFACE_REG_EXP = /export\s+interface\s+Props(?:<\w+>)?\s*{([^}]*)}/s;
|
|
15
15
|
const UNION_SYMBOLS_REG_EXP = /[?|:"|;]/g;
|
|
16
16
|
const WORD_IN_QUOTE_REG_EXP = /"([^"]+)"/g;
|
|
17
17
|
|
|
@@ -129,6 +129,11 @@ async function modifyComponentTypes(filePath, props) {
|
|
|
129
129
|
const defaultOptionalMark = lines[propIndex]?.includes(OPTIONAL_MARK) ? OPTIONAL_MARK : "";
|
|
130
130
|
const optionalMark = required === undefined ? defaultOptionalMark : userOptionalMark;
|
|
131
131
|
|
|
132
|
+
const isExtendOnly = lines
|
|
133
|
+
.slice(propIndex - 2, propIndex)
|
|
134
|
+
.join("")
|
|
135
|
+
.includes("@extendOnly");
|
|
136
|
+
|
|
132
137
|
const propDescription = description?.replaceAll(/[\n\s]+/g, " ").trim() || "–"; // removes new lines and double spaces.
|
|
133
138
|
const propType = unionType.length ? unionType : type;
|
|
134
139
|
|
|
@@ -142,14 +147,14 @@ async function modifyComponentTypes(filePath, props) {
|
|
|
142
147
|
|
|
143
148
|
/* Check if the prop type already exists. */
|
|
144
149
|
if (~propIndex) {
|
|
145
|
-
if (unionType.length && isAssignableValue) {
|
|
150
|
+
if (unionType.length && (isAssignableValue || !isExtendOnly)) {
|
|
146
151
|
// Remove multiline union types;
|
|
147
152
|
lines.splice(propIndex + 1, propEndIndex);
|
|
148
153
|
|
|
149
154
|
lines.splice(propIndex, 1, ` ${name}${defaultOptionalMark}: ${propType};`);
|
|
150
155
|
}
|
|
151
156
|
|
|
152
|
-
if (unionType.length && !isAssignableValue) {
|
|
157
|
+
if (unionType.length && isExtendOnly && !isAssignableValue) {
|
|
153
158
|
// eslint-disable-next-line no-console
|
|
154
159
|
console.warn(`${unionType} is not assignable to type ${defaultUnionType}.`);
|
|
155
160
|
}
|
|
@@ -147,15 +147,17 @@ export function createMergeConfigs(cx) {
|
|
|
147
147
|
function findItem(config = []) {
|
|
148
148
|
config = cloneDeep(config);
|
|
149
149
|
|
|
150
|
-
const
|
|
151
|
-
const
|
|
150
|
+
const globalConfigSimilarItemIndex = globalCompoundVariants.findIndex(isSameItem);
|
|
151
|
+
const propsConfigSimilarItemIndex = propsCompoundVariants.findIndex(isSameItem);
|
|
152
152
|
|
|
153
|
-
if (~
|
|
154
|
-
|
|
153
|
+
if (~globalConfigSimilarItemIndex) {
|
|
154
|
+
config.push(globalCompoundVariants[globalConfigSimilarItemIndex]);
|
|
155
|
+
globalCompoundVariants.splice(globalConfigSimilarItemIndex, 1);
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
if (~
|
|
158
|
-
|
|
158
|
+
if (~propsConfigSimilarItemIndex) {
|
|
159
|
+
config.push(propsCompoundVariants[propsConfigSimilarItemIndex]);
|
|
160
|
+
propsCompoundVariants.splice(propsConfigSimilarItemIndex, 1);
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
return config.find(isSameItem);
|
|
@@ -222,10 +222,6 @@ async function findComponentColors(componentName, files, vuelessConfigFiles) {
|
|
|
222
222
|
isComponentExists = Boolean(matchedComponent);
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
const propsColors = getPropsColors(fileContent);
|
|
226
|
-
|
|
227
|
-
propsColors.forEach((color) => colors.add(color));
|
|
228
|
-
|
|
229
225
|
if (isDefaultConfig) {
|
|
230
226
|
fileContent.match(objectColorRegExp)?.forEach((colorMatch) => {
|
|
231
227
|
const [, color] = objectColorRegExp.exec(colorMatch) || [];
|
|
@@ -264,16 +260,6 @@ async function findComponentColors(componentName, files, vuelessConfigFiles) {
|
|
|
264
260
|
};
|
|
265
261
|
}
|
|
266
262
|
|
|
267
|
-
function getPropsColors(inputString) {
|
|
268
|
-
const colorsMatch = inputString.match(/colors:\s*\[(.*?)\]/s);
|
|
269
|
-
|
|
270
|
-
if (colorsMatch && colorsMatch[1]) {
|
|
271
|
-
return colorsMatch[1].split(",").map((color) => color.trim().replace(/['"]/g, ""));
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return [];
|
|
275
|
-
}
|
|
276
|
-
|
|
277
263
|
function isDefaultComponentConfig(filePath, componentName) {
|
|
278
264
|
const componentDirName = filePath.split(path.sep).at(-2);
|
|
279
265
|
|
package/utils/theme.ts
CHANGED
|
@@ -5,7 +5,12 @@ import { tailwindConfig } from "./tailwindConfig.ts";
|
|
|
5
5
|
import { vuelessConfig } from "./ui.ts";
|
|
6
6
|
import { isSSR, isCSR } from "./helper.ts";
|
|
7
7
|
import {
|
|
8
|
-
|
|
8
|
+
PX_IN_REM,
|
|
9
|
+
COOL_COLOR,
|
|
10
|
+
GRAY_COLOR,
|
|
11
|
+
COLOR_MODE_KEY,
|
|
12
|
+
LIGHT_MODE_SELECTOR,
|
|
13
|
+
DARK_MODE_SELECTOR,
|
|
9
14
|
GRAYSCALE_COLOR,
|
|
10
15
|
DEFAULT_RING,
|
|
11
16
|
DEFAULT_RING_OFFSET,
|
|
@@ -14,13 +19,6 @@ import {
|
|
|
14
19
|
DEFAULT_GRAY_COLOR,
|
|
15
20
|
DEFAULT_RING_OFFSET_COLOR_LIGHT,
|
|
16
21
|
DEFAULT_RING_OFFSET_COLOR_DARK,
|
|
17
|
-
DARK_MODE_SELECTOR,
|
|
18
|
-
GRAY_COLORS,
|
|
19
|
-
PX_IN_REM,
|
|
20
|
-
COOL_COLOR,
|
|
21
|
-
GRAY_COLOR,
|
|
22
|
-
LIGHT_MODE_SELECTOR,
|
|
23
|
-
COLOR_MODE_KEY,
|
|
24
22
|
} from "../constants.js";
|
|
25
23
|
|
|
26
24
|
import type {
|
|
@@ -35,6 +33,10 @@ import { ColorMode } from "../types.ts";
|
|
|
35
33
|
|
|
36
34
|
type DefaultColors = typeof tailwindColors;
|
|
37
35
|
|
|
36
|
+
interface Colors extends DefaultColors {
|
|
37
|
+
[key: string]: Partial<TailwindColorShades> | string;
|
|
38
|
+
}
|
|
39
|
+
|
|
38
40
|
export function themeInit() {
|
|
39
41
|
if (isSSR) return;
|
|
40
42
|
|
|
@@ -97,46 +99,41 @@ export function setColorMode(colorMode: `${ColorMode}`) {
|
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
|
|
102
|
+
export function getSelectedBrandColor() {
|
|
103
|
+
return localStorage.getItem("brand") || undefined;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function getSelectedGrayColor() {
|
|
107
|
+
return localStorage.getItem("gray") || undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
100
110
|
export function setTheme(config: Config = {}) {
|
|
101
|
-
setColorMode(vuelessConfig.colorMode || config
|
|
111
|
+
setColorMode(vuelessConfig.colorMode || config.colorMode || ColorMode.Light);
|
|
102
112
|
|
|
103
|
-
const rounding = config
|
|
104
|
-
const roundingSm = config
|
|
105
|
-
const roundingLg = config
|
|
113
|
+
const rounding = config.rounding ?? vuelessConfig.rounding ?? DEFAULT_ROUNDING;
|
|
114
|
+
const roundingSm = config.roundingSm ?? vuelessConfig.roundingSm ?? rounding / 2;
|
|
115
|
+
const roundingLg = config.roundingLg ?? vuelessConfig.roundingLg ?? rounding * 2;
|
|
106
116
|
const isDarkMode = isCSR && document.documentElement.classList.contains(DARK_MODE_SELECTOR);
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
config
|
|
118
|
+
const brand: BrandColors =
|
|
119
|
+
config.brand ?? getSelectedBrandColor() ?? vuelessConfig.brand ?? DEFAULT_BRAND_COLOR;
|
|
110
120
|
|
|
111
|
-
let gray: GrayColors
|
|
112
|
-
config
|
|
121
|
+
let gray: GrayColors =
|
|
122
|
+
config.gray ?? getSelectedGrayColor() ?? vuelessConfig.gray ?? DEFAULT_GRAY_COLOR;
|
|
113
123
|
|
|
114
|
-
const ring = config
|
|
115
|
-
const ringOffset = config
|
|
124
|
+
const ring = config.ring ?? vuelessConfig.ring ?? DEFAULT_RING;
|
|
125
|
+
const ringOffset = config.ringOffset ?? vuelessConfig.ringOffset ?? DEFAULT_RING_OFFSET;
|
|
116
126
|
|
|
117
127
|
const ringOffsetColorDark =
|
|
118
|
-
config
|
|
128
|
+
config.ringOffsetColorDark ??
|
|
119
129
|
vuelessConfig.ringOffsetColorDark ??
|
|
120
130
|
DEFAULT_RING_OFFSET_COLOR_DARK;
|
|
121
131
|
|
|
122
132
|
const ringOffsetColorLight =
|
|
123
|
-
config
|
|
133
|
+
config.ringOffsetColorLight ??
|
|
124
134
|
vuelessConfig.ringOffsetColorLight ??
|
|
125
135
|
DEFAULT_RING_OFFSET_COLOR_LIGHT;
|
|
126
136
|
|
|
127
|
-
const isBrandColor = [...BRAND_COLORS, GRAYSCALE_COLOR].some((color) => color === brand);
|
|
128
|
-
const isGrayColor = GRAY_COLORS.some((color) => color === gray);
|
|
129
|
-
|
|
130
|
-
if (!isBrandColor) {
|
|
131
|
-
// eslint-disable-next-line no-console
|
|
132
|
-
console.warn(`Brand color '${brand}' is incorrect.`);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (!isGrayColor) {
|
|
136
|
-
// eslint-disable-next-line no-console
|
|
137
|
-
console.warn(`Gray color '${gray}' is incorrect.`);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
137
|
const defaultBrandShade = isDarkMode ? 400 : 600;
|
|
141
138
|
const defaultGrayShade = isDarkMode ? 400 : 600;
|
|
142
139
|
const defaultRingOffsetColor = isDarkMode ? ringOffsetColorDark : ringOffsetColorLight;
|
|
@@ -145,10 +142,6 @@ export function setTheme(config: Config = {}) {
|
|
|
145
142
|
gray = GRAY_COLOR;
|
|
146
143
|
}
|
|
147
144
|
|
|
148
|
-
if (brand === GRAYSCALE_COLOR) {
|
|
149
|
-
brand = gray;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
145
|
/* Remove deprecated color aliases. */
|
|
153
146
|
delete (tailwindColors as Partial<DefaultColors>).lightBlue;
|
|
154
147
|
delete (tailwindColors as Partial<DefaultColors>).warmGray;
|
|
@@ -156,12 +149,29 @@ export function setTheme(config: Config = {}) {
|
|
|
156
149
|
delete (tailwindColors as Partial<DefaultColors>).coolGray;
|
|
157
150
|
delete (tailwindColors as Partial<DefaultColors>).blueGray;
|
|
158
151
|
|
|
159
|
-
const colors:
|
|
160
|
-
tailwindColors,
|
|
152
|
+
const colors: Colors = merge(
|
|
153
|
+
tailwindColors as Colors,
|
|
161
154
|
tailwindConfig?.theme?.extend?.colors || {},
|
|
162
155
|
vuelessConfig.tailwindTheme?.extend?.colors || {},
|
|
163
156
|
);
|
|
164
157
|
|
|
158
|
+
const projectColors = Object.keys(colors);
|
|
159
|
+
const isBrandColor = projectColors.some((color) => color === brand) || brand === GRAYSCALE_COLOR;
|
|
160
|
+
const isGrayColor = projectColors.some((color) => color === gray);
|
|
161
|
+
|
|
162
|
+
if (!isBrandColor) {
|
|
163
|
+
// eslint-disable-next-line no-console
|
|
164
|
+
console.warn(`The brand color '${brand}' is missing in your palette.`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (!isGrayColor) {
|
|
168
|
+
// eslint-disable-next-line no-console
|
|
169
|
+
console.warn(`The gray color '${gray}' is missing in your palette.`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
localStorage.setItem("brand", brand);
|
|
173
|
+
localStorage.setItem("gray", gray);
|
|
174
|
+
|
|
165
175
|
const variables: Partial<VuelessCssVariables> = {
|
|
166
176
|
"--vl-rounding-sm": `${Number(roundingSm) / PX_IN_REM}rem`,
|
|
167
177
|
"--vl-rounding": `${Number(rounding) / PX_IN_REM}rem`,
|
|
@@ -169,23 +179,23 @@ export function setTheme(config: Config = {}) {
|
|
|
169
179
|
"--vl-ring": `${ring}px`,
|
|
170
180
|
"--vl-ring-offset": `${ringOffset}px`,
|
|
171
181
|
"--vl-ring-offset-color": convertHexInRgb(defaultRingOffsetColor),
|
|
172
|
-
"--vl-color-gray-default": convertHexInRgb(colors[gray][defaultBrandShade]),
|
|
173
|
-
"--vl-color-brand-default": convertHexInRgb(colors[brand][defaultGrayShade]),
|
|
182
|
+
"--vl-color-gray-default": convertHexInRgb(colors[gray]?.[defaultBrandShade]),
|
|
183
|
+
"--vl-color-brand-default": convertHexInRgb(colors[brand]?.[defaultGrayShade]),
|
|
174
184
|
};
|
|
175
185
|
|
|
176
|
-
for (const key in colors[gray]) {
|
|
186
|
+
for (const key in colors[gray] as TailwindColorShades) {
|
|
177
187
|
const shade = key as unknown as keyof TailwindColorShades;
|
|
178
188
|
|
|
179
189
|
variables[`--vl-color-gray-${key}` as keyof VuelessCssVariables] = convertHexInRgb(
|
|
180
|
-
colors[gray][shade],
|
|
190
|
+
colors[gray]?.[shade],
|
|
181
191
|
);
|
|
182
192
|
}
|
|
183
193
|
|
|
184
|
-
for (const key in colors[brand]) {
|
|
194
|
+
for (const key in colors[brand] as TailwindColorShades) {
|
|
185
195
|
const shade = key as unknown as keyof TailwindColorShades;
|
|
186
196
|
|
|
187
197
|
variables[`--vl-color-brand-${key}` as keyof VuelessCssVariables] = convertHexInRgb(
|
|
188
|
-
colors[brand][shade],
|
|
198
|
+
colors[brand]?.[shade],
|
|
189
199
|
);
|
|
190
200
|
}
|
|
191
201
|
|
|
@@ -205,7 +215,9 @@ export function setTheme(config: Config = {}) {
|
|
|
205
215
|
return rootVariables;
|
|
206
216
|
}
|
|
207
217
|
|
|
208
|
-
export function convertHexInRgb(hex
|
|
218
|
+
export function convertHexInRgb(hex?: string) {
|
|
219
|
+
if (!hex) return;
|
|
220
|
+
|
|
209
221
|
const color = hex.replace(/#/g, "");
|
|
210
222
|
|
|
211
223
|
let r, g, b;
|
package/utils/ui.ts
CHANGED
|
@@ -4,10 +4,10 @@ import { extendTailwindMerge } from "tailwind-merge";
|
|
|
4
4
|
import { isCSR, isSSR } from "./helper.ts";
|
|
5
5
|
import { createGetMergedConfig } from "./node/mergeConfigs.js";
|
|
6
6
|
import { COMPONENT_NAME as U_ICON } from "../ui.image-icon/constants.ts";
|
|
7
|
+
import { getSelectedBrandColor } from "./theme.ts";
|
|
7
8
|
import {
|
|
8
9
|
BRAND_COLOR,
|
|
9
10
|
GRAYSCALE_COLOR,
|
|
10
|
-
DEFAULT_BRAND_COLOR,
|
|
11
11
|
ICON_NON_PROPS_DEFAULTS,
|
|
12
12
|
TAILWIND_MERGE_EXTENSION,
|
|
13
13
|
NESTED_COMPONENT_PATTERN_REG_EXP,
|
|
@@ -129,10 +129,13 @@ export function getDefaults<Props, Config>(defaultConfig: Config, name: Componen
|
|
|
129
129
|
* Otherwise return given color.
|
|
130
130
|
*/
|
|
131
131
|
export function getColor(color: string) {
|
|
132
|
-
const isBrandColorGrayscale =
|
|
132
|
+
const isBrandColorGrayscale = vuelessConfig.brand === GRAYSCALE_COLOR;
|
|
133
|
+
const isSelectedColorGrayscale = getSelectedBrandColor() === GRAYSCALE_COLOR;
|
|
133
134
|
const isComponentColorBrand = color === BRAND_COLOR;
|
|
134
135
|
|
|
135
|
-
return isBrandColorGrayscale && isComponentColorBrand
|
|
136
|
+
return (isBrandColorGrayscale || isSelectedColorGrayscale) && isComponentColorBrand
|
|
137
|
+
? GRAYSCALE_COLOR
|
|
138
|
+
: color;
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
/**
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, useId } from "vue";
|
|
3
|
-
|
|
4
|
-
import useUI from "../composables/useUI.ts";
|
|
5
|
-
import { getDefaults } from "../utils/ui.ts";
|
|
6
|
-
|
|
7
|
-
import UIcon from "../ui.image-icon/UIcon.vue";
|
|
8
|
-
import URadio from "../ui.form-radio/URadio.vue";
|
|
9
|
-
import ULabel from "../ui.form-label/ULabel.vue";
|
|
10
|
-
|
|
11
|
-
import { COMPONENT_NAME } from "./constants.ts";
|
|
12
|
-
import defaultConfig from "./config.ts";
|
|
13
|
-
|
|
14
|
-
import type { Props, Config } from "./types.ts";
|
|
15
|
-
import type { BrandColors } from "../types.ts";
|
|
16
|
-
|
|
17
|
-
defineOptions({ inheritAttrs: false });
|
|
18
|
-
|
|
19
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
20
|
-
...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
|
|
21
|
-
colorOptions: () =>
|
|
22
|
-
getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME).colorOptions as BrandColors[],
|
|
23
|
-
modelValue: "",
|
|
24
|
-
label: "",
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const emit = defineEmits([
|
|
28
|
-
/**
|
|
29
|
-
* Triggers when color value changes.
|
|
30
|
-
* @property {string} value
|
|
31
|
-
*/
|
|
32
|
-
"update:modelValue",
|
|
33
|
-
]);
|
|
34
|
-
|
|
35
|
-
const elementId = props.id || useId();
|
|
36
|
-
|
|
37
|
-
const selectedItem = computed({
|
|
38
|
-
get: () => props.modelValue,
|
|
39
|
-
set: (value) => emit("update:modelValue", value),
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
function onUpdateValue(value: string) {
|
|
43
|
-
selectedItem.value = value;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Get element / nested component attributes for each config token ✨
|
|
48
|
-
* Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
|
|
49
|
-
*/
|
|
50
|
-
const {
|
|
51
|
-
config,
|
|
52
|
-
colorPickerLabelAttrs,
|
|
53
|
-
listAttrs,
|
|
54
|
-
colorPickerRadioAttrs,
|
|
55
|
-
unselectedColorPickerRadioAttrs,
|
|
56
|
-
unselectedIconAttrs,
|
|
57
|
-
unselectedAttrs,
|
|
58
|
-
} = useUI<Config>(defaultConfig);
|
|
59
|
-
</script>
|
|
60
|
-
|
|
61
|
-
<template>
|
|
62
|
-
<ULabel
|
|
63
|
-
:label="label"
|
|
64
|
-
:description="description"
|
|
65
|
-
:disabled="disabled"
|
|
66
|
-
:error="error"
|
|
67
|
-
:size="size"
|
|
68
|
-
align="topWithDesc"
|
|
69
|
-
v-bind="colorPickerLabelAttrs"
|
|
70
|
-
:data-test="dataTest"
|
|
71
|
-
>
|
|
72
|
-
<template #label>
|
|
73
|
-
<!--
|
|
74
|
-
@slot Use this to add custom content instead of the label.
|
|
75
|
-
@binding {string} label
|
|
76
|
-
-->
|
|
77
|
-
<slot name="label" :label="label" />
|
|
78
|
-
</template>
|
|
79
|
-
|
|
80
|
-
<div v-bind="listAttrs">
|
|
81
|
-
<div v-bind="unselectedAttrs">
|
|
82
|
-
<URadio
|
|
83
|
-
:id="elementId"
|
|
84
|
-
:name="name"
|
|
85
|
-
:size="size"
|
|
86
|
-
color="gray"
|
|
87
|
-
:checked="selectedItem === ''"
|
|
88
|
-
:disabled="disabled"
|
|
89
|
-
v-bind="unselectedColorPickerRadioAttrs"
|
|
90
|
-
@update:model-value="onUpdateValue('')"
|
|
91
|
-
/>
|
|
92
|
-
|
|
93
|
-
<label :for="elementId">
|
|
94
|
-
<UIcon
|
|
95
|
-
v-if="selectedItem === ''"
|
|
96
|
-
internal
|
|
97
|
-
color="gray"
|
|
98
|
-
:name="config.defaults.unselectedIcon"
|
|
99
|
-
v-bind="unselectedIconAttrs"
|
|
100
|
-
/>
|
|
101
|
-
</label>
|
|
102
|
-
</div>
|
|
103
|
-
|
|
104
|
-
<URadio
|
|
105
|
-
v-for="(color, index) in colorOptions"
|
|
106
|
-
:key="index"
|
|
107
|
-
:name="name"
|
|
108
|
-
:size="size"
|
|
109
|
-
:value="color"
|
|
110
|
-
:color="color"
|
|
111
|
-
:checked="selectedItem === color"
|
|
112
|
-
:disabled="disabled"
|
|
113
|
-
v-bind="colorPickerRadioAttrs"
|
|
114
|
-
@update:model-value="onUpdateValue(color)"
|
|
115
|
-
/>
|
|
116
|
-
</div>
|
|
117
|
-
</ULabel>
|
|
118
|
-
</template>
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
export default /*tw*/ {
|
|
2
|
-
colorPickerLabel: "{ULabel}",
|
|
3
|
-
list: {
|
|
4
|
-
base: "flex flex-wrap",
|
|
5
|
-
variants: {
|
|
6
|
-
size: {
|
|
7
|
-
sm: "gap-2 mt-px",
|
|
8
|
-
md: "gap-3 mt-0.5",
|
|
9
|
-
lg: "gap-3 mt-1",
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
unselected: "relative flex",
|
|
14
|
-
unselectedIcon: {
|
|
15
|
-
base: "{UIcon} absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full",
|
|
16
|
-
defaults: {
|
|
17
|
-
size: {
|
|
18
|
-
xs: "3xs",
|
|
19
|
-
sm: "2xs",
|
|
20
|
-
md: "xs",
|
|
21
|
-
lg: "sm",
|
|
22
|
-
xl: "md",
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
unselectedColorPickerRadio: {
|
|
27
|
-
base: "{URadio}",
|
|
28
|
-
radio: "checked:text-white !border-gray-300",
|
|
29
|
-
},
|
|
30
|
-
colorPickerRadio: {
|
|
31
|
-
base: "{URadio}",
|
|
32
|
-
radio: `
|
|
33
|
-
bg-{color}-600 border-{color}-600 hover:border-{color}-600 active:bg-{color}-800
|
|
34
|
-
disabled:border-{color}-400 disabled:bg-{color}-400
|
|
35
|
-
`,
|
|
36
|
-
},
|
|
37
|
-
defaults: {
|
|
38
|
-
size: "md",
|
|
39
|
-
name: "colorPicker",
|
|
40
|
-
disabled: false,
|
|
41
|
-
colorOptions: [
|
|
42
|
-
"red",
|
|
43
|
-
"orange",
|
|
44
|
-
"amber",
|
|
45
|
-
"yellow",
|
|
46
|
-
"lime",
|
|
47
|
-
"green",
|
|
48
|
-
"emerald",
|
|
49
|
-
"teal",
|
|
50
|
-
"cyan",
|
|
51
|
-
"sky",
|
|
52
|
-
"blue",
|
|
53
|
-
"indigo",
|
|
54
|
-
"violet",
|
|
55
|
-
"purple",
|
|
56
|
-
"fuchsia",
|
|
57
|
-
"pink",
|
|
58
|
-
"rose",
|
|
59
|
-
],
|
|
60
|
-
/* icons */
|
|
61
|
-
unselectedIcon: "close",
|
|
62
|
-
},
|
|
63
|
-
};
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getArgTypes,
|
|
3
|
-
getSlotNames,
|
|
4
|
-
getSlotsFragment,
|
|
5
|
-
getDocsDescription,
|
|
6
|
-
} from "../../utils/storybook.ts";
|
|
7
|
-
|
|
8
|
-
import UColorPicker from "../../ui.form-color-picker/UColorPicker.vue";
|
|
9
|
-
import UCol from "../../ui.container-col/UCol.vue";
|
|
10
|
-
|
|
11
|
-
import type { Meta, StoryFn } from "@storybook/vue3";
|
|
12
|
-
import type { Props } from "../types.ts";
|
|
13
|
-
|
|
14
|
-
interface UColorPickerArgs extends Props {
|
|
15
|
-
slotTemplate?: string;
|
|
16
|
-
enum: "size";
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
id: "3210",
|
|
21
|
-
title: "Form Inputs & Controls / Color Picker",
|
|
22
|
-
component: UColorPicker,
|
|
23
|
-
args: {
|
|
24
|
-
label: "Label",
|
|
25
|
-
modelValue: "",
|
|
26
|
-
},
|
|
27
|
-
argTypes: {
|
|
28
|
-
...getArgTypes(UColorPicker.__name),
|
|
29
|
-
},
|
|
30
|
-
parameters: {
|
|
31
|
-
docs: {
|
|
32
|
-
...getDocsDescription(UColorPicker.__name),
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
} as Meta;
|
|
36
|
-
|
|
37
|
-
const DefaultTemplate: StoryFn<UColorPickerArgs> = (args: UColorPickerArgs) => ({
|
|
38
|
-
components: { UColorPicker },
|
|
39
|
-
setup() {
|
|
40
|
-
const slots = getSlotNames(UColorPicker.__name);
|
|
41
|
-
|
|
42
|
-
return { args, slots };
|
|
43
|
-
},
|
|
44
|
-
template: `
|
|
45
|
-
<UColorPicker v-bind="args" v-model="args.modelValue">
|
|
46
|
-
${args.slotTemplate || getSlotsFragment("")}
|
|
47
|
-
</UColorPicker>
|
|
48
|
-
`,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const EnumVariantTemplate: StoryFn<UColorPickerArgs> = (args: UColorPickerArgs, { argTypes }) => ({
|
|
52
|
-
components: { UCol, UColorPicker },
|
|
53
|
-
setup() {
|
|
54
|
-
return {
|
|
55
|
-
args,
|
|
56
|
-
options: argTypes?.[args.enum]?.options,
|
|
57
|
-
};
|
|
58
|
-
},
|
|
59
|
-
template: `
|
|
60
|
-
<UCol>
|
|
61
|
-
<UColorPicker
|
|
62
|
-
v-for="(option, index) in options"
|
|
63
|
-
:key="index"
|
|
64
|
-
v-bind="args"
|
|
65
|
-
v-model="args.modelValue"
|
|
66
|
-
:[args.enum]="option"
|
|
67
|
-
:name="option"
|
|
68
|
-
/>
|
|
69
|
-
</UCol>
|
|
70
|
-
`,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
export const Default = DefaultTemplate.bind({});
|
|
74
|
-
Default.args = { name: "Default" };
|
|
75
|
-
|
|
76
|
-
export const Sizes = EnumVariantTemplate.bind({});
|
|
77
|
-
Sizes.args = { name: "Sizes", enum: "size" };
|
|
78
|
-
|
|
79
|
-
export const Description = DefaultTemplate.bind({});
|
|
80
|
-
Description.args = { name: "Description", description: "Description" };
|
|
81
|
-
|
|
82
|
-
export const Error = DefaultTemplate.bind({});
|
|
83
|
-
Error.args = { name: "Error", error: "some error" };
|
|
84
|
-
|
|
85
|
-
export const Disabled = DefaultTemplate.bind({});
|
|
86
|
-
Disabled.args = { name: "Disabled", disabled: true };
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import defaultConfig from "./config.ts";
|
|
2
|
-
|
|
3
|
-
import type { BrandColors, ComponentConfig } from "../types.ts";
|
|
4
|
-
|
|
5
|
-
export type Config = typeof defaultConfig;
|
|
6
|
-
|
|
7
|
-
export interface Props {
|
|
8
|
-
/**
|
|
9
|
-
* Color picker selected value.
|
|
10
|
-
*/
|
|
11
|
-
modelValue?: string;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Color picker name.
|
|
15
|
-
*/
|
|
16
|
-
name?: string;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Color picker label.
|
|
20
|
-
*/
|
|
21
|
-
label?: string;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Color picker description.
|
|
25
|
-
*/
|
|
26
|
-
description?: string;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Error message.
|
|
30
|
-
*/
|
|
31
|
-
error?: string;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Color picker size.
|
|
35
|
-
*/
|
|
36
|
-
size?: "sm" | "md" | "lg";
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Color picker color list.
|
|
40
|
-
*/
|
|
41
|
-
colorOptions?: BrandColors[];
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Set color picker disabled.
|
|
45
|
-
*/
|
|
46
|
-
disabled?: boolean;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Unique element id.
|
|
50
|
-
*/
|
|
51
|
-
id?: string;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Component config object.
|
|
55
|
-
*/
|
|
56
|
-
config?: ComponentConfig<Config>;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Data-test attribute for automated testing.
|
|
60
|
-
*/
|
|
61
|
-
dataTest?: string;
|
|
62
|
-
}
|
|
File without changes
|