Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(release-4.0.0) HDS-2069: Select final UI #1384

Closed
wants to merge 104 commits into from

Conversation

NikoHelle
Copy link
Contributor

@NikoHelle NikoHelle commented Oct 18, 2024

Description

238 changed files, but 200 are images 😄

Biggest changes:

  • useSelectStorage -hook + tests
  • "value"-prop + tests

Minor stuff:

  • merged, added and removed Stories
  • native element props goes to the container div
  • added util functions to process options and selections
  • fixed bug when labels are super long

Test changes:

  • Tonnes of e2e tests.
  • Removed Select from Loki.
  • e2e test util improvements

Missing:

  • changelog
  • docs
  • migration guide will be in one PR

Related Issue

Closes HDS-2069

How Has This Been Tested?

E2e, jest

Demos:

Links to demos are in the comments

Screenshots (if appropriate):

Add to changelog

  • changelog will be in docs PR

DataStorage is for storing given props like options, state, disabled, open

MetaDataStorage is for storing internal state and data, like clickedElement, element refs, ids.

Handlers are for updating storages and triggering changes.

When data changes, the component is usually re-rendered.

When metaData changes, re-rendering does not usually happen, but can.

When a ChangeEvent is triggered, the onChange-function is called. If the function returns true, the context is re-rendered.

onChange-function is memoized to force it to be a pure function and to avoid unnecessary renders.

data and metadata storages are also memoized, but given data and metaData props are memoization dependencies.

So changing data props between renders will create a new data storage. Same with metaData.

DataProvider wraps the DataContext and enables re-rendering.
The select button must show number of hidden elements.

This util can find the last visible one.
The option list should close on outside click.

Same feature has been used in other components, but no common hook has existed.
And a hook for using the DataProvider with Select data types.
Components trigger events that change the data. This is one common place for all events.
When an event is triggered, dataUpdater listens to them and changes Select component's data
The "onChange" function passed to the DataContext should also call an "onChange" function passed to the Select later on. This is added in another commit.

The "dataUpdater" should only update data, not handle the data returned from the "onChange". So changeHandler was added.

The "dataUpdater" should also return more info than a boolean, so the incoming "onChange" knows when selections changed.
The callback is called when selections change. Not on other changes.

In some cases, like with max number of selections, there is a need to edit selections. The onChange callback may return a set of options / groups which override current set of groups.

The callback is called with three arguments:
- currently selected options
- last selected option
- current SelectData
Also selected option is stored to the metadata
Select has a lot of texts. Some are "hidden" in aria-labels and some depend on current selections.

Texts are sometimes interpolated from a template and content.

Instead of passing 20+ texts as props, texts are passed now in one prop, "texts". It can be an object or a function.

If it is a function, it is stored to metadata and that function is called when a text is needed.

If it is an object, it is converted to an function returning data from that object or from default texts.  The function is stored to metadata

Actual texts are not ready yet with all translations, so currently there are only dummy texts.
These utils render the Select component, or parts of it, and return helper functions to find elements, update data and wait for re-renders after data updates.

Because Select relies on data, metaData and Context, it is not simple just to mock all of those.

This solution mocks/replaces the  "<Container>" component in the <Select> with the tested component.

Replacing one with another ensures data and metaData still work normally.

The util also sets all props and offers tools to update data and metaData on the fly.
Easy way to reset for example "error" or "assistive" after a selection change.
Renamed util functions to be clearer.
If user has made selections and the Select component is rendered via parent, selections could be lost.

Select memoizes props, but it cannot memoize too much or it will not update.

useSelectStorage is a proxy that memoizes props and selections for the Select and for the user.
Added data-test-ids to search info and improved test utils
Without it tests fail, when the func is called in a component
…ems() selector

Added a better comment about active-descendant

Removed open check from the activeDescendant element. It should be set/cleared also when input is hidden.
There test that all attributes are correct in all combinations.
Also adjusted icon color.
The focus rings were cut off because of overflow hidden
Hidden tags were counted wrong way
Selectors were independently in multiple places so created one to import where needed.
Added also an util to update selections easier
Take snapshot from all stories.

Removed !isMobile restriction to take all images.

StateSnapshot had wrong filename, it was too short.
SelectStorage won't accept them, because it handles options and updates internally and passing values would make it internals more complex.
Copy link

Preview found from hds-demo docs/preview_1384

Demos

Docs
Core Storybook
React Storybook

Copy link

Test Results

 1 files  20 suites   6m 26s ⏱️
28 tests 28 ✅ 0 💤 0 ❌
56 runs  56 ✅ 0 💤 0 ❌

Results for commit 325e081.

@NikoHelle
Copy link
Contributor Author

Needs new rebase

@NikoHelle NikoHelle closed this Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant