1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/renderer/components/radio/radio.tsx
Sebastian Malton 57e4e29a16
Fix not being able to switch metrics if none are available (#5430)
Co-authored-by: Alex Andreev <alex.andreev.email@gmail.com>
2022-08-02 10:05:15 -04:00

95 lines
2.2 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import "./radio.scss";
import React, { useContext, useRef } from "react";
import type { SingleOrMany } from "../../utils";
import { cssNames, noop } from "../../utils";
export interface RadioGroupProps<T> {
className?: string;
value?: T;
asButtons?: boolean;
disabled?: boolean;
onChange: (value: T) => void;
children: SingleOrMany<React.ReactElement<RadioProps<T>>>;
}
interface RadioGroupContext {
disabled: boolean;
value: any | undefined;
onSelect: (newValue: any) => void;
}
const radioGroupContext = React.createContext<RadioGroupContext>({
disabled: false,
value: undefined,
onSelect: noop,
});
export function RadioGroup<T>({
value,
asButtons,
disabled = false,
onChange,
className,
children,
}: RadioGroupProps<T>) {
return (
<div
className={cssNames("RadioGroup", { buttonsView: asButtons }, className)}
>
<radioGroupContext.Provider value={{ disabled, onSelect: onChange, value }}>
{children}
</radioGroupContext.Provider>
</div>
);
}
export interface RadioProps<T> {
className?: string;
label: React.ReactNode;
value: T;
disabled?: boolean;
}
export function Radio<T>({
className,
label,
value,
disabled = false,
}: RadioProps<T>) {
const ctx = useContext(radioGroupContext);
const ref = useRef<HTMLLabelElement | null>(null);
const checked = ctx.value === value;
return (
<label
className={cssNames("Radio flex align-center", className, {
checked,
disabled: disabled || ctx.disabled,
})}
tabIndex={checked ? undefined : 0}
onKeyDown={event => {
// Spacebar or Enter key
if (event.key === " " || event.key === "Enter") {
ref.current?.click();
event.preventDefault();
}
}}
ref={ref}
>
<input
type="radio"
checked={checked}
onChange={() => ctx.onSelect(value)}
disabled={disabled || ctx.disabled}
/>
<i className="tick flex center"/>
{label ? <div className="label">{label}</div> : null}
</label>
);
}