Skip to content

Commit

Permalink
feat: added plugin based context registration and readme
Browse files Browse the repository at this point in the history
  • Loading branch information
lajoskvcs committed Nov 17, 2022
1 parent 4665ddd commit 7f1e3d7
Show file tree
Hide file tree
Showing 19 changed files with 383 additions and 159 deletions.
112 changes: 112 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,115 @@

[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
[![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/71d84733b1b948c380e87d02f49f684f)](https://www.codacy.com/gh/dwmt/modalis/dashboard?utm_source=github.com&utm_medium=referral&utm_content=dwmt/modalis&utm_campaign=Badge_Grade)

We should have a nice description, but we are lazy.. 🤷‍♂️

## Table of contents

- [Installation](#installation)
- [Preparation](#preparation)
- [The Provider component way (Recommended)](#the-provider-component-way--recommended-)
- [The Vue plugin way](#the-vue-plugin-way)
- [Modals](#modals)

## Installation

Npm:

```sh
npm i @dwmt/modalis
```

Yarn:

```sh
yarn add @dwmt/modalis
```

Pnpm:

```sh
pnpm i @dwmt/modalis
```

## Preparation

We will need to create a `ModalisContext` because each open modal will be registered in that context. We have two possible options for you:

1. The Provider component way (Recommended)
2. The Vue plugin way

### The Provider component way (Recommended)

First, you have to wrap your application with the `ModalisProvider` component, which will give you the possibility to use Modalis within your components. `ModalisProvider` does two things:

1. It creates a context, so you can access that context anywhere in your application
2. It renders the open modals and teleports them into the body

To achieve that, you only need to import `ModalisProvider` and wrap your app with it.

App.vue:

```vue
<template>
<ModalisProvider>
<router-view></router-view>
</ModalisProvider>
</template>
<script lang="ts" setup>
import { ModalisProvider } from '@dwmt/modalis'
</script>
```

With that, every single component inside `ModalisProvider` can open up a modal.

> Attention!
> Only `ModalisProvider`'s children can access modalis. If you try to open a modal in a component, which is not the descendant of `ModalisProvider`, your code will fail!
### The Vue plugin way

The old way to register Modalis is to install it with Vue's plugin system.

```typescript
import { createApp } from 'vue'
import { createContext } from '@dwmt/modalis'
import App from './App.vue'

const modalisContext = createContext()

createApp(App).use(modalisContext).mount('#app')
```

With that approach, your entire application can access the Modalis context.

You also need to render the modals, so you will need the `ModalView` too.

```vue
<template>
<div>
<router-view></router-view>
<ModalisView />
</div>
</template>
<script lang="ts" setup>
import { ModalisView } from '@dwmt/modalis'
</script>
```

## Modals

Cool! 🎉 You are all set. Now you can create and show modals. But... how?

Let us show you!

### Creating a modal configuration

The first step on the path of the modals is the `createModal` function. With that function, you can create a configuration object, which will represent how your newly created modal will behave.

The `createModal` function has two generic types:

1. DataType
2. ReturnType

By default both the `DataType` and `ReturnType` are `void`. That means, you can call your modal without parameters, and it won't return any value.
27 changes: 27 additions & 0 deletions development/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineComponent } from 'vue'
import { ModalisProvider, ModalisView } from '../src'
import { Page } from './Page'

export const AppWithUse = defineComponent({
setup() {
return () => (
<div>
<h1>Application with ModalisView and vue plugin</h1>
<Page />
<ModalisView />
</div>
)
},
})
export const AppWithProvider = defineComponent({
setup() {
return () => (
<div>
<h1>Application with ModalisProvider</h1>
<ModalisProvider>
<Page />
</ModalisProvider>
</div>
)
},
})
17 changes: 0 additions & 17 deletions development/App.vue

This file was deleted.

40 changes: 40 additions & 0 deletions development/ExampleModalComponent.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.example-modal {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;

.modal-container {
display: flex;
flex-direction: column;
width: 20rem;
background-color: white;
border-radius: 15px;
-webkit-box-shadow: 4px 3px 15px -4px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 4px 3px 15px -4px rgba(0, 0, 0, 0.75);
box-shadow: 4px 3px 15px -4px rgba(0, 0, 0, 0.75);
.modal-title {
display: block;
text-align: center;
padding: 1rem 3rem;
}
.modal-body {
display: block;
text-align: left;
padding: 1rem 3rem;
}
.modal-footer {
display: block;
text-align: center;
padding: 1rem 3rem;
button {
padding: 1rem;
border: 1px solid black;
}
}
}
}
63 changes: 63 additions & 0 deletions development/ExampleModalComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { defineComponent, defineProps, defineEmits } from 'vue'
import { createModal, useModal } from '../src'
import styles from './ExampleModalComponent.module.scss'
export type ModalData = {
title: string
body: string
}

export type ReturnType = {
num: number
}

export class ErrorOne extends Error {}
export class ErrorTwo extends Error {}

export const ExampleModal = defineComponent({
props: {
title: String,
body: String,
},
emits: {
return(data: ReturnType) {
return true
},
throw(error: unknown) {
return true
},
},
setup(props, { emit }) {
const close = () => {
emit('return', { num: 12 })
}
const error = () => {
emit('throw', new Error('Random error'))
}
const errorOne = () => {
emit('throw', new ErrorOne('Random error'))
}
const errorTwo = () => {
emit('throw', new ErrorTwo('Random error'))
}
return () => (
<div className={styles['example-modal']}>
<div className={styles['modal-container']}>
<div className={styles['modal-title']}>{props.title}</div>
<div className={styles['modal-body']}>{props.body}</div>
<div className={styles['modal-footer']}>
<button onClick={close}>Close</button>
<button onClick={errorOne}>Error 1</button>
<button onClick={errorTwo}>Error 2</button>
<button onClick={error}>Error unexpected</button>
</div>
</div>
</div>
)
},
})

const exampleModal = createModal<ModalData, ReturnType>({
component: ExampleModal,
})

export const useExampleModal = () => useModal(exampleModal)
80 changes: 0 additions & 80 deletions development/ExampleModalComponent.vue

This file was deleted.

30 changes: 30 additions & 0 deletions development/Page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { defineComponent } from 'vue'
import { useExampleModal, ErrorOne, ErrorTwo } from './ExampleModalComponent'

export const Page = defineComponent({
setup() {
const { showModal: showExampleModal } = useExampleModal()
const showExample = async () => {
try {
const asd = await showExampleModal({
body: 'asd',
title: 'kek',
})
console.log(asd.num)
} catch (error: unknown) {
if (error instanceof ErrorOne) {
console.log('ErrorOne occured')
} else if (error instanceof ErrorTwo) {
console.log('ErrorTwo occured')
} else {
console.log('An unexpected error occured')
}
}
}
return () => (
<div>
<button onClick={showExample}>Show example modal</button>
</div>
)
},
})
Loading

0 comments on commit 7f1e3d7

Please sign in to comment.