Styling and Theming
Common styles are located in the frontend/src/css
folder such as: _calendar.css
, _table.css
, _scrollbars.css
, _progress.css
, _theme.css
, etc. which are responsible for customizing styles for tables, scroll bars, and other things.
Customizing Colors
The frontend/src/colors.ts
file contains text, borders, buttons, backgrounds, and more style variables. Below are some key variables and how they are defined:
Background Colors
The colorsBgLight
object defines various background color styles:
export const colorsBgLight = {
white: 'bg-white text-black',
light: 'bg-white text-black dark:bg-dark-900 dark:text-white',
contrast: 'bg-gray-800 text-white dark:bg-white dark:text-black',
success: 'bg-emerald-500 border-emerald-500 dark:bg-pavitra-blue dark:border-pavitra-blue text-white',
danger: 'bg-red-500 border-red-500 text-white',
warning: 'bg-yellow-500 border-yellow-500 text-white',
info: 'bg-blue-500 border-blue-500 dark:bg-pavitra-blue dark:border-pavitra-blue text-white',
};
Text Colors
The colorsText
object defines various text color styles:
export const colorsText = {
white: 'text-black dark:text-slate-100',
light: 'text-gray-700 dark:text-slate-400',
contrast: 'dark:text-white',
success: 'text-emerald-500',
danger: 'text-red-500',
warning: 'text-yellow-500',
info: 'text-blue-500',
};
Outline Colors
The colorsOutline
object defines various outline styles:
export const colorsOutline = {
white: [colorsText.white, 'border-gray-100'].join(' '),
light: [colorsText.light, 'border-gray-100'].join(' '),
contrast: [colorsText.contrast, 'border-gray-900 dark:border-slate-100'].join(' '),
success: [colorsText.success, 'border-emerald-500'].join(' '),
danger: [colorsText.danger, 'border-red-500'].join(' '),
warning: [colorsText.warning, 'border-yellow-500'].join(' '),
info: [colorsText.info, 'border-blue-500'].join(' '),
};
Button Styles
The getButtonColor
function defines styles for buttons:
export const getButtonColor = (
color: ColorButtonKey,
isOutlined: boolean,
hasHover: boolean,
isActive = false,
) => {
// Implementation
};
The main color types are enumerated in frontend/src/interfaces/index.ts
:
export type ColorKey =
| 'white'
| 'light'
| 'contrast'
| 'success'
| 'danger'
| 'warning'
| 'info';
The button color types used by the getButtonColor
function are also listed in frontend/src/interfaces/index.ts
:
export type ColorButtonKey =
| 'white'
| 'whiteDark'
| 'lightDark'
| 'contrast'
| 'success'
| 'danger'
| 'warning'
| 'info'
| 'void';
Styling Widgets
The frontend/src/styles.ts
file contains styles for the main widgets of the application:
interface StyleObject {
aside: string;
asideScrollbars: string;
asideBrand: string;
asideMenuItem: string;
asideMenuItemActive: string;
asideMenuDropdown: string;
navBarItemLabel: string;
navBarItemLabelHover: string;
navBarItemLabelActiveColor: string;
overlay: string;
}
The dataGridStyles
variable customizes the datagrid used in the project.
We use the @mui/x-data-grid
library for datagrid functionalities.
Managing Layouts
Currently, two layouts are used on the pages: Guest and Authenticated.
The Guest layout is for public pages, and the Authenticated layout is for private pages.
These layouts are in the frontend/src/layouts
directory.
Below is an example of how the Authenticated layout is used on the frontend/src/pages/dashboard.tsx
page:
import LayoutAuthenticated from '../layouts/Authenticated';
...
...
...
Dashboard.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};
Configuring Dark and Custom Themes
Theme styles are located in the file frontend/src/css/_theme.css
The frontend/src/stores/styleSlice.ts
file manages theme switching and theme management. The initialState
variable contains styles that participate in theme switching:
import * as styles from '../styles';
const initialState: StyleState = {
asideStyle: styles.white.aside,
asideScrollbarsStyle: styles.white.asideScrollbars,
asideBrandStyle: styles.white.asideBrand,
asideMenuItemStyle: styles.white.asideMenuItem,
asideMenuItemActiveStyle: styles.white.asideMenuItemActive,
asideMenuDropdownStyle: styles.white.asideMenuDropdown,
navBarItemLabelStyle: styles.white.navBarItemLabel,
navBarItemLabelHoverStyle: styles.white.navBarItemLabelHover,
navBarItemLabelActiveColorStyle: styles.white.navBarItemLabelActiveColor,
overlayStyle: styles.white.overlay,
darkMode: false,
};
Theme Management with Redux
Theme management is implemented using Redux. The reducer code is also contained in frontend/src/stores/styleSlice.ts
:
export const styleSlice = createSlice({
name: 'style',
initialState,
reducers: {
setDarkMode: (state, action: PayloadAction<boolean | null>) => {
// Implementation
},
setStyle: (state, action: PayloadAction<StyleKey>) => {
// Implementation
},
// Additional reducers
},
});
Using and Customizing Icons
We have components BaseIcon
and IconRounded
for working with icons, which can be found in the frontend/src/components
directory. We also use the @mdi/js
library for ready-made icons.
Below is an example of how BaseIcon
is used in the frontend/src/components/Pagination.tsx
component:
import {
mdiChevronDoubleLeft,
mdiChevronDoubleRight,
mdiChevronLeft,
mdiChevronRight,
} from '@mdi/js';
<div className='flex'>
<BaseIcon
path={mdiChevronDoubleLeft}
className='mr-2 text-pavitra-600 border-2 border-pavitra-600 rounded-full'
/>
<BaseIcon
path={mdiChevronLeft}
className='mr-2 text-pavitra-600 border-2 border-pavitra-600 rounded-full'
/>
</div>
This is how the pagination icons look: