vueless 0.0.675 → 0.0.677

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.
Files changed (89) hide show
  1. package/composables/useUI.ts +12 -1
  2. package/constants.js +1 -0
  3. package/package.json +1 -1
  4. package/types.ts +1 -1
  5. package/ui.boilerplate/types.ts +1 -1
  6. package/ui.button/UButton.vue +9 -6
  7. package/ui.button/types.ts +1 -1
  8. package/ui.button-link/ULink.vue +37 -62
  9. package/ui.button-link/config.ts +8 -35
  10. package/ui.button-link/storybook/stories.ts +0 -22
  11. package/ui.button-link/types.ts +1 -11
  12. package/ui.button-toggle/types.ts +1 -1
  13. package/ui.button-toggle-item/types.ts +1 -1
  14. package/ui.container-accordion/types.ts +1 -1
  15. package/ui.container-card/types.ts +1 -1
  16. package/ui.container-col/types.ts +1 -1
  17. package/ui.container-divider/types.ts +1 -1
  18. package/ui.container-group/types.ts +1 -1
  19. package/ui.container-groups/types.ts +1 -1
  20. package/ui.container-modal/UModal.vue +21 -20
  21. package/ui.container-modal/config.ts +3 -2
  22. package/ui.container-modal/types.ts +1 -1
  23. package/ui.container-modal-confirm/types.ts +1 -1
  24. package/ui.container-page/UPage.vue +31 -19
  25. package/ui.container-page/config.ts +1 -0
  26. package/ui.container-page/types.ts +1 -1
  27. package/ui.container-row/types.ts +1 -1
  28. package/ui.data-list/types.ts +1 -1
  29. package/ui.data-table/types.ts +1 -1
  30. package/ui.dropdown-badge/types.ts +1 -1
  31. package/ui.dropdown-button/types.ts +1 -1
  32. package/ui.dropdown-link/UDropdownLink.vue +29 -33
  33. package/ui.dropdown-link/config.ts +3 -3
  34. package/ui.dropdown-link/types.ts +1 -1
  35. package/ui.dropdown-list/types.ts +1 -1
  36. package/ui.form-calendar/types.ts +1 -1
  37. package/ui.form-checkbox/types.ts +1 -1
  38. package/ui.form-checkbox-group/types.ts +1 -1
  39. package/ui.form-checkbox-multi-state/types.ts +1 -1
  40. package/ui.form-color-picker/UColorPicker.vue +68 -0
  41. package/ui.form-color-picker/config.ts +29 -0
  42. package/ui.form-color-picker/constants.ts +5 -0
  43. package/ui.form-color-picker/storybook/docs.mdx +16 -0
  44. package/ui.form-color-picker/storybook/stories.ts +97 -0
  45. package/ui.form-color-picker/types.ts +42 -0
  46. package/ui.form-date-picker/types.ts +1 -1
  47. package/ui.form-date-picker-range/types.ts +1 -1
  48. package/ui.form-input/types.ts +1 -1
  49. package/ui.form-input-file/storybook/stories.ts +1 -1
  50. package/ui.form-input-file/types.ts +1 -1
  51. package/ui.form-input-money/types.ts +1 -1
  52. package/ui.form-input-number/types.ts +1 -1
  53. package/ui.form-input-rating/types.ts +1 -1
  54. package/ui.form-input-search/types.ts +1 -1
  55. package/ui.form-label/storybook/stories.ts +1 -1
  56. package/ui.form-label/types.ts +1 -1
  57. package/ui.form-radio/types.ts +1 -1
  58. package/ui.form-radio-group/types.ts +1 -1
  59. package/ui.form-select/USelect.vue +8 -6
  60. package/ui.form-select/types.ts +1 -1
  61. package/ui.form-switch/types.ts +1 -1
  62. package/ui.form-textarea/types.ts +1 -1
  63. package/ui.image-avatar/types.ts +1 -1
  64. package/ui.image-icon/UIcon.vue +2 -18
  65. package/ui.image-icon/storybook/stories.ts +0 -3
  66. package/ui.image-icon/types.ts +1 -13
  67. package/ui.loader/types.ts +1 -1
  68. package/ui.loader-overlay/types.ts +1 -1
  69. package/ui.loader-progress/types.ts +1 -1
  70. package/ui.navigation-pagination/types.ts +1 -1
  71. package/ui.navigation-progress/types.ts +2 -2
  72. package/ui.navigation-tab/types.ts +1 -1
  73. package/ui.navigation-tabs/types.ts +1 -1
  74. package/ui.other-dot/types.ts +1 -1
  75. package/ui.other-theme-color-toggle/UThemeColorToggle.vue +44 -70
  76. package/ui.other-theme-color-toggle/config.ts +2 -23
  77. package/ui.other-theme-color-toggle/storybook/stories.ts +6 -5
  78. package/ui.other-theme-color-toggle/types.ts +8 -3
  79. package/ui.text-alert/types.ts +1 -1
  80. package/ui.text-badge/types.ts +1 -1
  81. package/ui.text-block/types.ts +1 -1
  82. package/ui.text-empty/types.ts +1 -1
  83. package/ui.text-file/types.ts +1 -1
  84. package/ui.text-files/types.ts +1 -1
  85. package/ui.text-header/types.ts +1 -1
  86. package/ui.text-money/types.ts +1 -1
  87. package/ui.text-notify/types.ts +1 -1
  88. package/ui.text-number/types.ts +1 -1
  89. package/utils/theme.ts +8 -4
