Barista: Recherche: Combobox / Als Webkomponenten auswählen

Erstellt am 28. Juli 2020  ·  11Kommentare  ·  Quelle: dynatrace-oss/barista

Featureanfrage

Zusammenfassung

Wir müssen untersuchen, wie wir uns die API für die Auswahl-/Kombinationsbox in einer Webkomponentenwelt vorstellen.

Funktionsbeschreibung

Eine Auswahl- oder Kombinationsbox kann möglicherweise dieselbe Komponente sein, aber vielleicht möchten wir sie aufteilen. Das ist noch sehr unentschieden.

Vergleichen Sie verschiedene Komponentenbibliotheken / Designsystemansätze für eine Combobox / eine ausgewählte Komponente und erstellen Sie einen API-Vorschlag, der funktionieren würde.

Einige potenzielle Ressourcen:

Denken Sie daran, dass die Virtualisierung von Optionen ein Muss sein wird. Ist dies etwas, das wir auf der Webkomponentenschicht handhaben sollten oder ist dies etwas, das unsere Verbraucher auf einer potenziellen Framework-Schicht handhaben.
Testen und recherchieren Sie mit einer der oben genannten Webkomponenten in einem Angular-Setup mit virtuellem Scrollen für Optionen.
Versuchen Sie es auch mit der Webkomponente mit Reaction und Virtualisierung.

Wenn wir uns entscheiden, dies selbst zu handhaben, müssen wir einen Vorlagenmechanismus erstellen, der den Kontext für eine einmal erstellte Option festlegt.

Einige Ressourcen, um so etwas zu erreichen, könnten Microsoft-Graph-Toolkit sein

Das Ergebnis dieser Ausgabe sollte ein Überblick über unsere Optionen und Vor- und Nachteile sein, damit wir eine fundierte Entscheidung über das weitere Vorgehen treffen können.

Basic select mock

feature has-pr next

Hilfreichster Kommentar

Anforderungen

  • Virtuelles Scrollen: Nur ein Teil der Optionen sollte tatsächlich gerendert werden, um Performance-Probleme zu vermeiden
  • Benutzerdefinierte Vorlage: Der Benutzer muss in der Lage sein, eine Vorlage bereitzustellen, die zum Rendern der Optionen verwendet wird
  • Filtern: Der Benutzer muss in der Lage sein, Eingaben einzugeben, um die Liste der Elemente zu filtern; die Filterung sollte über eine vom Benutzer bereitgestellte Filterfunktion erfolgen
  • Scrollindikator: Es muss immer erkennbar sein, ob es mehr Optionen gibt --> solange es mehr Optionen gibt, sollte die Hälfte der anfangs letzten sichtbaren Option (oder maximal x Pixel) sichtbar sein, um eindeutig anzuzeigen, dass der Container scrollbar ist .

Anforderungen für die nächsten Schritte

  • Ladezustand: Ein Ladespinner soll im Overlay angezeigt werden, solange keine Artikel verfügbar sind ToDo Wo soll der Ladespinner angezeigt werden?
  • Mehrfachauswahl: Der Benutzer sollte in der Lage sein, mehrere Optionen auszuwählen
  • Optionsgruppen: Es sollte möglich sein, Optionen zu gruppieren

Barrierefreiheit

Wenn sie fokussiert ist, sollte sich die Combobox öffnen, wenn Sie die Taste Enter , ArrowUp oder ArrowDown drücken oder wenn der Benutzer beginnt, einen Filter in das Eingabefeld einzugeben.

Im geöffneten Zustand sollte der Benutzer die Taste ArrowUp / ArrowDown , um aus vorhandenen Optionen auszuwählen. Der Fokus für die Eingabe eines Filters sollte im Eingabefeld bleiben, Optionen sollten nicht tabellarisch sein. Der Auswahlstatus der Optionen sollte mit dem Attribut aria-selected werden.

Eine Auswahl sollte mit der Taste Enter übermittelt werden.

Durch Drücken der Taste Tab oder Escape sollte das Overlay geschlossen und das ausgewählte Element nicht geändert werden.

Beim Eintippen eines Filters und anschließendem Tabulator aus dem Eingabefeld sollte der Filter zurückgesetzt und das zuvor ausgewählte Element angezeigt werden.

Benutzerdefinierte Vorlagensyntax

Der Benutzer muss die öffnende und schließende Zeichenfolge der Vorlagenteile bereitstellen. Dies sollte entweder auf globaler oder komponentenbezogener Ebene möglich sein (muss noch entschieden werden).

Standardmäßig sind {{ und }} .

API-Vorschlag

_WIP_

Die ComboBox sollte in die Hauptkomponente FluidComboBox , eine FluidComboBoxOptionsList Komponente und eine FluidComboBoxOption Komponente aufgeteilt werden.

FluidComboBox

Enthält ein FluidComboBoxOptionsList , das wiederum FluidComboBoxOption s enthält.
Behandelt das Öffnen und Schließen des Overlays und die Positionierung des Overlays.
Akzeptiert eine Vorlage als untergeordnetes Element, das die Basis HTMLElement s akzeptiert.

Beim Bereitstellen einer Vorlage muss die öffnende und schließende Zeichenfolge, die für Vorlagenbindungen verwendet wird, festgelegt werden.

Eingänge

| Name | Geplant für | Typ | Standard | Beschreibung |
| -------------- | ------------ | -------- | -------- | -------------------------------------------------- ------------------------------------------ |
| Optionen | MVP | Array | [] | Array von Optionen zur Anzeige in FluidComboBoxOptionsList |
| filterFn | MVP | (option: T) => boolean | null | Funktion zum Filtern von Optionen |
| renderOptionFn | MVP | (option: T) => string | null | Funktion zum Rendern von Optionen im Autovervollständigungsfenster |
| Platzhalter | MVP | Zeichenfolge | '' | Platzhalter, der im Eingabefeld angezeigt wird, wenn keine Option ausgewählt ist |
| deaktiviert | MVP | boolesch | falsch | Boolean, um zu bestimmen, ob die Combobox deaktiviert ist |
| Laden | MVP | boolesch | falsch | Boolescher Wert, um zu bestimmen, ob der Ladeindikator angezeigt wird |
| ausgewählt | MVP | beliebig | null | Element zur Vorauswahl |
| Mehrfachauswahl | v2 | boolesch | falsch | Boolean, um zu bestimmen, ob mehr als eine Option gleichzeitig ausgewählt werden kann |

Ausgänge

| Name | Geplant für | Typ | Beschreibung |
| ---------------- | ------------ | --------------------------------- | -------------------------------------------------- ---- |
| ändern | MVP | FluidComboBoxChangeEvent | Ereignis wird ausgelöst, wenn sich der Wert ändert |
| Filterwechsel | MVP | FluidComboBoxFilterChangeEvent | Ereignis wird ausgelöst, wenn der Benutzer einen Wert zum Filtern eingibt |
| Auswahl-Änderung | MVP | FluidComboBoxSelectionChangeEvent | Ereignis wird ausgelöst, wenn sich die ausgewählte Option ändert |

FluidLoadingSpinner

Als Voraussetzung für die FluidComboBox müssen wir zunächst eine wiederverwendbare Ladespinner-Komponente implementieren.
ToDo Fragen Sie UX nach L&F des neuen Ladespinners (oder ob das alte Design wiederverwendet werden kann).

FluidVirtualScroller

Als Voraussetzung für die FluidComboBox müssen wir eine wiederverwendbare Komponente implementieren, die virtuelles Scrollen implementiert
um die Combobox mit einer großen Anzahl von Artikeln nutzen zu können.

Siehe auch:
https://github.com/WICG/virtual-scroller/blob/master/README.md
https://www.sitepen.com/blog/next-generation-virtual-scrolling/
https://dev.to/adamklein/build-your-own-virtual-scroll-part-i-11ib
https://blog.logrocket.com/virtual-scrolling-core-principles-and-basic-implementation-in-react/

FluidPopover

Als Voraussetzung für die FluidComboBox müssen wir eine wiederverwendbare Popover-Komponente implementieren, die platziert werden kann
perfekt unter dem Eingabeelement der Combobox.

Diese Bibliothek sollte zum Implementieren dieser Komponente verwendet werden:
https://popper.js.org/docs/v2/

