- Issue created by @balintbrews
- ๐ฌ๐งUnited Kingdom AaronMcHale Edinburgh, Scotland
balintbrews โ credited aaronmchale โ .
- ๐ญ๐บHungary Gรกbor Hojtsy Hungary
balintbrews โ credited gรกbor hojtsy โ .
- ๐ซ๐ฎFinland lauriii Finland
balintbrews โ credited lauriii โ .
- ๐ฌ๐งUnited Kingdom longwave UK
balintbrews โ credited longwave โ .
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
balintbrews โ credited wim leers โ .
- ๐ณ๐ฑNetherlands balintbrews Amsterdam, NL
Crediting people who were part of the discussion that led to the ADR at Drupal Dev Days in Leuven.
- Merge request !913#3519737: Plan how to evolve code component overrides โ (Open) created by Unnamed author
- ๐บ๐ธUnited States effulgentsia
I really like the option 2 proposal that's in the ADR. My one nit though is I don't think we should do it as a custom hook, but instead as a plain async function that's passed to React 19's use() API. In other words, instead of:
import { useMenuData } from '@/lib/menu'; const NavigationMenu = ({ menuId, level }) => { const menuData = useMenuData(menuId, { level }); // ... }
to do:
import { use } from 'react'; import { fetchMenuData } from '@/lib/menu'; const NavigationMenu = ({ menuId, level }) => { const menuData = use(fetchMenuData(menuId, { level })); // ... }
This would then also work for other UI frameworks when we add support for them in the future, which we might do soon as part of the CLI work. For example, in Svelte:
{#await fetchMenuData(menuId, { level }) then menuData} ... {/await}
One hiccup with this approach though is that
preact/compat
doesn't implement theuse()
function. I opened https://github.com/preactjs/preact/issues/4756, but we can't count on that getting done in time. However, I think we can work around that by implementing our ownuse()
function until such time as Preact implements the proper one, and ours can sidestep the need to work withSuspense
, because we can rely on either server-side prefetching or async Astro island hydration to make sure we don't hydrate the component until we've already fetched the data and can return it synchronously by the timeuse()
is called. - ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
Sorry for the long wait. Based on DDD discussions, I expected this to be much bigger than it turns out to be, I should've reviewed this sooner ๐
@effulgentsia's remarks in #10 are squarely on the front-end implementation side of this new component source plugin, which I have no strong opinions about.
I reviewed this from a XB data model + component source architecture + reliability + ecosystem reach POV.
The ADR simultaneously does not go into detail about the challenges of the most common use case (menu blocks) and also doesn't really explain how we'd make other use cases (think: arbitrary other block plugins such as the branding block). We discussed much of this at length in person at DDD Leuven.
I think this ADR is a great start, but I think there's a few crucial things that are too open-ended for this ADR to be mergeable. I'm happy to be overruled if all @balintbrews, @longwave, @effulgentsia and @lauriii all think this is sufficiently precise. But I would like to see more detail, because at least to me it's not clear how this proposes to implement "block overrides" for e.g. the breadcrumbs or site branding blocks. ๐๐
- โ
Always passing the entire menu tree to the component is not good enough: different menus want to show different slices or subtrees of a menu โ for example only the top level, only the first 2 levels, starting at the 3rd level etc.
The obvious solution to support parametrization: a HTTP API to fetch menu links, for which Drupal core has the โ endpoint.
๐ The ADR covers this: +
- โ The ADR does not explain the code component developer/author DX for knowing the shape of the data they would receive.
- โ The ADR does not explain how the breadcrumbs block would work in option 2. Drupal has no HTTP API to fetch the results of a service (the
breadcrumb
service in the server-side container). Is building such a HTTP API part of the envisioned scope? - โ The ADR does not explain how the site branding block would work in option 2. There's no HTTP API to fetch (simple) config (the site name + slogan). Core's JSON:API and REST modules both do not support that. Is building such a HTTP API part of the envisioned scope?
- ๐ค The ADR does not state whether this would be a new component source plugin, or whether it's just the existing "code component" source but with additional APIs (for data fetching) available. If it's the same component source plugin, how will we ensure that the data-fetching code components end up in the UI library? (See
\Drupal\experience_builder\Entity\Component::computeUiLibrary()
.)Can you confirm that the intent in all 3 options is to implement a new "block override"
ComponentSource
plugin, which just happens to share a lot of infrastructure with the existing "code component"ComponentSource
plugin, but is about data fetching (and hence ) instead of providing props/slots?
- โ
Always passing the entire menu tree to the component is not good enough: different menus want to show different slices or subtrees of a menu โ for example only the top level, only the first 2 levels, starting at the 3rd level etc.
- ๐ณ๐ฑNetherlands balintbrews Amsterdam, NL
Wim and I will meet tomorrow to talk things through, then I will make the necessary adjustments.
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
Productive meeting with @balintbrews just now ๐ He'll add great clarifications on the ADR ๐๐