Skip to content

Commit

Permalink
docs(guide): propsDefaults, componentAliases & AConfig docs added
Browse files Browse the repository at this point in the history
  • Loading branch information
jd-solanki committed Jun 14, 2023
1 parent c5b68dc commit ca59ad5
Show file tree
Hide file tree
Showing 6 changed files with 312 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
// Extension: UnoCSS
"unocss.root": "packages/documentation",
// Extension: Volar
"volar.vueserver.vitePress.processMdFile": true,
"vue.server.vitePress.supportMdFile": true,
"references.preferredLocation": "peek",
"commentAnchors.tagHighlights.enabled": true,
}
5 changes: 4 additions & 1 deletion docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ export default defineConfig({
collapsed: false,
items: [
{ text: 'Presets', link: '/guide/features/presets' },
{ text: 'Dynamic Props', link: '/guide/features/dynamic-props' },
{ text: 'Component Aliases', link: '/guide/features/component-aliases' },
{ text: 'Theme', link: '/guide/features/theme' },
{ text: 'DX Focused', link: '/guide/features/dx-focused' },
{ text: 'Arbitrary Sizes', link: '/guide/features/arbitrary-sizes' },
{ text: 'Spacing', link: '/guide/features/spacing' },
{ text: 'Theme', link: '/guide/features/theme' },
{ text: 'Transitions', link: '/guide/features/transitions' },
{ text: 'Icons', link: '/guide/features/icons' },
],
Expand All @@ -85,6 +87,7 @@ export default defineConfig({
{ text: 'Card', link: '/guide/components/card' },
{ text: 'Checkbox', link: '/guide/components/checkbox' },
{ text: 'Chip', link: '/guide/components/chip' },
{ text: 'Config', link: '/guide/components/config' },
{ text: 'Dialog', link: '/guide/components/dialog' },
{ text: 'Drawer', link: '/guide/components/drawer' },
{ text: 'Input', link: '/guide/components/input' },
Expand Down
8 changes: 8 additions & 0 deletions docs/components/demos/config/DemoConfigProps.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<template>
<ABtn class="me-4">
Button
</ABtn>
<AConfig :props="{ ABtn: { variant: 'light' } }">
<ABtn>Configured Button</ABtn>
</AConfig>
</template>
14 changes: 14 additions & 0 deletions docs/guide/components/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Config

This is config provider component which provides config to all the components in the app.

<!-- 👉 Props -->
::::card Props

You can set default props for all the components nested inside `AConfig` using `props` prop.

:::code DemoConfigProps
<<< @/components/demos/config/DemoConfigProps.vue{5}
:::

::::
66 changes: 66 additions & 0 deletions docs/guide/features/component-aliases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Component Aliases

Probably there will be case where you have to use the same component provided by the component library but with a same set of props or attributes. For example, you might use `ABtn` component for rendering icon only button with same set of props everywhere.

```vue
<template>
<!-- We're repeating icon-only & variant="text" prop -->
<ABtn
icon="i-bx-cloud"
icon-only // [!code hl]
variant="text" // [!code hl]
/>
<ABtn
icon="i-bx-trash"
icon-only // [!code hl]
variant="text" // [!code hl]
/>
<ABtn
icon="i-bx-send"
icon-only // [!code hl]
variant="text" // [!code hl]
/>
</template>
```

In this type of cases, You can't use `propsDefaults` because you are using the same component everywhere with same set of props and might not need this component to have these same props everywhere. In this case, you can use `componentAliases` to create aliases for your components.

```ts{6-16}
// Import the component you want to set alias for
import { ABtn } from 'anu-vue'
createApp(App)
.use(anu, {
componentAliases: {
// Set alias for ABtn component
IconBtn: ABtn,
},
propsDefaults: {
// Set props defaults for IconBtn component
IconBtn: {
iconOnly: true,
variant: 'text',
},
}
})
```

Now, you can use `IconBtn` component everywhere in your app and it will have the same set of props.

```vue
<template>
<IconBtn icon="i-bx-cloud" />
<IconBtn icon="i-bx-trash" />
<IconBtn icon="i-bx-send" />
</template>
```

I guess, You're now convinced that Anu is the best way to use component libraries in Vue. So, what are you waiting for? Go ahead and try it out.

:::info
Component aliases are registered globally so you don't have to import them.
:::
219 changes: 219 additions & 0 deletions docs/guide/features/dynamic-props.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
# Dynamic Props

Inspired from [Vuetify](https://vuetifyjs.com/), anu provides a way to configure the component props dynamically.

## Why Dynamic Props?

When you use a component from component libraries, that component has props defaults assigned to it according to common needs. For example, `color` prop is always set to `primary` because it is the most common color used in the application.

However, what about not so obvious props like `size` prop. Your design system might requires smaller components than provided by the component library. In that case you have to write `size` prop everywhere.

```vue
<template>
<ABtn size="sm">Submit</ABtn>
<ABtn size="sm">Preview</ABtn>
<ABtn size="sm">Download</ABtn>
</template>
```

You have to repeat `size` prop everywhere which is super inconvenient <i class="i-fluent-emoji-confounded-face"></i> and has few downsides as well (_we aren't going to discuss them here_).

## The Solution?

But what if we have a way to configure the props defaults for all the components provided by component libraries? That would be super convenient <i class="i-fluent-emoji-grinning-face"></i> and we don't have to repeat the same props everywhere.

With anu, you can configure the props defaults for all the components while registering the plugin.

```ts{4-8}
// ℹ️ Anu don't have `size` prop. This is just an example.
createApp(App)
.use(anu, {
propsDefaults: {
ABtn: {
size: 'sm',
},
}
})
```

Now, You can write your components without repeating the `size` prop and keep your code DRY.

```vue
<template>
<ABtn>Submit</ABtn>
<ABtn>Preview</ABtn>
<ABtn>Download</ABtn>
</template>
```

Using `propsDefaults` you can set props defaults for any Anu component.

## Nested Props Defaults

Life is not always simple and your client might need visually different component based on context. For example, you might need a text variant button inside alert and normal (fill variant) button elsewhere. Then we are back to square one. We have to repeat the `variant` prop in every alert <i class="i-fluent-emoji-expressionless-face"></i>

```vue
<template>
<AAlert>
<p>You're running out of storage!</p>
<ABtn variant="text" class="ms-auto">Upgrade</ABtn> // [!code hl]
</AAlert>
<AAlert>
<p>Critical error occurred!</p>
<ABtn variant="text" class="ms-auto">Check</ABtn> // [!code hl]
</AAlert>
<AAlert>
<p>Payment failed!</p>
<ABtn variant="text" class="ms-auto">Retry</ABtn> // [!code hl]
</AAlert>
</template>
```

Anu also provides support for nested props defaults. You can set props defaults for a component inside another component.

```ts{4-8}
createApp(App)
.use(anu, {
propsDefaults: {
AAlert: {
ABtn: {
variant: 'text',
},
},
}
})
```

Now, with new props defaults, you can write your components without repeating the `variant` prop and keep your code DRY.

```vue
<template>
<AAlert>
<p>You're running out of storage!</p>
<ABtn class="ms-auto">Upgrade</ABtn> // [!code hl]
</AAlert>
<AAlert>
<p>Critical error occurred!</p>
<ABtn class="ms-auto">Check</ABtn> // [!code hl]
</AAlert>
<AAlert>
<p>Payment failed!</p>
<ABtn class="ms-auto">Retry</ABtn> // [!code hl]
</AAlert>
</template>
```

Cool right? <i class="i-fluent-emoji-smiling-face-with-sunglasses"></i>

Hold on, there is more. We're still repeating the `class` attribute. <i class="i-fluent-emoji-expressionless-face"></i>

![Breaks Keyboard GIF](https://media.tenor.com/Tp6pUkz1oR8AAAAC/breaks-keyboard.gif)

## Class, Style & Attrs Defaults

Apart from props, Anu also supports setting defaults for `class`, `style` and `attrs` for all the components.

```ts
createApp(App)
.use(anu, {
propsDefaults: {
AAlert: {
ABtn: {
variant: 'text',
class: 'ms-auto', // [!code hl]
// style: {}, /* You can also set default styles */ // [!code hl]
// attrs: {}, /* Set default attrs, Just in case if needed */ // [!code hl]
},
},
},
})
```

Finally, we have a way to write our components without repeating the code and keep our code DRY.

```vue
<template>
<!-- All buttons will have "ms-auto" class "light" variant -->
<AAlert>
<p>You're running out of storage!</p>
<ABtn>Upgrade</ABtn> // [!code hl]
</AAlert>
<AAlert>
<p>Critical error occurred!</p>
<ABtn>Check</ABtn> // [!code hl]
</AAlert>
<AAlert>
<p>Payment failed!</p>
<ABtn>Retry</ABtn> // [!code hl]
</AAlert>
</template>
```

## Defaults for your component

You can also set defaults for your own components. For example, you can set defaults for your custom `AppBtn` component.

```ts{4-11}
createApp(App)
.use(anu, {
propsDefaults: {
AppBtn: {
class: 'uppercase',
},
AppAAlert: {
AppBtn: {
propName: false,
},
}
},
})
```

Later in your component use `useDefaults` composable:

```vue
<script lang="ts" setup>
// other imports
import { useDefaults } from 'anu-vue'
// ❗ Make sure to use `_props` as name
const _props = defineProps<{}>() // or `withDefaults`
const { props, defaultsClass, defaultsStyle, defaultsAttrs } = useDefaults(_props)
// other code
</script>
<template>
<div
class="my-class"
:class="defaultsClass"
:style="[
{ color: 'red' },
defaultsStyle,
]"
v-bind="defaultsAttrs"
>
<!-- Your component content -->
<!-- ❗ If you want to access props use `props.propName` -->
</div>
</template>
```

Whoa! Anu also added DX magic to your custom components <i class="i-fluent-emoji-man-mage-light"></i>

:::warning
When you use `useDefaults` composable, you have to use `props.propName` while accessing the props to get props configured by defaults.

Even in your template, use `props.propName` to access the props.
:::

0 comments on commit ca59ad5

Please sign in to comment.