parent
5895f9d8b8
commit
bdaae718ad
@ -0,0 +1,36 @@
|
||||
// Slider — eidos compound API, disciplined option C.
|
||||
//
|
||||
// import { Slider } from '$uix/eidos/components/slider';
|
||||
//
|
||||
// <Slider bind:value aria-label="Volume">
|
||||
// <Slider.Range />
|
||||
// <Slider.Thumb />
|
||||
// </Slider>
|
||||
import SliderRoot from './slider.svelte';
|
||||
import Range from './slider-range.svelte';
|
||||
import Thumb from './slider-thumb.svelte';
|
||||
import Tick from './slider-tick.svelte';
|
||||
|
||||
type SliderNamespace = typeof SliderRoot & {
|
||||
Range: typeof Range;
|
||||
Thumb: typeof Thumb;
|
||||
Tick: typeof Tick;
|
||||
};
|
||||
|
||||
const Slider = SliderRoot as SliderNamespace;
|
||||
Slider.Range = Range;
|
||||
Slider.Thumb = Thumb;
|
||||
Slider.Tick = Tick;
|
||||
|
||||
export { Slider };
|
||||
|
||||
export default Slider;
|
||||
|
||||
export type {
|
||||
SliderProps,
|
||||
SliderRangeProps as RangeProps,
|
||||
SliderThumbProps as ThumbProps,
|
||||
SliderTickProps as TickProps,
|
||||
SliderSize,
|
||||
SliderType
|
||||
} from './types';
|
||||
@ -0,0 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { Range as SomaSliderRange } from '$soma/components/slider';
|
||||
import type { SliderRangeProps } from './types';
|
||||
|
||||
let { children, ...rest }: SliderRangeProps = $props();
|
||||
</script>
|
||||
|
||||
<SomaSliderRange {...rest}>
|
||||
{@render children?.()}
|
||||
</SomaSliderRange>
|
||||
@ -0,0 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { Thumb as SomaSliderThumb } from '$soma/components/slider';
|
||||
import type { SliderThumbProps } from './types';
|
||||
|
||||
let { children, ...rest }: SliderThumbProps = $props();
|
||||
</script>
|
||||
|
||||
<SomaSliderThumb {...rest}>
|
||||
{@render children?.()}
|
||||
</SomaSliderThumb>
|
||||
@ -0,0 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { Tick as SomaSliderTick } from '$soma/components/slider';
|
||||
import type { SliderTickProps } from './types';
|
||||
|
||||
let { children, ...rest }: SliderTickProps = $props();
|
||||
</script>
|
||||
|
||||
<SomaSliderTick {...rest}>
|
||||
{@render children?.()}
|
||||
</SomaSliderTick>
|
||||
@ -0,0 +1,133 @@
|
||||
[data-slider] {
|
||||
--_slider-track-size: var(--slider-track-size-md);
|
||||
--_slider-thumb-size: var(--slider-thumb-size-md);
|
||||
--_slider-hit-size: var(--slider-hit-size-md);
|
||||
--_slider-tick-size: var(--slider-tick-size-md);
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
[data-slider][data-size='sm'] {
|
||||
--_slider-track-size: var(--slider-track-size-sm);
|
||||
--_slider-thumb-size: var(--slider-thumb-size-sm);
|
||||
--_slider-hit-size: var(--slider-hit-size-sm);
|
||||
--_slider-tick-size: var(--slider-tick-size-sm);
|
||||
}
|
||||
|
||||
[data-slider][data-size='lg'] {
|
||||
--_slider-track-size: var(--slider-track-size-lg);
|
||||
--_slider-thumb-size: var(--slider-thumb-size-lg);
|
||||
--_slider-hit-size: var(--slider-hit-size-lg);
|
||||
--_slider-tick-size: var(--slider-tick-size-lg);
|
||||
}
|
||||
|
||||
[data-slider][data-disabled] {
|
||||
cursor: not-allowed;
|
||||
opacity: var(--slider-disabled-opacity);
|
||||
}
|
||||
|
||||
[data-slider][data-orientation='horizontal'] {
|
||||
inline-size: 100%;
|
||||
block-size: var(--_slider-hit-size);
|
||||
min-inline-size: var(--slider-min-inline-size);
|
||||
}
|
||||
|
||||
[data-slider][data-orientation='vertical'] {
|
||||
inline-size: var(--_slider-hit-size);
|
||||
block-size: var(--slider-min-block-size);
|
||||
min-block-size: var(--slider-min-block-size);
|
||||
}
|
||||
|
||||
[data-slider]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-radius: var(--slider-track-radius);
|
||||
background: var(--slider-track-bg);
|
||||
}
|
||||
|
||||
[data-slider][data-orientation='horizontal']::before {
|
||||
inset-inline: 0;
|
||||
inset-block-start: 50%;
|
||||
block-size: var(--_slider-track-size);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
[data-slider][data-orientation='vertical']::before {
|
||||
inset-block: 0;
|
||||
inset-inline-start: 50%;
|
||||
inline-size: var(--_slider-track-size);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
[data-slider-range] {
|
||||
border-radius: var(--slider-track-radius);
|
||||
background: var(--slider-range-bg);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[data-slider-range][data-orientation='horizontal'] {
|
||||
inset-block-start: 50%;
|
||||
block-size: var(--_slider-track-size);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
[data-slider-range][data-orientation='vertical'] {
|
||||
inset-inline-start: 50%;
|
||||
inline-size: var(--_slider-track-size);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
[data-slider-thumb] {
|
||||
inline-size: var(--_slider-thumb-size);
|
||||
block-size: var(--_slider-thumb-size);
|
||||
border: var(--slider-thumb-border-width) solid var(--slider-thumb-border);
|
||||
border-radius: var(--slider-thumb-radius);
|
||||
background: var(--slider-thumb-bg);
|
||||
box-shadow: var(--slider-thumb-shadow);
|
||||
cursor: grab;
|
||||
outline: none;
|
||||
transition:
|
||||
background var(--slider-transition-duration) var(--slider-transition-ease),
|
||||
border-color var(--slider-transition-duration) var(--slider-transition-ease),
|
||||
box-shadow var(--slider-transition-duration) var(--slider-transition-ease);
|
||||
}
|
||||
|
||||
[data-slider-thumb]:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
[data-slider-thumb]:focus-visible {
|
||||
box-shadow: var(--slider-thumb-focus-shadow);
|
||||
}
|
||||
|
||||
[data-slider-thumb][data-disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
[data-slider-tick] {
|
||||
inline-size: var(--_slider-tick-size);
|
||||
block-size: var(--_slider-tick-size);
|
||||
border-radius: var(--slider-tick-radius);
|
||||
background: var(--slider-tick-bg);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[data-slider-tick][data-orientation='horizontal'] {
|
||||
inset-block-start: 50%;
|
||||
margin-block-start: calc(var(--_slider-tick-size) / -2);
|
||||
}
|
||||
|
||||
[data-slider-tick][data-orientation='vertical'] {
|
||||
inset-inline-start: 50%;
|
||||
margin-inline-start: calc(var(--_slider-tick-size) / -2);
|
||||
}
|
||||
|
||||
[data-slider-tick][data-active] {
|
||||
background: var(--slider-tick-bg-active);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
[data-slider-thumb] {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Eidos `<Slider>` — visual wrapper over Soma's slider primitive.
|
||||
* Soma owns pointer/keyboard/value behavior; Eidos adds `size`.
|
||||
*/
|
||||
import { ActiveEidos } from '$uix/eidos';
|
||||
import { Provider as SomaSliderProvider } from '$soma/components/slider';
|
||||
import type { SliderProps } from './types';
|
||||
|
||||
let { size = 'md', value = $bindable([0]), children, ...rest }: SliderProps = $props();
|
||||
|
||||
const eidos = ActiveEidos.require();
|
||||
const resolvedSize = $derived(eidos.resolve(size, 'md'));
|
||||
</script>
|
||||
|
||||
<SomaSliderProvider {...rest} bind:value data-size={resolvedSize}>
|
||||
{@render children?.()}
|
||||
</SomaSliderProvider>
|
||||
@ -0,0 +1,26 @@
|
||||
import type {
|
||||
ProviderProps as SomaSliderProviderProps,
|
||||
RangeProps as SomaSliderRangeProps,
|
||||
SliderType,
|
||||
ThumbProps as SomaSliderThumbProps,
|
||||
TickProps as SomaSliderTickProps
|
||||
} from '$soma/components/slider';
|
||||
import type { ResponsiveProp, Size } from '$uix/eidos/lib/types';
|
||||
|
||||
export type SliderSize = Extract<Size, 'sm' | 'md' | 'lg'>;
|
||||
|
||||
/**
|
||||
* Props for the eidos `<Slider>`.
|
||||
*
|
||||
* Extends Soma's slider with visual sizing only. Orientation, disabled state,
|
||||
* range position, thumb position and ARIA are owned by Soma.
|
||||
*/
|
||||
export type SliderProps = SomaSliderProviderProps & {
|
||||
/** Visual size. Accepts a responsive map resolved by ActiveEidos. @default 'md' */
|
||||
size?: ResponsiveProp<SliderSize>;
|
||||
};
|
||||
|
||||
export type SliderRangeProps = SomaSliderRangeProps;
|
||||
export type SliderThumbProps = SomaSliderThumbProps;
|
||||
export type SliderTickProps = SomaSliderTickProps;
|
||||
export type { SliderType };
|
||||
Loading…
Reference in new issue