SDC components: Fix JSON schema usage

Created on 8 January 2024, 6 months ago
Updated 12 April 2024, 2 months ago

Problem/Motivation

Hi,

We are building UI Patterns β†’ 2.x, based on SDC API, and we are using Kinetic for testing our site building and contribution features (usage of SDC components in blocks, views, layouts, field formatters...).

Doing those tests, we have found some issues related to JSON schema usage.

Incorrect JSON schemas

card component

media prop: It is not how required works https://json-schema.org/understanding-json-schema/reference/object#required

{
  "required": true,
  "type": "object"
}

Proposal: remove required

{"type":"object"}

accordion component

open prop: "mixed" is not a valid JSON schema type.

{"type":"mixed"}

Proposal:

{"type":"boolean"}

And remove this useless part in the Twig template :

{% set open = open is null ? false : open %}

Because:

  1. Twig strict_variables is false in Drupal. It is the default Twig behaviour and a enjoyable feature
  2. So, non-existing values are replaced by null
  3. And null values are resolved to false
  4. So, you don't need to mix boolean and null

billboard component

cta prop: "link" is not a valid JSON schema type

{
  "items": {
    "type": "link"
  },
  "type": "array"
}

Proposal: in my humble opinion, it would be better to replace this prop a slot than hardcoding the call to kinetic:link--button in the template. There are no slots in this component, which is lacking flexibility.

If we prefer to keep it as a prop, you need to have a proper data structure:

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "url": {
        "type": "string"
      },
      "title": {
        "type": "string"
      }
    }
  }
}

With "title" instead of "text" because it is the common link data structure, found in LinkItem and menu.html.twig for example. Let's be careful when we map this property to link--button in the template.

heading_style and heading_tag prop: an unexpected comma in the type string

{"enum":["h1","h2","h3"],"type":"string,"}

Proposal: remove it

Incomplete JSON schemas

Those are valid, but it is not possible to understand the expected data:

Empty undefined object

{"type":"object"}

Found in:

  • image's content prop. Proposal: this is clearly a slot
  • video's content prop. Proposal: this is clearly a slot
  • section's container_attributes prop. Proposal: reorganise the template to not need such a mapping of region => attributes ( Refactor Implementation of Section and Layouts that implement sections πŸ“Œ Refactor Implementation of Section and Layouts that implement sections. Active )
  • layout--onecol's & layout--twocol's settings prop. Proposal: each setting must be a prop: mobile_order, bg_color, content_width ( Refactor Implementation of Section and Layouts that implement sections πŸ“Œ Refactor Implementation of Section and Layouts that implement sections. Active )
  • layout--onecol's & layout--twocol's container_attributes prop. Proposal: reorganise the template to not need such a mapping of region => attributes ( Refactor Implementation of Section and Layouts that implement sections πŸ“Œ Refactor Implementation of Section and Layouts that implement sections. Active )
  • header's branding prop. Proposal: this is clearly a slot
  • header's main_menu prop. Proposal: this is clearly a slot

Array of undefined values

{"type":"array"}

  • section's region prop. Proposal: is it a slot? ( Refactor Implementation of Section and Layouts that implement sections πŸ“Œ Refactor Implementation of Section and Layouts that implement sections. Active )
  • grid's items prop. Proposal: is it a slot?
  • glide's items prop. Proposal: this is clearly a slot
  • glide's classes prop. Proposal: add items/type = string to the schema
  • tabs's items pop. Proposal: it may be better to have a slot, but let's add the expected data structure (id, body, heading...) if we prefer to keep it as a prop
  • accordion's items pop. Proposal: it may be better to have a slot, but let's add the expected data structure (body, heading...) if we prefer to keep it as a prop
  • text-and-media's ctas prop. Proposal: the same "links" data structure as the one proposed for billboard's ctas prop.
  • carousel's items prop. Proposal: it may be better to have a slot, because the template is doing some risky work with an expected render array item.heading[0]['#text']
