DX & authoring experience: for SDC+code components, the example is treated as the default, may not be desirable

Created on 21 March 2025, 3 months ago

Overview

Say you have a component with 2 optional properties: and .

Say that only an example is provided for .

The corresponding ComponentInputsForm looks like this:

It renders just fine. But:

  • Did the SDC developer really intend for that example text to end up being saved? What if it wasn't text, but an image? A date? A SKU? A โ€ฆ whatever?
  • Did the SDC developer not actually intend for this to be a pure schema example?
  • Did the SDC developer at most intend for this example to be used as the grayed out placeholder text, but never even considered it could end up being saved?

Proposed resolution

  1. Stop using the first example value as the default value.
  2. Instead, pass it as the example value to the Field Widget, for a UX like this: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/placeholder...
  3. Adopt JSON Schema's support for default, as surfaced months ago โ†’ .
  4. Only the default in the SDC metadata can become the default value for an instantiated component.

User interface changes

TBD

๐Ÿ› Bug report
Status

Active

Version

0.0

Component

Component sources

Created by

๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

Live updates comments and jobs are added and updated live.
  • Usability

    Makes Drupal easier to use. Preferred over UX, D7UX, etc.

  • Needs product manager review

    It is used to alert the product manager core committer(s) that an issue represents a significant new feature, UI change, or change to the "user experience" of Drupal, and their signoff is needed. If an issue significantly affects the usability of Drupal, use Needs usability review instead (see the governance policy draft for more information).

Sign in to follow issues