Alle 11 Kommentare

Synchronisiere mit @heartdisease über API-Ideen für die Combobox. Er verbessert unsere aktuelle experimentelle Version für Angular

Ich habe das Microsoft-Graph-Toolkit TemplateHelper getestet, um die Combobox-Elemente mit einem bestimmten Kontext und einer in einem Slot bereitgestellten
Ich habe den Test in dieses Repo hochgeladen

Wir sollten also gut sein, die Liste der Elemente und (optional) eine Vorlage an die Combobox zu übergeben und die Virtualisierung "nur" hinzuzufügen, bevor die Elemente tatsächlich rendern, um nur x Elemente zu rendern, abhängig von der Scroll-Position und der Höhe des Overlay-Container.

Derzeit akzeptiert die Methode TemplateHelper.renderTemplate() ein HTMLElement als Root-Knoten, eine Vorlage und einen Kontext (und optional einen zusätzlichen Kontext). Es erstellt alle Knoten gemäß der angegebenen Vorlage und hängt sie an den Wurzelknoten an.
Es ist möglicherweise besser, dieses Verhalten zu ändern und die Methode nur ein Template und einen Kontext akzeptieren zu lassen und das kompilierte Template zurückzugeben, um dann den zurückgegebenen HTML-Code direkt im lit-template in der Komponente ausgeben zu können.
Was denkst du?

Anforderungen

  • Virtuelles Scrollen: Nur ein Teil der Optionen sollte tatsächlich gerendert werden, um Performance-Probleme zu vermeiden
  • Benutzerdefinierte Vorlage: Der Benutzer muss in der Lage sein, eine Vorlage bereitzustellen, die zum Rendern der Optionen verwendet wird
  • Filtern: Der Benutzer muss in der Lage sein, Eingaben einzugeben, um die Liste der Elemente zu filtern; die Filterung sollte über eine vom Benutzer bereitgestellte Filterfunktion erfolgen
  • Scrollindikator: Es muss immer erkennbar sein, ob es mehr Optionen gibt --> solange es mehr Optionen gibt, sollte die Hälfte der anfangs letzten sichtbaren Option (oder maximal x Pixel) sichtbar sein, um eindeutig anzuzeigen, dass der Container scrollbar ist .

Anforderungen für die nächsten Schritte

  • Ladezustand: Ein Ladespinner soll im Overlay angezeigt werden, solange keine Artikel verfügbar sind ToDo Wo soll der Ladespinner angezeigt werden?
  • Mehrfachauswahl: Der Benutzer sollte in der Lage sein, mehrere Optionen auszuwählen
  • Optionsgruppen: Es sollte möglich sein, Optionen zu gruppieren

Barrierefreiheit

Wenn sie fokussiert ist, sollte sich die Combobox öffnen, wenn Sie die Taste Enter , ArrowUp oder ArrowDown drücken oder wenn der Benutzer beginnt, einen Filter in das Eingabefeld einzugeben.

Im geöffneten Zustand sollte der Benutzer die Taste ArrowUp / ArrowDown , um aus vorhandenen Optionen auszuwählen. Der Fokus für die Eingabe eines Filters sollte im Eingabefeld bleiben, Optionen sollten nicht tabellarisch sein. Der Auswahlstatus der Optionen sollte mit dem Attribut aria-selected werden.

Eine Auswahl sollte mit der Taste Enter übermittelt werden.

Durch Drücken der Taste Tab oder Escape sollte das Overlay geschlossen und das ausgewählte Element nicht geändert werden.

Beim Eintippen eines Filters und anschließendem Tabulator aus dem Eingabefeld sollte der Filter zurückgesetzt und das zuvor ausgewählte Element angezeigt werden.

Benutzerdefinierte Vorlagensyntax

Der Benutzer muss die öffnende und schließende Zeichenfolge der Vorlagenteile bereitstellen. Dies sollte entweder auf globaler oder komponentenbezogener Ebene möglich sein (muss noch entschieden werden).

Standardmäßig sind {{ und }} .

API-Vorschlag

_WIP_

Die ComboBox sollte in die Hauptkomponente FluidComboBox , eine FluidComboBoxOptionsList Komponente und eine FluidComboBoxOption Komponente aufgeteilt werden.

