JSFiddle - React, Tailwind, and code Playground

by Haze32

HTML

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" />


 <!-- Examples with default and class-based settings -->
  <div>
    <span class="dpwicon dpwicon-home">
      <span>This is all default (24px, black, left, 5px margin)</span>
    </span>
  </div>
  <div>
    <span class="dpwicon dpwicon-toggle_on dpwicon-position-left dpwicon-size-16 dpwicon-color-navy dpwicon-line-height-18 dpwicon-variation-FILL_1">
      <span>16px navy toggle_on, filled, 18px line-height, left</span>
    </span>
  </div>
  <div>
    <span class="dpwicon dpwicon-settings dpwicon-position-right dpwicon-size-20 dpwicon-color-mint dpwicon-line-height-22 dpwicon-variation-wght_500_GRAD_50">
      <span>20px mint settings, weight 500, grad 50, 22px line-height, right</span>
    </span>
  </div>
  <div>
    <span class="dpwicon dpwicon-star dpwicon-size-40 dpwicon-color-800080 dpwicon-line-height-36 dpwicon-variation-FILL_0_opsz_48">
      <span>40px purple star, unfilled, opsz 48, 36px line-height, left</span>
    </span>
  </div>
  <div>
    <span class="dpwicon dpwicon-home dpwicon-position-right dpwicon-size-18 dpwicon-color-red">
      <span>18px red home, default line-height, right</span>
    </span>
  </div>

CSS

/* Base styles for icon elements */
    .dpwicon {
      position: relative;
      display: inline-flex; /* Use flex for vertical alignment and text wrapping */
      align-items: center; /* Vertically center icon and text */
      vertical-align: middle;
      min-height: 24px; /* Default minimum height */
    }
    /* Default icon size and spacing for both :before and :after */
    .dpwicon::before,
    .dpwicon::after {
      font-size: 24px; /* Default icon size */
      line-height: 24px; /* Default line-height */
      display: inline-block;
      width: 24px;
      height: 24px;
      margin-right: 5px; /* Default spacing for left-positioned icons */
    }
    /* Icon on the right */
    .dpwicon-position-right::after {
      margin-left: 5px; /* Space between text and icon */
      margin-right: 0; /* Override default margin-right */
    }
    /* Ensure text wraps correctly */
    .dpwicon > span {
      display: inline;
    }

JavaScript

// Predefined color map
    const predefinedColors = {
      navy: '#060080',
      blue: '#140be3',
      azure: '#0592ff',
      sky: '#99d6ff',
      aqua: '#4eeaee',
      mint: '#02cfa3',
      white: '#fff',
      'light-gray': '#ccc',
      'dark-gray': '#333',
      red: '#ff033f'
    };

    // Find all elements with class "dpwicon"
    document.querySelectorAll('.dpwicon').forEach(element => {
      // Get all classes of the element
      const classes = element.className.split(' ');
      // Find the class that starts with "dpwicon-" for the icon name
      const iconClass = classes.find(cls => cls.startsWith('dpwicon-') && !cls.startsWith('dpwicon-position-') && !cls.startsWith('dpwicon-size-') && !cls.startsWith('dpwicon-color-') && !cls.startsWith('dpwicon-line-height-') && !cls.startsWith('dpwicon-variation-'));
      if (iconClass) {
        // Extract the icon name after "dpwicon-"
        const iconName = iconClass.replace('dpwicon-', '');
        // Get settings from classes
        const position = classes.includes('dpwicon-position-right') ? 'right' : 'left';
        const pseudo = position === 'right' ? 'after' : 'before';
        const sizeClass = classes.find(cls => cls.startsWith('dpwicon-size-'));
        const customSize = sizeClass ? parseInt(sizeClass.replace('dpwicon-size-', ''), 10) : null;
        const colorClass = classes.find(cls => cls.startsWith('dpwicon-color-'));
        const rawColor = colorClass ? colorClass.replace('dpwicon-color-', '') : null;
        const customColor = rawColor ? (predefinedColors[rawColor] || (rawColor.match(/^[0-9A-Fa-f]{6}$/) ? `#${rawColor}` : null)) : null;
        const lineHeightClass = classes.find(cls => cls.startsWith('dpwicon-line-height-'));
        const customLineHeight = lineHeightClass ? parseInt(lineHeightClass.replace('dpwicon-line-height-', ''), 10) : null;
        const variationClass = classes.find(cls => cls.startsWith('dpwicon-variation-'));
   ...