vueless 1.3.1-beta.0 → 1.3.1

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": "1.3.1-beta.0",
3
+ "version": "1.3.1",
4
4
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
5
5
  "author": "Johnny Grid <hello@vueless.com> (https://vueless.com)",
6
6
  "homepage": "https://vueless.com",
@@ -7,6 +7,7 @@ export default /*tw*/ {
7
7
  outlined: "bg-default border-muted",
8
8
  subtle: "bg-muted border-default/50",
9
9
  soft: "bg-muted border-transparent",
10
+ inverted: "bg-inverted border-transparent",
10
11
  },
11
12
  },
12
13
  },
@@ -23,6 +24,7 @@ export default /*tw*/ {
23
24
  outlined: "border-muted",
24
25
  subtle: "border-default/50",
25
26
  soft: "border-default/50",
27
+ inverted: "border-default/50",
26
28
  },
27
29
  },
28
30
  },
@@ -17,7 +17,7 @@ export interface Props {
17
17
  /**
18
18
  * Card variant.
19
19
  */
20
- variant?: "solid" | "outlined" | "subtle" | "soft";
20
+ variant?: "solid" | "outlined" | "subtle" | "soft" | "inverted";
21
21
 
22
22
  /**
23
23
  * Component config object.
@@ -314,9 +314,9 @@ const {
314
314
  <!-- @slot Use it to add something before the header title. -->
315
315
  <slot name="before-title" />
316
316
  <!--
317
- @slot Use it to add something to the left side of the header.
318
- @binding {string} title
319
- -->
317
+ @slot Use it to add something to the left side of the header.
318
+ @binding {string} title
319
+ -->
320
320
  <slot name="title" :title="title">
321
321
  <div v-bind="titleFallbackAttrs">
322
322
  <UHeader :label="title" size="sm" v-bind="titleAttrs" />
@@ -86,6 +86,7 @@ export default /*tw*/ {
86
86
  outlined: "bg-default border-muted",
87
87
  subtle: "bg-muted border-default/50",
88
88
  soft: "bg-muted border-transparent",
89
+ inverted: "bg-inverted border-transparent",
89
90
  },
90
91
  position: {
91
92
  top: "top-0 flex-col rounded-b-large w-full h-auto",
@@ -28,7 +28,7 @@ export interface Props {
28
28
  /**
29
29
  * Drawer variant.
30
30
  */
31
- variant?: "solid" | "outlined" | "subtle" | "soft";
31
+ variant?: "solid" | "outlined" | "subtle" | "soft" | "inverted";
32
32
 
33
33
  /**
34
34
  * Control whether the Drawer has a handle or not.
@@ -268,10 +268,10 @@ const {
268
268
  </div>
269
269
 
270
270
  <!--
271
- @slot Use it to add something instead of the close button.
272
- @binding {string} icon-name
273
- @binding {function} close
274
- -->
271
+ @slot Use it to add something instead of the close button.
272
+ @binding {string} icon-name
273
+ @binding {function} close
274
+ -->
275
275
  <slot name="actions" :icon-name="config.defaults.closeIcon" :close="closeModal">
276
276
  <UButton
277
277
  v-if="closeOnCross"
@@ -46,7 +46,7 @@ export default /*tw*/ {
46
46
  },
47
47
  },
48
48
  compoundVariants: [
49
- { divided: true, variant: ["subtle", "soft"], class: "border-default/50" },
49
+ { divided: true, variant: ["subtle", "soft", "inverted"], class: "border-default/50" },
50
50
  { divided: true, variant: ["solid", "outlined"], class: "border-muted" },
51
51
  ],
52
52
  },
@@ -60,6 +60,7 @@ export default /*tw*/ {
60
60
  outlined: "bg-default border-muted",
61
61
  subtle: "bg-muted border-default/50",
62
62
  soft: "bg-muted border-transparent",
63
+ inverted: "bg-inverted border-transparent",
63
64
  },
64
65
  size: {
65
66
  xs: "md:w-[25rem]",
@@ -25,7 +25,7 @@ export interface Props {
25
25
  /**
26
26
  * Modal variant.
27
27
  */
28
- variant?: "solid" | "outlined" | "subtle" | "soft";
28
+ variant?: "solid" | "outlined" | "subtle" | "soft" | "inverted";
29
29
 
30
30
  /**
31
31
  * Modal size (width).
@@ -145,7 +145,7 @@ describe("UModalConfirm", () => {
145
145
 
146
146
  // Variant prop
147
147
  it("passes variant prop to UModal", () => {
148
- const variants = ["solid", "outlined", "subtle", "soft"];
148
+ const variants = ["solid", "outlined", "subtle", "soft", "inverted"];
149
149
 
150
150
  variants.forEach((variant) => {
151
151
  const component = mount(UModalConfirm, {
@@ -52,7 +52,7 @@ export interface Props {
52
52
  /**
53
53
  * Modal variant.
54
54
  */
55
- variant?: "solid" | "outlined" | "subtle" | "soft";
55
+ variant?: "solid" | "outlined" | "subtle" | "soft" | "inverted";
56
56
 
57
57
  /**
58
58
  * Modal size (width).
@@ -28,6 +28,7 @@ export default /*tw*/ {
28
28
  outlined: "bg-default border-muted",
29
29
  subtle: "bg-muted border-default/50",
30
30
  soft: "bg-muted border-transparent",
31
+ inverted: "bg-inverted border-transparent",
31
32
  },
32
33
  rounding: {
33
34
  true: "md:pr-4 border-r-0",
@@ -51,6 +52,7 @@ export default /*tw*/ {
51
52
  outlined: "bg-default border-muted",
52
53
  subtle: "bg-muted border-default/50",
53
54
  soft: "bg-muted border-transparent",
55
+ inverted: "bg-inverted border-transparent",
54
56
  },
55
57
  },
56
58
  },
@@ -37,6 +37,7 @@ describe("UPage.vue", () => {
37
37
  outlined: "bg-default border-muted",
38
38
  subtle: "bg-muted border-default/50",
39
39
  soft: "bg-muted border-transparent",
40
+ inverted: "bg-inverted border-transparent",
40
41
  };
41
42
 
42
43
  Object.entries(variants).forEach(([variant, classes]) => {
@@ -34,7 +34,7 @@ export interface Props {
34
34
  /**
35
35
  * Page variant.
36
36
  */
37
- variant?: "solid" | "outlined" | "subtle" | "soft";
37
+ variant?: "solid" | "outlined" | "subtle" | "soft" | "inverted";
38
38
 
39
39
  /**
40
40
  * Page size (width).
@@ -176,7 +176,9 @@ function onKeydown(event: KeyboardEvent) {
176
176
  emit("keydown", event);
177
177
  }
178
178
 
179
- function onSlotClick() {
179
+ function onSlotClick(event: MouseEvent) {
180
+ if (event.target !== event.currentTarget) return;
181
+
180
182
  inputRef.value?.focus();
181
183
  }
182
184
 
@@ -193,9 +193,9 @@ export const Slots: StoryFn<UInputArgs> = (args) => ({
193
193
  components: { UInput, URow, UDropdownButton, UText, UChip },
194
194
  setup() {
195
195
  const countryCodes = [
196
- { label: "+33", id: "+33" },
197
- { label: "+44", id: "+44" },
198
- { label: "+49", id: "+49" },
196
+ { label: "+33", value: "+33" },
197
+ { label: "+44", value: "+44" },
198
+ { label: "+49", value: "+49" },
199
199
  ];
200
200
 
201
201
  const countryCode = ref("+33");
@@ -1,5 +1,4 @@
1
1
  <script setup lang="ts">
2
- import { computed } from "vue";
3
2
  import { useUI } from "../composables/useUI";
4
3
  import { getDefaults } from "../utils/ui";
5
4
 
@@ -10,14 +9,15 @@ import type { Props, Config } from "./types";
10
9
 
11
10
  defineOptions({ inheritAttrs: false });
12
11
 
13
- const props = withDefaults(defineProps<Props>(), {
12
+ withDefaults(defineProps<Props>(), {
14
13
  ...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
15
14
  });
16
15
 
17
- const { getDataTest, bodyAttrs } = useUI<Config>(
18
- defaultConfig,
19
- computed(() => props),
20
- );
16
+ /**
17
+ * Get element / nested component attributes for each config token ✨
18
+ * Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
19
+ */
20
+ const { getDataTest, bodyAttrs } = useUI<Config>(defaultConfig);
21
21
  </script>
22
22
 
23
23
  <template>
@@ -1,5 +1,4 @@
1
1
  <script setup lang="ts">
2
- import { computed } from "vue";
3
2
  import { useUI } from "../composables/useUI";
4
3
  import { getDefaults } from "../utils/ui";
5
4
 
@@ -12,14 +11,15 @@ import USkeleton from "../ui.skeleton/USkeleton.vue";
12
11
 
13
12
  defineOptions({ inheritAttrs: false });
14
13
 
15
- const props = withDefaults(defineProps<Props>(), {
14
+ withDefaults(defineProps<Props>(), {
16
15
  ...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
17
16
  });
18
17
 
19
- const { getDataTest, inputAttrs, labelAttrs, wrapperAttrs } = useUI<Config>(
20
- defaultConfig,
21
- computed(() => props),
22
- );
18
+ /**
19
+ * Get element / nested component attributes for each config token ✨
20
+ * Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
21
+ */
22
+ const { getDataTest, inputAttrs, labelAttrs, wrapperAttrs } = useUI<Config>(defaultConfig);
23
23
  </script>
24
24
 
25
25
  <template>
@@ -1,5 +1,4 @@
1
1
  <script setup lang="ts">
2
- import { computed } from "vue";
3
2
  import { useUI } from "../composables/useUI";
4
3
  import { getDefaults } from "../utils/ui";
5
4
 
@@ -12,24 +11,26 @@ import USkeleton from "../ui.skeleton/USkeleton.vue";
12
11
 
13
12
  defineOptions({ inheritAttrs: false });
14
13
 
15
- const props = withDefaults(defineProps<Props>(), {
14
+ withDefaults(defineProps<Props>(), {
16
15
  ...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
17
16
  });
18
17
 
19
- const { getDataTest, inputAttrs, textareaAttrs, labelAttrs, wrapperAttrs } = useUI<Config>(
20
- defaultConfig,
21
- computed(() => props),
22
- );
18
+ /**
19
+ * Get element / nested component attributes for each config token ✨
20
+ * Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
21
+ */
22
+ const { getDataTest, inputAttrs, textareaAttrs, labelAttrs, wrapperAttrs } =
23
+ useUI<Config>(defaultConfig);
23
24
  </script>
24
25
 
25
26
  <template>
26
27
  <div v-bind="wrapperAttrs" :data-test="getDataTest()">
27
28
  <!-- @slot Use it to customize the label skeleton. -->
28
- <slot v-if="props.labelAlign !== LABEL_ALIGN.topInside && props.label" name="label">
29
+ <slot v-if="labelAlign !== LABEL_ALIGN.topInside && label" name="label">
29
30
  <USkeleton :variant="variant" v-bind="labelAttrs" />
30
31
  </slot>
31
32
 
32
- <USkeleton v-if="props.type === 'input'" :variant="variant" v-bind="inputAttrs">
33
+ <USkeleton v-if="type === 'input'" :variant="variant" v-bind="inputAttrs">
33
34
  <!-- @slot Use it to add custom content inside the input skeleton. -->
34
35
  <slot />
35
36
  </USkeleton>
@@ -1,5 +1,4 @@
1
1
  <script setup lang="ts">
2
- import { computed } from "vue";
3
2
  import { useUI } from "../composables/useUI";
4
3
  import { getDefaults } from "../utils/ui";
5
4
 
@@ -12,15 +11,16 @@ import USkeleton from "../ui.skeleton/USkeleton.vue";
12
11
 
13
12
  defineOptions({ inheritAttrs: false });
14
13
 
15
- const props = withDefaults(defineProps<Props>(), {
14
+ withDefaults(defineProps<Props>(), {
16
15
  ...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
17
16
  });
18
17
 
18
+ /**
19
+ * Get element / nested component attributes for each config token ✨
20
+ * Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
21
+ */
19
22
  const { getDataTest, wrapperAttrs, headerAttrs, textAttrs, headerWrapperAttrs, textWrapperAttrs } =
20
- useUI<Config>(
21
- defaultConfig,
22
- computed(() => props),
23
- );
23
+ useUI<Config>(defaultConfig);
24
24
  </script>
25
25
 
26
26
  <template>
@@ -14,9 +14,10 @@ export default /*tw*/ {
14
14
  "2xl": "h-11.5",
15
15
  },
16
16
  },
17
+ compoundVariants: [{ textLines: 0, headerLines: 1, class: "last:max-w-full" }],
17
18
  },
18
19
  text: {
19
- base: "{USkeleton} rounded-small last:max-w-4/5",
20
+ base: "{USkeleton} rounded-small only:max-w-full last:max-w-4/5",
20
21
  variants: {
21
22
  size: {
22
23
  xs: "h-3.5",
@@ -15,28 +15,28 @@ withDefaults(defineProps<Props>(), {
15
15
  ...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
16
16
  });
17
17
 
18
- const wrapperRef = useTemplateRef<HTMLDivElement>("wrapper");
18
+ const textRef = useTemplateRef<HTMLElement>("text");
19
19
 
20
20
  defineExpose({
21
21
  /**
22
22
  * A reference to the component's wrapper element for direct DOM manipulation.
23
- * @property {HTMLDivElement}
23
+ * @property {HTMLElement}
24
24
  */
25
- wrapperRef,
25
+ textRef,
26
26
  });
27
27
 
28
28
  /**
29
29
  * Get element / nested component attributes for each config token ✨
30
30
  * Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
31
31
  */
32
- const { getDataTest, wrapperAttrs, labelAttrs } = useUI<Config>(defaultConfig);
32
+ const { getDataTest, textAttrs } = useUI<Config>(defaultConfig);
33
33
  </script>
34
34
 
35
35
  <template>
36
- <div ref="wrapper" v-bind="wrapperAttrs" :data-test="getDataTest()">
36
+ <component :is="tag" ref="text" v-bind="textAttrs" :data-test="getDataTest()">
37
37
  <!-- @slot Use it to add something inside. -->
38
38
  <slot>
39
- <div v-bind="labelAttrs" v-text="label" />
39
+ {{ label }}
40
40
  </slot>
41
- </div>
41
+ </component>
42
42
  </template>
@@ -1,7 +1,6 @@
1
1
  export default /*tw*/ {
2
- wrapper: {
2
+ text: {
3
3
  base: `
4
- flex flex-col
5
4
  font-normal leading-normal
6
5
  [&_b]:font-bold [&_i]:italic [&_p]:font-normal
7
6
  [&_a:not([class])]:underline [&_a:not([class])]:underline-offset-4
@@ -18,15 +17,16 @@ export default /*tw*/ {
18
17
  lifted: "text-{color}-lifted",
19
18
  accented: "text-{color}-accented",
20
19
  muted: "text-{color}/(--vl-disabled-opacity)",
20
+ inverted: "text-{color} brightness-125 dark:brightness-75",
21
21
  },
22
22
  color: {
23
23
  inherit: "text-inherit",
24
24
  },
25
25
  size: {
26
- xs: "text-tiny gap-1",
27
- sm: "text-small gap-2",
28
- md: "text-medium gap-3",
29
- lg: "text-large gap-4",
26
+ xs: "text-tiny",
27
+ sm: "text-small",
28
+ md: "text-medium",
29
+ lg: "text-large",
30
30
  },
31
31
  align: {
32
32
  left: "text-left",
@@ -52,15 +52,16 @@ export default /*tw*/ {
52
52
  { color: "text", variant: "lifted", class: "text-lifted" },
53
53
  { color: "text", variant: "accented", class: "text-accented" },
54
54
  { color: "text", variant: "muted", class: "text-muted" },
55
+ { color: "text", variant: "inverted", class: "text-inverted brightness-100 dark:brightness-100" },
55
56
  ],
56
57
  },
57
- label: "",
58
58
  defaults: {
59
59
  color: "text",
60
60
  variant: "default",
61
61
  size: "md",
62
62
  align: "left",
63
63
  weight: "normal",
64
+ tag: "div",
64
65
  line: false,
65
66
  wrap: true,
66
67
  },
@@ -114,6 +114,19 @@ export const Line: StoryFn<UTextArgs> = (args: UTextArgs) => ({
114
114
  });
115
115
  Line.args = {};
116
116
 
117
+ export const Tag: StoryFn<UTextArgs> = (args: UTextArgs) => ({
118
+ components: { UText, UCol },
119
+ setup: () => ({ args }),
120
+ template: `
121
+ <UCol>
122
+ <UText tag="p" label="This is a paragraph tag" />
123
+ <UText tag="span" label="This is a span tag" />
124
+ <UText tag="div" label="This is a div tag (default)" />
125
+ </UCol>
126
+ `,
127
+ });
128
+ Tag.args = {};
129
+
117
130
  export const Wrap: StoryFn<UTextArgs> = (args: UTextArgs) => ({
118
131
  components: { UText, UCol },
119
132
  setup: () => ({ args }),
@@ -135,31 +148,6 @@ export const Wrap: StoryFn<UTextArgs> = (args: UTextArgs) => ({
135
148
  });
136
149
  Wrap.args = {};
137
150
 
138
- export const Paragraphs = DefaultTemplate.bind({});
139
- Paragraphs.args = {
140
- slotTemplate: `
141
- <template #default>
142
- <p>
143
- In a world where technology evolves at an unprecedented pace, staying
144
- updated with the latest advancements is crucial for success. Companies
145
- that adapt quickly to new trends often find themselves at the forefront
146
- of their industries, leading to increased innovation and productivity.
147
- However, it's not just about adopting new tools but also about integrating
148
- them seamlessly into existing workflows to maximize their potential.
149
- </p>
150
-
151
- <p>
152
- Employees must be encouraged to continuously learn and develop new skills,
153
- ensuring they can leverage these technological advancements effectively.
154
- This not only enhances their professional growth but also contributes to
155
- the overall success of the organization. By fostering a culture of
156
- continuous improvement, businesses can navigate the challenges of a
157
- rapidly changing landscape and emerge stronger and more competitive.
158
- </p>
159
- </template>
160
- `,
161
- };
162
-
163
151
  export const List = DefaultTemplate.bind({});
164
152
  List.args = {
165
153
  slotTemplate: `
@@ -136,6 +136,20 @@ describe("UText.vue", () => {
136
136
  expect(component.html()).toContain(label);
137
137
  });
138
138
 
139
+ it("renders the correct HTML tag", () => {
140
+ const tags = ["div", "p", "span", "section", "article"];
141
+
142
+ tags.forEach((tag) => {
143
+ const component = mount(UText, {
144
+ props: {
145
+ tag,
146
+ },
147
+ });
148
+
149
+ expect(component.element.tagName.toLowerCase()).toBe(tag);
150
+ });
151
+ });
152
+
139
153
  // DataTest prop
140
154
  it("applies the correct data-test attribute", () => {
141
155
  const dataTest = "test-text";
@@ -205,7 +219,7 @@ describe("UText.vue", () => {
205
219
  it("exposes wrapperRef", () => {
206
220
  const component = mount(UText, {});
207
221
 
208
- expect(component.vm.wrapperRef).toBeDefined();
222
+ expect(component.vm.textRef).toBeDefined();
209
223
  });
210
224
  });
211
225
  });
@@ -22,7 +22,7 @@ export interface Props {
22
22
  /**
23
23
  * Text variant.
24
24
  */
25
- variant?: "default" | "accented" | "lifted" | "muted";
25
+ variant?: "default" | "accented" | "lifted" | "muted" | "inverted";
26
26
 
27
27
  /**
28
28
  * Font weight.
@@ -45,6 +45,11 @@ export interface Props {
45
45
  | "grayscale"
46
46
  | "inherit";
47
47
 
48
+ /**
49
+ * Allows changing HTML tag.
50
+ */
51
+ tag?: string;
52
+
48
53
  /**
49
54
  * Removes text line height (useful for 1-line text).
50
55
  */
@@ -6,6 +6,7 @@ export default /*tw*/ {
6
6
  lifted: "text-{color}-lifted",
7
7
  accented: "text-{color}-accented",
8
8
  muted: "text-{color}/(--vl-disabled-opacity)",
9
+ inverted: "text-{color} brightness-125 dark:brightness-75",
9
10
  },
10
11
  color: {
11
12
  inherit: "text-inherit",
@@ -34,6 +35,7 @@ export default /*tw*/ {
34
35
  { color: "text", variant: "lifted", class: "text-lifted" },
35
36
  { color: "text", variant: "accented", class: "text-accented" },
36
37
  { color: "text", variant: "muted", class: "text-muted" },
38
+ { color: "text", variant: "inverted", class: "text-inverted brightness-100 dark:brightness-100" },
37
39
  ],
38
40
  },
39
41
  defaults: {