Skip to content

Commit bc6bfab

Browse files
authored
Add delete all sites button (darkreader#9829)
- Add a new button to the sitelist page, which will clear the site list.
1 parent eb23317 commit bc6bfab

8 files changed

Lines changed: 129 additions & 0 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import {m} from 'malevic';
2+
import IconButton from '../icon-button';
3+
4+
interface DeleteAllButtonProps {
5+
onClick: () => void;
6+
}
7+
8+
export default function DeleteAllButton(props: DeleteAllButtonProps, ...content: Malevic.Child[]) {
9+
return (
10+
<IconButton
11+
class="delete-all-button"
12+
onclick={props.onClick}
13+
>
14+
<span class="delete-all-button__content">
15+
<span class="delete-all-button-icon"></span>
16+
{...content}
17+
</span>
18+
</IconButton>
19+
);
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@import "../../theme.less";
2+
3+
.delete-all-button-icon {
4+
background-image: @icon-delete;
5+
background-size: cover;
6+
display: inline-block;
7+
height: 1rem;
8+
width: 1rem;
9+
10+
&:hover {
11+
background-image: @icon-delete-hover;
12+
}
13+
}
14+
15+
.delete-all-icon-group {
16+
position: absolute;
17+
z-index: 1;
18+
left: -1em;
19+
top: -0.25em;
20+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {m} from 'malevic';
2+
import {mergeClass, omitAttrs} from '../utils';
3+
4+
export default function IconButton(props: Malevic.NodeAttrs, ...children: Malevic.Child[]) {
5+
const cls = mergeClass('icon-button', props.class);
6+
const attrs = omitAttrs(['class'], props);
7+
8+
return (
9+
<button class={cls} {...attrs}>
10+
<span class="button__wrapper">
11+
{...children}
12+
</span>
13+
</button>
14+
);
15+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@import "../../theme";
2+
3+
.icon-button {
4+
border: none;
5+
background: none;
6+
box-sizing: content-box;
7+
cursor: pointer;
8+
display: inline-block;
9+
height: @size-control-inner;
10+
line-height: @size-text-normal;
11+
min-width: @size-control-inner;
12+
outline: none;
13+
overflow: hidden;
14+
padding: 0;
15+
text-align: center;
16+
transition: background-color @time-slow;
17+
-moz-user-select: none;
18+
user-select: none;
19+
20+
&__wrapper {
21+
height: 100%;
22+
width: 100%;
23+
}
24+
}

src/ui/controls/style.less

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@
1818
@import "./color-dropdown/style";
1919
@import "./nav-button/style";
2020
@import "./reset-button/style";
21+
@import "./delete-all-button/style";
22+
@import "./icon-button/style";
23+

src/ui/icons.less

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@
1111
@icon-reset: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"><path fill="white" d="M4,1 v-1 l1.5,1.5 l-1.5,1.5 v-1 a2,2 0 1 0 2,2 h1 a3,3 0 1 1 -3,-3 z"/></svg>');
1212
@icon-right: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"><path fill="white" d="M2,1 h1.5 l3,3 l-3,3 h-1.5 l3,-3 z"/></svg>');
1313
@icon-settings: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16"><defs><path id="cog" d="M-1.25,-6.5 h2.5 l1,3 h-4.5 z" /></defs><g transform="translate(8 8)" fill="white"><path d="M0,-5 a5,5 0 0 1 0,10 a5,5 0 0 1 0,-10 z M0,-3 a3,3 0 0 0 0,6 a3,3 0 0 0 0,-6 z"></path><use xlink:href="%23cog" /><use xlink:href="%23cog" transform="rotate(60)" /><use xlink:href="%23cog" transform="rotate(120)" /><use xlink:href="%23cog" transform="rotate(180)" /><use xlink:href="%23cog" transform="rotate(240)" /><use xlink:href="%23cog" transform="rotate(300)" /></g></svg>');
14+
@icon-delete: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> <path fill="rgb(83, 161, 179)" d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"></path> <path fill="rgb(83, 161, 179)" fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"></path></svg>');
15+
@icon-delete-hover: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> <path fill="white" d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"></path> <path fill="white" fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"></path></svg>');
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {m} from 'malevic';
2+
import {getContext} from 'malevic/dom';
3+
import DeleteAllButton from '../../controls/delete-all-button';
4+
import {MessageBox} from '../../controls';
5+
import ControlGroup from '../control-group';
6+
import type {ViewProps} from '../types';
7+
8+
export default function RemoveAllButton(props: ViewProps) {
9+
const context = getContext();
10+
11+
function showDialog() {
12+
context.store.isDialogVisible = true;
13+
context.refresh();
14+
}
15+
16+
function hideDialog() {
17+
context.store.isDialogVisible = false;
18+
context.refresh();
19+
}
20+
21+
function reset() {
22+
context.store.isDialogVisible = false;
23+
props.actions.changeSettings({siteList: []});
24+
}
25+
26+
const dialog = context.store.isDialogVisible ? (
27+
<MessageBox
28+
caption="Are you sure you want to remove all your sites from the list? You cannot restore them later"
29+
onOK={reset}
30+
onCancel={hideDialog}
31+
/>
32+
) : null;
33+
34+
return (
35+
<ControlGroup class="delete-all-icon-group">
36+
<ControlGroup.Control>
37+
<DeleteAllButton onClick={showDialog}>
38+
{dialog}
39+
</DeleteAllButton>
40+
</ControlGroup.Control>
41+
</ControlGroup>
42+
);
43+
}

src/ui/popup/site-list-page/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {m} from 'malevic';
22
import type {ViewProps} from '../types';
33
import SiteList from './site-list';
44
import CheckButton from '../check-button';
5+
import RemoveAllButton from '../remove-all-sites-button/remove-site-list-button';
56
import {isFirefox} from '../../../utils/platform';
67

78
export default function SiteListPage(props: ViewProps) {
@@ -23,6 +24,7 @@ export default function SiteListPage(props: ViewProps) {
2324
return (
2425
<div class="site-list-page">
2526
<label class="site-list-page__label">{label}</label>
27+
{props.data.settings.siteList.length ? <RemoveAllButton {...props} /> : null}
2628
<SiteList
2729
siteList={props.data.settings.siteList}
2830
onChange={onSiteListChange}

0 commit comments

Comments
 (0)