FluidComboBox

Enthält ein FluidComboBoxOptionsList , das wiederum FluidComboBoxOption s enthält.
Behandelt das Öffnen und Schließen des Overlays und die Positionierung des Overlays.
Akzeptiert eine Vorlage als untergeordnetes Element, das die Basis HTMLElement s akzeptiert.

Beim Bereitstellen einer Vorlage muss die öffnende und schließende Zeichenfolge, die für Vorlagenbindungen verwendet wird, festgelegt werden.

Eingänge

| Name | Geplant für | Typ | Standard | Beschreibung |
| -------------- | ------------ | -------- | -------- | -------------------------------------------------- ------------------------------------------ |
| Optionen | MVP | Array | [] | Array von Optionen zur Anzeige in FluidComboBoxOptionsList |
| filterFn | MVP | (option: T) => boolean | null | Funktion zum Filtern von Optionen |
| renderOptionFn | MVP | (option: T) => string | null | Funktion zum Rendern von Optionen im Autovervollständigungsfenster |
| Platzhalter | MVP | Zeichenfolge | '' | Platzhalter, der im Eingabefeld angezeigt wird, wenn keine Option ausgewählt ist |
| deaktiviert | MVP | boolesch | falsch | Boolean, um zu bestimmen, ob die Combobox deaktiviert ist |
| Laden | MVP | boolesch | falsch | Boolescher Wert, um zu bestimmen, ob der Ladeindikator angezeigt wird |
| ausgewählt | MVP | beliebig | null | Element zur Vorauswahl |
| Mehrfachauswahl | v2 | boolesch | falsch | Boolean, um zu bestimmen, ob mehr als eine Option gleichzeitig ausgewählt werden kann |

Ausgänge

| Name | Geplant für | Typ | Beschreibung |
| ---------------- | ------------ | --------------------------------- | -------------------------------------------------- ---- |
| ändern | MVP | FluidComboBoxChangeEvent | Ereignis wird ausgelöst, wenn sich der Wert ändert |
| Filterwechsel | MVP | FluidComboBoxFilterChangeEvent | Ereignis wird ausgelöst, wenn der Benutzer einen Wert zum Filtern eingibt |
| Auswahl-Änderung | MVP | FluidComboBoxSelectionChangeEvent | Ereignis wird ausgelöst, wenn sich die ausgewählte Option ändert |

FluidLoadingSpinner

Als Voraussetzung für die FluidComboBox müssen wir zunächst eine wiederverwendbare Ladespinner-Komponente implementieren.
ToDo Fragen Sie UX nach L&F des neuen Ladespinners (oder ob das alte Design wiederverwendet werden kann).

FluidVirtualScroller

Als Voraussetzung für die FluidComboBox müssen wir eine wiederverwendbare Komponente implementieren, die virtuelles Scrollen implementiert
um die Combobox mit einer großen Anzahl von Artikeln nutzen zu können.

Siehe auch:
https://github.com/WICG/virtual-scroller/blob/master/README.md
https://www.sitepen.com/blog/next-generation-virtual-scrolling/
https://dev.to/adamklein/build-your-own-virtual-scroll-part-i-11ib
https://blog.logrocket.com/virtual-scrolling-core-principles-and-basic-implementation-in-react/

FluidPopover

Als Voraussetzung für die FluidComboBox müssen wir eine wiederverwendbare Popover-Komponente implementieren, die platziert werden kann
perfekt unter dem Eingabeelement der Combobox.

Diese Bibliothek sollte zum Implementieren dieser Komponente verwendet werden:
https://popper.js.org/docs/v2/

Bezüglich der Vorlagen habe ich einige Bedenken, da es für den Entwickler nicht sehr flexibel und umfangreich ist, nur Textersetzungen zu haben. Denken Sie an Texttransformationen über Funktionen oder einfache Bedingungen wie eine, wenn dies nicht möglich wäre, aber meiner Meinung nach erforderlich wäre.

Mein Ansatz wäre, Funktionen zu schreiben, die einen HTML-String zurückgeben, der in ein DocumentFragment eingefügt werden kann, das dann angehängt werden kann.

