Add ability to disable all setting types

This commit is contained in:
Zerebos 2024-12-07 21:27:40 -05:00
parent c3951cba25
commit 1b9d35654f
No known key found for this signature in database
14 changed files with 310 additions and 249 deletions

View File

@ -48,6 +48,11 @@
transition: 150ms ease border-color;
}
.bd-select.bd-select-disabled {
cursor: not-allowed;
opacity: 0.5;
}
.bd-select:hover,
.bd-select.menu-open {
border-color: var(--background-tertiary);
@ -123,7 +128,7 @@
.bd-setting-header label {
font-weight: 500;
cursor: pointer;
/* cursor: pointer; */
overflow: hidden;
word-wrap: break-word;
font-size: 16px;

View File

@ -2,6 +2,16 @@
display: flex;
}
.bd-color-picker-container.bd-color-picker-disabled {
cursor: not-allowed;
opacity: 0.5;
}
.bd-color-picker-container.bd-color-picker-disabled > .bd-color-picker-controls,
.bd-color-picker-container.bd-color-picker-disabled > .bd-color-picker-swatch {
pointer-events: none;
}
.bd-color-picker-controls {
padding-left: 1px;
padding-top: 2px;

View File

@ -10,6 +10,15 @@
cursor: pointer;
}
.bd-keybind-wrap.bd-keybind-disabled {
cursor: not-allowed;
opacity: 0.5;
}
.bd-keybind-wrap.bd-keybind-disabled .bd-keybind-controls {
pointer-events: none;
}
.bd-keybind-wrap input {
outline: none;
border: none;

View File

@ -14,3 +14,8 @@
border-radius: 3px;
width: 70px;
}
.bd-number-input:disabled {
cursor: not-allowed;
opacity: 0.5;
}

View File

@ -14,6 +14,15 @@
color: var(--interactive-normal);
}
.bd-radio-group.bd-radio-disabled {
cursor: not-allowed;
opacity: 0.5;
}
.bd-radio-group.bd-radio-disabled .bd-radio-option {
pointer-events: none;
}
.bd-radio-option:hover {
background-color: var(--background-modifier-hover);
}

View File

@ -2,7 +2,16 @@
display: flex;
color: var(--text-normal);
align-items: center;
}
}
.bd-slider-wrap.bd-slider-disabled {
cursor: not-allowed;
opacity: 0.5;
}
.bd-slider-wrap.bd-slider-disabled .bd-slider-input {
pointer-events: none;
}
.bd-slider-label {
background: var(--brand-experiment);

View File

@ -8,4 +8,9 @@
border: none;
padding: 10px;
height: 40px;
}
}
.bd-text-input:disabled {
cursor: not-allowed;
opacity: 0.5;
}

View File

