Skip to content

Commit

Permalink
feat(module): handle tailwindMerge config from app.config (#2902)
Browse files Browse the repository at this point in the history
Co-authored-by: Benjamin Canac <[email protected]>
  • Loading branch information
stijns96 and benjamincanac authored Dec 26, 2024
1 parent b7153cd commit ea15e21
Show file tree
Hide file tree
Showing 34 changed files with 111 additions and 62 deletions.
46 changes: 46 additions & 0 deletions docs/content/1.getting-started/3.theming.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,52 @@ export default defineAppConfig({
})
```

### Extend Tailwind Merge

Tailwind Merge is a library that allows you to efficiently merge Tailwind CSS classes. It is used by this module to merge the classes from the `ui` prop, the `class` attribute, and the default classes.

::callout{icon="i-heroicons-light-bulb" to="https://github.com/dcastil/tailwind-merge" target="_blank"}
Learn more about Tailwind Merge.
::

By default, Tailwind Merge doesn't handle custom Tailwind CSS configuration like custom colors, spacing, or other utilities you may have defined. You'll need to extend it to handle your custom configuration.

You can extend Tailwind Merge by using the `tailwindMerge` option in your `app.config.ts`:

::code-group
```ts [app.config.ts]
export default defineAppConfig({
ui: {
tailwindMerge: {
extend: {
theme: {
spacing: ['sm', 'md', 'lg', 'xl', '2xl']
}
}
}
}
})
```

```ts [tailwind.config.ts]
import type { Config } from 'tailwindcss'

export default <Partial<Config>>{
theme: {
extend: {
spacing: {
sm: '0.5rem',
md: '1rem',
lg: '1.5rem',
xl: '2rem',
'2xl': '2.5rem'
}
}
}
}
```
::

## Dark mode

All the components are styled with dark mode in mind.
Expand Down
2 changes: 2 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createRequire } from 'node:module'
import { defineNuxtModule, installModule, addComponentsDir, addImportsDir, createResolver, addPlugin } from '@nuxt/kit'
import type { ConfigExtension, DefaultClassGroupIds, DefaultThemeGroupIds } from 'tailwind-merge'
import { name, version } from '../package.json'
import createTemplates from './templates'
import type * as config from './runtime/ui.config'
Expand All @@ -20,6 +21,7 @@ type UI = {
gray?: string
colors?: string[]
strategy?: Strategy
tailwindMerge?: ConfigExtension<DefaultClassGroupIds, DefaultThemeGroupIds>
[key: string]: any
} & DeepPartial<typeof config, string | number | boolean>

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/components/data/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ import UButton from '../elements/Button.vue'
import UProgress from '../elements/Progress.vue'
import UCheckbox from '../forms/Checkbox.vue'
import { useUI } from '../../composables/useUI'
import { mergeConfig, get } from '../../utils'
import { get, mergeConfig } from '../../utils'
import type { TableRow, TableColumn, Strategy, Button, ProgressColor, ProgressAnimation, DeepPartial, Expanded } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/elements/Alert.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import UAvatar from '../elements/Avatar.vue'
import UButton from '../elements/Button.vue'
import { useUI } from '../../composables/useUI'
import type { Avatar, Button, AlertColor, AlertVariant, AlertAction, Strategy, DeepPartial } from '../../types/index'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
// @ts-expect-error
import appConfig from '#build/app.config'
import { alert } from '#ui/ui.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/elements/Avatar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
<script lang="ts">
import { defineComponent, ref, computed, toRef, watch } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { AvatarSize, AvatarChipColor, AvatarChipPosition, Strategy, DeepPartial } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/elements/AvatarGroup.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { h, cloneVNode, computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { mergeConfig, getSlotsChildren } from '../../utils'
import { getSlotsChildren, mergeConfig, twMerge } from '../../utils'
import type { AvatarSize, DeepPartial, Strategy } from '../../types/index'
import UAvatar from './Avatar.vue'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/elements/Badge.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
import type { BadgeColor, BadgeSize, BadgeVariant, DeepPartial, Strategy } from '../../types/index'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/elements/Button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
<script lang="ts">
import { computed, defineComponent, toRef } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import ULink from '../elements/Link.vue'
import { useUI } from '../../composables/useUI'
import { mergeConfig, nuxtLinkProps, getNuxtLinkProps } from '../../utils'
import { getNuxtLinkProps, mergeConfig, nuxtLinkProps, twMerge } from '../../utils'
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
import type { ButtonColor, ButtonSize, ButtonVariant, DeepPartial, Strategy } from '../../types/index'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/elements/ButtonGroup.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { h, computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { mergeConfig, getSlotsChildren } from '../../utils'
import { getSlotsChildren, mergeConfig, twMerge } from '../../utils'
import { useProvideButtonGroup } from '../../composables/useButtonGroup'
import type { ButtonSize, DeepPartial, Strategy } from '../../types/index'
// @ts-expect-error
Expand Down
3 changes: 1 addition & 2 deletions src/runtime/components/elements/Carousel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@
<script lang="ts">
import { ref, toRef, computed, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge } from 'tailwind-merge'
import { useScroll, useResizeObserver, useElementSize } from '@vueuse/core'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import UButton from '../elements/Button.vue'
import type { Strategy, Button, DeepPartial } from '../../types/index'
import { useUI } from '../../composables/useUI'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/elements/Dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ import { defineComponent, ref, computed, watch, toRef, onMounted, resolveCompone
import type { PropType } from 'vue'
import { Menu as HMenu, MenuButton as HMenuButton, MenuItems as HMenuItems, MenuItem as HMenuItem, provideUseId } from '@headlessui/vue'
import { defu } from 'defu'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import UAvatar from '../elements/Avatar.vue'
import UKbd from '../elements/Kbd.vue'
import { useUI } from '../../composables/useUI'
import { usePopper } from '../../composables/usePopper'
import { mergeConfig, getNuxtLinkProps } from '../../utils'
import { getNuxtLinkProps, mergeConfig, twMerge } from '../../utils'
import type { DeepPartial, DropdownItem, PopperOptions, Strategy } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/elements/Kbd.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
<script lang="ts">
import { toRef, defineComponent, computed } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { DeepPartial, KbdSize, Strategy } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/components/elements/MeterGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { ComputedRef, VNode, SlotsType, PropType } from 'vue'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import { useUI } from '../../composables/useUI'
import { mergeConfig, getSlotsChildren } from '../../utils'
import { getSlotsChildren, mergeConfig } from '../../utils'
import type { DeepPartial, Strategy, MeterSize } from '../../types/index'
import type Meter from './Meter.vue'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/Checkbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { DeepPartial, Strategy } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
<script lang="ts">
import { ref, computed, toRef, onMounted, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { defu } from 'defu'
import UIcon from '../elements/Icon.vue'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig, looseToNumber } from '../../utils'
import { looseToNumber, mergeConfig, twMerge } from '../../utils'
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
import type { InputSize, InputColor, InputVariant, Strategy, DeepPartial } from '../../types/index'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/InputMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ import {
} from '@headlessui/vue'
import { computedAsync, useDebounceFn } from '@vueuse/core'
import { defu } from 'defu'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { isEqual } from 'ohash'
import UIcon from '../elements/Icon.vue'
import UAvatar from '../elements/Avatar.vue'
import { useUI } from '../../composables/useUI'
import { usePopper } from '../../composables/usePopper'
import { useFormGroup } from '../../composables/useFormGroup'
import { get, mergeConfig } from '../../utils'
import { get, mergeConfig, twMerge } from '../../utils'
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
import type { InputSize, InputColor, InputVariant, PopperOptions, Strategy, DeepPartial } from '../../types/index'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/Radio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
<script lang="ts">
import { computed, defineComponent, inject, toRef } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { DeepPartial, Strategy } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/components/forms/RadioGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { computed, defineComponent, provide, toRef } from 'vue'
import type { PropType } from 'vue'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig, get } from '../../utils'
import { get, mergeConfig } from '../../utils'
import type { DeepPartial, Strategy } from '../../types/index'
import URadio from './Radio.vue'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/Range.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { RangeSize, RangeColor, Strategy, DeepPartial } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType, ComputedRef } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig, get } from '../../utils'
import { get, mergeConfig, twMerge } from '../../utils'
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
import type { SelectSize, SelectColor, SelectVariant, Strategy, DeepPartial } from '../../types/index'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/SelectMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,14 @@ import {
} from '@headlessui/vue'
import { computedAsync, useDebounceFn } from '@vueuse/core'
import { defu } from 'defu'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { isEqual } from 'ohash'
import UIcon from '../elements/Icon.vue'
import UAvatar from '../elements/Avatar.vue'
import { useUI } from '../../composables/useUI'
import { usePopper } from '../../composables/usePopper'
import { useFormGroup } from '../../composables/useFormGroup'
import { get, mergeConfig } from '../../utils'
import { get, mergeConfig, twMerge } from '../../utils'
import { useInjectButtonGroup } from '../../composables/useButtonGroup'
import type { SelectSize, SelectColor, SelectVariant, PopperOptions, Strategy, DeepPartial } from '../../types/index'
// @ts-expect-error
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/Textarea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
<script lang="ts">
import { ref, computed, toRef, watch, onMounted, nextTick, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { defu } from 'defu'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig, looseToNumber } from '../../utils'
import { looseToNumber, mergeConfig, twMerge } from '../../utils'
import type { TextareaSize, TextareaColor, TextareaVariant, Strategy, DeepPartial } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/forms/Toggle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { Switch as HSwitch, provideUseId } from '@headlessui/vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import { useUI } from '../../composables/useUI'
import { useFormGroup } from '../../composables/useFormGroup'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { ToggleSize, ToggleColor, Strategy, DeepPartial } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/layout/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { DeepPartial, Strategy } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/layout/Container.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { DeepPartial, Strategy } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/layout/Divider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
<script lang="ts">
import { toRef, computed, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import UIcon from '../elements/Icon.vue'
import UAvatar from '../elements/Avatar.vue'
import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { Avatar, DeepPartial, DividerSize, Strategy } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/components/layout/Skeleton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<script lang="ts">
import { computed, toRef, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { twMerge, twJoin } from 'tailwind-merge'
import { twJoin } from 'tailwind-merge'
import { useUI } from '../../composables/useUI'
import { mergeConfig } from '../../utils'
import { mergeConfig, twMerge } from '../../utils'
import type { DeepPartial, Strategy } from '../../types/index'
// @ts-expect-error
import appConfig from '#build/app.config'
Expand Down
Loading

0 comments on commit ea15e21

Please sign in to comment.