Skip to content

visualjerk/ari

This branch is 1 commit ahead of master.

Folders and files

NameName
Last commit message
Last commit date
Jan 22, 2022
Jul 28, 2020
Jan 22, 2022
Mar 21, 2022
Mar 24, 2022
Jan 22, 2022
Jan 22, 2022
Jul 29, 2020
Jul 29, 2020
Jul 27, 2020
Aug 8, 2022
Jul 21, 2020
Jan 22, 2022
Mar 24, 2022
Jul 21, 2020
Jan 22, 2022
Jan 22, 2022
Dec 6, 2022

Repository files navigation

Ari

CI Test Coverage

Accessible unstyled Vue components inspired by Reakit.

Try it on Stackblitz.

Installation

npm i vue-ari

or

yarn add vue-ari

Usage

<template>
  <PopoverDisclosure v-bind="popover">
    Open Popover
  </PopoverDisclosure>
  <Popover v-bind="popover">
    Popover Content
  </Popover>
</template>

<script>
import { Popover, PopoverDisclosure, usePopoverState } from 'vue-ari'

export default {
  components: {
    Popover,
    PopoverDisclosure,
  },
  setup() {
    const popover = usePopoverState()
    return {
      popover,
    }
  },
}
</script>

Styling

Ari components don't include styling by default. This gives you the ability to add styles however you like.

Example Using Tailwind

<template>
  <PopoverDisclosure
    v-bind="popover"
    class="text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
  >
    Open Popover
  </PopoverDisclosure>
  <Popover
    v-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'

export default {
  components: {
    Popover,
    PopoverDisclosure,
  },
  setup() {
    const popover = usePopoverState()
    return {
      popover,
    }
  },
}
</script>

Reusable Components

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>
  <PopoverDisclosure
    v-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'

export default {
  name: 'AppPopoverDisclosure',
  props: popoverDisclosureProps,
  components: {
    PopoverDisclosure,
  },
}
</script>

Abstracting State

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'

export default {
  name: 'AppModalProvider',
  setup() {
    provide('modalState', useModalState())
  },
}
</script>

Base component for disclosure:

<template>
  <ModalDisclosure
    v-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'

export default {
  name: 'AppModalDisclosure',
  components: {
    ModalDisclosure,
  },
  setup() {
    const modal = inject('modalState')
    return {
      modal,
    }
  },
}
</script>

Base component for modal:

<template>
  <ModalBackdrop
    v-bind="modal"
    class="fixed inset-0 flex items-center justify-center bg-opacity-75 bg-black"
  >
    <Modal
      v-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'

export default {
  name: 'AppModalDisclosure',
  components: {
    Modal,
    ModalBackdrop,
  },
  inheritAttrs: false,
  setup() {
    const modal = 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'

export default {
  components: {
    AppModalProvider,
    AppModal,
    AppModalDisclosure,
  },
}
</script>