@react-fabric/core 1.0.0-beta.1 → 1.0.0-beta.11
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/css/index.js +13 -13
- package/dist/cjs/components/actionLabel/ActionLabel.js +1 -0
- package/dist/cjs/components/animations/Animations.js +13 -6
- package/dist/cjs/components/avatar/Avatar.js +6 -7
- package/dist/cjs/components/badge/Badge.js +6 -4
- package/dist/cjs/components/breadcrumbs/Breadcrumbs.js +2 -2
- package/dist/cjs/components/button/Button.js +9 -7
- package/dist/cjs/components/button/Button.module.css +1 -1
- package/dist/cjs/components/button/ConfirmButton.js +4 -2
- package/dist/cjs/components/callout/Callout.js +3 -2
- package/dist/cjs/components/card/Card.js +4 -2
- package/dist/cjs/components/chip/Chip.js +2 -2
- package/dist/cjs/components/chip/Chip.module.css +1 -1
- package/dist/cjs/components/collapsable/Collapsable.js +5 -3
- package/dist/cjs/components/divider/Divider.js +3 -2
- package/dist/cjs/components/divider/Divider.module.css +1 -0
- package/dist/cjs/components/dropdown/Dropdown.js +4 -2
- package/dist/cjs/components/dropdown/DropdownTool.js +3 -2
- package/dist/cjs/components/icon/Icon.js +8 -7
- package/dist/cjs/components/menu/ContextMenu.js +30 -10
- package/dist/cjs/components/menu/Menu.js +1 -1
- package/dist/cjs/components/menu/MenuItem.js +1 -1
- package/dist/cjs/components/navigator/Navigator.js +15 -9
- package/dist/cjs/components/panel/Panel.js +2 -0
- package/dist/cjs/components/tabpanel/Tab.js +55 -36
- package/dist/cjs/components/tabpanel/TabPanel.js +18 -13
- package/dist/cjs/components/tabpanel/TabPanel.module.css +1 -1
- package/dist/cjs/core/aside/Aside.js +7 -2
- package/dist/cjs/core/content/Content.js +8 -5
- package/dist/cjs/core/headfoot/HeadFoot.js +1 -1
- package/dist/cjs/core/headfoot/HeadFoot.module.css +1 -1
- package/dist/cjs/core/page/Page.js +1 -0
- package/dist/cjs/core/section/Section.js +5 -2
- package/dist/cjs/hooks/useNavigator.js +6 -4
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/overlays/alert/Alert.js +38 -16
- package/dist/cjs/overlays/modal/Modal.js +1 -1
- package/dist/cjs/overlays/tooltip/Tooltip.js +2 -2
- package/dist/cjs/overlays/tooltip/Tooltip.module.css +1 -1
- package/dist/cjs/types/icons.js +3 -0
- package/dist/cjs/typography/Abbr.js +2 -0
- package/dist/cjs/typography/{Link.js → Anchor.js} +2 -2
- package/dist/cjs/typography/Typography.module.css +1 -1
- package/dist/esm/components/actionLabel/ActionLabel.js +1 -0
- package/dist/esm/components/animations/Animations.js +13 -6
- package/dist/esm/components/avatar/Avatar.js +7 -8
- package/dist/esm/components/badge/Badge.js +7 -5
- package/dist/esm/components/breadcrumbs/Breadcrumbs.js +2 -2
- package/dist/esm/components/button/Button.js +9 -7
- package/dist/esm/components/button/Button.module.css +1 -1
- package/dist/esm/components/button/ConfirmButton.js +4 -2
- package/dist/esm/components/callout/Callout.js +3 -2
- package/dist/esm/components/card/Card.js +4 -2
- package/dist/esm/components/chip/Chip.js +2 -2
- package/dist/esm/components/chip/Chip.module.css +1 -1
- package/dist/esm/components/collapsable/Collapsable.js +5 -3
- package/dist/esm/components/divider/Divider.js +3 -2
- package/dist/esm/components/divider/Divider.module.css +1 -0
- package/dist/esm/components/dropdown/Dropdown.js +4 -2
- package/dist/esm/components/dropdown/DropdownTool.js +3 -2
- package/dist/esm/components/icon/Icon.js +8 -7
- package/dist/esm/components/menu/ContextMenu.js +32 -12
- package/dist/esm/components/menu/Menu.js +1 -1
- package/dist/esm/components/menu/MenuItem.js +1 -1
- package/dist/esm/components/navigator/Navigator.js +15 -9
- package/dist/esm/components/panel/Panel.js +2 -0
- package/dist/esm/components/tabpanel/Tab.js +56 -37
- package/dist/esm/components/tabpanel/TabPanel.js +18 -13
- package/dist/esm/components/tabpanel/TabPanel.module.css +1 -1
- package/dist/esm/core/aside/Aside.js +7 -2
- package/dist/esm/core/content/Content.js +8 -5
- package/dist/esm/core/headfoot/HeadFoot.js +1 -1
- package/dist/esm/core/headfoot/HeadFoot.module.css +1 -1
- package/dist/esm/core/page/Page.js +1 -0
- package/dist/esm/core/section/Section.js +5 -2
- package/dist/esm/hooks/useNavigator.js +7 -5
- package/dist/esm/index.js +2 -1
- package/dist/esm/overlays/alert/Alert.js +27 -5
- package/dist/esm/overlays/modal/Modal.js +1 -1
- package/dist/esm/overlays/tooltip/Tooltip.js +2 -2
- package/dist/esm/overlays/tooltip/Tooltip.module.css +1 -1
- package/dist/esm/types/icons.js +3 -0
- package/dist/esm/typography/Abbr.js +2 -0
- package/dist/esm/typography/{Link.js → Anchor.js} +2 -2
- package/dist/esm/typography/Typography.module.css +1 -1
- package/dist/types/components/actionLabel/ActionLabel.d.ts +2 -2
- package/dist/types/components/animations/Animations.d.ts +1 -1
- package/dist/types/components/breadcrumbs/Breadcrumbs.d.ts +2 -2
- package/dist/types/components/button/Button.d.ts +5 -2
- package/dist/types/components/button/ConfirmButton.d.ts +6 -1
- package/dist/types/components/callout/Callout.d.ts +3 -3
- package/dist/types/components/card/Card.d.ts +3 -3
- package/dist/types/components/collapsable/Collapsable.d.ts +9 -1
- package/dist/types/components/dropdown/DropdownTool.d.ts +2 -1
- package/dist/types/components/media/Media.d.ts +2 -2
- package/dist/types/components/menu/ContextMenu.d.ts +2 -1
- package/dist/types/components/menu/types.d.ts +2 -2
- package/dist/types/components/navigator/Navigator.d.ts +3 -3
- package/dist/types/components/tabpanel/Tab.d.ts +8 -4
- package/dist/types/components/tabpanel/TabPanel.d.ts +10 -1
- package/dist/types/core/aside/Aside.d.ts +9 -5
- package/dist/types/core/content/Content.d.ts +3 -2
- package/dist/types/core/section/Section.d.ts +2 -2
- package/dist/types/overlays/alert/Alert.d.ts +9 -1
- package/dist/types/overlays/modal/Modal.d.ts +1 -1
- package/dist/types/types/icons.d.ts +3 -0
- package/dist/types/types/index.d.ts +6 -2
- package/dist/types/typography/Abbr.d.ts +3 -3
- package/dist/types/typography/{Link.d.ts → Anchor.d.ts} +4 -3
- package/dist/types/typography/index.d.ts +1 -1
- package/package.json +3 -3
- package/src/components/actionLabel/ActionLabel.tsx +13 -3
- package/src/components/animations/Animations.tsx +9 -3
- package/src/components/avatar/Avatar.tsx +68 -81
- package/src/components/badge/Badge.tsx +24 -20
- package/src/components/breadcrumbs/Breadcrumbs.tsx +3 -3
- package/src/components/button/Button.module.css +1 -1
- package/src/components/button/Button.tsx +16 -10
- package/src/components/button/ConfirmButton.tsx +10 -4
- package/src/components/callout/Callout.tsx +8 -1
- package/src/components/card/Card.tsx +4 -0
- package/src/components/chip/Chip.module.css +1 -1
- package/src/components/chip/Chip.tsx +2 -4
- package/src/components/collapsable/Collapsable.tsx +12 -1
- package/src/components/divider/Divider.module.css +32 -0
- package/src/components/divider/Divider.tsx +3 -2
- package/src/components/dropdown/Dropdown.tsx +3 -2
- package/src/components/dropdown/DropdownTool.tsx +3 -1
- package/src/components/icon/Icon.tsx +46 -57
- package/src/components/media/Media.tsx +2 -2
- package/src/components/menu/ContextMenu.tsx +36 -11
- package/src/components/menu/Menu.tsx +2 -2
- package/src/components/menu/types.ts +2 -2
- package/src/components/navigator/Navigator.tsx +16 -4
- package/src/components/panel/Panel.tsx +2 -0
- package/src/components/tabpanel/Tab.tsx +78 -59
- package/src/components/tabpanel/TabPanel.module.css +19 -26
- package/src/components/tabpanel/TabPanel.tsx +32 -10
- package/src/core/aside/Aside.tsx +26 -4
- package/src/core/content/Content.tsx +16 -10
- package/src/core/headfoot/HeadFoot.module.css +2 -0
- package/src/core/headfoot/HeadFoot.tsx +1 -1
- package/src/core/page/Page.tsx +1 -0
- package/src/core/section/Section.tsx +8 -2
- package/src/hooks/useNavigator.tsx +10 -5
- package/src/overlays/alert/Alert.tsx +25 -2
- package/src/overlays/modal/Modal.tsx +2 -2
- package/src/overlays/tooltip/Tooltip.module.css +1 -1
- package/src/overlays/tooltip/Tooltip.tsx +3 -3
- package/src/types/icons.ts +6 -0
- package/src/types/index.ts +10 -2
- package/src/typography/Abbr.tsx +4 -3
- package/src/typography/{Link.tsx → Anchor.tsx} +6 -3
- package/src/typography/Typography.module.css +2 -2
- package/src/typography/index.ts +1 -1
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
import { isSvgPath } from "@react-fabric/utilities";
|
|
25
25
|
import BoringAvatar from "boring-avatars";
|
|
26
26
|
import classNames from "classnames";
|
|
27
|
-
import { useState } from "react";
|
|
28
|
-
import { useMemoDebugger } from "../../hooks/useEffectDebugger";
|
|
27
|
+
import { useMemo, useState } from "react";
|
|
29
28
|
import {
|
|
30
29
|
type AriaProps,
|
|
31
30
|
type ColorType,
|
|
@@ -109,89 +108,77 @@ export const Avatar = ({
|
|
|
109
108
|
const [fallback, setFallback] = useState(true);
|
|
110
109
|
|
|
111
110
|
/** ***************** style map *******************/
|
|
112
|
-
const styles =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
},
|
|
129
|
-
[bg, color, size],
|
|
130
|
-
"Avatar styles",
|
|
131
|
-
);
|
|
111
|
+
const styles = useMemo(() => {
|
|
112
|
+
const s: KeyValue = {};
|
|
113
|
+
if (bg) {
|
|
114
|
+
s.backgroundColor = getColor(bg);
|
|
115
|
+
}
|
|
116
|
+
if (color) {
|
|
117
|
+
s.color = getColor(color);
|
|
118
|
+
}
|
|
119
|
+
if (size && !(size in SizeMap)) {
|
|
120
|
+
s.fontSize = size;
|
|
121
|
+
}
|
|
122
|
+
if (size && size in SizeMap) {
|
|
123
|
+
s.fontSize = SizeMap[size];
|
|
124
|
+
}
|
|
125
|
+
return s;
|
|
126
|
+
}, [bg, color, size]);
|
|
132
127
|
|
|
133
128
|
/** ***************** render icon *******************/
|
|
134
|
-
const avatarImage =
|
|
135
|
-
()
|
|
136
|
-
|
|
129
|
+
const avatarImage = useMemo(() => {
|
|
130
|
+
setFallback(!avatar);
|
|
131
|
+
return (
|
|
132
|
+
avatar && (
|
|
133
|
+
<div className="contents">
|
|
134
|
+
<div
|
|
135
|
+
className={classNames(
|
|
136
|
+
classes.imgPlaceholder,
|
|
137
|
+
"absolute inset-0 bg-gray animate-pulse",
|
|
138
|
+
)}
|
|
139
|
+
/>
|
|
140
|
+
<img
|
|
141
|
+
src={avatar}
|
|
142
|
+
alt={avatar}
|
|
143
|
+
className="align-baseline"
|
|
144
|
+
onError={() => setFallback(true)}
|
|
145
|
+
onLoad={(e) => e.currentTarget.previousElementSibling?.remove()}
|
|
146
|
+
/>
|
|
147
|
+
</div>
|
|
148
|
+
)
|
|
149
|
+
);
|
|
150
|
+
}, [avatar]);
|
|
151
|
+
|
|
152
|
+
const fallbackAvatar = useMemo(() => {
|
|
153
|
+
if (fallbackIcon) {
|
|
154
|
+
return isSvgPath(fallbackIcon) ? (
|
|
155
|
+
<svg viewBox={viewBox}>
|
|
156
|
+
<path fill="currentColor" d={fallbackIcon.toString()} />
|
|
157
|
+
</svg>
|
|
158
|
+
) : (
|
|
159
|
+
<i className={fallbackIcon} />
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
if (variant === "text") {
|
|
163
|
+
const [, first, second, group] =
|
|
164
|
+
name.match(/(?=(\w).* (\w).*)|(?=(\w\w).*)/) ?? [];
|
|
137
165
|
return (
|
|
138
|
-
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
onError={() => setFallback(true)}
|
|
151
|
-
onLoad={(e) => e.currentTarget.previousElementSibling?.remove()}
|
|
152
|
-
/>
|
|
153
|
-
</div>
|
|
154
|
-
)
|
|
166
|
+
<svg role="img">
|
|
167
|
+
<text
|
|
168
|
+
x="50%"
|
|
169
|
+
y="50%"
|
|
170
|
+
dy=".1em"
|
|
171
|
+
dominantBaseline="middle"
|
|
172
|
+
textAnchor="middle"
|
|
173
|
+
style={{ fontSize: ".5em", fontWeight: 500 }}
|
|
174
|
+
>
|
|
175
|
+
{group ?? `${first}${second}`}
|
|
176
|
+
</text>
|
|
177
|
+
</svg>
|
|
155
178
|
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
const fallbackAvatar = useMemoDebugger(
|
|
162
|
-
() => {
|
|
163
|
-
if (fallbackIcon) {
|
|
164
|
-
return isSvgPath(fallbackIcon) ? (
|
|
165
|
-
<svg viewBox={viewBox}>
|
|
166
|
-
<path fill="currentColor" d={fallbackIcon.toString()} />
|
|
167
|
-
</svg>
|
|
168
|
-
) : (
|
|
169
|
-
<i className={fallbackIcon} />
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
if (variant === "text") {
|
|
173
|
-
const [, first, second, group] =
|
|
174
|
-
name.match(/(?=(\w).* (\w).*)|(?=(\w\w).*)/) ?? [];
|
|
175
|
-
return (
|
|
176
|
-
<svg role="img">
|
|
177
|
-
<text
|
|
178
|
-
x="50%"
|
|
179
|
-
y="50%"
|
|
180
|
-
dy=".1em"
|
|
181
|
-
dominantBaseline="middle"
|
|
182
|
-
textAnchor="middle"
|
|
183
|
-
style={{ fontSize: ".5em", fontWeight: 500 }}
|
|
184
|
-
>
|
|
185
|
-
{group ?? `${first}${second}`}
|
|
186
|
-
</text>
|
|
187
|
-
</svg>
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
return <BoringAvatar square size={64} variant={variant} name={name} />;
|
|
191
|
-
},
|
|
192
|
-
[name, variant, fallbackIcon],
|
|
193
|
-
"Avatar fallback",
|
|
194
|
-
);
|
|
179
|
+
}
|
|
180
|
+
return <BoringAvatar square size={64} variant={variant} name={name} />;
|
|
181
|
+
}, [name, variant, fallbackIcon]);
|
|
195
182
|
|
|
196
183
|
return (
|
|
197
184
|
<dfn
|
|
@@ -21,7 +21,7 @@
|
|
|
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 { isNumber, isObject, mergeRefs } from "@react-fabric/utilities";
|
|
24
|
+
import { isNil, isNumber, isObject, mergeRefs } from "@react-fabric/utilities";
|
|
25
25
|
import classNames from "classnames";
|
|
26
26
|
import { cloneElement, useMemo } from "react";
|
|
27
27
|
import {
|
|
@@ -101,10 +101,12 @@ export const Badge = ({
|
|
|
101
101
|
...rest
|
|
102
102
|
}: BadgeProps) => {
|
|
103
103
|
const label = useMemo(() => {
|
|
104
|
-
if (
|
|
105
|
-
|
|
104
|
+
if (!isNil(value)) {
|
|
105
|
+
if (isNumber(value) && max && value > max) {
|
|
106
|
+
return `${max}+`;
|
|
107
|
+
}
|
|
108
|
+
return `${value}`;
|
|
106
109
|
}
|
|
107
|
-
return `${value}`;
|
|
108
110
|
}, [value, max]);
|
|
109
111
|
|
|
110
112
|
const innerRef = useMemo(
|
|
@@ -127,22 +129,24 @@ export const Badge = ({
|
|
|
127
129
|
...rest,
|
|
128
130
|
ref: innerRef,
|
|
129
131
|
})}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
132
|
+
{(!!ping || label) && (
|
|
133
|
+
<div
|
|
134
|
+
data-ref="badge"
|
|
135
|
+
data-ping={ping}
|
|
136
|
+
data-placement={placement}
|
|
137
|
+
className={classNames(
|
|
138
|
+
classes.badge,
|
|
139
|
+
className,
|
|
140
|
+
"inline-block p-px min-w-2 min-h-2 text-center select-none rounded-full leading-none z-5 pointer-events-none",
|
|
141
|
+
forButton && !placement ? "relative" : "absolute",
|
|
142
|
+
)}
|
|
143
|
+
>
|
|
144
|
+
{label && <span className="p-1">{label}</span>}
|
|
145
|
+
{icon && (
|
|
146
|
+
<Icon icon={icon} bg={iconBg} color={iconColor} rtlFlip={rtlFlip} />
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
)}
|
|
146
150
|
</div>
|
|
147
151
|
);
|
|
148
152
|
};
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
import classNames from "classnames";
|
|
25
25
|
import { Children, useMemo } from "react";
|
|
26
26
|
import { type AriaProps, type ChildrenProp, type CssProp } from "../../types";
|
|
27
|
-
import {
|
|
27
|
+
import { Anchor } from "../../typography/Anchor";
|
|
28
28
|
import { Dropdown } from "../dropdown/Dropdown";
|
|
29
29
|
import classes from "./Breadcrumbs.module.css";
|
|
30
30
|
|
|
31
31
|
export interface BreadcrumbProps
|
|
32
32
|
extends CssProp,
|
|
33
33
|
AriaProps,
|
|
34
|
-
ChildrenProp<typeof
|
|
34
|
+
ChildrenProp<typeof Anchor> {
|
|
35
35
|
/**
|
|
36
36
|
* breadcrumb styling
|
|
37
37
|
*/
|
|
@@ -85,7 +85,7 @@ export const Breadcrumbs = ({
|
|
|
85
85
|
{overflow && (
|
|
86
86
|
<Dropdown closeOnClick showArrow>
|
|
87
87
|
<li className={classes.breadcrumbLink} data-separator={separator}>
|
|
88
|
-
<
|
|
88
|
+
<Anchor>...</Anchor>
|
|
89
89
|
</li>
|
|
90
90
|
<div
|
|
91
91
|
data-color={color}
|
|
@@ -136,6 +136,8 @@ export interface BaseProps
|
|
|
136
136
|
*/
|
|
137
137
|
hotKey?: string;
|
|
138
138
|
|
|
139
|
+
stopPropagation?: boolean;
|
|
140
|
+
|
|
139
141
|
onMouseOut?: MouseEventHandler;
|
|
140
142
|
onMouseOver?: MouseEventHandler;
|
|
141
143
|
onMouseMove?: MouseEventHandler;
|
|
@@ -145,10 +147,14 @@ export interface BaseProps
|
|
|
145
147
|
onWheel?: WheelEventHandler;
|
|
146
148
|
}
|
|
147
149
|
|
|
148
|
-
|
|
150
|
+
type ButtonTypeProps =
|
|
149
151
|
| { children: string | React.ReactElement; "aria-label"?: string }
|
|
150
152
|
| { children?: never; "aria-label": string };
|
|
151
153
|
|
|
154
|
+
export type ButtonProps<Tag extends React.ElementType = "button"> = BaseProps &
|
|
155
|
+
ButtonTypeProps &
|
|
156
|
+
PolymorphicProps<Tag>;
|
|
157
|
+
|
|
152
158
|
/**
|
|
153
159
|
* Clickable action button
|
|
154
160
|
*/
|
|
@@ -175,6 +181,7 @@ export const Button = <Tag extends React.ElementType = "button">({
|
|
|
175
181
|
spinOnHover,
|
|
176
182
|
onClick,
|
|
177
183
|
actionMessage,
|
|
184
|
+
stopPropagation,
|
|
178
185
|
type = "button",
|
|
179
186
|
hotKey,
|
|
180
187
|
showActionDone,
|
|
@@ -183,7 +190,7 @@ export const Button = <Tag extends React.ElementType = "button">({
|
|
|
183
190
|
// @ts-expect-error ignore
|
|
184
191
|
"data-ref": dataRef,
|
|
185
192
|
...aria
|
|
186
|
-
}:
|
|
193
|
+
}: ButtonProps<Tag>) => {
|
|
187
194
|
const refEl = useRef<AnyObject>(null);
|
|
188
195
|
const [busy, setBusy] = useState(false);
|
|
189
196
|
const [actionDone, setActionDone] = useState(false);
|
|
@@ -191,7 +198,7 @@ export const Button = <Tag extends React.ElementType = "button">({
|
|
|
191
198
|
const clickHandler = useCallback(
|
|
192
199
|
(e: React.MouseEvent) => {
|
|
193
200
|
setBusy(true);
|
|
194
|
-
|
|
201
|
+
stopPropagation && e.stopPropagation();
|
|
195
202
|
const ret = onClick?.(e);
|
|
196
203
|
void Promise.resolve(ret).then((b) => {
|
|
197
204
|
setBusy(false);
|
|
@@ -200,7 +207,7 @@ export const Button = <Tag extends React.ElementType = "button">({
|
|
|
200
207
|
}
|
|
201
208
|
});
|
|
202
209
|
},
|
|
203
|
-
[onClick, disabled, actionMessage, showActionDoneEvent],
|
|
210
|
+
[onClick, disabled, actionMessage, showActionDoneEvent, stopPropagation],
|
|
204
211
|
);
|
|
205
212
|
|
|
206
213
|
/** ***************** reset done state on timeout *******************/
|
|
@@ -237,6 +244,10 @@ export const Button = <Tag extends React.ElementType = "button">({
|
|
|
237
244
|
return getBadgeProps(badge);
|
|
238
245
|
}, [badge]);
|
|
239
246
|
|
|
247
|
+
const hotKeyHandler = useRef(() => {
|
|
248
|
+
!disabled && refEl.current?.click();
|
|
249
|
+
});
|
|
250
|
+
|
|
240
251
|
const E = as ?? "button";
|
|
241
252
|
return (
|
|
242
253
|
<div
|
|
@@ -251,12 +262,7 @@ export const Button = <Tag extends React.ElementType = "button">({
|
|
|
251
262
|
data-loading={busy || loading}
|
|
252
263
|
data-disabled={disabled}
|
|
253
264
|
>
|
|
254
|
-
{hotKey &&
|
|
255
|
-
<HotKey
|
|
256
|
-
keyCombo={hotKey}
|
|
257
|
-
handler={() => !disabled && refEl.current?.click()}
|
|
258
|
-
/>
|
|
259
|
-
)}
|
|
265
|
+
{hotKey && <HotKey keyCombo={hotKey} handler={hotKeyHandler.current} />}
|
|
260
266
|
<TooltipWrapper {...tooltipProps}>
|
|
261
267
|
<E
|
|
262
268
|
ref={mergeRefs(ref, refEl)}
|
|
@@ -22,18 +22,19 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import {
|
|
25
|
-
FloatingArrow,
|
|
26
|
-
FloatingFocusManager,
|
|
27
|
-
FloatingPortal,
|
|
28
25
|
arrow,
|
|
29
26
|
autoUpdate,
|
|
30
27
|
flip,
|
|
28
|
+
FloatingArrow,
|
|
29
|
+
FloatingFocusManager,
|
|
30
|
+
FloatingPortal,
|
|
31
31
|
offset,
|
|
32
32
|
shift,
|
|
33
33
|
useClick,
|
|
34
34
|
useDismiss,
|
|
35
35
|
useFloating,
|
|
36
36
|
useInteractions,
|
|
37
|
+
type Placement,
|
|
37
38
|
} from "@floating-ui/react";
|
|
38
39
|
import { mergeRefs } from "@react-fabric/utilities";
|
|
39
40
|
import classNames from "classnames";
|
|
@@ -66,6 +67,10 @@ interface ExtendedProps extends Omit<BaseProps, "onClick">, RefProp {
|
|
|
66
67
|
* ok label
|
|
67
68
|
*/
|
|
68
69
|
cancelLabel?: string;
|
|
70
|
+
/**
|
|
71
|
+
* dropdown placement
|
|
72
|
+
*/
|
|
73
|
+
placement?: Placement;
|
|
69
74
|
/**
|
|
70
75
|
* click handler, return Promise to autoset loading state
|
|
71
76
|
*/
|
|
@@ -85,6 +90,7 @@ export const ConfirmButton = <Tag extends React.ElementType = "button">({
|
|
|
85
90
|
cancelLabel,
|
|
86
91
|
onClick,
|
|
87
92
|
loading,
|
|
93
|
+
placement = "bottom",
|
|
88
94
|
actionMessage,
|
|
89
95
|
showActionDone,
|
|
90
96
|
showActionDoneEvent = "click",
|
|
@@ -127,7 +133,7 @@ export const ConfirmButton = <Tag extends React.ElementType = "button">({
|
|
|
127
133
|
}
|
|
128
134
|
},
|
|
129
135
|
strategy: "fixed",
|
|
130
|
-
placement
|
|
136
|
+
placement,
|
|
131
137
|
whileElementsMounted: autoUpdate,
|
|
132
138
|
middleware: [
|
|
133
139
|
shift({ padding: 8 }),
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
type AriaProps,
|
|
27
27
|
type ChildrenProp,
|
|
28
28
|
type ColorType,
|
|
29
|
+
type CssProp,
|
|
29
30
|
type PaletteType,
|
|
30
31
|
type TestProps,
|
|
31
32
|
} from "../../types";
|
|
@@ -33,7 +34,11 @@ import { CoreIcons } from "../../types/icons";
|
|
|
33
34
|
import { getBgClass, getBorderClass, getColorClass } from "../../utils";
|
|
34
35
|
import { Icon } from "../icon/Icon";
|
|
35
36
|
|
|
36
|
-
export interface CalloutProps
|
|
37
|
+
export interface CalloutProps
|
|
38
|
+
extends AriaProps,
|
|
39
|
+
ChildrenProp,
|
|
40
|
+
CssProp,
|
|
41
|
+
TestProps {
|
|
37
42
|
/**
|
|
38
43
|
* callout color
|
|
39
44
|
*/
|
|
@@ -69,11 +74,13 @@ export const Callout = ({
|
|
|
69
74
|
icon,
|
|
70
75
|
border,
|
|
71
76
|
onClose,
|
|
77
|
+
className,
|
|
72
78
|
...aria
|
|
73
79
|
}: CalloutProps) => {
|
|
74
80
|
return (
|
|
75
81
|
<fieldset
|
|
76
82
|
className={classNames(
|
|
83
|
+
className,
|
|
77
84
|
"block rounded-capped border max-w-full relative overflow-hidden mb-4",
|
|
78
85
|
getBgClass(color + "-50"),
|
|
79
86
|
getColorClass(color + "-700"),
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
type AriaProps,
|
|
40
40
|
type ChildrenProp,
|
|
41
41
|
type CssProp,
|
|
42
|
+
type RefProp,
|
|
42
43
|
type TestProps,
|
|
43
44
|
} from "../../types";
|
|
44
45
|
import { nodeCheck } from "../../utils";
|
|
@@ -48,6 +49,7 @@ export interface CardProps
|
|
|
48
49
|
extends CssProp,
|
|
49
50
|
AriaProps,
|
|
50
51
|
TestProps,
|
|
52
|
+
RefProp<HTMLDivElement>,
|
|
51
53
|
ChildrenProp<React.ReactElement<HeadFootProps | ContentProps>> {
|
|
52
54
|
/**
|
|
53
55
|
* apply flex fill styling
|
|
@@ -94,6 +96,7 @@ export const Card = ({
|
|
|
94
96
|
draggable,
|
|
95
97
|
dragKey,
|
|
96
98
|
dragData,
|
|
99
|
+
ref,
|
|
97
100
|
...aria
|
|
98
101
|
}: CardProps) => {
|
|
99
102
|
const [header, body, footer] = useMemo(() => {
|
|
@@ -136,6 +139,7 @@ export const Card = ({
|
|
|
136
139
|
dragKey &&
|
|
137
140
|
e.dataTransfer?.setData(dragKey, JSON.stringify(dragData))
|
|
138
141
|
}
|
|
142
|
+
ref={ref}
|
|
139
143
|
{...aria}
|
|
140
144
|
>
|
|
141
145
|
{header}
|
|
@@ -156,7 +156,7 @@ export const Chip = <Tag extends React.ElementType = "div">({
|
|
|
156
156
|
classes.chip,
|
|
157
157
|
className,
|
|
158
158
|
color && getColorClass(color),
|
|
159
|
-
"select-none inline-flex flex-nowrap items-center max-w-72 text-sm
|
|
159
|
+
"select-none inline-flex flex-nowrap items-center max-w-72 text-sm rounded",
|
|
160
160
|
rounded && "rounded-full",
|
|
161
161
|
!!onClick && classes.clickable,
|
|
162
162
|
disabled && classes.disabled,
|
|
@@ -178,9 +178,7 @@ export const Chip = <Tag extends React.ElementType = "div">({
|
|
|
178
178
|
/>
|
|
179
179
|
)}
|
|
180
180
|
{children && (
|
|
181
|
-
<label
|
|
182
|
-
className={classNames(classes.chipLabel, "leading-none truncate")}
|
|
183
|
-
>
|
|
181
|
+
<label className={classNames(classes.chipLabel, "truncate")}>
|
|
184
182
|
{children}
|
|
185
183
|
</label>
|
|
186
184
|
)}
|
|
@@ -66,6 +66,10 @@ export interface CollapsableProps
|
|
|
66
66
|
* header button className
|
|
67
67
|
*/
|
|
68
68
|
headerClassName?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Header position sticky
|
|
71
|
+
*/
|
|
72
|
+
stickyHeader?: boolean;
|
|
69
73
|
/**
|
|
70
74
|
* open state icon
|
|
71
75
|
*/
|
|
@@ -78,6 +82,10 @@ export interface CollapsableProps
|
|
|
78
82
|
* open state
|
|
79
83
|
*/
|
|
80
84
|
open?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* disable collapsable
|
|
87
|
+
*/
|
|
88
|
+
disabled?: boolean;
|
|
81
89
|
/**
|
|
82
90
|
* open handler
|
|
83
91
|
*/
|
|
@@ -90,11 +98,13 @@ export interface CollapsableProps
|
|
|
90
98
|
|
|
91
99
|
export const Collapsable = ({
|
|
92
100
|
ref,
|
|
101
|
+
disabled,
|
|
93
102
|
className,
|
|
94
103
|
bodyClassName,
|
|
95
104
|
headerClassName,
|
|
96
105
|
children,
|
|
97
106
|
iconAlign,
|
|
107
|
+
stickyHeader,
|
|
98
108
|
iconClosed = CoreIcons.chevronRight,
|
|
99
109
|
iconOpen = CoreIcons.chevronDown,
|
|
100
110
|
open,
|
|
@@ -133,9 +143,10 @@ export const Collapsable = ({
|
|
|
133
143
|
classes.collapsableHead,
|
|
134
144
|
"flex gap-1 flex-nowrap py-2 font-medium cursor-pointer items-center select-none hover:opacity-70",
|
|
135
145
|
headerClassName,
|
|
146
|
+
stickyHeader && "bg-base sticky top-0 px-2 py-1 z-10",
|
|
136
147
|
iconAlign === "end" ? "flex-row-reverse" : "flex-row",
|
|
137
148
|
)}
|
|
138
|
-
onClick={() => setOpenState(!openState)}
|
|
149
|
+
onClick={() => !disabled && setOpenState(!openState)}
|
|
139
150
|
>
|
|
140
151
|
<Icon size="1.125em" icon={openState ? iconOpen : iconClosed} rtlFlip />
|
|
141
152
|
<div className="flex-1 px-2">{head}</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* React Fabric
|
|
3
|
+
* @version: 1.0.0
|
|
4
|
+
*
|
|
5
|
+
*
|
|
6
|
+
* The MIT License (MIT)
|
|
7
|
+
* Copyright (c) 2024 Adarsh Pastakia
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
|
10
|
+
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
11
|
+
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
12
|
+
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
13
|
+
* subject to the following conditions:
|
|
14
|
+
*
|
|
15
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
16
|
+
* portions of the Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
19
|
+
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
20
|
+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
@layer comp {
|
|
25
|
+
.vertical {
|
|
26
|
+
margin-inline: 0.25rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.horizontal {
|
|
30
|
+
margin-block: 0.25rem;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
type PaletteType,
|
|
31
31
|
} from "../../types";
|
|
32
32
|
import { getBgClass, getBorderClass, getColorClass } from "../../utils";
|
|
33
|
+
import classes from "./Divider.module.css";
|
|
33
34
|
|
|
34
35
|
export interface DividerProps extends CssProp, Partial<ChildProp> {
|
|
35
36
|
/**
|
|
@@ -67,7 +68,7 @@ export const Divider = ({
|
|
|
67
68
|
className,
|
|
68
69
|
vertical && "vertical",
|
|
69
70
|
!flex && "self-stretch",
|
|
70
|
-
vertical ?
|
|
71
|
+
vertical ? classes.vertical : classes.horizontal,
|
|
71
72
|
color && getBorderClass(color + "-200"),
|
|
72
73
|
)}
|
|
73
74
|
/>
|
|
@@ -88,7 +89,7 @@ export const Divider = ({
|
|
|
88
89
|
<div
|
|
89
90
|
className={classNames(
|
|
90
91
|
"px-2 whitespace-nowrap",
|
|
91
|
-
vertical ?
|
|
92
|
+
vertical ? classes.vertical : classes.horizontal,
|
|
92
93
|
fill && getBgClass((color ?? "tint") + "-200"),
|
|
93
94
|
!fill && getColorClass((color ?? "tint") + "-600"),
|
|
94
95
|
"rounded-full text-[0.75em]",
|
|
@@ -224,6 +224,7 @@ const DropdownElement = ({
|
|
|
224
224
|
e.stopPropagation();
|
|
225
225
|
},
|
|
226
226
|
}),
|
|
227
|
+
"data-inner-clickable": "true",
|
|
227
228
|
"data-dropdown-open": isOpen ? true : undefined,
|
|
228
229
|
ref: innerRef,
|
|
229
230
|
})}
|
|
@@ -248,6 +249,7 @@ const DropdownElement = ({
|
|
|
248
249
|
zIndex: "var(--z-popover)",
|
|
249
250
|
...floatingStyles,
|
|
250
251
|
}}
|
|
252
|
+
data-testid="dropdown-body"
|
|
251
253
|
{...getFloatingProps({
|
|
252
254
|
onClick: (e) => e.stopPropagation(),
|
|
253
255
|
})}
|
|
@@ -257,8 +259,7 @@ const DropdownElement = ({
|
|
|
257
259
|
className={classNames(
|
|
258
260
|
classes.dropdownBody,
|
|
259
261
|
dropdownClassName,
|
|
260
|
-
!plainDropdown &&
|
|
261
|
-
"shadow-lg shadow-base bg-base ring-1 ring-tint-100",
|
|
262
|
+
!plainDropdown && "shadow-lg bg-base ring-1 ring-tint-100",
|
|
262
263
|
"rounded-capped overflow-auto scroll-thin grid max-h-[70vh]",
|
|
263
264
|
)}
|
|
264
265
|
onMouseUpCapture={tryClosing}
|
|
@@ -31,10 +31,12 @@ export const DropdownTool = ({
|
|
|
31
31
|
children,
|
|
32
32
|
className,
|
|
33
33
|
groupHover,
|
|
34
|
+
icon,
|
|
34
35
|
...props
|
|
35
36
|
}: ChildProp &
|
|
36
37
|
CssProp &
|
|
37
38
|
Omit<DropdownProps, "children"> & {
|
|
39
|
+
icon?: string;
|
|
38
40
|
/**
|
|
39
41
|
* hide until group hovered
|
|
40
42
|
*/
|
|
@@ -43,7 +45,7 @@ export const DropdownTool = ({
|
|
|
43
45
|
return (
|
|
44
46
|
<Dropdown {...props}>
|
|
45
47
|
<Icon
|
|
46
|
-
icon={CoreIcons.caretDown}
|
|
48
|
+
icon={icon ?? CoreIcons.caretDown}
|
|
47
49
|
className={classNames(
|
|
48
50
|
className,
|
|
49
51
|
"outline bg-base flex-content pointer-events-auto cursor-pointer",
|