Skip to content

Conversation

@chaimann
Copy link
Contributor

@chaimann chaimann commented Mar 13, 2025

Summary

Adds a new select component in "ui/forms/select", using Tom Select under the hood.
Tom Select integration done with a web component, extending an HTMLSelectElement.
Reused styles from "ui/dropdown" for options dropdown, and from "ui/badge" for multiple options selected.
Other changes:

  • moved custom validity logic from "ui/forms/input/component.js" to its own controller;
  • updated "ui/forms/field" to conditionally show error message depending on the input validity state

Demo:
Component overview

Screen.Recording.2025-03-14.at.19.05.06.mov

Address component using new select

Screen.Recording.2025-03-14.at.19.08.52.mov

Checklist

Check out our PR guidelines for more details.

The following are mandatory for all PRs:

@chaimann chaimann force-pushed the admin-ui-select-component branch 3 times, most recently from f41962e to a4f6329 Compare March 14, 2025 14:24
@codecov
Copy link

codecov bot commented Mar 14, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 88.78%. Comparing base (7901f79) to head (252788d).
Report is 13 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6190      +/-   ##
==========================================
+ Coverage   88.72%   88.78%   +0.06%     
==========================================
  Files         838      839       +1     
  Lines       18193    18215      +22     
==========================================
+ Hits        16142    16173      +31     
+ Misses       2051     2042       -9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chaimann chaimann marked this pull request as ready for review March 14, 2025 18:12
@chaimann chaimann requested a review from a team as a code owner March 14, 2025 18:12
Copy link
Member

@tvdeyen tvdeyen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. I like us to include third party libraries like that. But I would like us to get rid of Stimulus as well in the select component. Can you try to extract the validation logic into a reusable es module?


pin "tom-select", to: "https://ga.jspm.io/npm:[email protected]/dist/esm/tom-select.complete.js"
pin "@orchidjs/sifter", to: "https://ga.jspm.io/npm:@orchidjs/[email protected]/dist/esm/sifter.js"
pin "@orchidjs/unicode-variants", to: "https://ga.jspm.io/npm:@orchidjs/[email protected]/dist/esm/index.js"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

urgh. just realized that we use CDNs for third party libraries. That is something we want to address in the future and download them instead. This is a performance nightmare and a potential GDPR violation.

@chaimann
Copy link
Contributor Author

@tvdeyen how about something like this? 6a6f256

@chaimann chaimann requested a review from tvdeyen March 20, 2025 17:36
Copy link
Member

@tvdeyen tvdeyen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice. Works great. We need to add support for Safari and I have a weird behaviour with single selects.

After selecting a value there still is a carret

CleanShot 2025-03-21 at 08 12 33@2x

And I can type ahead

CleanShot 2025-03-21 at 08 12 18@2x

Not sure if this is a expected behaviour for tomselect and there are valid reasons (a11y) for that, but still it is very uncommon. Maybe this can be disabled?

@chaimann
Copy link
Contributor Author

thanks @tvdeyen! re: single select caret, it's indeed a default Tomselect behaviour and I agree it does not feel right.

A workaround for that could be using a built-in plugin for search input being placed inside a dropdown for single selects:
image

We could customize it further, e.g. have search input only when there are more than 10 options in the dropdown (really does not make sense to have it for 2-3 options, only taking away the space).

And for multiple selects I'd still keep the search as it is now, it feels natural.

Let me know what you think!

@chaimann chaimann marked this pull request as draft March 31, 2025 14:13
@chaimann chaimann force-pushed the admin-ui-select-component branch 2 times, most recently from 848a8b0 to 1c43103 Compare April 1, 2025 11:37
@chaimann chaimann marked this pull request as ready for review April 1, 2025 12:01
@chaimann chaimann requested a review from tvdeyen April 1, 2025 12:01
@chaimann
Copy link
Contributor Author

chaimann commented Apr 1, 2025

@tvdeyen I ended up downloading the shim and continue using "is" attribute. The caret and type ahead in single selects is also fixed in a way that the input will become non-visible to the user, but if they try to type the options will still be filtered (kind of how the common select elements work)

Copy link
Member

@tvdeyen tvdeyen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great. The only thing is that a long result list in a Dialog now causes scrollbars.

CleanShot 2025-04-01 at 15 50 37

