Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NgxSvgSprite): add a directive for rendering symbols of svg sprites #219

Merged
merged 14 commits into from
Jan 10, 2024

Conversation

RobbyRabbitman
Copy link
Contributor

A directive for rendering symbols of svg sprites. It is done with the use element.

Import

import { NgxSvgSpriteFragment } from 'ngxtension/svg-sprite';

Usage

In this example the symbol github of the fontawesome svg sprite fa-brands is rendered. A symbol is identified by a fragment. Learn more about URLs.

<svg fragment="github" sprite="fa-brands"></svg>

Without NgxSvgSpriteFragment:

<svg viewBox="0 0 496 512">
	<use href="assets/fontawesome/sprites/brands.svg#github"></use>
</svg>

With Directive Composition Api

In your project you can utilize the Directive Composition Api to create specific svg sprites.

In this example a fontawesome brands svg sprite is created.

<svg faBrand="github"></svg>
@Directive({
	selector: 'svg[faBrand]',
	standalone: true,
	hostDirectives: [
		{ directive: NgxSvgSpriteFragment, inputs: ['fragment:faBrand'] },
	],
})
export class FaBrandSvg {
	constructor() {
		inject(NgxSvgSpriteFragment).sprite = 'fa-brands';
	}
}

Configuration

In order to render a symbol, sprites have to be provided.

provideSvgSprites(
	createSvgSprite({
		name: 'fa-brands',
		baseUrl: 'assets/fontawesome/sprites/brands.svg',
	}),
);

The name property can reference any arbitrary value, but should be unique, since you can register multiple different svg sprites.

The sprite input of the NgxSvgSpriteFragment should reference the name property of a provided sprite.

Auto View Box

When a symbol of an svg sprite is rendered the viewBox attribute or height and width should be set. The svg element does not copy/use the viewBox attribute of the symbol in the svg sprite, therefore the svg will have default dimensions of 300x150 px, which is probably not preferred.

Per default when an svg sprite is registered, the svg sprite is fetched with js in addition. NgxSvgSpriteFragment will copy the viewBox attribute of the symbol to its host.

This behavior can be disabled.

Disable via DI

Auto View Box is disabled for the svg sprite.

provideSvgSprites(
	createSvgSprite({
		name: 'fa-brands',
		baseUrl: 'assets/fontawesome/sprites/brands.svg',
		autoViewBox: false,
	}),
);

Disable via autoViewBoxDisabled Input

Auto View Box is disabled for a svg element, when the autoViewBoxDisabled input is set to false.

<svg fragment="github" sprite="fa-brands" autoViewBoxDisabled></svg>

Disable via viewBox Attribute

Auto View Box is disabled for a svg element, when the viewBox attribute already is defined.

<svg fragment="github" sprite="fa-brands" viewBox="0 0 32 32"></svg>

Classes

When the classes function is set, a list of classes will be added by the NgxSvgSpriteFragment to its host.

provideSvgSprites(
	createSvgSprite({
		name: 'my-sprite',
		baseUrl: 'path/to/my/sprite.svg',
		classes: (fragment) => ['some-class', `some-other-class-${fragment}`],
	}),
);

Url

Per default when using the createSvgSprite function, the url will return '${baseUrl}#${fragment}'. This can be overwritten:

provideSvgSprites(
	createSvgSprite({
		name: 'my-sprite',
		baseUrl: 'path/to/my/sprite.svg',
		url: (baseUrl, fragment) => `${baseUrl}#some-prefix-${fragment}`,
	}),
);

Copy link

nx-cloud bot commented Jan 9, 2024

☁️ Nx Cloud Report

CI is running/has finished running commands for commit d97625f. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this CI Pipeline Execution


⌛ The following targets are in progress

✅ Successfully ran 1 target

Sent with 💌 from NxCloud.

@RobbyRabbitman
Copy link
Contributor Author

@nartc Hello again, could you please review this feature and share your thoughts on the API 😄

@ajitzero
Copy link
Contributor

@RobbyRabbitman A general question: This doesn't need to be specific to fonticons/fontAwesome. Do you think we can make this configurable to accept any SVG file? We could also refactor to load the SVG file lazily on first use.

Thoughts?

@RobbyRabbitman
Copy link
Contributor Author

@ajitzero The configuration accepts any url. That means any svg can be used. The example shows fontawesome. I think the js fetch is already lazy, I should add test to verify that. The directive adds an use element, I don't know if the use element has a lazy loading feature like the img element. I will research that.

Copy link
Collaborator

@nartc nartc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contributions. Couple of nits and suggestions.

@RobbyRabbitman
Copy link
Contributor Author

Thank you for the review and your suggestions, I will refactor the code 😄

Robby Rabbitman and others added 5 commits January 10, 2024 22:13
@RobbyRabbitman RobbyRabbitman requested a review from nartc January 10, 2024 22:19
@nartc nartc merged commit c585aca into ngxtension:main Jan 10, 2024
5 checks passed
@RobbyRabbitman
Copy link
Contributor Author

@ajitzero I think possible solutions for lazy loading are Intersection Observers: You can even use Angulars new deferrable views to skip setting up the observers by yourself. Maybe like so:

@defer (on viewport) {
    <svg faBrand="github"></svg>
} @placeholder {
    <span>Some skeletton</span>
}

@RobbyRabbitman RobbyRabbitman deleted the feat/svg-sprite branch January 10, 2024 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants