diff --git a/src/ui/web/css/form.css b/src/ui/web/css/form.css
index 741d2bfd..e9771611 100644
--- a/src/ui/web/css/form.css
+++ b/src/ui/web/css/form.css
@@ -20,3 +20,13 @@ limitations under the License.
width: 100%;
box-sizing: border-box;
}
+
+.FilterField {
+ display: flex;
+}
+
+.FilterField input {
+ display: block;
+ flex: 1;
+ min-width: 0;
+}
diff --git a/src/ui/web/css/left-panel.css b/src/ui/web/css/left-panel.css
index 5a5240a2..5a7ae221 100644
--- a/src/ui/web/css/left-panel.css
+++ b/src/ui/web/css/left-panel.css
@@ -19,15 +19,12 @@ limitations under the License.
flex-direction: column;
}
-.LeftPanel .filter {
+.LeftPanel .utilities {
display: flex;
}
-.LeftPanel .filter input {
- display: block;
+.LeftPanel .utilities .FilterField {
flex: 1;
- box-sizing: border-box;
- min-width: 0;
}
.LeftPanel ul {
diff --git a/src/ui/web/css/themes/element/icons/clear.svg b/src/ui/web/css/themes/element/icons/clear.svg
new file mode 100644
index 00000000..9227cf4d
--- /dev/null
+++ b/src/ui/web/css/themes/element/icons/clear.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/ui/web/css/themes/element/icons/disable-grid.svg b/src/ui/web/css/themes/element/icons/disable-grid.svg
new file mode 100644
index 00000000..1be4ae6a
--- /dev/null
+++ b/src/ui/web/css/themes/element/icons/disable-grid.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/ui/web/css/themes/element/icons/enable-grid.svg b/src/ui/web/css/themes/element/icons/enable-grid.svg
new file mode 100644
index 00000000..776fec35
--- /dev/null
+++ b/src/ui/web/css/themes/element/icons/enable-grid.svg
@@ -0,0 +1,6 @@
+
diff --git a/src/ui/web/css/themes/element/theme.css b/src/ui/web/css/themes/element/theme.css
index 56c9fb29..234b63ef 100644
--- a/src/ui/web/css/themes/element/theme.css
+++ b/src/ui/web/css/themes/element/theme.css
@@ -117,6 +117,50 @@ button.styled {
font-weight: 500;
}
+.FilterField {
+ background-color: #e1e3e6;
+ border-radius: 16px;
+ height: 32px;
+ align-items: center;
+ padding: 0 8px;
+ box-sizing: border-box;
+}
+
+.FilterField :not(:first-child) {
+ margin-left: 8px;
+}
+
+.FilterField:focus-within {
+ border: 1px #e1e3e6 solid;
+ background-color: white;
+}
+
+/*.FilterField:not(:focus-within) button {
+ display: none;
+}*/
+
+.FilterField input {
+ font-family: "Inter";
+ font-size: 1.3rem;
+ font-weight: 500;
+ line-height: 1.573rem;
+ outline: none;
+ border: none;
+ background-color: transparent;
+ height: 100%;
+}
+
+.FilterField button {
+ width: 16px;
+ height: 16px;
+ background-position: center;
+ background-color: #e1e3e6;
+ background-repeat: no-repeat;
+ background-image: url('icons/clear.svg');
+ border: none;
+ border-radius: 100%;
+}
+
.PreSessionScreen {
padding: 30px;
}
diff --git a/src/ui/web/session/leftpanel/LeftPanelView.js b/src/ui/web/session/leftpanel/LeftPanelView.js
index b993531d..3eeaaada 100644
--- a/src/ui/web/session/leftpanel/LeftPanelView.js
+++ b/src/ui/web/session/leftpanel/LeftPanelView.js
@@ -18,34 +18,67 @@ import {ListView} from "../../general/ListView.js";
import {TemplateView} from "../../general/TemplateView.js";
import {RoomTileView} from "./RoomTileView.js";
-export class LeftPanelView extends TemplateView {
- render(t, vm) {
+class FilterField extends TemplateView {
+ render(t, options) {
+ const clear = () => {
+ filterInput.value = "";
+ filterInput.blur();
+ clearButton.blur();
+ options.clear();
+ };
const filterInput = t.input({
type: "text",
- placeholder: vm.i18n`Filter rooms…`,
- "aria-label": vm.i18n`Filter rooms by name`,
- autocomplete: true,
- name: "room-filter",
- onInput: event => vm.setFilter(event.target.value),
+ placeholder: options?.label,
+ "aria-label": options?.label,
+ autocomplete: options?.autocomplete,
+ name: options?.name,
+ onInput: event => options.set(event.target.value),
onKeydown: event => {
if (event.key === "Escape" || event.key === "Esc") {
- filterInput.value = "";
- vm.clearFilter();
+ clear();
}
- }
+ },
+ onFocus: () => filterInput.select()
});
+ const clearButton = t.button({
+ onClick: clear,
+ title: options.i18n`Clear`,
+ "aria-label": options.i18n`Clear`
+ });
+ return t.div({className: "FilterField"}, [filterInput, clearButton]);
+ }
+}
+
+export class LeftPanelView extends TemplateView {
+ render(t, vm) {
+ const gridButtonLabel = vm => {
+ return vm.gridEnabled ?
+ vm.i18n`Show single room` :
+ vm.i18n`Enable grid layout`;
+ };
+ const utilitiesRow = t.div({className: "utilities"}, [
+ t.view(new FilterField({
+ i18n: vm.i18n,
+ label: vm.i18n`Filter rooms…`,
+ name: "room-filter",
+ autocomplete: true,
+ set: query => vm.setFilter(query),
+ clear: () => vm.clearFilter()
+ })),
+ t.button({
+ onClick: () => vm.toggleGrid(),
+ className: {
+ utility: true,
+ grid: true,
+ on: vm => vm.gridEnabled
+ },
+ title: gridButtonLabel,
+ "aria-label": gridButtonLabel
+ })
+ ]);
+
return t.div({className: "LeftPanel"}, [
- t.div({className: "filter"}, [
- filterInput,
- t.button({onClick: () => {
- filterInput.value = "";
- vm.clearFilter();
- }}, vm.i18n`Clear`),
- t.button({
- onClick: () => vm.toggleGrid(),
- className: "grid"
- }, vm => vm.gridEnabled ? "Single" : "Grid")
- ]),
+ utilitiesRow,
t.view(new ListView(
{
className: "RoomList",