elegantthemes / Divi-Beta

8 stars 0 forks source link

Child module props in Parent module styles.tsx component. #19

Open dtcblyth opened 1 year ago

dtcblyth commented 1 year ago

Related Thread: https://discord.com/channels/1041765492907589683/1090150687339454514

Feature Request:

I would like to request that the ChildModules object (and its properties) be made available to the parent-module’s styles.tsx component. The ChildModules object and properties are currently accessible in the parent-module’s edit.tsx component. This makes it possible for developers to modify the parent’s HTML based on conditions like the number of child-modules and properties within them. However, while we can modify the parent element’s HTML, we can not modify the parent’s Styles based on the same conditions! There seems no good reason (to me) why the parent’s HTML-renderer is able to access the child-module properties but style-renderer can not.

Background:

Below is a concrete example of why this is important to me, and specifically to my product, Table Maker.

Table Maker works similarly to Divi’s own Pricing Table module. In Table Maker, the parent-module represents the table, child-modules represent the table-columns, and individual line-breaks in the child-module’s content field represent the table-rows.

However, unlike the Pricing Table module, Table Maker’s columns, rows and cells are not seperate entities, they are elements and properties of the table. The table (ie. parent-module) needs to know how many columns and rows it has, and each column must have the same number of rows.

The parent-module gets the column-count from the child-module array-count, and it get’s the row-count by looping over the child-modules and finding which one has the largest number of rows. It then uses the col-count and row-count to generate table columns, rows and cells, as well as ARIA tags and other things which are attributes of the parent.

From the CSS side of things, Table Maker uses CSS Grid to layout the table. The grid-template-columns property (which visually determines the table’s appearance) uses the column and row count, and also uses minmax values from each child-module to set minimum and maximum sizes for the table’s column and rows .

For example, a four column table’sgrid-template-columns property may look like this: grid-template-columns: minmax(150px,2fr) minmax(100px,1fr) minmax(100px,1fr) minmax(50px,50px);

This CSS property must be applied to the parent element, and the values which it depends on can only be calculated by processing properties from all child-modules. To me, the easiest and most logical place to do that is from within the parent-module’s style rendering functions.

Current Solutions:

All of the above can currently be done within the D4 and D5 React component render functions because they do have access to the child-module props. However, the PHP render function and React style functions can not access the child-module props and therefore currently require some hacky solutions to get around these limitations:

1) In the Visual Builder, I build my own responsive styles array within the parent’s React component render() function, and I output those styles as an inline <style /> element from the React component render() function.

2) On the front-end, I use the parent-module’s before_render() function to setup global variables which can be used by the child-module’s to share their properties with the parent-module’s render() function. (I learnt this technique from Jan Thielemann of Divi Sensei)

Neither of these solutions are ideal but they work. Things would be much, much easier if all rendering functions had access to the child-module props!

Final Words:

While the example above is very specific to my needs, it’s not hard to imagine other modules that may need to modify the parent element based on properties of its child-modules. For example, even a simple gallery slider may wish to modify its HTML structure and CSS styling depending on whether the user were to select 3 or 300 images.

Finally, regardless of the examples above, clearly at some point in Divi’s development it was considered appropriate and necessary to provide child-module properties to the React component render() function. This was done in D4 and has been replicated in D5. To me, it seems like an oversight not to provide the same properties to the style renderer, and one which leads to hacky solutions to overcome this arbitrary limitation.

MTaimoor79 commented 2 months ago

@fikrirasyid , Please provide an update on this feature. I need it for my plugin as well.