Repository: mermaid-js/mermaid
File: packages/mermaid/src/diagrams/class/shapeUtil.ts (TypeScript)

Code before:
  membersGroup.attr(
    'transform',
    `translate(${0}, ${annotationGroupHeight + labelGroupHeight + GAP * 2})`
  );
  bbox = shapeSvg.node()!.getBBox();
  methodsGroup.attr(
    'transform',
    `translate(${0}, ${annotationGroupHeight + labelGroupHeight + (membersGroupHeight ? membersGroupHeight + GAP * 4 : GAP * 2)})`
  );

  bbox = shapeSvg.node()!.getBBox();

  return { shapeSvg, bbox };
}

// Modified version of labelHelper() to help create and place text for classes
async function addText<T extends SVGGraphicsElement>(
  parentGroup: D3Selection<T>,
  node: Node | ClassNode | ClassMember,
  yOffset: number,
  styles: string[] = []
) {
  const textEl = parentGroup.insert('g').attr('class', 'label').attr('style', styles.join('; '));
  const config = getConfig();
  let useHtmlLabels =
    'useHtmlLabels' in node ? node.useHtmlLabels : evaluate(config.htmlLabels ?? undefined) || true;

  let textContent = '';
  // Support regular node type (.label) and classNodes (.text)
  if ('text' in node) {
    textContent = node.text;
  } else {
    textContent = node.label!;
  }

  // createText() will cause unwanted behavior because of classDiagram syntax so workarounds are needed

  if (!useHtmlLabels && textContent.startsWith('\\')) {
    textContent = textContent.substring(1);
  }

  if (hasKatex(textContent)) {
    useHtmlLabels = true;
  }

  const text = await createText(
    textEl,
    sanitizeText(decodeEntities(textContent)),
    {
      width: calculateTextWidth(textContent, config) + 50, // Add room for error when splitting text into multiple lines
      classes: 'markdown-node-label',

Review comment (suggestion):
**issue(blocking)**: `anything || true` is `true`. Test out the following:

Try:

````markdown
```mermaid
---
config:
    htmlLabels: false
---
classDiagram
    Animal <|-- Duck
    Animal <|-- Fish
    Animal <|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
      +String beakColor
      +swim()
      +quack()
    }
    class Fish{
      -int sizeInFeet
      -canEat()
    }
    class Zebra{
      +bool is_wild
      +run()
    }
```
````

Code after:
  membersGroup.attr(
    'transform',
    `translate(${0}, ${annotationGroupHeight + labelGroupHeight + GAP * 2})`
  );
  bbox = shapeSvg.node()!.getBBox();
  methodsGroup.attr(
    'transform',
    `translate(${0}, ${annotationGroupHeight + labelGroupHeight + (membersGroupHeight ? membersGroupHeight + GAP * 4 : GAP * 2)})`
  );

  bbox = shapeSvg.node()!.getBBox();

  return { shapeSvg, bbox };
}

// Modified version of labelHelper() to help create and place text for classes
async function addText<T extends SVGGraphicsElement>(
  parentGroup: D3Selection<T>,
  node: Node | ClassNode | ClassMember,
  yOffset: number,
  styles: string[] = []
) {
  const textEl = parentGroup.insert('g').attr('class', 'label').attr('style', styles.join('; '));
  const config = getConfig();
  let useHtmlLabels =
    'useHtmlLabels' in node ? node.useHtmlLabels : (evaluate(config.htmlLabels) ?? true);

  let textContent = '';
  // Support regular node type (.label) and classNodes (.text)
  if ('text' in node) {
    textContent = node.text;
  } else {
    textContent = node.label!;
  }

  // createText() will cause unwanted behavior because of classDiagram syntax so workarounds are needed

  if (!useHtmlLabels && textContent.startsWith('\\')) {
    textContent = textContent.substring(1);
  }

  if (hasKatex(textContent)) {
    useHtmlLabels = true;
  }

  const text = await createText(
    textEl,
    sanitizeText(decodeEntities(textContent)),
    {
      width: calculateTextWidth(textContent, config) + 50, // Add room for error when splitting text into multiple lines
      classes: 'markdown-node-label',