Better form themes (#465)
* Working on custom radius + input size * Fix date input clear vertical align * Moslty finished implementing small size * Polishing larger theme * Finish large theme * Added size/radius options in form editor * Darken help text, improve switch input help location * Slight form editor improvement * Fix styling * Polish of the form editor
This commit is contained in:
69
client/lib/forms/themes/ThemeBuilder.js
vendored
Normal file
69
client/lib/forms/themes/ThemeBuilder.js
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
import {twMerge} from 'tailwind-merge'
|
||||
import {themes} from './form-themes.js'
|
||||
|
||||
export const sizes = ['sm', 'md', 'lg']
|
||||
|
||||
class ThemeBuilder {
|
||||
constructor(theme = 'default', options = {}) {
|
||||
this.theme = themes[theme] || themes.default
|
||||
this.size = options.size || 'md'
|
||||
this.borderRadius = options.borderRadius || 'small'
|
||||
}
|
||||
|
||||
extractSizedClasses(baseConfig) {
|
||||
if (typeof baseConfig === 'object' &&
|
||||
sizes.every((size) => baseConfig[size])) {
|
||||
return baseConfig[this.size]
|
||||
}
|
||||
|
||||
return baseConfig
|
||||
}
|
||||
|
||||
mergeNestedClasses(baseConfig, componentConfig) {
|
||||
const mergedConfig = {}
|
||||
|
||||
const allKeys = new Set([
|
||||
...Object.keys(baseConfig),
|
||||
...Object.keys(componentConfig),
|
||||
])
|
||||
|
||||
allKeys.forEach((key) => {
|
||||
const baseValue = this.extractSizedClasses(baseConfig[key])
|
||||
const componentValue = this.extractSizedClasses(componentConfig[key])
|
||||
|
||||
if (key === 'borderRadius') {
|
||||
// Special case for border radius
|
||||
const borderRadiusClass = baseConfig.borderRadius?.[this.borderRadius] || ''
|
||||
mergedConfig[key] = twMerge(borderRadiusClass, componentValue)
|
||||
} else if (
|
||||
typeof baseValue === 'object' &&
|
||||
baseValue !== null &&
|
||||
!Array.isArray(baseValue)) {
|
||||
mergedConfig[key] = this.mergeNestedClasses(baseValue, componentValue || {})
|
||||
} else {
|
||||
mergedConfig[key] = twMerge(baseValue || '', componentValue || '')
|
||||
}
|
||||
})
|
||||
|
||||
return mergedConfig
|
||||
}
|
||||
|
||||
getComponentTheme(componentName = 'default') {
|
||||
const baseComponentConfig = this.theme.default || {}
|
||||
const componentConfig = this.theme[componentName] || {}
|
||||
return this.mergeNestedClasses(baseComponentConfig, componentConfig)
|
||||
}
|
||||
|
||||
// Get all components classes for the selected theme
|
||||
getAllComponents() {
|
||||
const allComponents = {}
|
||||
|
||||
Object.keys(this.theme).forEach((componentName) => {
|
||||
allComponents[componentName] = this.getComponentTheme(componentName)
|
||||
})
|
||||
|
||||
return allComponents
|
||||
}
|
||||
}
|
||||
|
||||
export default ThemeBuilder
|
||||
Reference in New Issue
Block a user