Add file input type

This commit is contained in:
Zerebos 2024-12-08 16:02:41 -05:00
parent f747ad5846
commit 25d3dcfac6
No known key found for this signature in database
5 changed files with 113 additions and 13 deletions

7
.gitignore vendored
View File

@ -1,3 +1,4 @@
dist/
node_modules
.env
dist/
node_modules
.env
.idea/

View File

@ -1,4 +1,4 @@
import {ipcRenderer as IPC, shell} from "electron";
import {ipcRenderer as IPC, shell, webUtils} from "electron";
export const ipcRenderer = {
send: IPC.send.bind(IPC),
@ -9,4 +9,4 @@ export const ipcRenderer = {
off: IPC.off.bind(IPC)
};
export {shell};
export {shell, webUtils};

View File

@ -0,0 +1,62 @@
.bd-file-input-wrap {
position: relative;
}
.bd-file-input {
color: var(--text-normal);
background-color: var(--input-background);
min-width: 250px;
width: 100%;
font-size: 16px;
border-radius: 3px;
padding: 10px;
height: 40px;
box-sizing: border-box;
overflow: hidden;
border: none;
}
.bd-file-input::-webkit-file-upload-button {
color: white;
background: #3E82E5;
outline: 0;
border: 0;
padding: 12px 16px!important;
margin-top: -10px;
margin-left: -10px;
margin-right: 10px;
bottom: 0;
border-radius: 3px 0 0 3px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
user-select: none;
}
.bd-file-input-wrap .bd-file-input-clear {
position: absolute;
top: 50%;
right: 5px;
transform: translateY(-50%);
opacity: 0.5;
}
.bd-file-input-wrap .bd-file-input-clear:hover {
background: none;
opacity: 1;
}
.bd-file-input-wrap .bd-file-input-clear svg {
width: 18px !important;
height: 18px !important;
}
.bd-file-input-wrap.bd-file-input-disabled {
cursor: not-allowed;
opacity: 0.5;
}
.bd-file-input-wrap.bd-file-input-disabled .bd-file-input,
.bd-file-input-wrap.bd-file-input-disabled .bd-file-input-clear {
pointer-events: none;
}

View File

@ -0,0 +1,35 @@
import {webUtils} from "electron";
import React from "@modules/react";
import Button from "@ui/base/button";
import Close from "@ui/icons/close";
const {useRef, useCallback, useEffect} = React;
export default function Filepicker({multiple, accept, clearable, onChange, disabled, actions}) {
const inputRef = useRef(null);
const change = useCallback((e) => {
if (disabled) return;
const files = [];
for (const file of e.target.files) {
files.push(webUtils.getPathForFile(file));
}
onChange?.(multiple ? files : files[0]);
}, [onChange, disabled, multiple]);
const clear = useCallback(() => {
inputRef.current.value = "";
onChange?.(multiple ? [] : "");
}, [onChange, multiple]);
useEffect(() => {
if (!actions) return;
actions.clear = clear;
}, [clear, actions]);
return <div className={`bd-file-input-wrap ${disabled ? "bd-file-input-disabled" : ""}`}>
<input onChange={change} type="file" className="bd-file-input" multiple={multiple} accept={accept} disabled={disabled} ref={inputRef} />
{clearable && <Button size={Button.Sizes.ICON} look={Button.Looks.BLANK} onClick={clear} className="bd-file-input-clear"><Close size="24px" /></Button>}
</div>;
}

View File

@ -10,6 +10,7 @@ import Slider from "./components/slider";
import Radio from "./components/radio";
import Keybind from "./components/keybind";
import Color from "./components/color";
import Filepicker from "./components/file";
const {useCallback} = React;
@ -35,14 +36,15 @@ export default function Group({onChange, id, name, button, shown, onDrawerToggle
export function buildSetting(setting) {
let children = null;
if (setting.type == "dropdown") children = <Dropdown disabled={setting.disabled} id={setting.id} options={setting.options} value={setting.value} onChange={setting.onChange} />;
if (setting.type == "number") children = <Number disabled={setting.disabled} id={setting.id} min={setting.min} max={setting.max} step={setting.step} value={setting.value} onChange={setting.onChange} />;
if (setting.type == "switch") children = <Switch disabled={setting.disabled} id={setting.id} value={setting.value} onChange={setting.onChange} />;
if (setting.type == "text") children = <Textbox disabled={setting.disabled} id={setting.id} value={setting.value} onChange={setting.onChange} />;
if (setting.type == "slider") children = <Slider disabled={setting.disabled} id={setting.id} min={setting.min} max={setting.max} step={setting.step} value={setting.value} onChange={setting.onChange} units={setting.units} markers={setting.markers} />;
if (setting.type == "radio") children = <Radio disabled={setting.disabled} id={setting.id} name={setting.id} options={setting.options} value={setting.value} onChange={setting.onChange} />;
if (setting.type == "keybind") children = <Keybind disabled={setting.disabled} id={setting.id} value={setting.value} max={setting.max} onChange={setting.onChange} />;
if (setting.type == "color") children = <Color disabled={setting.disabled} id={setting.id} value={setting.value} defaultValue={setting.defaultValue} colors={setting.colors} onChange={setting.onChange} />;
if (setting.type == "dropdown") children = <Dropdown {...setting} />;
if (setting.type == "number") children = <Number {...setting} />;
if (setting.type == "switch") children = <Switch {...setting} />;
if (setting.type == "text") children = <Textbox {...setting} />;
if (setting.type == "file") children = <Filepicker {...setting} />;
if (setting.type == "slider") children = <Slider {...setting} />;
if (setting.type == "radio") children = <Radio {...setting} />;
if (setting.type == "keybind") children = <Keybind {...setting} />;
if (setting.type == "color") children = <Color {...setting} />;
if (setting.type == "custom") children = setting.children;
if (!children) return null;
return <Item id={setting.id} inline={setting.hasOwnProperty("inline") ? setting.inline : setting.type !== "radio" && setting.type !== "color" && setting.type !== "slider"} key={setting.id} name={setting.name} note={setting.note}>{children}</Item>;