Accessible unstyled Vue components inspired by Reakit.
Try it on Stackblitz.
npm i vue-arior
yarn add vue-ari<template>
<PopoverDisclosurev-bind="popover">
Open Popover
</PopoverDisclosure>
<Popoverv-bind="popover">
Popover Content
</Popover>
</template>
<script>import { Popover, PopoverDisclosure, usePopoverState } from'vue-ari'exportdefault { components: { Popover, PopoverDisclosure, },setup() {constpopover=usePopoverState()return { popover, } },}</script>Ari components don't include styling by default. This gives you the ability to add styles however you like.
<template>
<PopoverDisclosurev-bind="popover"
class="text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
>
Open Popover
</PopoverDisclosure>
<Popoverv-bind="popover"
class="rounded shadow-lg border border-solid border-gray-300 py-3 px-5 bg-white"
>
Popover Content
</Popover>
</template>
<script>import { Popover, PopoverDisclosure, usePopoverState } from'vue-ari'exportdefault { components: { Popover, PopoverDisclosure, },setup() {constpopover=usePopoverState()return { popover, } },}</script>It would get pretty verbose to add the same styling classes wherever you like to use a Popover. So the recommended way is wrapping Ari components inside your own base components and use them inside your app.
<template>
<PopoverDisclosurev-bind="$props"
class="text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
>
<slot />
</PopoverDisclosure>
</template>
<script>import { PopoverDisclosure, popoverDisclosureProps } from'vue-ari'exportdefault { name:'AppPopoverDisclosure', props: popoverDisclosureProps, components: { PopoverDisclosure, },}</script>If you would rather not create a modal state each time, just create a provider component.
Provider component:
<template>
<slot />
</template>
<script>import { provide } from'vue'import { useModalState } from'vue-ari'exportdefault { name:'AppModalProvider',setup() {provide('modalState', useModalState()) },}</script>Base component for disclosure:
<template>
<ModalDisclosurev-bind="modal"
class="text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
>
<slot />
</ModalDisclosure>
</template>
<script>import { inject } from'vue'import { ModalDisclosure } from'vue-ari'exportdefault { name:'AppModalDisclosure', components: { ModalDisclosure, },setup() {constmodal=inject('modalState')return { modal, } },}</script>Base component for modal:
<template>
<ModalBackdropv-bind="modal"
class="fixed inset-0 flex items-center justify-center bg-opacity-75 bg-black"
>
<Modalv-bind="{ ...modal, ...$attrs }"
class="max-w-xs rounded shadow-lg border border-solid border-gray-300 py-3 px-5 bg-white"
>
<slot />
</Modal>
</ModalBackdrop>
</template>
<script>import { inject } from'vue'import { Modal, ModalBackdrop } from'vue-ari'exportdefault { name:'AppModalDisclosure', components: { Modal, ModalBackdrop, }, inheritAttrs:false,setup() {constmodal=inject('modalState')return { modal, } },}</script>Inside your app:
<template>
<AppModalProvider>
<AppModalDisclosure>
Open Modal
</AppModalDisclosure>
<AppModal>
Modal Content
</AppModal>
</AppModalProvider>
</template>
<script>import { AppModalProvider, AppModal, AppModalDisclosure } from'./components'exportdefault { components: { AppModalProvider, AppModal, AppModalDisclosure, },}</script>