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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.685",
3
+ "version": "0.0.687",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
6
6
  "keywords": [
@@ -124,6 +124,7 @@ const { config, wrapperAttrs, dropdownBadgeAttrs, dropdownListAttrs, dropdownIco
124
124
  v-if="isShownOptions"
125
125
  ref="dropdown-list"
126
126
  :size="size"
127
+ :color="color"
127
128
  :options="options"
128
129
  :label-key="labelKey"
129
130
  v-bind="dropdownListAttrs"
@@ -125,6 +125,7 @@ const { config, dropdownButtonAttrs, dropdownListAttrs, dropdownIconAttrs, wrapp
125
125
  <UDropdownList
126
126
  v-if="isShownOptions"
127
127
  ref="dropdown-list"
128
+ :color="color"
128
129
  :options="options"
129
130
  :label-key="labelKey"
130
131
  v-bind="dropdownListAttrs"
@@ -38,7 +38,7 @@ export default /*tw*/ {
38
38
  size: {
39
39
  "2xs": "sm",
40
40
  xs: "sm",
41
- sm: "sm",
41
+ sm: "md",
42
42
  md: "md",
43
43
  lg: "lg",
44
44
  xl: "lg",
@@ -126,6 +126,7 @@ const { config, getDataTest, wrapperAttrs, dropdownLinkAttrs, dropdownListAttrs,
126
126
  v-if="isShownOptions"
127
127
  ref="dropdown-list"
128
128
  :size="size"
129
+ :color="color"
129
130
  :options="options"
130
131
  :label-key="labelKey"
131
132
  v-bind="dropdownListAttrs"
@@ -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="!(option && (option.groupLabel || option.isSubGroup)) && !option.isHidden"
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-brand-50 active:bg-brand-100
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-brand-100 hover:bg-brand-100 text-brand-600",
29
- optionHighlighted: "bg-brand-50",
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: "option 1", id: "1" },
29
- { label: "option 2", id: "2" },
30
- { label: "option 3", id: "3" },
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: "180px",
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
- return { args, slots };
53
+ const showAlert = (message: string) => alert(message);
54
+
55
+ return { args, slots, showAlert };
52
56
  },
53
57
  template: `
54
- <UDropdownList v-bind="args" class="mx-4 w-[24rem]">
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
- <div class="flex flex-col gap-6">
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: "option 1", id: "1" },
119
- { label: "option 2", id: "2", isHidden: true },
178
+ { label: "New York", id: "1" },
179
+ { label: "Los Angeles", id: "2", isHidden: true },
120
180
  {
121
- label: "option 3",
181
+ label: "Chicago",
122
182
  id: "3",
123
- onClick: (option: Option) => alert("onClick option 3 " + JSON.stringify(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
  */
@@ -189,7 +189,7 @@ async function findAndCopyIcons(files) {
189
189
  const iconName = groupMatch ? groupMatch[3] : null;
190
190
 
191
191
  try {
192
- if (!iconName) return;
192
+ if (!iconName) continue;
193
193
 
194
194
  if (iconName?.includes("?") && iconName?.includes(":")) {
195
195
  const [trueName, falseName] = getTernaryValues(iconName);