This is due to the fact that the dialog container has a overflow-auto class. Maybe we just remove this?

@chaimann
Copy link
Contributor Author

chaimann commented Apr 1, 2025

@tvdeyen oh yeah! i thought i added it but apparently it's in another PR I've been working on. will fix!

@chaimann
Copy link
Contributor Author

chaimann commented Apr 4, 2025

hi @tvdeyen, so it appeared that removing overflow-auto allowed the options dropdown to overflow the modal, but it actually disables the scrolling within the dialog if content does not fit max modal height. so instead i had to tweak our web component to account for that, it's not ideal to my taste, but it works correctly now

@chaimann chaimann requested a review from tvdeyen April 4, 2025 10:51
@tvdeyen
Copy link
Member

tvdeyen commented Apr 4, 2025

hi @tvdeyen, so it appeared that removing overflow-auto allowed the options dropdown to overflow the modal, but it actually disables the scrolling within the dialog if content does not fit max modal height. so instead i had to tweak our web component to account for that, it's not ideal to my taste, but it works correctly now

I feared that that will be the problem and I don't like that solution either. It will fall apart very fast (selects on the bottom of the screen need to be aligned to the bottom of the container. etc. pp.) This can be very cumbersome to maintain.

If there is no simpler solution (or plugin) I think we should live with that fact. That's due to the fact that we use modals now. I like modals, but they come with their own bag of problems.

We can also decide to not use a modal in that example (adding store credit)

@chaimann
Copy link
Contributor Author

chaimann commented Apr 6, 2025

@tvdeyen agreed, but can you please clarify what you mean by:

It will fall apart very fast (selects on the bottom of the screen need to be aligned to the bottom of the container

The simplest I can do is to remove overflow-auto from inner container, so that instead of this
Screenshot 2025-04-06 at 11 38 27
we will have this
Screenshot 2025-04-06 at 11 38 44
i.e. it will still cut off but at least not at the footer edge but at the modal edge. The modal scroll will still be preserved

@chaimann chaimann force-pushed the admin-ui-select-component branch from d28ab12 to c3f7c7c Compare April 6, 2025 20:12
@chaimann
Copy link
Contributor Author

@tvdeyen could you please have a look when you have time, I have a couple of PRs dependent on this one, would be very helpful to move this forward 🙏

@tvdeyen
Copy link
Member

tvdeyen commented Apr 10, 2025

@chaimann on it. Still busy with #6203 to get our test suite green and more stable again.

@tvdeyen
Copy link
Member

tvdeyen commented Apr 10, 2025

@chaimann #6203 has been merged, can you rebase please?

This allows to reuse it in the new select component.
Changes value name to be more reflective of what it stores.
chaimann added 10 commits April 10, 2025 12:09
Changed "Store Credit ..." to "Store credit ..." to match the
lowercase second-word style used in other places.
Also removes all logic regarding rendering a select field from
"ui/forms/input" component as not relevant.
Adds a test helper `tomselect` for feature tests.
Uses tailwind's `peer-invalid` state modifier to conditionally
show/hide error message.
Due to Safari not supporting customized builtins (is=""
attribute) (https://bugs.webkit.org/show_bug.cgi?id=182671)
use a polyfill to provide this functionality in Safari.
This change brings a behaviour similar to the one
that common HTML selects have, on top of some of
TomSelect niceties.

By default, TomSelect would include a search input
in single select mode, even when there is an option
selected, which is uncommon. So instead, we keep
search box visible only when there is nothing
selected. As soon as user selects an option, select
box gains "opacity-0" and therefore hides the
confusing search box effects (caret and ability to
type ahead). However, since a usual HTML select
responds to user's typing by highlighting matched
option (if any), we can replicate this logic because
 technically the input is not gone, and it still
 responds to user input. If user types while the
 select is focused, the options will be filtered and
  highlight will be applied (TomSelect defaults),
  however if filter search returns 0 options - we
  reset the search term to empty string and options
  displayed to show full list again.
@chaimann chaimann force-pushed the admin-ui-select-component branch from c3f7c7c to 252788d Compare April 10, 2025 10:10
@chaimann
Copy link
Contributor Author

@tvdeyen done!

Copy link
Member

@tvdeyen tvdeyen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works very well now! Thanks

@tvdeyen tvdeyen merged commit 63d01f1 into solidusio:main Apr 10, 2025
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants