@dolanske/vui 1.2.1 → 1.4.0

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 (115) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +4 -27
  3. package/package.json +2 -2
  4. package/src/App.vue +8 -0
  5. package/src/components/Accordion/Accordion.vue +10 -3
  6. package/src/components/Accordion/accordion.scss +18 -3
  7. package/src/components/Button/Button.vue +5 -4
  8. package/src/components/Button/button.scss +9 -1
  9. package/src/components/ButtonGroup/button-group.scss +2 -2
  10. package/src/components/Calendar/calendar.scss +5 -0
  11. package/src/components/Card/Card.vue +1 -1
  12. package/src/components/CopyClipboard/CopyClipboard.vue +10 -3
  13. package/src/components/CopyClipboard/copy-clipboard.scss +1 -1
  14. package/src/components/Dropdown/Dropdown.vue +1 -15
  15. package/src/components/Dropdown/dropdown-item.scss +1 -1
  16. package/src/components/Dropdown/dropdown.scss +2 -2
  17. package/src/components/Grid/Grid.vue +3 -0
  18. package/src/components/Input/Counter.vue +1 -1
  19. package/src/components/Input/Password.vue +1 -1
  20. package/src/components/Input/input.scss +3 -3
  21. package/src/components/OTP/otp.scss +3 -3
  22. package/src/components/Pagination/Pagination.vue +25 -10
  23. package/src/components/Popout/Popout.vue +30 -9
  24. package/src/components/Popout/popout.scss +2 -1
  25. package/src/components/Progress/progress.scss +1 -1
  26. package/src/components/Select/Select.vue +2 -0
  27. package/src/components/Select/select.scss +1 -1
  28. package/src/components/Sidebar/sidebar.scss +1 -1
  29. package/src/components/Table/Head.vue +23 -16
  30. package/src/components/Table/table.scss +9 -8
  31. package/src/components/Tabs/Tabs.vue +1 -1
  32. package/src/components/Tabs/tabs.scss +2 -2
  33. package/src/components/Tooltip/Tooltip.vue +9 -17
  34. package/src/components/Tooltip/tooltip.scss +1 -4
  35. package/src/examples/ExampleAccordions.vue +17 -4
  36. package/src/examples/ExampleCopyClipboard.vue +2 -2
  37. package/src/examples/ExamplePalette.vue +6 -0
  38. package/src/examples/ExamplePopouts.vue +1 -1
  39. package/src/examples/ExampleTables.vue +164 -0
  40. package/src/examples/ExampleTabs.vue +3 -2
  41. package/src/internal/Backdrop/backdrop.scss +2 -2
  42. package/src/shared/helpers.ts +7 -0
  43. package/src/style/animation.scss +33 -5
  44. package/src/style/core.scss +24 -10
  45. package/src/style/fonts.scss +73 -0
  46. package/src/style/layout.scss +8 -39
  47. package/src/style/theme.scss +1 -1
  48. package/src/style/tooltip.scss +4 -4
  49. package/src/style/typography.scss +45 -25
  50. package/src/vite-env.d.ts +1 -1
  51. package/dist/components/Accordion/Accordion.vue.d.ts +0 -47
  52. package/dist/components/Accordion/AccordionGroup.vue.d.ts +0 -21
  53. package/dist/components/Alert/Alert.vue.d.ts +0 -36
  54. package/dist/components/Avatar/Avatar.vue.d.ts +0 -25
  55. package/dist/components/Badge/Badge.vue.d.ts +0 -22
  56. package/dist/components/Breadcrumbs/BreadcrumbItem.vue.d.ts +0 -22
  57. package/dist/components/Breadcrumbs/Breadcrumbs.vue.d.ts +0 -18
  58. package/dist/components/Button/Button.vue.d.ts +0 -32
  59. package/dist/components/ButtonGroup/ButtonGroup.vue.d.ts +0 -22
  60. package/dist/components/Calendar/Calendar.vue.d.ts +0 -27
  61. package/dist/components/Card/Card.vue.d.ts +0 -26
  62. package/dist/components/Checkbox/Checkbox.vue.d.ts +0 -33
  63. package/dist/components/CopyClipboard/CopyClipboard.vue.d.ts +0 -41
  64. package/dist/components/Divider/Divider.vue.d.ts +0 -23
  65. package/dist/components/Drawer/Drawer.vue.d.ts +0 -53
  66. package/dist/components/Dropdown/Dropdown.vue.d.ts +0 -183
  67. package/dist/components/Dropdown/DropdownItem.vue.d.ts +0 -23
  68. package/dist/components/Dropdown/DropdownTitle.vue.d.ts +0 -21
  69. package/dist/components/Flex/Flex.vue.d.ts +0 -41
  70. package/dist/components/Grid/Grid.vue.d.ts +0 -34
  71. package/dist/components/Input/Color.vue.d.ts +0 -11
  72. package/dist/components/Input/Counter.vue.d.ts +0 -19
  73. package/dist/components/Input/Dropzone.vue.d.ts +0 -193
  74. package/dist/components/Input/File.vue.d.ts +0 -8
  75. package/dist/components/Input/Input.vue.d.ts +0 -56
  76. package/dist/components/Input/Password.vue.d.ts +0 -6
  77. package/dist/components/Input/Textarea.vue.d.ts +0 -31
  78. package/dist/components/Kbd/Kbd.vue.d.ts +0 -23
  79. package/dist/components/Kbd/KbdGroup.vue.d.ts +0 -19
  80. package/dist/components/Modal/Confirm.vue.d.ts +0 -43
  81. package/dist/components/Modal/Modal.vue.d.ts +0 -58
  82. package/dist/components/OTP/OTP.vue.d.ts +0 -44
  83. package/dist/components/OTP/OTPItem.vue.d.ts +0 -5
  84. package/dist/components/Pagination/Pagination.vue.d.ts +0 -46
  85. package/dist/components/Pagination/pagination.d.ts +0 -12
  86. package/dist/components/Popout/Popout.vue.d.ts +0 -42
  87. package/dist/components/Progress/Progress.vue.d.ts +0 -33
  88. package/dist/components/Radio/Radio.vue.d.ts +0 -29
  89. package/dist/components/Radio/RadioGroup.vue.d.ts +0 -27
  90. package/dist/components/Select/Select.vue.d.ts +0 -35
  91. package/dist/components/Sheet/Sheet.vue.d.ts +0 -47
  92. package/dist/components/Sidebar/Sidebar.vue.d.ts +0 -70
  93. package/dist/components/Skeleton/Skeleton.vue.d.ts +0 -8
  94. package/dist/components/Spinner/Spinner.vue.d.ts +0 -6
  95. package/dist/components/Switch/Switch.vue.d.ts +0 -28
  96. package/dist/components/Table/Cell.vue.d.ts +0 -22
  97. package/dist/components/Table/Head.vue.d.ts +0 -30
  98. package/dist/components/Table/Root.vue.d.ts +0 -41
  99. package/dist/components/Table/SelectAll.vue.d.ts +0 -2
  100. package/dist/components/Table/SelectRow.vue.d.ts +0 -6
  101. package/dist/components/Table/index.d.ts +0 -6
  102. package/dist/components/Table/table.d.ts +0 -68
  103. package/dist/components/Tabs/Tab.vue.d.ts +0 -22
  104. package/dist/components/Tabs/Tabs.vue.d.ts +0 -34
  105. package/dist/components/Toast/Toasts.vue.d.ts +0 -2
  106. package/dist/components/Toast/toast.d.ts +0 -287
  107. package/dist/components/Tooltip/Tooltip.vue.d.ts +0 -33
  108. package/dist/index.d.ts +0 -56
  109. package/dist/internal/Backdrop/Backdrop.vue.d.ts +0 -21
  110. package/dist/shared/helpers.d.ts +0 -32
  111. package/dist/shared/slots.d.ts +0 -20
  112. package/dist/shared/theme.d.ts +0 -3
  113. package/dist/shared/types.d.ts +0 -24
  114. package/dist/vui.css +0 -1
  115. package/dist/vui.js +0 -16166
