fiboui 1.0.0

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.
Files changed (141) hide show
  1. package/README.md +101 -0
  2. package/dist/content/Alert/index.d.ts +878 -0
  3. package/dist/content/Avatar/index.d.ts +886 -0
  4. package/dist/content/Badge/index.d.ts +887 -0
  5. package/dist/content/Image/index.d.ts +893 -0
  6. package/dist/content/Label/index.d.ts +879 -0
  7. package/dist/content/Progress/index.d.ts +898 -0
  8. package/dist/content/Skeleton/index.d.ts +879 -0
  9. package/dist/content/Spinner/index.d.ts +880 -0
  10. package/dist/content/Text/index.d.ts +878 -0
  11. package/dist/content/index.d.ts +9 -0
  12. package/dist/core/StateWrapper.d.ts +28 -0
  13. package/dist/core/builder.d.ts +50 -0
  14. package/dist/core/component.d.ts +7 -0
  15. package/dist/core/effects.d.ts +3 -0
  16. package/dist/core/icons.d.ts +11 -0
  17. package/dist/core/index.d.ts +5 -0
  18. package/dist/core/state.d.ts +37 -0
  19. package/dist/core/types.d.ts +51 -0
  20. package/dist/demo.d.ts +7 -0
  21. package/dist/effects-Co9C_Dyx.mjs +9 -0
  22. package/dist/examples/ScaffoldExamples.d.ts +3 -0
  23. package/dist/examples/StateExamples.d.ts +5 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.esm.js +4622 -0
  26. package/dist/index.umd.js +251 -0
  27. package/dist/interactive/Button/index.d.ts +897 -0
  28. package/dist/interactive/Checkbox/index.d.ts +884 -0
  29. package/dist/interactive/Combobox/index.d.ts +898 -0
  30. package/dist/interactive/RadioGroup/index.d.ts +888 -0
  31. package/dist/interactive/Select/index.d.ts +895 -0
  32. package/dist/interactive/Switch/index.d.ts +881 -0
  33. package/dist/interactive/TextField/index.d.ts +892 -0
  34. package/dist/interactive/Textarea/index.d.ts +890 -0
  35. package/dist/interactive/index.d.ts +8 -0
  36. package/dist/layout/Center/index.d.ts +869 -0
  37. package/dist/layout/Column/index.d.ts +881 -0
  38. package/dist/layout/Container/index.d.ts +870 -0
  39. package/dist/layout/DashboardLayout/index.d.ts +870 -0
  40. package/dist/layout/Header/index.d.ts +870 -0
  41. package/dist/layout/Line/index.d.ts +872 -0
  42. package/dist/layout/Row/index.d.ts +879 -0
  43. package/dist/layout/Scaffold/index.d.ts +878 -0
  44. package/dist/layout/ScrollView/index.d.ts +879 -0
  45. package/dist/layout/Sidebar/index.d.ts +870 -0
  46. package/dist/layout/Spacer/index.d.ts +875 -0
  47. package/dist/layout/StakentComponents.d.ts +4 -0
  48. package/dist/layout/index.d.ts +11 -0
  49. package/dist/structure/Banner/index.d.ts +879 -0
  50. package/dist/structure/Box/index.d.ts +869 -0
  51. package/dist/structure/Card/index.d.ts +881 -0
  52. package/dist/structure/Collapse/index.d.ts +884 -0
  53. package/dist/structure/Grid/index.d.ts +1757 -0
  54. package/dist/structure/List/index.d.ts +888 -0
  55. package/dist/structure/Table/index.d.ts +895 -0
  56. package/dist/structure/Tags/index.d.ts +876 -0
  57. package/dist/structure/cards/AssetCard/index.d.ts +884 -0
  58. package/dist/structure/cards/CollectionCard/index.d.ts +880 -0
  59. package/dist/structure/cards/ContentCard/index.d.ts +884 -0
  60. package/dist/structure/cards/ProfileCard/index.d.ts +892 -0
  61. package/dist/structure/cards/index.d.ts +5 -0
  62. package/dist/structure/cards/variants/index.d.ts +3490 -0
  63. package/dist/structure/index.d.ts +9 -0
  64. package/dist/style.css +1 -0
  65. package/dist/theme/cupertino.d.ts +3 -0
  66. package/dist/theme/index.d.ts +5 -0
  67. package/dist/theme/material.d.ts +3 -0
  68. package/dist/theme/provider.d.ts +16 -0
  69. package/dist/theme/types.d.ts +57 -0
  70. package/dist/theme/web.d.ts +3 -0
  71. package/package.json +54 -0
  72. package/src/content/Alert/index.ts +110 -0
  73. package/src/content/Avatar/index.ts +116 -0
  74. package/src/content/Badge/index.ts +162 -0
  75. package/src/content/Image/index.ts +137 -0
  76. package/src/content/Label/index.ts +66 -0
  77. package/src/content/Progress/index.ts +378 -0
  78. package/src/content/Skeleton/index.ts +71 -0
  79. package/src/content/Spinner/index.ts +139 -0
  80. package/src/content/Text/index.ts +74 -0
  81. package/src/content/index.ts +9 -0
  82. package/src/core/StateWrapper.tsx +105 -0
  83. package/src/core/builder.ts +259 -0
  84. package/src/core/component.ts +49 -0
  85. package/src/core/effects.ts +27 -0
  86. package/src/core/icons.tsx +57 -0
  87. package/src/core/index.ts +5 -0
  88. package/src/core/state.ts +233 -0
  89. package/src/core/types.ts +62 -0
  90. package/src/demo.tsx +1045 -0
  91. package/src/examples/ScaffoldExamples.tsx +299 -0
  92. package/src/examples/StateExamples.tsx +149 -0
  93. package/src/index.ts +8 -0
  94. package/src/interactive/Button/index.ts +218 -0
  95. package/src/interactive/Checkbox/index.ts +145 -0
  96. package/src/interactive/Combobox/index.ts +278 -0
  97. package/src/interactive/RadioGroup/index.ts +124 -0
  98. package/src/interactive/Select/index.ts +227 -0
  99. package/src/interactive/Switch/index.ts +123 -0
  100. package/src/interactive/TextField/index.ts +200 -0
  101. package/src/interactive/Textarea/index.ts +129 -0
  102. package/src/interactive/index.ts +8 -0
  103. package/src/layout/Center/index.ts +34 -0
  104. package/src/layout/Column/index.ts +101 -0
  105. package/src/layout/Container/index.ts +28 -0
  106. package/src/layout/DashboardLayout/index.ts +106 -0
  107. package/src/layout/Header/index.ts +50 -0
  108. package/src/layout/Line/index.ts +41 -0
  109. package/src/layout/Row/index.ts +93 -0
  110. package/src/layout/Scaffold/index.ts +133 -0
  111. package/src/layout/ScrollView/index.ts +67 -0
  112. package/src/layout/Sidebar/index.ts +56 -0
  113. package/src/layout/Spacer/index.ts +46 -0
  114. package/src/layout/StakentComponents.tsx +57 -0
  115. package/src/layout/index.ts +11 -0
  116. package/src/structure/Banner/index.ts +92 -0
  117. package/src/structure/Box/index.ts +45 -0
  118. package/src/structure/Card/index.ts +113 -0
  119. package/src/structure/Collapse/index.ts +122 -0
  120. package/src/structure/Grid/index.ts +197 -0
  121. package/src/structure/List/index.ts +185 -0
  122. package/src/structure/Table/index.ts +165 -0
  123. package/src/structure/Tags/index.ts +69 -0
  124. package/src/structure/cards/AssetCard/index.ts +158 -0
  125. package/src/structure/cards/CollectionCard/index.ts +95 -0
  126. package/src/structure/cards/ContentCard/index.ts +127 -0
  127. package/src/structure/cards/ProfileCard/index.ts +152 -0
  128. package/src/structure/cards/index.ts +5 -0
  129. package/src/structure/cards/variants/index.ts +301 -0
  130. package/src/structure/index.ts +10 -0
  131. package/src/styles/base.css +186 -0
  132. package/src/styles/core.css +52 -0
  133. package/src/styles/themes/cupertino.css +197 -0
  134. package/src/styles/themes/material.css +322 -0
  135. package/src/styles/themes/web.css +196 -0
  136. package/src/theme/cupertino.ts +85 -0
  137. package/src/theme/index.ts +5 -0
  138. package/src/theme/material.ts +86 -0
  139. package/src/theme/provider.tsx +76 -0
  140. package/src/theme/types.ts +62 -0
  141. package/src/theme/web.ts +82 -0