Comments & Activities

  • Issue created by @wim leers
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States mglaman WI, USA

    +++++++1 for default value being a placeholder. I've placed a paragraph component so many times and starting typing only to start adding letters after the example content.

    However, that's really hard for non-text inputs. In that case I think it's fine to render the example as the default but leave the form empty.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom f.mazeikis Brighton
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    It is hard for non-textual prop shapes .

    But even for some textual ones, like date and time. Let alone images.

    For images, @lauriii has been saying that we need to make XBenhance what coreโ€™s image widget and media library widget do, precisely to show the default as a kind of placeholder.

    No designs exist for it yet to my knowledge.

    Given your +1, assigning to @lauriii.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Given a meeting last night surfaced this as a challenge/stable blocker for code components, and @effulgentsiaโ€™s firm +1 to label default value as โ€œinitial valueโ€ in the UI, to set clear expectations for content authors, bumping to Critical.

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    My experience is that most page builders treat default values exactly the way Experience Builder does now: if thereโ€™s text in a field, thatโ€™s what will be saved. This matches how forms typically behave: when you see prefilled text, you expect it to be submitted unless you overwrite it.

    That said, we need to decide whether to rely on default or examples in JSON Schema for this. Personally, I donโ€™t have a strong preference either way.

    Additionally, we may want to consider supporting both a placeholder value which is purely a form display concern and a true fallback value which is a rendering concern (i.e. fallback value determined at render time). I donโ€™t think these should block the stable release.

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    FWIW, this is called "Default value" in the Field UI module today and it behaves the same way as XB.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    @lauriii in #10:

    FWIW, this is called "Default value" in the Field UI module today and it behaves the same way as XB.

    You dropped from the call with @f.mazeikis, @jessebaker, @effulgensia and others, in which they explained that precisely this behavior has actually led to a LOT of support requests for Acquia Site Studio. Short version: users expected that changing the default would make the new default appear in all component instances where the default had not been modified.

    Hence my proposal from #7.

    #8 is a very narrow reading/interpretation of the problem described with nuance in the issue summary, which @f.mazeikis had nothing to add to, and @mglaman added #2 to.

    Crucially, #8's ignores that it cannot work like that for SDC's default images โ€” otherwise they'd end up being saved into Drupal's Media Library. Or is that what you're implying? ๐Ÿค” That'd be counter to what you said before.

  • ๐Ÿ‡ฎ๐Ÿ‡ฑIsrael heyyo Jerusalem
  • ๐Ÿ‡ฆ๐Ÿ‡บAustralia larowlan ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ.au GMT+10

    From slack via @heyyo

    The first example is used as default, but not the default property itself. What's the purpose of default as?

    i.e. if a default is provided, we're ignoring it and using the example value. That feels like a bug and we should address it here or open a separate issue - thoughts on which you'd prefer?

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Still needs @lauriii per #11.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    This has significant data storage implications, so tentatively tagging .

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    This is different in Site Studio where there's no way of setting defaults/fallbacks for empty values AFAIK? In Experience Builder, both SDC and in-browser code components provide a way to use fallback values in code.

    UI Suite themes are using this approach too. See https://git.drupalcode.org/project/ui_suite_dsfr/-/blob/1.1.x/components... for an example. This is also what their docs are recommending: https://www.drupal.org/docs/extending-drupal/contributed-modules/contrib... โ†’ .

    To me this seems largely a docs concern to explain how we'd recommend components to be built. There are potential UX implications because many page builders have special handling for empty behavior where they don't even show the field when the fallback value is used.

    Crucially, #8's when you see prefilled text, you expect it to be submitted unless you overwrite it. ignores that it cannot work like that for SDC's default images โ€” otherwise they'd end up being saved into Drupal's Media Library.

    This seems just the incorrect behavior of the widget itself? We should make it possible for the widget to display the default value, regardless of it not being in Media Library. The widget is just means to displaying the value of the field, which in Drupal has historically been tied to a specific field type. In this case it's interesting because the example value cannot use media library and therefore we must implement a field widget which is able to handle display of multiple field types.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    I'm extremely confused by #16. The issue summary clearly states that the problem with the current approach is that we cannot know the intent of the SDC author. We assume that the first example is to be used as the default, and is okay to be saved as such into the database.

    But perhaps that wasn't concrete enough yet. Updated issue summary to make it more precise still. Note, I'm just trying to recall from memory an ~hour-long discussion from ~2 months ago, which others were actually much more vocal on than I.

    • 1+2 would require: at the data storage level, change it to not store the default value in a component instance, so that if the default value changes in the Component config entity, it updates in all instances
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    #17 ๐Ÿ› DX & authoring experience: for SDC+code components, the example is treated as the default, may not be desirable Active : I understand clearly that there's a limitation where the current example values are stored in the database. If you don't want that behavior, you can define fallback values in the SDC/React component. I understand we may want to provide an API for this in future for an improved DX+UX but I don't see how that should be critical and block a release.

  • Assigned to lauriii
  • Status changed to Needs review 16 days ago
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    you can define fallback values in the SDC/React component

    Ah, you view it as a matter of logic rather than metadata.

    But, that's not actually possible today:

    1. Any SDC/code component that has an required/optional prop examples[0] specified will get that value stored in the component tree, so any fallback logic in the SDC/code component will never run. So if the example changes, all existing component instances will continue showing the original example value.
    2. ONLY SDC/code components with an specified will have no value stored in the component tree, so only for these kinds of props will fallback logic in the SDC/code component ever run.

    I understand we may want to provide an API for this in future for an improved DX+UX but I don't see how that should be critical and block a release.

    Because:

    1. the way that SDC components' examples[0] or default is used would change completely if we do this issue
    2. whether we duplicate the example/default values and actually store them in the component tree or not has big data storage implications
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    #19 ๐Ÿ› DX & authoring experience: for SDC+code components, the example is treated as the default, may not be desirable Active : Exactly. Providing an API for this would help improve the UX/DX since it would allow users to see the default value on the form โ€“ but I don't think this is critical. The reason this gets surfaced as a critical feature from Site Studio users is because there's literally no way to achieve this there.

    I would imagine if we did this, we would still keep the examples[0] behavior just as it's today. Then we'd add support for default which would have a different behavior.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Will think about that.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    I would imagine if we did this, we would still keep the examples[0] behavior just as it's today. Then we'd add support for default which would have a different behavior.

    I see โ€ฆโ€ฆโ€ฆ different potential kinds of sample/example/default values for component inputs (for SDC-sourced. components: "props"). When I write "stored", read that as "stored for that component instance".

    1. Those declared as metadata, used as placeholders (think https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/placeholder...) and are .
    2. Those declared as metadata, used as placeholders (think https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/placeholder...) and are .
    3. Those declared as metadata, used as default value in the generated input UX (field widget), and are .
    4. Those declared as metadata, used as default value in the generated input UX (field widget), and are .
    5. Those NOT declared as metadata but as logic, and are (similar to case 4, but as logic, not metadata).

    XB currently:

    1. uses SDC's examples[0] for implementing case 3
    2. technically it supports case 5 if it's an optional prop without examples[0]

    #20 proposes to:

    1. never implement cases 1, 2
    2. implement case 4 later, and use SDC's default for that. That would mean that if the SDC changes fromdefault: 'foo' to default: 'bar', that all existing instances of that SDC rendered using XB would start showing "bar" (unless the user entered a different value, then the user's value continues to show). That'd be achieved by comparing the value in the StaticPropSource with the default: โ€ฆ in the SDC, and if they match, we would not store it in the component tree. That will either require updating our validation logic, or introducing a new DefaultPropSource.

    If @lauriii confirms that XB A) indeed never needs to support cases 1+2, and B) my general interpretation for how to achieve case 4 sounds sensible, then I agree this doesn't need to be a beta blocker nor a stable blocker.

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    I don't think we would do 2. 1 seems something we might do but it also seems like a new API to specify attributes outside of the schema. Same as how https://github.com/rjsf-team/react-jsonschema-form separates UI Schema from the Schema.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    #23 only responded to A, not to B. So I'm assuming silence about it is confirmation :)

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    Yep, that's correct! ๐Ÿ˜Ž

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Great! ๐Ÿ˜Š Added this to a new section (#post-stable) ๐ŸŒฑ [META] Production-ready ComponentSource plugins Active at ๐ŸŒฑ [META] Production-ready ComponentSource plugins Active .

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States effulgentsia

    I agree with the conclusion here that any further work on this can wait until after 1.0. However, a few minor points I want to capture here while I'm thinking of them:

    [#22.1] seems something we might do but it also seems like a new API to specify attributes outside of the schema.

    I interpret this as meaning that it would not be part of the SDC's YAML, and instead be something "owned" by XB. For example, it might be extra info on the Component config entity. In other words, SDCs just say "here are some examples" and it's not their concern whether those are treated as initial content, placeholder content, fallback content, etc. People administering XB would be the ones deciding what behavior they want for what gets done with the examples. For example, someone using XB to create a demo site for a DrupalCon presentation might want examples to be the initial value, and stored with the content, as per the current behavior. But someone making a corporate site for production might want SDCs' example values to help give some guidance to the content creators, but not get accidentally leaked to the published site.

    implement case 4 later, and use SDC's default for that. That would mean that if the SDC changes fromdefault: 'foo' to default: 'bar', that all existing instances of that SDC rendered using XB would start showing "bar" (unless the user entered a different value, then the user's value continues to show). That'd be achieved by comparing the value in the StaticPropSource with the default: โ€ฆ in the SDC, and if they match, we would not store it in the component tree.

    I think yes to using the default keyword in the json schema for this for when we want to implement it, and to not implementing this until later, probably not until after XB 1.0. However, I don't think the logic/UI should be "does the value in the form happen to match the default", but rather I think we'll want to implement something more explicit like wrapping/extending the widget to give the content editor a choice to either fill in the decorated/base widget or choose a "Use the default" option, or something like that.

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    People administering XB would be the ones deciding what behavior they want for what gets done with the examples. For example, someone using XB to create a demo site for a DrupalCon presentation might want examples to be the initial value, and stored with the content, as per the current behavior. But someone making a corporate site for production might want SDCs' example values to help give some guidance to the content creators, but not get accidentally leaked to the published site.

    It's unclear to me still how we'd implement this at this point. I think we have to design the no-code component editor before we make decisions around implementing this. There's tension between the single directory nature of SDCs and making decisions like this in XB UI. However, if we can allow users to achieve all of this by easily decorating a component via the UI, it wouldn't actually be conceptually modifying the component but creating effectively a new component.

    I think we'll want to implement something more explicit like wrapping/extending the widget to give the content editor a choice to either fill in the decorated/base widget or choose a "Use the default" option, or something like that.

    ๐Ÿ’ฏ ๐Ÿ‘

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Great discussion! ๐Ÿ‘ Let's continue it after 1.0 ๐Ÿ˜Š

    Thanks, both of you!

Production build 0.71.5 2024