package/LICENSE CHANGED
@@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
671
671
  may consider it more useful to permit linking proprietary applications with
672
672
  the library. If this is what you want to do, use the GNU Lesser General
673
673
  Public License instead of this License. But first, please read
674
- <https://www.gnu.org/licenses/why-not-lgpl.html>.
674
+ <https://www.gnu.org/licenses/why-not-lgpl.html>.
package/README.md CHANGED
@@ -6,37 +6,14 @@
6
6
 
7
7
  ---
8
8
 
9
- ## 1.0 Checklist
10
-
11
- - [ ] Real life test
12
- - [x] Might be useful to build this in the hivecom project
13
- - [x] Build an example page with 100% of the components
14
- - [x] Run accessibility tools on it
15
- - [x] Run color contrast test
16
- - [ ] Make sure it works on mobile down to 340px
17
- - [ ] Components
18
- - [ ] Scale down Typography
19
- - [x] Sidebar
20
-
21
- ---
22
-
23
- ### Post 1.2 components
9
+ ## TODO
24
10
 
11
+ - [ ] Bump target from ES2022 whenever vite-plugin-dts is fixed
25
12
  - [ ] Carousel (slider)
26
13
  - [ ] CodeBlock
27
14
  - [ ] Code highlighting
28
15
  - [ ] Copy code
