Skip to content

Commit

Permalink
ready all api
Browse files Browse the repository at this point in the history
  • Loading branch information
zernonia committed Aug 16, 2023
1 parent 6c1aa83 commit 258e6f7
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 22 deletions.
7 changes: 5 additions & 2 deletions packages/radix-vue/src/Select/SelectArrow.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
<script setup lang="ts">
import { PopperArrow } from "@/Popper";
import { inject } from "vue";
import { PopperArrow, type PopperArrowProps } from "@/Popper";
import { getCurrentInstance, inject } from "vue";
import { SELECT_INJECTION_KEY } from "./SelectRoot.vue";
import { SELECT_CONTENT_INJECTION_KEY } from "./SelectContentImpl.vue";
const context = inject(SELECT_INJECTION_KEY);
const contentContext = inject(SELECT_CONTENT_INJECTION_KEY);
const props = defineProps<PopperArrowProps>();
</script>

<template>
<PopperArrow
v-if="context?.open.value && contentContext?.position === 'popper'"
v-bind="props"
>
<slot></slot>
</PopperArrow>
Expand Down
9 changes: 8 additions & 1 deletion packages/radix-vue/src/Select/SelectContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@
import { inject } from "vue";
import SelectContentImpl, {
type SelectContentImplProps,
type SelectContentImplEmits,
} from "./SelectContentImpl.vue";
import { Presence } from "@/Presence";
import { SELECT_INJECTION_KEY } from "./SelectRoot.vue";
import { useEmitAsProps } from "@/shared";
interface SelectContentProps extends SelectContentImplProps {}
interface SelectContentEmits extends SelectContentImplEmits {}
const context = inject(SELECT_INJECTION_KEY);
const props = defineProps<SelectContentProps>();
const emits = defineEmits<SelectContentEmits>();
const emitsAsProps = useEmitAsProps(emits);
</script>

<template>
<Presence :present="context!.open.value">
<SelectContentImpl v-bind="props">
<SelectContentImpl v-bind="{ ...props, ...emitsAsProps }">
<slot></slot>
</SelectContentImpl>
</Presence>
Expand Down
50 changes: 36 additions & 14 deletions packages/radix-vue/src/Select/SelectContentImpl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ export const SELECT_CONTENT_INJECTION_KEY =
export interface SelectContentImplProps extends PopperContentProps {
position?: "item-aligned" | "popper";
}
export interface SelectContentImplEmits {
(e: "closeAutoFocus", event: Event): void;
/**
* Event handler called when the escape key is down.
* Can be prevented.
*/
(e: "escapeKeyDown", event: KeyboardEvent): void;
/**
* Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`.
* Can be prevented.
*/
(e: "pointerDownOutside", event: PointerDownOutsideEvent): void;
}
</script>

