mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-02-24 08:48:47 +01:00
Slight redesign of Shortcuts form
Yeah, still no Edit
This commit is contained in:
parent
b1d6f2001e
commit
ab616c5fc7
2 changed files with 154 additions and 129 deletions
|
@ -40,39 +40,20 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#shortcuts-settings-container form {
|
#shortcut-settings-form form > * {
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
padding: 16px;
|
|
||||||
background-color: var(--bg-faded-color);
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#shortcuts-settings-container form header {
|
#shortcut-settings-form label {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shortcuts-settings-container form > * {
|
|
||||||
flex-basis: max(320px, 100%);
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#shortcuts-settings-container form label {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
#shortcuts-settings-container form label > span:first-child {
|
#shortcut-settings-form label > span:first-child {
|
||||||
flex-basis: 5em;
|
flex-basis: 5em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
#shortcuts-settings-container form :is(input[type='text'], select) {
|
#shortcut-settings-form :is(input[type='text'], select) {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-basis: 70%;
|
flex-basis: 70%;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import states from '../utils/states';
|
||||||
|
|
||||||
import AsyncText from './AsyncText';
|
import AsyncText from './AsyncText';
|
||||||
import Icon from './icon';
|
import Icon from './icon';
|
||||||
|
import Modal from './modal';
|
||||||
|
|
||||||
const SHORTCUTS_LIMIT = 9;
|
const SHORTCUTS_LIMIT = 9;
|
||||||
|
|
||||||
|
@ -161,6 +162,7 @@ function ShortcutsSettings() {
|
||||||
|
|
||||||
const [lists, setLists] = useState([]);
|
const [lists, setLists] = useState([]);
|
||||||
const [followedHashtags, setFollowedHashtags] = useState([]);
|
const [followedHashtags, setFollowedHashtags] = useState([]);
|
||||||
|
const [showForm, setShowForm] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@ -308,116 +310,158 @@ function ShortcutsSettings() {
|
||||||
No shortcuts yet. Add one from the form below.
|
No shortcuts yet. Add one from the form below.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<hr />
|
<p
|
||||||
<ShortcutForm
|
style={{
|
||||||
disabled={shortcuts.length >= SHORTCUTS_LIMIT}
|
display: 'flex',
|
||||||
lists={lists}
|
justifyContent: 'space-between',
|
||||||
followedHashtags={followedHashtags}
|
alignItems: 'center',
|
||||||
onSubmit={(data) => {
|
|
||||||
console.log('onSubmit', data);
|
|
||||||
states.shortcuts.push(data);
|
|
||||||
}}
|
}}
|
||||||
/>
|
>
|
||||||
|
<span class="insignificant">
|
||||||
|
{shortcuts.length >= SHORTCUTS_LIMIT &&
|
||||||
|
`Max ${SHORTCUTS_LIMIT} shortcuts`}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={shortcuts.length >= SHORTCUTS_LIMIT}
|
||||||
|
onClick={() => setShowForm(true)}
|
||||||
|
>
|
||||||
|
<Icon icon="plus" /> <span>Add shortcut</span>
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</main>
|
||||||
|
{showForm && (
|
||||||
|
<Modal
|
||||||
|
class="light"
|
||||||
|
onClick={(e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
setShowForm(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ShortcutForm
|
||||||
|
disabled={shortcuts.length >= SHORTCUTS_LIMIT}
|
||||||
|
lists={lists}
|
||||||
|
followedHashtags={followedHashtags}
|
||||||
|
onSubmit={(data) => {
|
||||||
|
console.log('onSubmit', data);
|
||||||
|
states.shortcuts.push(data);
|
||||||
|
}}
|
||||||
|
onClose={() => setShowForm(false)}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ShortcutForm({
|
||||||
|
type,
|
||||||
|
lists,
|
||||||
|
followedHashtags,
|
||||||
|
onSubmit,
|
||||||
|
disabled,
|
||||||
|
onClose = () => {},
|
||||||
|
}) {
|
||||||
|
const [currentType, setCurrentType] = useState(type);
|
||||||
|
return (
|
||||||
|
<div id="shortcut-settings-form" class="sheet">
|
||||||
|
<header>
|
||||||
|
<h2>Add shortcut</h2>
|
||||||
|
</header>
|
||||||
|
<main tabindex="-1">
|
||||||
|
<form
|
||||||
|
onSubmit={(e) => {
|
||||||
|
// Construct a nice object from form
|
||||||
|
e.preventDefault();
|
||||||
|
const data = new FormData(e.target);
|
||||||
|
const result = {};
|
||||||
|
data.forEach((value, key) => {
|
||||||
|
result[key] = value?.trim();
|
||||||
|
});
|
||||||
|
if (!result.type) return;
|
||||||
|
onSubmit(result);
|
||||||
|
// Reset
|
||||||
|
e.target.reset();
|
||||||
|
setCurrentType(null);
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
<span>Timeline</span>
|
||||||
|
<select
|
||||||
|
required
|
||||||
|
disabled={disabled}
|
||||||
|
onChange={(e) => {
|
||||||
|
setCurrentType(e.target.value);
|
||||||
|
}}
|
||||||
|
name="type"
|
||||||
|
>
|
||||||
|
<option></option>
|
||||||
|
{TYPES.map((type) => (
|
||||||
|
<option value={type}>{TYPE_TEXT[type]}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
{TYPE_PARAMS[currentType]?.map?.(
|
||||||
|
({ text, name, type, placeholder, pattern }) => {
|
||||||
|
if (currentType === 'list') {
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
<span>List</span>
|
||||||
|
<select name="id" required disabled={disabled}>
|
||||||
|
{lists.map((list) => (
|
||||||
|
<option value={list.id}>{list.title}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
<span>{text}</span>{' '}
|
||||||
|
<input
|
||||||
|
type={type}
|
||||||
|
name={name}
|
||||||
|
placeholder={placeholder}
|
||||||
|
required={type === 'text'}
|
||||||
|
disabled={disabled}
|
||||||
|
list={
|
||||||
|
currentType === 'hashtag'
|
||||||
|
? 'followed-hashtags-datalist'
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
autocorrect="off"
|
||||||
|
autocapitalize="off"
|
||||||
|
spellcheck={false}
|
||||||
|
pattern={pattern}
|
||||||
|
/>
|
||||||
|
{currentType === 'hashtag' &&
|
||||||
|
followedHashtags.length > 0 && (
|
||||||
|
<datalist id="followed-hashtags-datalist">
|
||||||
|
{followedHashtags.map((tag) => (
|
||||||
|
<option value={tag.name} />
|
||||||
|
))}
|
||||||
|
</datalist>
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
<button type="submit" class="block" disabled={disabled}>
|
||||||
|
Add
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ShortcutsSettings;
|
export default ShortcutsSettings;
|
||||||
function ShortcutForm({ type, lists, followedHashtags, onSubmit, disabled }) {
|
|
||||||
const [currentType, setCurrentType] = useState(type);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
// Construct a nice object from form
|
|
||||||
e.preventDefault();
|
|
||||||
const data = new FormData(e.target);
|
|
||||||
const result = {};
|
|
||||||
data.forEach((value, key) => {
|
|
||||||
result[key] = value?.trim();
|
|
||||||
});
|
|
||||||
if (!result.type) return;
|
|
||||||
onSubmit(result);
|
|
||||||
// Reset
|
|
||||||
e.target.reset();
|
|
||||||
setCurrentType(null);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<header>
|
|
||||||
<h3>Add a shortcut</h3>
|
|
||||||
<button type="submit" disabled={disabled}>
|
|
||||||
Add
|
|
||||||
</button>
|
|
||||||
</header>
|
|
||||||
<p>
|
|
||||||
<label>
|
|
||||||
<span>Timeline</span>
|
|
||||||
<select
|
|
||||||
required
|
|
||||||
disabled={disabled}
|
|
||||||
onChange={(e) => {
|
|
||||||
setCurrentType(e.target.value);
|
|
||||||
}}
|
|
||||||
name="type"
|
|
||||||
>
|
|
||||||
<option></option>
|
|
||||||
{TYPES.map((type) => (
|
|
||||||
<option value={type}>{TYPE_TEXT[type]}</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</p>
|
|
||||||
{TYPE_PARAMS[currentType]?.map?.(
|
|
||||||
({ text, name, type, placeholder, pattern }) => {
|
|
||||||
if (currentType === 'list') {
|
|
||||||
return (
|
|
||||||
<p>
|
|
||||||
<label>
|
|
||||||
<span>List</span>
|
|
||||||
<select name="id" required disabled={disabled}>
|
|
||||||
{lists.map((list) => (
|
|
||||||
<option value={list.id}>{list.title}</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<p>
|
|
||||||
<label>
|
|
||||||
<span>{text}</span>{' '}
|
|
||||||
<input
|
|
||||||
type={type}
|
|
||||||
name={name}
|
|
||||||
placeholder={placeholder}
|
|
||||||
required={type === 'text'}
|
|
||||||
disabled={disabled}
|
|
||||||
list={
|
|
||||||
currentType === 'hashtag'
|
|
||||||
? 'followed-hashtags-datalist'
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
autocorrect="off"
|
|
||||||
autocapitalize="off"
|
|
||||||
spellcheck={false}
|
|
||||||
pattern={pattern}
|
|
||||||
/>
|
|
||||||
{currentType === 'hashtag' && followedHashtags.length > 0 && (
|
|
||||||
<datalist id="followed-hashtags-datalist">
|
|
||||||
{followedHashtags.map((tag) => (
|
|
||||||
<option value={tag.name} />
|
|
||||||
))}
|
|
||||||
</datalist>
|
|
||||||
)}
|
|
||||||
</label>
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)}
|
|
||||||
</form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue