@cyber-harbour/ui 1.0.27 → 1.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyber-harbour/ui",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,17 @@
1
+ import { createComponent, FabricComponent } from '../../Theme';
2
+ import { styled } from 'styled-components';
3
+
4
+ type BoxProps = FabricComponent<{
5
+ children: any;
6
+ }>;
7
+
8
+ export const Box = styled(createComponent<BoxProps>('div'))(
9
+ ({ theme }) => `
10
+ padding: ${theme.box.padding};
11
+ border-radius: ${theme.box.borderRadius};
12
+ background-color: ${theme.box.background};
13
+ border-width: ${theme.box.border.width};
14
+ border-style: ${theme.box.border.style};
15
+ border-color: ${theme.box.border.color};
16
+ `
17
+ );
@@ -0,0 +1 @@
1
+ export * from './Box';
@@ -7,9 +7,11 @@ import {
7
7
  getButtonStyles,
8
8
  getButtonSizeStyles,
9
9
  ButtonElementStyle,
10
+ createComponent,
11
+ FabricComponent,
10
12
  } from '../../Theme';
11
13
 
12
- interface BaseButtonProps {
14
+ type BaseButtonProps = FabricComponent<{
13
15
  children?: any;
14
16
  variant?: ButtonVariant;
15
17
  color?: ButtonColor;
@@ -19,10 +21,14 @@ interface BaseButtonProps {
19
21
  className?: string;
20
22
  icon?: any;
21
23
  iconPosition?: 'left' | 'right';
22
- }
24
+ iconVariant?: 'filled' | 'empty';
25
+ }>;
23
26
 
24
- export type ButtonProps = BaseButtonProps &
25
- (React.AnchorHTMLAttributes<HTMLAnchorElement> | React.ButtonHTMLAttributes<HTMLButtonElement>);
27
+ export type ButtonProps = (
28
+ | Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'children'>
29
+ | Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'>
30
+ ) &
31
+ BaseButtonProps;
26
32
 
27
33
  const getCss = (styles: ButtonElementStyle) => `
28
34
  background: ${styles.background};
@@ -31,26 +37,54 @@ const getCss = (styles: ButtonElementStyle) => `
31
37
  box-shadow: ${styles.boxShadow};
32
38
  `;
33
39
 
40
+ const getIconStyles = (styles: ButtonElementStyle) =>
41
+ styles.filledIcon
42
+ ? `
43
+ color: ${styles.filledIcon.color};
44
+ background: ${styles.filledIcon.background};
45
+ `
46
+ : '';
47
+
34
48
  // Створюємо стилізований компонент, що використовує уніфіковану палітру
35
- const StyledButton = styled.button<{
49
+ const ButtonTextContainer = styled.div`
50
+ text-overflow: ellipsis;
51
+ overflow: hidden;
52
+ white-space: nowrap;
53
+ `;
54
+
55
+ const StyledIconWrapper = styled.span`
56
+ display: inline-flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ `;
60
+
61
+ const StyledButton = styled(createComponent('button'))<{
36
62
  $variant: ButtonVariant;
37
63
  $color: ButtonColor;
38
64
  $size: ButtonSize;
39
65
  $disabled: boolean;
40
66
  $fullWidth: boolean;
41
67
  $iconPosition: 'left' | 'right';
68
+ $iconVariant: 'filled' | 'empty';
42
69
  }>`
43
- ${({ $variant, $color, $size, $disabled, $fullWidth, $iconPosition, theme }) => {
70
+ ${({ $variant, $color, $size, $disabled, $fullWidth, $iconPosition, $iconVariant, theme, ...props }) => {
44
71
  const sizes = getButtonSizeStyles(theme, $size);
45
72
  return `
46
73
  ${getCss(getButtonStyles(theme, $variant, $color, 'default'))}
47
74
  font-size: ${sizes.fontSize};
48
75
  gap: ${sizes.gap};
49
- padding-block: ${sizes.paddingBlock};
50
- padding-inline: ${sizes.paddingInline};
76
+ ${
77
+ $variant !== 'empty'
78
+ ? `
79
+ ${!props.py ? `padding-block: ${sizes.paddingBlock};` : ''}
80
+ ${!props.px ? `padding-inline: ${sizes.paddingInline};` : ''}
81
+ `
82
+ : ''
83
+ }
51
84
  border-radius: ${sizes.borderRadius};
52
85
  border-width: ${sizes.borderWidth};
53
86
  border-style: solid;
87
+ max-width: 100%;
54
88
  width: ${$fullWidth ? '100%' : 'auto'};
55
89
  cursor: ${$disabled ? 'not-allowed' : 'pointer'};
56
90
  font-weight: 500;
@@ -78,7 +112,39 @@ const StyledButton = styled.button<{
78
112
  svg {
79
113
  width: ${sizes.iconSize};
80
114
  height: ${sizes.iconSize};
115
+
81
116
  }
117
+
118
+ ${
119
+ $iconVariant === 'filled'
120
+ ? `
121
+ ${StyledIconWrapper} {
122
+ width: 24px;
123
+ height: 24px;
124
+ border-radius: ${sizes.borderRadius};
125
+ transition: all 0.2s ease;
126
+ ${getIconStyles(getButtonStyles(theme, $variant, $color, 'default'))}
127
+ }
128
+ &:hover {
129
+ ${StyledIconWrapper} {
130
+ ${getIconStyles(getButtonStyles(theme, $variant, $color, 'hover'))}
131
+ }
132
+ }
133
+
134
+ &:active {
135
+ ${StyledIconWrapper} {
136
+ ${getIconStyles(getButtonStyles(theme, $variant, $color, 'active'))}
137
+ }
138
+ }
139
+
140
+ &:disabled {
141
+ ${StyledIconWrapper} {
142
+ ${getIconStyles(getButtonStyles(theme, $variant, $color, 'disabled'))}
143
+ }
144
+ }
145
+ `
146
+ : ``
147
+ }
82
148
  `;
83
149
  }}
84
150
  `;
@@ -93,6 +159,7 @@ export const Button = ({
93
159
  className,
94
160
  icon,
95
161
  iconPosition = 'left',
162
+ iconVariant = 'empty',
96
163
  ...props
97
164
  }: ButtonProps) => {
98
165
  return (
@@ -104,12 +171,13 @@ export const Button = ({
104
171
  $disabled={disabled}
105
172
  $fullWidth={fullWidth}
106
173
  $iconPosition={iconPosition}
174
+ $iconVariant={iconVariant}
107
175
  disabled={disabled}
108
176
  className={className}
109
177
  {...props}
110
178
  >
111
- {icon}
112
- <div>{children}</div>
179
+ {!!icon && <StyledIconWrapper>{icon}</StyledIconWrapper>}
180
+ {!!children && <ButtonTextContainer>{children}</ButtonTextContainer>}
113
181
  </StyledButton>
114
182
  );
115
183
  };
@@ -0,0 +1,83 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ export type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';
5
+ export type FlexWrap = 'nowrap' | 'wrap' | 'wrap-reverse';
6
+ export type FlexJustify = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly';
7
+ export type FlexAlign = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
8
+ export type FlexGap = string | number;
9
+
10
+ export interface FlexContainerProps {
11
+ children: any;
12
+ direction?: FlexDirection;
13
+ wrap?: FlexWrap;
14
+ justify?: FlexJustify;
15
+ align?: FlexAlign;
16
+ alignContent?: FlexAlign;
17
+ gap?: FlexGap;
18
+ rowGap?: FlexGap;
19
+ columnGap?: FlexGap;
20
+ className?: string;
21
+ style?: CSSProperties;
22
+ as?: any; // TODO: fix type to styled component or intrinsic element
23
+ }
24
+
25
+ export const FlexContainer = ({
26
+ children,
27
+ direction = 'row',
28
+ wrap = 'nowrap',
29
+ justify = 'flex-start',
30
+ align = 'stretch',
31
+ alignContent,
32
+ gap,
33
+ rowGap,
34
+ columnGap,
35
+ className,
36
+ style,
37
+ as = 'div',
38
+ }: FlexContainerProps) => {
39
+ return (
40
+ <StyledFlexContainer
41
+ as={as}
42
+ $direction={direction}
43
+ $wrap={wrap}
44
+ $justify={justify}
45
+ $align={align}
46
+ $alignContent={alignContent}
47
+ $gap={gap}
48
+ $rowGap={rowGap}
49
+ $columnGap={columnGap}
50
+ className={className}
51
+ style={style}
52
+ >
53
+ {children}
54
+ </StyledFlexContainer>
55
+ );
56
+ };
57
+
58
+ interface StyledFlexContainerProps {
59
+ $direction: FlexDirection;
60
+ $wrap: FlexWrap;
61
+ $justify: FlexJustify;
62
+ $align: FlexAlign;
63
+ $alignContent?: FlexAlign;
64
+ $gap?: FlexGap;
65
+ $rowGap?: FlexGap;
66
+ $columnGap?: FlexGap;
67
+ }
68
+
69
+ const StyledFlexContainer = styled.div<StyledFlexContainerProps>`
70
+ ${({ $direction, $wrap, $justify, $align, $alignContent, $gap, $rowGap, $columnGap }) => `
71
+ display: flex;
72
+ width: 100%;
73
+ min-width: 0;
74
+ flex-direction: ${$direction};
75
+ flex-wrap: ${$wrap};
76
+ justify-content: ${$justify};
77
+ align-items: ${$align};
78
+ ${$alignContent ? `align-content: ${$alignContent};` : ''}
79
+ ${$gap !== undefined ? `gap: ${typeof $gap === 'number' ? `${$gap}px` : $gap};` : ''}
80
+ ${$rowGap !== undefined ? `row-gap: ${typeof $rowGap === 'number' ? `${$rowGap}px` : $rowGap};` : ''}
81
+ ${$columnGap !== undefined ? `column-gap: ${typeof $columnGap === 'number' ? `${$columnGap}px` : $columnGap};` : ''}
82
+ `}
83
+ `;
@@ -0,0 +1,65 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ import { styled } from 'styled-components';
3
+
4
+ export type FlexItemGrow = number;
5
+ export type FlexItemShrink = number;
6
+ export type FlexItemBasis = string | number;
7
+ export type FlexItemAlign = 'auto' | 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch';
8
+
9
+ export interface FlexItemProps {
10
+ children?: any;
11
+ grow?: FlexItemGrow;
12
+ shrink?: FlexItemShrink;
13
+ basis?: FlexItemBasis;
14
+ align?: FlexItemAlign;
15
+ order?: number;
16
+ className?: string;
17
+ style?: CSSProperties;
18
+ as?: any; //TODO: fix type to styled component or intrinsic element
19
+ }
20
+
21
+ export const FlexItem = ({
22
+ children,
23
+ grow,
24
+ shrink,
25
+ basis,
26
+ align,
27
+ order,
28
+ className,
29
+ style,
30
+ as = 'div',
31
+ }: FlexItemProps) => {
32
+ return (
33
+ <StyledFlexItem
34
+ as={as}
35
+ $grow={grow}
36
+ $shrink={shrink}
37
+ $basis={basis}
38
+ $align={align}
39
+ $order={order}
40
+ className={className}
41
+ style={style}
42
+ >
43
+ {children}
44
+ </StyledFlexItem>
45
+ );
46
+ };
47
+
48
+ interface StyledFlexItemProps {
49
+ $grow?: FlexItemGrow;
50
+ $shrink?: FlexItemShrink;
51
+ $basis?: FlexItemBasis;
52
+ $align?: FlexItemAlign;
53
+ $order?: number;
54
+ }
55
+
56
+ const StyledFlexItem = styled.div<StyledFlexItemProps>`
57
+ ${({ $grow, $shrink, $basis, $align, $order }) => `
58
+ min-width: 0;
59
+ ${$grow !== undefined ? `flex-grow: ${$grow};` : ''}
60
+ ${$shrink !== undefined ? `flex-shrink: ${$shrink};` : ''}
61
+ ${$basis !== undefined ? `flex-basis: ${typeof $basis === 'number' ? `${$basis}px` : $basis};` : ''}
62
+ ${$align ? `align-self: ${$align};` : ''}
63
+ ${$order !== undefined ? `order: ${$order};` : ''}
64
+ `}
65
+ `;
@@ -0,0 +1,4 @@
1
+ import { FlexContainer } from './FlexContainer';
2
+ import { FlexItem } from './FlexItem';
3
+
4
+ export { FlexContainer, FlexItem };
@@ -0,0 +1,28 @@
1
+ import { SVGProps } from 'react';
2
+
3
+ interface MaximizeIconProps extends SVGProps<SVGSVGElement> {
4
+ fill?: string;
5
+ }
6
+
7
+ export const MaximizeIcon = ({ fill = 'currentColor', ...props }: MaximizeIconProps) => {
8
+ return (
9
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <path
11
+ d="M14 6.5C13.7267 6.5 13.5 6.27333 13.5 6V2.5H10C9.72667 2.5 9.5 2.27333 9.5 2C9.5 1.72667 9.72667 1.5 10 1.5H14C14.2733 1.5 14.5 1.72667 14.5 2V6C14.5 6.27333 14.2733 6.5 14 6.5Z"
12
+ fill={fill}
13
+ />
14
+ <path
15
+ d="M6 14.5H2C1.72667 14.5 1.5 14.2733 1.5 14V10C1.5 9.72667 1.72667 9.5 2 9.5C2.27333 9.5 2.5 9.72667 2.5 10V13.5H6C6.27333 13.5 6.5 13.7267 6.5 14C6.5 14.2733 6.27333 14.5 6 14.5Z"
16
+ fill={fill}
17
+ />
18
+ <path
19
+ d="M8.9998 7.50224C8.87313 7.50224 8.74646 7.45557 8.64646 7.35557C8.45313 7.16224 8.45313 6.84224 8.64646 6.64891L13.6465 1.64891C13.8398 1.45557 14.1598 1.45557 14.3531 1.64891C14.5465 1.84224 14.5465 2.16224 14.3531 2.35557L9.35313 7.35557C9.25313 7.45557 9.12646 7.50224 8.9998 7.50224Z"
20
+ fill={fill}
21
+ />
22
+ <path
23
+ d="M1.9998 14.5022C1.87313 14.5022 1.74646 14.4556 1.64646 14.3556C1.45313 14.1622 1.45313 13.8422 1.64646 13.6489L6.64646 8.64891C6.8398 8.45557 7.1598 8.45557 7.35313 8.64891C7.54646 8.84224 7.54646 9.16224 7.35313 9.35557L2.35313 14.3556C2.25313 14.4556 2.12646 14.5022 1.9998 14.5022Z"
24
+ fill={fill}
25
+ />
26
+ </svg>
27
+ );
28
+ };
@@ -0,0 +1,14 @@
1
+ import { SVGProps } from 'react';
2
+
3
+ interface SearchIconProps extends SVGProps<SVGSVGElement> {
4
+ stroke?: string;
5
+ }
6
+
7
+ export const SearchIcon = ({ stroke = 'currentColor', ...props }: SearchIconProps) => {
8
+ return (
9
+ <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
+ <ellipse cx="5.80004" cy="5.80062" rx="4.80004" ry="4.80062" stroke={stroke} />
11
+ <path d="M9.00012 9.80078L13.0002 12.9997" stroke={stroke} strokeLinecap="round" strokeLinejoin="round" />
12
+ </svg>
13
+ );
14
+ };
@@ -28,6 +28,7 @@ export { PrintIcon } from './PrintIcon';
28
28
  export { Profiler2Icon } from './Profiler2Icon';
29
29
  export { ProfilerIcon } from './ProfilerIcon';
30
30
  export { SandBoxIcon } from './SandBoxIcon';
31
+ export { SearchIcon } from './SearchIcon';
31
32
  export { StatisticIcon } from './StatisticIcon';
32
33
  export { SunIcon } from './SunIcon';
33
34
  export { UpRightArrowCircleIcon } from './UpRightArrowCircleIcon';
@@ -41,3 +42,4 @@ export { UsersIcon } from './Users';
41
42
  export { InfoCircleFilledIcon } from './InfoCircleFilled';
42
43
  export { UnfoldIcon } from './Unfold';
43
44
  export { CrossIcon } from './Cross';
45
+ export { MaximizeIcon } from './MaximizeIcon';
@@ -0,0 +1,24 @@
1
+ import { createComponent, FabricComponent, pxToRem } from '../../Theme';
2
+ import { styled } from 'styled-components';
3
+
4
+ type LineProps = FabricComponent<
5
+ {
6
+ direction?: 'horizontal' | 'vertical';
7
+ } & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, 'children'>
8
+ >;
9
+
10
+ export const Line = ({ direction = 'horizontal', ...props }: LineProps) => {
11
+ return <StyledLine {...props} $direction={direction} />;
12
+ };
13
+
14
+ interface StyledLineProps {
15
+ $direction: 'horizontal' | 'vertical';
16
+ }
17
+
18
+ const StyledLine = styled(createComponent('div'))<StyledLineProps>(
19
+ ({ theme, $direction }) => `
20
+ width: ${$direction === 'horizontal' ? '100%' : theme.line.size};
21
+ height: ${$direction === 'vertical' ? '100%' : theme.line.size};
22
+ background-color: ${theme.line.color};
23
+ `
24
+ );
@@ -0,0 +1 @@
1
+ export * from './Line';
@@ -1,20 +1,21 @@
1
1
  import styled from 'styled-components';
2
2
  import { CSSProperties, ElementType, ReactNode } from 'react';
3
- import { ColorVariant, TypographyVariant } from '../../Theme';
3
+ import { ColorVariant, createComponent, FabricComponent, TypographyVariant } from '../../Theme';
4
4
  import { resolveThemeColor } from '../../Theme/utils';
5
5
 
6
- export interface TypographyProps {
6
+ type TypographyProps = FabricComponent<{
7
+ style?: CSSProperties;
7
8
  variant?: TypographyVariant;
8
9
  element?: ElementType;
9
10
  children: any;
10
11
  weight?: CSSProperties['fontWeight'];
11
- style?: CSSProperties['fontStyle'];
12
+ fontStyle?: CSSProperties['fontStyle'];
12
13
  color?: ColorVariant | string;
13
14
  className?: string;
14
- }
15
+ }>;
15
16
 
16
17
  // Create a styled component that can be dynamically rendered as different HTML elements
17
- const StyledTypography = styled.div<{
18
+ const StyledTypography = styled(createComponent('div'))<{
18
19
  $variant: TypographyVariant;
19
20
  $weight?: CSSProperties['fontWeight'];
20
21
  $style?: CSSProperties['fontStyle'];
@@ -35,9 +36,10 @@ export const Typography = ({
35
36
  element,
36
37
  children,
37
38
  weight,
38
- style,
39
+ fontStyle,
39
40
  color,
40
41
  className,
42
+ style,
41
43
  }: TypographyProps) => {
42
44
  // Determine which HTML element to render based on the variant if not explicitly specified
43
45
  const Element = element || (variant.startsWith('h') ? variant : 'p');
@@ -47,9 +49,10 @@ export const Typography = ({
47
49
  as={Element}
48
50
  $variant={variant}
49
51
  $weight={weight}
50
- $style={style}
52
+ $style={fontStyle}
51
53
  $color={color}
52
54
  className={className}
55
+ style={style}
53
56
  >
54
57
  {children}
55
58
  </StyledTypography>
@@ -1,2 +1 @@
1
- export { Typography } from './Typography';
2
- export type { TypographyProps } from './Typography';
1
+ export * from './Typography';
package/src/Core/index.ts CHANGED
@@ -10,3 +10,6 @@ export * from './ContextMenu';
10
10
  export * from './Select';
11
11
  export * from './RowActionsMenu';
12
12
  export * from './Input';
13
+ export * from './Flex';
14
+ export * from './Box';
15
+ export * from './Line';
@@ -0,0 +1,30 @@
1
+ import styled from 'styled-components';
2
+
3
+ interface FullscreenCardProps {
4
+ children: any;
5
+ position: 'absolute' | 'fixed';
6
+ isActive: boolean;
7
+ }
8
+
9
+ export const FullscreenCard = ({ isActive, position, ...props }: FullscreenCardProps) => {
10
+ return <StyledContainer $isActive={isActive} $position={position} {...props} />;
11
+ };
12
+
13
+ const StyledContainer = styled.div<{ $isActive: boolean; $position: 'absolute' | 'fixed' }>(
14
+ ({ $isActive, $position }) => `
15
+ ${
16
+ $isActive
17
+ ? `
18
+ position: ${$position};
19
+ top: 0;
20
+ left: 0;
21
+ height: 100%;
22
+ width: 100%;
23
+ z-index: 1000;
24
+ `
25
+ : ''
26
+ }
27
+
28
+ min-width: 0;
29
+ `
30
+ );
@@ -0,0 +1 @@
1
+ export * from './FullscreenCard';
@@ -0,0 +1,18 @@
1
+ import { createComponent, FabricComponent, pxToRem } from '../../Theme';
2
+ import { styled } from 'styled-components';
3
+
4
+ type ContainerProps = FabricComponent<{
5
+ children: any;
6
+ maxWidth?: string | number;
7
+ }>;
8
+
9
+ export const Container = ({ ...props }: ContainerProps) => {
10
+ return <StyledContainer {...props} />;
11
+ };
12
+
13
+ const StyledContainer = styled(createComponent<ContainerProps>('div'))`
14
+ padding-inline: ${pxToRem(20)};
15
+ width: 100%;
16
+ min-width: 0;
17
+ max-width: ${({ maxWidth }) => (typeof maxWidth === 'number' ? pxToRem(maxWidth) : maxWidth || '100%')};
18
+ `;
@@ -0,0 +1 @@
1
+ export * from './Container';
@@ -1 +1,2 @@
1
1
  export * from './PageLayout';
2
+ export * from './Container';
@@ -1,12 +1,21 @@
1
- import { ThemeProvider as ThemeProviderStyled } from 'styled-components';
1
+ import { StyleSheetManager, ThemeProvider as ThemeProviderStyled, WebTarget } from 'styled-components';
2
2
  import { lightTheme } from './theme';
3
3
  import { GlobalStyle } from './GlobalStyle';
4
4
 
5
5
  export const ThemeProvider = ({ children }: { children: any }) => {
6
6
  return (
7
- <ThemeProviderStyled theme={lightTheme}>
8
- <GlobalStyle />
9
- {children}
10
- </ThemeProviderStyled>
7
+ <StyleSheetManager shouldForwardProp={shouldForwardProp}>
8
+ <ThemeProviderStyled theme={lightTheme}>
9
+ <GlobalStyle />
10
+ {children}
11
+ </ThemeProviderStyled>
12
+ </StyleSheetManager>
11
13
  );
12
14
  };
15
+
16
+ function shouldForwardProp(propName: any, target: WebTarget) {
17
+ if (typeof target === 'string') {
18
+ return !['m', 'mt', 'mr', 'mb', 'ml', 'mx', 'my', 'p', 'pt', 'pr', 'pb', 'pl', 'px', 'py'].includes(propName);
19
+ }
20
+ return true;
21
+ }
@@ -0,0 +1,70 @@
1
+ import styled, { css, WebTarget } from 'styled-components';
2
+
3
+ type MarginProps = {
4
+ m?: string | number; // margin
5
+ mt?: string | number; // margin-top
6
+ mr?: string | number; // margin-right
7
+ mb?: string | number; // margin-bottom
8
+ ml?: string | number; // margin-left
9
+ mx?: string | number; // margin-left + margin-right
10
+ my?: string | number; // margin-top + margin-bottom
11
+ p?: string | number; // padding
12
+ pt?: string | number; // padding-top
13
+ pr?: string | number; // padding-right
14
+ pb?: string | number; // padding-bottom
15
+ pl?: string | number; // padding-left
16
+ px?: string | number; // padding-left + padding-right
17
+ py?: string | number; // padding-top + padding-bottom
18
+ };
19
+
20
+ export type FabricComponent<T = object> = T & MarginProps;
21
+
22
+ const marginStyles = css<FabricComponent>((props) => {
23
+ return `
24
+ ${props.m ? `margin: ${typeof props.m === 'number' ? `${props.m}px` : props.m};` : ''}
25
+ ${props.mt ? `margin-top: ${typeof props.mt === 'number' ? `${props.mt}px` : props.mt};` : ''}
26
+ ${props.mr ? `margin-right: ${typeof props.mr === 'number' ? `${props.mr}px` : props.mr};` : ''}
27
+ ${props.mb ? `margin-bottom: ${typeof props.mb === 'number' ? `${props.mb}px` : props.mb};` : ''}
28
+ ${props.ml ? `margin-left: ${typeof props.ml === 'number' ? `${props.ml}px` : props.ml};` : ''}
29
+ ${
30
+ props.mx
31
+ ? `margin-left: ${typeof props.mx === 'number' ? `${props.mx}px` : props.mx}; margin-right: ${
32
+ typeof props.mx === 'number' ? `${props.mx}px` : props.mx
33
+ };`
34
+ : ''
35
+ }
36
+ ${
37
+ props.my
38
+ ? `margin-top: ${typeof props.my === 'number' ? `${props.my}px` : props.my}; margin-bottom: ${
39
+ typeof props.my === 'number' ? `${props.my}px` : props.my
40
+ };`
41
+ : ''
42
+ }
43
+ ${props.p ? `padding: ${typeof props.p === 'number' ? `${props.p}px` : props.p};` : ''}
44
+ ${props.pt ? `padding-top: ${typeof props.pt === 'number' ? `${props.pt}px` : props.pt};` : ''}
45
+ ${props.pr ? `padding-right: ${typeof props.pr === 'number' ? `${props.pr}px` : props.pr};` : ''}
46
+ ${props.pb ? `padding-bottom: ${typeof props.pb === 'number' ? `${props.pb}px` : props.pb};` : ''}
47
+ ${props.pl ? `padding-left: ${typeof props.pl === 'number' ? `${props.pl}px` : props.pl};` : ''}
48
+ ${
49
+ props.px
50
+ ? `padding-left: ${typeof props.px === 'number' ? `${props.px}px` : props.px}; padding-right: ${
51
+ typeof props.px === 'number' ? `${props.px}px` : props.px
52
+ };`
53
+ : ''
54
+ }
55
+ ${
56
+ props.py
57
+ ? `padding-top: ${typeof props.py === 'number' ? `${props.py}px` : props.py}; padding-bottom: ${
58
+ typeof props.py === 'number' ? `${props.py}px` : props.py
59
+ };`
60
+ : ''
61
+ }
62
+
63
+ `;
64
+ });
65
+
66
+ export const createComponent = <T = object>(element: WebTarget) => {
67
+ return styled(element)<FabricComponent<T>>`
68
+ ${marginStyles};
69
+ `;
70
+ };
@@ -3,3 +3,4 @@ export * from './ThemeProvider';
3
3
  export * from './utils';
4
4
  export * from './types';
5
5
  export * from './theme';
6
+ export * from './componentFabric';