@cyber-harbour/ui 1.0.47 → 1.0.49

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.47",
3
+ "version": "1.0.49",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,81 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { FabricComponent, createComponent, generatePropertySpaceStyle } from '../../Theme';
4
+ import { AlertIcon } from '../IconComponents';
5
+
6
+ type AlertProps = FabricComponent<{
7
+ title?: any;
8
+ note?: any;
9
+ }> &
10
+ Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>;
11
+
12
+ export const Alert = ({ title, note, ...props }: AlertProps) => {
13
+ return (
14
+ <StyledContainer {...props}>
15
+ <IconWrapper>
16
+ <AlertIcon />
17
+ </IconWrapper>
18
+ <div>
19
+ {!!title && <Title>{title}</Title>}
20
+ {!!note && <Note>{note}</Note>}
21
+ </div>
22
+ </StyledContainer>
23
+ );
24
+ };
25
+
26
+ const IconWrapper = styled.div(
27
+ ({ theme: { alert } }) => `
28
+ flex-shrink: 0;
29
+ color: ${alert.color.icon};
30
+ padding-top: ${alert.icon.paddingTop};
31
+ svg {
32
+ width: ${alert.icon.width};
33
+ height: ${alert.icon.height};
34
+ display: block;
35
+ }
36
+ `
37
+ );
38
+
39
+ const Title = styled.h3(
40
+ ({ theme: { alert } }) => `
41
+ margin: 0;
42
+ padding: 0;
43
+ font-size: ${alert.fontSize};
44
+ line-height: 1.2;
45
+ font-weight: 700;
46
+ color: ${alert.color.text};
47
+ &:not(:last-child) {
48
+ margin-bottom: 8px;
49
+ }
50
+ `
51
+ );
52
+ const Note = styled.p(
53
+ ({ theme: { alert } }) => `
54
+ margin: 0;
55
+ padding: 0;
56
+ word-break: break-word;
57
+ font-size: ${alert.fontSize};
58
+ color: ${alert.color.text};
59
+ line-height: 1.5;
60
+ `
61
+ );
62
+
63
+ const StyledContainer = createComponent(
64
+ styled.div<FabricComponent>(
65
+ ({ theme, py = theme.alert.paddingBlock, pl = theme.alert.paddingLeft, pr = theme.alert.paddingRight }) => {
66
+ return `
67
+ display: flex;
68
+ align-items: flex-start;
69
+ justify-content: flex-start;
70
+ flex-wrap: nowrap;
71
+ gap: ${theme.alert.gap};
72
+ background-color: ${theme.alert.color.background};
73
+ border-radius: ${theme.alert.borderRadius};
74
+ ${generatePropertySpaceStyle(theme, 'padding-block', py)};
75
+ ${generatePropertySpaceStyle(theme, 'padding-right', pr)};
76
+ ${generatePropertySpaceStyle(theme, 'padding-left', pl)};
77
+ `;
78
+ }
79
+ ),
80
+ { ignoreStyles: ['padding-block', 'padding-right', 'padding-left'] }
81
+ );
@@ -0,0 +1 @@
1
+ export * from './Alert';
@@ -1,4 +1,4 @@
1
- import { createComponent, FabricComponent } from '../../Theme';
1
+ import { createComponent, FabricComponent, generatePropertySpaceStyle } from '../../Theme';
2
2
  import { styled } from 'styled-components';
3
3
 
4
4
  type BoxProps = FabricComponent<
@@ -11,13 +11,19 @@ export const Box = ({ children, ...props }: BoxProps) => {
11
11
  return <StyledBox {...props}>{children}</StyledBox>;
12
12
  };
13
13
 
14
- const StyledBox = styled(createComponent('div'))(
15
- ({ theme }) => `
16
- padding: ${theme.box.padding};
14
+ const StyledBox = createComponent(
15
+ styled('div')<FabricComponent>(
16
+ ({ theme, px = theme.box.padding, py = theme.box.padding }) => `
17
+ ${generatePropertySpaceStyle(theme, 'padding-inline', px)}
18
+ ${generatePropertySpaceStyle(theme, 'padding-block', py)}
17
19
  border-radius: ${theme.box.borderRadius};
18
20
  background-color: ${theme.box.background};
19
21
  border-width: ${theme.box.border.width};
20
22
  border-style: ${theme.box.border.style};
21
23
  border-color: ${theme.box.border.color};
22
24
  `
25
+ ),
26
+ {
27
+ ignoreStyles: ['padding-inline', 'padding-block'],
28
+ }
23
29
  );
@@ -9,6 +9,7 @@ import {
9
9
  ButtonElementStyle,
10
10
  createComponent,
11
11
  FabricComponent,
12
+ generatePropertySpaceStyle,
12
13
  } from '../../Theme';
13
14
 
14
15
  type BaseButtonProps = FabricComponent<{
@@ -59,7 +60,7 @@ const StyledIconWrapper = styled.span`
59
60
  justify-content: center;
60
61
  `;
61
62
 
62
- const StyledButton = styled(createComponent('button'))<{
63
+ type StyledButtonProps = {
63
64
  $variant: ButtonVariant;
64
65
  $color: ButtonColor;
65
66
  $size: ButtonSize;
@@ -67,21 +68,28 @@ const StyledButton = styled(createComponent('button'))<{
67
68
  $fullWidth: boolean;
68
69
  $iconPosition: 'left' | 'right';
69
70
  $iconVariant: 'filled' | 'empty';
70
- }>`
71
- ${({ $variant, $color, $size, $disabled, $fullWidth, $iconPosition, $iconVariant, theme, ...props }) => {
71
+ };
72
+
73
+ const Btn = styled.button<FabricComponent<StyledButtonProps>>(
74
+ ({
75
+ $variant,
76
+ $color,
77
+ $size,
78
+ $disabled,
79
+ $fullWidth,
80
+ $iconPosition,
81
+ $iconVariant,
82
+ theme,
83
+ px = $variant !== 'empty' ? theme.button.sizes[$size].paddingInline : 0,
84
+ py = $variant !== 'empty' ? theme.button.sizes[$size].paddingBlock : 0,
85
+ }) => {
72
86
  const sizes = getButtonSizeStyles(theme, $size);
73
87
  return `
74
88
  ${getCss(getButtonStyles(theme, $variant, $color, 'default'))}
75
89
  font-size: ${sizes.fontSize};
76
90
  gap: ${sizes.gap};
77
- ${
78
- $variant !== 'empty'
79
- ? `
80
- ${!props.py ? `padding-block: ${sizes.paddingBlock};` : ''}
81
- ${!props.px ? `padding-inline: ${sizes.paddingInline};` : ''}
82
- `
83
- : ''
84
- }
91
+ ${generatePropertySpaceStyle(theme, 'padding-block', py)};
92
+ ${generatePropertySpaceStyle(theme, 'padding-inline', px)};
85
93
  border-radius: ${sizes.borderRadius};
86
94
  border-width: ${sizes.borderWidth};
87
95
  border-style: solid;
@@ -147,8 +155,9 @@ const StyledButton = styled(createComponent('button'))<{
147
155
  : ``
148
156
  }
149
157
  `;
150
- }}
151
- `;
158
+ }
159
+ );
160
+ const StyledButton = createComponent(Btn);
152
161
 
153
162
  export const Button = ({
154
163
  children,
@@ -1,4 +1,5 @@
1
1
  import { CSSProperties, forwardRef } from 'react';
2
+ import { createComponent, FabricComponent } from '../../Theme';
2
3
  import styled from 'styled-components';
3
4
 
4
5
  export type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';
@@ -7,7 +8,7 @@ export type FlexJustify = 'flex-start' | 'flex-end' | 'center' | 'space-between'
7
8
  export type FlexAlign = 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline';
8
9
  export type FlexGap = string | number;
9
10
 
10
- export interface FlexContainerProps {
11
+ export interface FlexContainerProps extends FabricComponent<Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>> {
11
12
  children: any;
12
13
  direction?: FlexDirection;
13
14
  wrap?: FlexWrap;
@@ -70,7 +71,7 @@ interface StyledFlexContainerProps {
70
71
  $columnGap?: FlexGap;
71
72
  }
72
73
 
73
- const StyledFlexContainer = styled.div<StyledFlexContainerProps>`
74
+ const StyledContainer = styled.div<StyledFlexContainerProps>`
74
75
  ${({ $direction, $wrap, $justify, $align, $alignContent, $gap, $rowGap, $columnGap }) => `
75
76
  display: flex;
76
77
  width: 100%;
@@ -85,3 +86,5 @@ const StyledFlexContainer = styled.div<StyledFlexContainerProps>`
85
86
  ${$columnGap !== undefined ? `column-gap: ${typeof $columnGap === 'number' ? `${$columnGap}px` : $columnGap};` : ''}
86
87
  `}
87
88
  `;
89
+
90
+ const StyledFlexContainer = createComponent(StyledContainer);
@@ -6,7 +6,7 @@ interface AlertIconProps extends SVGProps<SVGSVGElement> {
6
6
 
7
7
  export const AlertIcon = ({ fill = 'currentColor', ...props }: AlertIconProps) => {
8
8
  return (
9
- <svg width="17" height="15" viewBox="0 0 17 15" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
9
+ <svg viewBox="0 0 17 15" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
10
10
  <path
11
11
  fillRule="evenodd"
12
12
  clipRule="evenodd"
@@ -15,10 +15,12 @@ interface StyledLineProps {
15
15
  $direction: 'horizontal' | 'vertical';
16
16
  }
17
17
 
18
- const StyledLine = styled(createComponent('div'))<StyledLineProps>(
19
- ({ theme, $direction }) => `
18
+ const StyledLine = createComponent(
19
+ styled.div<StyledLineProps>(
20
+ ({ theme, $direction }) => `
20
21
  width: ${$direction === 'horizontal' ? '100%' : theme.line.size};
21
22
  height: ${$direction === 'vertical' ? '100%' : theme.line.size};
22
23
  background-color: ${theme.line.color};
23
24
  `
25
+ )
24
26
  );
@@ -0,0 +1,143 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import {
4
+ FabricComponent,
5
+ createComponent,
6
+ TagVariant,
7
+ TagColor,
8
+ hexToRgba,
9
+ generatePropertySpaceStyle,
10
+ } from '../../Theme';
11
+ import { CrossIcon } from '../IconComponents';
12
+
13
+ type TagProps = FabricComponent<{
14
+ children?: any;
15
+ variant?: TagVariant;
16
+ color?: TagColor;
17
+ className?: string;
18
+ icon?: any;
19
+ disabled?: boolean;
20
+ onClick?: () => void;
21
+ onDelete?: () => void;
22
+ }> &
23
+ Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>;
24
+
25
+ export const Tag = ({
26
+ children,
27
+ variant = 'fill',
28
+ color = 'default',
29
+ className,
30
+ disabled,
31
+ icon,
32
+ onClick,
33
+ onDelete,
34
+ ...props
35
+ }: TagProps) => {
36
+ return (
37
+ <StyledContainer
38
+ $variant={variant}
39
+ $color={color}
40
+ $clickable={!!onClick && !disabled}
41
+ onClick={!disabled ? onClick : undefined}
42
+ className={className}
43
+ {...props}
44
+ >
45
+ {!!children && <Content>{children}</Content>}
46
+ {!!onDelete && !disabled && (
47
+ <DeleteButton
48
+ aria-label="delete"
49
+ onClick={(e) => {
50
+ e.stopPropagation();
51
+ onDelete();
52
+ }}
53
+ >
54
+ <CrossIcon />
55
+ </DeleteButton>
56
+ )}
57
+ </StyledContainer>
58
+ );
59
+ };
60
+
61
+ type StyledProps = {
62
+ $variant: TagVariant;
63
+ $color: TagColor;
64
+ $clickable: boolean;
65
+ };
66
+
67
+ const Content = styled.span`
68
+ display: inline-flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ min-width: 0;
72
+
73
+ font-size: 14px;
74
+ line-height: 16px;
75
+ `;
76
+
77
+ const DeleteButton = styled.button`
78
+ border: none;
79
+ outline: none;
80
+ background-color: transparent;
81
+ cursor: pointer;
82
+ color: currentColor;
83
+ transition: color 0.2s ease;
84
+ svg {
85
+ width: 10px;
86
+ height: 10px;
87
+ fill: currentColor;
88
+ }
89
+ `;
90
+
91
+ const Container = styled.div<FabricComponent<StyledProps>>(
92
+ ({
93
+ theme,
94
+ $variant,
95
+ $color,
96
+ $clickable,
97
+ py = theme.tag[$variant].paddingBlock,
98
+ px = theme.tag[$variant].paddingInline,
99
+ }) => {
100
+ const color = theme.tag[$variant].color[$color] || $color;
101
+ return `
102
+ display: inline-flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ min-width: 0;
106
+ border-width: ${theme.tag[$variant].borderWidth};
107
+ border-style: solid;
108
+ border-color: ${color};
109
+ border-radius: ${theme.tag[$variant].borderRadius};
110
+ background-color: ${$variant === 'outlined' ? theme.colors.background : hexToRgba(color, 0.05)};
111
+ color: ${color};
112
+
113
+ ${Content} {
114
+ ${generatePropertySpaceStyle(theme, 'padding-block', py)};
115
+ ${generatePropertySpaceStyle(theme, 'padding-inline', px)};
116
+ color: ${color};
117
+ ${
118
+ $clickable
119
+ ? `
120
+ cursor: pointer;
121
+ transition: color 0.2s ease;
122
+ &:hover {
123
+ color: ${hexToRgba(color, 0.7)};
124
+ }
125
+ `
126
+ : ''
127
+ }
128
+ }
129
+ ${DeleteButton} {
130
+ ${generatePropertySpaceStyle(theme, 'padding-block', py)};
131
+ ${generatePropertySpaceStyle(theme, 'padding-right', px)};
132
+
133
+ &:hover {
134
+ color: ${hexToRgba(color, 0.7)};
135
+ }
136
+ }
137
+ `;
138
+ }
139
+ );
140
+
141
+ const StyledContainer = createComponent(Container, {
142
+ ignoreStyles: ['padding-block', 'padding-inline'],
143
+ });
@@ -0,0 +1 @@
1
+ export * from './Tag';
@@ -13,26 +13,31 @@ type TypographyProps = FabricComponent<{
13
13
  color?: ColorVariant | string;
14
14
  className?: string;
15
15
  ellipsis?: boolean;
16
- }>;
16
+ }> &
17
+ Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>;
17
18
 
18
- // Create a styled component that can be dynamically rendered as different HTML elements
19
- const StyledTypography = styled(createComponent('div'))<{
19
+ type StyledProps = {
20
20
  $variant: TypographyVariant;
21
21
  $weight?: CSSProperties['fontWeight'];
22
22
  $style?: CSSProperties['fontStyle'];
23
23
  $color?: ColorVariant | string;
24
24
  $ellipsis?: boolean;
25
- }>(({ theme, $variant, $color, $weight = '400', $style = 'initial', $ellipsis }) => {
26
- // Resolve color from theme if it's a theme color path, or use the direct color value
25
+ };
26
+
27
+ // Create a styled component that can be dynamically rendered as different HTML elements
28
+ const StyledTypography = createComponent(
29
+ styled('div')<StyledProps>(({ theme, $variant, $color, $weight = '400', $style = 'initial', $ellipsis }) => {
30
+ // Resolve color from theme if it's a theme color path, or use the direct color value
27
31
 
28
- return `
32
+ return `
29
33
  font-size: ${theme.typography.variants[$variant].fontSize};
30
34
  font-weight: ${$weight};
31
35
  font-style: ${$style};
32
36
  color: ${resolveThemeColor(theme, $color) || theme.colors.text.main};
33
37
  ${$ellipsis ? 'overflow: hidden; text-overflow: ellipsis; white-space: nowrap;' : ''}
34
38
  `;
35
- });
39
+ })
40
+ );
36
41
 
37
42
  export const Typography = ({
38
43
  variant = 'body',
package/src/Core/index.ts CHANGED
@@ -14,3 +14,5 @@ export * from './Flex';
14
14
  export * from './Box';
15
15
  export * from './Line';
16
16
  export * from './EmptyData';
17
+ export * from './Tag';
18
+ export * from './Alert';
@@ -1,4 +1,4 @@
1
- import { createComponent, FabricComponent, pxToRem } from '../../Theme';
1
+ import { createComponent, FabricComponent, generatePropertySpaceStyle, pxToRem } from '../../Theme';
2
2
  import { styled } from 'styled-components';
3
3
 
4
4
  type ContainerProps = FabricComponent<{
@@ -14,11 +14,14 @@ export const Container = ({ maxWidth, ...props }: ContainerProps) => {
14
14
  return <StyledContainer {...props} $maxWidth={maxWidth} />;
15
15
  };
16
16
 
17
- const StyledContainer = styled(createComponent<StyledContainerProps>('div'))(({ theme, $maxWidth }) => {
18
- return `
19
- padding-inline: ${pxToRem(20, theme.baseSize)};
17
+ const StyledContainer = createComponent(
18
+ styled.div<FabricComponent<StyledContainerProps>>(({ theme, $maxWidth, px = 20 }) => {
19
+ return `
20
+ ${generatePropertySpaceStyle(theme, 'padding-inline', px)}
20
21
  width: 100%;
21
22
  min-width: 0;
22
23
  max-width: ${typeof $maxWidth === 'number' ? pxToRem($maxWidth, theme.baseSize) : $maxWidth || '100%'};
23
24
  `;
24
- });
25
+ }),
26
+ { ignoreStyles: ['padding-inline'] }
27
+ );
@@ -1,4 +1,5 @@
1
- import styled, { css, WebTarget } from 'styled-components';
1
+ import styled, { css, IStyledComponent, DefaultTheme, WebTarget } from 'styled-components';
2
+ import { pxToRem } from './utils';
2
3
 
3
4
  type MarginProps = {
4
5
  m?: string | number; // margin
@@ -19,52 +20,74 @@ type MarginProps = {
19
20
 
20
21
  export type FabricComponent<T = object> = T & MarginProps;
21
22
 
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
- }
23
+ const marginStyles = ({ ignoreStyles }: FabricComponentOptions = {}) =>
24
+ css<FabricComponent>(({ theme, ...props }) => {
25
+ return `
26
+ ${generatePropertySpaceStyle(theme, 'margin', props.m, ignoreStyles)}
27
+ ${generatePropertySpaceStyle(theme, 'margin-top', props.mt, ignoreStyles)}
28
+ ${generatePropertySpaceStyle(theme, 'margin-right', props.mr, ignoreStyles)}
29
+ ${generatePropertySpaceStyle(theme, 'margin-bottom', props.mb, ignoreStyles)}
30
+ ${generatePropertySpaceStyle(theme, 'margin-left', props.ml, ignoreStyles)}
31
+ ${generatePropertySpaceStyle(theme, 'margin-inline', props.mx, ignoreStyles)}
32
+ ${generatePropertySpaceStyle(theme, 'margin-block', props.my, ignoreStyles)}
33
+ `;
34
+ });
62
35
 
36
+ const paddingStyles = ({ ignoreStyles }: FabricComponentOptions = {}) =>
37
+ css<FabricComponent>(({ theme, ...props }) => {
38
+ return `
39
+ ${generatePropertySpaceStyle(theme, 'padding', props.p, ignoreStyles)}
40
+ ${generatePropertySpaceStyle(theme, 'padding-top', props.pt, ignoreStyles)}
41
+ ${generatePropertySpaceStyle(theme, 'padding-right', props.pr, ignoreStyles)}
42
+ ${generatePropertySpaceStyle(theme, 'padding-bottom', props.pb, ignoreStyles)}
43
+ ${generatePropertySpaceStyle(theme, 'padding-left', props.pl, ignoreStyles)}
44
+ ${generatePropertySpaceStyle(theme, 'padding-inline', props.px, ignoreStyles)}
45
+ ${generatePropertySpaceStyle(theme, 'padding-block', props.py, ignoreStyles)}
63
46
  `;
64
- });
47
+ });
48
+
49
+ type GeneratedFabricMarginProperties =
50
+ | 'margin'
51
+ | 'margin-top'
52
+ | 'margin-right'
53
+ | 'margin-bottom'
54
+ | 'margin-left'
55
+ | 'margin-inline'
56
+ | 'margin-block'
57
+ | 'padding'
58
+ | 'padding-top'
59
+ | 'padding-right'
60
+ | 'padding-bottom'
61
+ | 'padding-left'
62
+ | 'padding-inline'
63
+ | 'padding-block';
64
+
65
+ export const generatePropertySpaceStyle = (
66
+ theme: DefaultTheme,
67
+ property: GeneratedFabricMarginProperties,
68
+ value?: string | number,
69
+ ignoredOptions?: GeneratedFabricMarginProperties[]
70
+ ) => {
71
+ if (ignoredOptions && ignoredOptions.includes(property)) {
72
+ return '';
73
+ }
74
+ if (value !== undefined) {
75
+ const t = typeof value === 'number';
76
+ return `${property}: ${typeof value === 'number' ? `${pxToRem(value, theme.baseSize)}` : value};`;
77
+ }
78
+ return '';
79
+ };
80
+
81
+ type FabricComponentOptions = {
82
+ ignoreStyles?: GeneratedFabricMarginProperties[] | undefined; // Ignore margin styles
83
+ };
65
84
 
66
- export const createComponent = <T = object>(element: WebTarget) => {
67
- return styled(element)<FabricComponent<T>>`
68
- ${marginStyles};
85
+ export const createComponent = <T extends object = {}>(
86
+ component: React.ComponentType<T>,
87
+ options?: FabricComponentOptions
88
+ ) => {
89
+ return styled(component)<T & FabricComponent>`
90
+ ${marginStyles(options)}
91
+ ${paddingStyles(options)}
69
92
  `;
70
93
  };
@@ -706,6 +706,54 @@ export const darkThemePx: Theme = {
706
706
  foreground: '#99989C',
707
707
  background: '#535353',
708
708
  },
709
+ tag: {
710
+ outlined: {
711
+ borderRadius: 50,
712
+ paddingBlock: 5,
713
+ paddingInline: 10,
714
+ borderWidth: 1,
715
+ color: {
716
+ default: '#99989C',
717
+ primary: '#3991FA',
718
+ error: '#D82323',
719
+ success: '#38A473',
720
+ warning: '#DEB839',
721
+ disabled: '#ebebeb',
722
+ },
723
+ },
724
+ fill: {
725
+ borderRadius: 4,
726
+ paddingBlock: 5,
727
+ paddingInline: 10,
728
+ borderWidth: 0,
729
+ color: {
730
+ default: '#99989C',
731
+ primary: '#3991FA',
732
+ error: '#D82323',
733
+ success: '#38A473',
734
+ warning: '#DEB839',
735
+ disabled: '#ebebeb',
736
+ },
737
+ },
738
+ },
739
+ alert: {
740
+ paddingBlock: 16,
741
+ paddingLeft: 16,
742
+ paddingRight: 44,
743
+ borderRadius: 5,
744
+ fontSize: 14,
745
+ gap: 12,
746
+ icon: {
747
+ width: 16,
748
+ height: 14,
749
+ paddingTop: 2,
750
+ },
751
+ color: {
752
+ icon: '#FDC700',
753
+ text: '#894B00',
754
+ background: '#FFFBE0',
755
+ },
756
+ },
709
757
  };
710
758
 
711
759
  export const darkTheme = convertPaletteToRem(darkThemePx, darkThemePx.baseSize) as DefaultTheme;