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",