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: Add support for LESS asset type #11

Merged
merged 2 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Options:
-o, --output <value> specify output directory
-n, --name <value> base name of the font set used both as default asset name (default: icons)
-t, --font-types <value...> specify font formats to generate (default: eot, woff2, woff, available: eot, woff2, woff, ttf, svg)
-g --asset-types <value...> specify other asset types to generate (default: css, html, json, ts, available: css, scss, sass, html, json, ts)
-g --asset-types <value...> specify other asset types to generate (default: css, html, json, ts, available: css, less, scss, sass, html, json, ts)
-h, --font-height <value> the output font height (icons will be scaled so the highest has this height) (default: 300)
--descent <value> the font descent
--normalize [bool] normalize icons by scaling them to the height of the highest icon
Expand Down
1 change: 1 addition & 0 deletions src/core/__tests__/config-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const mockConfig = {
fontsUrl: '/fonts',
templates: {
css: 'css',
less: 'less',
sass: 'sass',
scss: 'scss',
html: 'html'
Expand Down
61 changes: 61 additions & 0 deletions src/generators/asset-types/__tests__/__snapshots__/less.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`\`LESS\` asset generator renders LESS correctly with \`selector\` option 1`] = `
"@test-font: "test";

@font-face {
font-display: block;
font-family: @test-font;
src: "::src-attr::";
}

.my-selector::before {
font-family: test !important;
font-style: normal;
font-weight: normal !important;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

@test-map: {
my-icon: "\\f101";
}

.my-selector.tf-my-icon::before {
content: @test-map[my-icon];
}
"
`;

exports[`\`LESS\` asset generator renders LESS correctly with prefix and tag name options 1`] = `
"@test-font: "test";

@font-face {
font-display: block;
font-family: @test-font;
src: "::src-attr::";
}

b[class^="tf-"]::before, b[class*=" tf-"]::before {
font-family: test !important;
font-style: normal;
font-weight: normal !important;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

@test-map: {
my-icon: "\\f101";
}

.tf-my-icon::before {
content: @test-map[my-icon];
}
"
`;
77 changes: 77 additions & 0 deletions src/generators/asset-types/__tests__/less.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import lessGen from '../less';
import { renderSrcAttribute } from '../../../utils/css';
import { resolve } from 'path';

const renderSrcMock = renderSrcAttribute as any as jest.Mock;

const mockOptions = {
name: 'test',
prefix: 'tf',
tag: 'b',
codepoints: { 'my-icon': 0xf101 },
assets: { 'my-icon': null },
templates: {
less: resolve(__dirname, '../../../../templates/less.hbs')
}
} as any;

jest.mock('../../../utils/css', () => ({
renderSrcAttribute: jest.fn(() => '"::src-attr::"')
}));

describe('`LESS` asset generator', () => {
beforeEach(() => {
renderSrcMock.mockClear();
});

test('renders LESS correctly with prefix and tag name options', async () => {
expect(
await lessGen.generate(mockOptions, Buffer.from(''))
).toMatchSnapshot();
});

test('renders LESS correctly with `selector` option', async () => {
expect(
await lessGen.generate(
{ ...mockOptions, selector: '.my-selector' },
Buffer.from('')
)
).toMatchSnapshot();
});

test('calls renderSrcAttribute correctly and includes its return value in the rendered template', async () => {
const fontBuffer = Buffer.from('::svg-content::');

const result = await lessGen.generate(mockOptions, fontBuffer);

expect(renderSrcMock).toHaveBeenCalledTimes(1);
expect(renderSrcMock).toHaveBeenCalledWith(mockOptions, fontBuffer);
expect(result).toContain('::src-attr::');
});

test('renders expected selector blocks', async () => {
const less = await lessGen.generate(mockOptions, Buffer.from(''));

expect(less).toContain(
'b[class^="tf-"]::before, b[class*=" tf-"]::before {'
);
expect(less).toContain('.tf-my-icon::before {');
});

test('renders expected variables', async () => {
const less = await lessGen.generate(mockOptions, Buffer.from(''));

expect(less).toContain('@test-font:');
expect(less).toContain('@test-map:');
});

test('renders expected selector blocks with `selector` option', async () => {
const less = await lessGen.generate(
{ ...mockOptions, selector: '.my-selector' },
Buffer.from('')
);

expect(less).toContain('.my-selector::before {');
expect(less).toContain('.my-selector.tf-my-icon::before {');
});
});
2 changes: 2 additions & 0 deletions src/generators/asset-types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import css from './css';
import html from './html';
import json from './json';
import ts from './ts';
import less from './less';
import sass from './sass';
import scss from './scss';

Expand All @@ -22,6 +23,7 @@ const generators: { [key in AssetType]: FontGenerator<any> } = {
[OtherAssetType.HTML]: html,
[OtherAssetType.JSON]: json,
[OtherAssetType.TS]: ts,
[OtherAssetType.LESS]: less,
[OtherAssetType.SASS]: sass,
[OtherAssetType.SCSS]: scss
};
Expand Down
17 changes: 17 additions & 0 deletions src/generators/asset-types/less.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FontGenerator } from '../../types/generator';
import { FontAssetType } from '../../types/misc';
import { renderTemplate } from '../../utils/template';
import { renderSrcAttribute } from '../../utils/css';

const generator: FontGenerator<Buffer> = {
dependsOn: FontAssetType.SVG,

generate: (options, svg: Buffer) =>
renderTemplate(
options.templates.less,
{ ...options, fontSrc: renderSrcAttribute(options, svg) },
{ helpers: { codepoint: str => str.toString(16) } }
)
};

export default generator;
2 changes: 2 additions & 0 deletions src/types/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export enum FontAssetType {

export enum OtherAssetType {
CSS = 'css',
LESS = 'less',
SCSS = 'scss',
SASS = 'sass',
HTML = 'html',
Expand All @@ -18,6 +19,7 @@ export enum OtherAssetType {
export const ASSET_TYPES_WITH_TEMPLATE = [
OtherAssetType.CSS,
OtherAssetType.HTML,
OtherAssetType.LESS,
OtherAssetType.SCSS,
OtherAssetType.SASS
];
Expand Down
38 changes: 38 additions & 0 deletions templates/less.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@{{ name }}-font: "{{ name }}";

@font-face {
font-display: block;
font-family: @{{ name }}-font;
src: {{{ fontSrc }}};
}

{{# if selector }}
{{ selector }}::before {
{{ else }}
{{ tag }}[class^="{{prefix}}-"]::before, {{ tag }}[class*=" {{prefix}}-"]::before {
{{/ if }}
font-family: {{ name }} !important;
font-style: normal;
font-weight: normal !important;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

@{{ name }}-map: {
{{# each codepoints }}
{{ @key }}: "\\{{ codepoint this }}";
{{/ each }}
}

{{# each codepoints }}
{{# if ../selector }}
{{ ../selector }}.{{ ../prefix }}-{{ @key }}::before {
{{ else }}
{{ tag }}.{{ ../prefix }}-{{ @key }}::before {
{{/ if }}
content: @{{ ../name }}-map[{{ @key }}];
}
{{/ each }}