Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 143 additions & 28 deletions shesha-core/src/Shesha.Framework/Configuration/ThemeSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,82 @@ public static ThemeSettings Default
{
get
{
return defaultInstance = defaultInstance ??
new ThemeSettings()
return defaultInstance ??= new ThemeSettings()
{
Application = new ApplicationSettings()
{
Application = new ApplicationSettings()
{
PrimaryColor = "#2197dc",
ErrorColor = "#ff4d4f",
WarningColor = "#ff6f00",
InfoColor = "#faad14",
SuccessColor = "#25b864",
},
Text = new TextSettings()
PrimaryColor = "#2197dc",
ErrorColor = "#ff4d4f",
WarningColor = "#ff6f00",
InfoColor = "#faad14",
SuccessColor = "#25b864",
},
Text = new TextSettings()
{
Default = "#000000",
Secondary = "#8c8c8c",
},
Sidebar = "dark",
LayoutBackground = "#fafafa",
SidebarBackground = "#4d192b",
ComponentBackground = "#ffffff",
LabelSpan = 6,
ComponentSpan = 18,
MarginPadding = new MarginPaddingSettings()
{
FormFields = "",
Layout = "",
Grid = "",
Standard = "",
Inline = "",
},
LayoutComponents = new LayoutComponentsSettings()
{
StylingBox = "{\"marginBottom\":\"0\"}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Deduplicate repeated StylingBox default literal.

The same JSON literal appears multiple times. Extracting a constant avoids drift and typo regressions.

♻️ Suggested refactor
+        private const string ZeroMarginBottomStylingBox = "{\"marginBottom\":\"0\"}";
+
         public static ThemeSettings Default
         {
             get
             {
                 return defaultInstance ??= new ThemeSettings()
                 {
                     LayoutComponents = new LayoutComponentsSettings()
                     {
-                        StylingBox = "{\"marginBottom\":\"0\"}",
+                        StylingBox = ZeroMarginBottomStylingBox,
                         GridGapHorizontal = 8,
                         GridGapVertical = 8,
                         Border = new BorderTheme()
                         {
                             Border = new BorderConfig()
@@
                     InputComponents = new InputComponentsSettings()
                     {
                         LabelSpan = 8,
                         ContentSpan = 16,
                         LabelColon = true,
-                        StylingBox = "{\"marginBottom\":\"0\"}"
+                        StylingBox = ZeroMarginBottomStylingBox
                     },
                     StandardComponents = new StandardComponentsSettings()
                     {
-                        StylingBox = "{\"marginBottom\":\"0\"}"
+                        StylingBox = ZeroMarginBottomStylingBox
                     },
                     InlineComponents = new InlineComponentsSettings()
                     {
-                        StylingBox = "{\"marginBottom\":\"0\"}"
+                        StylingBox = ZeroMarginBottomStylingBox
                     }
                 };
             }
         }

Also applies to: 75-75, 79-79, 83-83

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shesha-core/src/Shesha.Framework/Configuration/ThemeSettings.cs` at line 41,
Extract the repeated JSON literal used for StylingBox into a single constant
(e.g., private static readonly string DefaultStylingBox =
"{\"marginBottom\":\"0\"}") inside the ThemeSettings class and replace every
inline occurrence of the literal (all StylingBox initializers) with that
constant; update object initializers or defaults that currently set StylingBox =
"{\"marginBottom\":\"0\"}" to StylingBox = DefaultStylingBox (or use a public
const if the value should be exposed).

GridGapHorizontal = 8,
GridGapVertical = 8,
Border = new BorderTheme()
{
Default = "#000000",
Secondary = "#8c8c8c",
Border = new BorderConfig()
{
All = new BorderStyle()
{
Width = "1",
Style = "solid",
Color = "#d9d9d9"
}
},
Radius = new RadiusConfig()
{
All = 4
},
RadiusType = "all"
},
Sidebar = "dark",
LayoutBackground = "#fafafa",
SidebarBackground = "#4d192b",
LabelSpan = 6,
ComponentSpan = 18,
MarginPadding = new MarginPaddingSettings()
Shadow = new ShadowTheme()
{
FormFields = "",
Layout = "",
Grid = "",
Standard = "",
Inline = "",
OffsetX = 0,
OffsetY = 0,
BlurRadius = 0,
SpreadRadius = 0,
Color = "#000000"
}
};
},
InputComponents = new InputComponentsSettings()
{
LabelSpan = 8,
ContentSpan = 16,
LabelColon = true,
StylingBox = "{\"marginBottom\":\"0\"}"
},
StandardComponents = new StandardComponentsSettings()
{
StylingBox = "{\"marginBottom\":\"0\"}"
},
InlineComponents = new InlineComponentsSettings()
{
StylingBox = "{\"marginBottom\":\"0\"}"
}
};
}
}
public class ApplicationSettings
Expand All @@ -63,13 +109,82 @@ public class MarginPaddingSettings
public string? Inline { get; set; }
}

public ThemeSettings.ApplicationSettings? Application { get; set; }
public class BorderStyle
{
public string? Width { get; set; }
public string? Style { get; set; }
public string? Color { get; set; }
}

public class RadiusConfig
{
public int? All { get; set; }
public int? TopLeft { get; set; }
public int? TopRight { get; set; }
public int? BottomLeft { get; set; }
public int? BottomRight { get; set; }
}

public class BorderTheme
{
public BorderConfig? Border { get; set; }
public RadiusConfig? Radius { get; set; }
public string? RadiusType { get; set; }
}

public class BorderConfig
{
public BorderStyle? All { get; set; }
}

public class ShadowTheme
{
public int? OffsetX { get; set; }
public int? OffsetY { get; set; }
public int? BlurRadius { get; set; }
public int? SpreadRadius { get; set; }
public string? Color { get; set; }
}

public class LayoutComponentsSettings
{
public string? StylingBox { get; set; }
public int? GridGapHorizontal { get; set; }
public int? GridGapVertical { get; set; }
public BorderTheme? Border { get; set; }
public ShadowTheme? Shadow { get; set; }
}

public class InputComponentsSettings
{
public int? LabelSpan { get; set; }
public int? ContentSpan { get; set; }
public bool? LabelColon { get; set; }
public string? StylingBox { get; set; }
}

public class StandardComponentsSettings
{
public string? StylingBox { get; set; }
}

public class InlineComponentsSettings
{
public string? StylingBox { get; set; }
}

public ApplicationSettings? Application { get; set; }
public string? Sidebar { get; set; }
public string? LayoutBackground { get; set; }
public ThemeSettings.TextSettings? Text { get; set; }
public TextSettings? Text { get; set; }
public string? SidebarBackground { get; set; }
public int? LabelSpan { get; set; }
public int? ComponentSpan { get; set; }
public ThemeSettings.MarginPaddingSettings? MarginPadding { get; set; }
public MarginPaddingSettings? MarginPadding { get; set; }
public string? ComponentBackground { get; set; }
public LayoutComponentsSettings? LayoutComponents { get; set; }
public InputComponentsSettings? InputComponents { get; set; }
public StandardComponentsSettings? StandardComponents { get; set; }
public InlineComponentsSettings? InlineComponents { get; set; }
}
}
125 changes: 123 additions & 2 deletions shesha-reactjs/src/providers/theme/contexts.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,96 @@
import { createNamedContext } from '@/utils/react';
import { Theme } from 'antd/lib/config-provider/context';

interface ITextTheme {
export interface ITextTheme {
default?: string;
secondary?: string;
link?: string;
}

export interface IApplicationTheme {
primaryColor?: string;
errorColor?: string;
warningColor?: string;
successColor?: string;
infoColor?: string;
processingColor?: string;
}

export interface IMarginPaddingTheme {
formFields?: string;
layout?: string;
grid?: string;
standard?: string;
inline?: string;
}

export interface IBorderStyle {
width?: string;
style?: string;
color?: string;
}

export interface IRadiusConfig {
all?: number;
topLeft?: number;
topRight?: number;
bottomLeft?: number;
bottomRight?: number;
}

export interface IBorderTheme {
border?: {
all?: IBorderStyle;
};
radius?: IRadiusConfig;
radiusType?: 'all' | 'individual';
}

export interface IShadowTheme {
offsetX?: number;
offsetY?: number;
blurRadius?: number;
spreadRadius?: number;
color?: string;
}

export interface ILayoutComponents {
stylingBox?: string;
gridGapHorizontal?: number;
gridGapVertical?: number;
border?: IBorderTheme;
shadow?: IShadowTheme;
}

export interface IInputComponents {
labelSpan?: number;
contentSpan?: number;
labelColon?: boolean;
stylingBox?: string;
}

export interface IStandardComponents {
stylingBox?: string;
}

export interface IInlineComponents {
stylingBox?: string;
}

export interface IConfigurableTheme {
application?: Theme;
application?: IApplicationTheme | Theme;
sidebar?: 'dark' | 'light';
sidebarBackground?: string;
layoutBackground?: string;
text?: ITextTheme;
labelSpan?: number;
componentSpan?: number;
marginPadding?: IMarginPaddingTheme;
componentBackground?: string;
layoutComponents?: ILayoutComponents;
inputComponents?: IInputComponents;
standardComponents?: IStandardComponents;
inlineComponents?: IInlineComponents;
}

export interface IThemeStateContext {
Expand Down Expand Up @@ -43,11 +119,56 @@ export const THEME_CONTEXT_INITIAL_STATE: IThemeStateContext = {
},
sidebar: 'dark',
layoutBackground: '#f0f2f5',
componentBackground: '#ffffff',
text: {
default: '#000000d9',
secondary: '#00000073',
link: '',
},
marginPadding: {
formFields: '{"marginTop":"0","paddingTop":"0"}',
layout: '{"paddingBottom":"0","paddingTop":"0"}',
grid: '{"paddingBottom":"0","paddingTop":"0"}',
standard: '{"marginTop":"0","paddingTop":"0"}',
inline: '{"paddingTop":"0","marginTop":"0"}',
},
layoutComponents: {
stylingBox: '{"marginBottom":"0"}',
gridGapHorizontal: 8,
gridGapVertical: 8,
border: {
border: {
all: {
width: '1',
style: 'solid',
color: '#d9d9d9',
},
},
radius: {
all: 4,
},
radiusType: 'all',
},
shadow: {
offsetX: 0,
offsetY: 0,
blurRadius: 0,
spreadRadius: 0,
color: '#000000',
},
},
inputComponents: {
labelSpan: 8,
contentSpan: 16,
labelColon: true,
stylingBox: '{"marginBottom":"0"}',
},
standardComponents: {
stylingBox: '{"marginBottom":"0"}',
},
inlineComponents: {
stylingBox: '{"marginBottom":"0"}',
},
},
prefixCls: 'antd',
iconPrefixCls: 'antdicon',
Expand Down
17 changes: 16 additions & 1 deletion shesha-reactjs/src/providers/theme/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,19 @@ function useTheme(): IThemeStateContext & IThemeActionsContext | undefined {
return { ...useThemeState(), ...useThemeActions() };
}

export { ThemeProvider, useTheme, useThemeActions, useThemeState, type IConfigurableTheme };
export {
type IConfigurableTheme,
type IApplicationTheme,
type ITextTheme,
type IMarginPaddingTheme,
type IBorderStyle,
type IRadiusConfig,
type IBorderTheme,
type IShadowTheme,
type ILayoutComponents,
type IInputComponents,
type IStandardComponents,
type IInlineComponents,
} from './contexts';

export { ThemeProvider, useTheme, useThemeActions, useThemeState };