Introduce Icon component to abstract icons
Recent change aosp/2470800 broke a couple of things where I relied on
variations of icons to be visually distinguishable (e.g. 'star' and
'star_outline'). Abstracting a component for the icon seems to be a
reasonable way to mitigate those problems in the future; this CL
introduces such component and uses it in query history.
Change-Id: I0c0d401c1274fa9596da7cc5dffcc9174b10fcdd
diff --git a/ui/src/assets/common.scss b/ui/src/assets/common.scss
index d621810..9e26d09 100644
--- a/ui/src/assets/common.scss
+++ b/ui/src/assets/common.scss
@@ -897,7 +897,7 @@
button {
margin: 0 0.5rem;
- i.material-icons {
+ i.material-icons, i.material-icons-filled {
font-size: 18px;
}
}
diff --git a/ui/src/frontend/query_history.ts b/ui/src/frontend/query_history.ts
index 35aa9bf..e2e503c 100644
--- a/ui/src/frontend/query_history.ts
+++ b/ui/src/frontend/query_history.ts
@@ -26,6 +26,7 @@
ValidatedType,
} from '../controller/validators';
import {assertTrue} from '../base/logging';
+import {Icon} from './widgets/icon';
const QUERY_HISTORY_KEY = 'queryHistory';
@@ -67,8 +68,7 @@
globals.rafScheduler.scheduleFullRedraw();
},
},
- m('i.material-icons',
- vnode.attrs.entry.starred ? 'star' : 'star_outline')),
+ m(Icon, {icon: 'star', filled: vnode.attrs.entry.starred})),
m('button',
{
onclick: () => {
@@ -76,7 +76,7 @@
{queryId: 'analyze-page-query', query}));
},
},
- m('i.material-icons', 'play_arrow')),
+ m(Icon, {icon: 'play_arrow'})),
m('button',
{
onclick: () => {
@@ -84,7 +84,7 @@
globals.rafScheduler.scheduleFullRedraw();
},
},
- m('i.material-icons', 'delete'))),
+ m(Icon, {icon: 'delete'}))),
m('pre', query));
}
}
diff --git a/ui/src/frontend/widgets/icon.ts b/ui/src/frontend/widgets/icon.ts
new file mode 100644
index 0000000..209db85
--- /dev/null
+++ b/ui/src/frontend/widgets/icon.ts
@@ -0,0 +1,28 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import * as m from 'mithril';
+
+export interface IconAttrs {
+ icon: string;
+ filled?: boolean;
+}
+
+export class Icon implements m.ClassComponent<IconAttrs> {
+ view(vnode: m.Vnode<IconAttrs>): m.Child {
+ return m(
+ vnode.attrs.filled ? 'i.material-icons-filled' : 'i.material-icons',
+ vnode.attrs.icon);
+ }
+}
diff --git a/ui/src/frontend/widgets_page.ts b/ui/src/frontend/widgets_page.ts
index 041e663..94930df 100644
--- a/ui/src/frontend/widgets_page.ts
+++ b/ui/src/frontend/widgets_page.ts
@@ -21,6 +21,7 @@
import {Button} from './widgets/button';
import {Checkbox} from './widgets/checkbox';
import {EmptyState} from './widgets/empty_state';
+import {Icon} from './widgets/icon';
import {Popup, PopupPosition} from './widgets/popup';
import {Portal} from './widgets/portal';
import {TextInput} from './widgets/text_input';
@@ -325,6 +326,10 @@
renderWidget: (opts) => m(ControlledPopup, opts),
initialOpts: {},
}),
- );
+ m('h2', 'Icon'),
+ m(WidgetShowcase, {
+ renderWidget: (opts) => m(Icon, {icon: 'star', ...opts}),
+ initialOpts: {filled: false},
+ }));
},
});