@@ -0,0 +1,56 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { FiboBuilder, createBuilder } from '../../core/builder';
3
+
4
+
5
+
6
+
7
+
8
+ const SidebarInner = React.memo((props: any) => {
9
+ const { width = 260, collapsed, className, style, children, ...rest } = props;
10
+
11
+
12
+ const currentWidth = collapsed ? 80 : width;
13
+
14
+ return React.createElement(
15
+ 'aside',
16
+ {
17
+ className: `flex flex-col border-r border-gray-200 bg-white transition-all duration-300 h-full ${className || ''}`,
18
+ style: { width: currentWidth, minWidth: currentWidth, ...style },
19
+ ...rest
20
+ },
21
+ children
22
+ );
23
+ });
24
+
25
+ class SidebarBuilder extends FiboBuilder {
26
+ private _width: number | string = 260;
27
+ private _collapsed: boolean = false;
28
+
29
+ width(width: number | string): this {
30
+ this._width = width;
31
+ return this;
32
+ }
33
+
34
+ collapsible(collapsed: boolean = false): this {
35
+ this._collapsed = collapsed;
36
+ return this;
37
+ }
38
+
39
+ build(): ReactElement {
40
+ const props = {
41
+ width: this._width,
42
+ collapsed: this._collapsed,
43
+ className: this.getClassName(),
44
+ style: this.getStyle(),
45
+ children: this.processChildren(),
46
+ ...this._props
47
+ };
48
+ return React.createElement(SidebarInner, props);
49
+ }
50
+ }
51
+
52
+
53
+ export const Sidebar = createBuilder(SidebarBuilder);
54
+
55
+
56
+
@@ -0,0 +1,46 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { FiboBuilder, createBuilder } from '../../core/builder';
3
+ import { BaseProps } from '../../core/types';
4
+
5
+ class SpacerBuilder extends FiboBuilder {
6
+ private _height?: string | number;
7
+ private _width?: string | number;
8
+
9
+ height(value: string | number): this {
10
+ this._height = value;
11
+ return this;
12
+ }
13
+
14
+ width(value: string | number): this {
15
+ this._width = value;
16
+ return this;
17
+ }
18
+
19
+ build(): ReactElement {
20
+ const style = this.getStyle();
21
+
22
+ if (this._height) {
23
+ style.height = typeof this._height === 'number' ? `${this._height}px` : this._height;
24
+ }
25
+
26
+ if (this._width) {
27
+ style.width = typeof this._width === 'number' ? `${this._width}px` : this._width;
28
+ }
29
+
30
+ const className = this.getClassName();
31
+
32
+ return React.createElement('div', {
33
+ className: `fibo-spacer ${className}`,
34
+ style,
35
+ ...this._props,
36
+ });
37
+ }
38
+ }
39
+
40
+
41
+ export const Spacer = createBuilder(SpacerBuilder);
42
+
43
+ export interface SpacerProps extends BaseProps {
44
+ height?: string | number;
45
+ width?: string | number;
46
+ }
@@ -0,0 +1,57 @@
1
+ import { Box } from '../structure/Box';
2
+ import { Button } from '../interactive/Button';
3
+
4
+ export const StakentCard = ({ className = "", style = {} }: any): any => {
5
+ return Box()
6
+ .className(`bg-[#0B0C15] border border-white/5 rounded-[32px] overflow-hidden relative ${className}`)
7
+ .style({ backgroundColor: '#0B0C15', ...style });
8
+ };
9
+
10
+ export const StakentButton = ({ text, icon, variant = 'primary', className = "", onClick }: any): React.ReactElement => {
11
+ let baseClass = "rounded-xl font-bold transition-all duration-200 flex items-center justify-center gap-2";
12
+
13
+ if (variant === 'primary') {
14
+ baseClass += " bg-[#6366f1] text-white shadow-[0_0_20px_rgba(99,102,241,0.4)] hover:shadow-[0_0_25px_rgba(99,102,241,0.6)] hover:-translate-y-0.5";
15
+ } else if (variant === 'secondary') {
16
+ baseClass += " bg-white/5 border border-white/10 text-white hover:bg-white/10";
17
+ } else if (variant === 'outline') {
18
+ baseClass += " border border-white/10 text-gray-400 hover:text-white hover:border-white/20";
19
+ } else if (variant === 'ghost') {
20
+ baseClass += " text-gray-400 hover:text-white hover:bg-white/5";
21
+ } else if (variant === 'gradient') {
22
+ baseClass += " bg-gradient-to-r from-[#818CF8] to-[#6366f1] text-white shadow-lg shadow-indigo-500/30 border-none";
23
+ }
24
+
25
+ return Button(text)
26
+ .icon(icon)
27
+ .className(`${baseClass} ${className}`)
28
+ .onPress(onClick)
29
+ .variant("text")
30
+ .build();
31
+ };
32
+
33
+ export const StakentSidebarItem = ({ label, icon, active = false }: any): React.ReactElement => {
34
+ if (active) {
35
+ return Button(label)
36
+ .icon(icon ? Box().className(`${icon} w-5 h-5 text-white`).build() : null)
37
+ .className("w-full justify-start text-sm font-bold text-white bg-[#6366f1] shadow-[0_4px_20px_rgba(99,102,241,0.4)] rounded-xl mb-1 py-3 px-4")
38
+ .build();
39
+ }
40
+ return Button(label)
41
+ .icon(icon ? Box().className(`${icon} w-5 h-5 text-gray-400 group-hover:text-white transition-colors`).build() : null)
42
+ .variant("ghost")
43
+ .className("w-full justify-start text-sm font-medium text-gray-400 hover:text-white hover:bg-white/5 rounded-xl group py-3 px-4")
44
+ .build();
45
+ };
46
+
47
+ export const StakentBadge = ({ text, type = 'default' }: any): React.ReactElement => {
48
+ let style = "text-[10px] px-2 py-0.5 rounded border font-bold uppercase tracking-wider";
49
+ if (type === 'hot') {
50
+ style = "bg-[#FF3B30] text-white border-none text-[9px] px-1.5 py-0.5 rounded-md shadow-lg shadow-red-500/20";
51
+ } else if (type === 'beta') {
52
+ style = "bg-[#6366f1]/10 text-[#818CF8] border-[#6366f1]/20";
53
+ } else if (type === 'new') {
54
+ style = "bg-white text-black border-none";
55
+ }
56
+ return Box().className(style).children(text).build();
57
+ }
@@ -0,0 +1,11 @@
1
+ export * from './Container';
2
+ export * from './Row';
3
+ export * from './Column';
4
+ export * from './Spacer';
5
+ export * from './Line';
6
+ export * from './Center';
7
+ export * from './ScrollView';
8
+ export * from './Header';
9
+ export * from './Sidebar';
10
+ export * from './DashboardLayout';
11
+ export * from './Scaffold';
@@ -0,0 +1,92 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { FiboBuilder, createBuilder } from '../../core/builder';
3
+ import { BaseProps, StatusType } from '../../core/types';
4
+
5
+ const BannerInner = React.memo((props: any) => {
6
+ const { status, title, subtitle, className, style, ...rest } = props;
7
+
8
+ return React.createElement(
9
+ 'div',
10
+ {
11
+ className,
12
+ style,
13
+ ...rest,
14
+ },
15
+ React.createElement(
16
+ 'div',
17
+ { className: 'flex flex-col gap-1' },
18
+ title &&
19
+ React.createElement(
20
+ 'h4',
21
+ {
22
+ className: 'font-semibold text-sm uppercase tracking-wide opacity-90',
23
+ },
24
+ title
25
+ ),
26
+ subtitle &&
27
+ React.createElement(
28
+ 'p',
29
+ {
30
+ className: 'opacity-80 text-sm',
31
+ },
32
+ subtitle
33
+ )
34
+ )
35
+ );
36
+ });
37
+
38
+ class BannerBuilder extends FiboBuilder {
39
+ private _status: StatusType = 'info';
40
+ private _title: string = '';
41
+ private _subtitle?: string;
42
+
43
+ constructor(title: string = '') {
44
+ super();
45
+ this._title = title;
46
+ }
47
+
48
+ status(value: StatusType): this {
49
+ this._status = value;
50
+ return this;
51
+ }
52
+
53
+ title(value: string): this {
54
+ this._title = value;
55
+ return this;
56
+ }
57
+
58
+ subtitle(value: string): this {
59
+ this._subtitle = value;
60
+ return this;
61
+ }
62
+
63
+ build(): ReactElement {
64
+ const classes = [
65
+ 'fibo-banner',
66
+ `fibo-banner-${this._status}`,
67
+ ...this._classNames,
68
+ ];
69
+
70
+ const className = classes.filter(Boolean).join(' ');
71
+
72
+ const props = {
73
+ status: this._status,
74
+ title: this._title,
75
+ subtitle: this._subtitle,
76
+ className: className,
77
+ style: this.getStyle(),
78
+ ...this._props
79
+ };
80
+
81
+ return React.createElement(BannerInner, props);
82
+ }
83
+ }
84
+
85
+
86
+ export const Banner = createBuilder(BannerBuilder);
87
+
88
+ export interface BannerProps extends BaseProps {
89
+ status: StatusType;
90
+ title: string;
91
+ subtitle?: string;
92
+ }
@@ -0,0 +1,45 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { FiboBuilder, createBuilder } from '../../core/builder';
3
+ import { ChildrenProps } from '../../core/types';
4
+
5
+ const BoxInner = React.memo((props: any) => {
6
+ const { className, style, children, ...rest } = props;
7
+ return React.createElement(
8
+ 'div',
9
+ {
10
+ className,
11
+ style,
12
+ ...rest,
13
+ },
14
+ ...children
15
+ );
16
+ });
17
+
18
+ class BoxBuilder extends FiboBuilder {
19
+
20
+ build(): ReactElement {
21
+ const classes = [
22
+ 'fibo-box',
23
+ ...this._classNames,
24
+ ];
25
+
26
+ const className = classes.filter(Boolean).join(' ');
27
+ const style = this.getStyle();
28
+ const children = this.processChildren();
29
+
30
+
31
+ const props = {
32
+ className,
33
+ style: style,
34
+ children: children,
35
+ ...this._props
36
+ };
37
+
38
+ return React.createElement(BoxInner, props);
39
+ }
40
+ }
41
+
42
+
43
+ export const Box = createBuilder(BoxBuilder);
44
+
45
+ export interface BoxProps extends ChildrenProps {}
@@ -0,0 +1,113 @@
1
+ import React, { ReactElement } from 'react';
2
+ import { FiboBuilder, createBuilder } from '../../core/builder';
3
+ import { BaseProps } from '../../core/types';
4
+
5
+ const CardInner = React.memo((props: any) => {
6
+ const { text, subtitle, number, color, className, style, children, ...rest } = props;
7
+
8
+ return React.createElement(
9
+ 'div',
10
+ {
11
+ className: `rounded-[24px] shadow-[0_8px_30px_rgb(0,0,0,0.04)] hover:shadow-[0_8px_30px_rgb(0,0,0,0.08)] transition-shadow duration-300 border-none p-4 ${className || ''}`,
12
+ style: { backgroundColor: '#ffffff', ...style },
13
+ ...rest,
14
+ },
15
+ React.createElement(
16
+ 'div',
17
+ { className: 'flex flex-col gap-2' },
18
+ text &&
19
+ React.createElement(
20
+ 'h3',
21
+ {
22
+ className: 'font-semibold text-[var(--fibo-on-surface-variant)] text-sm uppercase tracking-wide',
23
+ },
24
+ text
25
+ ),
26
+ number &&
27
+ React.createElement(
28
+ 'p',
29
+ {
30
+ className: 'font-bold text-[var(--fibo-on-surface)] text-3xl',
31
+ },
32
+ number
33
+ ),
34
+ subtitle &&
35
+ React.createElement(
36
+ 'p',
37
+ {
38
+ className: 'text-[var(--fibo-on-surface-variant)] text-xs',
39
+ },
40
+ subtitle
41
+ ),
42
+ ...children
43
+ )
44
+ );
45
+ });
46
+
47
+ class CardBuilder extends FiboBuilder {
48
+ private _text: string = '';
49
+ private _subtitle?: string;
50
+ private _number?: string;
51
+ private _color?: string;
52
+
53
+ text(value: string): this {
54
+ this._text = value;
55
+ return this;
56
+ }
57
+
58
+ subtitle(value: string): this {
59
+ this._subtitle = value;
60
+ return this;
61
+ }
62
+
63
+ number(value: string): this {
64
+ this._number = value;
65
+ return this;
66
+ }
67
+
68
+ color(value: string): this {
69
+ this._color = value;
70
+ return this;
71
+ }
72
+
73
+ build(): ReactElement {
74
+ const colorClasses: Record<string, string> = {
75
+ green: 'border-l-green-500',
76
+ orange: 'border-l-orange-500',
77
+ red: 'border-l-red-500',
78
+ blue: 'border-l-blue-500',
79
+ purple: 'border-l-purple-500',
80
+ };
81
+
82
+ const className = [
83
+ 'fibo-card',
84
+ this._color ? `border-l-4 ${colorClasses[this._color]}` : '',
85
+ ...this._classNames,
86
+ ]
87
+ .filter(Boolean)
88
+ .join(' ');
89
+
90
+ const props = {
91
+ text: this._text,
92
+ subtitle: this._subtitle,
93
+ number: this._number,
94
+ color: this._color,
95
+ className: className,
96
+ style: this.getStyle(),
97
+ children: this.processChildren(),
98
+ ...this._props
99
+ };
100
+
101
+ return React.createElement(CardInner, props);
102
+ }
103
+ }
104
+
105
+
106
+ export const Card = createBuilder(CardBuilder);
107
+
108
+ export interface CardProps extends BaseProps {
109
+ text: string;
110
+ subtitle?: string;
111
+ number?: string;
112
+ color?: string;
113
+ }
@@ -0,0 +1,122 @@
1
+ import React, { ReactElement, ReactNode, useState } from 'react';
2
+ import { FiboBuilder, createBuilder } from '../../core/builder';
3
+ import { BaseProps } from '../../core/types';
4
+ import { Box } from '../Box';
5
+ import { Row } from '../../layout/Row';
6
+ import { Text } from '../../content/Text';
7
+
8
+
9
+ class CollapseBuilder extends FiboBuilder {
10
+ public _title: ReactNode | string = '';
11
+ public _content: ReactNode = null;
12
+ public _defaultExpanded: boolean = false;
13
+ public _expanded?: boolean;
14
+ public _onToggle?: (isOpen: boolean) => void;
15
+
16
+ title(value: ReactNode | string): this {
17
+ this._title = value;
18
+ return this;
19
+ }
20
+
21
+ content(value: ReactNode): this {
22
+ this._content = value;
23
+ return this;
24
+ }
25
+
26
+ isOpen(value: boolean): this {
27
+ this._expanded = value;
28
+ return this;
29
+ }
30
+
31
+ defaultOpen(value: boolean): this {
32
+ this._defaultExpanded = value;
33
+ return this;
34
+ }
35
+
36
+ onToggle(handler: (isOpen: boolean) => void): this {
37
+ this._onToggle = handler;
38
+ return this;
39
+ }
40
+
41
+ build(): ReactElement {
42
+ return React.createElement(CollapseBase, {
43
+ builder: this,
44
+ ...this._props
45
+ });
46
+ }
47
+ }
48
+
49
+
50
+ const CollapseBase = React.memo(({ builder }: { builder: CollapseBuilder }) => {
51
+
52
+
53
+ const b = builder as any;
54
+
55
+
56
+ const isControlled = b._expanded !== undefined;
57
+ const [internalOpen, setInternalOpen] = useState(b._defaultExpanded);
58
+
59
+ const isOpen = isControlled ? b._expanded : internalOpen;
60
+
61
+ const toggle = () => {
62
+ if (!isControlled) {
63
+ setInternalOpen(!isOpen);
64
+ }
65
+ if (b._onToggle) {
66
+ b._onToggle(!isOpen);
67
+ }
68
+ };
69
+
70
+ return Box()
71
+ .classNames(['w-full', 'border', 'border-gray-200', 'rounded-xl', 'overflow-hidden', 'bg-white', 'transition-all', 'duration-300'])
72
+ .className(b.getClassName())
73
+ .style(b.getStyle())
74
+ .children([
75
+
76
+ Row()
77
+ .justifyContent("between")
78
+ .alignItems("center")
79
+ .classNames(['p-4', 'cursor-pointer', 'hover:bg-gray-50', 'transition-colors', 'select-none'])
80
+ .props({ onClick: toggle })
81
+ .children([
82
+ typeof b._title === 'string'
83
+ ? Text(b._title).fontWeight(600).fontSize(15).color("#1F2937").build()
84
+ : b._title,
85
+
86
+
87
+ Box()
88
+ .classNames(['transition-transform', 'duration-300'])
89
+ .style({ transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)' })
90
+ .children(
91
+
92
+ React.createElement('svg', {
93
+ width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round",
94
+ className: "text-gray-400"
95
+ }, React.createElement('polyline', { points: "6 9 12 15 18 9" }))
96
+ ).build()
97
+ ]).build(),
98
+
99
+
100
+ Box()
101
+ .classNames(['transition-all', 'duration-300', 'ease-in-out', 'overflow-hidden'])
102
+ .style({
103
+ maxHeight: isOpen ? '500px' : '0px',
104
+ opacity: isOpen ? 1 : 0,
105
+ })
106
+ .children(
107
+ Box().classNames(['p-4', 'pt-0', 'text-gray-600', 'text-sm']).children(b._content).build()
108
+ ).build()
109
+ ])
110
+ .build();
111
+ });
112
+
113
+
114
+ export const Collapse = createBuilder(CollapseBuilder);
115
+
116
+ export interface CollapseProps extends BaseProps {
117
+ title: ReactNode | string;
118
+ content: ReactNode;
119
+ isOpen?: boolean;
120
+ defaultOpen?: boolean;
121
+ onToggle?: (isOpen: boolean) => void;
122
+ }