@ -57,15 +57,16 @@ const getContrastColor = (color) => {
};
export default function Color({value: initialValue, onChange, colors = defaultColors, defaultValue}) {
export default function Color({value: initialValue, onChange, colors = defaultColors, defaultValue, disabled}) {
const [value, setValue] = useState(initialValue);
const change = useCallback((e) => {
if (disabled) return;
onChange?.(resolveColor(e.target.value));
setValue(e.target.value);
}, [onChange]);
}, [onChange, disabled]);
const intValue = resolveColor(value, false);
return <div className="bd-color-picker-container">
return <div className={`bd-color-picker-container ${disabled ? "bd-color-picker-disabled" : ""}`}>
<div className="bd-color-picker-controls">
<DiscordModules.Tooltip text="Default" position="bottom">
{props => (
@ -81,7 +82,7 @@ export default function Color({value: initialValue, onChange, colors = defaultCo
{props => (
<div className="bd-color-picker-custom">
<Dropper color={getContrastColor(resolveColor(value, true))} />
<input {...props} style={{backgroundColor: resolveColor(value)}} type="color" className="bd-color-picker" value={resolveColor(value)} onChange={change} />
<input {...props} style={{backgroundColor: resolveColor(value)}} type="color" className="bd-color-picker" value={resolveColor(value)} onChange={change} disabled={disabled} />
</div>
)}
</DiscordModules.Tooltip>

View File

@ -5,7 +5,7 @@ import Arrow from "@ui/icons/downarrow";
const {useState, useCallback} = React;
export default function Select({value: initialValue, options, style, onChange}) {
export default function Select({value: initialValue, options, style, onChange, disabled}) {
const [value, setValue] = useState(initialValue ?? options[0].value);
const change = useCallback((val) => {
onChange?.(val);
@ -23,11 +23,13 @@ export default function Select({value: initialValue, options, style, onChange})
event.preventDefault();
event.stopPropagation();
if (disabled) return;
const next = !open;
setOpen(next);
if (!next) return;
document.addEventListener("click", hideMenu);
}, [hideMenu, open]);
}, [hideMenu, open, disabled]);
// ?? options[0] provides a double failsafe
@ -40,7 +42,8 @@ export default function Select({value: initialValue, options, style, onChange})
const styleClass = style == "transparent" ? " bd-select-transparent" : "";
const isOpen = open ? " menu-open" : "";
return <div className={`bd-select${styleClass}${isOpen}`} onClick={showMenu}>
const isDisabled = disabled ? " bd-select-disabled" : "";
return <div className={`bd-select${styleClass}${isOpen}${isDisabled}`} onClick={showMenu}>
<div className="bd-select-value">{selected.label}</div>
<Arrow className="bd-select-arrow" />
{open && optionComponents}

View File

@ -7,7 +7,7 @@ import Close from "@ui/icons/close";
const {useState, useCallback, useEffect} = React;
export default function Keybind({value: initialValue, onChange, max = 2, clearable = true}) {
export default function Keybind({value: initialValue, onChange, max = 2, clearable = true, disabled}) {
const [state, setState] = useState({value: initialValue, isRecording: false, accum: []});
useEffect(() => {
@ -32,19 +32,21 @@ export default function Keybind({value: initialValue, onChange, max = 2, clearab
const clearKeybind = useCallback((event) => {
event.stopPropagation();
event.preventDefault();
if (disabled) return;
if (onChange) onChange([]);
setState({...state, isRecording: false, value: [], accum: []});
}, [onChange, state]);
}, [onChange, state, disabled]);
const onClick = useCallback((e) => {
if (disabled) return;
if (e.target?.className?.includes?.("bd-keybind-clear") || e.target?.closest(".bd-button")?.className?.includes("bd-keybind-clear")) return clearKeybind(e);
setState({...state, isRecording: !state.isRecording});
}, [state, clearKeybind]);
}, [state, clearKeybind, disabled]);
const displayValue = state.isRecording ? "Recording..." : !state.value.length ? "N/A" : state.value.join(" + ");
return <div className={"bd-keybind-wrap" + (state.isRecording ? " recording" : "")} onClick={onClick}>
<input readOnly={true} type="text" className="bd-keybind-input" value={displayValue} />
return <div className={"bd-keybind-wrap" + (state.isRecording ? " recording" : "") + (disabled ? " bd-keybind-disabled" : "")} onClick={onClick}>
<input readOnly={true} type="text" className="bd-keybind-input" value={displayValue} disabled={disabled} />
<div className="bd-keybind-controls">
<Button size={Button.Sizes.ICON} look={Button.Looks.FILLED} color={state.isRecording ? Button.Colors.RED : Button.Colors.BRAND} className="bd-keybind-record" onClick={onClick}><Keyboard size="24px" /></Button>
{clearable && <Button size={Button.Sizes.ICON} look={Button.Looks.BLANK} onClick={clearKeybind} className="bd-keybind-clear"><Close size="24px" /></Button>}

View File

@ -3,12 +3,12 @@ import React from "@modules/react";
const {useState, useCallback} = React;
export default function Number({value: initialValue, min, max, step, onChange}) {
export default function Number({value: initialValue, min, max, step, onChange, disabled}) {
const [value, setValue] = useState(initialValue);
const change = useCallback((e) => {
onChange?.(e.target.value);
setValue(e.target.value);
}, [onChange]);
return <input onChange={change} type="number" className="bd-number-input" min={min} max={max} step={step} value={value} />;
return <input onChange={change} type="number" className="bd-number-input" min={min} max={max} step={step} value={value} disabled={disabled} />;
}

View File

@ -5,19 +5,20 @@ import RadioIcon from "@ui/icons/radio";
const {useState, useCallback} = React;
export default function Radio({name, value, options, onChange}) {
export default function Radio({name, value, options, onChange, disabled}) {
const [index, setIndex] = useState(options.findIndex(o => o.value === value));
const change = useCallback((e) => {
if (disabled) return;
const newIndex = parseInt(e.target.value);
const newValue = options[newIndex].value;
onChange?.(newValue);
setIndex(newIndex);
}, [options, onChange]);
}, [options, onChange, disabled]);
function renderOption(opt, i) {
const isSelected = index === i;
return <label className={"bd-radio-option" + (isSelected ? " bd-radio-selected" : "")}>
<input onChange={change} type="radio" name={name} checked={isSelected} value={i} />
<input onChange={change} type="radio" name={name} checked={isSelected} value={i} disabled={disabled} />
{/* <span className="bd-radio-button"></span> */}
<RadioIcon className="bd-radio-icon" size="24" checked={isSelected} />
<div className="bd-radio-label-wrap">
@ -27,5 +28,5 @@ export default function Radio({name, value, options, onChange}) {
</label>;
}
return <div className="bd-radio-group">{options.map(renderOption)}</div>;
return <div className={`bd-radio-group ${disabled ? "bd-radio-disabled" : ""}`}>{options.map(renderOption)}</div>;
}

View File

@ -3,14 +3,15 @@ import React from "@modules/react";
const {useState, useCallback} = React;
export default function Slider({value: initialValue, min, max, step, onChange}) {
export default function Slider({value: initialValue, min, max, step, onChange, disabled}) {
const [value, setValue] = useState(initialValue);
const change = useCallback((e) => {
if (disabled) return;
onChange?.(e.target.value);
setValue(e.target.value);
}, [onChange]);
}, [onChange, disabled]);
return <div className="bd-slider-wrap">
<div className="bd-slider-label">{value}</div><input onChange={change} type="range" className="bd-slider-input" min={min} max={max} step={step} value={value} style={{backgroundSize: (value - min) * 100 / (max - min) + "% 100%"}} />
return <div className={`bd-slider-wrap ${disabled ? "bd-slider-disabled" : ""}`}>
<div className="bd-slider-label">{value}</div><input onChange={change} type="range" className="bd-slider-input" min={min} max={max} step={step} value={value} style={{backgroundSize: (value - min) * 100 / (max - min) + "% 100%"}} disabled={disabled} />
</div>;
}

View File

@ -3,12 +3,13 @@ import React from "@modules/react";
const {useState, useCallback} = React;
export default function Textbox({value: initialValue, maxLength, placeholder, onKeyDown, onChange}) {
export default function Textbox({value: initialValue, maxLength, placeholder, onKeyDown, onChange, disabled}) {
const [value, setValue] = useState(initialValue);
const change = useCallback((e) => {
if (disabled) return;
onChange?.(e.target.value);
setValue(e.target.value);
}, [onChange]);
}, [onChange, disabled]);
return <input onChange={change} onKeyDown={onKeyDown} type="text" className="bd-text-input" placeholder={placeholder} maxLength={maxLength} value={value} />;
return <input onChange={change} onKeyDown={onKeyDown} type="text" className="bd-text-input" placeholder={placeholder} maxLength={maxLength} value={value} disabled={disabled} />;
}