Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>pull/55432/head
parent
f3383f9f90
commit
da5e27917f
@ -0,0 +1,381 @@ |
||||
/** |
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
import { readFileSync, writeFileSync} from 'node:fs' |
||||
import { join, resolve } from 'node:path' |
||||
import { compileString } from 'sass' |
||||
|
||||
const IMAGE_PATH = resolve(import.meta.dirname, '../core/img') |
||||
|
||||
const colors = { |
||||
dark: '000', |
||||
white: 'fff', |
||||
// gold but for backwards compatibility called yellow
|
||||
yellow: 'a08b00', |
||||
red: 'e9322d', |
||||
orange: 'eca700', |
||||
green: '46ba61', |
||||
grey: '969696', |
||||
} |
||||
|
||||
const variables = {} |
||||
const icons = { |
||||
add: join(IMAGE_PATH, 'actions', 'add.svg'), |
||||
address: join(IMAGE_PATH, 'actions', 'address.svg'), |
||||
'alert-outline': join(IMAGE_PATH, 'actions', 'alert-outline.svg'), |
||||
'audio-off': join(IMAGE_PATH, 'actions', 'audio-off.svg'), |
||||
audio: join(IMAGE_PATH, 'actions', 'audio.svg'), |
||||
calendar: join(IMAGE_PATH, 'places', 'calendar.svg'), |
||||
caret: join(IMAGE_PATH, 'actions', 'caret.svg'), |
||||
'category-app-bundles': join(IMAGE_PATH, 'categories', 'bundles.svg'), |
||||
'category-auth': join(IMAGE_PATH, 'categories', 'auth.svg'), |
||||
'category-customization': join(IMAGE_PATH, 'categories', 'customization.svg'), |
||||
'category-dashboard': join(IMAGE_PATH, 'categories', 'dashboard.svg'), |
||||
'category-files': join(IMAGE_PATH, 'categories', 'files.svg'), |
||||
'category-games': join(IMAGE_PATH, 'categories', 'games.svg'), |
||||
'category-integration': join(IMAGE_PATH, 'categories', 'integration.svg'), |
||||
'category-monitoring': join(IMAGE_PATH, 'categories', 'monitoring.svg'), |
||||
'category-multimedia': join(IMAGE_PATH, 'categories', 'multimedia.svg'), |
||||
'category-office': join(IMAGE_PATH, 'categories', 'office.svg'), |
||||
'category-organization': join(IMAGE_PATH, 'categories', 'organization.svg'), |
||||
'category-social': join(IMAGE_PATH, 'categories', 'social.svg'), |
||||
'category-workflow': join(IMAGE_PATH, 'categories', 'workflow.svg'), |
||||
change: join(IMAGE_PATH, 'actions', 'change.svg'), |
||||
checkmark: join(IMAGE_PATH, 'actions', 'checkmark.svg'), |
||||
circles: join(IMAGE_PATH, 'apps', 'circles.svg'), |
||||
clippy: join(IMAGE_PATH, 'actions', 'clippy.svg'), |
||||
close: join(IMAGE_PATH, 'actions', 'close.svg'), |
||||
comment: join(IMAGE_PATH, 'actions', 'comment.svg'), |
||||
'confirm-fade': join(IMAGE_PATH, 'actions', 'confirm-fade.svg'), |
||||
confirm: join(IMAGE_PATH, 'actions', 'confirm.svg'), |
||||
contacts: join(IMAGE_PATH, 'places', 'contacts.svg'), |
||||
delete: join(IMAGE_PATH, 'actions', 'delete.svg'), |
||||
desktop: join(IMAGE_PATH, 'clients', 'desktop.svg'), |
||||
details: join(IMAGE_PATH, 'actions', 'details.svg'), |
||||
'disabled-user': join(IMAGE_PATH, 'actions', 'disabled-user.svg'), |
||||
'disabled-users': join(IMAGE_PATH, 'actions', 'disabled-users.svg'), |
||||
download: join(IMAGE_PATH, 'actions', 'download.svg'), |
||||
edit: join(IMAGE_PATH, 'actions', 'edit.svg'), |
||||
encryption: resolve(import.meta.dirname, '../apps/files_external/img', 'app.svg'), |
||||
error: join(IMAGE_PATH, 'actions', 'error.svg'), |
||||
external: join(IMAGE_PATH, 'actions', 'external.svg'), |
||||
favorite: join(IMAGE_PATH, 'actions', 'star-dark.svg'), |
||||
files: join(IMAGE_PATH, 'places', 'files.svg'), |
||||
filter: join(IMAGE_PATH, 'actions', 'filter.svg'), |
||||
folder: join(IMAGE_PATH, 'filetypes', 'folder.svg'), |
||||
fullscreen: join(IMAGE_PATH, 'actions', 'fullscreen.svg'), |
||||
group: join(IMAGE_PATH, 'actions', 'group.svg'), |
||||
history: join(IMAGE_PATH, 'actions', 'history.svg'), |
||||
home: join(IMAGE_PATH, 'places', 'home.svg'), |
||||
info: join(IMAGE_PATH, 'actions', 'info.svg'), |
||||
link: join(IMAGE_PATH, 'places', 'link.svg'), |
||||
logout: join(IMAGE_PATH, 'actions', 'logout.svg'), |
||||
mail: join(IMAGE_PATH, 'actions', 'mail.svg'), |
||||
'menu-sidebar': join(IMAGE_PATH, 'actions', 'menu-sidebar.svg'), |
||||
menu: join(IMAGE_PATH, 'actions', 'menu.svg'), |
||||
more: join(IMAGE_PATH, 'actions', 'more.svg'), |
||||
music: join(IMAGE_PATH, 'places', 'music.svg'), |
||||
password: join(IMAGE_PATH, 'actions', 'password.svg'), |
||||
pause: join(IMAGE_PATH, 'actions', 'pause.svg'), |
||||
phone: join(IMAGE_PATH, 'clients', 'phone.svg'), |
||||
picture: join(IMAGE_PATH, 'places', 'picture.svg'), |
||||
'play-add': join(IMAGE_PATH, 'actions', 'play-add.svg'), |
||||
'play-next': join(IMAGE_PATH, 'actions', 'play-next.svg'), |
||||
'play-previous': join(IMAGE_PATH, 'actions', 'play-previous.svg'), |
||||
play: join(IMAGE_PATH, 'actions', 'play.svg'), |
||||
projects: join(IMAGE_PATH, 'actions', 'projects.svg'), |
||||
public: join(IMAGE_PATH, 'actions', 'public.svg'), |
||||
quota: join(IMAGE_PATH, 'actions', 'quota.svg'), |
||||
recent: join(IMAGE_PATH, 'actions', 'recent.svg'), |
||||
rename: join(IMAGE_PATH, 'actions', 'rename.svg'), |
||||
'screen-off': join(IMAGE_PATH, 'actions', 'screen-off.svg'), |
||||
screen: join(IMAGE_PATH, 'actions', 'screen.svg'), |
||||
search: join(IMAGE_PATH, 'actions', 'search.svg'), |
||||
settings: join(IMAGE_PATH, 'actions', 'settings-dark.svg'), |
||||
share: join(IMAGE_PATH, 'actions', 'share.svg'), |
||||
shared: join(IMAGE_PATH, 'actions', 'share.svg'), |
||||
'sound-off': join(IMAGE_PATH, 'actions', 'sound-off.svg'), |
||||
sound: join(IMAGE_PATH, 'actions', 'sound.svg'), |
||||
star: join(IMAGE_PATH, 'actions', 'star.svg'), |
||||
starred: join(IMAGE_PATH, 'actions', 'star-dark.svg'), |
||||
'star-rounded': join(IMAGE_PATH, 'actions', 'star-rounded.svg'), |
||||
tablet: join(IMAGE_PATH, 'clients', 'tablet.svg'), |
||||
tag: join(IMAGE_PATH, 'actions', 'tag.svg'), |
||||
talk: join(IMAGE_PATH, 'apps', 'spreed.svg'), |
||||
teams: join(IMAGE_PATH, 'apps', 'circles.svg'), |
||||
'template-add': join(IMAGE_PATH, 'actions', 'template-add.svg'), |
||||
timezone: join(IMAGE_PATH, 'actions', 'timezone.svg'), |
||||
'toggle-background': join(IMAGE_PATH, 'actions', 'toggle-background.svg'), |
||||
'toggle-filelist': join(IMAGE_PATH, 'actions', 'toggle-filelist.svg'), |
||||
'toggle-pictures': join(IMAGE_PATH, 'actions', 'toggle-pictures.svg'), |
||||
toggle: join(IMAGE_PATH, 'actions', 'toggle.svg'), |
||||
'triangle-e': join(IMAGE_PATH, 'actions', 'triangle-e.svg'), |
||||
'triangle-n': join(IMAGE_PATH, 'actions', 'triangle-n.svg'), |
||||
'triangle-s': join(IMAGE_PATH, 'actions', 'triangle-s.svg'), |
||||
unshare: join(IMAGE_PATH, 'actions', 'unshare.svg'), |
||||
upload: join(IMAGE_PATH, 'actions', 'upload.svg'), |
||||
'user-admin': join(IMAGE_PATH, 'actions', 'user-admin.svg'), |
||||
user: join(IMAGE_PATH, 'actions', 'user.svg'), |
||||
'video-off': join(IMAGE_PATH, 'actions', 'video-off.svg'), |
||||
'video-switch': join(IMAGE_PATH, 'actions', 'video-switch.svg'), |
||||
video: join(IMAGE_PATH, 'actions', 'video.svg'), |
||||
'view-close': join(IMAGE_PATH, 'actions', 'view-close.svg'), |
||||
'view-download': join(IMAGE_PATH, 'actions', 'view-download.svg'), |
||||
'view-next': join(IMAGE_PATH, 'actions', 'arrow-right.svg'), |
||||
'view-pause': join(IMAGE_PATH, 'actions', 'view-pause.svg'), |
||||
'view-play': join(IMAGE_PATH, 'actions', 'view-play.svg'), |
||||
'view-previous': join(IMAGE_PATH, 'actions', 'arrow-left.svg'), |
||||
} |
||||
|
||||
const iconsColor = { |
||||
'add-folder-description': { |
||||
path: join(IMAGE_PATH, 'actions', 'add-folder-description.svg'), |
||||
color: 'grey', |
||||
}, |
||||
settings: { |
||||
path: join(IMAGE_PATH, 'actions', 'settings.svg'), |
||||
color: 'black', |
||||
}, |
||||
'error-color': { |
||||
path: join(IMAGE_PATH, 'actions', 'error.svg'), |
||||
color: 'red', |
||||
}, |
||||
'checkmark-color': { |
||||
path: join(IMAGE_PATH, 'actions', 'checkmark.svg'), |
||||
color: 'green', |
||||
}, |
||||
starred: { |
||||
path: join(IMAGE_PATH, 'actions', 'star-dark.svg'), |
||||
color: 'yellow', |
||||
}, |
||||
star: { |
||||
path: join(IMAGE_PATH, 'actions', 'star-dark.svg'), |
||||
color: 'grey', |
||||
}, |
||||
'delete-color': { |
||||
path: join(IMAGE_PATH, 'actions', 'delete.svg'), |
||||
color: 'red', |
||||
}, |
||||
file: { |
||||
path: join(IMAGE_PATH, 'filetypes', 'text.svg'), |
||||
color: 'grey', |
||||
}, |
||||
'filetype-file': { |
||||
path: join(IMAGE_PATH, 'filetypes', 'file.svg'), |
||||
color: 'grey', |
||||
}, |
||||
'filetype-folder': { |
||||
path: join(IMAGE_PATH, 'filetypes', 'folder.svg'), |
||||
// TODO: replace primary ?
|
||||
color: 'primary', |
||||
}, |
||||
'filetype-folder-drag-accept': { |
||||
path: join(IMAGE_PATH, 'filetypes', 'folder-drag-accept.svg'), |
||||
// TODO: replace primary ?
|
||||
color: 'primary', |
||||
}, |
||||
'filetype-text': { |
||||
path: join(IMAGE_PATH, 'filetypes', 'text.svg'), |
||||
color: 'grey', |
||||
}, |
||||
'file-text': { |
||||
path: join(IMAGE_PATH, 'filetypes', 'text.svg'), |
||||
color: 'black', |
||||
}, |
||||
} |
||||
|
||||
// use this to define aliases to existing icons
|
||||
// key is the css selector, value is the variable
|
||||
const iconsAliases = { |
||||
'icon-caret': 'icon-caret-white', |
||||
// starring action
|
||||
'icon-star:hover': 'icon-starred', |
||||
'icon-star:focus': 'icon-starred', |
||||
// Un-starring action
|
||||
'icon-starred:hover': 'icon-star-grey', |
||||
'icon-starred:focus': 'icon-star-grey', |
||||
// Delete normal
|
||||
'icon-delete.no-permission:hover': 'icon-delete-dark', |
||||
'icon-delete.no-permission:focus': 'icon-delete-dark', |
||||
'icon-delete.no-hover:hover': 'icon-delete-dark', |
||||
'icon-delete.no-hover:focus': 'icon-delete-dark', |
||||
'icon-delete:hover': 'icon-delete-color-red', |
||||
'icon-delete:focus': 'icon-delete-color-red', |
||||
// Delete white
|
||||
'icon-delete-white.no-permission:hover': 'icon-delete-white', |
||||
'icon-delete-white.no-permission:focus': 'icon-delete-white', |
||||
'icon-delete-white.no-hover:hover': 'icon-delete-white', |
||||
'icon-delete-white.no-hover:focus': 'icon-delete-white', |
||||
'icon-delete-white:hover': 'icon-delete-color-red', |
||||
'icon-delete-white:focus': 'icon-delete-color-red', |
||||
// Default to white
|
||||
'icon-view-close': 'icon-view-close-white', |
||||
'icon-view-download': 'icon-view-download-white', |
||||
'icon-view-pause': 'icon-view-pause-white', |
||||
'icon-view-play': 'icon-view-play-white', |
||||
// Default app place to white
|
||||
'icon-calendar': 'icon-calendar-white', |
||||
'icon-contacts': 'icon-contacts-white', |
||||
'icon-files': 'icon-files-white', |
||||
// Re-using existing icons
|
||||
'icon-category-installed': 'icon-user-dark', |
||||
'icon-category-enabled': 'icon-checkmark-dark', |
||||
'icon-category-disabled': 'icon-close-dark', |
||||
'icon-category-updates': 'icon-download-dark', |
||||
'icon-category-security': 'icon-password-dark', |
||||
'icon-category-search': 'icon-search-dark', |
||||
'icon-category-tools': 'icon-settings-dark', |
||||
'nav-icon-systemtagsfilter': 'icon-tag-dark', |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param svg |
||||
* @param color |
||||
*/ |
||||
function colorSvg(svg = '', color = '000') { |
||||
if (!color.match(/^[0-9a-f]{3,6}$/i)) { |
||||
// Prevent not-sane colors from being written into the SVG
|
||||
console.warn(color, 'does not match the required format') |
||||
color = '000' |
||||
} |
||||
|
||||
// add fill (fill is not present on black elements)
|
||||
const fillRe = /<((circle|rect|path)((?!fill=)[a-z0-9 =".\-#():;,])+)\/>/gmi |
||||
svg = svg.replace(fillRe, '<$1 fill="#' + color + '"/>') |
||||
|
||||
// replace any fill or stroke colors
|
||||
svg = svg.replace(/stroke="#([a-z0-9]{3,6})"/gmi, 'stroke="#' + color + '"') |
||||
svg = svg.replace(/fill="#([a-z0-9]{3,6})"/gmi, 'fill="#' + color + '"') |
||||
|
||||
return svg |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param invert |
||||
*/ |
||||
function generateVariablesAliases(invert = false) { |
||||
let css = '' |
||||
Object.keys(variables).forEach((variable) => { |
||||
if (variable.indexOf('original-') !== -1) { |
||||
let finalVariable = variable.replace('original-', '') |
||||
if (invert) { |
||||
finalVariable = finalVariable.replace('white', 'tempwhite') |
||||
.replace('dark', 'white') |
||||
.replace('tempwhite', 'dark') |
||||
} |
||||
css += `${finalVariable}: var(${variable});` |
||||
} |
||||
}) |
||||
return css |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param icon |
||||
* @param invert |
||||
*/ |
||||
function formatIcon(icon, invert = false) { |
||||
const color1 = invert ? 'white' : 'dark' |
||||
const color2 = invert ? 'dark' : 'white' |
||||
return ` |
||||
.icon-${icon}, |
||||
.icon-${icon}-dark { |
||||
background-image: var(--icon-${icon}-${color1}); |
||||
} |
||||
.icon-${icon}-white, |
||||
.icon-${icon}.icon-white { |
||||
background-image: var(--icon-${icon}-${color2}); |
||||
}` |
||||
} |
||||
/** |
||||
* |
||||
* @param icon |
||||
*/ |
||||
function formatIconColor(icon) { |
||||
const { color } = iconsColor[icon] |
||||
return ` |
||||
.icon-${icon} { |
||||
background-image: var(--icon-${icon}-${color}); |
||||
}` |
||||
} |
||||
/** |
||||
* |
||||
* @param alias |
||||
* @param invert |
||||
*/ |
||||
function formatAlias(alias, invert = false) { |
||||
let icon = iconsAliases[alias] |
||||
if (invert) { |
||||
icon = icon.replace('white', 'tempwhite') |
||||
.replace('dark', 'white') |
||||
.replace('tempwhite', 'dark') |
||||
} |
||||
return ` |
||||
.${alias} { |
||||
background-image: var(--${icon}) |
||||
}` |
||||
} |
||||
|
||||
let css = '' |
||||
Object.keys(icons).forEach((icon) => { |
||||
const path = icons[icon] |
||||
|
||||
const svg = readFileSync(path, 'utf8') |
||||
const darkSvg = colorSvg(svg, '000000') |
||||
const whiteSvg = colorSvg(svg, 'ffffff') |
||||
|
||||
variables[`--original-icon-${icon}-dark`] = Buffer.from(darkSvg, 'utf-8').toString('base64') |
||||
variables[`--original-icon-${icon}-white`] = Buffer.from(whiteSvg, 'utf-8').toString('base64') |
||||
}) |
||||
|
||||
Object.keys(iconsColor).forEach((icon) => { |
||||
const { path, color } = iconsColor[icon] |
||||
|
||||
const svg = readFileSync(path, 'utf8') |
||||
const coloredSvg = colorSvg(svg, colors[color]) |
||||
variables[`--icon-${icon}-${color}`] = Buffer.from(coloredSvg, 'utf-8').toString('base64') |
||||
}) |
||||
|
||||
// ICONS VARIABLES LIST
|
||||
css += ':root {' |
||||
Object.keys(variables).forEach((variable) => { |
||||
const data = variables[variable] |
||||
css += `${variable}: url(data:image/svg+xml;base64,${data});` |
||||
}) |
||||
css += '}' |
||||
|
||||
// DEFAULT THEME
|
||||
css += 'body {' |
||||
css += generateVariablesAliases() |
||||
Object.keys(icons).forEach((icon) => { |
||||
css += formatIcon(icon) |
||||
}) |
||||
Object.keys(iconsColor).forEach((icon) => { |
||||
css += formatIconColor(icon) |
||||
}) |
||||
Object.keys(iconsAliases).forEach((alias) => { |
||||
css += formatAlias(alias) |
||||
}) |
||||
css += '}' |
||||
|
||||
// DARK THEME MEDIA QUERY
|
||||
css += '@media (prefers-color-scheme: dark) { body {' |
||||
css += generateVariablesAliases(true) |
||||
css += '}}' |
||||
|
||||
// DARK THEME
|
||||
css += '[data-themes*=light] {' |
||||
css += generateVariablesAliases() |
||||
css += '}' |
||||
|
||||
// DARK THEME
|
||||
css += '[data-themes*=dark] {' |
||||
css += generateVariablesAliases(true) |
||||
css += '}' |
||||
|
||||
// WRITE CSS
|
||||
writeFileSync(join(import.meta.dirname, '../dist', 'icons.css'), compileString(css).css) |
||||
@ -1,379 +0,0 @@ |
||||
/** |
||||
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
import fs from 'fs' |
||||
import path from 'path' |
||||
import sass from 'sass' |
||||
|
||||
const colors = { |
||||
dark: '000', |
||||
white: 'fff', |
||||
// gold but for backwards compatibility called yellow |
||||
yellow: 'a08b00', |
||||
red: 'e9322d', |
||||
orange: 'eca700', |
||||
green: '46ba61', |
||||
grey: '969696', |
||||
} |
||||
|
||||
const variables = {} |
||||
const icons = { |
||||
add: path.join(__dirname, '../img', 'actions', 'add.svg'), |
||||
address: path.join(__dirname, '../img', 'actions', 'address.svg'), |
||||
'alert-outline': path.join(__dirname, '../img', 'actions', 'alert-outline.svg'), |
||||
'audio-off': path.join(__dirname, '../img', 'actions', 'audio-off.svg'), |
||||
audio: path.join(__dirname, '../img', 'actions', 'audio.svg'), |
||||
calendar: path.join(__dirname, '../img', 'places', 'calendar.svg'), |
||||
caret: path.join(__dirname, '../img', 'actions', 'caret.svg'), |
||||
'category-app-bundles': path.join(__dirname, '../img', 'categories', 'bundles.svg'), |
||||
'category-auth': path.join(__dirname, '../img', 'categories', 'auth.svg'), |
||||
'category-customization': path.join(__dirname, '../img', 'categories', 'customization.svg'), |
||||
'category-dashboard': path.join(__dirname, '../img', 'categories', 'dashboard.svg'), |
||||
'category-files': path.join(__dirname, '../img', 'categories', 'files.svg'), |
||||
'category-games': path.join(__dirname, '../img', 'categories', 'games.svg'), |
||||
'category-integration': path.join(__dirname, '../img', 'categories', 'integration.svg'), |
||||
'category-monitoring': path.join(__dirname, '../img', 'categories', 'monitoring.svg'), |
||||
'category-multimedia': path.join(__dirname, '../img', 'categories', 'multimedia.svg'), |
||||
'category-office': path.join(__dirname, '../img', 'categories', 'office.svg'), |
||||
'category-organization': path.join(__dirname, '../img', 'categories', 'organization.svg'), |
||||
'category-social': path.join(__dirname, '../img', 'categories', 'social.svg'), |
||||
'category-workflow': path.join(__dirname, '../img', 'categories', 'workflow.svg'), |
||||
change: path.join(__dirname, '../img', 'actions', 'change.svg'), |
||||
checkmark: path.join(__dirname, '../img', 'actions', 'checkmark.svg'), |
||||
circles: path.join(__dirname, '../img', 'apps', 'circles.svg'), |
||||
clippy: path.join(__dirname, '../img', 'actions', 'clippy.svg'), |
||||
close: path.join(__dirname, '../img', 'actions', 'close.svg'), |
||||
comment: path.join(__dirname, '../img', 'actions', 'comment.svg'), |
||||
'confirm-fade': path.join(__dirname, '../img', 'actions', 'confirm-fade.svg'), |
||||
confirm: path.join(__dirname, '../img', 'actions', 'confirm.svg'), |
||||
contacts: path.join(__dirname, '../img', 'places', 'contacts.svg'), |
||||
delete: path.join(__dirname, '../img', 'actions', 'delete.svg'), |
||||
desktop: path.join(__dirname, '../img', 'clients', 'desktop.svg'), |
||||
details: path.join(__dirname, '../img', 'actions', 'details.svg'), |
||||
'disabled-user': path.join(__dirname, '../img', 'actions', 'disabled-user.svg'), |
||||
'disabled-users': path.join(__dirname, '../img', 'actions', 'disabled-users.svg'), |
||||
download: path.join(__dirname, '../img', 'actions', 'download.svg'), |
||||
edit: path.join(__dirname, '../img', 'actions', 'edit.svg'), |
||||
encryption: path.join(__dirname, '../../', 'apps/files_external/img', 'app.svg'), |
||||
error: path.join(__dirname, '../img', 'actions', 'error.svg'), |
||||
external: path.join(__dirname, '../img', 'actions', 'external.svg'), |
||||
favorite: path.join(__dirname, '../img', 'actions', 'star-dark.svg'), |
||||
files: path.join(__dirname, '../img', 'places', 'files.svg'), |
||||
filter: path.join(__dirname, '../img', 'actions', 'filter.svg'), |
||||
folder: path.join(__dirname, '../img', 'filetypes', 'folder.svg'), |
||||
fullscreen: path.join(__dirname, '../img', 'actions', 'fullscreen.svg'), |
||||
group: path.join(__dirname, '../img', 'actions', 'group.svg'), |
||||
history: path.join(__dirname, '../img', 'actions', 'history.svg'), |
||||
home: path.join(__dirname, '../img', 'places', 'home.svg'), |
||||
info: path.join(__dirname, '../img', 'actions', 'info.svg'), |
||||
link: path.join(__dirname, '../img', 'places', 'link.svg'), |
||||
logout: path.join(__dirname, '../img', 'actions', 'logout.svg'), |
||||
mail: path.join(__dirname, '../img', 'actions', 'mail.svg'), |
||||
'menu-sidebar': path.join(__dirname, '../img', 'actions', 'menu-sidebar.svg'), |
||||
menu: path.join(__dirname, '../img', 'actions', 'menu.svg'), |
||||
more: path.join(__dirname, '../img', 'actions', 'more.svg'), |
||||
music: path.join(__dirname, '../img', 'places', 'music.svg'), |
||||
password: path.join(__dirname, '../img', 'actions', 'password.svg'), |
||||
pause: path.join(__dirname, '../img', 'actions', 'pause.svg'), |
||||
phone: path.join(__dirname, '../img', 'clients', 'phone.svg'), |
||||
picture: path.join(__dirname, '../img', 'places', 'picture.svg'), |
||||
'play-add': path.join(__dirname, '../img', 'actions', 'play-add.svg'), |
||||
'play-next': path.join(__dirname, '../img', 'actions', 'play-next.svg'), |
||||
'play-previous': path.join(__dirname, '../img', 'actions', 'play-previous.svg'), |
||||
play: path.join(__dirname, '../img', 'actions', 'play.svg'), |
||||
projects: path.join(__dirname, '../img', 'actions', 'projects.svg'), |
||||
public: path.join(__dirname, '../img', 'actions', 'public.svg'), |
||||
quota: path.join(__dirname, '../img', 'actions', 'quota.svg'), |
||||
recent: path.join(__dirname, '../img', 'actions', 'recent.svg'), |
||||
rename: path.join(__dirname, '../img', 'actions', 'rename.svg'), |
||||
'screen-off': path.join(__dirname, '../img', 'actions', 'screen-off.svg'), |
||||
screen: path.join(__dirname, '../img', 'actions', 'screen.svg'), |
||||
search: path.join(__dirname, '../img', 'actions', 'search.svg'), |
||||
settings: path.join(__dirname, '../img', 'actions', 'settings-dark.svg'), |
||||
share: path.join(__dirname, '../img', 'actions', 'share.svg'), |
||||
shared: path.join(__dirname, '../img', 'actions', 'share.svg'), |
||||
'sound-off': path.join(__dirname, '../img', 'actions', 'sound-off.svg'), |
||||
sound: path.join(__dirname, '../img', 'actions', 'sound.svg'), |
||||
star: path.join(__dirname, '../img', 'actions', 'star.svg'), |
||||
starred: path.join(__dirname, '../img', 'actions', 'star-dark.svg'), |
||||
'star-rounded': path.join(__dirname, '../img', 'actions', 'star-rounded.svg'), |
||||
tablet: path.join(__dirname, '../img', 'clients', 'tablet.svg'), |
||||
tag: path.join(__dirname, '../img', 'actions', 'tag.svg'), |
||||
talk: path.join(__dirname, '../img', 'apps', 'spreed.svg'), |
||||
teams: path.join(__dirname, '../img', 'apps', 'circles.svg'), |
||||
'template-add': path.join(__dirname, '../img', 'actions', 'template-add.svg'), |
||||
timezone: path.join(__dirname, '../img', 'actions', 'timezone.svg'), |
||||
'toggle-background': path.join(__dirname, '../img', 'actions', 'toggle-background.svg'), |
||||
'toggle-filelist': path.join(__dirname, '../img', 'actions', 'toggle-filelist.svg'), |
||||
'toggle-pictures': path.join(__dirname, '../img', 'actions', 'toggle-pictures.svg'), |
||||
toggle: path.join(__dirname, '../img', 'actions', 'toggle.svg'), |
||||
'triangle-e': path.join(__dirname, '../img', 'actions', 'triangle-e.svg'), |
||||
'triangle-n': path.join(__dirname, '../img', 'actions', 'triangle-n.svg'), |
||||
'triangle-s': path.join(__dirname, '../img', 'actions', 'triangle-s.svg'), |
||||
unshare: path.join(__dirname, '../img', 'actions', 'unshare.svg'), |
||||
upload: path.join(__dirname, '../img', 'actions', 'upload.svg'), |
||||
'user-admin': path.join(__dirname, '../img', 'actions', 'user-admin.svg'), |
||||
user: path.join(__dirname, '../img', 'actions', 'user.svg'), |
||||
'video-off': path.join(__dirname, '../img', 'actions', 'video-off.svg'), |
||||
'video-switch': path.join(__dirname, '../img', 'actions', 'video-switch.svg'), |
||||
video: path.join(__dirname, '../img', 'actions', 'video.svg'), |
||||
'view-close': path.join(__dirname, '../img', 'actions', 'view-close.svg'), |
||||
'view-download': path.join(__dirname, '../img', 'actions', 'view-download.svg'), |
||||
'view-next': path.join(__dirname, '../img', 'actions', 'arrow-right.svg'), |
||||
'view-pause': path.join(__dirname, '../img', 'actions', 'view-pause.svg'), |
||||
'view-play': path.join(__dirname, '../img', 'actions', 'view-play.svg'), |
||||
'view-previous': path.join(__dirname, '../img', 'actions', 'arrow-left.svg'), |
||||
} |
||||
|
||||
const iconsColor = { |
||||
'add-folder-description': { |
||||
path: path.join(__dirname, '../img', 'actions', 'add-folder-description.svg'), |
||||
color: 'grey', |
||||
}, |
||||
settings: { |
||||
path: path.join(__dirname, '../img', 'actions', 'settings.svg'), |
||||
color: 'black', |
||||
}, |
||||
'error-color': { |
||||
path: path.join(__dirname, '../img', 'actions', 'error.svg'), |
||||
color: 'red', |
||||
}, |
||||
'checkmark-color': { |
||||
path: path.join(__dirname, '../img', 'actions', 'checkmark.svg'), |
||||
color: 'green', |
||||
}, |
||||
starred: { |
||||
path: path.join(__dirname, '../img', 'actions', 'star-dark.svg'), |
||||
color: 'yellow', |
||||
}, |
||||
star: { |
||||
path: path.join(__dirname, '../img', 'actions', 'star-dark.svg'), |
||||
color: 'grey', |
||||
}, |
||||
'delete-color': { |
||||
path: path.join(__dirname, '../img', 'actions', 'delete.svg'), |
||||
color: 'red', |
||||
}, |
||||
file: { |
||||
path: path.join(__dirname, '../img', 'filetypes', 'text.svg'), |
||||
color: 'grey', |
||||
}, |
||||
'filetype-file': { |
||||
path: path.join(__dirname, '../img', 'filetypes', 'file.svg'), |
||||
color: 'grey', |
||||
}, |
||||
'filetype-folder': { |
||||
path: path.join(__dirname, '../img', 'filetypes', 'folder.svg'), |
||||
// TODO: replace primary ? |
||||
color: 'primary', |
||||
}, |
||||
'filetype-folder-drag-accept': { |
||||
path: path.join(__dirname, '../img', 'filetypes', 'folder-drag-accept.svg'), |
||||
// TODO: replace primary ? |
||||
color: 'primary', |
||||
}, |
||||
'filetype-text': { |
||||
path: path.join(__dirname, '../img', 'filetypes', 'text.svg'), |
||||
color: 'grey', |
||||
}, |
||||
'file-text': { |
||||
path: path.join(__dirname, '../img', 'filetypes', 'text.svg'), |
||||
color: 'black', |
||||
}, |
||||
} |
||||
|
||||
// use this to define aliases to existing icons |
||||
// key is the css selector, value is the variable |
||||
const iconsAliases = { |
||||
'icon-caret': 'icon-caret-white', |
||||
// starring action |
||||
'icon-star:hover': 'icon-starred', |
||||
'icon-star:focus': 'icon-starred', |
||||
// Un-starring action |
||||
'icon-starred:hover': 'icon-star-grey', |
||||
'icon-starred:focus': 'icon-star-grey', |
||||
// Delete normal |
||||
'icon-delete.no-permission:hover': 'icon-delete-dark', |
||||
'icon-delete.no-permission:focus': 'icon-delete-dark', |
||||
'icon-delete.no-hover:hover': 'icon-delete-dark', |
||||
'icon-delete.no-hover:focus': 'icon-delete-dark', |
||||
'icon-delete:hover': 'icon-delete-color-red', |
||||
'icon-delete:focus': 'icon-delete-color-red', |
||||
// Delete white |
||||
'icon-delete-white.no-permission:hover': 'icon-delete-white', |
||||
'icon-delete-white.no-permission:focus': 'icon-delete-white', |
||||
'icon-delete-white.no-hover:hover': 'icon-delete-white', |
||||
'icon-delete-white.no-hover:focus': 'icon-delete-white', |
||||
'icon-delete-white:hover': 'icon-delete-color-red', |
||||
'icon-delete-white:focus': 'icon-delete-color-red', |
||||
// Default to white |
||||
'icon-view-close': 'icon-view-close-white', |
||||
'icon-view-download': 'icon-view-download-white', |
||||
'icon-view-pause': 'icon-view-pause-white', |
||||
'icon-view-play': 'icon-view-play-white', |
||||
// Default app place to white |
||||
'icon-calendar': 'icon-calendar-white', |
||||
'icon-contacts': 'icon-contacts-white', |
||||
'icon-files': 'icon-files-white', |
||||
// Re-using existing icons |
||||
'icon-category-installed': 'icon-user-dark', |
||||
'icon-category-enabled': 'icon-checkmark-dark', |
||||
'icon-category-disabled': 'icon-close-dark', |
||||
'icon-category-updates': 'icon-download-dark', |
||||
'icon-category-security': 'icon-password-dark', |
||||
'icon-category-search': 'icon-search-dark', |
||||
'icon-category-tools': 'icon-settings-dark', |
||||
'nav-icon-systemtagsfilter': 'icon-tag-dark', |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param svg |
||||
* @param color |
||||
*/ |
||||
function colorSvg(svg = '', color = '000') { |
||||
if (!color.match(/^[0-9a-f]{3,6}$/i)) { |
||||
// Prevent not-sane colors from being written into the SVG |
||||
console.warn(color, 'does not match the required format') |
||||
color = '000' |
||||
} |
||||
|
||||
// add fill (fill is not present on black elements) |
||||
const fillRe = /<((circle|rect|path)((?!fill=)[a-z0-9 =".\-#():;,])+)\/>/gmi |
||||
svg = svg.replace(fillRe, '<$1 fill="#' + color + '"/>') |
||||
|
||||
// replace any fill or stroke colors |
||||
svg = svg.replace(/stroke="#([a-z0-9]{3,6})"/gmi, 'stroke="#' + color + '"') |
||||
svg = svg.replace(/fill="#([a-z0-9]{3,6})"/gmi, 'fill="#' + color + '"') |
||||
|
||||
return svg |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param invert |
||||
*/ |
||||
function generateVariablesAliases(invert = false) { |
||||
let css = '' |
||||
Object.keys(variables).forEach((variable) => { |
||||
if (variable.indexOf('original-') !== -1) { |
||||
let finalVariable = variable.replace('original-', '') |
||||
if (invert) { |
||||
finalVariable = finalVariable.replace('white', 'tempwhite') |
||||
.replace('dark', 'white') |
||||
.replace('tempwhite', 'dark') |
||||
} |
||||
css += `${finalVariable}: var(${variable});` |
||||
} |
||||
}) |
||||
return css |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param icon |
||||
* @param invert |
||||
*/ |
||||
function formatIcon(icon, invert = false) { |
||||
const color1 = invert ? 'white' : 'dark' |
||||
const color2 = invert ? 'dark' : 'white' |
||||
return ` |
||||
.icon-${icon}, |
||||
.icon-${icon}-dark { |
||||
background-image: var(--icon-${icon}-${color1}); |
||||
} |
||||
.icon-${icon}-white, |
||||
.icon-${icon}.icon-white { |
||||
background-image: var(--icon-${icon}-${color2}); |
||||
}` |
||||
} |
||||
/** |
||||
* |
||||
* @param icon |
||||
*/ |
||||
function formatIconColor(icon) { |
||||
const { color } = iconsColor[icon] |
||||
return ` |
||||
.icon-${icon} { |
||||
background-image: var(--icon-${icon}-${color}); |
||||
}` |
||||
} |
||||
/** |
||||
* |
||||
* @param alias |
||||
* @param invert |
||||
*/ |
||||
function formatAlias(alias, invert = false) { |
||||
let icon = iconsAliases[alias] |
||||
if (invert) { |
||||
icon = icon.replace('white', 'tempwhite') |
||||
.replace('dark', 'white') |
||||
.replace('tempwhite', 'dark') |
||||
} |
||||
return ` |
||||
.${alias} { |
||||
background-image: var(--${icon}) |
||||
}` |
||||
} |
||||
|
||||
let css = '' |
||||
Object.keys(icons).forEach((icon) => { |
||||
const path = icons[icon] |
||||
|
||||
const svg = fs.readFileSync(path, 'utf8') |
||||
const darkSvg = colorSvg(svg, '000000') |
||||
const whiteSvg = colorSvg(svg, 'ffffff') |
||||
|
||||
variables[`--original-icon-${icon}-dark`] = Buffer.from(darkSvg, 'utf-8').toString('base64') |
||||
variables[`--original-icon-${icon}-white`] = Buffer.from(whiteSvg, 'utf-8').toString('base64') |
||||
}) |
||||
|
||||
Object.keys(iconsColor).forEach((icon) => { |
||||
const { path, color } = iconsColor[icon] |
||||
|
||||
const svg = fs.readFileSync(path, 'utf8') |
||||
const coloredSvg = colorSvg(svg, colors[color]) |
||||
variables[`--icon-${icon}-${color}`] = Buffer.from(coloredSvg, 'utf-8').toString('base64') |
||||
}) |
||||
|
||||
// ICONS VARIABLES LIST |
||||
css += ':root {' |
||||
Object.keys(variables).forEach((variable) => { |
||||
const data = variables[variable] |
||||
css += `${variable}: url(data:image/svg+xml;base64,${data});` |
||||
}) |
||||
css += '}' |
||||
|
||||
// DEFAULT THEME |
||||
css += 'body {' |
||||
css += generateVariablesAliases() |
||||
Object.keys(icons).forEach((icon) => { |
||||
css += formatIcon(icon) |
||||
}) |
||||
Object.keys(iconsColor).forEach((icon) => { |
||||
css += formatIconColor(icon) |
||||
}) |
||||
Object.keys(iconsAliases).forEach((alias) => { |
||||
css += formatAlias(alias) |
||||
}) |
||||
css += '}' |
||||
|
||||
// DARK THEME MEDIA QUERY |
||||
css += '@media (prefers-color-scheme: dark) { body {' |
||||
css += generateVariablesAliases(true) |
||||
css += '}}' |
||||
|
||||
// DARK THEME |
||||
css += '[data-themes*=light] {' |
||||
css += generateVariablesAliases() |
||||
css += '}' |
||||
|
||||
// DARK THEME |
||||
css += '[data-themes*=dark] {' |
||||
css += generateVariablesAliases(true) |
||||
css += '}' |
||||
|
||||
// WRITE CSS |
||||
fs.writeFileSync(path.join(__dirname, '../../dist', 'icons.css'), sass.compileString(css).css) |
||||
Loading…
Reference in new issue