Mit Schreibfunktionen würden Sie die volle Flexibilität beim Transformieren von Bedingungen gewinnen.
Um eine einfache Möglichkeit dafür bereitzustellen, könnten wir etwas Ähnliches wie JSX htm nutzen , das in einen String gerendert werden kann, sodass kein Kompilieren erforderlich ist. Es hat auch einen sehr geringen Platzbedarf, von dem wir sprechen ~ 700 Bytes.

es könnte dann irgendwie verwendet werden wie:

<script type="text/template">
html`
  <span>${text}</span>
   {count > 0
     <span>occurrences ${count}</span>
   }
   </div>
`;
</script>

import { render } from "preact-render-to-string";

const template = document.createElement('template');
template.innerHTML = render(option); // option is the script that can be passed via slot or input

const fragment = temp.content;

alternativ könnten wir getaggte Vorlagen verwenden https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates.

Dies wäre vielleicht die minimale Lösung.

Ich habe einige Tests durchgeführt und Angular entfernt leider alle Skript-Tags aus der Vorlage. Nur meine 2 Cent für das Deklarieren des Skripts in der Vorlage.

Vielleicht gehen wir mit einem funktionsorientierten Ansatz vor, damit die Combobox eine Eingabe hat, in der Sie eine Funktion zum Rendern der Vorlage bereitstellen können.

Ist es möglich, eine Funktion auf LitElements als Eigenschaft bereitzustellen? Denn dann würde ich das Rendering an den Consumer weitergeben wo er alle Flexibilitäten von Javascript in dieser Funktion hat. Die Funktion hat deklarierte Parameter (die Eingabe für das Template) und muss einen String zurückgeben.

Eine Standardimplementierung könnte wie folgt erfolgen:

_defaultTemplate<T>(display: string, value: T): string {
   return `<option>${display}</option>`
}

Wie in #1513 besprochen, müssen wir das Popover richtig handhaben.

Ich bin mir nicht sicher, ob dies der richtige Ort ist, um die Eingabe zu diskutieren, die Teil der Combobox-Komponente ist - Aber da die Eingabe mit dem Fokus wächst, denke ich, dass es sinnvoll ist, die Box der Eingabekomponente zu erweitern, um den Raum einzunehmen, den der größte Zustand einnimmt hat.

Derzeit wächst die Eingabe um 16px in der Breite, sobald sie fokussiert ist. Daher würde ich vorschlagen, die Beschriftung + die Eingabe um eine Auffüllung von 8 zu verschieben. Dies würde bedeuten, dass, wenn sich mehrere Steuerelemente (Eingabe, Auswahl, ...) in einem vertikalen Formularlayout befinden, alle Beschriftungen aller Steuerelemente sein müssen ausgerichtet. Vielleicht ist ein Formularsteuerelement sinnvoll, das dafür sorgt, dass die Abstände für Beschriftungen + Eingaben vereinheitlicht werden.

Ich möchte den Vorschlag ändern, indem ich eine neue Eingabe zum Rendern der Anzeigezeichenfolge für die aktuelle Auswahloption hinzufüge:

Eingänge

| Name | Geplant für | Typ | Standard | Beschreibung |
| -------------- | ------------ | -------- | -------- | -------------------------------------------------- ------------------------------------------ |
| displayNameFn | MVP | (option: T) => string | (Option) => `${Option}` | Funktion, die einen Anzeigestring (kein HTML erlaubt) für eine gegebene Option zurückgibt. |

Dies wäre auch eine einfache Lösung für dieses Problem: #1527

Etwas Kleines, das ich für wichtig halte: Die aktuelle DtCombobox verwendet value einer Option als standardmäßigen Anzeigetext für die "ausgewählte Option". Ich denke, es ist viel sinnvoller, die Option textContent .
1) textContent ist immer ein UI-freundlicher Wert ( value ist nur manchmal ein UI-freundlicher Wert)
2) Die Verwendung von textContent ist das, was die Standard- select tun

Wir werden dieses Thema schließen, da Webkomponenten nicht die Art sind, wie wir Komponenten in Zukunft erstellen möchten. Dies hängt mit einer Verschiebung der Prioritäten im Team zusammen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen