Skip to content
29 changes: 29 additions & 0 deletions docs/components/progress.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup>
import FwbProgressExample from './progress/examples/FwbProgressExample.vue'
import FwbProgressExampleColor from './progress/examples/FwbProgressExampleColor.vue'
import FwbProgressExampleCustom from './progress/examples/FwbProgressExampleCustom.vue'
import FwbProgressExampleLabelInside from './progress/examples/FwbProgressExampleLabelInside.vue'
import FwbProgressExampleLabelOutside from './progress/examples/FwbProgressExampleLabelOutside.vue'
import FwbProgressExampleSize from './progress/examples/FwbProgressExampleSize.vue'
Expand Down Expand Up @@ -101,3 +102,31 @@ You can also apply color.
import { FwbProgress } from 'flowbite-vue'
</script>
```

## Custom
You can fully customize the appearance of the progress bar using TailwindCSS utility classes via the following props:

| Prop | Description |
|-----------------------|------------------------------------------------------------------|
| `inner-classes` | Custom classes for the inner progress bar |
| `outer-classes` | Custom classes for the outer progress bar container |
| `outside-label-classes` | Custom classes for the label outside the progress bar |

These props allow you to override or extend the default styling for each part of the component, enabling advanced use cases such as gradients, custom colors, rounded corners, and more.

<fwb-progress-example-custom />
```vue
<template>
<fwb-progress
:progress="50"
:inner-classes="'rounded-xs bg-teal-900 dark:bg-teal-200'"
:outer-classes="'bg-teal-200 dark:bg-teal-900'"
:outside-label-classes="'italic text-sky-800 dark:text-sky-200'"
label="Custom"
/>
</template>

