Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Solid ESLint warnings #95

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
14 changes: 7 additions & 7 deletions src/renderer/src/components/list/List.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import ListItem from "./ListItem";
import useControllableState from "@renderer/lib/controllable-state";
import { Accessor, createContext, ParentComponent, useContext } from "solid-js";
import createControllableSignal from "@renderer/lib/controllable-signal";
import { createContext, ParentComponent, useContext } from "solid-js";

const DEFAULT_SELECTED_VALUE = "";

export type Props = {
defaultValue?: string;
value?: Accessor<string>;
value?: string;
onValueChange?: (newValue: string) => void;
};

export type Context = ReturnType<typeof useProviderValue>;
function useProviderValue(props: Props) {
const [selectedValue, setSelectedValue] = useControllableState({
defaultProp: props.defaultValue || DEFAULT_SELECTED_VALUE,
onChange: props.onValueChange,
prop: props.value,
const [selectedValue, setSelectedValue] = createControllableSignal({
defaultValue: props.defaultValue || DEFAULT_SELECTED_VALUE,
onChange: (newValue) => props.onValueChange?.(newValue),
value: () => props.value,
});

return {
Expand Down
1 change: 1 addition & 0 deletions src/renderer/src/components/list/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type Props = JSX.IntrinsicElements["button"] & {
};
const ListItem: Component<Props> = (props) => {
const state = useList();

return (
<button
data-selected={state.selectedValue() === props.value}
Expand Down
14 changes: 7 additions & 7 deletions src/renderer/src/components/popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
shift,
ShiftOptions,
} from "@floating-ui/dom";
import useControllableState from "@renderer/lib/controllable-state";
import { createSignal, createContext, useContext, ParentComponent, Accessor } from "solid-js";
import createControllableSignal from "@renderer/lib/controllable-signal";
import { createSignal, createContext, useContext, ParentComponent } from "solid-js";

export const DEFAULT_POPOVER_OPEN = false;

Expand All @@ -23,19 +23,19 @@
flip?: FlipOptions;
shift?: ShiftOptions;
placement?: Placement;
mousePos?: Accessor<[number, number]>; // [x, y]

Check failure on line 26 in src/renderer/src/components/popover/Popover.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Cannot find name 'Accessor'.
defaultProp?: boolean;
isOpen?: Accessor<boolean>;
isOpen?: boolean;
onValueChange?: (newOpen: boolean) => void;
};

export type Context = ReturnType<typeof useProviderValue>;

function useProviderValue(props: Props) {
const [isOpen, setIsOpen] = useControllableState<boolean>({
defaultProp: props.defaultProp || DEFAULT_POPOVER_OPEN,
onChange: props.onValueChange,
prop: props.isOpen,
const [isOpen, setIsOpen] = createControllableSignal<boolean>({
defaultValue: props.defaultProp || DEFAULT_POPOVER_OPEN,
onChange: (newValue) => props.onValueChange?.(newValue),
value: () => props.isOpen,
});

const [position, setPosition] = createSignal<ComputePositionReturn | null>(null);
Expand Down
10 changes: 6 additions & 4 deletions src/renderer/src/components/popover/PopoverContent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { usePopover } from "./Popover";
import { ComputePositionReturn } from "@floating-ui/dom";
import createFocusTrap from "solid-focus-trap";
import { Component, Show } from "solid-js";
import { Component, createEffect, Show } from "solid-js";
import { JSX } from "solid-js/jsx-runtime";

function stylesFromPosition(position: ComputePositionReturn | null): JSX.CSSProperties | undefined {
Expand All @@ -19,9 +19,11 @@ type Props = JSX.IntrinsicElements["div"];
const PopoverContent: Component<Props> = (props) => {
const state = usePopover();

createFocusTrap({
element: state.contentRef,
enabled: state.isOpen,
createEffect(() => {
createFocusTrap({
element: state.contentRef,
enabled: state.isOpen(),
});
});

return (
Expand Down
1 change: 1 addition & 0 deletions src/renderer/src/components/popover/PopoverOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { JSX } from "solid-js/jsx-runtime";
type Props = JSX.IntrinsicElements["div"];
const PopoverOverlay: Component<Props> = (props) => {
const state = usePopover();

return (
<Show when={state.isOpen()}>
<div {...props} onClick={state.close} class={`popover-overlay ${props.class}`} />
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/components/popover/PopoverTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const PopoverTrigger: Component<Props> = (props) => {
<button
ref={state.setTriggerRef}
onClick={() => {
state?.toggle();
state.toggle();
}}
{...props}
/>
Expand Down
6 changes: 2 additions & 4 deletions src/renderer/src/components/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const Setting: Component<SettingProps> = (props) => {
};

const AudioDeviceSetting: Component = () => {
const [isPopoverOpen, setIsPopoverOpen] = createSignal(false);
const [selectedAudioDevice, setSelectedAudioDevice] = createSignal("");
const [audioDevices, setAudioDevices] = createSignal(new Map<string, () => any>());

Expand All @@ -73,18 +72,17 @@ const AudioDeviceSetting: Component = () => {

const handleValueChange = (newSelectedOption: string) => {
setSelectedAudioDevice(newSelectedOption);
setIsPopoverOpen(false);
audioDevices().get(newSelectedOption)?.();
};

return (
<Setting name="audio-device" label="Choose audio device">
<Dropdown isOpen={isPopoverOpen} onValueChange={setIsPopoverOpen}>
<Dropdown>
<Dropdown.SelectTrigger class="w-full rounded border border-stroke bg-surface px-2 py-1 text-text focus:outline-none focus:ring-2 focus:ring-overlay">
{selectedAudioDevice() || "No device selected"}
</Dropdown.SelectTrigger>

<Dropdown.List value={selectedAudioDevice} onValueChange={handleValueChange}>
<Dropdown.List value={selectedAudioDevice()} onValueChange={handleValueChange}>
<For each={Array.from(audioDevices().keys())}>
{(audioDevice) => <Dropdown.Item value={audioDevice}>{audioDevice}</Dropdown.Item>}
</For>
Expand Down
39 changes: 21 additions & 18 deletions src/renderer/src/components/slider/Slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import SliderRange from "./SliderRange";
import SliderThumb from "./SliderThumb";
import SliderTime from "./SliderTime";
import SliderTrack from "./SliderTrack";
import useControllableState from "@renderer/lib/controllable-state";
import createControllableSignal from "@renderer/lib/controllable-signal";
import { cn } from "@renderer/lib/css.utils";
import { linearScale } from "@renderer/lib/linear-scale";
import { throttle } from "@renderer/lib/throttle";
import { clamp } from "@renderer/lib/tungsten/math";
import {
Accessor,
createContext,
createMemo,
createSignal,
Expand All @@ -25,7 +24,7 @@ const DEFAULT_MAX = 100;

export type Props = {
defaultValue?: number;
value?: Accessor<number>;
value?: number;
onValueChange?: (newValue: number) => void;
onValueCommit?: () => void;
onValueStart?: () => void;
Expand Down Expand Up @@ -54,10 +53,11 @@ function useProviderValue(props: Props) {
const [isDragging, setIsDragging] = createSignal(false);
const [thumbWidth, setThumbWidth] = createSignal<number>(0);
const [thumb, _setThumb] = createSignal<HTMLElement>();
const [value, setValue] = useControllableState({
defaultProp: props.defaultValue ?? DEFAULT_SLIDER_VALUE,
prop: props.value,
onChange: props.onValueChange,

const [value, setValue] = createControllableSignal({
defaultValue: props.defaultValue ?? DEFAULT_SLIDER_VALUE,
onChange: (newValue) => props.onValueChange?.(newValue),
value: () => props.value,
});

const setThumb = (node: HTMLElement) => {
Expand All @@ -74,10 +74,14 @@ function useProviderValue(props: Props) {
setIsDragging(false);
};

const min = props.min ?? DEFAULT_MIN;
const max = props.max ?? DEFAULT_MAX;
const min = () => props.min ?? DEFAULT_MIN;
const max = () => props.max ?? DEFAULT_MAX;

const percentage = createMemo(() => {
const currentValue = value() ?? min();
return convertValueToPercentage(currentValue, min(), max());
});

const percentage = createMemo(() => convertValueToPercentage(value(), min, max));
const transitionStyleValue = createMemo<JSX.CSSProperties>(() => {
if (!props.animate || isDragging()) {
return {};
Expand Down Expand Up @@ -119,8 +123,8 @@ const SliderRoot: ParentComponent<Props> = (props) => {
const sliderRect = sliderElement.getBoundingClientRect();
const rect = lastRect() || sliderRect;

const min = sliderContext.min;
const max = sliderContext.max;
const min = sliderContext.min();
const max = sliderContext.max();
const input: [number, number] = [0, rect.width];
const output: [number, number] = [min, max];
const value = linearScale(input, output);
Expand Down Expand Up @@ -154,19 +158,18 @@ const SliderRoot: ParentComponent<Props> = (props) => {
};

const handleHomePress = () => {
sliderContext.setValue(sliderContext.min);
sliderContext.setValue(sliderContext.min());
};

const handleEndPress = () => {
sliderContext.setValue(sliderContext.max);
sliderContext.setValue(sliderContext.max());
};

const [handleStep] = throttle((direction: "left" | "right") => {
const stepDirection = direction === "left" ? -1 : 1;
const step = (sliderContext.max / 100) * 5;
const step = (sliderContext.max() / 100) * 5;
const stepInDirection = step * stepDirection;
const min = sliderContext.min;
const max = sliderContext.max;
const min = sliderContext.min();
const max = sliderContext.max();
sliderContext.setValue((value) => clamp(min, max, value + stepInDirection));
sliderContext.thumb()?.focus();
}, 50);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ const LeftPart = () => {
class="flex h-8 w-28 flex-grow items-center"
min={0}
max={1}
value={volume}
value={volume()}
onValueChange={setVolume}
enableWheelSlide
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const ProgressBar = (props: ProgressBarProps) => {
class="mt-4 block"
min={0}
max={1}
value={currentValue}
value={currentValue()}
onValueChange={seek}
onValueStart={handleSeekStart}
onValueCommit={handleSeekEnd}
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/components/song/song-item/SongItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@

const SongItem: Component<SongItemProps> = (props) => {
let item: HTMLDivElement | undefined;
const [, setCoords] = createSignal<[number, number]>([0, 0], { equals: false });

Check warning on line 27 in src/renderer/src/components/song/song-item/SongItem.tsx

View workflow job for this annotation

GitHub Actions / lint

For proper analysis, array destructuring should be used to capture the first result of this function call

const { extractColorFromImage } = useColorExtractor();
const { primaryColor, secondaryColor, processImage } = extractColorFromImage(props.song);

Check warning on line 30 in src/renderer/src/components/song/song-item/SongItem.tsx

View workflow job for this annotation

GitHub Actions / lint

The reactive variable 'props.song' should be used within JSX, a tracked scope (like createEffect), or inside an event handler function, or else changes will be ignored
const [localShow, setLocalShow] = createSignal(false);
const [mousePos, setMousePos] = createSignal<[number, number]>([0, 0]);

Expand All @@ -36,7 +36,7 @@

// Initialize draggable functionality
draggable(item, {
onClick: ignoreClickInContextMenu(() => props.onSelect(props.song.path)),
onClick: () => ignoreClickInContextMenu(props.onSelect(props.song.path)),
onDrop: props.onDrop ?? (() => {}),
createHint: SongHint,
useOnlyAsOnClickBinder: !props.draggable || selectedSong().path === props.song.path,
Expand Down Expand Up @@ -76,7 +76,7 @@

return (
<Popover
isOpen={localShow}

Check failure on line 79 in src/renderer/src/components/song/song-item/SongItem.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Type 'Accessor<boolean>' is not assignable to type 'boolean | undefined'.
onValueChange={setLocalShow}
placement="right"
offset={{ crossAxis: 5, mainAxis: 5 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ type OrderSelectProps = {
};

const SongListSearchOrderBy: Component<OrderSelectProps> = (props) => {
const [isOpen, setIsOpen] = createSignal(false);
const [option, setOption] = createSignal<OrderOptions>("title");
const [direction, setDirection] = createSignal<OrderDirection>("asc");

Expand Down Expand Up @@ -72,17 +71,16 @@ const SongListSearchOrderBy: Component<OrderSelectProps> = (props) => {
</Match>
</Switch>
</Button>
<Dropdown isOpen={isOpen} onValueChange={setIsOpen}>
<Dropdown>
<Dropdown.Trigger class="rounded-md bg-thin-material px-3 py-1">
{optionLabel()}
</Dropdown.Trigger>
<Dropdown.List
onValueChange={(newSelectedOption) => {
setIsOpen(false);
setOption(newSelectedOption as OrderOptions);
handlerOrderChanged();
}}
value={option}
value={option()}
>
<For each={orderOptions}>
{(option) => (
Expand Down
30 changes: 30 additions & 0 deletions src/renderer/src/lib/controllable-signal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { accessWith } from "./solid-utils";
import { Accessor, createMemo, createSignal } from "solid-js";

type createControllableSignalParams<T> = {
value?: Accessor<T | undefined>;
defaultValue: T;
onChange?: (newValue: T) => void;
};

function createControllableSignal<T>(props: createControllableSignalParams<T>) {
const [uncontrolledValue, setUncontrolledValue] = createSignal(props.defaultValue);
const isControlled = createMemo(() => props.value?.() !== undefined);
const value = createMemo(() => (isControlled() ? props.value?.() : uncontrolledValue()));

const setValue = (next: T | ((prevValue: T) => T)) => {
const nextValue = accessWith(next, value() as T);

if (!Object.is(nextValue, value())) {
if (!isControlled()) {
setUncontrolledValue(nextValue as any);
}

props.onChange?.(nextValue);
}
};

return [value, setValue] as const;
}

export default createControllableSignal;
33 changes: 0 additions & 33 deletions src/renderer/src/lib/controllable-state.ts

This file was deleted.

8 changes: 8 additions & 0 deletions src/renderer/src/lib/solid-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type AnyFunction = (...args: any[]) => any;

export function accessWith<T>(
valueOrFn: T,
...args: T extends AnyFunction ? Parameters<T> : never
): T extends AnyFunction ? ReturnType<T> : T {
return typeof valueOrFn === "function" ? valueOrFn(...args) : valueOrFn;
}
2 changes: 1 addition & 1 deletion src/renderer/src/scenes/loading-scene/LoadingScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function LoadingScene() {
<div class="loading-scene">
<h3 class="loading-scene__title">{title()}</h3>

<Slider max={1} min={0} value={progressValue}>
<Slider max={1} min={0} value={progressValue()}>
<Slider.Track class="block h-2.5 w-[420px] overflow-hidden rounded bg-thick-material">
<Slider.Range class="block h-full bg-white" />
</Slider.Track>
Expand Down
Loading