GithubHelp home page GithubHelp logo

ember-a11y / ember-select-light Goto Github PK

View Code? Open in Web Editor NEW

This project forked from q2ebanking/ember-select-light

12.0 12.0 11.0 1.11 MB

The simplest Ember <select> there is.

License: Other

JavaScript 83.75% HTML 8.56% Handlebars 7.69%

ember-select-light's People

Contributors

cah-danmonroe avatar colenso avatar david-peden-q2 avatar dependabot[bot] avatar ember-tomster avatar hergaiety avatar jandillmann avatar javve avatar joe-wroten-q2 avatar knownasilya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ember-select-light's Issues

Doesn't support EmberJS v4.x.x

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

@change causes ember-template-lint to have coniptions

Describe the bug

  5:2  error  Event handler methods like `change` should not be passed in as a component arguments  no-passed-in-event-handlers

image

Latest ember-template-lint at the time: 3.4.2

To Reproduce

Use the @change arg

Expected behavior

I don't get yelled at

Add ember try

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.

Push up to NPM

After #1, #2, and #3 are completed we'll need to push this up to NPM. Ideally I'd like to do this in a way that respects Semver as a major bump to the existing package, but if that's not possible then we'll have to discuss alternatives here.

[Brainstorming] Better performance for updating `selected`

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 ๐Ÿ˜„

Allow object/reference values

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:

<SelectLight
  @value={{this.selected.id}}
  @options={{this.options}}
  @valueKey="id"
  @displayKey="name"
  @change={{this.handleChange}} 
/>
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:

<SelectLight
  @value={{this.selected}}
  @options={{this.options}}
  @displayKey="name"
  @change={{this.handleChange}} 
/>
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:

<SelectLight
  @value={{this.selected}}
  @options={{this.options}}
  @displayKey="name"
  @change={{set this "selected"}} 
/>

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:

<SelectLight as |s|>
  <s.option></s.option>
</SelectLight>

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:

<SelectLight as |s|>
  <option value="foo">Foo</option>
  <s.option @value={{this.someObj}}>Bar</s.option>
</SelectLight>

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>.

Update License

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:

  • Keep the license as is
  • Update the license in a meaningful way
  • Replace the license with MIT to match what other ember-a11y projects do

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).

Set up CI

Linting and tests should have to pass for Pull Requests to be allowed to merge.

Allow option with empty value

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'
  }]
}

At the moment this will result in this:
image
image

Enable Dependabot

After #3 and #5 it'd be ideal to enable Dependabot to keep this dependency up to date.

Pass the selected value(s) as the first parameter to `@change`

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:

<SelectLight
  @value={{this.selected}}
  @options={{array "turtle" "tortoise"}}
  @change={{this.handleChange}} 
/>
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:

<SelectLight
  @value={{this.selected}}
  @options={{array "turtle" "tortoise"}}
  @change={{set this "selected"}} 
/>

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.

Consider adding named blocks

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:

<SelectLight
  @value={{this.selected}}
  @options={{this.options}}
  @change={{this.handleChange}} 
>
  <:option as |value|>
   {{value.name}}
  </option>
<SelectLight>
class MyComponent extends Component {
  options = [{
    id: 1,
    name: "turtle",
  }, {
    id: 2,
    name: "mako",
  }];

  @tracked selected = this.options[0];
}

Update README badges

  • This repo now uses GitHub Actions instead of Travis, so the Travis build badge should be replaced with a GitHub Actions one.
  • The NPM badge should be replaced with one that points to the new package after #5 is done.
  • Ember Observer may need to be a new badge as well. We'll see?
  • PR's welcome badge?
  • License MIT Badge

Reference: https://github.com/emberjs/ember.js

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.