swordev / suid

A port of Material-UI (MUI) built with SolidJS.
https://suid.io
MIT License
673 stars 48 forks source link

Select does not work when creating dynamic ranges #223

Open quasaray opened 1 year ago

quasaray commented 1 year ago

I have a dynamic range, for selecting the start and end of an interval, which uses two select inputs for choosing the start and end.

Whenever the range changes though, the newly added values are not selectable. The values still display on the select, but clicking on them does not update the select value. e.g if the start value has [1,2] but is then expanded to [1,2,3], 1 and 2 can be selected, but 3 cannot.

I have created a stackblitz reproducing the problem here, changing the end value to a larger number will update the display of the start values, but it can only select what was originally present.

Is the Select component not intended for dynamic menus? I could not see anything in the documentation about it.

juanrgm commented 1 year ago

There is a bug in inspectChildren.

The children introspection is a common pattern in ReactJS, but nonexistent in SolidJS. I don't know if this case can be fixed, otherwhise I would have to use contexts. I need to investigate further.

scdailey commented 1 year ago

Also having this issue. Glad I finally found a post about it because I thought it was just me 😅

urish commented 1 year ago

Same here - any workarounds?

quasaray commented 1 year ago

native select still works fine, I am using that for now

lukexor commented 9 months ago

It seems like this might also be an issue for buildless environments? Even when not using dynamic options. No onChange triggered. NativeSelect works fine as well, though less ideal as I also want to use the multi select chip component in this environment. and the Native version of multiselect doesn't seem to work correctly (I can't seem to get it working in a normal solid build either)

e.g.

  const [value, setValue] = createSignal(props.defaultValue);
  return html`
    <${Show} when=${props.visible}>
      <div class="py-4">
        <${InputLabel}>${props.name}${" "}<//>
        <${Select}
          title=${props.title}
          label=${props.name}
          name=${props.name}
          value=${value}
          disabled=${props.disabled}
          fullWidth=${() => props.fullWidth ?? true}
          onChange=${(e) => setValue(e.target.value)}
        >
          <${Show} when=${() => !props.required}>
            <${MenuItem} value="">
              <em>None</em>
            <//>
          <//>
          <${MenuItem} value="1">
            <em>Item 1</em>
          <//>
        <//>
      </div>
    <//>
  `;
BierDav commented 9 months ago

Hi guys! I have created an SSR compatible version of the select component here. You can check it out, unfortunately it is not compatible with the Select API of MUI, but that is as close as I it gets, I guess, and I also support dynamic ranges with <For/> component

urish commented 4 months ago

Same here - any workarounds?

My current workaround is the wrap the Select elements with <Show>, and hide / reshow them whenever the value list changes.

Azq2 commented 4 months ago

If I understand correctly, the whole problem is that in SolidJS it is impossible to get the properties of child elements - the DOM node is returned instead.

https://github.com/solidjs/solid/issues/222


As another workaround, I suggest WeakMap with all MenuItem's. Why not? Only what we need - find all .MuiMenuItem-root in the props.children and then convert to the props using WeakMap.

https://playground.solidjs.com/anonymous/65cf3993-1671-4d44-9e45-f85380b2028b

BierDav commented 4 months ago

That's a good point, i haven't ever heard of that until now, but it seems to solve the technical issues i had. Unfortunately i currently don't have a lot of time, to implement this but I could offer to review the pr.

Azq2 commented 4 months ago

PR is here: https://github.com/swordev/suid/pull/292

cs-clarence commented 4 weeks ago

Temporary fix for me is use

Array.map and jsx interpolation

<Select>
  {names()?.map((name) => (
    <MenuItem value={name}>
      {name}
    </MenuItem>
  ))}
</Select>

instead of

<Select>
  <For each={names()}>
    {(name) => (
      <MenuItem value={name}>
        {name}
      </MenuItem>
    )}
  </For>
</Select>
Azq2 commented 4 weeks ago

In my project I use https://github.com/siemens-mobile-hacks/web-tools/tree/main/patches with https://www.npmjs.com/package/patch-package