Skip to content

Commit 2dffff0

Browse files
committed
remove pushDefault, complete documentation
1 parent cca283f commit 2dffff0

13 files changed

+2454
-6237
lines changed

README.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,16 @@
22

33
Lightweight and flexible system for modal dialogs, snackbars, toasts, ...
44

5-
## [Docs](https://jshmrtn.github.io/vue-haystack/)
5+
[Documentation and Demos](https://jshmrtn.github.io/vue-haystack/)
6+
7+
## Installation
8+
9+
```sh
10+
npm i vue-haystack
11+
```
12+
13+
Import the styles (e.g. in your `App.vue`):
14+
15+
```ts
16+
import "vue-haystack/style.css";
17+
```

docs/.vuepress/config.ts

+9-20
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,22 @@ export default defineUserConfig<DefaultThemeOptions>({
77
port: 3000,
88
lang: "en-US",
99
title: "Vue Haystack 🧱",
10-
bundler: "@vuepress/vite",
10+
bundler: "@vuepress/bundler-vite",
1111
clientAppEnhanceFiles: [path.resolve(__dirname, "./enhanceAppFile.ts")],
12+
plugins: ["@vuepress/plugin-search"],
1213
themeConfig: {
1314
repo: "https://github.com/jshmrtn/vue-haystack",
14-
navbar: [],
15+
navbar: [{ text: "npm", link: "https://npmjs.com/package/vue-haystack" }],
1516
locales: {
1617
"/": {
1718
selectLanguageName: "English",
1819
},
1920
},
20-
sidebar: [
21-
{
22-
text: "Home",
23-
link: "/README.md",
24-
},
25-
{
26-
text: "Modals",
27-
link: "/modal.md",
28-
},
29-
{
30-
text: "Snackbar",
31-
link: "/snackbar.md",
32-
},
33-
{
34-
text: "Generic store",
35-
link: "/generic.md",
36-
},
37-
],
21+
displayAllHeaders: true,
22+
sidebarDepth: 3,
23+
sidebar: ["/setup.md", "/modal.md", "/snackbar.md", "/generic.md"],
24+
editLink: false,
25+
contributors: false,
26+
lastUpdated: false,
3827
},
3928
});

docs/README.md

+2-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ actions:
99
- text: Snackbar
1010
link: /snackbar
1111
type: primary
12-
- text: Generic store
12+
- text: Custom stores
1313
link: /generic
1414
type: primary
1515
features:
@@ -18,14 +18,10 @@ features:
1818
- title: Flexible
1919
details: Use your own components and maintain full control over the looks and functionality of your system.
2020
- title: Extensible
21-
details: A generic store allows you to easily implement your own systems
21+
details: A custom store allows you to easily implement your own systems
2222
footer: MIT Licensed | Copyright © 2021-present JOSHMARTIN GmbH
2323
---
2424

25-
<div class="alert">
26-
This is an early version, only the modal system is ready to use and documented
27-
</div>
28-
2925
## Installation
3026

3127
```sh

docs/generic.md

+187-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,190 @@
1-
# Generic store
1+
# Custom store
22

3-
<div class="alert">
4-
Work in progress
5-
</div>
3+
If you want to create your own system with special items or store behavior, you can write your own store. The generic store does the heavy lifting for you.
64

7-
If you have specific use cases, e.g. want to implement a `Toast` system or something similar, the generic store will take this much easier.
5+
All the built-in systems use the generic store, take a look [at the source](https://github.com/jshmrtn/vue-haystack/tree/master/src/modal) as well.
86

9-
The modal system uses the generic store, take a look [at the source](https://github.com/jshmrtn/vue-haystack/tree/master/src/modal) if you want to implement your own stores.
7+
## Creating a Store
8+
9+
To create a store, call `createItemStoreInstance` with two callbacks, the first to set up your item (`createItem`) instances, the second to extend the store as a whole (`extendStore`).
10+
11+
This is a skeleton that should help you get started (`myStore.ts`):
12+
13+
```ts
14+
import { createItemStoreInstance } from "vue-haystack";
15+
16+
const store = createItemStoreInstance(
17+
// `base` contains all the mandatory item properties (id, component, props, listeners, options)
18+
(base) => {
19+
const options = {
20+
// add custom options for your items
21+
...base.options,
22+
};
23+
24+
const item = {
25+
...base,
26+
// define custom properties that will be available in your component (return of `useMyItem`)
27+
options: options,
28+
};
29+
30+
return {
31+
item: {
32+
...base,
33+
options: options,
34+
},
35+
useReturn: {
36+
// define custom properties that will be available on the push functions (return of `useMyStore().push()`)
37+
},
38+
options: item.options,
39+
};
40+
},
41+
(_items) => {
42+
// extend the store here to provide custom push functions for example
43+
return {};
44+
},
45+
);
46+
47+
export const { useStore: useMyStore, useItem: useMyItem, provideItem: provideMyItem, store: myStore } = store;
48+
```
49+
50+
## Components
51+
52+
A system usually relies on two components, a `Container` and a `Provider`.
53+
54+
### Container component
55+
56+
The container will be responsible for displaying all your items (e.g. `Modal`, `Toast`, ...) on the screen. This is where you define where to show them, how many at the same time, in what order and define animations. A minimal container may look like this:
57+
58+
```vue
59+
<template>
60+
<div>
61+
<MyProvider v-for="item in items" :key="item.id" :item="item">
62+
</div>
63+
<component
64+
:is="item.component"
65+
:key="item.id"
66+
v-bind="item.props"
67+
v-on="item.listeners"
68+
/>
69+
</MyProvider>
70+
</div>
71+
</template>
72+
73+
<script lang="ts">
74+
import { computed, defineComponent } from "vue";
75+
import MyProvider from "./MyProvider.vue";
76+
import { useMyStore } from "./myStore";
77+
78+
export default defineComponent({
79+
name: "MyContainer",
80+
components: { MyProvider },
81+
setup: () => {
82+
const myStore = useMyStore();
83+
84+
const items = computed(() => {
85+
return myStore.items.value;
86+
});
87+
88+
return { items };
89+
},
90+
});
91+
</script>
92+
```
93+
94+
### Provider component
95+
96+
As you can see, `MyContainer` relies on the `MyProvider` component. The only responsibility of the `Provider` is to provide an item instance to your custom item components. The implementation is very simple and should not look much different than this:
97+
98+
```vue
99+
<template>
100+
<div>
101+
<slot :item="item" />
102+
</div>
103+
</template>
104+
105+
<script lang="ts">
106+
import { defineComponent, PropType } from "vue";
107+
import { provideMyItem, useMyItem } from "./myStore";
108+
109+
export default defineComponent({
110+
name: "MyProvider",
111+
components: {},
112+
props: {
113+
item: {
114+
type: Object as PropType<ReturnType<typeof useMyItem>>,
115+
required: true,
116+
},
117+
},
118+
setup: (props) => {
119+
provideMyItem(props.item);
120+
return {};
121+
},
122+
});
123+
</script>
124+
```
125+
126+
### Item components
127+
128+
These are the components you can push into your store and display in your container, so can take basically any shape. You can access the item instance using your `useMyItem()` function:
129+
130+
```vue
131+
<template>
132+
<div>MyItem: {{ foo }}</div>
133+
</template>
134+
135+
<script lang="ts">
136+
import { defineComponent } from "vue";
137+
import { useMyItem } from "./myStore";
138+
139+
export default defineComponent({
140+
name: "MyExampleItem",
141+
components: {},
142+
props: {
143+
foo: {
144+
type: String,
145+
required: true,
146+
},
147+
},
148+
setup: () => {
149+
const myItem = useMyItem();
150+
151+
return {};
152+
},
153+
});
154+
</script>
155+
```
156+
157+
## Using your custom store
158+
159+
As with the built-in stores, use your container component in a template, for example your `App.vue`:
160+
161+
```ts
162+
import { MyContainer } from "./MyContainer.vue";
163+
```
164+
165+
```vue
166+
<template>
167+
<div>
168+
<router-view />
169+
<MyContainer />
170+
</div>
171+
</template>
172+
```
173+
174+
Then wherever you want to instantiate your items:
175+
176+
```ts
177+
import { useMyStore } from "./myStore";
178+
import MyExampleItem from "./MyExampleItem.vue";
179+
180+
useMyStore().push(
181+
MyExampleItem /* item component */,
182+
{ foo: "propValue" /* props */ },
183+
{
184+
/* listeners */
185+
},
186+
{
187+
/* options */
188+
},
189+
);
190+
```

docs/setup.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Setup
2+
3+
Install vue-haystack using `npm`, `yarn` or `pnPm`:
4+
5+
```sh
6+
npm i vue-haystack
7+
```
8+
9+
Import the styles (e.g. in your `App.vue`):
10+
11+
```ts
12+
import "vue-haystack/style.css";
13+
```
14+
15+
Now you can use one of the prebuilt systems ([modal](./modal.md), [snackbar](./modal.md)) or create your own ([custom store](./generic.md)).

0 commit comments

Comments
 (0)