sprintify-ui 0.0.94 → 0.0.95

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 (30) hide show
  1. package/dist/sprintify-ui.es.js +4540 -4519
  2. package/dist/style.css +1 -1
  3. package/dist/types/src/components/BaseAutocomplete.vue.d.ts +2 -2
  4. package/dist/types/src/components/BaseColor.vue.d.ts +0 -16
  5. package/dist/types/src/components/BaseDropdown.vue.d.ts +3 -2
  6. package/dist/types/src/components/BaseFieldI18n.vue.d.ts +1 -1
  7. package/dist/types/src/components/BaseInput.vue.d.ts +1 -1
  8. package/dist/types/src/components/BaseInputPercent.vue.d.ts +1 -1
  9. package/dist/types/src/components/BaseLocaleForm.vue.d.ts +1 -1
  10. package/dist/types/src/components/BaseNavbarSideItem.vue.d.ts +3 -3
  11. package/dist/types/src/composables/clickOutside.d.ts +8 -0
  12. package/dist/types/src/composables/modal.d.ts +1 -1
  13. package/dist/types/src/utils/scrollPreventer.d.ts +1 -2
  14. package/package.json +1 -1
  15. package/src/components/BaseAppDialogs.vue +1 -1
  16. package/src/components/BaseAutocomplete.vue +6 -25
  17. package/src/components/BaseColor.stories.js +0 -2
  18. package/src/components/BaseColor.vue +3 -10
  19. package/src/components/BaseDropdown.stories.js +47 -9
  20. package/src/components/BaseDropdown.vue +27 -35
  21. package/src/components/BaseLayoutSidebar.vue +4 -1
  22. package/src/components/BaseModalCenter.vue +1 -5
  23. package/src/components/BaseModalSide.vue +1 -4
  24. package/src/components/BaseSideNavigation.vue +4 -1
  25. package/src/components/BaseTable.vue +1 -0
  26. package/src/components/BaseTabs.vue +4 -1
  27. package/src/components/BaseTagAutocomplete.vue +1 -0
  28. package/src/composables/clickOutside.ts +57 -0
  29. package/src/composables/modal.ts +2 -6
  30. package/src/utils/scrollPreventer.ts +3 -13
@@ -15,9 +15,10 @@
15
15
  leave-from-class="transform scale-100 opacity-100"
16
16
  leave-to-class="transform scale-90 opacity-0"
17
17
  >
18
- <div v-show="showDropdown" class="inline-block" scroll-lock-target>
18
+ <div v-show="showDropdown" class="inline-block">
19
19
  <slot
20
20
  name="dropdown"
21
+ :show-dropdown="showDropdown"
21
22
  :close="close"
22
23
  :open="open"
23
24
  :toggle="toggle"
@@ -30,6 +31,8 @@
30
31
  </template>
31
32
 
32
33
  <script lang="ts" setup>
34
+ import { useClickOutside } from '@/composables/clickOutside';
35
+ import { throttle } from 'lodash';
33
36
  import { PropType, StyleValue } from 'vue';
34
37
  import { disableScroll, enableScroll } from '../utils';
35
38
 
@@ -96,7 +99,7 @@ function open() {
96
99
  showDropdown.value = true;
97
100
  nextTick(() => {
98
101
  setBoundingBoxes();
99
- disableScroll(dropdown.value);
102
+ disableScroll();
100
103
  emit('open');
101
104
  });
102
105
  }
@@ -108,16 +111,6 @@ function close() {
108
111
  emit('close');
109
112
  }
110
113
 
