vueless 0.0.13 → 0.0.15

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 (45) hide show
  1. package/README.md +33 -152
  2. package/package.json +2 -5
  3. package/preset.tailwind/index.js +95 -0
  4. package/service.storybook/index.js +1 -1
  5. package/service.ui/index.js +1 -1
  6. package/ui.button/index.vue +16 -3
  7. package/ui.button-link/index.vue +6 -3
  8. package/ui.container-page/configs/default.config.js +1 -1
  9. package/ui.data-table-cell/configs/default.config.js +2 -2
  10. package/ui.dropdown-badge/index.vue +11 -1
  11. package/ui.dropdown-button/index.vue +14 -2
  12. package/ui.dropdown-link/index.vue +11 -1
  13. package/ui.form-calendar/configs/default.config.js +1 -1
  14. package/ui.form-checkbox/index.vue +1 -1
  15. package/ui.form-color-picker/index.vue +1 -1
  16. package/ui.form-date-picker-range/configs/default.config.js +4 -4
  17. package/ui.form-input/configs/default.config.js +1 -1
  18. package/ui.form-input/index.vue +5 -8
  19. package/ui.form-input-file/configs/default.config.js +1 -1
  20. package/ui.form-input-file/index.vue +4 -8
  21. package/ui.form-input-rating/configs/default.config.js +1 -1
  22. package/ui.form-input-rating/index.vue +3 -7
  23. package/ui.form-label/configs/default.config.js +2 -0
  24. package/ui.form-label/index.vue +3 -3
  25. package/ui.form-radio/index.vue +5 -3
  26. package/ui.form-radio-card/composables/attrs.composable.js +3 -1
  27. package/ui.form-radio-card/configs/default.config.js +8 -2
  28. package/ui.form-radio-card/index.vue +26 -40
  29. package/ui.form-select/configs/default.config.js +3 -3
  30. package/ui.form-select/index.vue +7 -18
  31. package/ui.form-switch/index.vue +1 -1
  32. package/ui.form-textarea/index.vue +2 -2
  33. package/ui.navigation-stepper/index.vue +1 -1
  34. package/ui.notify/index.vue +3 -3
  35. package/ui.other-loader-top/composables/attrs.composable.js +32 -0
  36. package/ui.other-loader-top/configs/default.config.js +20 -0
  37. package/ui.other-loader-top/constants/index.js +8 -0
  38. package/ui.other-loader-top/index.vue +230 -0
  39. package/ui.other-loader-top/services/loaderTop.service.js +31 -0
  40. package/ui.text-badge/index.vue +7 -0
  41. package/web-types.json +36 -132
  42. package/service.tailwind/index.js +0 -103
  43. package/ui.loader-top/components/TopProgress.vue +0 -277
  44. package/ui.loader-top/index.vue +0 -221
  45. /package/{ui.loader-top → ui.other-loader-top}/store/index.js +0 -0
package/README.md CHANGED
@@ -1,174 +1,55 @@
1
- ## How to run the project locally
1
+ ![logo.png](public/images/vueless-logo-git.png)
2
2
 
