feat(ComboControlV2): crete ComboControlV2 - without increase/decrease buttons. Refresh styling of the original one
This commit is contained in:
@@ -8,9 +8,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { TypographyControl } from '$shared/lib';
|
import type { TypographyControl } from '$shared/lib';
|
||||||
import { Button } from '$shared/shadcn/ui/button';
|
import { Button } from '$shared/shadcn/ui/button';
|
||||||
import * as ButtonGroup from '$shared/shadcn/ui/button-group';
|
import { Root as ButtonGroupRoot } from '$shared/shadcn/ui/button-group';
|
||||||
import { Input } from '$shared/shadcn/ui/input';
|
import { Input } from '$shared/shadcn/ui/input';
|
||||||
import * as Popover from '$shared/shadcn/ui/popover';
|
import {
|
||||||
|
Content as PopoverContent,
|
||||||
|
Root as PopoverRoot,
|
||||||
|
Trigger as PopoverTrigger,
|
||||||
|
} from '$shared/shadcn/ui/popover';
|
||||||
import { Slider } from '$shared/shadcn/ui/slider';
|
import { Slider } from '$shared/shadcn/ui/slider';
|
||||||
import MinusIcon from '@lucide/svelte/icons/minus';
|
import MinusIcon from '@lucide/svelte/icons/minus';
|
||||||
import PlusIcon from '@lucide/svelte/icons/plus';
|
import PlusIcon from '@lucide/svelte/icons/plus';
|
||||||
@@ -67,30 +71,32 @@ const handleSliderChange = (newValue: number) => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ButtonGroup.Root>
|
<ButtonGroupRoot class="bg-transparent border-none shadow-none">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="ghost"
|
||||||
|
class="hover:bg-white/50 bg-white/20 border-none"
|
||||||
size="icon"
|
size="icon"
|
||||||
aria-label={decreaseLabel}
|
aria-label={decreaseLabel}
|
||||||
onclick={control.decrease}
|
onclick={control.decrease}
|
||||||
disabled={control.isAtMin}
|
disabled={control.isAtMin}
|
||||||
>
|
>
|
||||||
<MinusIcon />
|
<MinusIcon class="size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Popover.Root>
|
<PopoverRoot>
|
||||||
<Popover.Trigger>
|
<PopoverTrigger>
|
||||||
{#snippet child({ props })}
|
{#snippet child({ props })}
|
||||||
<Button
|
<Button
|
||||||
{...props}
|
{...props}
|
||||||
variant="outline"
|
variant="ghost"
|
||||||
|
class="hover:bg-white/50 bg-white/20 border-none"
|
||||||
size="icon"
|
size="icon"
|
||||||
aria-label={controlLabel}
|
aria-label={controlLabel}
|
||||||
>
|
>
|
||||||
{control.value}
|
{control.value}
|
||||||
</Button>
|
</Button>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Popover.Trigger>
|
</PopoverTrigger>
|
||||||
<Popover.Content class="w-auto p-4">
|
<PopoverContent class="w-auto p-4">
|
||||||
<div class="flex flex-col items-center gap-3">
|
<div class="flex flex-col items-center gap-3">
|
||||||
<Slider
|
<Slider
|
||||||
min={control.min}
|
min={control.min}
|
||||||
@@ -110,15 +116,16 @@ const handleSliderChange = (newValue: number) => {
|
|||||||
class="w-16 text-center"
|
class="w-16 text-center"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Popover.Content>
|
</PopoverContent>
|
||||||
</Popover.Root>
|
</PopoverRoot>
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="ghost"
|
||||||
|
class="hover:bg-white/50 bg-white/20 border-none"
|
||||||
size="icon"
|
size="icon"
|
||||||
aria-label={increaseLabel}
|
aria-label={increaseLabel}
|
||||||
onclick={control.increase}
|
onclick={control.increase}
|
||||||
disabled={control.isAtMax}
|
disabled={control.isAtMax}
|
||||||
>
|
>
|
||||||
<PlusIcon />
|
<PlusIcon class="size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup.Root>
|
</ButtonGroupRoot>
|
||||||
|
|||||||
72
src/shared/ui/ComboControlV2/ComboControlV2.svelte
Normal file
72
src/shared/ui/ComboControlV2/ComboControlV2.svelte
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<!--
|
||||||
|
Component: ComboControl
|
||||||
|
Provides the same functionality as the original ComboControl but lacks increase/decrease buttons.
|
||||||
|
-->
|
||||||
|
<script lang="ts">
|
||||||
|
import type { TypographyControl } from '$shared/lib';
|
||||||
|
import { Input } from '$shared/shadcn/ui/input';
|
||||||
|
import { Slider } from '$shared/shadcn/ui/slider';
|
||||||
|
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
import type { ChangeEventHandler } from 'svelte/elements';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
control: TypographyControl;
|
||||||
|
ref?: Snippet;
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
control,
|
||||||
|
ref = $bindable(),
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
|
let sliderValue = $state(Number(control.value));
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
sliderValue = Number(control.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleInputChange: ChangeEventHandler<HTMLInputElement> = event => {
|
||||||
|
const parsedValue = parseFloat(event.currentTarget.value);
|
||||||
|
if (!isNaN(parsedValue)) {
|
||||||
|
control.value = parsedValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSliderChange = (newValue: number) => {
|
||||||
|
control.value = newValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Shared glass button class for consistency
|
||||||
|
// const glassBtnClass = cn(
|
||||||
|
// 'border-none transition-all duration-200',
|
||||||
|
// 'bg-white/10 hover:bg-white/40 active:scale-90',
|
||||||
|
// 'text-slate-900 font-medium',
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const ghostStyle = cn(
|
||||||
|
// 'flex items-center justify-center transition-all duration-300 ease-out',
|
||||||
|
// 'text-slate-900/40 hover:text-slate-950 hover:bg-white/20 active:scale-90',
|
||||||
|
// 'disabled:opacity-10 disabled:pointer-events-none',
|
||||||
|
// );
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-col items-center gap-4">
|
||||||
|
<Input
|
||||||
|
value={control.value}
|
||||||
|
onchange={handleInputChange}
|
||||||
|
min={control.min}
|
||||||
|
max={control.max}
|
||||||
|
class="w-14 h-8 text-xs text-center bg-white/40 border-none rounded-lg focus-visible:ring-indigo-500/50"
|
||||||
|
/>
|
||||||
|
<Slider
|
||||||
|
min={control.min}
|
||||||
|
max={control.max}
|
||||||
|
step={control.step}
|
||||||
|
value={sliderValue}
|
||||||
|
onValueChange={handleSliderChange}
|
||||||
|
type="single"
|
||||||
|
orientation="vertical"
|
||||||
|
class="h-30"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
import CheckboxFilter from './CheckboxFilter/CheckboxFilter.svelte';
|
import CheckboxFilter from './CheckboxFilter/CheckboxFilter.svelte';
|
||||||
import ComboControl from './ComboControl/ComboControl.svelte';
|
import ComboControl from './ComboControl/ComboControl.svelte';
|
||||||
import ComparisonSlider from './ComparisonSlider/ComparisonSlider.svelte';
|
import ComboControlV2 from './ComboControlV2/ComboControlV2.svelte';
|
||||||
import ContentEditable from './ContentEditable/ContentEditable.svelte';
|
import ContentEditable from './ContentEditable/ContentEditable.svelte';
|
||||||
import SearchBar from './SearchBar/SearchBar.svelte';
|
import SearchBar from './SearchBar/SearchBar.svelte';
|
||||||
import VirtualList from './VirtualList/VirtualList.svelte';
|
import VirtualList from './VirtualList/VirtualList.svelte';
|
||||||
@@ -14,7 +14,7 @@ import VirtualList from './VirtualList/VirtualList.svelte';
|
|||||||
export {
|
export {
|
||||||
CheckboxFilter,
|
CheckboxFilter,
|
||||||
ComboControl,
|
ComboControl,
|
||||||
ComparisonSlider,
|
ComboControlV2,
|
||||||
ContentEditable,
|
ContentEditable,
|
||||||
SearchBar,
|
SearchBar,
|
||||||
VirtualList,
|
VirtualList,
|
||||||
|
|||||||
Reference in New Issue
Block a user