29
16
  - [ ] Type, padding, etc
30
17
  - [ ] Use this https://shiki.style/guide/install
31
- - [ ] Command dropdown
32
- - [ ] Documentation
33
- - [ ] Design my own documentation site (GENERIC?!)
34
- - [ ] Pages
35
- - [ ] CSS variable setup, accent, fonts
36
- - [ ] CSS helpers
37
- - [ ] Components
38
- - [ ] Typography page
39
-
40
- ### Whenever
41
-
42
- - [ ] Bump target from ES2022 whenever vite-plugin-dts is fixed
18
+ - [ ] Command menu
19
+ - [ ] Documentation site using my own template
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dolanske/vui",
3
3
  "type": "module",
4
- "version": "1.2.1",
4
+ "version": "1.4.0",
5
5
  "private": false,
6
6
  "description": "Brother in Christ there's a new UI library",
7
7
  "author": "dolanske",
@@ -9,7 +9,7 @@
9
9
  "sass": "src/index.scss",
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/dolanske/vui.git"
12
+ "url": "git+https://github.com/dolanske/vui.git"
13
13
  },
14
14
  "keywords": [
15
15
  "vue",
package/src/App.vue CHANGED
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import Card from './components/Card/Card.vue'
2
3
  import Divider from './components/Divider/Divider.vue'
3
4
  import ExampleAccordions from './examples/ExampleAccordions.vue'
4
5
  import ExampleAlerts from './examples/ExampleAlerts.vue'
@@ -35,6 +36,13 @@ import ExampleTooltips from './examples/ExampleTooltips.vue'
35
36
  <h1 class="mb-l">
36
37
  VUI
37
38
  </h1>
39
+
40
+ <Card class="typeface">
41
+ <pre><code>export function removeColorPrefix(value: string): string {
42
+ return value.replace('--dark', '--').replace('--light', '--')
43
+ }</code></pre>
44
+ </Card>
45
+
38
46
  <p>The purpose of this page is to showcase and test every single component case</p>
39
47
  <Divider :size="64" />
40
48
  <ExamplePalette />
@@ -1,13 +1,14 @@
1
1
  <script setup lang="ts">
2
2
  import { Icon } from '@iconify/vue'
3
3
  import { useResizeObserver } from '@vueuse/core'
4
- import { onMounted, ref, useTemplateRef, watch, watchEffect } from 'vue'
4
+ import { onBeforeMount, onMounted, ref, useTemplateRef, watch, watchEffect } from 'vue'
5
5
  import './accordion.scss'
6
6
 
7
7
  export interface AccordionProps {
8
8
  open?: boolean
9
9
  label?: string
10
10
  card?: boolean
11
+ unstyled?: boolean
11
12
  }
12
13
 
13
14
  const props = defineProps<AccordionProps>()
@@ -58,6 +59,12 @@ defineExpose({
58
59
  isOpen,
59
60
  })
60
61
 
62
+ onBeforeMount(() => {
63
+ if (props.card && props.unstyled) {
64
+ console.warn('[Accordion] Both \'card\' and \'unstyled\' props are selected. Unstyled will take precedence.')
65
+ }
66
+ })
67
+
61
68
  onMounted(() => {
62
69
  useResizeObserver(contentRef, ([entry]) => {
63
70
  if (isOpen.value && contentMaxHeight.value !== entry.contentRect.height) {
@@ -68,14 +75,14 @@ onMounted(() => {
68
75
  </script>
69
76
 
70
77
  <template>
71
- <div class="vui-accordion" :class="{ 'open': isOpen, 'is-card': !!props.card }">
78
+ <div class="vui-accordion" :class="{ 'open': isOpen, 'is-card': !!props.card && !props.unstyled, 'is-unstyled': !!props.unstyled }">
72
79
  <!-- Completely custom header which needs to be styled and implemented by the developer -->
73
80
  <slot v-if="$slots.trigger" name="trigger" :open :close :toggle :is-open />
74
81
  <button v-else class="vui-accordion-header" @click="isOpen = !isOpen">
75
82
  <slot name="header">
76
83
  {{ props.label }}
77
84
  </slot>
78
- <Icon icon="ph:caret-down" />
85
+ <Icon v-if="!props.unstyled" icon="ph:caret-down" />
79
86
  </button>
80
87
 
81
88
  <div
@@ -4,6 +4,19 @@
4
4
  border-bottom: 1px solid var(--color-border);
5
5
  padding-bottom: 0;
6
6
 
7
+ &.is-unstyled {
8
+ border-bottom: none;
9
+
10
+ .vui-accordion-header {
11
+ padding: unset;
12
+ text-decoration: unset;
13
+
14
+ &:hover {
15
+ text-decoration: unset;
16
+ }
17
+ }
18
+ }
19
+
7
20
  &.is-card {
8
21
  border: 1px solid var(--color-border);
9
22
  border-radius: var(--border-radius-m);
@@ -37,10 +50,12 @@
37
50
  }
38
51
 
39
52
  &.open {
40
- padding-bottom: var(--space-m);
53
+ &:not(.is-unstyled) {
54
+ padding-bottom: var(--space-m);
41
55
 
42
- .vui-accordion-header svg {
43
- transform: rotate(180deg);
56
+ .vui-accordion-header svg {
57
+ transform: rotate(180deg);
58
+ }
44
59
  }
45
60
 
46
61
  .vui-accordion-content {
@@ -2,6 +2,7 @@
2
2
  import type { Sizes } from '../../shared/types'
3
3
  import { Icon } from '@iconify/vue'
4
4
  import { computed } from 'vue'
5
+ import { isNil } from '../../shared/helpers'
5
6
  import { Size } from '../../shared/types'
6
7
  import Spinner from '../Spinner/Spinner.vue'
7
8
  import './button.scss'
@@ -42,7 +43,7 @@ const {
42
43
  const height = computed(() => {
43
44
  switch (size) {
44
45
  case Size.s: return '28px'
45
- case Size.l: return '40px'
46
+ case Size.l: return '42px'
46
47
  case Size.m:
47
48
  default: return 'var(--interactive-el-height)'
48
49
  }
@@ -51,7 +52,7 @@ const height = computed(() => {
51
52
  const padding = computed(() => {
52
53
  switch (size) {
53
54
  case Size.s: return '4px'
54
- case Size.l: return '16px'
55
+ case Size.l: return '18px'
55
56
  case Size.m:
56
57
  default: return '8px'
57
58
  }
@@ -61,7 +62,7 @@ const padding = computed(() => {
61
62
  <template>
62
63
  <button
63
64
  class="vui-button"
64
- :class="[{ loading, expand, disabled, plain, icon, square, outline }, `vui-button-variant-${variant}`]"
65
+ :class="[{ loading, expand, disabled, plain, icon, square, outline }, `vui-button-variant-${variant}`, `vui-button-size-${size}`]"
65
66
  :disabled
66
67
  role="button"
67
68
  :style="{
@@ -70,7 +71,7 @@ const padding = computed(() => {
70
71
  }"
71
72
  :name="icon && !$slots.default ? icon.split(':')[1] : undefined"
72
73
  >
73
- <Spinner size="s" />
74
+ <Spinner v-if="!isNil(loading)" size="s" />
74
75
  <div class="vui-button-slot">
75
76
  <div class="vui-button-slot-start">
76
77
  <slot name="start" />
@@ -1,6 +1,8 @@
1
1
  .vui-button {
2
2
  --button-height: var(--interactive-el-height);
3
3
  --button-padding: 8px;
4
+ --button-font-size: var(--font-size-s);
5
+ --button-font-size-l: 1.4rem;
4
6
 
5
7
  &.disabled {
6
8
  // color: var(--color-text-lighter) !important;
@@ -49,6 +51,10 @@
49
51
  border-style: dashed !important;
50
52
  }
51
53
 
54
+ &.vui-button-size-l {
55
+ font-size: var(--button-font-size-l);
56
+ }
57
+
52
58
  svg path {
53
59
  transition: var(--transition-fast);
54
60
  }
@@ -60,12 +66,13 @@
60
66
  border-radius: var(--border-radius-s);
61
67
  background: transparent;
62
68
  padding-inline: var(--button-padding);
63
- font-size: var(--font-size-s);
69
+ font-size: var(--button-font-size);
64
70
  position: relative;
65
71
  transition: var(--transition-fast);
66
72
  border: 1px solid transparent;
67
73
  background-color: transparent;
68
74
  color: var(--color-text);
75
+ font-weight: var(--font-weight-medium);
69
76
 
70
77
  // Default gray
71
78
 
@@ -74,6 +81,7 @@
74
81
  place-items: center;
75
82
  transition: var(--transition-fast);
76
83
  opacity: 1;
84
+ font-weight: var(--font-weight-medium);
77
85
  }
78
86
 
79
87
  .vui-button-slot-start,
@@ -1,9 +1,9 @@
1
1
  .vui-button-group {
2
2
  .vui-button {
3
- z-index: 1;
3
+ z-index: var(--z-default);
4
4
 
5
5
  &:hover {
6
- z-index: 2;
6
+ z-index: var(--z-active);
7
7
  }
8
8
 
9
9
  &:not(:first-child, :last-child) {
@@ -64,6 +64,11 @@
64
64
 
65
65
  .dp__main {
66
66
  font-size: var(--font-size-m);
67
+ font-weight: var(--font-weight);
68
+ }
69
+
70
+ .dp__btn {
71
+ font-weight: var(--font-medium);
67
72
  }
68
73
 
69
74
  .dp__outer_menu_wrap {
@@ -27,7 +27,7 @@ const {
27
27
  }"
28
28
  >
29
29
  <div v-if="$slots.header || $slots['header-end']" class="vui-card-header">
30
- <div>
30
+ <div class="flex-1">
31
31
  <slot name="header" />
32
32
  </div>
33
33
  <slot name="header-end" />
@@ -1,9 +1,10 @@
1
1
  <script setup lang='ts'>
2
+ import type { Placement } from '@floating-ui/vue'
2
3
  import { autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/vue'
3
4
  import { Icon } from '@iconify/vue'
4
5
  import { useClipboard } from '@vueuse/core'
5
6
  import { computed, onMounted, useSlots, useTemplateRef } from 'vue'
6
- import { isNil } from '../../shared/helpers'
7
+ import { getPlacementAnimationName, isNil } from '../../shared/helpers'
7
8
  import Flex from '../Flex/Flex.vue'
8
9
  import './copy-clipboard.scss'
9
10
 
@@ -20,12 +21,17 @@ interface Props {
20
21
  * How long will the copy confirmation tooltip be visible in milliseconds.
21
22
  */
22
23
  confirmTime?: number
24
+ /**
25
+ * Tooltip position. Default is top
26
+ */
27
+ confirmPlacement?: Placement
23
28
  }
24
29
 
25
30
  const {
26
31
  text,
27
32
  confirm,
28
33
  confirmTime,
34
+ confirmPlacement = 'top',
29
35
  } = defineProps<Props>()
30
36
 
31
37
  const {
@@ -61,7 +67,8 @@ const tooltipRef = useTemplateRef('tooltip')
61
67
  const { floatingStyles } = useFloating(anchorRef, tooltipRef, {
62
68
  whileElementsMounted: autoUpdate,
63
69
  transform: false,
64
- placement: 'top',
70
+ strategy: 'fixed',
71
+ placement: confirmPlacement,
65
72
  middleware: [
66
73
  offset(8),
67
74
  shift(),
@@ -75,7 +82,7 @@ const { floatingStyles } = useFloating(anchorRef, tooltipRef, {
75
82
  <slot :copy :copied />
76
83
  </div>
77
84
 
78
- <Transition name="fade-up" mode="in-out">
85
+ <Transition :name="getPlacementAnimationName(confirmPlacement)" mode="in-out">
79
86
  <div v-if="copied && (!!parsedConfirm || $slots.confirm)" ref="tooltip" class="vui-clipboard-tooltip" :style="floatingStyles">
80
87
  <slot name="confirm">
81
88
  <template v-if="typeof parsedConfirm === 'string'">
@@ -10,7 +10,7 @@
10
10
  font-size: var(--font-size-m);
11
11
  color: var(--color-text);
12
12
  box-shadow: var(--box-shadow);
13
- z-index: 1000;
13
+ z-index: var(--z-popout);
14
14
 
15
15
  svg path {
16
16
  color: var(--color-text);
@@ -104,10 +104,9 @@ onMounted(() => {
104
104
  <slot name="trigger" :open :is-open="showMenu" :close :toggle />
105
105
  </div>
106
106
 
107
- <!-- <Transition name="dropdown" mode="out-in"> -->
108
107
  <Popout
109
- v-if="showMenu"
110
108
  ref="dropdown"
109
+ :visible="showMenu"
111
110
  :anchor="anchorRef"
112
111
  class="vui-dropdown"
113
112
  :placement
@@ -118,17 +117,4 @@ onMounted(() => {
118
117
  >
119
118
  <slot :open :close :toggle :is-open="showMenu" />
120
119
  </Popout>
121
- <!-- </Transition> -->
122
120
  </template>
123
-
124
- <!-- <style scoped lang="scss">
125
- .dropdown-enter-active,
126
- .dropdown-leave-active {
127
- transition: var(--transition-fast);
128
- }
129
-
130
- .dropdown-enter-from,
131
- .dropdown-leave-to {
132
- opacity: 0;
133
- }
134
- </style> -->
@@ -33,7 +33,7 @@
33
33
  .vui-dropdown-item-hint {
34
34
  visibility: hidden;
35
35
  opacity: 0;
36
- z-index: -1;
36
+ z-index: var(--z-behind);
37
37
  }
38
38
  }
39
39
 
@@ -27,7 +27,7 @@
27
27
  gap: var(--space-m);
28
28
  justify-content: space-between;
29
29
  background-color: var(--color-bg-medium);
30
- z-index: 50;
30
+ z-index: var(--z-popout);
31
31
 
32
32
  &.sticky {
33
33
  position: sticky;
@@ -41,7 +41,7 @@
41
41
 
42
42
  .vui-dropdown-title-end {
43
43
  font-size: var(--font-size-s);
44
- font-weight: 400;
44
+ font-weight: var(--font-weight);
45
45
  color: var(--color-text-lighter);
46
46
  }
47
47
  }
@@ -19,6 +19,7 @@ interface Props {
19
19
  yStart?: boolean
20
20
  yEnd?: boolean
21
21
  yBaseline?: boolean
22
+ yStretch?: boolean
22
23
 
23
24
  expand?: boolean
24
25
  }
@@ -60,6 +61,8 @@ const aA = computed(() => {
60
61
  return 'center'
61
62
  else if (props.yBaseline)
62
63
  return 'baseline'
64
+ else if (props.yStretch)
65
+ return 'stretch'
63
66
  return 'flex-start'
64
67
  })
65
68
 
@@ -36,7 +36,7 @@ const count = defineModel<number>({
36
36
 
37
37
  <template #end>
38
38
  <ButtonGroup>
39
- <Button v-if="!hideDecrement" key="decrease" :disabled="!decrementEnabled" :style="{ 'border-top-left-radius': 0, 'border-bottom-left-radius': 0 }" @click="count -= decrementBy">
39
+ <Button v-if="!hideDecrement" key="decrease" :disabled="!decrementEnabled" :style="{ 'border-top-left-radius': 0, 'border-bottom-left-radius': 0, 'marginRight': '-1px' }" @click="count -= decrementBy">
40
40
  <Icon icon="ph:minus" /> {{ decrementBy > 1 ? decrementBy : '' }}
41
41
  </Button>
42
42
  <Button v-if="!hideIncrement" key="increase" :disabled="!incrementEnabled" @click="count += incrementBy">
@@ -25,7 +25,7 @@ const show = ref(showPassword)
25
25
  <template #end>
26
26
  <Button
27
27
  square
28
- :data-title-top="show ? 'Hide' : 'Reveal'"
28
+ :aria-label="show ? 'Hide' : 'Reveal'"
29
29
  @click="show = !show"
30
30
  >
31
31
  <Icon :width="18" :height="18" :icon="show ? 'ph:eye-slash' : 'ph:eye'" />
@@ -44,7 +44,7 @@
44
44
  input,
45
45
  textarea,
46
46
  .vui-input-style {
47
- pointer-events: none;
47
+ // pointer-events: none;
48
48
  color: var(--input-color-text-light);
49
49
  border-color: var(--input-color-border-weak);
50
50
  resize: none !important;
@@ -92,7 +92,7 @@
92
92
  }
93
93
 
94
94
  ::placeholder {
95
- font-weight: 400;
95
+ font-weight: var(--font-weight);
96
96
  color: var(--color-text-lighter);
97
97
  font-family: var(--global-font);
98
98
  }
@@ -111,7 +111,7 @@
111
111
  width: 100%;
112
112
  transition: var(--transition-fast);
113
113
  padding-inline: var(--input-padding);
114
- z-index: 1;
114
+ z-index: var(--z-default);
115
115
 
116
116
  &:has(input:focus),
117
117
  &:focus {
@@ -14,7 +14,7 @@
14
14
  height: var(--interactive-el-height);
15
15
  border: 1px solid var(--color-border-strong);
16
16
  color: var(--color-text);
17
- z-index: 1;
17
+ z-index: var(--z-default);
18
18
  font-size: var(--font-size-m);
19
19
  outline: 0 solid var(--color-text-light);
20
20
  transition: var(--transition-fast);
@@ -49,7 +49,7 @@
49
49
  }
50
50
 
51
51
  &.active {
52
- z-index: 2;
52
+ z-index: var(--z-active);
53
53
  outline-width: 2px;
54
54
 
55
55
  .blinker {
@@ -79,6 +79,6 @@
79
79
  outline-width: 0px;
80
80
  opacity: 0;
81
81
  background: transparent;
82
- z-index: 5;
82
+ z-index: var(--z-mask);
83
83
  }
84
84
  }
@@ -4,6 +4,7 @@ import type { Pagination } from './pagination'
4
4
  import { computed } from 'vue'
5
5
  import Button from '../Button/Button.vue'
6
6
  import Flex from '../Flex/Flex.vue'
7
+ import Tooltip from '../Tooltip/Tooltip.vue'
7
8
 
8
9
  interface Props {
9
10
  numbers?: boolean
@@ -39,11 +40,21 @@ function setPrev() {
39
40
  <template>
40
41
  <Flex inline class="vui-pagination" gap="xxs">
41
42
  <slot name="start">
42
- <Button v-if="props.firstLast" data-title-top="First page" plain :disabled="props.pagination.startPage === props.pagination.currentPage" square icon="ph:caret-double-left" @click="emit('change', props.pagination.startPage)" />
43
+ <Tooltip v-if="props.firstLast">
44
+ <Button plain :disabled="props.pagination.startPage === props.pagination.currentPage" square icon="ph:caret-double-left" @click="emit('change', props.pagination.startPage)" />
45
+ <template #tooltip>
46
+ <p>First page</p>
47
+ </template>
48
+ </Tooltip>
43
49
  </slot>
44
50
 
45
51
  <slot name="prev" :disabled="canPrevPage" :set-page="setPrev">
46
- <Button v-if="props.prevNext" data-title-top="Previous page" plain :disabled="!canPrevPage" square icon="ph:caret-left" @click="setPrev" />
52
+ <Tooltip v-if="props.prevNext">
53
+ <Button plain :disabled="!canPrevPage" square icon="ph:caret-left" @click="setPrev" />
54
+ <template #tooltip>
55
+ <p>Previous page</p>
56
+ </template>
57
+ </Tooltip>
47
58
  </slot>
48
59
 
49
60
  <template v-if="props.numbers">
@@ -61,17 +72,21 @@ function setPrev() {
61
72
  </Flex>
62
73
  </template>
63
74
  <slot name="next" :disabled="canNextPage" :set-page="setNext">
64
- <Button v-if="props.prevNext" data-title-top="Next page" plain :disabled="!canNextPage" square icon="ph:caret-right" @click="setNext" />
75
+ <Tooltip v-if="props.prevNext">
76
+ <Button plain :disabled="!canNextPage" square icon="ph:caret-right" @click="setNext" />
77
+ <template #tooltip>
78
+ <p>Next page</p>
79
+ </template>
80
+ </Tooltip>
65
81
  </slot>
66
82
 
67
83
  <slot name="end">
68
- <Button v-if="props.firstLast" data-title-top="Last page" plain :disabled="props.pagination.endPage === props.pagination.currentPage" square icon="ph:caret-double-right" @click="emit('change', props.pagination.endPage)" />
84
+ <Tooltip v-if="props.firstLast">
85
+ <Button plain :disabled="props.pagination.endPage === props.pagination.currentPage" square icon="ph:caret-double-right" @click="emit('change', props.pagination.endPage)" />
86
+ <template #tooltip>
87
+ <p>Last page</p>
88
+ </template>
89
+ </Tooltip>
69
90
  </slot>
70
91
  </Flex>
71
92
  </template>
72
-
73
- <style scoped>
74
- [data-title-top]:before {
75
- white-space: nowrap;
76
- }
77
- </style>
@@ -1,8 +1,9 @@
1
1
  <script setup lang='ts'>
2
2
  import type { Placement, PopoutMaybeElement } from '../../shared/types'
3
- import { flip, offset, shift, useFloating } from '@floating-ui/vue'
3
+ import { autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/vue'
4
4
  import { onClickOutside } from '@vueuse/core'
5
- import { toRef, useTemplateRef } from 'vue'
5
+ import { toRef, useTemplateRef, watch } from 'vue'
6
+ import { getPlacementAnimationName } from '../../shared/helpers'
6
7
  import './popout.scss'
7
8
 
8
9
  export interface Props {
@@ -18,10 +19,15 @@ export interface Props {
18
19
  * Distance between the anchor and the rendered tooltip
19
20
  */
20
21
  offset?: number
22
+ /**
23
+ * Set the visibility of the dropdown
24
+ */
25
+ visible: boolean
21
26
  }
22
27
 
23
28
  const props = withDefaults(defineProps<Props>(), {
24
29
  offset: 8,
30
+ placement: 'top',
25
31
  })
26
32
 
27
33
  const emit = defineEmits<{
@@ -30,23 +36,38 @@ const emit = defineEmits<{
30
36
  const popoutRef = useTemplateRef('popout')
31
37
  const anchorRef = toRef(props.anchor)
32
38
 
33
- const { floatingStyles } = useFloating(anchorRef, popoutRef, {
39
+ const { floatingStyles, update } = useFloating(anchorRef, popoutRef, {
40
+ whileElementsMounted: autoUpdate,
41
+ strategy: 'fixed',
42
+ transform: false,
34
43
  placement: props.placement,
35
44
  middleware: [
36
- // ...(props.placement
37
- // ? []
38
- // : [autoPlacement()]),
39
45
  shift({ padding: 8 }),
40
46
  flip(),
41
47
  offset(props.offset),
42
48
  ],
43
49
  })
44
50
 
51
+ // Make sure to update the popout when the anchor is mounted
52
+ watch(() => props.anchor, (value) => {
53
+ if (value) {
54
+ anchorRef.value = value
55
+ update()
56
+ }
57
+ })
58
+
45
59
  onClickOutside(popoutRef, () => emit('clickOutside'))
46
60
  </script>
47
61
 
48
62
  <template>
49
- <div ref="popout" :style="floatingStyles" class="vui-popout">
50
- <slot />
51
- </div>
63
+ <Transition :name="getPlacementAnimationName(props.placement)">
64
+ <div
65
+ v-if="props.visible"
66
+ ref="popout"
67
+ :style="floatingStyles"
68
+ class="vui-popout"
69
+ >
70
+ <slot />
71
+ </div>
72
+ </Transition>
52
73
  </template>
@@ -4,7 +4,8 @@
4
4
  min-width: 80px;
5
5
  background-color: var(--color-bg-medium);
6
6
  border-radius: var(--border-radius-m);
7
- z-index: 1000;
7
+ z-index: var(--z-popout);
8
+ position: fixed;
8
9
  }
9
10
 
10
11
  :root.light {
@@ -30,7 +30,7 @@
30
30
 
31
31
  .vui-progress-indicator {
32
32
  position: absolute;
33
- z-index: 4;
33
+ z-index: var(--z-active);
34
34
  inset: 0;
35
35
  right: unset;
36
36
  width: 0;
@@ -186,6 +186,8 @@ const id = useId()
186
186
  :class="{ selected: selected?.find(v => v.value === option.value) }"
187
187
  :icon="selected?.find(v => v.value === option.value) ? 'ph:check-bold' : ''"
188
188
  @click="() => {
189
+ if (readonly) return
190
+
189
191
  setValue(option)
190
192
  // In single mode, close modal after clicking
191
193
  if (single && !(required && selected && selected[0].value === option.value)) {