Skip to content

Commit

Permalink
New: Add font family editor
Browse files Browse the repository at this point in the history
  • Loading branch information
jonnitto committed Dec 19, 2024
1 parent 9edd66d commit a700684
Show file tree
Hide file tree
Showing 17 changed files with 1,400 additions and 9 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
12 changes: 12 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"env": {
"es6": true,
"browser": true,
"node": true
}
}
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/.editorconfig export-ignore
/.eslintignore export-ignore
/.eslintrc export-ignore
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/.jshintrc
/.nvmrc export-ignore
/.prettierrc export-ignore
/config.json export-ignore
Expand Down
4 changes: 4 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"esversion": 6,
"asi": true
}
4 changes: 0 additions & 4 deletions Configuration/Settings.EelHelper.yaml

This file was deleted.

43 changes: 43 additions & 0 deletions Configuration/Settings.Neos.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Neos:
Fusion:
defaultContext:
Carbon.Webfonts: 'Carbon\Webfonts\EelHelper'
Neos:
userInterface:
translation:
autoInclude:
Carbon.Webfonts:
- 'Main'
Ui:
resources:
javascript:
Carbon.Webfonts:
resource: resource://Carbon.Webfonts/Public/Editor/Main.js
attributes:
type: 'module'
stylesheets:
Carbon.Webfonts:
resource: resource://Carbon.Webfonts/Public/Editor/Main.css

frontendConfiguration:
'Carbon.Webfonts.FontFamily':
disabled: false
readonly: false
allowEmpty: true
placeholder: ''
placeholderFont: false
# A path to a CSS file with @font-face declarations. Can be a resource:// or a http(s):// path
cssFile: false

# Sort the fonts by name
sortFonts: true

# Use the fonts from Carbon Webfonts
useCarbonWebfonts: true

# If set to false, only the font name is stored in the database
enableFallback: true
# Show icon if the font has a font file or a css file
showIcon: true
# List of available fonts
# fonts:
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

.DEFAULT_GOAL := production

## Clean build files
clean:
rm -rf Resources/Public/Editor

## Prettier files
prettier:
pnpm prettier --write --no-error-on-unmatched-pattern '**/*.{yaml,md,js,json}'
Expand All @@ -13,10 +17,21 @@ production: install prettier build
install:
pnpm install

## Watch for changes in JS and CSS files
watch:
make clean
pnpm watch

## Build production version
build:
make clean
pnpm build

## Build development version
dev:
make clean
pnpm dev

# Define colors
GREEN := $(shell tput -Txterm setaf 2)
YELLOW := $(shell tput -Txterm setaf 3)
Expand Down
58 changes: 57 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,63 @@ Neos:
# The fallback is automatically done by the group name, but if you want to override it, you can set it here
fallback: "Helvetica, sans-serif"
# If your font is a webfont, please add a css-file with all declartions in it. It has to be in the public folder
cssFile: resource://Vendor.Packages/Fonts/MyCustomFontName.css
cssFile: resource://Vendor.Package/Fonts/MyCustomFontName.css
```
This setting can also be added on a per property basis:
```yaml
Vendor.Package:Mixin.FontFamily:
properties:
type: string
ui:
inspector:
editor: "Carbon.Webfonts/FontFamily"
editorOptions:
allowEmpty:
true
# Set this to an object just like a font value to use a placeholder font
# It takes the same values as a font value, but adding the needed name
placeholderFont:
name: "Open Sans"
fallback: "Helvetica, Arial, sans-serif"
# A path to a CSS file with @font-face declarations.
# Can be a resource:// or a http(s):// path
cssFile: false
# This disables the fonts from this package
useCarbonWebfonts: false
# If set to false, only the font name is stored in the database
enableFallback: true
fonts:
Alumni Sans:
# Sets properties for showing in the editor preview. Does not affect saved value.
# defaults to fontWeight: 400 and fontStyle: normal
display:
fontWeight: 500
fontStyle: italic
group: Sans Serif
cssFile: resource://Vendor.Package/Fonts/Alumni-Sans.css
fontWeight: 100 900
fallback:
ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto
Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji'
Atkinson Hyperlegible:
group: Sans Serif
cssFile: resource://Vendor.Package/Fonts/Atkinson-Hyperlegible.css
fontWeight:
- 400
- 700
fallback:
ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto
Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji'
Impact:
group: Sans Serif
fontWeight:
- 400
- 700
fallback:
ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto
Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji'
```
[packagist]: https://packagist.org/packages/carbon/webfonts
Expand Down
89 changes: 89 additions & 0 deletions Resources/Private/Editor/FontFamily/Helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
function getFilePath(file) {
if (!file || typeof file !== "string") {
return null;
}
if (file.startsWith("resource://")) {
return file.replace("resource://", "/_Resources/Static/Packages/");
}
return file;
}

export function injectStylesheet(file) {
const href = getFilePath(file);
if (!href || document.querySelector(`link[href="${href}"]`)) {
return null;
}
const head = document.head;
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = href;
head.appendChild(link);
}

function determineFontType(fallback, group) {
if (group) {
if (group === "Sans Serif") return "sans-serif";
return group.toLowerCase();
}
if (fallback.includes("sans-serif")) return "sans-serif";
if (fallback.includes("serif")) return "serif";
if (fallback.includes("monospace")) return "monospace";
if (fallback.includes("cursive")) return "cursive";
if (fallback.includes("fantasy")) return "fantasy";
return "sans-serif";
}

export function beautifyFontOutput(string) {
if (!string || typeof string !== "string") {
return "";
}
return string.replaceAll("'", "").replaceAll('"', "").replaceAll(",", ", ").replaceAll(" ", " ").trim();
}

function generateFontObject(key, item, enableFallback) {
const label = beautifyFontOutput(item.label || key);
const fallbackValue = item.fallback || "";
const fallback = beautifyFontOutput(fallbackValue);
const type = determineFontType(fallback, item.group);
const cssFile = item.cssFile === true ? true : getFilePath(item.cssFile);
const value = `${key}${enableFallback && fallbackValue ? `,${fallbackValue}` : ""}`;
const fontStyle = item?.display?.fontStyle || "normal";
const fontWeight = item?.display?.fontWeight || 400;

if (typeof cssFile === "string") {
injectStylesheet(cssFile);
}

return { label, fallback, fontStyle, fontWeight, cssFile, value, type };
}

export function getFontCollection(fonts, enableFallback, placeholderFont, sortFonts) {
const object = {
fonts: {},
flat: {},
};
if (placeholderFont && placeholderFont.name) {
generateFontObject(placeholderFont.name, placeholderFont, enableFallback);
}
for (const key in fonts) {
const item = fonts[key];
if (!item) {
continue;
}
const { type, ...result } = generateFontObject(key, item, enableFallback);

if (!object.fonts[type]) {
object.fonts[type] = {};
}
object.flat[key] = result;
object.fonts[type][key] = result;
}
if (sortFonts) {
for (const type in object.fonts) {
object.fonts[type] = Object.fromEntries(
Object.entries(object.fonts[type]).sort(([, a], [, b]) => a.label.localeCompare(b.label)),
);
}
}
return object;
}
Loading

0 comments on commit a700684

Please sign in to comment.