πŸ› Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡«πŸ‡·France pdureau Paris

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

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @pdureau
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡«πŸ‡·France pdureau Paris
  • πŸ‡ΊπŸ‡ΈUnited States michaellander

    Really appreciate this @pdureau! We will try to get these in shortly.

  • First commit to issue fork.
  • πŸ‡ΊπŸ‡ΈUnited States brayn7 Lexington, Ky
  • πŸ‡ΊπŸ‡ΈUnited States brayn7 Lexington, Ky
  • Merge request !14Resolve #3413121 "Sdc components fix" β†’ (Merged) created by brayn7
  • Status changed to Needs review 5 months ago
  • πŸ‡ΊπŸ‡ΈUnited States michaellander
  • Assigned to pdureau
  • πŸ‡«πŸ‡·France pdureau Paris

    I will have a look :)

  • Issue was unassigned.
  • Status changed to Needs work 5 months ago
  • πŸ‡«πŸ‡·France pdureau Paris

    Incorrect JSON schema type

    accordion-item component's open prop: "mixed" is not a valid JSON schema type.

    {"type":"mixed"}

    Proposal:

    {"type":"boolean"}

    it was done for accordion component, but still need to be done for accordion-item

    Array of undefined values

    {"type":"array"}

    • section's regions prop. Proposal: is it a slot? ( Refactor Implementation of Section and Layouts that implement sections πŸ“Œ Refactor Implementation of Section and Layouts that implement sections. Active )
    • grid's items prop. Proposal: is it a slot?
    • glide's items prop. Proposal: this is clearly a slot
    • glide's classes prop. Proposal: add items/type = string to the schema
    • tabs's items pop. Proposal: it may be better to have a slot, but let's add the expected data structure (id, body, heading...) if we prefer to keep it as a prop
    • accordion's items pop. Proposal: it may be better to have a slot, but let's add the expected data structure (body, heading...) if we prefer to keep it as a prop
    • text-and-media's ctas prop. Proposal: the same "links" data structure as the one proposed for billboard's ctas prop.
    • carousel's items prop. Proposal: it may be better to have a slot, because the template is doing some risky work with an expected render array item.heading[0]['#text']
    • card's ctas prop

    Empty undefined object

    {"type":"object"}

    Found in:

    List of undefined objects

    billboard's component ctas prop:

    {
      "items": {
        "type": "object"
      },
      "type": "array"
    }

    Proposal: in my humble opinion, it would be better to replace this prop a slot than hardcoding the call to kinetic:link--button in the template. There are no slots in this component, which is lacking flexibility.

    If we prefer to keep it as a prop, you need to have a proper data structure:

    {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "title": {
            "type": "string"
          }
        }
      }
    }

    With "title" instead of "text" because it is the common link data structure, found in LinkItem and menu.html.twig for example. Let's be careful when we map this property to link--button in the template.

  • πŸ‡ΊπŸ‡ΈUnited States brayn7 Lexington, Ky

    I made some more changes. I think we should have a different issue for considering things to be slots rather than props for things mentioned like accodion-item, ctas and the like. I wouldn't mind being pointed in the direction of some examples and articles to see what best practice is for those items. The current mindset is that we want to be super defined about what is accepted in certain places like ctas where we don't necessarily want just anything passed there. That being said @pdureau we are open to learning and changing our mindset.

  • πŸ‡«πŸ‡·France pdureau Paris

    The current mindset is that we want to be super defined about what is accepted in certain places like ctas where we don't necessarily want just anything passed there.

    If you want to be superdefined about what is accepted in certain places, props are better than slots.

    However, I would suggest to learn to "let go" while designing a design system. Components are meant to be shared and used with different business constraint and context. To achieve this, we need to both:

    • Make the components flexible
    • Make the components forward compatible

    And slots are perfect for that. One day, instead of the super defined CTAs, your card may have something else. Those CTAs is not what make this component a card.

    Also, in a Drupal context, slots have the advantage of being able to accept any renderable (rendered entities, views displays, forms...), so they are easy to use while site building from admin pages.

    Anyway, if you keep them as props, {"type":"array"} and/or {"type":"array"} are not enough.

    I wouldn't mind being pointed in the direction of some examples and articles to see what best practice is for those items.

    Because this subject is still new in Drupal community, those articles are easier to find in other communities (like Vue.js, for example).

    Also, witnessing the struggle of ReactJS with "prop drilling" teach us about the advantages of a proper slots system (which React lacks):

  • πŸ‡ΊπŸ‡ΈUnited States brayn7 Lexington, Ky

    @pdureau taking into consideration your comments. Thank you for that. I feel that it could end up being a new ticket that revolves around making our base components more flexible and use slots but this would be more of a change than just schema. So TBD.

  • Status changed to Fixed 3 months ago
  • πŸ‡ΊπŸ‡ΈUnited States brayn7 Lexington, Ky

    Going to mark this fixed in terms of the schema is fixed but not using slots yet to be more flexible. That is tracked in the related issue.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.69.0 2024