111
- function activate() {
112
- window.addEventListener('keydown', onKeydown);
113
- window.addEventListener('mousedown', onMouseDown);
114
- }
115
-
116
- function deactivate() {
117
- window.removeEventListener('keydown', onKeydown);
118
- window.removeEventListener('mousedown', onMouseDown);
119
- }
120
-
121
114
  function onKeydown(event: KeyboardEvent) {
122
115
  if (event.code == 'Escape') {
123
116
  if (showDropdown.value) {
@@ -126,33 +119,32 @@ function onKeydown(event: KeyboardEvent) {
126
119
  }
127
120
  }
128
121
 
129
- function onMouseDown(event: MouseEvent) {
130
- if (!dropdown.value) {
131
- return;
132
- }
133
- // Get the element that was clicked
134
- const clickedElement = event.target as HTMLElement | null;
135
-
136
- if (!clickedElement) {
137
- return;
138
- }
122
+ const setBoundingBoxesDebounced = throttle(() => {
123
+ setBoundingBoxes();
124
+ }, 10);
139
125
 
140
- // Button is clicked
141
- if (
142
- button.value == clickedElement ||
143
- button.value?.contains(clickedElement)
144
- ) {
145
- return;
146
- }
126
+ function activate() {
127
+ window.addEventListener('keydown', onKeydown);
128
+ window.addEventListener('resize', setBoundingBoxesDebounced);
129
+ window.addEventListener('scroll', setBoundingBoxesDebounced, true);
130
+ }
147
131
 
148
- // `el` is the element you're detecting clicks outside of
149
- if (dropdown.value.contains(clickedElement)) {
150
- // do nothing..
151
- } else {
152
- close();
153
- }
132
+ function deactivate() {
133
+ window.removeEventListener('resize', setBoundingBoxesDebounced);
134
+ window.removeEventListener('scroll', setBoundingBoxesDebounced, true);
135
+ window.removeEventListener('keydown', onKeydown);
154
136
  }
155
137
 
138
+ useClickOutside(
139
+ dropdown,
140
+ (outside: boolean) => {
141
+ if (outside && showDropdown.value) {
142
+ close();
143
+ }
144
+ },
145
+ { includes: [button] }
146
+ );
147
+
156
148
  const placementInternal = computed(() => {
157
149
  const tooTallForTop =
158
150
  buttonY.value - dropdownHeight.value - props.padding < 0;
@@ -59,7 +59,10 @@
59
59
  <div class="flex flex-shrink-0 items-center px-4">
60
60
  <img class="block h-8 w-auto" :src="logoUrl" :alt="appName" />
61
61
  </div>
62
- <div class="mt-5 h-0 flex-1 overflow-y-auto">
62
+ <div
63
+ data-scroll-lock-scrollable
64
+ class="mt-5 h-0 flex-1 overflow-y-auto"
65
+ >
63
66
  <nav>
64
67
  <slot name="menu" />
65
68
  </nav>
@@ -7,9 +7,8 @@
7
7
  >
8
8
  <div v-show="modelValue">
9
9
  <div
10
- ref="allow"
10
+ data-scroll-lock-scrollable
11
11
  class="fixed inset-0 z-modal w-full overflow-y-auto overflow-x-hidden"
12
- scroll-lock-target
13
12
  >
14
13
  <div
15
14
  class="flex min-h-full w-full items-end justify-center overflow-hidden sm:px-6 sm:pb-6"
@@ -112,11 +111,8 @@ const props = defineProps({
112
111
 
113
112
  const emit = defineEmits(['update:modelValue']);
114
113
 
115
- const allow = ref(null);
116
-
117
114
  const modal = useModal(
118
115
  computed(() => props.modelValue),
119
- allow,
120
116
  emit as any
121
117
  );
122
118
  </script>
@@ -7,9 +7,8 @@
7
7
  >
8
8
  <div v-show="modelValue">
9
9
  <div
10
- ref="allow"
10
+ data-scroll-lock-scrollable
11
11
  class="fixed inset-0 z-modal w-full overflow-y-auto overflow-x-hidden"
12
- scroll-lock-target
13
12
  >
14
13
  <div class="flex min-h-full w-full pt-20 sm:pt-0">
15
14
  <div class="min-h-full grow">
@@ -97,10 +96,8 @@ const props = defineProps({
97
96
 
98
97
  const emit = defineEmits(['update:modelValue']);
99
98
 
100
- const allow = ref(null);
101
99
  const modal = useModal(
102
100
  computed(() => props.modelValue),
103
- allow,
104
101
  emit
105
102
  );
106
103
 
@@ -1,7 +1,10 @@
1
1
  <template>
2
2
  <nav aria-label="Sidebar" class="relative">
3
3
  <div class="absolute bottom-0 left-0 h-full w-px bg-slate-300" />
4
- <div class="relative overflow-x-auto overflow-y-hidden">
4
+ <div
5
+ class="relative overflow-x-auto overflow-y-hidden"
6
+ data-scroll-lock-scrollable
7
+ >
5
8
  <div class="space-y-2">
6
9
  <slot />
7
10
  </div>
@@ -7,6 +7,7 @@
7
7
  <div class="flex flex-col">
8
8
  <div
9
9
  class="overflow-x-auto overflow-y-auto"
10
+ data-scroll-lock-scrollable
10
11
  :style="{ maxHeight: maxHeight ? maxHeight + 'px' : undefined }"
11
12
  >
12
13
  <div class="inline-block min-w-full align-middle">
@@ -1,7 +1,10 @@
1
1
  <template>
2
2
  <div class="relative">
3
3
  <div class="absolute bottom-0 left-0 h-px w-full bg-slate-300" />
4
- <div class="relative overflow-x-auto overflow-y-hidden">
4
+ <div
5
+ class="relative overflow-x-auto overflow-y-hidden"
6
+ data-scroll-lock-scrollable
7
+ >
5
8
  <ul class="flex space-x-4 text-center">
6
9
  <slot />
7
10
  </ul>
@@ -58,6 +58,7 @@
58
58
  >
59
59
  <div
60
60
  ref="dropdown"
61
+ data-scroll-lock-scrollable
61
62
  class="max-h-[214px] min-h-[75px] w-full overflow-y-auto"
62
63
  >
63
64
  <slot v-if="filteredNormalizedOptions.length == 0" name="empty">
@@ -0,0 +1,57 @@
1
+ import { MaybeElementRef, unrefElement, tryOnScopeDispose } from '@vueuse/core';
2
+
3
+ interface UseClickOutsideOptions {
4
+ includes?: MaybeElementRef[];
5
+ }
6
+
7
+ export function useClickOutside(
8
+ element: MaybeElementRef,
9
+ callback: (outside: boolean) => void,
10
+ options: UseClickOutsideOptions = {}
11
+ ) {
12
+ function cleanup() {
13
+ window.removeEventListener('mousedown', onClick);
14
+ }
15
+
16
+ const stopWatch = watch(
17
+ () => unrefElement(element),
18
+ (el) => {
19
+ if (el) {
20
+ cleanup();
21
+ window.addEventListener('mousedown', onClick);
22
+ }
23
+ },
24
+ { immediate: true }
25
+ );
26
+
27
+ function onClick(e: Event) {
28
+ const el = unrefElement(element);
29
+
30
+ const includeEls = options.includes?.map(unrefElement) ?? [];
31
+
32
+ if (!el) {
33
+ return;
34
+ }
35
+
36
+ const contains = el.contains(e.target as HTMLElement);
37
+
38
+ const includeContainsEl = includeEls.some((exceptionEl) =>
39
+ exceptionEl?.contains(e.target as HTMLElement)
40
+ );
41
+
42
+ const outside = !contains && !includeContainsEl;
43
+
44
+ callback(outside);
45
+ }
46
+
47
+ const stop = () => {
48
+ cleanup();
49
+ stopWatch();
50
+ };
51
+
52
+ tryOnScopeDispose(stop);
53
+
54
+ return {
55
+ stop,
56
+ };
57
+ }
@@ -1,11 +1,7 @@
1
1
  import { disableScroll, enableScroll } from '../utils';
2
2
  import { Ref } from 'vue';
3
3
 
4
- export function useModal(
5
- modelValue: Ref<boolean>,
6
- scrollable: Ref<HTMLElement | null>,
7
- emit: any
8
- ) {
4
+ export function useModal(modelValue: Ref<boolean>, emit: any) {
9
5
  const mounted = ref(false);
10
6
 
11
7
  watch(
@@ -38,7 +34,7 @@ export function useModal(
38
34
  }
39
35
 
40
36
  function activate() {
41
- disableScroll(scrollable.value);
37
+ disableScroll();
42
38
  window.addEventListener('keydown', onKeydown);
43
39
  }
44
40
 
@@ -1,20 +1,10 @@
1
- import {
2
- disablePageScroll,
3
- clearQueueScrollLocks,
4
- enablePageScroll,
5
- ScrollableTarget,
6
- } from 'scroll-lock';
1
+ import { disablePageScroll, enablePageScroll } from 'scroll-lock';
7
2
 
8
- function disableScroll(allow: ScrollableTarget | null = null) {
9
- if (allow == null) {
10
- allow = document.querySelectorAll('[scroll-lock-target]');
11
- }
12
-
13
- disablePageScroll(allow);
3
+ function disableScroll() {
4
+ disablePageScroll();
14
5
  }
15
6
 
16
7
  function enableScroll() {
17
- clearQueueScrollLocks();
18
8
  enablePageScroll();
19
9
  }
20
10