<script setup>
import { FwbProgress } from 'flowbite-vue'
</script>
```
13 changes: 13 additions & 0 deletions docs/components/progress/examples/FwbProgressExampleCustom.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<fwb-progress
:progress="50"
:inner-classes="'rounded-xs bg-teal-900 dark:bg-teal-200'"
:outer-classes="'bg-teal-200 dark:bg-teal-900'"
:outside-label-classes="'italic text-sky-800 dark:text-sky-200'"
label="Custom"
/>
</template>

<script lang="ts" setup>
import { FwbProgress } from '../../../../src/index'
</script>
3 changes: 2 additions & 1 deletion docs/components/spinner.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { FwbSpinner } from 'flowbite-vue'
<fwb-spinner color="red" />
<fwb-spinner color="white" />
<fwb-spinner color="yellow" />
<fwb-spinner color="#3fb984" /> <!-- Custom color -->
</template>

<script setup>
Expand All @@ -71,5 +72,5 @@ import { FwbSpinner } from 'flowbite-vue'
### Props
| Name | Values | Default |
|-------|-----------------------------------------------------------------------------------------|---------|
| color | `blue`, `gray`, `green`, `pink`, `purple`, `red`, `white`, `yellow` | `blue` |
| color | `blue`, `gray`, `green`, `pink`, `purple`, `red`, `white`, `yellow`, any hex code | `blue` |
| size | `0`, `0.5`, `1`, `1.5`, `10`, `11`, `12`, `2`, `2.5`, `3`, `4`, `5`, `6`, `7`, `8`, `9` | `4` |
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<fwb-spinner color="red" />
<fwb-spinner color="white" />
<fwb-spinner color="yellow" />
<fwb-spinner color="#3fb984" />
</div>
</template>

Expand Down
10 changes: 6 additions & 4 deletions src/components/FwbProgress/FwbProgress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,19 @@
<div class="mb-1 flex justify-between">
<span
:class="outsideLabelClasses"
class="text-base font-medium"
>{{ label }}</span>
<span
v-if="labelProgress && labelPosition === 'outside'"
:class="outsideLabelClasses"
class="text-sm font-medium"
>{{ progress }}%</span>
</div>
</template>
<div
:class="outerClasses"
class="w-full rounded-full bg-gray-200 dark:bg-gray-700"
>
<div
:class="innerClasses"
:style="{ width: progress + '%' }"
class="rounded-full p-0.5 text-center font-medium text-blue-100"
>
<template v-if="labelProgress && labelPosition === 'inside'">
{{ progress }}%
Expand All @@ -44,6 +40,9 @@ interface IProgressProps {
labelProgress?: boolean
progress?: number
size?: ProgressSize
innerClasses?: string | Record<string, boolean>
outerClasses?: string | Record<string, boolean>
outsideLabelClasses?: string | Record<string, boolean>
}

const props = withDefaults(defineProps<IProgressProps>(), {
Expand All @@ -53,6 +52,9 @@ const props = withDefaults(defineProps<IProgressProps>(), {
labelProgress: false,
progress: 0,
size: 'md',
innerClasses: '',
outerClasses: '',
outsideLabelClasses: '',
})

const {
Expand Down
52 changes: 33 additions & 19 deletions src/components/FwbProgress/composables/useProgressClasses.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import classNames from 'classnames'
import { computed, type Ref } from 'vue'

import type { ProgressLabelPosition, ProgressSize, ProgressVariant } from '../types'

import { useMergeClasses } from '@/composables/useMergeClasses'

const defaultInnerClasses = 'rounded-full p-0.5 text-center font-medium text-blue-100'
const defaultOuterClasses = 'w-full rounded-full bg-gray-200 dark:bg-gray-700'
const defaultOutsideLabelClasses = 'text-base font-medium'

const barColorClasses: Record<ProgressVariant, string> = {
default: 'bg-blue-600 dark:bg-blue-600',
blue: 'bg-blue-600 dark:bg-blue-600',
Expand Down Expand Up @@ -36,28 +41,37 @@ export type UseProgressClassesProps = {
color: Ref<ProgressVariant>
size: Ref<ProgressSize>
labelPosition: Ref<ProgressLabelPosition>
innerClasses?: Ref<string | Record<string, boolean>>
outerClasses?: Ref<string | Record<string, boolean>>
outsideLabelClasses?: Ref<string | Record<string, boolean>>
}

export function useProgressClasses (props: UseProgressClassesProps): { innerClasses: Ref<string>, outerClasses: Ref<string>, outsideLabelClasses: Ref<string> } {
const bindClasses = computed(() => {
return classNames(
barColorClasses[props.color.value],
progressSizeClasses[props.size.value],
)
})
const outerClasses = computed(() => {
return classNames(
progressSizeClasses[props.size.value],
)
})
const outsideLabelClasses = computed(() => {
return classNames(
outsideTextColorClasses[props.color.value],
)
})
export function useProgressClasses (props: UseProgressClassesProps): {
innerClasses: Ref<string>
outerClasses: Ref<string>
outsideLabelClasses: Ref<string>
} {
const innerClasses = computed(() => useMergeClasses([
defaultInnerClasses,
barColorClasses[props.color.value],
progressSizeClasses[props.size.value],
props.innerClasses?.value || '',
]))

const outerClasses = computed(() => useMergeClasses([
defaultOuterClasses,
progressSizeClasses[props.size.value],
props.outerClasses?.value || '',
]))

const outsideLabelClasses = computed(() => useMergeClasses([
defaultOutsideLabelClasses,
outsideTextColorClasses[props.color.value],
props.outsideLabelClasses?.value || '',
]))

return {
innerClasses: bindClasses,
innerClasses,
outerClasses,
outsideLabelClasses,
}
Expand Down
5 changes: 3 additions & 2 deletions src/components/FwbSpinner/FwbSpinner.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<svg
:class="spinnerClasses"
:style="customColor ? { '--custom-fill': customColor } : {}"
fill="none"
role="status"
viewBox="0 0 100 101"
Expand All @@ -12,7 +13,7 @@
/>
<path
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
fill="currentFill"
:fill="customColor || 'currentFill'"
/>
</svg>
</template>
Expand All @@ -34,5 +35,5 @@ const props = withDefaults(defineProps<ISpinnerProps>(), {
size: '4',
})

const { spinnerClasses } = useSpinnerClasses(toRefs(props))
const { spinnerClasses, customColor } = useSpinnerClasses(toRefs(props))
</script>
9 changes: 6 additions & 3 deletions src/components/FwbSpinner/composables/useSpinnerClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ export type UseSpinnerClassesProps = {
size: Ref<SpinnerSize>
}

export function useSpinnerClasses (props: UseSpinnerClassesProps): { spinnerClasses: Ref<string> } {
export function useSpinnerClasses (props: UseSpinnerClassesProps): { spinnerClasses: Ref<string>, customColor: Ref<string | null> } {
const sizeClasses = computed(() => sizes[props.size.value])
const colorClasses = computed(() => colors[props.color.value])

const colorClasses = computed(() => colors[props.color.value as SpinnerColor] ?? '')
const customColor = computed(() => colorClasses.value ? null : (props.color.value as string))

const bgColorClasses = computed(() => 'text-gray-200 dark:text-gray-600')
const animateClasses = computed(() => 'animate-spin')
const spinnerClasses = computed(() => classNames(
Expand All @@ -50,5 +53,5 @@ export function useSpinnerClasses (props: UseSpinnerClassesProps): { spinnerClas
sizeClasses.value,
))

return { spinnerClasses }
return { spinnerClasses, customColor }
}
3 changes: 2 additions & 1 deletion src/components/FwbSpinner/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export type SpinnerColor = 'blue' | 'gray' | 'green' | 'red' | 'yellow' | 'pink' | 'purple' | 'white'
type CustomColor = (`#${string}` & {})
export type SpinnerColor = 'blue' | 'gray' | 'green' | 'red' | 'yellow' | 'pink' | 'purple' | 'white' | CustomColor

export type SpinnerSize = '0' | '0.5' | '1' | '1.5' | '2' | '2.5' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12'
Loading