`enum` data shapes: error when choosing "- None -" in `<select>`

Created on 2 September 2024, 18 days ago
Updated 9 September 2024, 10 days ago

Overview

While working on Component props form: make form elements match design 📌 Component props form: map textarea, bool, and select elements to React components Fixed I bumped into this error.When a user tries to select None from the select options then it breaks the app with an error Drupal\Core\Render\Component\Exception\InvalidComponentException: [style] Does not have a value in the enumeration ["primary","secondary"] in Drupal\Core\Theme\Component\ComponentValidator->validateProps().
For context i tried changing the value of style in the heading props and selected that to none.

Proposed resolution

Only allow valid choices per the enum. See #6 for details.

User interface changes

🐛 Bug report
Status

Closed: duplicate

Component

Page builder

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @Utkarsh_33
  • 🇮🇳India Gauravvv Delhi, India

    This issue also occurs when selecting 'None' for the column width. Could you specify which component you encountered this issue with? Thanks!

  • It occurs for every select element as far as i know.Is there an instance where it works correctly @gauravvvv ?

  • 🇭🇺Hungary balintk

    I wonder if those "-None-" options should even be there in the first place. Just by looking at a few components, it looks like those values should be required with a default value.

  • Assigned to Wim Leers
  • 🇧🇪Belgium Wim Leers Ghent 🇧🇪🇪🇺

    #5++

    Yes, exactly.

    When using type: string, enum: [foo, bar], the value MUST be either foo or bar — IOW: it is required to pick a value.

    But the difference is that per #3469855-3: Emptying a required value through the UI crashes the app , @balintbrews is convinced it can be solved entirely on the client-side. That's true generally speaking, but not for this particular case. This particular case does need it, to avoid the - None - option being added (see \Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsSelectWidget::getEmptyLabel()).

  • 🇧🇪Belgium Wim Leers Ghent 🇧🇪🇪🇺

    Adding missing issue relationships.

    Making issue title more specific.

  • Assigned to Utkarsh_33
  • Status changed to Needs review 16 days ago
  • 🇧🇪Belgium Wim Leers Ghent 🇧🇪🇪🇺
  • 🇫🇮Finland lauriii Finland

    When using type: string, enum: [foo, bar], the value MUST be either foo or bar — IOW: it is required to pick a value.

    But if that prop is not required, you should be able to leave it unset. Isn't that what the "- none -" would be for?

  • Assigned to lauriii
  • 🇧🇪Belgium Wim Leers Ghent 🇧🇪🇪🇺

    #10: Hm … I wonder then if the problem is that we do not support default.

    IOW:

    • a prop with a shape like enum: […] that IS NOT listed in the SDC's required MUST have a default specified
    • a prop with a shape like enum: […] that IS listed in the SDC's required MAY have a default specified
  • Assigned to Wim Leers
  • Status changed to Needs work 16 days ago
  • 🇧🇪Belgium Wim Leers Ghent 🇧🇪🇪🇺

    Will investigate the SDC subsystem closer.

  • Issue was unassigned.
  • 🇧🇪Belgium Wim Leers Ghent 🇧🇪🇪🇺

    Verifying fundamentals

    For the experience_builder:heading SDC, the generated Component config entity does contain:

        style:
          field_type: list_string
          field_storage_settings:
            allowed_values:
              -
                value: primary
                label: primary
              -
                value: secondary
                label: secondary
          field_instance_settings: {  }
          field_widget: options_select
          default_value:
            value: primary
    

    IOW: primary is selected as the default automatically, because that's the first example. So why is this not being respected? 🤔

    Turns out it is:

    So the default aspect mentioned in #12 is an irrelevant distraction.

    So: server allows selecting "nothing", but how to make client know this?

    All that matters is what @lauriiii was getting at in #10: if an SDC marks a prop as optional, we should be able to detect that (the "no value entered" scenario). So how do we do that?

    Turns out that form_select_options() hardcodes a particular special value: _none — specifically for <select>. (Even the "list" field type's widget base class must hardcode this knowledge, see \Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsWidgetBase::validateElement()). It can optionally be overridden using #empty_value.

    Conclusion

    Select.tsx, introduced in 🐛 Prop select lists don't affect the component Fixed , needs to be updated to be aware of this special value. If this special value is selected, then:

    1. the UI should interpret this as "no input specified by user"
    2. the UI should then delete this prop from the model, rather than setting "_none" as the value — because that's the whole point of Contextual form values need to be integrated with Redux Active : to allow real-time updates of the preview based on information on the client side only
    3. that will then prevent this invalid model to be sent from the client to the server:
  • Status changed to Closed: duplicate 13 days ago
  • 🇺🇸United States bnjmnm Ann Arbor, MI

    I have this solved and will soon have tests for it in my in-progress MR for 🌱 [META] Redux sync on ALL prop types, not just ones with a single [value] property Active . If this is crazy urgent and can't wait on the larger issue feel free to reopen and assign this to me and I'll extract what I have in there.

  • 🇧🇪Belgium Wim Leers Ghent 🇧🇪🇪🇺

    👍 Great! 😄

Production build 0.71.5 2024