vueless 0.0.685 → 0.0.687
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/package.json +1 -1
- package/ui.dropdown-badge/UDropdownBadge.vue +1 -0
- package/ui.dropdown-button/UDropdownButton.vue +1 -0
- package/ui.dropdown-button/config.ts +1 -1
- package/ui.dropdown-link/UDropdownLink.vue +1 -0
- package/ui.dropdown-list/UDropdownList.vue +9 -2
- package/ui.dropdown-list/config.ts +6 -4
- package/ui.dropdown-list/storybook/docs.mdx +19 -1
- package/ui.dropdown-list/storybook/stories.ts +84 -14
- package/ui.dropdown-list/types.ts +26 -0
- package/utils/node/loaderIcon.js +1 -1
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import { isMac } from "../utils/platform.ts";
|
|
|
8
8
|
|
|
9
9
|
import UIcon from "../ui.image-icon/UIcon.vue";
|
|
10
10
|
import UButton from "../ui.button/UButton.vue";
|
|
11
|
+
import UDivider from "../ui.container-divider/UDivider.vue";
|
|
11
12
|
|
|
12
13
|
import usePointer from "./usePointer.ts";
|
|
13
14
|
import { useLocale } from "../composables/useLocale.ts";
|
|
@@ -136,7 +137,7 @@ function onClickAddOption() {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
function isMetaKey(key: string) {
|
|
139
|
-
return ["isSubGroup", "groupLabel", "level", "isHidden", "onClick"].includes(key);
|
|
140
|
+
return ["isSubGroup", "groupLabel", "level", "isHidden", "onClick", "divider"].includes(key);
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
function select(option: Option, keyCode?: string) {
|
|
@@ -261,6 +262,7 @@ const {
|
|
|
261
262
|
subGroupAttrs,
|
|
262
263
|
groupAttrs,
|
|
263
264
|
optionContentAttrs,
|
|
265
|
+
optionDividerAttrs,
|
|
264
266
|
} = useUI<Config>(defaultConfig);
|
|
265
267
|
</script>
|
|
266
268
|
|
|
@@ -285,9 +287,14 @@ const {
|
|
|
285
287
|
:role="!(option && option.groupLabel) ? 'option' : undefined"
|
|
286
288
|
:data-group-label="Boolean(option.groupLabel)"
|
|
287
289
|
>
|
|
290
|
+
<UDivider v-if="option.divider" padding="none" v-bind="optionDividerAttrs" />
|
|
288
291
|
<!-- option title -->
|
|
289
292
|
<span
|
|
290
|
-
v-if="
|
|
293
|
+
v-if="
|
|
294
|
+
!(option && (option.groupLabel || option.isSubGroup)) &&
|
|
295
|
+
!option.isHidden &&
|
|
296
|
+
!option.divider
|
|
297
|
+
"
|
|
291
298
|
v-bind="isSelectedOption(option) ? optionActiveAttrs : optionAttrs"
|
|
292
299
|
:data-test="`${dataTest}-option`"
|
|
293
300
|
:class="optionHighlight(index, option)"
|
|
@@ -11,7 +11,7 @@ export default /*tw*/ {
|
|
|
11
11
|
base: `
|
|
12
12
|
rounded-dynamic-sm px-2 py-2.5 flex items-center align-middle whitespace-nowrap cursor-pointer
|
|
13
13
|
font-normal !leading-none text-gray-900
|
|
14
|
-
hover:bg-
|
|
14
|
+
hover:bg-{color}-50 active:bg-{color}-100
|
|
15
15
|
overflow-hidden text-ellipsis
|
|
16
16
|
`,
|
|
17
17
|
variants: {
|
|
@@ -21,12 +21,12 @@ export default /*tw*/ {
|
|
|
21
21
|
lg: "text-base",
|
|
22
22
|
},
|
|
23
23
|
disabled: {
|
|
24
|
-
true: "pointer-events-none",
|
|
24
|
+
true: "pointer-events-none text-gray-400",
|
|
25
25
|
},
|
|
26
26
|
},
|
|
27
27
|
},
|
|
28
|
-
optionActive: "{>option} font-semibold bg-
|
|
29
|
-
optionHighlighted: "bg-
|
|
28
|
+
optionActive: "{>option} font-semibold bg-{color}-100 hover:bg-{color}-100 text-brand-600",
|
|
29
|
+
optionHighlighted: "bg-{color}-50",
|
|
30
30
|
optionContent: "overflow-visible text-ellipsis",
|
|
31
31
|
groupBase: {
|
|
32
32
|
base: "px-2 pb-2.5 font-medium !leading-none text-gray-400 overflow-hidden text-ellipsis",
|
|
@@ -50,11 +50,13 @@ export default /*tw*/ {
|
|
|
50
50
|
addOptionLabelHotkey: "text-gray-500",
|
|
51
51
|
addOptionButton: "{UButton} !leading-none sticky left-[calc(100%-2.15rem)] bottom-2 p-1",
|
|
52
52
|
addOptionIcon: "{UIcon} bg-transparent",
|
|
53
|
+
optionDivider: "{UDivider}",
|
|
53
54
|
i18n: {
|
|
54
55
|
noDataToShow: "No data to show.",
|
|
55
56
|
add: "Add",
|
|
56
57
|
},
|
|
57
58
|
defaults: {
|
|
59
|
+
color: "brand",
|
|
58
60
|
size: "md",
|
|
59
61
|
labelKey: "label",
|
|
60
62
|
valueKey: "id",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
|
|
1
|
+
import { Markdown, Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
|
|
2
2
|
import { getSource } from "../../utils/storybook.ts";
|
|
3
3
|
|
|
4
4
|
import * as stories from "./stories.ts";
|
|
@@ -12,5 +12,23 @@ import defaultConfig from "../config.ts?raw"
|
|
|
12
12
|
<Controls of={stories.Default} />
|
|
13
13
|
<Stories of={stories} />
|
|
14
14
|
|
|
15
|
+
## Row meta keys
|
|
16
|
+
Keys you may/have to provide to component in an option object.
|
|
17
|
+
|
|
18
|
+
<Markdown>
|
|
19
|
+
{`
|
|
20
|
+
| Key name | Description | Type |
|
|
21
|
+
| ------------------| ---------------------------------- | ---------------|
|
|
22
|
+
| id | A unique identifier for option | String, Number |
|
|
23
|
+
| label | Option label | String |
|
|
24
|
+
| isHidden | Indicates if option is hidden | Boolean |
|
|
25
|
+
| isSubGroup | Indicates if option is subGroup | Boolean |
|
|
26
|
+
| groupLabel | Option group label | String |
|
|
27
|
+
| level | Indicates option nesting level | Number |
|
|
28
|
+
| divider | Adds divider instead of option | Boolean |
|
|
29
|
+
| onClick | Option event handler | Function |
|
|
30
|
+
`}
|
|
31
|
+
</Markdown>
|
|
32
|
+
|
|
15
33
|
## Default config
|
|
16
34
|
<Source code={getSource(defaultConfig)} language="jsx" dark />
|
|
@@ -16,7 +16,7 @@ interface DefaultUDropdownListArgs extends Props {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
interface EnumUDropdownListArgs extends DefaultUDropdownListArgs {
|
|
19
|
-
enum: keyof Pick<Props, "size">;
|
|
19
|
+
enum: keyof Pick<Props, "size" | "color">;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export default {
|
|
@@ -25,9 +25,11 @@ export default {
|
|
|
25
25
|
component: UDropdownList,
|
|
26
26
|
args: {
|
|
27
27
|
options: [
|
|
28
|
-
{ label: "
|
|
29
|
-
{ label: "
|
|
30
|
-
{ label: "
|
|
28
|
+
{ label: "New York", id: "1" },
|
|
29
|
+
{ label: "Los Angeles", id: "2" },
|
|
30
|
+
{ label: "Chicago", id: "3" },
|
|
31
|
+
{ label: "Houston", id: "4" },
|
|
32
|
+
{ label: "San Francisco", id: "5" },
|
|
31
33
|
],
|
|
32
34
|
},
|
|
33
35
|
argTypes: {
|
|
@@ -37,7 +39,7 @@ export default {
|
|
|
37
39
|
docs: {
|
|
38
40
|
...getDocsDescription(UDropdownList.__name),
|
|
39
41
|
story: {
|
|
40
|
-
height: "
|
|
42
|
+
height: "250px",
|
|
41
43
|
},
|
|
42
44
|
},
|
|
43
45
|
},
|
|
@@ -48,10 +50,16 @@ const DefaultTemplate: StoryFn<DefaultUDropdownListArgs> = (args: DefaultUDropdo
|
|
|
48
50
|
setup() {
|
|
49
51
|
const slots = getSlotNames(UDropdownList.__name);
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
const showAlert = (message: string) => alert(message);
|
|
54
|
+
|
|
55
|
+
return { args, slots, showAlert };
|
|
52
56
|
},
|
|
53
57
|
template: `
|
|
54
|
-
<UDropdownList
|
|
58
|
+
<UDropdownList
|
|
59
|
+
v-bind="args"
|
|
60
|
+
class="mx-4 w-[24rem]"
|
|
61
|
+
@add="showAlert('You triggered the add action!')"
|
|
62
|
+
>
|
|
55
63
|
${args.slotTemplate || getSlotsFragment("")}
|
|
56
64
|
</UDropdownList>
|
|
57
65
|
`,
|
|
@@ -69,27 +77,51 @@ const EnumVariantTemplate: StoryFn<EnumUDropdownListArgs> = (
|
|
|
69
77
|
};
|
|
70
78
|
},
|
|
71
79
|
template: `
|
|
72
|
-
|
|
73
|
-
<URow>
|
|
80
|
+
<URow class="w-fit">
|
|
74
81
|
<UDropdownList
|
|
75
82
|
v-for="(option, index) in options"
|
|
76
83
|
:key="index"
|
|
77
84
|
v-bind="args"
|
|
78
85
|
:[args.enum]="option"
|
|
86
|
+
class="static w-36"
|
|
79
87
|
/>
|
|
80
88
|
</URow>
|
|
81
|
-
</div>
|
|
82
89
|
`,
|
|
83
90
|
});
|
|
84
91
|
|
|
85
92
|
export const Default = DefaultTemplate.bind({});
|
|
86
93
|
Default.args = {};
|
|
87
94
|
|
|
95
|
+
export const AddOption = DefaultTemplate.bind({});
|
|
96
|
+
AddOption.args = { addOption: true };
|
|
97
|
+
AddOption.parameters = {
|
|
98
|
+
docs: {
|
|
99
|
+
description: {
|
|
100
|
+
story:
|
|
101
|
+
// eslint-disable-next-line vue/max-len
|
|
102
|
+
"The `addOption` prop displays an 'Add option' button, while the `add` event allows handling custom functionality when the button is clicked.",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
88
107
|
export const Sizes = EnumVariantTemplate.bind({});
|
|
89
108
|
Sizes.args = { enum: "size" };
|
|
90
109
|
|
|
110
|
+
export const Colors = EnumVariantTemplate.bind({});
|
|
111
|
+
Colors.args = { enum: "color", modelValue: "2" };
|
|
112
|
+
|
|
91
113
|
export const VisibleOptions = DefaultTemplate.bind({});
|
|
92
114
|
VisibleOptions.args = { visibleOptions: 3 };
|
|
115
|
+
VisibleOptions.parameters = {
|
|
116
|
+
docs: {
|
|
117
|
+
description: {
|
|
118
|
+
story: "`visibleOptions` prop regulates number of options to show without a scroll.",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const Disabled = DefaultTemplate.bind({});
|
|
124
|
+
Disabled.args = { disabled: true };
|
|
93
125
|
|
|
94
126
|
export const WithoutOptions = DefaultTemplate.bind({});
|
|
95
127
|
WithoutOptions.args = { options: [] };
|
|
@@ -111,16 +143,54 @@ GroupedOptions.args = {
|
|
|
111
143
|
{ name: "Phoenix" },
|
|
112
144
|
],
|
|
113
145
|
};
|
|
146
|
+
GroupedOptions.parameters = {
|
|
147
|
+
docs: {
|
|
148
|
+
story: {
|
|
149
|
+
height: "500px",
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export const Divider = DefaultTemplate.bind({});
|
|
155
|
+
Divider.args = {
|
|
156
|
+
options: [
|
|
157
|
+
{ label: "North America", id: "1" },
|
|
158
|
+
{ label: "South America", id: "2" },
|
|
159
|
+
{ divider: true },
|
|
160
|
+
{ label: "Europe", id: "3" },
|
|
161
|
+
{ divider: true },
|
|
162
|
+
{ label: "Asia", id: "4" },
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
Divider.parameters = {
|
|
166
|
+
docs: {
|
|
167
|
+
description: {
|
|
168
|
+
story:
|
|
169
|
+
// eslint-disable-next-line vue/max-len
|
|
170
|
+
"In addition to grouping options, you can insert a divider between specific items by adding an object with a single `divider: true` property.",
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
};
|
|
114
174
|
|
|
115
175
|
export const OptionSettings = DefaultTemplate.bind({});
|
|
116
176
|
OptionSettings.args = {
|
|
117
177
|
options: [
|
|
118
|
-
{ label: "
|
|
119
|
-
{ label: "
|
|
178
|
+
{ label: "New York", id: "1" },
|
|
179
|
+
{ label: "Los Angeles", id: "2", isHidden: true },
|
|
120
180
|
{
|
|
121
|
-
label: "
|
|
181
|
+
label: "Chicago",
|
|
122
182
|
id: "3",
|
|
123
|
-
onClick: (option: Option) =>
|
|
183
|
+
onClick: (option: Option) =>
|
|
184
|
+
alert("onClick function for the third option: " + JSON.stringify(option)),
|
|
124
185
|
},
|
|
125
186
|
],
|
|
126
187
|
};
|
|
188
|
+
OptionSettings.parameters = {
|
|
189
|
+
docs: {
|
|
190
|
+
description: {
|
|
191
|
+
story:
|
|
192
|
+
// eslint-disable-next-line vue/max-len
|
|
193
|
+
"The second option of the array is hidden (`isHidden` object property is set to `true`). <br/> The third option has `onClick` event handler: <br/> `onClick: (option: Option) => alert('onClick function for option 3: ' + JSON.stringify(option))`",
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
};
|
|
@@ -47,6 +47,32 @@ export interface Props {
|
|
|
47
47
|
*/
|
|
48
48
|
size?: "sm" | "md" | "lg";
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Option highlight color.
|
|
52
|
+
*/
|
|
53
|
+
color?:
|
|
54
|
+
| "grayscale"
|
|
55
|
+
| "red"
|
|
56
|
+
| "orange"
|
|
57
|
+
| "amber"
|
|
58
|
+
| "yellow"
|
|
59
|
+
| "lime"
|
|
60
|
+
| "green"
|
|
61
|
+
| "emerald"
|
|
62
|
+
| "teal"
|
|
63
|
+
| "cyan"
|
|
64
|
+
| "sky"
|
|
65
|
+
| "blue"
|
|
66
|
+
| "indigo"
|
|
67
|
+
| "violet"
|
|
68
|
+
| "purple"
|
|
69
|
+
| "fuchsia"
|
|
70
|
+
| "pink"
|
|
71
|
+
| "rose"
|
|
72
|
+
| "gray"
|
|
73
|
+
| "white"
|
|
74
|
+
| "brand";
|
|
75
|
+
|
|
50
76
|
/**
|
|
51
77
|
* Number of options to show without a scroll.
|
|
52
78
|
*/
|
package/utils/node/loaderIcon.js
CHANGED
|
@@ -189,7 +189,7 @@ async function findAndCopyIcons(files) {
|
|
|
189
189
|
const iconName = groupMatch ? groupMatch[3] : null;
|
|
190
190
|
|
|
191
191
|
try {
|
|
192
|
-
if (!iconName)
|
|
192
|
+
if (!iconName) continue;
|
|
193
193
|
|
|
194
194
|
if (iconName?.includes("?") && iconName?.includes(":")) {
|
|
195
195
|
const [trueName, falseName] = getTernaryValues(iconName);
|