mirror of
https://github.com/donpat1to/Schichtenplaner.git
synced 2025-12-01 15:05:45 +01:00
reworked scheduling
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
// frontend/src/design/DesignSystem.tsx
|
||||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
|
||||
// Design Tokens
|
||||
export const designTokens = {
|
||||
colors: {
|
||||
// Primary Colors
|
||||
white: '#FBFAF6',
|
||||
default_white: '#ddd', //boxes
|
||||
white: '#FBFAF6', //background, fonts
|
||||
black: '#161718',
|
||||
|
||||
// Purple Gradients
|
||||
@@ -122,275 +120,4 @@ export const designTokens = {
|
||||
xl: '1280px',
|
||||
'2xl': '1536px',
|
||||
},
|
||||
} as const;
|
||||
|
||||
// Context for Design System
|
||||
interface DesignSystemContextType {
|
||||
tokens: typeof designTokens;
|
||||
getColor: (path: string) => string;
|
||||
getSpacing: (size: keyof typeof designTokens.spacing) => string;
|
||||
}
|
||||
|
||||
const DesignSystemContext = createContext<DesignSystemContextType | undefined>(undefined);
|
||||
|
||||
// Design System Provider
|
||||
interface DesignSystemProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const DesignSystemProvider: React.FC<DesignSystemProviderProps> = ({ children }) => {
|
||||
const getColor = (path: string): string => {
|
||||
const parts = path.split('.');
|
||||
let current: any = designTokens.colors;
|
||||
|
||||
for (const part of parts) {
|
||||
if (current[part] === undefined) {
|
||||
console.warn(`Color path "${path}" not found in design tokens`);
|
||||
return designTokens.colors.primary;
|
||||
}
|
||||
current = current[part];
|
||||
}
|
||||
|
||||
return current;
|
||||
};
|
||||
|
||||
const getSpacing = (size: keyof typeof designTokens.spacing): string => {
|
||||
return designTokens.spacing[size];
|
||||
};
|
||||
|
||||
const value: DesignSystemContextType = {
|
||||
tokens: designTokens,
|
||||
getColor,
|
||||
getSpacing,
|
||||
};
|
||||
|
||||
return (
|
||||
<DesignSystemContext.Provider value={value}>
|
||||
{children}
|
||||
</DesignSystemContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// Hook to use Design System
|
||||
export const useDesignSystem = (): DesignSystemContextType => {
|
||||
const context = useContext(DesignSystemContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useDesignSystem must be used within a DesignSystemProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
// Utility Components
|
||||
export interface BoxProps {
|
||||
children?: ReactNode;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
p?: keyof typeof designTokens.spacing;
|
||||
px?: keyof typeof designTokens.spacing;
|
||||
py?: keyof typeof designTokens.spacing;
|
||||
m?: keyof typeof designTokens.spacing;
|
||||
mx?: keyof typeof designTokens.spacing;
|
||||
my?: keyof typeof designTokens.spacing;
|
||||
bg?: string;
|
||||
color?: string;
|
||||
borderRadius?: keyof typeof designTokens.borderRadius;
|
||||
}
|
||||
|
||||
export const Box: React.FC<BoxProps> = ({
|
||||
children,
|
||||
className,
|
||||
style,
|
||||
p,
|
||||
px,
|
||||
py,
|
||||
m,
|
||||
mx,
|
||||
my,
|
||||
bg,
|
||||
color,
|
||||
borderRadius,
|
||||
...props
|
||||
}) => {
|
||||
const { tokens, getColor } = useDesignSystem();
|
||||
|
||||
const boxStyle: React.CSSProperties = {
|
||||
padding: p && tokens.spacing[p],
|
||||
paddingLeft: px && tokens.spacing[px],
|
||||
paddingRight: px && tokens.spacing[px],
|
||||
paddingTop: py && tokens.spacing[py],
|
||||
paddingBottom: py && tokens.spacing[py],
|
||||
margin: m && tokens.spacing[m],
|
||||
marginLeft: mx && tokens.spacing[mx],
|
||||
marginRight: mx && tokens.spacing[mx],
|
||||
marginTop: my && tokens.spacing[my],
|
||||
marginBottom: my && tokens.spacing[my],
|
||||
backgroundColor: bg && getColor(bg),
|
||||
color: color && getColor(color),
|
||||
borderRadius: borderRadius && tokens.borderRadius[borderRadius],
|
||||
fontFamily: tokens.typography.fontFamily,
|
||||
...style,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={className} style={boxStyle} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export interface TextProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
variant?: 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl';
|
||||
weight?: keyof typeof designTokens.typography.fontWeights;
|
||||
color?: string;
|
||||
align?: 'left' | 'center' | 'right' | 'justify';
|
||||
lineHeight?: keyof typeof designTokens.typography.lineHeights;
|
||||
letterSpacing?: keyof typeof designTokens.typography.letterSpacing;
|
||||
}
|
||||
|
||||
export const Text: React.FC<TextProps> = ({
|
||||
children,
|
||||
className,
|
||||
style,
|
||||
variant = 'base',
|
||||
weight = 'normal',
|
||||
color = 'text.primary',
|
||||
align = 'left',
|
||||
lineHeight = 'normal',
|
||||
letterSpacing = 'normal',
|
||||
...props
|
||||
}) => {
|
||||
const { tokens, getColor } = useDesignSystem();
|
||||
|
||||
const textStyle: React.CSSProperties = {
|
||||
fontSize: tokens.typography.fontSizes[variant],
|
||||
fontWeight: tokens.typography.fontWeights[weight],
|
||||
color: getColor(color),
|
||||
textAlign: align,
|
||||
lineHeight: tokens.typography.lineHeights[lineHeight],
|
||||
letterSpacing: tokens.typography.letterSpacing[letterSpacing],
|
||||
fontFamily: tokens.typography.fontFamily,
|
||||
...style,
|
||||
};
|
||||
|
||||
return (
|
||||
<span className={className} style={textStyle} {...props}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
// Global Styles Component
|
||||
export const GlobalStyles: React.FC = () => {
|
||||
const { tokens } = useDesignSystem();
|
||||
|
||||
const globalStyles = `
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: ${tokens.typography.fontFamily};
|
||||
font-size: 16px;
|
||||
line-height: ${tokens.typography.lineHeights.normal};
|
||||
color: ${tokens.colors.text.primary};
|
||||
background-color: ${tokens.colors.background};
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: ${tokens.typography.fontFamily};
|
||||
font-weight: ${tokens.typography.fontWeights.normal};
|
||||
line-height: ${tokens.typography.lineHeights.normal};
|
||||
color: ${tokens.colors.text.primary};
|
||||
background-color: ${tokens.colors.background};
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: ${tokens.typography.fontFamily};
|
||||
font-weight: ${tokens.typography.fontWeights.bold};
|
||||
line-height: ${tokens.typography.lineHeights.tight};
|
||||
color: ${tokens.colors.text.primary};
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: ${tokens.typography.fontSizes['4xl']};
|
||||
letter-spacing: ${tokens.typography.letterSpacing.tight};
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: ${tokens.typography.fontSizes['3xl']};
|
||||
letter-spacing: ${tokens.typography.letterSpacing.tight};
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: ${tokens.typography.fontSizes['2xl']};
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: ${tokens.typography.fontSizes.xl};
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: ${tokens.typography.fontSizes.lg};
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: ${tokens.typography.fontSizes.base};
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: ${tokens.typography.fontSizes.base};
|
||||
line-height: ${tokens.typography.lineHeights.relaxed};
|
||||
color: ${tokens.colors.text.primary};
|
||||
}
|
||||
|
||||
a {
|
||||
color: ${tokens.colors.primary};
|
||||
text-decoration: none;
|
||||
transition: ${tokens.transitions.default};
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: ${tokens.colors.secondary};
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: ${tokens.typography.fontFamily};
|
||||
transition: ${tokens.transitions.default};
|
||||
}
|
||||
|
||||
input, textarea, select {
|
||||
font-family: ${tokens.typography.fontFamily};
|
||||
}
|
||||
|
||||
/* Scrollbar Styling */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: ${tokens.colors.background};
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: ${tokens.colors.border.medium};
|
||||
border-radius: ${tokens.borderRadius.full};
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: ${tokens.colors.border.dark};
|
||||
}
|
||||
`;
|
||||
|
||||
return <style>{globalStyles}</style>;
|
||||
};
|
||||
|
||||
export default designTokens;
|
||||
} as const;
|
||||
Reference in New Issue
Block a user