Skip to content

Commit

Permalink
Add test for local src
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeltaranto committed Apr 17, 2024
1 parent efa4229 commit 568498c
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 9 deletions.
123 changes: 123 additions & 0 deletions packages/core/src/createFontStack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,4 +503,127 @@ describe('createFontStack', () => {
`);
});
});

describe('local sources', () => {
it('with a familyName only provided', () => {
const { fontFaces } = createFontStack(
[merriweatherSans, { ...arial, familyName: 'Arial Family Name' }],
{ fontFaceFormat: 'styleObject' },
);

expect(fontFaces[0]['@font-face'].src).toBe(`local('Arial Family Name')`);
});

it('with a fullName provided', () => {
const { fontFaces } = createFontStack(
[merriweatherSans, { ...arial, fullName: 'Arial Full Name' }],
{ fontFaceFormat: 'styleObject' },
);

expect(fontFaces[0]['@font-face'].src).toBe(`local('Arial Full Name')`);
});

it('with a fullName and familyName provided', () => {
const { fontFaces } = createFontStack(
[
merriweatherSans,
{
...arial,
familyName: 'Arial Family Name',
fullName: 'Arial Full Name',
},
],
{ fontFaceFormat: 'styleObject' },
);

expect(fontFaces[0]['@font-face'].src).toBe(`local('Arial Full Name')`);
});

it('with a postscriptName provided', () => {
const { fontFaces } = createFontStack(
[
merriweatherSans,
{ ...arial, postscriptName: 'Arial Postscript Name' },
],
{ fontFaceFormat: 'styleObject' },
);

expect(fontFaces[0]['@font-face'].src).toBe(
`local('Arial Postscript Name')`,
);
});

it('with a postscriptName and familyName provided', () => {
const { fontFaces } = createFontStack(
[
merriweatherSans,
{
...arial,
familyName: 'Arial Family Name',
postscriptName: 'Arial Postscript Name',
},
],
{ fontFaceFormat: 'styleObject' },
);

expect(fontFaces[0]['@font-face'].src).toBe(
`local('Arial Postscript Name')`,
);
});

it('with both fullName and postscriptName provided', () => {
const { fontFaces } = createFontStack(
[
merriweatherSans,
{
...arial,
fullName: 'Arial Full Name',
postscriptName: 'Arial Postscript Name',
},
],
{ fontFaceFormat: 'styleObject' },
);

expect(fontFaces[0]['@font-face'].src).toBe(
`local('Arial Full Name'), local('Arial Postscript Name')`,
);
});

it('with both fullName and postscriptName provided', () => {
const { fontFaces } = createFontStack(
[
merriweatherSans,
{
...arial,
fullName: 'Arial Full Name',
postscriptName: 'Arial Postscript Name',
},
],
{ fontFaceFormat: 'styleObject' },
);

expect(fontFaces[0]['@font-face'].src).toBe(
`local('Arial Full Name'), local('Arial Postscript Name')`,
);
});

it('with all names provided', () => {
const { fontFaces } = createFontStack(
[
merriweatherSans,
{
...arial,
familyName: 'Arial Family Name',
fullName: 'Arial Full Name',
postscriptName: 'Arial Postscript Name',
},
],
{ fontFaceFormat: 'styleObject' },
);

expect(fontFaces[0]['@font-face'].src).toBe(
`local('Arial Full Name'), local('Arial Postscript Name')`,
);
});
});
});
39 changes: 30 additions & 9 deletions packages/core/src/createFontStack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ export const toCssProperty = (property: string) =>
property.replace(/([A-Z])/g, (property) => `-${property.toLowerCase()}`);

type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
/*
Making `fullName` and `postscriptName` optional for the `createFontStack` API.
MDN recommends using these when accessing local fonts for to ensure the best
matching across platforms. This also enables selecting a single font face
within a larger family, e.g. `Arial Bold` or `Arial-BoldMT` within `Arial`.
See MDN for details: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src#localfont-face-name
Falling back to `familyName` (original behaviour) if these are not available.
This works, but will default to the `regular` font face within the family.
*/
type FontStackMetrics = Optional<
Pick<
FontMetrics,
Expand All @@ -24,6 +35,24 @@ type FontStackMetrics = Optional<
'fullName' | 'postscriptName'
>;

const resolveLocalFallbackSource = (metrics: FontStackMetrics) => {
const sources: string[] = [];

if (metrics.fullName) {
sources.push(`local('${metrics.fullName}')`);
}

if (metrics.postscriptName) {
sources.push(`local('${metrics.postscriptName}')`);
}

if (sources.length > 0) {
return sources.join(', ');
}

return `local('${metrics.familyName}')`;
};

// Support old metrics pre-`subsets` alongside the newer core package with `subset` support.
const resolveXWidthAvg = (
metrics: FontStackMetrics,
Expand Down Expand Up @@ -231,15 +260,7 @@ export function createFontStack(
'@font-face': {
...fontFaceProperties,
fontFamily,
src: [
fallback.fullName ? `local('${fallback.fullName}')` : '',
fallback.postscriptName ? `local('${fallback.postscriptName}')` : '',
!fallback.fullName && !fallback.postscriptName
? `local('${fallback.familyName}')`
: '',
]
.filter(Boolean)
.join(', '),
src: resolveLocalFallbackSource(fallback),
...calculateOverrideValues({
metrics,
fallbackMetrics: fallback,
Expand Down

0 comments on commit 568498c

Please sign in to comment.