@@ -241,7 +241,18 @@ export default function useUI<T>(
241
241
  return vuelessAttrs;
242
242
  }
243
243
 
244
- return { config, getKeysAttrs, ...getKeysAttrs(mutatedProps) } as UseUI<T>;
244
+ /**
245
+ * Get data test attribute value if exist.
246
+ */
247
+ function getDataTest(suffix?: string) {
248
+ if (!props.dataTest) {
249
+ return null;
250
+ }
251
+
252
+ return suffix ? `${props.dataTest}-${suffix}` : props.dataTest;
253
+ }
254
+
255
+ return { config, getDataTest, ...getKeysAttrs(mutatedProps) } as UseUI<T>;
245
256
  }
246
257
 
247
258
  /**
package/constants.js CHANGED
@@ -107,6 +107,7 @@ export const COMPONENTS = {
107
107
  UCalendar: "ui.form-calendar",
108
108
  UDatePicker: "ui.form-date-picker",
109
109
  UDatePickerRange: "ui.form-date-picker-range",
110
+ UColorPicker: "ui.form-color-picker",
110
111
  ULabel: "ui.form-label",
111
112
 
112
113
  /* Text & Content */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.675",
3
+ "version": "0.0.677",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
6
6
  "keywords": [
package/types.ts CHANGED
@@ -297,7 +297,7 @@ export type MutatedProps = ComputedRef<UnknownObject>;
297
297
 
298
298
  export type UseUI<T> = {
299
299
  config: Ref<T & ComponentConfig<T>>;
300
- getKeysAttrs: (mutatedProps?: MutatedProps) => KeysAttrs<T>;
300
+ getDataTest: (suffix?: string) => string | null;
301
301
  } & KeysAttrs<T>;
302
302
 
303
303
  export type KeysAttrs<T> = Record<
@@ -14,5 +14,5 @@ export interface Props {
14
14
  /**
15
15
  * Data-test attribute for automated testing.
16
16
  */
17
- dataTest?: string;
17
+ dataTest?: string | null;
18
18
  }
@@ -67,10 +67,8 @@ const mutatedProps = computed(() => ({
67
67
  label: Boolean(props.label),
68
68
  }));
69
69
 
70
- const { buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs } = useUI<Config>(
71
- defaultConfig,
72
- mutatedProps,
73
- );
70
+ const { getDataTest, buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs } =
71
+ useUI<Config>(defaultConfig, mutatedProps);
74
72
  </script>
75
73
 
76
74
  <template>
@@ -82,10 +80,15 @@ const { buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs
82
80
  v-bind="buttonAttrs"
83
81
  :style="buttonStyle"
84
82
  :tabindex="!loading ? tabindex : -1"
85
- :data-test="dataTest"
83
+ :data-test="getDataTest()"
86
84
  >
87
85
  <template v-if="loading">
88
- <ULoader :loading="loading" color="inherit" v-bind="loaderAttrs" />
86
+ <ULoader
87
+ :loading="loading"
88
+ color="inherit"
89
+ v-bind="loaderAttrs"
90
+ :data-test="getDataTest('loader')"
91
+ />
89
92
  </template>
90
93
 
91
94
  <template v-else>
@@ -118,5 +118,5 @@ export interface Props {
118
118
  /**
119
119
  * Data-test attribute for automated testing.
120
120
  */
121
- dataTest?: string;
121
+ dataTest?: string | null;
122
122
  }
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, ref, useSlots } from "vue";
2
+ import { computed, useSlots } from "vue";
3
3
  import { RouterLink, useLink } from "vue-router";
4
4
 
5
5
  import useUI from "../composables/useUI.ts";
@@ -71,13 +71,6 @@ const useLinkOptions = {
71
71
 
72
72
  const { route, isActive, isExactActive } = useLink(useLinkOptions);
73
73
 
74
- const wrapperRef = ref(null);
75
-
76
- const wrapperActiveClasses = computed(() => [
77
- isActive.value && props.wrapperActiveClass,
78
- isExactActive.value && props.wrapperExactActiveClass,
79
- ]);
80
-
81
74
  const linkActiveClasses = computed(() => [
82
75
  isActive.value && props.activeClass,
83
76
  isExactActive.value && props.exactActiveClass,
@@ -117,14 +110,6 @@ function onBlur(event: FocusEvent) {
117
110
  emit("blur", event);
118
111
  }
119
112
 
120
- defineExpose({
121
- /**
122
- * A reference to the link wrapper element for direct DOM manipulation.
123
- * @property {HTMLElement}
124
- */
125
- wrapperRef,
126
- });
127
-
128
113
  /**
129
114
  * Get element / nested component attributes for each config token ✨
130
115
  * Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
@@ -134,53 +119,43 @@ const mutatedProps = computed(() => ({
134
119
  defaultSlot: hasSlotContent(slots["default"]),
135
120
  }));
136
121
 
137
- const { wrapperAttrs, linkAttrs } = useUI<Config>(defaultConfig, mutatedProps, "link");
122
+ const { getDataTest, linkAttrs } = useUI<Config>(defaultConfig, mutatedProps);
138
123
  </script>
139
124
 
140
125
  <template>
141
- <div v-bind="wrapperAttrs" ref="wrapperRef" :class="wrapperActiveClasses" tabindex="-1">
142
- <!-- @slot Use it to add something before the label. -->
143
- <slot name="left" />
144
-
145
- <router-link
146
- v-if="isPresentRoute"
147
- :to="route"
148
- :target="targetValue"
149
- v-bind="linkAttrs"
150
- :class="linkActiveClasses"
151
- :data-test="dataTest"
152
- tabindex="0"
153
- @blur="onBlur"
154
- @focus="onFocus"
155
- @click="onClick"
156
- @keydown="onKeydown"
157
- @mouseover="onMouseover"
158
- >
159
- <!-- @slot Use it replace the label. -->
160
- <slot>
161
- {{ label }}
162
- </slot>
163
- </router-link>
164
-
165
- <a
166
- v-else
167
- :href="prefixedHref"
168
- :target="targetValue"
169
- v-bind="linkAttrs"
170
- :class="linkActiveClasses"
171
- :data-test="dataTest"
172
- tabindex="0"
173
- @blur="onBlur"
174
- @focus="onFocus"
175
- @click="onClick"
176
- @keydown="onKeydown"
177
- @mouseover="onMouseover"
178
- >
179
- <!-- @slot Use it replace the label. -->
180
- <slot>{{ label }}</slot>
181
- </a>
182
-
183
- <!-- @slot Use it to add something after the label. -->
184
- <slot name="right" />
185
- </div>
126
+ <router-link
127
+ v-if="isPresentRoute"
128
+ :to="route"
129
+ :target="targetValue"
130
+ v-bind="linkAttrs"
131
+ :class="linkActiveClasses"
132
+ :data-test="getDataTest()"
133
+ tabindex="0"
134
+ @blur="onBlur"
135
+ @focus="onFocus"
136
+ @click="onClick"
137
+ @keydown="onKeydown"
138
+ @mouseover="onMouseover"
139
+ >
140
+ <!-- @slot Use it replace the label. -->
141
+ <slot>{{ label }}</slot>
142
+ </router-link>
143
+
144
+ <a
145
+ v-else
146
+ :href="prefixedHref"
147
+ :target="targetValue"
148
+ v-bind="linkAttrs"
149
+ :class="linkActiveClasses"
150
+ :data-test="getDataTest()"
151
+ tabindex="0"
152
+ @blur="onBlur"
153
+ @focus="onFocus"
154
+ @click="onClick"
155
+ @keydown="onKeydown"
156
+ @mouseover="onMouseover"
157
+ >
158
+ <!-- @slot Use it replace the label. -->
159
+ <slot>{{ label }}</slot>
160
+ </a>
186
161
  </template>
@@ -1,40 +1,12 @@
1
1
  export default /*tw*/ {
2
- wrapper: {
3
- base: `
4
- w-fit inline-flex items-center rounded transition focus-visible:outline-none
5
- focus-within:ring-dynamic focus-within:ring-offset-4 focus-within:ring-{color}-700/15
6
- `,
7
- variants: {
8
- size: {
9
- sm: "gap-1",
10
- md: "gap-1",
11
- lg: "gap-1.5",
12
- },
13
- color: {
14
- grayscale: "focus-within:ring-gray-700/15",
15
- white: "focus-within:ring-white/15",
16
- },
17
- disabled: {
18
- true: "!ring-0 !ring-offset-0 cursor-not-allowed",
19
- },
20
- defaultSlot: {
21
- true: "flex items-center focus-within:ring-0 focus-within:ring-offset-0",
22
- },
23
- ring: {
24
- false: "!ring-0 !ring-offset-0",
25
- },
26
- block: {
27
- true: "w-full",
28
- },
29
- },
30
- },
31
2
  link: {
32
3
  base: `
33
- inline-block cursor-pointer !leading-none transition
4
+ inline-block cursor-pointer !leading-none rounded transition
34
5
  text-{color}-600 decoration-{color}-600 underline-offset-4
35
6
  hover:text-{color}-700 hover:decoration-{color}-700
36
7
  focus:text-{color}-700 focus:decoration-{color}-700 focus:outline-0
37
8
  active:text-{color}-800 active:decoration-{color}-800
9
+ focus:ring-dynamic focus:ring-offset-4 focus:ring-{color}-700/15
38
10
  `,
39
11
  variants: {
40
12
  size: {
@@ -57,10 +29,10 @@ export default /*tw*/ {
57
29
  grayscale: `
58
30
  text-gray-900 decoration-gray-900
59
31
  hover:text-gray-800 hover:decoration-gray-800
60
- focus:text-gray-800 focus:decoration-gray-800
32
+ focus:text-gray-800 focus:decoration-gray-800 focus:ring-gray-700/15
61
33
  active:text-gray-700 active:decoration-gray-700
62
34
  `,
63
- white: "decoration-white text-white",
35
+ white: "decoration-white text-white focus:ring-white/15",
64
36
  },
65
37
  defaultSlot: {
66
38
  true: "flex items-center no-underline hover:no-underline",
@@ -71,6 +43,9 @@ export default /*tw*/ {
71
43
  disabled: {
72
44
  true: "text-gray-400 pointer-events-none",
73
45
  },
46
+ ring: {
47
+ false: "!ring-0 !ring-offset-0",
48
+ },
74
49
  block: {
75
50
  true: "w-full",
76
51
  },
@@ -83,11 +58,9 @@ export default /*tw*/ {
83
58
  ariaCurrentValue: "page",
84
59
  activeClass: "",
85
60
  exactActiveClass: "",
86
- wrapperActiveClass: "",
87
- wrapperExactActiveClass: "",
88
61
  underlined: undefined,
89
62
  block: false,
90
- ring: true,
63
+ ring: false,
91
64
  dashed: false,
92
65
  disabled: false,
93
66
  targetBlank: false,
@@ -196,25 +196,3 @@ DefaultSlot.args = {
196
196
  </template>
197
197
  `,
198
198
  };
199
-
200
- export const LeftAndRightSlots: StoryFn<ULinkArgs> = (args: ULinkArgs) => ({
201
- components: { ULink, UIcon, URow },
202
- setup() {
203
- return { args };
204
- },
205
- template: `
206
- <URow no-mobile>
207
- <ULink label="Download">
208
- <template #left>
209
- <UIcon name="download" size="xs" color="green" />
210
- </template>
211
- </ULink>
212
-
213
- <ULink label="Open">
214
- <template #right>
215
- <UIcon name="open_in_new" size="xs" color="green" />
216
- </template>
217
- </ULink>
218
- </URow>
219
- `,
220
- });
@@ -87,16 +87,6 @@ export interface Props {
87
87
  */
88
88
  exactActiveClass?: string;
89
89
 
90
- /**
91
- * Apply classes to the wrapper div when link route is active or when it matches any parent route.
92
- */
93
- wrapperActiveClass?: string;
94
-
95
- /**
96
- * Apply classes to the wrapper div when link route is active.
97
- */
98
- wrapperExactActiveClass?: string;
99
-
100
90
  /**
101
91
  * Show underline.
102
92
  */
@@ -130,5 +120,5 @@ export interface Props {
130
120
  /**
131
121
  * Data-test attribute for automated testing.
132
122
  */
133
- dataTest?: string;
123
+ dataTest?: string | null;
134
124
  }
@@ -94,5 +94,5 @@ export interface Props {
94
94
  /**
95
95
  * Data-test attribute for automated testing.
96
96
  */
97
- dataTest?: string;
97
+ dataTest?: string | null;
98
98
  }
@@ -56,5 +56,5 @@ export interface Props {
56
56
  /**
57
57
  * Data-test attribute for automated testing.
58
58
  */
59
- dataTest?: string;
59
+ dataTest?: string | null;
60
60
  }
@@ -32,5 +32,5 @@ export interface Props {
32
32
  /**
33
33
  * Data-test attribute for automated testing.
34
34
  */
35
- dataTest?: string;
35
+ dataTest?: string | null;
36
36
  }
@@ -22,5 +22,5 @@ export interface Props {
22
22
  /**
23
23
  * Data-test attribute for automated testing.
24
24
  */
25
- dataTest?: string;
25
+ dataTest?: string | null;
26
26
  }
@@ -52,5 +52,5 @@ export interface Props {
52
52
  /**
53
53
  * Data-test attribute for automated testing.
54
54
  */
55
- dataTest?: string;
55
+ dataTest?: string | null;
56
56
  }
@@ -53,5 +53,5 @@ export interface Props {
53
53
  /**
54
54
  * Data-test attribute for automated testing.
55
55
  */
56
- dataTest?: string;
56
+ dataTest?: string | null;
57
57
  }
@@ -28,5 +28,5 @@ export interface Props {
28
28
  /**
29
29
  * Data-test attribute for automated testing.
30
30
  */
31
- dataTest?: string;
31
+ dataTest?: string | null;
32
32
  }
@@ -18,5 +18,5 @@ export interface Props {
18
18
  /**
19
19
  * Data-test attribute for automated testing.
20
20
  */
21
- dataTest?: string;
21
+ dataTest?: string | null;
22
22
  }
@@ -32,7 +32,7 @@ const emit = defineEmits([
32
32
  "update:modelValue",
33
33
 
34
34
  /**
35
- * Triggers when back link in modal is clicked.
35
+ * Triggers when a back link is clicked.
36
36
  */
37
37
  "back",
38
38
  ]);
@@ -113,6 +113,7 @@ const {
113
113
  config,
114
114
  modalAttrs,
115
115
  titleAttrs,
116
+ backLinkWrapperAttrs,
116
117
  backLinkAttrs,
117
118
  backLinkIconAttrs,
118
119
  closeIconAttrs,
@@ -157,25 +158,25 @@ const {
157
158
  <slot name="before-title" />
158
159
 
159
160
  <div v-bind="headerLeftFallbackAttrs">
160
- <ULink
161
- v-if="isShownArrowButton"
162
- size="sm"
163
- color="gray"
164
- :to="backTo"
165
- :label="backLabel"
166
- v-bind="backLinkAttrs"
167
- @click="onClickBackLink"
168
- >
169
- <template #left>
170
- <UIcon
171
- internal
172
- size="xs"
173
- color="gray"
174
- :name="config.defaults.backIcon"
175
- v-bind="backLinkIconAttrs"
176
- />
177
- </template>
178
- </ULink>
161
+ <div v-if="isShownArrowButton" v-bind="backLinkWrapperAttrs">
162
+ <UIcon
163
+ internal
164
+ size="2xs"
165
+ color="gray"
166
+ :name="config.defaults.backIcon"
167
+ v-bind="backLinkIconAttrs"
168
+ />
169
+
170
+ <ULink
171
+ size="sm"
172
+ color="gray"
173
+ :to="backTo"
174
+ :ring="false"
175
+ :label="backLabel"
176
+ v-bind="backLinkAttrs"
177
+ @click="onClickBackLink"
178
+ />
179
+ </div>
179
180
 
180
181
  <UHeader :label="title" size="sm" v-bind="titleAttrs" />
181
182
  <div v-if="description" v-bind="descriptionAttrs" v-text="description" />
@@ -18,9 +18,10 @@ export default /*tw*/ {
18
18
  leaveToClass: "opacity-0",
19
19
  },
20
20
  innerWrapper: "py-12 w-full h-full overflow-auto",
21
- header: "flex items-center justify-between px-4 md:px-8 pb-6 pt-8",
22
- headerLeft: "flex items-center space-x-4",
21
+ header: "flex justify-between px-4 md:px-8 pb-6 pt-8",
22
+ headerLeft: "flex items-center gap-4",
23
23
  headerLeftFallback: "flex flex-col",
24
+ backLinkWrapper: "flex items-center gap-0.5 mb-0.5",
24
25
  backLink: "{ULink} flex items-center gap-0.5",
25
26
  backLinkIcon: "{UIcon}",
26
27
  title: "{UHeader}",
@@ -80,5 +80,5 @@ export interface Props {
80
80
  /**
81
81
  * Data-test attribute for automated testing.
82
82
  */
83
- dataTest?: string;
83
+ dataTest?: string | null;
84
84
  }
@@ -104,5 +104,5 @@ export interface Props {
104
104
  /**
105
105
  * Data-test attribute for automated testing.
106
106
  */
107
- dataTest?: string;
107
+ dataTest?: string | null;
108
108
  }
@@ -25,6 +25,13 @@ const props = withDefaults(defineProps<Props>(), {
25
25
  backLabel: "",
26
26
  });
27
27
 
28
+ const emit = defineEmits([
29
+ /**
30
+ * Triggers when a back link is clicked.
31
+ */
32
+ "back",
33
+ ]);
34
+
28
35
  const { isMobileBreakpoint } = useBreakpoint();
29
36
 
30
37
  const isExistHeader = computed(() => {
@@ -56,6 +63,10 @@ onMounted(() => {
56
63
  }
57
64
  });
58
65
 
66
+ function onClickBackLink() {
67
+ emit("back");
68
+ }
69
+
59
70
  /**
60
71
  * Get element / nested component attributes for each config token ✨
61
72
  * Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
@@ -66,6 +77,7 @@ const {
66
77
  pageAttrs,
67
78
  rightRoundingAttrs,
68
79
  titleAttrs,
80
+ backLinkWrapperAttrs,
69
81
  backLinkAttrs,
70
82
  backLinkIconAttrs,
71
83
  headerAttrs,
@@ -95,25 +107,25 @@ const {
95
107
  <slot name="before-title" />
96
108
 
97
109
  <div v-bind="headerLeftFallbackAttrs">
98
- <ULink
99
- v-if="isShownArrowButton"
100
- :ring="false"
101
- size="sm"
102
- color="gray"
103
- :to="backTo"
104
- :label="backLabel"
105
- v-bind="backLinkAttrs"
106
- >
107
- <template #left>
108
- <UIcon
109
- internal
110
- size="2xs"
111
- color="gray"
112
- :name="config.defaults.backIcon"
113
- v-bind="backLinkIconAttrs"
114
- />
115
- </template>
116
- </ULink>
110
+ <div v-if="isShownArrowButton" v-bind="backLinkWrapperAttrs">
111
+ <UIcon
112
+ internal
113
+ size="2xs"
114
+ color="gray"
115
+ :name="config.defaults.backIcon"
116
+ v-bind="backLinkIconAttrs"
117
+ />
118
+
119
+ <ULink
120
+ :ring="false"
121
+ size="sm"
122
+ color="gray"
123
+ :to="backTo"
124
+ :label="backLabel"
125
+ v-bind="backLinkAttrs"
126
+ @click="onClickBackLink"
127
+ />
128
+ </div>
117
129
 
118
130
  <UHeader :label="title" :size="titleSize" v-bind="titleAttrs" />
119
131
  <div v-if="description" v-bind="descriptionAttrs" v-text="description" />
@@ -32,6 +32,7 @@ export default /*tw*/ {
32
32
  header: "flex items-start justify-between mb-4 md:mb-6",
33
33
  headerLeft: "flex items-center gap-4",
34
34
  headerLeftFallback: "flex flex-col gap-0.5",
35
+ backLinkWrapper: "flex items-center gap-0.5",
35
36
  backLink: "{ULink}",
36
37
  backLinkIcon: "{UIcon}",
37
38
  title: "{UHeader}",
@@ -54,5 +54,5 @@ export interface Props {
54
54
  /**
55
55
  * Data-test attribute for automated testing.
56
56
  */
57
- dataTest?: string;
57
+ dataTest?: string | null;
58
58
  }
@@ -57,5 +57,5 @@ export interface Props {
57
57
  /**
58
58
  * Data-test attribute for automated testing.
59
59
  */
60
- dataTest?: string;
60
+ dataTest?: string | null;
61
61
  }
@@ -82,5 +82,5 @@ export interface Props {
82
82
  /**
83
83
  * Data-test attribute for automated testing.
84
84
  */
85
- dataTest?: string;
85
+ dataTest?: string | null;
86
86
  }
@@ -111,7 +111,7 @@ export interface UTableProps {
111
111
  /**
112
112
  * Data-test attribute for automated testing.
113
113
  */
114
- dataTest?: string;
114
+ dataTest?: string | null;
115
115
  }
116
116
 
117
117
  export interface UTableRowAttrs {
@@ -90,5 +90,5 @@ export interface Props {
90
90
  /**
91
91
  * Data-test attribute for automated testing.
92
92
  */
93
- dataTest?: string;
93
+ dataTest?: string | null;
94
94
  }
@@ -105,5 +105,5 @@ export interface Props {
105
105
  /**
106
106
  * Data-test attribute for automated testing.
107
107
  */
108
- dataTest?: string;
108
+ dataTest?: string | null;
109
109
  }