Files
smatchit_tailwind_project/node_modules/daisyui/src/theming/functions.js
2024-07-15 15:57:41 +03:00

263 lines
8.3 KiB
JavaScript

const pc = require("picocolors")
const colorNames = require("./colorNames")
const themeDefaults = require("./themeDefaults")
const { oklch, interpolate, wcagContrast } = require("culori/require")
const colorIsInvalid = (input) => {
console.error(
`├─ ${pc.red("⚠︎")} ${pc.bgRed(" Error ")} Invalid color ${pc.red(input)} in ${pc.green(
"tailwind.config.js"
)}`
)
}
const cutNumber = (number) => {
try {
if (number) {
return +number.toFixed(6)
}
return 0
} catch (e) {
// colorIsInvalid(number)
return false
}
}
module.exports = {
isDark: (color) => {
try {
if (wcagContrast(color, "black") < wcagContrast(color, "white")) {
return true
}
return false
} catch (e) {
// colorIsInvalid(color)
return false
}
},
colorObjToString: (input) => {
const { l, c, h } = input
return `${Number.parseFloat((cutNumber(l) * 100).toFixed(6))}% ${cutNumber(c)} ${cutNumber(h)}`
},
generateForegroundColorFrom: function (input, percentage = 0.8) {
try {
const result = interpolate(
[input, this.isDark(input) ? "white" : "black"],
"oklch"
)(percentage)
return this.colorObjToString(result)
} catch (e) {
// colorIsInvalid(input)
return false
}
},
generateDarkenColorFrom: function (input, percentage = 0.07) {
try {
const result = interpolate([input, "black"], "oklch")(percentage)
return this.colorObjToString(result)
} catch (e) {
// colorIsInvalid(input)
return false
}
},
convertColorFormat: function (input) {
if (typeof input !== "object" || input === null) {
return input
}
const resultObj = {}
for (const [rule, value] of Object.entries(input)) {
if (Object.hasOwn(colorNames, rule)) {
try {
const colorObj = oklch(value)
resultObj[colorNames[rule]] = this.colorObjToString(colorObj)
} catch (e) {
colorIsInvalid(value)
return false
}
} else {
resultObj[rule] = value
}
// auto generate base colors
if (!Object.hasOwn(input, "base-100")) {
resultObj["--b1"] = "100% 0 0"
}
if (!Object.hasOwn(input, "base-200")) {
resultObj["--b2"] = this.generateDarkenColorFrom(input["base-100"], 0.07)
}
if (!Object.hasOwn(input, "base-300")) {
if (Object.hasOwn(input, "base-200")) {
resultObj["--b3"] = this.generateDarkenColorFrom(input["base-200"], 0.07)
} else {
resultObj["--b3"] = this.generateDarkenColorFrom(input["base-100"], 0.14)
}
}
// auto generate state colors
if (!Object.hasOwn(input, "info")) {
resultObj["--in"] = "72.06% 0.191 231.6"
}
if (!Object.hasOwn(input, "success")) {
resultObj["--su"] = "64.8% 0.150 160"
}
if (!Object.hasOwn(input, "warning")) {
resultObj["--wa"] = "84.71% 0.199 83.87"
}
if (!Object.hasOwn(input, "error")) {
resultObj["--er"] = "71.76% 0.221 22.18"
}
// auto generate content colors
if (!Object.hasOwn(input, "base-content")) {
resultObj["--bc"] = this.generateForegroundColorFrom(input["base-100"], 0.8)
}
if (!Object.hasOwn(input, "primary-content")) {
resultObj["--pc"] = this.generateForegroundColorFrom(input.primary, 0.8)
}
if (!Object.hasOwn(input, "secondary-content")) {
resultObj["--sc"] = this.generateForegroundColorFrom(input.secondary, 0.8)
}
if (!Object.hasOwn(input, "accent-content")) {
resultObj["--ac"] = this.generateForegroundColorFrom(input.accent, 0.8)
}
if (!Object.hasOwn(input, "neutral-content")) {
resultObj["--nc"] = this.generateForegroundColorFrom(input.neutral, 0.8)
}
if (!Object.hasOwn(input, "info-content")) {
if (Object.hasOwn(input, "info")) {
resultObj["--inc"] = this.generateForegroundColorFrom(input.info, 0.8)
} else {
resultObj["--inc"] = "0% 0 0"
}
}
if (!Object.hasOwn(input, "success-content")) {
if (Object.hasOwn(input, "success")) {
resultObj["--suc"] = this.generateForegroundColorFrom(input.success, 0.8)
} else {
resultObj["--suc"] = "0% 0 0"
}
}
if (!Object.hasOwn(input, "warning-content")) {
if (Object.hasOwn(input, "warning")) {
resultObj["--wac"] = this.generateForegroundColorFrom(input.warning, 0.8)
} else {
resultObj["--wac"] = "0% 0 0"
}
}
if (!Object.hasOwn(input, "error-content")) {
if (Object.hasOwn(input, "error")) {
resultObj["--erc"] = this.generateForegroundColorFrom(input.error, 0.8)
} else {
resultObj["--erc"] = "0% 0 0"
}
}
// add css variables if not exist
for (const item of Object.entries(themeDefaults.variables)) {
const [variable, value] = item
if (!Object.hasOwn(input, variable)) {
resultObj[variable] = value
}
}
// add other custom styles
if (!Object.hasOwn(colorNames, rule)) {
resultObj[rule] = value
}
}
return resultObj
},
injectThemes: function (addBase, config, themes) {
const includedThemesObj = {}
// add default themes
const themeRoot = config("daisyui.themeRoot") ?? ":root"
for (const [theme, value] of Object.entries(themes)) {
includedThemesObj[theme] = this.convertColorFormat(value)
}
// add custom themes
if (Array.isArray(config("daisyui.themes"))) {
for (const item of config("daisyui.themes")) {
if (typeof item === "object" && item !== null) {
for (const [customThemeName, customThemevalue] of Object.entries(item)) {
includedThemesObj[customThemeName] = this.convertColorFormat(customThemevalue)
}
}
}
}
let themeOrder = []
if (Array.isArray(config("daisyui.themes"))) {
for (const theme of config("daisyui.themes")) {
if (typeof theme === "object" && theme !== null) {
for (const customThemeName of Object.keys(theme)) {
themeOrder.push(customThemeName)
}
} else if (Object.hasOwn(includedThemesObj, theme)) {
themeOrder.push(theme)
}
}
} else if (config("daisyui.themes") === true) {
themeOrder = themeDefaults.themeOrder
} else {
themeOrder = ["light", "dark"]
}
// inject themes in order
const themesToInject = {}
themeOrder.forEach((themeName, index) => {
if (index === 0) {
// first theme as root
themesToInject[themeRoot] = includedThemesObj[themeName]
} else if (index === 1) {
// auto dark
if (config("daisyui.darkTheme")) {
if (
themeOrder[0] !== config("daisyui.darkTheme") &&
themeOrder.includes(config("daisyui.darkTheme"))
) {
themesToInject["@media (prefers-color-scheme: dark)"] = {
[themeRoot]: includedThemesObj[`${config("daisyui.darkTheme")}`],
}
}
} else if (config("daisyui.darkTheme") === false) {
// disables prefers-color-scheme: dark
} else {
if (themeOrder[0] !== "dark" && themeOrder.includes("dark")) {
themesToInject["@media (prefers-color-scheme: dark)"] = {
[themeRoot]: includedThemesObj.dark,
}
}
}
// theme 0 with name
themesToInject[`[data-theme=${themeOrder[0]}]`] = includedThemesObj[themeOrder[0]]
themesToInject[`${themeRoot}:has(input.theme-controller[value=${themeOrder[0]}]:checked)`] =
includedThemesObj[themeOrder[0]]
// theme 1 with name
themesToInject[`[data-theme=${themeOrder[1]}]`] = includedThemesObj[themeOrder[1]]
themesToInject[`${themeRoot}:has(input.theme-controller[value=${themeOrder[1]}]:checked)`] =
includedThemesObj[themeOrder[1]]
} else {
themesToInject[`[data-theme=${themeName}]`] = includedThemesObj[themeName]
themesToInject[`${themeRoot}:has(input.theme-controller[value=${themeName}]:checked)`] =
includedThemesObj[themeName]
}
})
addBase(themesToInject)
return {
includedThemesObj,
themeOrder,
}
},
}