@react-fabric/core 1.0.0-beta.3 → 1.0.0-beta.30

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 (207) hide show
  1. package/css/index.js +14 -14
  2. package/css/reset/_reset.css +1 -1
  3. package/dist/cjs/components/actionLabel/ActionLabel.js +1 -0
  4. package/dist/cjs/components/animations/Animations.js +14 -7
  5. package/dist/cjs/components/avatar/Avatar.js +8 -10
  6. package/dist/cjs/components/avatar/AvatarGroup.js +1 -0
  7. package/dist/cjs/components/badge/Badge.js +5 -4
  8. package/dist/cjs/components/breadcrumbs/Breadcrumbs.js +5 -2
  9. package/dist/cjs/components/button/Button.js +5 -4
  10. package/dist/cjs/components/button/Button.module.css +1 -1
  11. package/dist/cjs/components/button/ButtonGroup.js +3 -1
  12. package/dist/cjs/components/button/ConfirmButton.js +7 -2
  13. package/dist/cjs/components/button/ToggleButtonGroup.js +2 -1
  14. package/dist/cjs/components/callout/Callout.js +7 -2
  15. package/dist/cjs/components/card/Card.js +5 -3
  16. package/dist/cjs/components/card/CardCover.js +1 -1
  17. package/dist/cjs/components/chip/Chip.js +9 -4
  18. package/dist/cjs/components/chip/Chip.module.css +1 -1
  19. package/dist/cjs/components/collapsable/Collapsable.js +3 -2
  20. package/dist/cjs/components/divider/Divider.js +4 -3
  21. package/dist/cjs/components/divider/Divider.module.css +1 -0
  22. package/dist/cjs/components/dropdown/Dropdown.js +4 -2
  23. package/dist/cjs/components/dropdown/DropdownTool.js +4 -3
  24. package/dist/cjs/components/icon/Icon.js +14 -12
  25. package/dist/cjs/components/icon/Icon.module.css +1 -1
  26. package/dist/cjs/components/menu/ContextMenu.js +30 -10
  27. package/dist/cjs/components/menu/Menu.js +39 -20
  28. package/dist/cjs/components/menu/MenuItem.js +29 -14
  29. package/dist/cjs/components/navigator/Navigator.js +16 -9
  30. package/dist/cjs/components/panel/Panel.js +3 -1
  31. package/dist/cjs/components/progress/ProgressBar.js +2 -1
  32. package/dist/cjs/components/progress/ProgressCircle.js +2 -1
  33. package/dist/cjs/components/tabpanel/Tab.js +55 -36
  34. package/dist/cjs/components/tabpanel/TabPanel.js +19 -14
  35. package/dist/cjs/components/tabpanel/TabPanel.module.css +1 -1
  36. package/dist/cjs/core/aside/Aside.js +6 -2
  37. package/dist/cjs/core/content/Content.js +8 -5
  38. package/dist/cjs/core/headfoot/HeadFoot.js +3 -2
  39. package/dist/cjs/core/headfoot/HeadFoot.module.css +1 -1
  40. package/dist/cjs/core/page/Page.js +1 -0
  41. package/dist/cjs/core/responsive/Responsive.js +1 -1
  42. package/dist/cjs/core/section/Section.module.css +1 -1
  43. package/dist/cjs/hooks/useNavigator.js +6 -4
  44. package/dist/cjs/index.js +7 -2
  45. package/dist/cjs/overlays/alert/Alert.js +42 -17
  46. package/dist/cjs/overlays/alert/Alert.module.css +1 -1
  47. package/dist/cjs/overlays/flyout/Flyout.js +40 -42
  48. package/dist/cjs/overlays/message/Message.js +1 -1
  49. package/dist/cjs/overlays/modal/Modal.js +4 -5
  50. package/dist/cjs/overlays/toast/Toast.js +1 -1
  51. package/dist/cjs/overlays/tooltip/Tooltip.js +3 -3
  52. package/dist/cjs/overlays/tooltip/Tooltip.module.css +1 -1
  53. package/dist/cjs/types/icons.js +3 -0
  54. package/dist/cjs/typography/Abbr.js +1 -1
  55. package/dist/cjs/typography/{Link.js → Anchor.js} +4 -3
  56. package/dist/cjs/typography/Mark.js +1 -1
  57. package/dist/cjs/typography/Text.js +2 -2
  58. package/dist/cjs/typography/Title.js +3 -2
  59. package/dist/cjs/typography/Typography.module.css +1 -1
  60. package/dist/cjs/utils/cloneElement.js +44 -0
  61. package/dist/esm/components/actionLabel/ActionLabel.js +1 -0
  62. package/dist/esm/components/animations/Animations.js +14 -7
  63. package/dist/esm/components/avatar/Avatar.js +9 -11
  64. package/dist/esm/components/avatar/AvatarGroup.js +1 -0
  65. package/dist/esm/components/badge/Badge.js +5 -4
  66. package/dist/esm/components/breadcrumbs/Breadcrumbs.js +5 -2
  67. package/dist/esm/components/button/Button.js +5 -4
  68. package/dist/esm/components/button/Button.module.css +1 -1
  69. package/dist/esm/components/button/ButtonGroup.js +4 -2
  70. package/dist/esm/components/button/ConfirmButton.js +7 -2
  71. package/dist/esm/components/button/ToggleButtonGroup.js +3 -2
  72. package/dist/esm/components/callout/Callout.js +7 -2
  73. package/dist/esm/components/card/Card.js +5 -3
  74. package/dist/esm/components/card/CardCover.js +1 -1
  75. package/dist/esm/components/chip/Chip.js +9 -4
  76. package/dist/esm/components/chip/Chip.module.css +1 -1
  77. package/dist/esm/components/collapsable/Collapsable.js +3 -2
  78. package/dist/esm/components/divider/Divider.js +4 -3
  79. package/dist/esm/components/divider/Divider.module.css +1 -0
  80. package/dist/esm/components/dropdown/Dropdown.js +4 -2
  81. package/dist/esm/components/dropdown/DropdownTool.js +4 -3
  82. package/dist/esm/components/icon/Icon.js +14 -12
  83. package/dist/esm/components/icon/Icon.module.css +1 -1
  84. package/dist/esm/components/menu/ContextMenu.js +32 -12
  85. package/dist/esm/components/menu/Menu.js +41 -22
  86. package/dist/esm/components/menu/MenuItem.js +23 -8
  87. package/dist/esm/components/navigator/Navigator.js +16 -9
  88. package/dist/esm/components/panel/Panel.js +3 -1
  89. package/dist/esm/components/progress/ProgressBar.js +2 -1
  90. package/dist/esm/components/progress/ProgressCircle.js +2 -1
  91. package/dist/esm/components/tabpanel/Tab.js +56 -37
  92. package/dist/esm/components/tabpanel/TabPanel.js +19 -14
  93. package/dist/esm/components/tabpanel/TabPanel.module.css +1 -1
  94. package/dist/esm/core/aside/Aside.js +6 -2
  95. package/dist/esm/core/content/Content.js +8 -5
  96. package/dist/esm/core/headfoot/HeadFoot.js +3 -2
  97. package/dist/esm/core/headfoot/HeadFoot.module.css +1 -1
  98. package/dist/esm/core/page/Page.js +1 -0
  99. package/dist/esm/core/responsive/Responsive.js +1 -1
  100. package/dist/esm/core/section/Section.module.css +1 -1
  101. package/dist/esm/hooks/useNavigator.js +7 -5
  102. package/dist/esm/index.js +4 -1
  103. package/dist/esm/overlays/alert/Alert.js +31 -6
  104. package/dist/esm/overlays/alert/Alert.module.css +1 -1
  105. package/dist/esm/overlays/flyout/Flyout.js +41 -43
  106. package/dist/esm/overlays/message/Message.js +1 -1
  107. package/dist/esm/overlays/modal/Modal.js +5 -6
  108. package/dist/esm/overlays/toast/Toast.js +1 -1
  109. package/dist/esm/overlays/tooltip/Tooltip.js +3 -3
  110. package/dist/esm/overlays/tooltip/Tooltip.module.css +1 -1
  111. package/dist/esm/types/icons.js +3 -0
  112. package/dist/esm/typography/Abbr.js +1 -1
  113. package/dist/esm/typography/{Link.js → Anchor.js} +4 -3
  114. package/dist/esm/typography/Mark.js +1 -1
  115. package/dist/esm/typography/Text.js +2 -2
  116. package/dist/esm/typography/Title.js +3 -2
  117. package/dist/esm/typography/Typography.module.css +1 -1
  118. package/dist/esm/utils/cloneElement.js +44 -0
  119. package/dist/types/components/actionLabel/ActionLabel.d.ts +2 -2
  120. package/dist/types/components/animations/Animations.d.ts +1 -1
  121. package/dist/types/components/badge/Badge.d.ts +5 -1
  122. package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts +2 -2
  123. package/dist/types/components/button/Button.d.ts +5 -3
  124. package/dist/types/components/button/ConfirmButton.d.ts +6 -1
  125. package/dist/types/components/card/Card.d.ts +3 -3
  126. package/dist/types/components/chip/Chip.d.ts +1 -1
  127. package/dist/types/components/collapsable/Collapsable.d.ts +5 -1
  128. package/dist/types/components/dropdown/DropdownTool.d.ts +2 -1
  129. package/dist/types/components/media/Media.d.ts +2 -2
  130. package/dist/types/components/menu/ContextMenu.d.ts +2 -1
  131. package/dist/types/components/menu/MenuItem.d.ts +1 -1
  132. package/dist/types/components/navigator/Navigator.d.ts +3 -3
  133. package/dist/types/components/tabpanel/Tab.d.ts +4 -4
  134. package/dist/types/components/tabpanel/TabPanel.d.ts +10 -1
  135. package/dist/types/core/aside/Aside.d.ts +7 -3
  136. package/dist/types/core/content/Content.d.ts +3 -2
  137. package/dist/types/core/responsive/Responsive.d.ts +1 -1
  138. package/dist/types/core/theme/ThemeProvider.d.ts +1 -1
  139. package/dist/types/hooks/useOverlayService.d.ts +3 -3
  140. package/dist/types/index.d.ts +3 -0
  141. package/dist/types/overlays/alert/Alert.d.ts +9 -1
  142. package/dist/types/overlays/flyout/Flyout.d.ts +3 -2
  143. package/dist/types/overlays/modal/Modal.d.ts +4 -3
  144. package/dist/types/types/icons.d.ts +3 -0
  145. package/dist/types/types/index.d.ts +8 -1
  146. package/dist/types/typography/{Link.d.ts → Anchor.d.ts} +2 -2
  147. package/dist/types/typography/index.d.ts +1 -1
  148. package/dist/types/utils/cloneElement.d.ts +2 -0
  149. package/dist/types/utils/index.d.ts +1 -0
  150. package/package.json +5 -5
  151. package/src/components/actionLabel/ActionLabel.tsx +13 -3
  152. package/src/components/animations/Animations.tsx +9 -3
  153. package/src/components/avatar/Avatar.tsx +69 -81
  154. package/src/components/avatar/AvatarGroup.tsx +1 -0
  155. package/src/components/badge/Badge.tsx +9 -4
  156. package/src/components/breadcrumbs/Breadcrumbs.tsx +9 -4
  157. package/src/components/button/Button.module.css +8 -1
  158. package/src/components/button/Button.tsx +12 -9
  159. package/src/components/button/ButtonGroup.tsx +3 -2
  160. package/src/components/button/ConfirmButton.tsx +15 -5
  161. package/src/components/button/ToggleButtonGroup.tsx +3 -2
  162. package/src/components/callout/Callout.tsx +12 -3
  163. package/src/components/card/Card.tsx +4 -0
  164. package/src/components/chip/Chip.module.css +4 -1
  165. package/src/components/chip/Chip.tsx +9 -4
  166. package/src/components/collapsable/Collapsable.tsx +6 -0
  167. package/src/components/divider/Divider.module.css +32 -0
  168. package/src/components/divider/Divider.tsx +3 -2
  169. package/src/components/dropdown/Dropdown.tsx +3 -2
  170. package/src/components/dropdown/DropdownTool.tsx +4 -2
  171. package/src/components/icon/Icon.module.css +0 -1
  172. package/src/components/icon/Icon.tsx +48 -58
  173. package/src/components/media/Media.tsx +2 -2
  174. package/src/components/menu/ContextMenu.tsx +36 -11
  175. package/src/components/menu/Menu.tsx +51 -30
  176. package/src/components/menu/MenuItem.tsx +14 -3
  177. package/src/components/navigator/Navigator.tsx +17 -4
  178. package/src/components/panel/Panel.tsx +3 -1
  179. package/src/components/tabpanel/Tab.tsx +74 -59
  180. package/src/components/tabpanel/TabPanel.module.css +19 -30
  181. package/src/components/tabpanel/TabPanel.tsx +33 -10
  182. package/src/core/aside/Aside.tsx +17 -3
  183. package/src/core/content/Content.tsx +16 -10
  184. package/src/core/headfoot/HeadFoot.module.css +2 -0
  185. package/src/core/headfoot/HeadFoot.tsx +1 -1
  186. package/src/core/page/Page.tsx +1 -0
  187. package/src/core/responsive/Responsive.tsx +3 -2
  188. package/src/core/section/Section.module.css +1 -1
  189. package/src/core/theme/ThemeProvider.tsx +1 -1
  190. package/src/hooks/useNavigator.tsx +10 -5
  191. package/src/hooks/useOverlayService.tsx +12 -4
  192. package/src/index.ts +4 -0
  193. package/src/overlays/alert/Alert.module.css +1 -1
  194. package/src/overlays/alert/Alert.tsx +30 -4
  195. package/src/overlays/flyout/Flyout.tsx +63 -62
  196. package/src/overlays/modal/Modal.tsx +13 -8
  197. package/src/overlays/tooltip/Tooltip.module.css +7 -7
  198. package/src/overlays/tooltip/Tooltip.tsx +4 -4
  199. package/src/types/icons.ts +6 -0
  200. package/src/types/index.ts +10 -9
  201. package/src/typography/{Link.tsx → Anchor.tsx} +3 -3
  202. package/src/typography/Text.tsx +1 -1
  203. package/src/typography/Title.tsx +0 -1
  204. package/src/typography/Typography.module.css +4 -2
  205. package/src/typography/index.ts +1 -1
  206. package/src/utils/cloneElement.ts +44 -0
  207. package/src/utils/index.ts +1 -0
