Skip to content
Snippets Groups Projects

Draft: Resolve #3462310 "Component edit"

Closes #3462310

Merge request reports

Test summary results are being parsed

Closed by Bálint KlériBálint Kléri Aug 29, 2024 (Aug 29, 2024 12:12pm UTC)

Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
13 14 'drupal-form--xbxb': Form,
14 15 'drupal-form-element--xbxb': FormElement,
15 16 'drupal-form-element-label--xbxb': FormElementLabel,
17 select: SelectComponent,
  • 1 import type * as React from 'react';
    • Author Contributor

      Had a discussion with @jessebaker regarding this that we need to use the select component form the Radix library.For now i have added the code with basic structure which can be further fine-tuned as we move forward.

    • Please register or sign in to reply
  • utkarsh_33 added 1 commit

    added 1 commit

    Compare with previous version

  • utkarsh_33 added 2 commits

    added 2 commits

    • 75cbd76e - Wip for link component
    • 6679c63f - Added drupal-select--xbxb for mapping

    Compare with previous version

  • utkarsh_33 added 1 commit

    added 1 commit

    Compare with previous version

  • 13 14 'drupal-form--xbxb': Form,
    14 15 'drupal-form-element--xbxb': FormElement,
    15 16 'drupal-form-element-label--xbxb': FormElementLabel,
    17 'drupal-select--xbxb': SelectComponent,
    • Author Contributor

      This does not renders the component that we create. But if i use select: SelectComponent then it loads the custom component that we created.

    • For any new components here, you also need to add a .twig file in experience_builder/templates/form

      Look at the existing files there to see the naming conventions and what the file contents should be.

    • Please register or sign in to reply
  • 16
    17 const SelectComponent: React.FC<SelectComponentProps> = ({
    18 options,
    19 initialSelection = '',
    20 }) => {
    21 const [selectedValue, setSelectedValue] = useState(initialSelection);
    22
    23 return (
    24 <div>
    25 <Select.Root
    26 value={selectedValue}
    27 onValueChange={(value) => setSelectedValue(value)}
    28 >
    29 <Select.Trigger className={clsx('selectTrigger')} />
    30 <Select.Content className={clsx('selectContent')}>
    31 {/*<Select.Group>*/}
  • utkarsh_33 added 10 commits

    added 10 commits

    Compare with previous version

  • utkarsh_33 added 3 commits

    added 3 commits

    Compare with previous version

  • utkarsh_33 added 1 commit

    added 1 commit

    • eebf7a6f - Removed imports and fixed styleLint

    Compare with previous version

  • utkarsh_33 added 2 commits

    added 2 commits

    • fcfe3b7b - fixed styleLint
    • 9a48986e - Added empty link element and mapped the element

    Compare with previous version

  • utkarsh_33 added 18 commits

    added 18 commits

    Compare with previous version

  • utkarsh_33 added 1 commit

    added 1 commit

    • 59f3a153 - Conditionally rendered link element inside input element

    Compare with previous version

  • 13 15 'drupal-form--xbxb': Form,
    14 16 'drupal-form-element--xbxb': FormElement,
    15 17 'drupal-form-element-label--xbxb': FormElementLabel,
    18 'drupal-select--xbxb': SelectComponent,
    19 'drupal-links--xbxb': Links,
    • Author Contributor

      This won't work as we are not processing the link element seperately but it's processed as a part of input.tsx where i have added a if condition that if props.attributes.type === 'url' then return a distinguishing markup for link element. We can see that in the DummyPropsForm.

      I am not sure what and how we need to distinguish between the link and input component.

    • When you reference DummyPropsForm can you also mention what component is being edited? The contents can be a vastly different depending on the component type so not knowing it makes it very difficult to know what is being referenced.

      I'm also not entirely sure what is meant by but it's processed as a part of input.ts but if that but as mentioned in another comment, Links and inputs are separate templates, you do not need to account for one in the other. The input template renders children, and links can be one of those children, but it doesn't need to do anything special for it. This may be an issue of not having the props fully set up in links--xbxb-html.twig

    • Please register or sign in to reply
  • 6 6 const Input = (props: React.ComponentProps<any>) => {
    7 7 const { attributes = {}, renderChildren = '' } = props;
    8 8 const unHandledTypes = ['submit', 'hidden'];
    9 if (props.attributes.type === 'url') {
    10 return (
    • Author Contributor

      This is a workaround so that we can distinguish the Link elements with the default input element. This is also the reason for the test fails i guess.

    • In Twig, the input links are fully separate templates that are not codependent in any way, and the same can happen (and should happen) in JSX equivalents.

    • Please register or sign in to reply
  • 1 {
    • Author Contributor

      templates/form/links--xbxb.html.twig i have added links because we have links.html.twig as the templates.

    • Based on the variables list in links.html.twig, it seems like there should be more depth to this configuration. This determines what gets sent as props, and what data type is expected. For example within links there are sub-properties that will likely be different data types `* - links: Links to be output.

      • Each link will have the following elements:
        • link: (optional) A render array that returns a link. See
      • template_preprocess_links() for details how it is generated.
        • text: The link text.
        • attributes: HTML attributes for the list item element.
        • text_attributes: (optional) HTML attributes for the span element if no
      • 'url' was supplied.`

      If you're unsure what props to set up, a breakpoint at the end of semi_coupled_theme can help too. return $renderer->render($element);

    • Please register or sign in to reply
  • 1 import type React from 'react';
  • 1 {
    2 "props": {
    3 "attributes": "object",
    4 "links": "array",
    5 "heading": "object | string"
    • This isn't typescript or syntax that supports | syntax. This is information passed to _semi_coupled_collect_props. Looking at the logic in _semi_coupled_collect_props can help you determine what type to use.

    • Please register or sign in to reply
  • 1 {
    2 "props": {
    3 "attributes": "object",
    4 "links": "array",
    • Suggested change
      4 "links": "array",
      4 "links": "array",

      "array" is not recognized syntax, but defining array contents is. For example: "items": [ { "attributes": "object", "content": "JSX.Element" } ],

    • Please register or sign in to reply
  • 9 if (props.attributes.type === 'url') {
    10 return (
    11 <div className="link-input-container">
    12 <input type="text" className="link-input" placeholder="🔗Add" />
    13 </div>
    14 );
    15 }
    9 16
    10 17 return (
    11 18 <>
    12 19 {!unHandledTypes.includes(attributes?.type) && (
    13 <TextField.Root {...a2p(attributes)} mb="5" />
    20 <TextField.Root
    21 {...a2p(attributes)}
    22 mb="5"
    23 style={{
  • 1 import type React from 'react';
    2
    3 interface LinkProps {
    4 links: Array<{
    5 text: string;
    6 url?: string;
    7 icon?: JSX.Element;
    • Where is this icon property coming from? That doesn't seem to match the template variables documented in the twig version ` * Each link will have the following elements:

        • link: (optional) A render array that returns a link. See
      • template_preprocess_links() for details how it is generated.
        • text: The link text.
        • attributes: HTML attributes for the list item element.
        • text_attributes: (optional) HTML attributes for the span element if no
      • 'url' was supplied.`
    • Please register or sign in to reply
  • 50 className="SelectItem"
    51 disabled={option.disabled}
    52 >
    53 {option.label}
    54 </Select.Item>
    55 ))}
    56 </>
    57 )}
    58 </Select.Group>
    59 </Select.Content>
    60 </Select.Root>
    61 </div>
    62 );
    63 };
    64
    65 export default SelectComponent;
    • If you look at the existing components, you'll notice the export is wrapped in InputBehaviors

      For example export default inputBehaviors(Input); this is what makes it possible to manage values at the form level instead of the component level and update redux without having to add handlers to every new component.

    • Please register or sign in to reply
  • 18 initialSelection?: string;
    19 }
    20
    21 const SelectComponent: React.FC<SelectComponentProps> = ({
    22 attributes,
    23 options,
    24 renderOptions,
    25 initialSelection = 'none',
    26 }) => {
    27 const [selectedValue, setSelectedValue] = useState(initialSelection);
    28
    29 return (
    30 <div className="SelectWrapperDiv">
    31 <Select.Root
    32 value={selectedValue}
    33 onValueChange={(value) => setSelectedValue(value)}
    • Comment on lines +27 to +33

      Values aren't managed on a per-component basis, they are instead wrapped by InputBehaviors. See the existing components for how this is done.

      If there is a specific reason for component level state then it can ALSO be here, but we need to loop into the onChange setup in inputBehaviors

    • Please register or sign in to reply
  • 26 }) => {
    27 const [selectedValue, setSelectedValue] = useState(initialSelection);
    28
    29 return (
    30 <div className="SelectWrapperDiv">
    31 <Select.Root
    32 value={selectedValue}
    33 onValueChange={(value) => setSelectedValue(value)}
    34 {...a2p(attributes)}
    35 >
    36 <Select.Trigger className={clsx('selectTrigger')}>
    37 {selectedValue || 'Select an option'}
    38 </Select.Trigger>
    39 <Select.Content className={clsx('selectContent')}>
    40 <Select.Group>
    41 {renderOptions ? (
    • I think it would be great to leverage design tokens from Radix Themes in the form of CSS variables. A few examples:

      We may need to customize the Theme component to tweak some of the values. I think it's also a good idea to keep in mind that if we end up with a lot of CSS overrides, we should probably be using the unstyled Radix Primitive rather than the component from Radix Theme. Also when adding wrappers only for layout, let's use Box, Flex etc, so we can avoid adding paddings, margin etc. with custom CSS.

    • Please register or sign in to reply
  • Closing this in favor of !188 (merged).

  • Please register or sign in to reply
    Loading