Skip to content

Commit

Permalink
feat(theme): add new colors, useAnu composable, Theming improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
jd-solanki committed Feb 19, 2023
1 parent f70d632 commit e340271
Show file tree
Hide file tree
Showing 26 changed files with 450 additions and 149 deletions.
3 changes: 3 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export default defineConfig({
items: [
// { text: 'useSearch', link: '/guide/composables/useSearch' },
// { text: 'useSort', link: '/guide/composables/useSort' },
{ text: 'useAnu', link: '/guide/composables/useAnu' },
{ text: 'useGroupModel', link: '/guide/composables/useGroupModel' },
],
},
Expand Down Expand Up @@ -119,6 +120,8 @@ export default defineConfig({
},
},
markdown: {
// ℹ️ We only enabled this in development so that we can highlight code lines by seeing line number without calculating it in our editor.
lineNumbers: process.env.NODE_ENV === 'development',
theme: 'dracula',
config: md => {
md.use(Container, 'card', {
Expand Down
4 changes: 1 addition & 3 deletions docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import './style.css'
export default {
...DefaultTheme,
enhanceApp({ app }) {
app.use(anu, {
registerComponents: true,
})
app.use(anu)

// Register demos as components
const demos = import.meta.globEager('../../components/demos/**/*.vue')
Expand Down
23 changes: 11 additions & 12 deletions docs/components/demos/chip/DemoChipClosable.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
<script setup lang="ts">
import { defaultThemeColors } from 'anu-vue'
import { computed, ref } from 'vue'
const chips = ref([
{ title: 'Primary', color: 'primary', isOpen: true },
{ title: 'Success', color: 'success', isOpen: true },
{ title: 'Info', color: 'info', isOpen: true },
{ title: 'Warning', color: 'warning', isOpen: true },
{ title: 'Danger', color: 'danger', isOpen: true },
])
const chips = ref(defaultThemeColors.map(c => ({
color: c,
isClosed: false,
})))
const allChipsClosed = computed(() => chips.value.every(chip => !chip.isOpen))
const reset = () => chips.value.forEach(chip => chip.isOpen = true)
const allChipsClosed = computed(() => chips.value.every(chip => !chip.isClosed))
const reset = () => chips.value.forEach(chip => chip.isClosed = true)
</script>

<template>
<div class="flex flex-wrap gap-2">
<AChip
v-for="chip in chips"
:key="chip.title"
v-model="chip.isOpen"
:key="chip.color"
v-model="chip.isClosed"
:color="chip.color"
closable
class="capitalize"
>
{{ chip.title }}
{{ chip.color }}
</AChip>

<div class="w-full">
Expand Down
4 changes: 2 additions & 2 deletions docs/components/demos/radio/DemoRadioColor.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<script lang="ts" setup>
import { defaultThemeColors } from 'anu-vue'
import { ref } from 'vue'
const favoriteFruit = ref()
const colors = ['primary', 'success', 'info', 'warning', 'danger']
</script>

<template>
<div class="flex flex-col gap-y-3 mt-6">
<ARadio
v-for="color in colors"
v-for="color in defaultThemeColors"
:key="color"
v-model="favoriteFruit"
name="radio-color"
Expand Down
77 changes: 77 additions & 0 deletions docs/guide/composables/useAnu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# useAnu

`useAnu` composable provides API for interactive with Anu.

## Basic

`useAnu` provides following reactive variables:

- `themes: ConfigThemes` => Registered themes. You can modify colors & CSS variables at runtime 😍
- `activeThemeName: string` => Name of the active theme in your app
- `activeTheme: ({ name: string, theme: ThemeOptions })` => Convenient computed property to get details of active theme. Don't modify it 🙅🏻‍♂️

```ts
import { useAnu } from 'anu-vue';

const { themes, activeThemeName, activeTheme } = useAnu()
```

## Changing Active Theme

You can change the active theme at runtime by modifying the `activeThemeName` ref.

```ts{5}
import { useAnu } from 'anu-vue';
const { activeThemeName } = useAnu()
activeThemeName.value = 'dark'
```

## Active Theme Details

Use `activeTheme` computed property to get the details of active theme.

```ts{6-7}
import { computed } from 'vue';
import { useAnu } from 'anu-vue';
const { activeTheme } = useAnu()
const activeThemeName = computed(() => activeTheme.value.name)
const primaryColor = computed(() => activeTheme.value.theme.colors.primary)
```

:::warning
Modifying `activeTheme` computed property won't do anything so never mutate this computed property.
:::

## Modifying Themes

You can modify any theme at runtime via `theme` ref.

```ts{8,12}
import { useAnu } from 'anu-vue';
const { themes } = useAnu()
// Change primary color for all themes
for (const themeName in themes.value) {
const theme = themes.value[themeName]
theme.colors.primary = '235, 97.7%, 66.3%'
}
// Or you can also change the primary color for single theme
themes.value.light.colors.primary = '235, 97.7%, 66.3%'
```

<br>

---

<br>

Related documentation:

- [Theme](/guide/features/theme.md)
- [Colors](/guide/getting-started/customization.html#color)
132 changes: 99 additions & 33 deletions docs/guide/features/theme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,125 @@

Anu officially supports light & dark theme. Anu also allows users to customize the appearance of their application by providing a custom theme or modifying the existing.

This is achieved through the use of CSS variables, which can be defined and modified at runtime. This means that users can change the theme of their application on the fly. This allows for a more flexible and dynamic user experience, as users can tailor the appearance of their application to their personal preferences or to match the branding of their organization.
This is achieved through the use of CSS variables, which can be defined and modified at runtime (via `useAnu` composable). This means that users can change the theme of their application on the fly. This allows for a more flexible and dynamic user experience, as users can tailor the appearance of their application to their personal preferences or to match the branding of their organization.

Light theme is enabled by default. If you want to switch to dark mode just apply `.dark` class to root `html` element.
Light theme is enabled by default. If you want to switch to dark mode use `initialTheme` option while registering anu.

```html
<html class="dark">
<!-- ... -->
</html>
```
```ts{9-11}
import { createApp } from 'vue'
import App from './App.vue'
import { anu } from 'anu-vue'
You can check list of available CSS variables in [preset-theme-default](https://github.com/jd-solanki/anu/blob/main/packages/preset-theme-default/src/scss/index.scss).
// other stuff
## How to customize the theme?
const app = createApp(App)
app.use(anu, {
initialTheme: 'dark',
})
```

To customize any of the existing theme, light or dark, you just have to override the CSS variable.
## How to customize the theme?

Assume your theme color is `#5563fd`. Just convert it to [hsl](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl) format and override the `--a-primary` root CSS variable in your stylesheet.
To customize any of the existing theme, light or dark, you just have to override the theme option.

```vue{6}
<!-- App.vue -->
<template>
<ABtn>Button</ABtn>
</template>
Assume your theme color is `#5563fd`. Just convert it to [hsl](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl) format and override the `primary` color via anu options.

<style>
:root {
--a-primary: 235, 97.7%, 66.3%;
}
</style>
```ts{5}
app.use(anu, {
themes: {
light: {
colors: {
primary: '235, 98%, 66%',
},
},
},
})
```

Done 🥳

If you want to change the CSS variant in the dark theme, just update the selector:

```diff
- :root
+ :root.dark
```
Do note that, this will only update the primary color for light theme.

## How to create custom theme?

Creating a custom theme is as easy as defining new values for the existing CSS variables.
Creating a custom theme is as easy as defining new values for the existing theme colors.

Create a new CSS selector for `:root` with the theme name (assuming `coffee`) and write down the CSS variables with the desired values:

```css
:root.coffee {
---a-primary: 27, 39%, 77%,
/* other CSS variables */
}
```ts{5}
app.use(anu, {
themes: {
class: 'a-theme-coffee',
coffee: {
colors: {
primary: '27, 39%, 77%',
// other theme colors
},
},
},
})
```

Now just add class `coffee` to the html element: `html.coffee`.

Don't forget to include the CSS file in your entrypoint 😜

## How to add new color?

Anu provides **primary**, **success**, **info**, **warning** & **danger** colors by default.

Additionally, you can also add new colors to the palette. Add new color to the palette via theme option:

```ts{5,10}
app.use(anu, {
themes: {
light: {
colors: {
secondary: '0, 0%, 50%',
},
},
dark: {
colors: {
secondary: '0, 0%, 25%',
},
},
},
})
```

Passing options to anu config will merge them and will result in new color **secondary** added to existing theme palette.

Additionally, You also have to add this new color in Anu's UnoCSS preset.

> _Working on omitting this preset step. Guide WIP._
Finally let's use new color 😍

```vue
<template>
<ABtn color="secondary">Secondary</ABtn>
</template>
```

<br>

---

<br>

:::tip Default Colors
You can get array of default colors provide by anu from `defaultThemeColors` export.

```ts
import { defaultThemeColors } from 'anu-vue'
```

:::

<br>

Related documentation:

- [`useAnu` composable](/guide/composables/useAnu.md)
- [Colors](/guide/getting-started/customization.html#color)
33 changes: 24 additions & 9 deletions docs/guide/getting-started/customization.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
<script setup lang="ts">
import { useCssVar } from '@vueuse/core';
import { useAnu } from 'anu-vue';
import { computed } from 'vue';

const primaryColor = useCssVar('--a-primary')
const { activeTheme, themes } = useAnu()
const vpBrandHue = useCssVar('--vp-brand-hue')
const isPrimaryChanged = computed(() => primaryColor.value.startsWith('235'))
const isPrimaryChanged = computed(() => activeTheme.value.theme?.colors.primary?.startsWith('235'))

const updatePrimaryColor = () => {
// To update the look & feel of whole template, update VitePress primary color as well
vpBrandHue.value = isPrimaryChanged.value ? '265' : '235'
const primaryColor = activeTheme.value.theme.colors.primary
const primaryHue = isPrimaryChanged.value ? '265' : '235'

primaryColor.value = `${isPrimaryChanged.value ? '265' : '235'}, 97.7%, 66.3%`
// To update the look & feel of whole template, update VitePress primary color as well
vpBrandHue.value = primaryHue

// ℹ️ Change primary color for all themes. You can also just change the primary color of current/active theme 😇
for (const themeName in themes.value) {
const theme = themes.value[themeName]
theme.colors.primary = `${primaryHue}, 97.7%, 66.3%`
}
}
</script>

# Customization

## Color

Anu uses [HSL](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl) color format to define colors. You can configure theme colors via [CSS variables(custom properties)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties).
Anu uses [HSL](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl) color format to define and use colors. You can update theme colors via [themes](/guide/features/theme.md) configurations.

To customize theme color, set a CSS variable in your CSS with color name prefixed with `a-` (_e.g. `--a-primary`_). Below is the list of colors you can configure.
Below is the list of default colors. You can also [add new colors](/guide/features/theme.html#how-to-add-new-color) to the palette.

<div class="flex gap-6 flex-wrap">
<ACard variant="fill" color="primary" class="rounded-2xl shadow-2xl shadow-primary shadow-opacity-40 w-26 h-26 font-semibold grid place-items-center">Primary</ACard>
Expand All @@ -32,9 +40,16 @@ To customize theme color, set a CSS variable in your CSS with color name prefixe

<ABtn class="mt-8" :class="isPrimaryChanged ? 'bg-[hsl(265,97.7%,66.3%)]' : 'bg-[hsl(235,97.7%,66.3%)]'" @click="updatePrimaryColor">{{ isPrimaryChanged ? 'Reset' : 'Change' }} primary</ABtn>

<br />
<br />

Also checkout related documentation:

- [`useAnu` composable](/guide/composables/useAnu.md)

## CSS variables

Besides colors, Anu uses CSS variables for other stuff for providing maximum flexibility and customization on the fly. All anu's CSS variables are prefixed with `a-`.
For the most part, Anu uses CSS variables for other stuff to providing maximum flexibility and customization on the fly. All anu's CSS variables are prefixed with `a-`.
:::details View all CSS vars
Below is CSS vars defined for preset theme default's light theme:
Expand Down Expand Up @@ -69,7 +84,7 @@ Just change the colors to Bootstrap's color and see the magic 😍
![Bootstrap buttons using anu](/images/guide/anu-bootstrap-btns.png)
:::

You can refer to available shortcuts in [this](https://github.com/jd-solanki/anu/blob/main/packages/anu-vue/src/presets/theme-default/index.ts) file.
You can refer to available shortcuts in [this](https://github.com/jd-solanki/anu/blob/main/packages/preset-theme-default/src/shortcuts.ts) file.

If you like this simple customization don't forget to give a **star on Github**. If you don't like it give a triple star 😉.

Expand Down
Loading

0 comments on commit e340271

Please sign in to comment.