3
- - Install **node.js 16.XX** version (see [instructions](https://nodejs.org/en/download/package-manager/) for your OS).
3
+ ## Vueless UI
4
4
 
5
- - Install globally [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable):
5
+ * [Documentation](https://docs.vueless.com/)
6
+ * [UI Components](https://ui.vueless.com/)
7
+ * [Website](http://vueless.com/)
6
8
 
7
- ```bash
8
- npm install --global yarn
9
- ```
10
-
11
- - Create project folder and clone files from Git into:
12
-
13
- ```bash
14
- # download project from remote repository
15
- git clone origin git@gitlab.com:<project_name>.git
16
-
17
- # go to project folder
18
- cd <project_name>
19
- ```
20
-
21
- - Install project dependencies (node_modules):
22
-
23
- ```bash
24
- yarn install
25
- ```
9
+ ## Quick Start
26
10
 
27
- - Create environment file:
11
+ 1. Install `vueless` UI library packages.
28
12
 
29
13
  ```bash
30
- # for local environment
31
- cp .env.local.example .env.local
14
+ npm install vueless @vueless/plugin-vite
32
15
  ```
33
16
 
34
- - Run the app in **development** mode:
35
-
36
- ```bash
37
- yarn dev
38
- ```
39
-
40
- - The project is ready!
41
-
42
- ## REST API
43
-
44
- - Public URL: https://fine.gitbook.io/api/
45
-
46
- - Development URL (same but editable):
17
+ 2. Create `vueless.config.js` at the root of the project.
47
18
 
48
- - URL: https://app.gitbook.com/s/-MAVM-6BL-A_fpwuMsE1/
49
- - Login: i.ivan.gridnev@gmail.com
50
- - Password: XZQnUtFEZ4v9PML
51
-
52
- Section **AUTH & APPS** contains **Main** application endpoints, while section **APP INSTANCE** contains **Business** application endpoints.
53
-
54
-
55
- ## Additional commands
56
-
57
- - Open Storybook (frontend base UI components documentation):
58
-
59
- ```bash
60
- # run Storybook in development mode (with docs and stories):
61
- # It's good for debugging components.
62
- yarn sb:dev-full
63
-
64
- # run Storybook in development mode (with docs only):
65
- yarn sb:dev
66
-
67
- # build Storybook (to publish in the web):
68
- yarn sb:build
69
-
70
- # Run the built application from a `/storybook-static` folder in production mode:
71
- yarn sb:preview
19
+ ```javascript filename="vueless.config.js" title="vueless.config.js"
20
+ export default {
21
+ color: {},
22
+ component: {},
23
+ };
72
24
  ```
73
25
 
74
- - Run code-style check / formatting:
26
+ 3. Add TailwindCSS preset.
75
27
 
76
- ```bash
77
- # check code style (only show errors)
78
- yarn lint
79
-
80
- # check code style and fix all possible errors
81
- yarn lint:fix
28
+ ```javascript
29
+ import { vuelessPreset } from "vueless/preset.tailwind";
82
30
 
83
- # check code style of given file paths (fail pipeline if at least 1 error or warning appears)
84
- yarn lint:ci
31
+ export default {
32
+ presets: [vuelessPreset],
33
+ ...
34
+ };
85
35
  ```
86
36
 
87
- - Run auto tests:
37
+ 4. Add Vite plugins.
88
38
 
89
- ```bash
90
- # start unit tests
91
- yarn test:unit
39
+ ```javascript
40
+ import { Vueless, VuelessUnpluginComponents } from "@vueless/plugin-vite";
92
41
 
93
- # start end to end tests
94
- yarn test:e2e
95
-
96
- # start end to end tests in headless mode (no UI)
97
- yarn test:e2e-ci
42
+ export default defineConfig({
43
+ plugins: [
44
+ ...
45
+ Vueless(),
46
+ VuelessUnpluginComponents(),
47
+ ],
48
+ ...
49
+ })
98
50
  ```
99
51
 
100
- - Build application:
52
+ That's it! You can use components in your app now ✨
101
53
 
102
- ```bash
103
- # for the dev / test / production servers
104
- cp .env.example .env
105
54
 
106
- yarn build
107
- # TIP: 📐
108
- # to analise and reduce the build size see the report.html in a project root folder.
109
- ```
110
-
111
- - Run the built application from a `/dist` folder in **production mode**:
112
55
 
113
- ```bash
114
- yarn preview
115
- ```
116
-
117
- - Automated releases (new app release in GitLab and increase app version number):
118
-
119
- ```bash
120
- # increase third app version number (0.0.X).
121
- yarn release
122
-
123
- # increase second app version number (0.X.0).
124
- yarn release:production
125
-
126
- # increase first app version number (X.0.0).
127
- release:production-major
128
- ```
129
-
130
- - Update browserslist DB to the latest version (it changes yarn.lock only):
131
-
132
- ```bash
133
- npx browserslist@latest --update-db
134
- ```
135
-
136
- - **Note**: `yarn` automatically calls the` postinstall` command,
137
- which generate components web-types for IDE (props autocomplete).
138
- If you need to do this manually, just use the command below:
139
-
140
- ```bash
141
- node .mono/our.library.web-types-gen
142
- ```
143
-
144
- ## Capacitor (iOS & Android apps)
145
-
146
- - Update app src after `dist` or `capacitor.config.js` file changes:
147
-
148
- ```bash
149
- npx cap copy
150
- ```
151
-
152
- - Open iOS app locally:
153
-
154
- ```bash
155
- npx cap open ios
156
- ```
157
-
158
- - Open Android app locally:
159
-
160
- ```bash
161
- npx cap open android
162
- ```
163
-
164
- - Sync the app after new capacitor plugin installation:
165
-
166
- ```bash
167
- npx cap sync
168
- ```
169
-
170
- - Generate app icons and splash screens ([docs](https://github.com/ionic-team/capacitor-assets)):
171
-
172
- ```bash
173
- npx @capacitor/assets generate --assetPath 'public/static/capacitor' --iconBackgroundColor '#FFFFFF' --iconBackgroundColorDark '#111827' --splashBackgroundColor '#F3F4F6' --splashBackgroundColorDark '#1F2937' --ios --android
174
- ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless Component Framework.",
6
6
  "homepage": "https://vueless.com",
@@ -19,7 +19,7 @@
19
19
  "sb:build": "STORYBOOK_VUELESS_ENV=1 storybook build",
20
20
  "sb:preview": "vite preview --host --outDir=storybook-static",
21
21
  "vueless:update": "yarn add -D file:../vite-plugin-vueless file:../vueless-storybook",
22
- "vueless:prepare": "rm -rf dist && mkdir -p dist && cp -r src/* package.json LICENSE web-types.json README.md dist/ && node .web-types-gen"
22
+ "vueless:prepare": "node .web-types-gen && rm -rf dist && mkdir -p dist && cp -r src/* package.json LICENSE web-types.json README.md dist/"
23
23
  },
24
24
  "dependencies": {
25
25
  "@kyvg/vue3-notification": "^3.2.1",
@@ -59,9 +59,6 @@
59
59
  "vite-plugin-eslint": "^1.8.1",
60
60
  "vue": "^3.4.19"
61
61
  },
62
- "resolutions": {
63
- "string-width": ">=4.2.3"
64
- },
65
62
  "repository": {
66
63
  "type": "git",
67
64
  "url": "git+https://github.com/vuelessjs/vueless.git"
@@ -0,0 +1,95 @@
1
+ import colors from "tailwindcss/colors.js";
2
+ import forms from "@tailwindcss/forms";
3
+ import vuelessConfig from "../../../vueless.config.js";
4
+
5
+ export const grayColors = ["slate", "gray", "zinc", "neutral", "stone"];
6
+ export const brandColors = [
7
+ "brand",
8
+ "red",
9
+ "orange",
10
+ "amber",
11
+ "yellow",
12
+ "lime",
13
+ "green",
14
+ "emerald",
15
+ "teal",
16
+ "cyan",
17
+ "sky",
18
+ "blue",
19
+ "indigo",
20
+ "violet",
21
+ "purple",
22
+ "fuchsia",
23
+ "pink",
24
+ "rose",
25
+ ];
26
+
27
+ /**
28
+ * Generates preset for TailwindCSS base on Vueless config.
29
+ * @returns {Object}
30
+ */
31
+ export function vuelessPreset() {
32
+ const isProd = process.env.NODE_ENV === "production";
33
+ const brandColor = twColorWithOpacity("--color-brand");
34
+ const { brand, gray } = vuelessConfig;
35
+
36
+ let brandPalette = brandColors.includes(brand) ? colors[brand] : colors.green;
37
+ let grayPalette = grayColors.includes(gray) ? colors[gray] : colors.zinc;
38
+
39
+ if (brand === "grayscale") {
40
+ brandPalette = grayPalette;
41
+ }
42
+
43
+ const prodSafelist = getSafelist();
44
+ const devSafelist = [
45
+ {
46
+ pattern: /(border|bg|text|ring)-(.*)-((50|[1-9]00|950)?)$/,
47
+ variants: ["hover", "focus", "focus-within", "active"],
48
+ },
49
+ ];
50
+
51
+ return {
52
+ content: [
53
+ "./index.html",
54
+ "./src/**/*.{js,ts,jsx,tsx,vue}",
55
+ "./vueless.config.{js,ts}",
56
+ "./node_modules/vueless/**/*.{js,ts,vue}",
57
+ ],
58
+ safelist: isProd ? prodSafelist : devSafelist,
59
+ theme: {
60
+ extend: {
61
+ colors: {
62
+ brand: { ...brandPalette, DEFAULT: brandColor },
63
+ gray: grayPalette,
64
+ },
65
+ fontSize: {
66
+ "2xs": ["0.625rem", "0.875rem"], // 10px
67
+ },
68
+ },
69
+ },
70
+ plugins: [forms],
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Transform CSS variable with RGB numbers into CSS color.
76
+ * @returns {Function}
77
+ */
78
+ function twColorWithOpacity(variableName) {
79
+ return ({ opacityValue }) => {
80
+ return opacityValue !== undefined
81
+ ? `rgba(var(${variableName}), ${opacityValue})`
82
+ : `rgb(var(${variableName}))`;
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Convert sting patterns to RegExp.
88
+ * @returns {Array} - TailwindCSS safelist.
89
+ */
90
+ function getSafelist() {
91
+ return JSON.parse(process.env.SAFELIST_JSON || "[]").map((rule) => ({
92
+ ...rule,
93
+ pattern: new RegExp(rule.pattern),
94
+ }));
95
+ }
@@ -1,4 +1,4 @@
1
- import { contributions } from "/web-types.json";
1
+ import { contributions } from "../web-types.json";
2
2
 
3
3
  const getComponentData = (componentName) => {
4
4
  return contributions.html.tags.find((item) => item.name === componentName);
@@ -2,7 +2,7 @@ import { merge } from "lodash-es";
2
2
  import { defineConfig } from "cva";
3
3
  import { twMerge } from "tailwind-merge";
4
4
  import colors from "tailwindcss/colors";
5
- import { brandColors, grayColors } from "../service.tailwind";
5
+ import { brandColors, grayColors } from "../preset.tailwind";
6
6
  import vuelessConfig from "../../../vueless.config.js";
7
7
 
8
8
  /*
@@ -1,5 +1,12 @@
1
1
  <template>
2
- <button :id="id" :disabled="disabled" :data-cy="dataCy" v-bind="buttonAttrs" @click="onClick">
2
+ <button
3
+ :id="id"
4
+ ref="buttonRef"
5
+ :disabled="disabled"
6
+ :data-cy="dataCy"
7
+ v-bind="buttonAttrs"
8
+ @click="onClick"
9
+ >
3
10
  <!-- @slot Use it to add something before text. -->
4
11
  <slot v-if="!loading" name="left" />
5
12
 
@@ -16,11 +23,13 @@
16
23
  </template>
17
24
 
18
25
  <script setup>
19
- import ULoader from "../ui.other-loader";
26
+ import { ref } from "vue";
27
+
20
28
  import UIService, { getRandomId } from "../service.ui";
29
+ import ULoader from "../ui.other-loader";
21
30
 
22
- import { useAttrs } from "./composables/attrs.composable";
23
31
  import defaultConfig from "./configs/default.config";
32
+ import { useAttrs } from "./composables/attrs.composable";
24
33
  import { UButton } from "./constants";
25
34
 
26
35
  /* Should be a string for correct web-types gen */
@@ -140,6 +149,10 @@ const emit = defineEmits(["click"]);
140
149
 
141
150
  const { textAttrs, buttonAttrs } = useAttrs(props);
142
151
 
152
+ const buttonRef = ref(null);
153
+
154
+ defineExpose({ buttonRef });
155
+
143
156
  function onClick(event) {
144
157
  if (props.disabled) return;
145
158
 
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div tabindex="-1" v-bind="wrapperAttrs">
2
+ <div v-bind="wrapperAttrs" ref="wrapperRef" tabindex="-1">
3
3
  <div v-if="hasSlotContent(slots['left'])" v-bind="leftSlotAttrs">
4
4
  <!-- @slot Use it to add something before text. -->
5
5
  <slot name="left" />
@@ -49,8 +49,7 @@
49
49
  </template>
50
50
 
51
51
  <script setup>
52
- import { computed, useSlots } from "vue";
53
-
52
+ import { computed, useSlots, ref } from "vue";
54
53
  import UIService from "../service.ui";
55
54
 
56
55
  import { useAttrs } from "./composables/attrs.composable";
@@ -181,6 +180,10 @@ const props = defineProps({
181
180
 
182
181
  const slots = useSlots();
183
182
 
183
+ const wrapperRef = ref(null);
184
+
185
+ defineExpose({ wrapperRef });
186
+
184
187
  const { wrapperAttrs, linkAttrs, rightSlotAttrs, leftSlotAttrs, textAttrs, hasSlotContent } =
185
188
  useAttrs(props);
186
189
 
@@ -2,7 +2,7 @@ export default /*tw*/ {
2
2
  htmlBody: "bg-gray-50 group/body-gray",
3
3
  wrapperMobile: "overflow-x-hidden mb-[theme('spacing.mobile-menu-height')]",
4
4
  wrapper: {
5
- base: "min-h-screen overflow-auto",
5
+ base: "min-h-screen overflow-auto UNotifyPage",
6
6
  variants: {
7
7
  width: {
8
8
  xs: "md:w-[25rem] md:max-[500px]:!w-full",
@@ -1,13 +1,13 @@
1
1
  export default /*tw*/ {
2
2
  tableCell: {
3
3
  base: `
4
- p-[1.125rem] py-5 first:p-5 [&:nth-child(2)]:pl-0 group-[]/body:truncate group-[]/body:align-top
4
+ p-[1.125rem] py-5 first:p-5 [&:nth-child(2)]:pl-0 group-[]/body:truncate group-[]/body:align-top
5
5
  group-[]/body:last:p-5
6
6
  `,
7
7
  variants: {
8
8
  compact: {
9
9
  true: `
10
- group-[]/body:px-4 group-[]/body:py-3 group-[]/body:last:px-4 group-[]/body:last:py-3
10
+ group-[]/body:px-4 group-[]/body:py-3 group-[]/body:last:px-4 group-[]/body:last:py-3
11
11
  group-[]/body:first:px-4 group-[]/body:first:py-3 group-[]/footer:p-4:
12
12
  `,
13
13
  },
@@ -2,6 +2,7 @@
2
2
  <div v-bind="wrapperAttrs">
3
3
  <UBadge
4
4
  :id="id"
5
+ ref="badgeRef"
5
6
  :label="label"
6
7
  :size="size"
7
8
  :color="color"
@@ -10,6 +11,7 @@
10
11
  :data-cy="`${dataCy}-badge`"
11
12
  v-bind="badgeAttrs"
12
13
  @click.stop="onClickBadge"
14
+ @blur="onBlurBadge"
13
15
  >
14
16
  <template #right>
15
17
  <UIcon
@@ -192,6 +194,8 @@ const emit = defineEmits(["update:modelValue"]);
192
194
 
193
195
  const isShownOptions = ref(false);
194
196
 
197
+ const badgeRef = ref(null);
198
+
195
199
  const { config, listWrapperAttrs, wrapperAttrs, badgeAttrs, listAttrs, iconAttrs, hasSlotContent } =
196
200
  useAttrs(props, { isShownOptions });
197
201
 
@@ -227,7 +231,13 @@ function hideOptions() {
227
231
  }
228
232
 
229
233
  function onClickOutside(event) {
230
- if (!document.getElementById(props.id)?.contains(event.target)) {
234
+ if (!badgeRef.value?.wrapperRef?.contains(event.target)) {
235
+ hideOptions();
236
+ }
237
+ }
238
+
239
+ function onBlurBadge(event) {
240
+ if (!event.target.isEqualNode(event.relatedTarget) && event.relatedTarget) {
231
241
  hideOptions();
232
242
  }
233
243
  }
@@ -2,6 +2,7 @@
2
2
  <div v-bind="wrapperAttrs">
3
3
  <UButton
4
4
  :id="id"
5
+ ref="buttonRef"
5
6
  :label="label"
6
7
  :size="size"
7
8
  :variant="variant"
@@ -13,6 +14,7 @@
13
14
  :data-cy="`${dataCy}-button`"
14
15
  v-bind="buttonAttrs"
15
16
  @click.stop="onClickButton"
17
+ @blur="onBlurButton"
16
18
  >
17
19
  <template #right>
18
20
  <UIcon
@@ -39,7 +41,10 @@
39
41
  :value-key="valueKey"
40
42
  :label-key="labelKey"
41
43
  :data-cy="`${dataCy}-item`"
44
+ tabindex="-1"
42
45
  v-bind="listAttrs"
46
+ @mousedown.stop
47
+ @click.stop
43
48
  />
44
49
  </div>
45
50
  </template>
@@ -54,8 +59,8 @@ import UDropdownList from "../ui.dropdown-list";
54
59
  import UIService, { getRandomId } from "../service.ui";
55
60
 
56
61
  import defaultConfig from "./configs/default.config";
57
- import { UDropdownButton, BUTTON_VARIANT } from "./constants";
58
62
  import { useAttrs } from "./composables/attrs.composable";
63
+ import { UDropdownButton, BUTTON_VARIANT } from "./constants";
59
64
 
60
65
  /* Should be a string for correct web-types gen */
61
66
  defineOptions({ name: "UDropdownButton", inheritAttrs: false });
@@ -217,6 +222,7 @@ provide("hideDropdownOptions", () => hideOptions);
217
222
  const emit = defineEmits(["update:modelValue"]);
218
223
 
219
224
  const isShownOptions = ref(false);
225
+ const buttonRef = ref(null);
220
226
 
221
227
  const {
222
228
  config,
@@ -264,7 +270,13 @@ function hideOptions() {
264
270
  }
265
271
 
266
272
  function onClickOutside(event) {
267
- if (!document.getElementById(props.id)?.contains(event.target)) {
273
+ if (!buttonRef.value?.buttonRef?.contains(event.target)) {
274
+ hideOptions();
275
+ }
276
+ }
277
+
278
+ function onBlurButton(event) {
279
+ if (!event.target.isEqualNode(event.relatedTarget) && event.relatedTarget) {
268
280
  hideOptions();
269
281
  }
270
282
  }
@@ -3,6 +3,7 @@
3
3
  <div v-bind="triggerAttrs">
4
4
  <ULink
5
5
  :id="id"
6
+ ref="linkRef"
6
7
  :label="label"
7
8
  :size="size"
8
9
  :color="color"
@@ -13,6 +14,7 @@
13
14
  :data-cy="`${dataCy}-link`"
14
15
  v-bind="linkAttrs"
15
16
  @click.stop="onClickLink"
17
+ @blur="onBlurLink"
16
18
  >
17
19
  <template #right>
18
20
  <UIcon
@@ -210,6 +212,8 @@ const emit = defineEmits(["update:modelValue"]);
210
212
 
211
213
  const isShownOptions = ref(false);
212
214
 
215
+ const linkRef = ref(null);
216
+
213
217
  const {
214
218
  config,
215
219
  listWrapperAttrs,
@@ -254,7 +258,13 @@ function hideOptions() {
254
258
  }
255
259
 
256
260
  function onClickOutside(event) {
257
- if (!document.getElementById(props.id)?.contains(event.target)) {
261
+ if (!linkRef.value?.wrapperRef?.contains(event.target)) {
262
+ hideOptions();
263
+ }
264
+ }
265
+
266
+ function onBlurLink(event) {
267
+ if (!event.target.isEqualNode(event.relatedTarget) && event.relatedTarget) {
258
268
  hideOptions();
259
269
  }
260
270
  }
@@ -40,7 +40,7 @@ export default /*tw*/ {
40
40
  activeMonth: "bg-gray-100",
41
41
  yearViewWrapper: "grid w-64 grid-cols-4 items-center justify-center px-3 pt-2",
42
42
  year: `
43
- mx-auto flex h-12 w-full items-center justify-center rounded-lg text-sm hover:cursor-pointer hover:bg-gray-100
43
+ mx-auto flex h-12 w-full items-center justify-center rounded-lg text-sm hover:cursor-pointer hover:bg-gray-100
44
44
  disabled:opacity-50 disabled:cursor-not-allowed
45
45
  `,
46
46
  selectedYear: "bg-gray-900 hover:bg-gray-900 text-white",
@@ -111,7 +111,7 @@ const props = defineProps({
111
111
 
112
112
  /**
113
113
  * Label placement.
114
- * @values left, right
114
+ * @values top, topInside, topWithDesc, bottom, left, right
115
115
  */
116
116
  labelAlign: {
117
117
  type: String,
@@ -6,7 +6,7 @@
6
6
  :disabled="disabled"
7
7
  :error="error"
8
8
  :size="size"
9
- placement="topWithDesc"
9
+ align="topWithDesc"
10
10
  :data-cy="dataCy"
11
11
  v-bind="labelAttrs"
12
12
  >
@@ -7,14 +7,14 @@ export default /*tw*/ {
7
7
  },
8
8
  buttonWrapper: "flex h-full rounded-lg focus-within:ring-4 focus-within:ring-gray-600/[.15] max-md:justify-between",
9
9
  button: `
10
- shrink-0 grow rounded-none border-0 bg-zinc-100 py-2 text-base font-medium text-gray-900 shadow-none
11
- hover:bg-zinc-200 hover:ring-gray-600/[.15] focus:border-0 focus:bg-zinc-200 focus:ring-0 focus:ring-gray-600/[.15]
10
+ shrink-0 grow rounded-none border-0 bg-zinc-100 py-2 text-base font-medium text-gray-900 shadow-none
11
+ hover:bg-zinc-200 hover:ring-gray-600/[.15] focus:border-0 focus:bg-zinc-200 focus:ring-0 focus:ring-gray-600/[.15]
12
12
  active:bg-zinc-200 disabled:cursor-not-allowed
13
13
  `,
14
14
  buttonActive: "border-0 hover:bg-zinc-200 ring-0 ring-gray-600/[.15] bg-zinc-200",
15
15
  buttonWrapperActive: "ring-4 ring-gray-600/[.15]",
16
16
  shiftRangeButton: `
17
- focus:bg-bg-zinc-200 flex items-center border-0 bg-zinc-100 py-[0.71875rem] shadow-none
17
+ focus:bg-bg-zinc-200 flex items-center border-0 bg-zinc-100 py-[0.71875rem] shadow-none
18
18
  hover:bg-zinc-200 hover:ring-gray-600/[.15] focus:border-0 focus:ring-0 focus:ring-gray-600/[.15] active:bg-zinc-200
19
19
  disabled:cursor-not-allowed last:rounded-l-none last:rounded-r-lg first:rounded-l-lg first:rounded-r-none
20
20
  `,
@@ -29,7 +29,7 @@ export default /*tw*/ {
29
29
  },
30
30
  periodsRow: "mb-1 flex min-w-64 gap-1",
31
31
  periodButton: `
32
- flex h-[3.125rem] w-full cursor-pointer flex-col items-center justify-center rounded-lg bg-zinc-100
32
+ flex h-[3.125rem] w-full cursor-pointer flex-col items-center justify-center rounded-lg bg-zinc-100
33
33
  px-1.5 py-2.5 text-center text-xs font-medium text-gray-900 hover:bg-gray-200
34
34
  [&_span]:block [&_span]:font-normal [&_span]:text-gray-500
35
35
  `,
@@ -66,7 +66,7 @@ export default /*tw*/ {
66
66
  error: false,
67
67
  readonly: false,
68
68
  disabled: false,
69
- labelOutside: false,
69
+ labelAlign: "topInside",
70
70
  noAutocomplete: false,
71
71
  },
72
72
  };
@@ -123,11 +123,12 @@ const props = defineProps({
123
123
  },
124
124
 
125
125
  /**
126
- * Show label outside the input block.
126
+ * Set label placement related from the default slot.
127
+ * @values top, topInside, topWithDesc, bottom, left, right
127
128
  */
128
- labelOutside: {
129
- type: Boolean,
130
- default: UIService.get(defaultConfig, UInput).default.labelOutside,
129
+ labelAlign: {
130
+ type: String,
131
+ default: UIService.get(defaultConfig, UInput).default.labelAlign,
131
132
  },
132
133
 
133
134
  /**
@@ -285,10 +286,6 @@ const {
285
286
  hasSlotContent,
286
287
  } = useAttrs(props, { isTypePassword, inputPasswordClasses });
287
288
 
288
- const labelAlign = computed(() => {
289
- return props.labelOutside ? "top" : "topInside";
290
- });
291
-
292
289
  const passwordIconName = computed(() => {
293
290
  return isShownPassword.value
294
291
  ? config.value.passwordVisibleIconName