@@ -21,8 +21,10 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
 
24
+ import { isString } from "@react-fabric/utilities";
24
25
  import classNames from "classnames";
25
- import { type ReactElement, useMemo } from "react";
26
+ import { Fragment, type ReactElement, useMemo } from "react";
27
+ import { Tooltip } from "../../overlays";
26
28
  import {
27
29
  type AriaProps,
28
30
  type BadgeType,
@@ -34,6 +36,7 @@ import {
34
36
  type PolymorphicProps,
35
37
  type RefProp,
36
38
  type TestProps,
39
+ type TooltipProp,
37
40
  } from "../../types";
38
41
  import { Badge, getBadgeProps } from "../badge/Badge";
39
42
  import { DropdownTool } from "../dropdown/DropdownTool";
@@ -46,7 +49,8 @@ export interface TabProps
46
49
  RefProp,
47
50
  AriaProps,
48
51
  TestProps,
49
- IconProps {
52
+ IconProps,
53
+ TooltipProp {
50
54
  /**
51
55
  * tab id
52
56
  */
@@ -62,7 +66,7 @@ export interface TabProps
62
66
  /**
63
67
  * tab badge
64
68
  */
65
- badge?: BadgeType;
69
+ badge?: string | number | BadgeType;
66
70
  /**
67
71
  * disabled
68
72
  */
@@ -110,6 +114,7 @@ export const Tab = <Tag extends React.ElementType = "button">({
110
114
  tabFlex,
111
115
  color,
112
116
  actions,
117
+ tooltip,
113
118
  activeClassName,
114
119
  ...aria
115
120
  }: TabProps & PolymorphicProps<Tag>) => {
@@ -117,63 +122,73 @@ export const Tab = <Tag extends React.ElementType = "button">({
117
122
  return getBadgeProps(badge);
118
123
  }, [badge]);
119
124
 
125
+ const tooltipProps = useMemo(() => {
126
+ if (isString(tooltip)) return { content: tooltip };
127
+
128
+ return tooltip ?? {};
129
+ }, [tooltip]);
130
+
120
131
  const E = as ?? "button";
132
+ const W = tooltip ? Tooltip : Fragment;
121
133
  return (
122
- <E
123
- data-id={id}
124
- disabled={disabled}
125
- data-color={color}
126
- className={classNames(
127
- classes.tabButton,
128
- className,
129
- active && "active pointer-events-none",
130
- active && activeClassName,
131
- disabled && "text-tint-500 pointer-events-none",
132
- tabFlex ? "flex-1" : "flex-initial max-w-36 min-w-24",
133
- "flex items-center justify-center px-1 rounded overflow-hidden",
134
- )}
135
- onClick={() => !active && onClick?.(id)}
136
- ref={ref as AnyObject}
137
- {...aria}
138
- >
139
- {icon && (
140
- <Icon
141
- icon={icon}
142
- bg={iconBg}
143
- color={iconColor}
144
- rtlFlip={rtlFlip}
145
- className="flex-content"
146
- />
147
- )}
148
- {!minimal && (
149
- <label className="flex-initial truncate text-center px-1 py-1">
150
- {label}
151
- </label>
152
- )}
153
- {badge && (
154
- <Badge
155
- {...badgeProps}
156
- placement={minimal ? "end" : ""}
157
- className={classNames("me-1", badgeProps.className)}
158
- />
159
- )}
160
- {actions && active && (
161
- <DropdownTool className="bg-base/20 me-1 z-5">{actions}</DropdownTool>
162
- )}
163
- {onClose && (
164
- <span
165
- role="none"
166
- className={classNames(
167
- "cursor-pointer me-1 opacity-65 hover:opacity-90 pointer-events-auto",
168
- )}
169
- onClick={(e) => {
170
- onClose?.();
171
- e.stopPropagation();
172
- }}
173
- >
174
- &times;
175
- </span>
176
- )}
177
- </E>
134
+ <W {...tooltipProps}>
135
+ <E
136
+ data-id={id}
137
+ disabled={disabled}
138
+ data-color={color}
139
+ data-inner-clickable
140
+ className={classNames(
141
+ classes.tabButton,
142
+ className,
143
+ active && "active pointer-events-none",
144
+ active && activeClassName,
145
+ disabled && "text-tint-500 pointer-events-none",
146
+ tabFlex ? "flex-1" : "flex-initial max-w-36 min-w-24",
147
+ "flex items-center justify-center px-1 rounded overflow-hidden",
148
+ )}
149
+ onClick={() => !active && onClick?.(id)}
150
+ ref={ref as AnyObject}
151
+ {...aria}
152
+ >
153
+ {icon && (
154
+ <Icon
155
+ icon={icon}
156
+ bg={iconBg}
157
+ color={iconColor}
158
+ rtlFlip={rtlFlip}
159
+ className="flex-content"
160
+ />
161
+ )}
162
+ {!minimal && (
163
+ <label className="flex-initial truncate text-center px-1 py-1">
164
+ {label}
165
+ </label>
166
+ )}
167
+ {badge && (
168
+ <Badge
169
+ {...badgeProps}
170
+ placement={minimal ? "end" : ""}
171
+ className={classNames("me-1", badgeProps.className)}
172
+ />
173
+ )}
174
+ {actions && active && (
175
+ <DropdownTool className="bg-base/20 me-1 z-5">{actions}</DropdownTool>
176
+ )}
177
+ {onClose && (
178
+ <span
179
+ role="none"
180
+ className={classNames(
181
+ "cursor-pointer me-1 opacity-65 hover:opacity-90 pointer-events-auto",
182
+ )}
183
+ onClick={(e) => {
184
+ onClose?.();
185
+ e.stopPropagation();
186
+ }}
187
+ >
188
+ &times;
189
+ </span>
190
+ )}
191
+ </E>
192
+ </W>
178
193
  );
179
194
  };
@@ -25,10 +25,10 @@
25
25
  .tabPanel {
26
26
  --color: theme(colors.primary.500);
27
27
 
28
- & > .tabList {
28
+ & > .tabHeader {
29
29
  grid-area: tablist;
30
30
 
31
- & > .tabButton {
31
+ & > .tabList > .tabButton {
32
32
  &[data-color="accent"] {
33
33
  --color: theme(colors.accent.500);
34
34
  }
@@ -64,7 +64,7 @@
64
64
  }
65
65
 
66
66
  &[data-variant="outline"] {
67
- & > .tabList > .tabButton:global(.active) {
67
+ & .tabList > .tabButton:global(.active) {
68
68
  --active-color: theme(backgroundColor.base);
69
69
  --active-border: 0 0 0 1px theme(borderColor.base) inset;
70
70
 
@@ -73,58 +73,47 @@
73
73
  }
74
74
 
75
75
  &[data-variant="solid"] {
76
- & > .tabList > .tabButton:global(.active) {
76
+ & .tabList > .tabButton:global(.active) {
77
77
  color: theme(colors.white);
78
78
  background-color: var(--color);
79
79
  }
80
80
  }
81
81
 
82
82
  &[data-variant="soft"] {
83
- & > .tabList > .tabButton:global(.active) {
83
+ & .tabList > .tabButton:global(.active) {
84
84
  background-color: color-mix(in lab, var(--color) 20%, var(--fabric-bg));
85
85
  }
86
86
  }
87
87
 
88
88
  &[data-orientation="top"] {
89
89
  grid-template: "tablist" auto "content" 1fr / 1fr;
90
- padding-inline: 2px;
91
90
 
92
- &[data-variant="outline"] > .tabList,
93
- &[data-variant="solid"] > .tabList,
94
- &[data-variant="soft"] > .tabList {
91
+ .tabHeader {
95
92
  box-shadow: 0 -1px 0 theme(borderColor.dimmed) inset;
96
93
  }
97
94
  }
98
95
 
99
96
  &[data-orientation="bottom"] {
100
97
  grid-template: "content" 1fr "tablist" auto / 1fr;
101
- padding-inline: 2px;
102
98
 
103
- &[data-variant="outline"] > .tabList,
104
- &[data-variant="solid"] > .tabList,
105
- &[data-variant="soft"] > .tabList {
99
+ .tabHeader {
100
+ margin-top: 1px;
106
101
  box-shadow: 0 1px 0 theme(borderColor.dimmed) inset;
107
102
  }
108
103
  }
109
104
 
110
105
  &[data-orientation="start"] {
111
106
  grid-template: "tablist content" 1fr / auto 1fr;
112
- padding-block: 2px;
113
107
 
114
- &[data-variant="outline"] > .tabList,
115
- &[data-variant="solid"] > .tabList,
116
- &[data-variant="soft"] > .tabList {
108
+ .tabHeader {
117
109
  box-shadow: -1px 0 0 theme(borderColor.dimmed) inset;
118
110
  }
119
111
  }
120
112
 
121
113
  &[data-orientation="end"] {
122
114
  grid-template: "content tablist" 1fr / 1fr auto;
123
- padding-block: 2px;
124
115
 
125
- &[data-variant="outline"] > .tabList,
126
- &[data-variant="solid"] > .tabList,
127
- &[data-variant="soft"] > .tabList {
116
+ .tabHeader {
128
117
  box-shadow: 1px 0 0 theme(borderColor.dimmed) inset;
129
118
  }
130
119
  }
@@ -133,11 +122,11 @@
133
122
 
134
123
  @layer util {
135
124
  .tabPanel {
136
- & > .tabList > .tabButton:global(.active) {
125
+ & .tabList > .tabButton:global(.active) {
137
126
  pointer-events: none;
138
127
  }
139
128
 
140
- &[data-orientation="top"] > .tabList {
129
+ &[data-orientation="top"] .tabList {
141
130
  & > .tabButton:global(.active) {
142
131
  box-shadow:
143
132
  0 -2px 0 var(--active-color) inset,
@@ -145,7 +134,7 @@
145
134
  }
146
135
  }
147
136
 
148
- &[data-orientation="bottom"] > .tabList {
137
+ &[data-orientation="bottom"] .tabList {
149
138
  & > .tabButton:global(.active) {
150
139
  box-shadow:
151
140
  0 2px 0 var(--active-color) inset,
@@ -153,7 +142,7 @@
153
142
  }
154
143
  }
155
144
 
156
- &[data-orientation="start"] > .tabList {
145
+ &[data-orientation="start"] .tabList {
157
146
  & > .tabButton:global(.active) {
158
147
  box-shadow:
159
148
  -2px 0 0 var(--active-color) inset,
@@ -161,7 +150,7 @@
161
150
  }
162
151
  }
163
152
 
164
- &[data-orientation="end"] > .tabList {
153
+ &[data-orientation="end"] .tabList {
165
154
  & > .tabButton:global(.active) {
166
155
  box-shadow:
167
156
  2px 0 0 var(--active-color) inset,
@@ -169,28 +158,28 @@
169
158
  }
170
159
  }
171
160
 
172
- &[data-orientation="top"] > .tabList > .tabButton {
161
+ &[data-orientation="top"] .tabList > .tabButton {
173
162
  margin-top: 2px;
174
163
  margin-inline: 1px;
175
164
  border-end-start-radius: 0;
176
165
  border-end-end-radius: 0;
177
166
  }
178
167
 
179
- &[data-orientation="bottom"] > .tabList > .tabButton {
168
+ &[data-orientation="bottom"] .tabList > .tabButton {
180
169
  margin-bottom: 2px;
181
170
  margin-inline: 1px;
182
171
  border-start-start-radius: 0;
183
172
  border-start-end-radius: 0;
184
173
  }
185
174
 
186
- &[data-orientation="start"] > .tabList > .tabButton {
175
+ &[data-orientation="start"] .tabList > .tabButton {
187
176
  margin-block: 1px;
188
177
  margin-inline-start: 2px;
189
178
  border-start-end-radius: 0;
190
179
  border-end-end-radius: 0;
191
180
  }
192
181
 
193
- &[data-orientation="end"] > .tabList > .tabButton {
182
+ &[data-orientation="end"] .tabList > .tabButton {
194
183
  margin-block: 1px;
195
184
  margin-inline-end: 2px;
196
185
  border-start-start-radius: 0;
@@ -25,6 +25,7 @@ import classNames from "classnames";
25
25
  import {
26
26
  Children,
27
27
  cloneElement,
28
+ type ReactNode,
28
29
  useCallback,
29
30
  useEffect,
30
31
  useMemo,
@@ -64,6 +65,14 @@ export interface TabPanelProps extends ChildrenProp<typeof Tab> {
64
65
  * tab list className
65
66
  */
66
67
  headerClassName?: string;
68
+ /**
69
+ * append element
70
+ */
71
+ append?: ReactNode;
72
+ /**
73
+ * prepend element
74
+ */
75
+ prepend?: ReactNode;
67
76
  /**
68
77
  * change handler
69
78
  */
@@ -84,6 +93,8 @@ export const TabPanel = ({
84
93
  justify,
85
94
  variant,
86
95
  tabFlex,
96
+ append,
97
+ prepend,
87
98
  gap,
88
99
  onBeforeChange,
89
100
  onChange,
@@ -132,21 +143,33 @@ export const TabPanel = ({
132
143
  >
133
144
  <div
134
145
  className={classNames(
135
- classes.tabList,
146
+ classes.tabHeader,
136
147
  headerClassName,
137
148
  justify && `justify-${justify}`,
138
149
  ["start", "end"].includes(orientation) && "flex-col",
139
- "flex flex-nowrap overflow-auto scroll-thin",
150
+ "flex flex-nowrap overflow-hidden items-center",
140
151
  )}
141
- style={{ gap }}
142
152
  >
143
- {tabs.map((node: AnyObject) =>
144
- cloneElement(node, {
145
- tabFlex: node.props.tabFlex ?? tabFlex,
146
- onClick: handleClick,
147
- active: node.props.id === active,
148
- }),
149
- )}
153
+ {prepend}
154
+ <div
155
+ className={classNames(
156
+ classes.tabList,
157
+ justify && `justify-${justify}`,
158
+ ["start", "end"].includes(orientation) && "flex-col",
159
+ ["bottom", "end"].includes(orientation) ? "self-start" : "self-end",
160
+ "flex flex-1 flex-nowrap overflow-auto scroll-thin",
161
+ )}
162
+ style={{ gap }}
163
+ >
164
+ {tabs.map((node: AnyObject) =>
165
+ cloneElement(node, {
166
+ tabFlex: node.props.tabFlex ?? tabFlex,
167
+ onClick: handleClick,
168
+ active: node.props.id === active,
169
+ }),
170
+ )}
171
+ </div>
172
+ {append}
150
173
  </div>
151
174
  {rest}
152
175
  {activeTabPanel}
@@ -23,12 +23,12 @@
23
23
 
24
24
  import classNames from "classnames";
25
25
  import {
26
- type ReactNode,
27
26
  useCallback,
28
27
  useEffect,
29
28
  useMemo,
30
29
  useRef,
31
30
  useState,
31
+ type ReactNode,
32
32
  } from "react";
33
33
  import { Loading } from "../../components/animations/Animations";
34
34
  import { Icon } from "../../components/icon/Icon";
@@ -38,6 +38,7 @@ import { useResize } from "../../hooks/useResize";
38
38
  import {
39
39
  type ChildrenProp,
40
40
  type CollapseProps,
41
+ type CssProp,
41
42
  type Elements,
42
43
  type IconProps,
43
44
  type TestProps,
@@ -50,6 +51,7 @@ export interface AsideProps
50
51
  extends IconProps,
51
52
  ChildrenProp,
52
53
  CollapseProps,
54
+ CssProp,
53
55
  TestProps {
54
56
  /**
55
57
  * page title
@@ -67,6 +69,10 @@ export interface AsideProps
67
69
  * header class
68
70
  */
69
71
  headerClassName?: string;
72
+ /**
73
+ * header class
74
+ */
75
+ bodyClassName?: string;
70
76
 
71
77
  /**
72
78
  * show loading indicator
@@ -109,6 +115,8 @@ export const Aside = ({
109
115
  iconBg,
110
116
  iconColor,
111
117
  rtlFlip,
118
+ className,
119
+ bodyClassName,
112
120
  headerClassName,
113
121
  resizeable,
114
122
  flyout,
@@ -189,9 +197,10 @@ export const Aside = ({
189
197
 
190
198
  return (
191
199
  <aside
192
- className={classNames(classes.aside, "overflow-hidden grid")}
200
+ className={classNames(classes.aside, className, "overflow-hidden grid")}
193
201
  data-align={align}
194
202
  data-flyout={peek}
203
+ data-loading={loading}
195
204
  data-collapsed={isCollapsed}
196
205
  style={isCollapsed ? undefined : widthStyles}
197
206
  data-testid={testId}
@@ -203,6 +212,7 @@ export const Aside = ({
203
212
  headerClassName,
204
213
  "grid area-head items-center",
205
214
  )}
215
+ data-ref="asideHeader"
206
216
  >
207
217
  {title && (
208
218
  <div
@@ -250,7 +260,11 @@ export const Aside = ({
250
260
  <section
251
261
  ref={elementRef}
252
262
  data-ref="asideBody"
253
- className={classNames(classes.asideBody, "overflow-hidden grid")}
263
+ className={classNames(
264
+ classes.asideBody,
265
+ bodyClassName,
266
+ "overflow-hidden grid",
267
+ )}
254
268
  style={isCollapsed ? widthStyles : undefined}
255
269
  >
256
270
  <ErrorBoundary>{children}</ErrorBoundary>
@@ -22,14 +22,14 @@
22
22
  */
23
23
 
24
24
  import classNames from "classnames";
25
- import { useImperativeHandle } from "react";
25
+ import { type MouseEvent, useImperativeHandle } from "react";
26
26
  import { useDebounce } from "../../hooks/useDebounce";
27
27
  import { useResizeObserver } from "../../hooks/useResizeObserver";
28
28
  import {
29
29
  type ChildrenProp,
30
30
  type CssProp,
31
- type PositionObject,
32
31
  type RefProp,
32
+ type ScrollObject,
33
33
  type SizeObject,
34
34
  type TestProps,
35
35
  } from "../../types";
@@ -44,7 +44,7 @@ export interface ContentProps
44
44
  /**
45
45
  * scroll vevent handler
46
46
  */
47
- onScroll?: (event: PositionObject) => void;
47
+ onScroll?: (scroll: ScrollObject, event: MouseEvent<HTMLDivElement>) => void;
48
48
  /**
49
49
  * scroll vevent handler
50
50
  */
@@ -65,13 +65,19 @@ export const Content = ({
65
65
  }: ContentProps) => {
66
66
  const resizeHandle = useResizeObserver(onResize);
67
67
  const scrollHandler = useDebounce(
68
- (e: React.UIEvent<HTMLDivElement>) => {
69
- onScroll?.({
70
- // @ts-expect-error ignore
71
- left: e.target.scrollLeft,
72
- // @ts-expect-error ignore
73
- top: e.target.scrollTop,
74
- });
68
+ (e: MouseEvent<HTMLDivElement>) => {
69
+ const el = e.target as HTMLElement;
70
+ onScroll?.(
71
+ {
72
+ left: el.scrollLeft,
73
+ top: el.scrollTop,
74
+ scrollHeight: el.scrollHeight,
75
+ scrollWidth: el.scrollWidth,
76
+ width: el.offsetWidth,
77
+ height: el.offsetHeight,
78
+ },
79
+ e,
80
+ );
75
81
  },
76
82
  [onScroll],
77
83
  );
@@ -23,6 +23,8 @@
23
23
 
24
24
  @layer comp {
25
25
  .headfoot {
26
+ gap: 2px;
27
+
26
28
  .buttonWrapper + .buttonWrapper {
27
29
  margin-inline-start: 0.25rem;
28
30
  }
@@ -93,7 +93,7 @@ const HeadFoot = ({
93
93
  color && getColorClass(color),
94
94
  area === "head" ? "area-head" : "area-foot",
95
95
  `leading-none`,
96
- flex && "flex flex-nowrap gap-px",
96
+ flex && "flex flex-nowrap",
97
97
  align && `items-${align}`,
98
98
  justify && `justify-${justify}`,
99
99
  )}
@@ -66,6 +66,7 @@ export const Page = ({
66
66
  <div
67
67
  data-testid={testId}
68
68
  data-test-value={testValue}
69
+ data-loading={loading}
69
70
  className={classNames(
70
71
  classes.page,
71
72
  "overflow-hidden grid area-content",
@@ -81,7 +81,7 @@ export interface ColProps
81
81
  /**
82
82
  * column flex
83
83
  */
84
- flex?: "auto" | "fill" | "full";
84
+ flex?: "auto" | "fill" | "full" | "content";
85
85
  /**
86
86
  * stretch inner content
87
87
  */
@@ -159,9 +159,10 @@ export const Col = ({
159
159
  classes.col,
160
160
  className,
161
161
  stretchContent && classes.stretchContent,
162
- flex === "auto" && "flex-content",
163
162
  flex === "fill" && "flex-1",
164
163
  flex === "full" && "flex-full",
164
+ flex === "auto" && "flex-initial",
165
+ flex === "content" && "flex-content",
165
166
  align && `self-${align}`,
166
167
  )}
167
168
  {...aria}
@@ -23,6 +23,6 @@
23
23
 
24
24
  @layer comp {
25
25
  .section {
26
- grid-template: "head head head" auto "side-s content side-e" 1fr "foot foot foot" auto / auto 1fr auto;
26
+ grid-template: ". loader ." auto "head head head" auto "side-s content side-e" 1fr "foot foot foot" auto / auto 1fr auto;
27
27
  }
28
28
  }
@@ -57,7 +57,7 @@ export interface ThemeProps {
57
57
  /**
58
58
  * component rounding
59
59
  */
60
- rounding?: "minimal" | "normal" | "full";
60
+ rounding?: "sm" | "md" | "full";
61
61
  }
62
62
 
63
63
  /**
@@ -21,24 +21,29 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
 
24
- import { useCallback, useMemo, useState } from "react";
24
+ import { useCallback, useMemo, useRef, useState } from "react";
25
25
 
26
26
  export const useNavigator = (totalCount = 0, defaultIndex = 0) => {
27
27
  const [currentIndex, setCurrentIndex] = useState(defaultIndex);
28
+ const refCurrent = useRef(defaultIndex);
29
+
28
30
  const onNavigate = useCallback(
29
31
  (dir: 1 | -1) => {
30
32
  if (dir === -1) {
31
- setCurrentIndex(currentIndex > 0 ? currentIndex - 1 : totalCount - 1);
33
+ refCurrent.current =
34
+ refCurrent.current > 0 ? refCurrent.current - 1 : totalCount - 1;
32
35
  }
33
36
  if (dir === 1) {
34
- setCurrentIndex(currentIndex + 1 < totalCount ? currentIndex + 1 : 0);
37
+ refCurrent.current =
38
+ refCurrent.current + 1 < totalCount ? refCurrent.current + 1 : 0;
35
39
  }
40
+ setCurrentIndex(refCurrent.current);
36
41
  },
37
- [currentIndex, totalCount],
42
+ [totalCount],
38
43
  );
39
44
  const headLabel = useMemo(
40
45
  () => (
41
- <span className="text-muted leading-none">
46
+ <span className="text-muted leading-none select-none">
42
47
  {currentIndex + 1}/{totalCount}
43
48
  </span>
44
49
  ),
@@ -21,10 +21,15 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
 
24
- import { useState, type FC, type ReactNode } from "react";
24
+ import {
25
+ useState,
26
+ type ComponentProps,
27
+ type ElementType,
28
+ type ReactNode,
29
+ } from "react";
25
30
 
26
- type OverlayComponent = FC<{
27
- onClose: (args?: AnyObject) => void;
31
+ type OverlayComponent = ElementType<{
32
+ onClose: (...args: AnyObject) => void;
28
33
  [key: string]: AnyObject;
29
34
  }>;
30
35
 
@@ -36,7 +41,10 @@ export const useOverlayService = (
36
41
  ] => {
37
42
  const [Overlay, setOverlay] = useState<ReactNode | null>(null);
38
43
 
39
- const openOverlay = async ({ onClose, ...props }: KeyValue = {}) => {
44
+ const openOverlay = async ({
45
+ onClose,
46
+ ...props
47
+ }: ComponentProps<typeof ModalOrFlyout> = {}) => {
40
48
  return await new Promise((resolve) => {
41
49
  const handleClose = (args: AnyObject) => {
42
50
  setOverlay(null);