Close button for modal sheets

This commit is contained in:
Lim Chee Aun 2023-04-20 16:10:57 +08:00
parent b2827e690d
commit 5dc3603795
14 changed files with 183 additions and 28 deletions

View file

@ -1207,6 +1207,7 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
box-shadow: 0 -1px 32px var(--drop-shadow-color);
animation: slide-up 0.3s var(--timing-function);
/* border: 1px solid var(--outline-color); */
position: relative;
}
.sheet-max {
width: 90vw;
@ -1215,12 +1216,52 @@ body:has(.media-modal-container + .status-deck) .media-post-link {
height: 90vh;
height: 90dvh;
}
.sheet .sheet-close {
position: absolute;
border-radius: 0;
padding: 0;
right: env(safe-area-inset-right);
width: 44px;
height: 44px;
display: inline-flex;
align-items: center;
justify-content: center;
z-index: 2;
background-color: transparent;
background-image: radial-gradient(
circle,
var(--close-button-bg-color) 0px 14px,
transparent 14px
);
color: var(--close-button-color);
}
.sheet .sheet-close.outer {
margin-top: -44px;
background-image: radial-gradient(
circle,
var(--bg-faded-color) 0px 14px,
transparent 14px
);
}
.sheet .sheet-close:is(:hover, :focus) {
color: var(--close-button-hover-color);
}
.sheet .sheet-close:active {
background-image: radial-gradient(
circle,
var(--close-button-bg-active-color) 0px 14px,
transparent 14px
);
}
.sheet header {
padding: 16px 16px 8px;
padding-left: max(16px, env(safe-area-inset-left));
padding-right: max(16px, env(safe-area-inset-right));
user-select: none;
}
.sheet .sheet-close:not(.outer) + header {
padding-right: max(44px, env(safe-area-inset-right));
}
.sheet header :is(h1, h2, h3) {
margin: 0;
}

View file

@ -365,7 +365,7 @@ function App() {
}
}}
>
<Drafts />
<Drafts onClose={() => (states.showDrafts = false)} />
</Modal>
)}
{!!snapStates.showMediaModal && (
@ -399,7 +399,9 @@ function App() {
}
}}
>
<ShortcutsSettings />
<ShortcutsSettings
onClose={() => (states.showShortcutsSettings = false)}
/>
</Modal>
)}
<BackgroundService isLoggedIn={isLoggedIn} />

View file

@ -846,7 +846,11 @@ function RelatedActions({ info, instance, authenticated }) {
}
}}
>
<TranslatedBioSheet note={note} fields={fields} />
<TranslatedBioSheet
note={note}
fields={fields}
onClose={() => setShowTranslatedBio(false)}
/>
</Modal>
)}
{!!showAddRemoveLists && (
@ -858,7 +862,10 @@ function RelatedActions({ info, instance, authenticated }) {
}
}}
>
<AddRemoveListsSheet accountID={accountID.current} />
<AddRemoveListsSheet
accountID={accountID.current}
onClose={() => setShowAddRemoveLists(false)}
/>
</Modal>
)}
</>
@ -895,7 +902,7 @@ function niceAccountURL(url) {
);
}
function TranslatedBioSheet({ note, fields }) {
function TranslatedBioSheet({ note, fields, onClose }) {
const fieldsText =
fields
?.map(({ name, value }) => `${name}\n${getHTMLText(value)}`)
@ -905,8 +912,13 @@ function TranslatedBioSheet({ note, fields }) {
return (
<div class="sheet">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<h2>Translated Bio</h2>
x<h2>Translated Bio</h2>
</header>
<main>
<p
@ -922,7 +934,7 @@ function TranslatedBioSheet({ note, fields }) {
);
}
function AddRemoveListsSheet({ accountID }) {
function AddRemoveListsSheet({ accountID, onClose }) {
const { masto } = api();
const [uiState, setUiState] = useState('default');
const [lists, setLists] = useState([]);
@ -952,6 +964,11 @@ function AddRemoveListsSheet({ accountID }) {
return (
<div class="sheet" id="list-add-remove-container">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<h2>Add/Remove from Lists</h2>
</header>

View file

@ -5,6 +5,7 @@ import { api } from '../utils/api';
import states from '../utils/states';
import AccountInfo from './account-info';
import Icon from './icon';
function AccountSheet({ account, instance: propInstance, onClose }) {
const { masto, instance, authenticated } = api({ instance: propInstance });
@ -31,6 +32,11 @@ function AccountSheet({ account, instance: propInstance, onClose }) {
}
}}
>
{!!onClose && (
<button type="button" class="sheet-close outer" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<AccountInfo
instance={instance}
authenticated={authenticated}

View file

@ -1504,6 +1504,15 @@ function MediaAttachment({
}}
>
<div id="media-sheet" class="sheet sheet-max">
<button
type="button"
class="sheet-close"
onClick={() => {
setShowModal(false);
}}
>
<Icon icon="x" />
</button>
<header>
<h2>
{
@ -1742,6 +1751,11 @@ function CustomEmojisModal({
return (
<div id="custom-emojis-sheet" class="sheet">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<b>Custom emojis</b>{' '}
{uiState === 'loading' ? (

View file

@ -11,7 +11,7 @@ import { getCurrentAccountNS } from '../utils/store-utils';
import Icon from './icon';
import Loader from './loader';
function Drafts() {
function Drafts({ onClose }) {
const { masto } = api();
const [uiState, setUIState] = useState('default');
const [drafts, setDrafts] = useState([]);
@ -51,6 +51,11 @@ function Drafts() {
return (
<div class="sheet">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<h2>
Unsent drafts <Loader abrupt hidden={uiState !== 'loading'} />

View file

@ -2,7 +2,9 @@ import { useEffect, useRef, useState } from 'preact/hooks';
import { api } from '../utils/api';
function ListAddEdit({ list, onClose = () => {} }) {
import Icon from './icon';
function ListAddEdit({ list, onClose }) {
const { masto } = api();
const [uiState, setUiState] = useState('default');
const editMode = !!list;
@ -16,6 +18,11 @@ function ListAddEdit({ list, onClose = () => {} }) {
}, [editMode]);
return (
<div class="sheet">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}{' '}
<header>
<h2>{editMode ? 'Edit list' : 'New list'}</h2>
</header>
@ -52,7 +59,7 @@ function ListAddEdit({ list, onClose = () => {} }) {
console.log(listResult);
setUiState('default');
onClose({
onClose?.({
state: 'success',
list: listResult,
});
@ -109,7 +116,7 @@ function ListAddEdit({ list, onClose = () => {} }) {
try {
await masto.v1.lists.remove(list.id);
setUiState('default');
onClose({
onClose?.({
state: 'deleted',
});
} catch (e) {

View file

@ -275,17 +275,25 @@ function MediaModal({
}
}}
>
<MediaAltModal alt={showMediaAlt} />
<MediaAltModal
alt={showMediaAlt}
onClose={() => setShowMediaAlt(false)}
/>
</Modal>
)}
</div>
);
}
function MediaAltModal({ alt }) {
function MediaAltModal({ alt, onClose }) {
const [forceTranslate, setForceTranslate] = useState(false);
return (
<div class="sheet">
{!!onClose && (
<button type="button" class="sheet-close outer" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header class="header-grid">
<h2>Media description</h2>
<div class="header-side">

View file

@ -194,7 +194,7 @@ export const SHORTCUTS_META = {
},
};
function ShortcutsSettings() {
function ShortcutsSettings({ onClose }) {
const snapStates = useSnapshot(states);
const { masto } = api();
const { shortcuts } = snapStates;
@ -231,6 +231,11 @@ function ShortcutsSettings() {
return (
<div id="shortcuts-settings-container" class="sheet" tabindex="-1">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<h2>
<Icon icon="shortcut" /> Shortcuts{' '}
@ -484,7 +489,7 @@ function ShortcutForm({
disabled,
shortcut,
shortcutIndex,
onClose = () => {},
onClose,
}) {
console.log('shortcut', shortcut);
const editMode = !!shortcut;
@ -510,6 +515,11 @@ function ShortcutForm({
return (
<div id="shortcut-settings-form" class="sheet">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<h2>{editMode ? 'Edit' : 'Add'} shortcut</h2>
</header>
@ -541,7 +551,7 @@ function ShortcutForm({
// Reset
e.target.reset();
setCurrentType(null);
onClose();
onClose?.();
}}
>
<p>
@ -627,7 +637,7 @@ function ShortcutForm({
class="light danger"
onClick={() => {
states.shortcuts.splice(shortcutIndex, 1);
onClose();
onClose?.();
}}
>
Remove

View file

@ -1193,7 +1193,11 @@ function Status({
}
}}
>
<ReactionsModal statusID={id} instance={instance} />
<ReactionsModal
statusID={id}
instance={instance}
onClose={() => setShowReactions(false)}
/>
</Modal>
)}
</article>
@ -1571,7 +1575,7 @@ function EditedAtModal({
statusID,
instance,
fetchStatusHistory = () => {},
onClose = () => {},
onClose,
}) {
const [uiState, setUIState] = useState('default');
const [editHistory, setEditHistory] = useState([]);
@ -1593,10 +1597,12 @@ function EditedAtModal({
return (
<div id="edit-history" class="sheet">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
{/* <button type="button" class="close-button plain large" onClick={onClose}>
<Icon icon="x" alt="Close" />
</button> */}
<h2>Edit History</h2>
{uiState === 'error' && <p>Failed to load history</p>}
{uiState === 'loading' && (
@ -1642,7 +1648,7 @@ function EditedAtModal({
}
const REACTIONS_LIMIT = 80;
function ReactionsModal({ statusID, instance }) {
function ReactionsModal({ statusID, instance, onClose }) {
const { masto } = api({ instance });
const [uiState, setUIState] = useState('default');
const [accounts, setAccounts] = useState([]);
@ -1718,6 +1724,11 @@ function ReactionsModal({ statusID, instance }) {
return (
<div id="reactions-container" class="sheet">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<h2>Boosted/Favourited by</h2>
</header>
@ -2074,10 +2085,17 @@ function FilteredStatus({ status, filterInfo, instance, containerProps = {} }) {
}}
>
<div id="filtered-status-peek" class="sheet">
<button
type="button"
class="sheet-close"
onClick={() => setShowPeek(false)}
>
<Icon icon="x" />
</button>
<header>
<b class="status-filtered-badge">Filtered</b> {filterTitleStr}
</header>
<main tabIndex="-1">
<p class="heading">
<b class="status-filtered-badge">Filtered</b> {filterTitleStr}
</p>
<Link
class="status-link"
to={`/${instance}/s/${status.id}`}

View file

@ -47,6 +47,10 @@
--loader-color: #1c1e2199;
--comment-line-color: #e5e5e5;
--drop-shadow-color: rgba(0, 0, 0, 0.15);
--close-button-bg-color: rgba(0, 0, 0, 0.1);
--close-button-bg-active-color: rgba(0, 0, 0, 0.2);
--close-button-color: rgba(0, 0, 0, 0.5);
--close-button-hover-color: rgba(0, 0, 0, 1);
--timing-function: cubic-bezier(0.3, 0.5, 0, 1);
}
@ -81,6 +85,10 @@
--loader-color: #f0f2f599;
--comment-line-color: #565656;
--drop-shadow-color: rgba(0, 0, 0, 0.5);
--close-button-bg-color: rgba(255, 255, 255, 0.2);
--close-button-bg-active-color: rgba(255, 255, 255, 0.15);
--close-button-color: rgba(255, 255, 255, 0.5);
--close-button-hover-color: rgba(255, 255, 255, 1);
}
}

View file

@ -23,6 +23,11 @@ function Accounts({ onClose }) {
return (
<div id="settings-container" class="sheet" tabIndex="-1">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header class="header-grid">
<h2>Accounts</h2>
</header>

View file

@ -166,7 +166,10 @@ function List(props) {
}
}}
>
<ListManageMembers listID={id} />
<ListManageMembers
listID={id}
onClose={() => setShowManageMembersModal(false)}
/>
</Modal>
)}
</>
@ -174,7 +177,7 @@ function List(props) {
}
const MEMBERS_LIMIT = 40;
function ListManageMembers({ listID }) {
function ListManageMembers({ listID, onClose }) {
// Show list of members with [Remove] button
// API only returns 40 members at a time, so this need to be paginated with infinite scroll
// Show [Add] button after removing a member
@ -220,6 +223,11 @@ function ListManageMembers({ listID }) {
return (
<div class="sheet" id="list-manage-members-container">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<h2>Manage members</h2>
</header>

View file

@ -4,6 +4,7 @@ import { useRef } from 'preact/hooks';
import { useSnapshot } from 'valtio';
import logo from '../assets/logo.svg';
import Icon from '../components/icon';
import RelativeTime from '../components/relative-time';
import targetLanguages from '../data/lingva-target-languages';
import getTranslateTargetLanguage from '../utils/get-translate-target-language';
@ -26,6 +27,11 @@ function Settings({ onClose }) {
return (
<div id="settings-container" class="sheet" tabIndex="-1">
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" />
</button>
)}
<header>
<h2>Settings</h2>
</header>