ember-a11y / ember-select-light Goto Github PK
View Code? Open in Web Editor NEWThis project forked from q2ebanking/ember-select-light
The simplest Ember <select> there is.
License: Other
This project forked from q2ebanking/ember-select-light
The simplest Ember <select> there is.
License: Other
This repo is a bit oldschool and still uses master
as its branch whereas now main
is the ideal default.
Should write an upgrade guide from 1.x for current users.
Describe the bug
CI is failing trying to build this for ember-canary and ember-beta, I think this means it's failing on 4.x.x in general.
To Reproduce
Steps to reproduce the behavior:
Run the full test suite and watch it fail.
Expected behavior
Should support EmberJS v4.x.x and pass all tests.
Screenshots
N/A
Desktop (please complete the following information):
N/A
Smartphone (please complete the following information):
N/A
Additional context
N/A
CI is already set up to run all test:
scripts, we should add in the standard: "test:ember-compatibility": "ember try:each"
to the package.json
scripts. Putting up a PR with these changes will run them against GitHub Actions automatically.
This was already enabled for a moment but I had to pull it due to some failures. Didn't want it to hold up the glimmer upgrades.
Not a standard feature request or bug report really, this is really something that would be very much a micro-tuning type of change, and I think it's something we should only consider doing if we happen to have a lot of spare time ๐ this is more of a braindump of some knowledge about the internals
Basically, the current solution for checking if an option is selected is a bit suboptimal. To be clear, it is definitely idiomatic, it's the way you would expect to do it:
{{#each @options as | optionValue |}}
<option value={{optionValue}} selected={{is-equal optionValue @value}}>
{{optionValue}}
</option>
{{/each}}
But the issue is, we are checking is-equal
inside each item in this loop. That means that whenever @value
changes, we need to re-iterate every option in the loop to check if it is selected again. I've been thinking about a way to prevent this at the VM level, but so far I haven't been able to come up with anything. The state is being used and consumed in each item, and for all it knows, each item could be selected (I guess in a multiple select, it actually could!)
This just seems a bit unfortunate. Iterating an array in JS is really really fast, but if you go through a few layers like we have to when rendering, it gets much slower.
I really don't have any ideas about how we could do this better necessarily, maybe we can't! I think wrapping the options in objects with a @tracked selected
property would actually be bad, because then we'd be creating and allocating more objects which would hurt initial render, and would increase overall memory usage.
One idea, which is definitely a bit out there, would be to use a modifier. This modifier could manually read the options and selected values synchronously and then update the <select>
's state accordingly. I really am unsure about this approach though, I'd definitely want to benchmark it to see if it actually works, and I'd want to think about whether or not it makes sense in general from a rendering perspective.
Anyways, it's possible the current solution is the optimal one, so I think for now it should stay the way it is. I'm just throwing this out there as something I've been thinking about ๐
Two tasks would be ideal to examine:
Something like this perhaps: https://github.com/nodejs/node/blob/master/CHANGELOG.md
Ideally something that lets dependabot resolve changes.
Is your feature request related to a problem? Please describe.
It's fairly common to want to be able to select an object or reference to an object from a select. For instance, you may be wanting to associate a relationship with an Ember Data model. Currently, this requires a lot of boilerplate with this component, because <option>
serializes the value passed to it as a string always. So, you would have to do something like:
class MyComponent extends Component {
options = [{
id: 1,
name: "turtle",
}, {
id: 2,
name: "mako",
}];
@tracked selected = this.options[0];
handleChange = (event) => {
let selectedId = event.target.selectedOptions[0].value;
this.selected = this.options.find(option => option.id === selectedId);
};
}
IMO this isn't as much of a performance worry because setting is not super common, but it's a lot to write for something that is pretty common in my day-to-day use cases.
Describe the solution you'd like
Ideally, it would be possible to get the selected value by reference some how. So you could do something like:
class MyComponent extends Component {
options = [{
id: 1,
name: "turtle",
}, {
id: 2,
name: "mako",
}];
@tracked selected = this.options[0];
handleChange = (event) => {
this.selected = event.target.selectedOptions[0].value;
};
}
Or ideally, combined with #30, it could become:
As far as I can tell, however, this would mean that the current ability to use <option>
directly wouldn't work any longer, because option values always get serialized to strings ๐ this is definitely annoying, it would mean that the API would have to pass a closure component like:
This would in my opinion be worth it though, because the ability to handle references is really important, and the common use case wouldn't require using this form (you would just pass in @options
instead).
Describe alternatives you've considered
We could possibly support both option
and a curried component, and option
could be used for string values:
I'm not sure about this API, whether it would be more or less confusing. Also, I think it would complicate the internal logic a lot.
I'll keep thinking about if there is a way to somehow pass a reference directly into an attribute on an <option>
.
Not sure we use it or it's even relevant in modern Ember.
The original repo this is forked from has a copyright from Q2 (2016) of the Apache 2.0 License. We need to interpret this and determine if we can either:
Perhaps we discover in this investigation that the existing license makes this fork impossible. If that's the case we'll need to recreate this from scratch and lose any existing users (primarily just Q2 at this point).
Linting and tests should have to pass for Pull Requests to be allowed to merge.
I don't believe it's used in anything. Let's remove the lodash
dependency.
Thanks a lot for a nice lib. I'm currently in the process of switching from x-select to ember-select-light and I found something I would consider a bug.
It's not possible to have an option with a value that is just an empty string.
<SelectLight @value={{value}} @change={{action "myAction"}} @options={{selectOptions}} />
get selectOptions() {
return [{
label: 'Nothing',
value: ''
},{
label: 'Option 1',
value: '1'
}]
}
Point to https://emberjs.com/guidelines/ instead of using the original forked Q2 code of conduct.
I'll be taking this on, it's the bulk of the work but I wanted to log it in some way here. This code hasn't been touched in a while and it needs some upgrades.
Is your feature request related to a problem? Please describe.
When using <SelectLight>
, currently you must always handle the change
event yourself. This means that you must create a JavaScript event handler to update the value, like so:
class MyComponent extends Component {
@tracked selected = "turtle";
handleChange = (event) => {
this.selected = event.target.selectedOptions[0].value;
};
}
This is a lot of boilerplate to write, and also means that you can't use a conventional solution like ember-set-helper
or {{mut}}
to update a value with this component.
Describe the solution you'd like
Instead of passing the event as the first value to @change
, I think it would be better to pass the value of the newly selected option (or options if there are multiple):
class MyComponent extends Component {
@tracked selected = "turtle";
handleChange = (value, event) => {
this.selected = value;
};
}
This could be used conventionally with {{set}}
from ember-set-helper
like so:
I think the event could still be provided as the second parameter, there are definitely cases where the user may want to do something a bit more custom and may need access to the original event.
Describe alternatives you've considered
This could possibly be provided as a separate API, @changeValue
(name is definitely bikesheddable), but IMO this would be a bit confusing, since there would be multiple event handlers at that point.
Is your feature request related to a problem? Please describe.
Not really, it would just be convenient.
Describe the solution you'd like
It'd be nice to be able to use named blocks instead of @displayKey
to show what the value should look like, something like:
class MyComponent extends Component {
options = [{
id: 1,
name: "turtle",
}, {
id: 2,
name: "mako",
}];
@tracked selected = this.options[0];
}
Much like #25, except for when passing in an array of objects and the first value or label is null
.
In order to add support for named blocks as per this issue #32 we need to update the project to ember 3.25.
Reference: https://github.com/emberjs/ember.js
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.