Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/ui/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export * from './select';
export * from './separator';
export * from './sheet';
export * from './skeleton';
export * from './slider';
export * from './switch';
export * from './tabs';
export * from './textarea';
Expand Down
9 changes: 9 additions & 0 deletions packages/ui/src/components/slider/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SSliderRoot from './slider-root.vue';
import SSliderTrack from './slider-track.vue';
import SSliderRange from './slider-range.vue';
import SSliderThumb from './slider-thumb.vue';
import SSlider from './slider.vue';

export { SSliderRoot, SSliderTrack, SSliderRange, SSliderThumb, SSlider };

export * from './types';
22 changes: 22 additions & 0 deletions packages/ui/src/components/slider/slider-range.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script setup lang="ts">
import { computed } from 'vue';
import { SliderRange } from '@soybean-ui/primitive';
import { cn, sliderVariants } from '@soybean-ui/variants';
import type { SliderRangeProps } from './types';

defineOptions({
name: 'SSliderRange'
});

const { class: cls, color } = defineProps<SliderRangeProps>();

const mergedCls = computed(() => {
const { range } = sliderVariants({ color });

return cn(range(), cls);
});
</script>

<template>
<SliderRange :class="mergedCls" />
</template>
26 changes: 26 additions & 0 deletions packages/ui/src/components/slider/slider-root.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup lang="ts">
import { computed } from 'vue';
import { SliderRoot, useForwardPropsEmits } from '@soybean-ui/primitive';
import { cn, sliderVariants } from '@soybean-ui/variants';
import type { SliderRootEmits, SliderRootProps } from './types';

defineOptions({
name: 'SSliderRoot'
});

const { class: cls, ...delegatedProps } = defineProps<SliderRootProps>();

const emit = defineEmits<SliderRootEmits>();

const forwarded = useForwardPropsEmits(delegatedProps, emit);

const { root } = sliderVariants();

const mergedCls = computed(() => cn(root(), cls));
</script>

<template>
<SliderRoot v-bind="forwarded" :class="mergedCls">
<slot />
</SliderRoot>
</template>
22 changes: 22 additions & 0 deletions packages/ui/src/components/slider/slider-thumb.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script setup lang="ts">
import { computed } from 'vue';
import { SliderThumb } from '@soybean-ui/primitive';
import { cn, sliderVariants } from '@soybean-ui/variants';
import type { SliderThumbProps } from './types';

defineOptions({
name: 'SSliderThumb'
});

const { class: cls, color } = defineProps<SliderThumbProps>();

const mergedCls = computed(() => {
const { thumb } = sliderVariants({ color });

return cn(thumb(), cls);
});
</script>

<template>
<SliderThumb :class="mergedCls" />
</template>
24 changes: 24 additions & 0 deletions packages/ui/src/components/slider/slider-track.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang="ts">
import { computed } from 'vue';
import { SliderTrack } from '@soybean-ui/primitive';
import { cn, sliderVariants } from '@soybean-ui/variants';
import type { SliderTrackProps } from './types';

defineOptions({
name: 'SSliderTrack'
});

const { class: cls, color } = defineProps<SliderTrackProps>();

const mergedCls = computed(() => {
const { track } = sliderVariants({ color });

return cn(track(), cls);
});
</script>

<template>
<SliderTrack :class="mergedCls">
<slot />
</SliderTrack>
</template>
35 changes: 35 additions & 0 deletions packages/ui/src/components/slider/slider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script setup lang="ts">
import { useForwardPropsEmits } from '@soybean-ui/primitive';
import SSliderRoot from './slider-root.vue';
import SSliderTrack from './slider-track.vue';
import SSliderRange from './slider-range.vue';
import SSliderThumb from './slider-thumb.vue';
import type { SliderEmits, SliderProps } from './types';

defineOptions({
name: 'SSlider'
});

const { color, trackClass, thumbClass, rangeClass, ...delegatedRootProps } = defineProps<SliderProps>();

const emit = defineEmits<SliderEmits>();

const forwardedRootProps = useForwardPropsEmits(delegatedRootProps, emit);
</script>

<template>
<SSliderRoot v-bind="forwardedRootProps">
<slot v-bind="{ color, ...delegatedRootProps }">
<slot name="track" v-bind="{ color, ...delegatedRootProps }">
<SSliderTrack :class="trackClass" :color="color">
<slot name="range" v-bind="{ color, ...delegatedRootProps }">
<SSliderRange :class="rangeClass" :color="color" />
</slot>
</SSliderTrack>
</slot>
<slot name="thumb" v-bind="{ color, ...delegatedRootProps }">
<SSliderThumb v-for="(_, key) in modelValue" :key="key" :class="thumbClass" :color="color" />
</slot>
</slot>
</SSliderRoot>
</template>
32 changes: 32 additions & 0 deletions packages/ui/src/components/slider/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type {
ClassValue,
SliderRootEmits,
SliderRootProps,
SliderRangeProps as _SliderRangeProps,
SliderThumbProps as _SliderThumbProps,
SliderTrackProps as _SliderTrackProps
} from '@soybean-ui/primitive';
import type { ThemeColor } from '../../types';

export interface SliderTrackProps extends _SliderTrackProps {
color?: ThemeColor;
}

export interface SliderRangeProps extends _SliderRangeProps {
color?: ThemeColor;
}

export interface SliderThumbProps extends _SliderThumbProps {
color?: ThemeColor;
}

export interface SliderProps extends SliderRootProps {
color?: ThemeColor;
trackClass?: ClassValue;
rangeClass?: ClassValue;
thumbClass?: ClassValue;
}

export type SliderEmits = SliderRootEmits;

export type { SliderRootEmits, SliderRootProps };
1 change: 1 addition & 0 deletions packages/variants/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export * from './variants/select';
export * from './variants/separator';
export * from './variants/sheet';
export * from './variants/skeleton';
export * from './variants/slider';
export * from './variants/switch';
export * from './variants/tabs';
export * from './variants/textarea';
Expand Down
60 changes: 60 additions & 0 deletions packages/variants/src/variants/slider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// @unocss-include
import { tv } from 'tailwind-variants';

export const sliderVariants = tv({
slots: {
root: [
`relative flex w-full touch-none select-none items-center`,
`data-[orientation=vertical]:(flex-col w-2 h-full)`
],
track: `relative h-2 w-full data-[orientation=vertical]:w-2 grow overflow-hidden rounded-full`,
range: `absolute h-full data-[orientation=vertical]:w-full`,
thumb: [
`block h-5 w-5 rounded-full border-2 bg-background transition-colors`,
`focus-visible:(outline outline-2 outline-offset-2)`,
`disabled:(pointer-events-none opacity-50)`
]
},
variants: {
color: {
primary: {
track: 'bg-primary/20',
range: 'bg-primary',
thumb: 'border-primary focus-visible:outline-primary'
},
destructive: {
track: 'bg-destructive/20',
range: 'bg-destructive',
thumb: 'border-destructive focus-visible:outline-destructive'
},
success: {
track: 'bg-success/20',
range: 'bg-success',
thumb: 'border-success focus-visible:outline-success'
},
warning: {
track: 'bg-warning/20',
range: 'bg-warning',
thumb: 'border-warning focus-visible:outline-warning'
},
info: {
track: 'bg-info/20',
range: 'bg-info',
thumb: 'border-info focus-visible:outline-info'
},
secondary: {
track: 'bg-secondary-foreground/20',
range: 'bg-secondary-foreground',
thumb: 'border-secondary-foreground focus-visible:outline-secondary-foreground'
},
accent: {
track: 'bg-accent-foreground/20',
range: 'bg-accent-foreground',
thumb: 'border-accent-foreground focus-visible:outline-accent-foreground'
}
}
},
defaultVariants: {
color: 'primary'
}
});
6 changes: 6 additions & 0 deletions src/views/ui/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import UiSelect from './modules/select.vue';
import UiSeparator from './modules/separator.vue';
import UiSheet from './modules/sheet.vue';
import UiSkeleton from './modules/skeleton.vue';
import UiSlider from './modules/slider.vue';
import UiSonner from './modules/sonner.vue';
import UiSwitch from './modules/switch.vue';
import UiTabs from './modules/tabs.vue';
Expand Down Expand Up @@ -217,6 +218,11 @@ const tabs: TabConfig[] = [
label: 'Skeleton',
component: UiSkeleton
},
{
value: 'slider',
label: 'Slider',
component: UiSlider
},
{
value: 'sonner',
label: 'Sonner',
Expand Down
22 changes: 22 additions & 0 deletions src/views/ui/modules/slider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script setup lang="ts">
import { ref } from 'vue';
import { SSlider } from '@soybean-ui/vue';
import type { ThemeColor } from '@soybean-ui/vue';

const model = ref<number[]>([33]);

const model2 = ref<number[]>([10, 60]);

const colors: ThemeColor[] = ['primary', 'destructive', 'success', 'warning', 'info', 'secondary', 'accent'];
</script>

<template>
<div class="py-12px text-18px">Color</div>
<div class="w-480px flex flex-c-stretch gap-20px lt-sm:w-auto">
<SSlider v-for="color in colors" :key="color" v-model="model" :max="100" :step="1" :color="color" />
</div>
<div class="py-12px text-18px">Orientation: Vertical</div>
<div class="h-40">
<SSlider v-model="model2" orientation="vertical" :max="100" :step="1" />
</div>
</template>
Loading