@alikhalilll/ui 1.2.2 → 1.2.4
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/dist/entries/drawer/components/ADrawer.vue.d.ts +1 -5
- package/dist/entries/drawer/components/ADrawerContent.vue.d.ts +1 -5
- package/dist/entries/drawer/components/ADrawerTrigger.vue.d.ts +1 -5
- package/dist/entries/input/components/AInput.vue.d.ts +1 -5
- package/dist/entries/popover/components/APopover.vue.d.ts +1 -5
- package/dist/entries/popover/components/APopoverContent.vue.d.ts +1 -5
- package/dist/entries/popover/components/APopoverTrigger.vue.d.ts +1 -5
- package/dist/entries/responsive-popover/components/AResponsivePopover.vue.d.ts +1 -5
- package/dist/entries/responsive-popover/components/AResponsivePopoverContent.vue.d.ts +1 -5
- package/dist/entries/responsive-popover/components/AResponsivePopoverTrigger.vue.d.ts +1 -5
- package/dist/entries/tell-input/components/ACountryFlag.vue.d.ts +1 -5
- package/dist/entries/tell-input/components/ACountrySelect.vue.d.ts +1 -5
- package/dist/entries/tell-input/components/ATellInput.vue.d.ts +1 -5
- package/entries/drawer/components/ADrawer.vue +16 -0
- package/entries/drawer/components/ADrawerContent.vue +35 -0
- package/entries/drawer/components/ADrawerOverlay.vue +25 -0
- package/entries/drawer/components/ADrawerTrigger.vue +13 -0
- package/entries/drawer/index.ts +4 -0
- package/entries/input/components/AInput.vue +111 -0
- package/entries/input/index.ts +1 -0
- package/entries/popover/components/APopover.vue +19 -0
- package/entries/popover/components/APopoverContent.vue +65 -0
- package/entries/popover/components/APopoverOverlay.vue +69 -0
- package/entries/popover/components/APopoverTrigger.vue +13 -0
- package/entries/popover/composables/useEventScrollLock.ts +193 -0
- package/entries/popover/index.ts +8 -0
- package/entries/responsive-popover/components/AResponsivePopover.vue +67 -0
- package/entries/responsive-popover/components/AResponsivePopoverContent.vue +80 -0
- package/entries/responsive-popover/components/AResponsivePopoverTrigger.vue +23 -0
- package/entries/responsive-popover/composables/useResponsivePopoverContext.ts +20 -0
- package/entries/responsive-popover/index.ts +3 -0
- package/entries/tell-input/components/ACountryFlag.vue +68 -0
- package/entries/tell-input/components/ACountrySelect.vue +522 -0
- package/entries/tell-input/components/ATellInput.vue +616 -0
- package/entries/tell-input/composables/useCountryDetection.ts +247 -0
- package/entries/tell-input/composables/useCountryMatching.ts +213 -0
- package/entries/tell-input/composables/usePhoneValidation.ts +573 -0
- package/entries/tell-input/composables/useTellInputValidation.ts +136 -0
- package/entries/tell-input/composables/useTypingPhase.ts +88 -0
- package/entries/tell-input/index.ts +29 -0
- package/entries/tell-input/utils/digits.ts +42 -0
- package/entries/tell-input/utils/flag-url.ts +10 -0
- package/entries/tell-input/utils/types.ts +169 -0
- package/package.json +4 -1
- package/utils/cn.ts +6 -0
- package/utils/index.ts +10 -0
- package/utils/sizes.ts +48 -0
|
@@ -23,9 +23,5 @@ declare const __VLS_base: import("vue").DefineComponent<DrawerRootProps, {}, {},
|
|
|
23
23
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
24
24
|
declare const _default: typeof __VLS_export;
|
|
25
25
|
export default _default;
|
|
26
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
27
|
-
new (): {
|
|
28
|
-
$slots: S;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
26
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
31
27
|
//# sourceMappingURL=ADrawer.vue.d.ts.map
|
|
@@ -25,9 +25,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
25
25
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
26
26
|
declare const _default: typeof __VLS_export;
|
|
27
27
|
export default _default;
|
|
28
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
29
|
-
new (): {
|
|
30
|
-
$slots: S;
|
|
31
|
-
};
|
|
32
|
-
};
|
|
28
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
33
29
|
//# sourceMappingURL=ADrawerContent.vue.d.ts.map
|
|
@@ -7,9 +7,5 @@ declare const __VLS_base: import("vue").DefineComponent<DrawerTriggerProps, {},
|
|
|
7
7
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
8
8
|
declare const _default: typeof __VLS_export;
|
|
9
9
|
export default _default;
|
|
10
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
11
|
-
new (): {
|
|
12
|
-
$slots: S;
|
|
13
|
-
};
|
|
14
|
-
};
|
|
10
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
15
11
|
//# sourceMappingURL=ADrawerTrigger.vue.d.ts.map
|
|
@@ -28,9 +28,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
28
28
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
29
29
|
declare const _default: typeof __VLS_export;
|
|
30
30
|
export default _default;
|
|
31
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
32
|
-
new (): {
|
|
33
|
-
$slots: S;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
31
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
36
32
|
//# sourceMappingURL=AInput.vue.d.ts.map
|
|
@@ -16,9 +16,5 @@ declare const __VLS_base: import("vue").DefineComponent<PopoverRootProps, {}, {}
|
|
|
16
16
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
17
17
|
declare const _default: typeof __VLS_export;
|
|
18
18
|
export default _default;
|
|
19
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
20
|
-
new (): {
|
|
21
|
-
$slots: S;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
19
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
24
20
|
//# sourceMappingURL=APopover.vue.d.ts.map
|
|
@@ -40,9 +40,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
40
40
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
41
41
|
declare const _default: typeof __VLS_export;
|
|
42
42
|
export default _default;
|
|
43
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
44
|
-
new (): {
|
|
45
|
-
$slots: S;
|
|
46
|
-
};
|
|
47
|
-
};
|
|
43
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
48
44
|
//# sourceMappingURL=APopoverContent.vue.d.ts.map
|
|
@@ -7,9 +7,5 @@ declare const __VLS_base: import("vue").DefineComponent<PopoverTriggerProps, {},
|
|
|
7
7
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
8
8
|
declare const _default: typeof __VLS_export;
|
|
9
9
|
export default _default;
|
|
10
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
11
|
-
new (): {
|
|
12
|
-
$slots: S;
|
|
13
|
-
};
|
|
14
|
-
};
|
|
10
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
15
11
|
//# sourceMappingURL=APopoverTrigger.vue.d.ts.map
|
|
@@ -42,9 +42,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
42
42
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
43
43
|
declare const _default: typeof __VLS_export;
|
|
44
44
|
export default _default;
|
|
45
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
46
|
-
new (): {
|
|
47
|
-
$slots: S;
|
|
48
|
-
};
|
|
49
|
-
};
|
|
45
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
50
46
|
//# sourceMappingURL=AResponsivePopover.vue.d.ts.map
|
|
@@ -31,9 +31,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
31
31
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
32
32
|
declare const _default: typeof __VLS_export;
|
|
33
33
|
export default _default;
|
|
34
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
35
|
-
new (): {
|
|
36
|
-
$slots: S;
|
|
37
|
-
};
|
|
38
|
-
};
|
|
34
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
39
35
|
//# sourceMappingURL=AResponsivePopoverContent.vue.d.ts.map
|
|
@@ -12,9 +12,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
12
12
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
13
13
|
declare const _default: typeof __VLS_export;
|
|
14
14
|
export default _default;
|
|
15
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
16
|
-
new (): {
|
|
17
|
-
$slots: S;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
15
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
20
16
|
//# sourceMappingURL=AResponsivePopoverTrigger.vue.d.ts.map
|
|
@@ -22,9 +22,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
22
22
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
23
23
|
declare const _default: typeof __VLS_export;
|
|
24
24
|
export default _default;
|
|
25
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
26
|
-
new (): {
|
|
27
|
-
$slots: S;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
25
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
30
26
|
//# sourceMappingURL=ACountryFlag.vue.d.ts.map
|
|
@@ -132,9 +132,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
132
132
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
133
133
|
declare const _default: typeof __VLS_export;
|
|
134
134
|
export default _default;
|
|
135
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
136
|
-
new (): {
|
|
137
|
-
$slots: S;
|
|
138
|
-
};
|
|
139
|
-
};
|
|
135
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
140
136
|
//# sourceMappingURL=ACountrySelect.vue.d.ts.map
|
|
@@ -137,9 +137,5 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
137
137
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
138
138
|
declare const _default: typeof __VLS_export;
|
|
139
139
|
export default _default;
|
|
140
|
-
type __VLS_WithSlots<T, S> = T & {
|
|
141
|
-
new (): {
|
|
142
|
-
$slots: S;
|
|
143
|
-
};
|
|
144
|
-
};
|
|
140
|
+
type __VLS_WithSlots<T, S> = T & (new () => (T extends new (...args: any) => infer R ? R : {}) & { $slots: S });
|
|
145
141
|
//# sourceMappingURL=ATellInput.vue.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { DrawerRoot, type DrawerRootEmits, type DrawerRootProps } from 'vaul-vue';
|
|
3
|
+
import { useForwardPropsEmits } from 'reka-ui';
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<DrawerRootProps>(), {
|
|
6
|
+
shouldScaleBackground: true,
|
|
7
|
+
});
|
|
8
|
+
const emits = defineEmits<DrawerRootEmits>();
|
|
9
|
+
const forwarded = useForwardPropsEmits(props, emits);
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<DrawerRoot data-slot="drawer" v-bind="forwarded">
|
|
14
|
+
<slot />
|
|
15
|
+
</DrawerRoot>
|
|
16
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { DrawerContent, DrawerPortal } from 'vaul-vue';
|
|
4
|
+
import type { DialogContentEmits, DialogContentProps } from 'reka-ui';
|
|
5
|
+
import { reactiveOmit } from '@vueuse/core';
|
|
6
|
+
import { useForwardPropsEmits } from 'reka-ui';
|
|
7
|
+
import { cn } from '@/utils';
|
|
8
|
+
import ADrawerOverlay from './ADrawerOverlay.vue';
|
|
9
|
+
|
|
10
|
+
defineOptions({ inheritAttrs: false });
|
|
11
|
+
|
|
12
|
+
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>();
|
|
13
|
+
const emits = defineEmits<DialogContentEmits>();
|
|
14
|
+
const delegated = reactiveOmit(props, 'class');
|
|
15
|
+
const forwarded = useForwardPropsEmits(delegated, emits);
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<DrawerPortal>
|
|
20
|
+
<ADrawerOverlay />
|
|
21
|
+
<DrawerContent
|
|
22
|
+
data-slot="drawer-content"
|
|
23
|
+
v-bind="{ ...$attrs, ...forwarded }"
|
|
24
|
+
:class="
|
|
25
|
+
cn(
|
|
26
|
+
'bg-background fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] shadow-2xl shadow-black/30 outline-none',
|
|
27
|
+
props.class
|
|
28
|
+
)
|
|
29
|
+
"
|
|
30
|
+
>
|
|
31
|
+
<div class="bg-muted mx-auto mt-4 h-2 w-[100px] rounded-full" />
|
|
32
|
+
<slot />
|
|
33
|
+
</DrawerContent>
|
|
34
|
+
</DrawerPortal>
|
|
35
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { DrawerOverlay } from 'vaul-vue';
|
|
4
|
+
import type { DialogOverlayProps } from 'reka-ui';
|
|
5
|
+
import { reactiveOmit } from '@vueuse/core';
|
|
6
|
+
import { useForwardProps } from 'reka-ui';
|
|
7
|
+
import { cn } from '@/utils';
|
|
8
|
+
|
|
9
|
+
const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>();
|
|
10
|
+
const delegated = reactiveOmit(props, 'class');
|
|
11
|
+
const forwarded = useForwardProps(delegated);
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<DrawerOverlay
|
|
16
|
+
data-slot="drawer-overlay"
|
|
17
|
+
v-bind="forwarded"
|
|
18
|
+
:class="
|
|
19
|
+
cn(
|
|
20
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-40 bg-black/70',
|
|
21
|
+
props.class
|
|
22
|
+
)
|
|
23
|
+
"
|
|
24
|
+
/>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { DrawerTrigger, type DrawerTriggerProps } from 'vaul-vue';
|
|
3
|
+
import { useForwardProps } from 'reka-ui';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<DrawerTriggerProps>();
|
|
6
|
+
const forwarded = useForwardProps(props);
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<DrawerTrigger data-slot="drawer-trigger" v-bind="forwarded">
|
|
11
|
+
<slot />
|
|
12
|
+
</DrawerTrigger>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as ADrawer } from './components/ADrawer.vue';
|
|
2
|
+
export { default as ADrawerTrigger } from './components/ADrawerTrigger.vue';
|
|
3
|
+
export { default as ADrawerContent } from './components/ADrawerContent.vue';
|
|
4
|
+
export { default as ADrawerOverlay } from './components/ADrawerOverlay.vue';
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { computed, useSlots } from 'vue';
|
|
4
|
+
import { useVModel } from '@vueuse/core';
|
|
5
|
+
import { cn } from '@/utils';
|
|
6
|
+
import { controlHeight, controlPaddingX, controlTextSize, DEFAULT_SIZE, type Size } from '@/utils';
|
|
7
|
+
|
|
8
|
+
const props = withDefaults(
|
|
9
|
+
defineProps<{
|
|
10
|
+
defaultValue?: string | number;
|
|
11
|
+
modelValue?: string | number;
|
|
12
|
+
class?: HTMLAttributes['class'];
|
|
13
|
+
/** Classes for the inner <input> element (useful when prefix/suffix are present). */
|
|
14
|
+
inputClass?: HTMLAttributes['class'];
|
|
15
|
+
/** Classes for the prefix wrapper. */
|
|
16
|
+
prefixClass?: HTMLAttributes['class'];
|
|
17
|
+
/** Classes for the suffix wrapper. */
|
|
18
|
+
suffixClass?: HTMLAttributes['class'];
|
|
19
|
+
size?: Size;
|
|
20
|
+
}>(),
|
|
21
|
+
{ size: DEFAULT_SIZE }
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const emits = defineEmits<{
|
|
25
|
+
(e: 'update:modelValue', payload: string | number): void;
|
|
26
|
+
}>();
|
|
27
|
+
|
|
28
|
+
defineSlots<{
|
|
29
|
+
/** Content rendered inside the input's border, left of the field. */
|
|
30
|
+
prefix?: () => unknown;
|
|
31
|
+
/** Content rendered inside the input's border, right of the field. */
|
|
32
|
+
suffix?: () => unknown;
|
|
33
|
+
}>();
|
|
34
|
+
|
|
35
|
+
const slots = useSlots();
|
|
36
|
+
const hasPrefix = computed(() => !!slots.prefix);
|
|
37
|
+
const hasSuffix = computed(() => !!slots.suffix);
|
|
38
|
+
const hasAdornment = computed(() => hasPrefix.value || hasSuffix.value);
|
|
39
|
+
|
|
40
|
+
const modelValue = useVModel(props, 'modelValue', emits, {
|
|
41
|
+
passive: true,
|
|
42
|
+
defaultValue: props.defaultValue,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const sizeHeight = computed(() => controlHeight[props.size]);
|
|
46
|
+
const sizePaddingX = computed(() => controlPaddingX[props.size]);
|
|
47
|
+
const sizeText = computed(() => controlTextSize[props.size]);
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<!--
|
|
52
|
+
When prefix or suffix slots are filled we render a wrapper that owns the border,
|
|
53
|
+
background and focus ring — so the visible "input" is the whole bar, not just the
|
|
54
|
+
native element. Otherwise we render the plain native input directly so consumers
|
|
55
|
+
can use AInput as a drop-in for <input>.
|
|
56
|
+
-->
|
|
57
|
+
<div
|
|
58
|
+
v-if="hasAdornment"
|
|
59
|
+
:data-size="props.size"
|
|
60
|
+
:class="
|
|
61
|
+
cn(
|
|
62
|
+
'border-input bg-background ring-offset-background focus-within:ring-ring inline-flex w-full items-center rounded-md border shadow-sm transition-colors focus-within:ring-1',
|
|
63
|
+
sizeHeight,
|
|
64
|
+
sizePaddingX,
|
|
65
|
+
sizeText,
|
|
66
|
+
props.class
|
|
67
|
+
)
|
|
68
|
+
"
|
|
69
|
+
>
|
|
70
|
+
<span
|
|
71
|
+
v-if="hasPrefix"
|
|
72
|
+
:class="cn('text-muted-foreground flex shrink-0 items-center pr-2', props.prefixClass)"
|
|
73
|
+
>
|
|
74
|
+
<slot name="prefix" />
|
|
75
|
+
</span>
|
|
76
|
+
|
|
77
|
+
<input
|
|
78
|
+
v-model="modelValue"
|
|
79
|
+
data-slot="input"
|
|
80
|
+
:class="
|
|
81
|
+
cn(
|
|
82
|
+
'placeholder:text-muted-foreground h-full min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
83
|
+
props.inputClass
|
|
84
|
+
)
|
|
85
|
+
"
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
<span
|
|
89
|
+
v-if="hasSuffix"
|
|
90
|
+
:class="cn('text-muted-foreground flex shrink-0 items-center pl-2', props.suffixClass)"
|
|
91
|
+
>
|
|
92
|
+
<slot name="suffix" />
|
|
93
|
+
</span>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<input
|
|
97
|
+
v-else
|
|
98
|
+
v-model="modelValue"
|
|
99
|
+
data-slot="input"
|
|
100
|
+
:data-size="props.size"
|
|
101
|
+
:class="
|
|
102
|
+
cn(
|
|
103
|
+
'border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex w-full rounded-md border py-1 shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
104
|
+
sizeHeight,
|
|
105
|
+
sizePaddingX,
|
|
106
|
+
sizeText,
|
|
107
|
+
props.class
|
|
108
|
+
)
|
|
109
|
+
"
|
|
110
|
+
/>
|
|
111
|
+
</template>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as AInput } from './components/AInput.vue';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PopoverRootEmits, PopoverRootProps } from 'reka-ui';
|
|
3
|
+
import { PopoverRoot, useForwardPropsEmits } from 'reka-ui';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Defaults `modal` to `true` so the popover locks page scroll, traps focus, and an overlay
|
|
7
|
+
* (rendered by APopoverContent when `overlay` is set) actually dims the page.
|
|
8
|
+
* Pass `:modal="false"` for tooltip-style non-modal popovers.
|
|
9
|
+
*/
|
|
10
|
+
const props = withDefaults(defineProps<PopoverRootProps>(), { modal: true });
|
|
11
|
+
const emits = defineEmits<PopoverRootEmits>();
|
|
12
|
+
const forwarded = useForwardPropsEmits(props, emits);
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<PopoverRoot v-slot="slotProps" data-slot="popover" v-bind="forwarded">
|
|
17
|
+
<slot v-bind="slotProps" />
|
|
18
|
+
</PopoverRoot>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { reactiveOmit } from '@vueuse/core';
|
|
4
|
+
import {
|
|
5
|
+
PopoverContent,
|
|
6
|
+
type PopoverContentEmits,
|
|
7
|
+
type PopoverContentProps,
|
|
8
|
+
PopoverPortal,
|
|
9
|
+
useForwardPropsEmits,
|
|
10
|
+
} from 'reka-ui';
|
|
11
|
+
import { cn } from '@/utils';
|
|
12
|
+
import APopoverOverlay from './APopoverOverlay.vue';
|
|
13
|
+
|
|
14
|
+
defineOptions({ inheritAttrs: false });
|
|
15
|
+
|
|
16
|
+
const props = withDefaults(
|
|
17
|
+
defineProps<
|
|
18
|
+
PopoverContentProps & {
|
|
19
|
+
class?: HTMLAttributes['class'];
|
|
20
|
+
/** Dim the entire viewport behind the popover and block all interaction with the
|
|
21
|
+
* page (clicks are captured by the overlay). Pair with `<APopover :modal="true">`
|
|
22
|
+
* (the default) for the full modal behaviour. */
|
|
23
|
+
overlay?: boolean;
|
|
24
|
+
overlayClass?: HTMLAttributes['class'];
|
|
25
|
+
/**
|
|
26
|
+
* When true, the overlay also locks page scroll via `body { overflow: hidden }`.
|
|
27
|
+
* Off by default — `AResponsivePopover` opts in to this when `scrollLock="body"`.
|
|
28
|
+
*/
|
|
29
|
+
overlayLockScroll?: boolean;
|
|
30
|
+
}
|
|
31
|
+
>(),
|
|
32
|
+
{ align: 'center', sideOffset: 4, overlay: false, overlayLockScroll: false }
|
|
33
|
+
);
|
|
34
|
+
const emits = defineEmits<PopoverContentEmits>();
|
|
35
|
+
const delegated = reactiveOmit(props, 'class', 'overlay', 'overlayClass', 'overlayLockScroll');
|
|
36
|
+
const forwarded = useForwardPropsEmits(delegated, emits);
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<PopoverPortal>
|
|
41
|
+
<!--
|
|
42
|
+
Overlay is a sibling of PopoverContent inside the same portal. Reka-ui's
|
|
43
|
+
DismissableLayer treats any pointer-down outside the content as a dismiss,
|
|
44
|
+
so clicking the overlay closes the popover for free. The overlay component
|
|
45
|
+
locks body scroll on mount and restores it on unmount.
|
|
46
|
+
-->
|
|
47
|
+
<APopoverOverlay
|
|
48
|
+
v-if="props.overlay"
|
|
49
|
+
:class="props.overlayClass"
|
|
50
|
+
:lock-scroll="props.overlayLockScroll"
|
|
51
|
+
/>
|
|
52
|
+
<PopoverContent
|
|
53
|
+
data-slot="popover-content"
|
|
54
|
+
v-bind="{ ...$attrs, ...forwarded }"
|
|
55
|
+
:class="
|
|
56
|
+
cn(
|
|
57
|
+
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-[60] w-72 rounded-md border border-border/70 p-4 shadow-xl shadow-black/15 outline-none',
|
|
58
|
+
props.class
|
|
59
|
+
)
|
|
60
|
+
"
|
|
61
|
+
>
|
|
62
|
+
<slot />
|
|
63
|
+
</PopoverContent>
|
|
64
|
+
</PopoverPortal>
|
|
65
|
+
</template>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { onBeforeUnmount, onMounted } from 'vue';
|
|
4
|
+
import { cn } from '@/utils';
|
|
5
|
+
|
|
6
|
+
defineOptions({ inheritAttrs: false });
|
|
7
|
+
|
|
8
|
+
const props = withDefaults(
|
|
9
|
+
defineProps<{
|
|
10
|
+
class?: HTMLAttributes['class'];
|
|
11
|
+
/**
|
|
12
|
+
* When true, set `body { overflow: hidden; touchAction: none }` for the lifetime of
|
|
13
|
+
* the overlay. Off by default because it breaks `position: sticky` on the host page.
|
|
14
|
+
* Prefer the event-based lock (see `AResponsivePopover`'s `scrollLock` prop) which
|
|
15
|
+
* keeps the page scrollbar in place.
|
|
16
|
+
*/
|
|
17
|
+
lockScroll?: boolean;
|
|
18
|
+
}>(),
|
|
19
|
+
{ lockScroll: false }
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
let prevBodyOverflow = '';
|
|
23
|
+
let prevBodyTouchAction = '';
|
|
24
|
+
let prevPaddingRight = '';
|
|
25
|
+
|
|
26
|
+
function getScrollbarWidth() {
|
|
27
|
+
if (typeof window === 'undefined') return 0;
|
|
28
|
+
return window.innerWidth - document.documentElement.clientWidth;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
onMounted(() => {
|
|
32
|
+
if (!props.lockScroll) return;
|
|
33
|
+
if (typeof document === 'undefined') return;
|
|
34
|
+
const body = document.body;
|
|
35
|
+
const sbw = getScrollbarWidth();
|
|
36
|
+
prevBodyOverflow = body.style.overflow;
|
|
37
|
+
prevBodyTouchAction = body.style.touchAction;
|
|
38
|
+
prevPaddingRight = body.style.paddingRight;
|
|
39
|
+
body.style.overflow = 'hidden';
|
|
40
|
+
body.style.touchAction = 'none';
|
|
41
|
+
// Compensate for the missing scrollbar so the layout doesn't jump.
|
|
42
|
+
if (sbw > 0) body.style.paddingRight = `${sbw}px`;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
onBeforeUnmount(() => {
|
|
46
|
+
if (!props.lockScroll) return;
|
|
47
|
+
if (typeof document === 'undefined') return;
|
|
48
|
+
const body = document.body;
|
|
49
|
+
body.style.overflow = prevBodyOverflow;
|
|
50
|
+
body.style.touchAction = prevBodyTouchAction;
|
|
51
|
+
body.style.paddingRight = prevPaddingRight;
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<template>
|
|
56
|
+
<div
|
|
57
|
+
data-slot="popover-overlay"
|
|
58
|
+
aria-hidden="true"
|
|
59
|
+
:class="
|
|
60
|
+
cn(
|
|
61
|
+
// `fixed inset-0` covers the entire viewport; `pointer-events-auto` captures every
|
|
62
|
+
// click so it can never reach the page underneath. `z-50` keeps us above any normal
|
|
63
|
+
// page chrome; the popover content sits at `z-[60]`.
|
|
64
|
+
'fixed inset-0 z-50 bg-black/70 pointer-events-auto data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
65
|
+
props.class
|
|
66
|
+
)
|
|
67
|
+
"
|
|
68
|
+
/>
|
|
69
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PopoverTriggerProps } from 'reka-ui';
|
|
3
|
+
import { PopoverTrigger, useForwardProps } from 'reka-ui';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<PopoverTriggerProps>();
|
|
6
|
+
const forwarded = useForwardProps(props);
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<PopoverTrigger data-slot="popover-trigger" v-bind="forwarded">
|
|
11
|
+
<slot />
|
|
12
|
+
</PopoverTrigger>
|
|
13
|
+
</template>
|