<script setup lang="ts">
Expand All @@ -40,6 +54,7 @@ import {
watchEffect,
provide,
type ComponentPublicInstance,
computed,
} from "vue";
import { SELECT_INJECTION_KEY } from "./SelectRoot.vue";
import {
Expand All @@ -49,7 +64,10 @@ import {
useTypeahead,
} from "@/shared";
import { FocusScope } from "@/FocusScope";
import { DismissableLayer } from "@/DismissableLayer";
import {
DismissableLayer,
type PointerDownOutsideEvent,
} from "@/DismissableLayer";
import { focusFirst } from "@/Menu/utils";
import type { PopperContentProps } from "@/Popper";
import SelectItemAlignedPosition from "./SelectItemAlignedPosition.vue";
Expand All @@ -59,6 +77,7 @@ import { unrefElement } from "@vueuse/core";
const props = withDefaults(defineProps<SelectContentImplProps>(), {
position: "item-aligned",
});
const emits = defineEmits<SelectContentImplEmits>();
const context = inject(SELECT_INJECTION_KEY);
Expand All @@ -80,6 +99,7 @@ const firstValidItemFoundRef = ref(false);
// React.useEffect(() => {
// if (content) return hideOthers(content);
// }, [content]);
const focusSelectedItem = () => {
if (selectedItem.value && content.value) {
focusFirst([selectedItem.value, content.value]);
Expand Down Expand Up @@ -137,16 +157,6 @@ watchEffect((cleanupFn) => {
});
});
watchEffect((cleanupFn) => {
// const close = () => onOpenChange(false);
// window.addEventListener("blur", close);
// window.addEventListener("resize", close);
// cleanupFn(() => {
// window.removeEventListener("blur", close);
// window.removeEventListener("resize", close);
// });
});
const handleKeyDown = (event: KeyboardEvent) => {
const isModifierKey = event.ctrlKey || event.altKey || event.metaKey;
Expand Down Expand Up @@ -178,6 +188,11 @@ const handleKeyDown = (event: KeyboardEvent) => {
}
};
const pickedProps = computed(() => {
if (props.position === "popper") return props;
else return {};
});
provide(SELECT_CONTENT_INJECTION_KEY, {
content,
viewport,
Expand Down Expand Up @@ -219,15 +234,22 @@ provide(SELECT_CONTENT_INJECTION_KEY, {
<FocusScope
asChild
@mount-auto-focus.prevent
@unmount-auto-focus.prevent="
context?.triggerElement.value?.focus({ preventScroll: true })
@unmount-auto-focus="
(event) => {
emits('closeAutoFocus', event);
if (event.defaultPrevented) return;
context?.triggerElement.value?.focus({ preventScroll: true });
event.preventDefault();
}
"
>
<DismissableLayer
asChild
disableOutsidePointerEvents
@focus-outside.prevent
@dismiss="context?.onOpenChange(false)"
@escape-key-down="emits('escapeKeyDown', $event)"
@pointer-down-outside="emits('pointerDownOutside', $event)"
>
<component
:ref="
Expand All @@ -241,7 +263,7 @@ provide(SELECT_CONTENT_INJECTION_KEY, {
? SelectPopperPosition
: SelectItemAlignedPosition
"
v-bind="$attrs"
v-bind="{ ...$attrs, ...pickedProps }"
role="listbox"
:id="context?.contentId"
:data-state="context?.open.value ? 'open' : 'closed'"
Expand Down
4 changes: 3 additions & 1 deletion packages/radix-vue/src/Select/SelectItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const handleKeyDown = async (event: KeyboardEvent) => {
if (props.value === "") {
throw new Error(
"A <Select.Item /> must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder."
"A <SelectItem /> must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder."
);
}
Expand Down Expand Up @@ -128,6 +128,8 @@ provide(SELECT_ITEM_INJECTION_KEY, {
:aria-disabled="disabled || undefined"
:data-disabled="disabled ? '' : undefined"
:tabIndex="disabled ? undefined : -1"
:as="as"
:as-child="asChild"
@focus="isFocused = true"
@blur="isFocused = false"
@pointerup="handleSelect"
Expand Down
2 changes: 1 addition & 1 deletion packages/radix-vue/src/Select/SelectRoot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const props = withDefaults(defineProps<SelectRootProps>(), {
orientation: "vertical",
defaultValue: "",
modelValue: "",
open: false,
open: undefined,
dir: "ltr",
});
Expand Down
4 changes: 2 additions & 2 deletions packages/radix-vue/src/Select/SelectTrigger.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface SelectTriggerProps extends PrimitiveProps {
</script>

<script setup lang="ts">
import { computed, inject, nextTick, onMounted } from "vue";
import { computed, inject, onMounted } from "vue";
import {
Primitive,
usePrimitiveElement,
Expand Down Expand Up @@ -55,7 +55,7 @@ const handleOpen = () => {
:type="as === 'button' ? 'button' : undefined"
:aria-controls="context?.contentId"
:aria-expanded="context?.open.value || false"
:aria-required="context?.required"
:aria-required="context?.required?.value"
aria-autocomplete="none"
:dir="context?.dir.value"
:data-state="context?.open.value ? 'open' : 'closed'"
Expand Down
2 changes: 1 addition & 1 deletion packages/radix-vue/src/Select/story/SelectDemo.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
SelectScrollDownButton,
} from "../";
const fruit = ref("Apple");
const fruit = ref("");
const options = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
const vegetables = ["Aubergine", "Broccoli", "Carrot", "Courgette", "Leek"];
Expand Down

0 comments on commit 258e6f7

Please sign in to comment.