Pass arbitrary SVG icon to Pug mixin without "block"

Viewed 232

Targets

  1. Message box must be the component with icon and arbitrary content, like paragraphs, lists, etc. The reason of 'without "block"' in the title of this question is block is being already used inside .AttentionBox-MainSection.
  2. There is the default SVG icon in component, however it must could be substituted with arbitrary custom SVG icon.
mixin AttentionBox(propertiesObject)
 
  - const {
    customIcon
  } = propertiesObject

  .AttentionBox

    if !customIcon
      svg.AttentionBox-Icon(viewBox="0 0 24 24")
        path(d="M5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3M13,13V7H11V13H13M13,17V15H11V17H13Z")
      else 
        //- ???
    
      .AttentionBox-MainSection
        block //- arbitrary content

Difficulties

I learned that basically no way to store pug mixin execution result to variable. There is only hacky way to do it, but it looks like make a big impact to performance (even for pre-processing before deploying), non-intuitive and make the code hard to read. Too expensive price.

There is a way to emulate the slots in Pug. However, it have the tangible limitations:

  1. Nested mixin-components with slots are not supported because slots variable will be overridden. E. g. if we want to use the AttentionBox inside modal from the link - maybe there will not be a pug compilation error, however there will not the the expected output too.
  2. The slots could be used only after block.

Unsatisfying solutions

  1. Pass svg's path's attribute d value as mixin parameter: works for single-path svg icons, but svg tag content is unknown in advance (could be multiple paths, circles etc.)
  2. Pass icon html code as mixin parameter: we should to avoid to write the HTML in Pug, but also the icon could the another pug mixin.
  3. Using switch/case like this:
case:
  when Icons.info
    +Icon-Info
  when Icons.warning
    +Icon-Info

The custom icon is arbitrary, in could be not among Icons.

Other example

In below DropdownSelect component, block is being used for option list. What if user wants to use custom SVG icon?

mixin DropdownSelect(parametersObject)
    
  -
    const {
      currentSelectionText,
      nothingSelectedText = "select please ...",
      customIcon
    } = parametersObject

  .DropdownSelect
    div.DropdownSelect-CurrentSelectionView(
      role="button"
      aria-haspopup="listbox"
    )= currentSelectionText || nothingSelectedText
      if !customIcon
          svg.DropdownSelect-Icon(
            viewBox="0 0 24 24"
          ): path(d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z")
        else 
            // ??
      if block
        .DropdownSelect-OptionsList(
          role="list"
          aria-expanded="true"
          tabindex="-1"
        )
          block
0 Answers
Related