Skip to content

Clarify documentation around svg fragments in templates #40916

@baarney

Description

@baarney

📚 Docs or angular.io bug report

Description

The Angular guide contains a section on how to use svg elements in templates, but this only deals with "complete" elements which include the base tag.

It is also useful to define components which render svg fragments within an existing parent svg element, which is not covered in the current docs. These only appear to work if the elements are prefixed with an (undefined?) "svg" namespace prefix.

Please update the docs to:

  • Clarify if this is working as intended, or is just a by-product of the implementation which just happens to work.
  • Include a similar example.

🔬 Minimal Reproduction

Full Example

https://stackblitz.com/edit/angular-ivy-5schxp

What's the affected URL?

https://angular.io/guide/svg-in-templates

Reproduction Steps

// app.component.ts
interface SvgRect {
  x: number;
  y: number;
  text: string;
}
export class AppComponent  {
  rects: SvgRect[];
}
<!-- app.component.html -->
<!-- create a separate g for each rect -->
<svg width="200" height="100">
  <g svgRect *ngFor='let rect of rects' [rect]="rect"></g>
</svg>
// svg-rect.component.ts
@Component({
  selector: '[svgRect]',
  template: `
      <rect
          [attr.x]="rect.x" [attr.y]="rect.y" width="80" height="30"
          stroke="black" stroke-width="1" fill="transparent"></rect>
      <text
          [attr.x]="rect.x + 40" [attr.y]="rect.y + 15"
          dominant-baseline="middle" text-anchor="middle">{{rect.text}}</text>
  `,
  styles: []
})
export class SvgRectComponent  {
  @Input() rect: SvgRect;
}

This template as written does not render anything, although inspecting the underlying html looks ok. Following the advice in this SO issue, adding the "svg" namespace prefix to the component template elements does render correctly:

  template: `
      <svg:rect
          [attr.x]="rect.x" [attr.y]="rect.y" width="80" height="30"
          stroke="black" stroke-width="1" fill="transparent"></rect>
      <svg:text
          [attr.x]="rect.x + 40" [attr.y]="rect.y + 15"
          dominant-baseline="middle" text-anchor="middle">{{rect.text}}</text>
  `,

Would also be good to clarify whether the selector should include the svg namespace if restricted to a specific element:

  selector: 'g[svgRect]',
  selector: 'svn:g[svgRect]',

Thanks

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgentarea: docsRelated to the documentationcross-cutting: SVG

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions