@react-fabric/core 1.0.0-beta.61 → 1.0.0-beta.62
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/components/_breadcrumbs.css +2 -0
- package/css/components/_button.css +8 -2
- package/css/components/_modal.css +2 -2
- package/css/core/_theme.css +1 -1
- package/css/reset/_reset.css +6 -2
- package/dist/cjs/components/button/Button.js +1 -1
- package/dist/cjs/components/dropdown/Dropdown.js +13 -1
- package/dist/cjs/components/icon/Icon.js +24 -24
- package/dist/cjs/components/menu/Menu.js +4 -3
- package/dist/cjs/components/menu/MenuItem.js +1 -1
- package/dist/cjs/components/navigator/Navigator.js +2 -2
- package/dist/cjs/components/tabpanel/TabPanel.js +3 -2
- package/dist/cjs/core/theme/ThemeProvider.js +3 -2
- package/dist/cjs/hooks/useNavigator.js +9 -8
- package/dist/cjs/hooks/useOverlayService.js +34 -13
- package/dist/cjs/i18n/index.js +4 -4
- package/dist/cjs/index.js +1 -0
- package/dist/esm/components/button/Button.js +1 -1
- package/dist/esm/components/dropdown/Dropdown.js +14 -2
- package/dist/esm/components/icon/Icon.js +24 -24
- package/dist/esm/components/menu/Menu.js +4 -3
- package/dist/esm/components/menu/MenuItem.js +1 -1
- package/dist/esm/components/navigator/Navigator.js +2 -2
- package/dist/esm/components/tabpanel/TabPanel.js +3 -2
- package/dist/esm/core/theme/ThemeProvider.js +3 -2
- package/dist/esm/hooks/useNavigator.js +10 -9
- package/dist/esm/hooks/useOverlayService.js +35 -14
- package/dist/esm/i18n/index.js +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/types/components/index.d.ts +2 -2
- package/dist/types/components/menu/types.d.ts +6 -1
- package/dist/types/components/navigator/Navigator.d.ts +6 -0
- package/dist/types/core/theme/ThemeProvider.d.ts +2 -2
- package/dist/types/hooks/useOverlayService.d.ts +3 -5
- package/package.json +3 -3
- package/src/components/button/Button.tsx +3 -1
- package/src/components/dropdown/Dropdown.tsx +23 -6
- package/src/components/icon/Icon.tsx +22 -22
- package/src/components/index.ts +4 -3
- package/src/components/menu/Menu.tsx +3 -2
- package/src/components/menu/MenuItem.tsx +1 -1
- package/src/components/menu/types.ts +6 -1
- package/src/components/navigator/Navigator.tsx +9 -2
- package/src/components/tabpanel/TabPanel.tsx +2 -1
- package/src/core/theme/ThemeProvider.tsx +4 -2
- package/src/hooks/useNavigator.tsx +10 -11
- package/src/hooks/useOverlayService.tsx +29 -16
- package/src/i18n/index.ts +2 -2
- /package/dist/cjs/i18n/{ar.json.js → ar/core.json.js} +0 -0
- /package/dist/cjs/i18n/{en.json.js → en/core.json.js} +0 -0
- /package/dist/esm/i18n/{ar.json.js → ar/core.json.js} +0 -0
- /package/dist/esm/i18n/{en.json.js → en/core.json.js} +0 -0
- /package/src/i18n/{ar.json → ar/core.json} +0 -0
- /package/src/i18n/{en.json → en/core.json} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
4
|
+
import { getValue } from '@react-fabric/utilities';
|
|
4
5
|
import classNames from 'classnames';
|
|
5
6
|
import { useState, useMemo, Children, useEffect, useCallback, cloneElement } from 'react';
|
|
6
7
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
-
import '@react-fabric/utilities';
|
|
8
8
|
import { nodeCheck } from '../../utils/nodeCheck.js';
|
|
9
9
|
import { Tab } from './Tab.js';
|
|
10
10
|
|
|
@@ -73,7 +73,8 @@ var TabPanel = function TabPanel(_ref) {
|
|
|
73
73
|
tabs = _useMemo2[0],
|
|
74
74
|
rest = _useMemo2[1];
|
|
75
75
|
useEffect(function () {
|
|
76
|
-
|
|
76
|
+
var _tabs$;
|
|
77
|
+
setActive(getValue(activeTab !== null && activeTab !== void 0 ? activeTab : (_tabs$ = tabs[0]) === null || _tabs$ === void 0 ? void 0 : _tabs$.props.id));
|
|
77
78
|
}, [activeTab]);
|
|
78
79
|
var activeTabPanel = useMemo(function () {
|
|
79
80
|
var _tabs$find;
|
|
@@ -59,7 +59,8 @@ var ThemeProvider = function ThemeProvider(_ref) {
|
|
|
59
59
|
accentColor = _ref.accentColor,
|
|
60
60
|
tintColor = _ref.tintColor,
|
|
61
61
|
colorScheme = _ref.colorScheme,
|
|
62
|
-
rounding = _ref.rounding
|
|
62
|
+
rounding = _ref.rounding,
|
|
63
|
+
className = _ref.className;
|
|
63
64
|
var _useApplicationContex = useApplicationContext(),
|
|
64
65
|
currentColorScheme = _useApplicationContex.currentColorScheme;
|
|
65
66
|
var styles = useMemo(function () {
|
|
@@ -88,7 +89,7 @@ var ThemeProvider = function ThemeProvider(_ref) {
|
|
|
88
89
|
style: styles,
|
|
89
90
|
"data-color-scheme": colorScheme !== null && colorScheme !== void 0 ? colorScheme : currentColorScheme,
|
|
90
91
|
"data-rounding": rounding,
|
|
91
|
-
className: classNames("fabric-themeProvider", "contents theme-base", branding),
|
|
92
|
+
className: classNames("fabric-themeProvider", "contents theme-base", branding, className),
|
|
92
93
|
children: children
|
|
93
94
|
});
|
|
94
95
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
4
|
-
import { useState,
|
|
4
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
5
5
|
import { jsxs } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
var useNavigator = function useNavigator() {
|
|
@@ -11,15 +11,16 @@ var useNavigator = function useNavigator() {
|
|
|
11
11
|
_useState2 = _slicedToArray(_useState, 2),
|
|
12
12
|
currentIndex = _useState2[0],
|
|
13
13
|
setCurrentIndex = _useState2[1];
|
|
14
|
-
var refCurrent = useRef(defaultIndex);
|
|
15
14
|
var onNavigate = useCallback(function (dir) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
setCurrentIndex(function (prevValue) {
|
|
16
|
+
if (dir === -1) {
|
|
17
|
+
return prevValue > 0 ? prevValue - 1 : totalCount - 1;
|
|
18
|
+
}
|
|
19
|
+
if (dir === 1) {
|
|
20
|
+
return prevValue + 1 < totalCount ? prevValue + 1 : 0;
|
|
21
|
+
}
|
|
22
|
+
return prevValue;
|
|
23
|
+
});
|
|
23
24
|
}, [totalCount]);
|
|
24
25
|
var headLabel = useMemo(function () {
|
|
25
26
|
return /*#__PURE__*/jsxs("span", {
|
|
@@ -5,12 +5,19 @@ import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProper
|
|
|
5
5
|
import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
|
|
6
6
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
7
7
|
import _regeneratorRuntime from '@babel/runtime/regenerator';
|
|
8
|
-
import { useState } from 'react';
|
|
8
|
+
import { useState, useRef } from 'react';
|
|
9
9
|
import { jsx } from 'react/jsx-runtime';
|
|
10
10
|
|
|
11
11
|
var _excluded = ["onClose"];
|
|
12
12
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
13
13
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
14
|
+
// return the blank function since state functionality will execute if the value is function
|
|
15
|
+
var EMPTY_FC = function EMPTY_FC() {
|
|
16
|
+
return function () {
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
14
21
|
/**
|
|
15
22
|
* Hook to manage overlay components like modals or flyouts.
|
|
16
23
|
* It provides a way to open an overlay with specified properties and handle its closure.
|
|
@@ -21,7 +28,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
21
28
|
* of the overlay when it is closed, allowing you to handle the result in a controlled manner.
|
|
22
29
|
*
|
|
23
30
|
* @param ModalOrFlyout - The component to be used as an overlay.
|
|
24
|
-
* @
|
|
31
|
+
* @param toggleOpen - If true, calling `openOverlay` while an overlay is already open will close the existing one instead of opening a new one.
|
|
32
|
+
* @returns An array containing the current overlay, a function to open it, and a boolean indicating if the overlay is open.
|
|
25
33
|
*
|
|
26
34
|
* @example
|
|
27
35
|
* ```jsx
|
|
@@ -36,34 +44,47 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
36
44
|
* ```
|
|
37
45
|
*/
|
|
38
46
|
var useOverlayService = function useOverlayService(ModalOrFlyout) {
|
|
39
|
-
var _useState = useState(
|
|
47
|
+
var _useState = useState(EMPTY_FC),
|
|
40
48
|
_useState2 = _slicedToArray(_useState, 2),
|
|
41
49
|
Overlay = _useState2[0],
|
|
42
50
|
setOverlay = _useState2[1];
|
|
51
|
+
var existingOpenPromise = useRef(null);
|
|
43
52
|
var openOverlay = /*#__PURE__*/function () {
|
|
44
53
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
45
54
|
var _ref2,
|
|
46
55
|
onClose,
|
|
47
|
-
|
|
56
|
+
outerProps,
|
|
48
57
|
_args = arguments;
|
|
49
58
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
50
59
|
while (1) switch (_context.prev = _context.next) {
|
|
51
60
|
case 0:
|
|
52
|
-
_ref2 = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, onClose = _ref2.onClose,
|
|
53
|
-
|
|
61
|
+
_ref2 = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, onClose = _ref2.onClose, outerProps = _objectWithoutProperties(_ref2, _excluded);
|
|
62
|
+
if (!existingOpenPromise.current) {
|
|
63
|
+
_context.next = 3;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
return _context.abrupt("return");
|
|
67
|
+
case 3:
|
|
68
|
+
_context.next = 5;
|
|
54
69
|
return new Promise(function (resolve) {
|
|
55
|
-
|
|
56
|
-
setOverlay(
|
|
70
|
+
existingOpenPromise.current = function (args) {
|
|
71
|
+
setOverlay(EMPTY_FC);
|
|
57
72
|
resolve(args);
|
|
58
73
|
onClose === null || onClose === void 0 || onClose(args);
|
|
74
|
+
existingOpenPromise.current = null;
|
|
59
75
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
76
|
+
// eslint-disable-next-line react/display-name
|
|
77
|
+
setOverlay(function () {
|
|
78
|
+
return function (overrideProps) {
|
|
79
|
+
return /*#__PURE__*/jsx(ModalOrFlyout, _objectSpread(_objectSpread(_objectSpread({}, outerProps), overrideProps), {}, {
|
|
80
|
+
onClose: existingOpenPromise.current
|
|
81
|
+
}));
|
|
82
|
+
};
|
|
83
|
+
});
|
|
63
84
|
});
|
|
64
|
-
case
|
|
85
|
+
case 5:
|
|
65
86
|
return _context.abrupt("return", _context.sent);
|
|
66
|
-
case
|
|
87
|
+
case 6:
|
|
67
88
|
case "end":
|
|
68
89
|
return _context.stop();
|
|
69
90
|
}
|
|
@@ -73,7 +94,7 @@ var useOverlayService = function useOverlayService(ModalOrFlyout) {
|
|
|
73
94
|
return _ref.apply(this, arguments);
|
|
74
95
|
};
|
|
75
96
|
}();
|
|
76
|
-
return [Overlay, openOverlay];
|
|
97
|
+
return [Overlay, openOverlay, existingOpenPromise.current];
|
|
77
98
|
};
|
|
78
99
|
|
|
79
100
|
export { useOverlayService };
|
package/dist/esm/i18n/index.js
CHANGED
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
export { ActionLabel } from './components/actionLabel/ActionLabel.js';
|
|
4
|
-
export { AnimationIndicator, LoadingBars, LoadingLine, LoadingSpinner, Skeleton } from './components/animations/Animations.js';
|
|
4
|
+
export { AnimationIndicator, AnimationLoader, LoadingBars, LoadingLine, LoadingSpinner, Skeleton } from './components/animations/Animations.js';
|
|
5
5
|
export { Avatar } from './components/avatar/Avatar.js';
|
|
6
6
|
export { AvatarGroup } from './components/avatar/AvatarGroup.js';
|
|
7
7
|
export { Badge, getBadgeProps } from './components/badge/Badge.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ActionLabel } from "./actionLabel/ActionLabel";
|
|
2
|
-
export {
|
|
2
|
+
export { AnimationIndicator, AnimationLoader, LoadingBars, LoadingLine, LoadingSpinner, Skeleton, } from "./animations/Animations";
|
|
3
3
|
export { Avatar } from "./avatar/Avatar";
|
|
4
4
|
export { AvatarGroup } from "./avatar/AvatarGroup";
|
|
5
5
|
export { Badge, getBadgeProps } from "./badge/Badge";
|
|
@@ -18,7 +18,7 @@ export { Divider } from "./divider/Divider";
|
|
|
18
18
|
export { Dropdown, DropdownDismiss } from "./dropdown/Dropdown";
|
|
19
19
|
export { DropdownTool } from "./dropdown/DropdownTool";
|
|
20
20
|
export { EmptyContent } from "./empty/EmptyContent";
|
|
21
|
-
export {
|
|
21
|
+
export { getIconProps, Icon } from "./icon/Icon";
|
|
22
22
|
export { Image, Video } from "./media/Media";
|
|
23
23
|
export { ContextMenu } from "./menu/ContextMenu";
|
|
24
24
|
export { Menu } from "./menu/Menu";
|
|
@@ -13,7 +13,7 @@ export interface MenuItemProps extends CssProp, AriaProps, TestProps {
|
|
|
13
13
|
/**
|
|
14
14
|
* append label badge text
|
|
15
15
|
*/
|
|
16
|
-
appendLabel?: string | false;
|
|
16
|
+
appendLabel?: JSX.Element | string | number | false;
|
|
17
17
|
/**
|
|
18
18
|
* menu color
|
|
19
19
|
*/
|
|
@@ -50,6 +50,10 @@ export interface MenuItemProps extends CssProp, AriaProps, TestProps {
|
|
|
50
50
|
export interface MenuRootProps extends CssProp {
|
|
51
51
|
label?: never;
|
|
52
52
|
minimal?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* use this create a dropdown button within menu-item
|
|
55
|
+
*/
|
|
56
|
+
forDropdown?: boolean;
|
|
53
57
|
menuClassName?: never;
|
|
54
58
|
onClick?: (id: string) => CallbackReturn;
|
|
55
59
|
}
|
|
@@ -57,6 +61,7 @@ export interface MenuInnerProps extends MenuItemProps {
|
|
|
57
61
|
label: string;
|
|
58
62
|
minimal?: never;
|
|
59
63
|
trigger?: "hover" | "click";
|
|
64
|
+
forDropdown?: boolean;
|
|
60
65
|
/**
|
|
61
66
|
* floating menu className
|
|
62
67
|
*/
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { type AriaProps, type ChildProp, type ColorType, type CssProp, type PaletteType, type TestProps } from "../../types";
|
|
2
2
|
export interface NavigatorProps extends CssProp, AriaProps, TestProps, Partial<ChildProp> {
|
|
3
|
+
/**
|
|
4
|
+
* item list length (ignore to enable infinite navigation)
|
|
5
|
+
*/
|
|
3
6
|
length?: number;
|
|
7
|
+
/**
|
|
8
|
+
* current item index (ignore to enable infinite navigation)
|
|
9
|
+
*/
|
|
4
10
|
current?: number;
|
|
5
11
|
disableKeyHandlers?: boolean;
|
|
6
12
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ChildrenProp } from "../../types";
|
|
1
|
+
import { type ChildrenProp, type CssProp } from "../../types";
|
|
2
2
|
export interface ThemeProps {
|
|
3
3
|
/**
|
|
4
4
|
* light/dark color scheme
|
|
@@ -54,4 +54,4 @@ export interface ThemeProps {
|
|
|
54
54
|
*
|
|
55
55
|
* @see {@link https://adarshpastakia.github.io/react-fabric/?path=/story/core-application--theme-provider} for more details.
|
|
56
56
|
*/
|
|
57
|
-
export declare const ThemeProvider: ({ children, branding, primaryColor, accentColor, tintColor, colorScheme, rounding, }: ThemeProps & ChildrenProp) => import("react/jsx-runtime").JSX.Element;
|
|
57
|
+
export declare const ThemeProvider: ({ children, branding, primaryColor, accentColor, tintColor, colorScheme, rounding, className, }: ThemeProps & ChildrenProp & CssProp) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { type ElementType } from "react";
|
|
2
1
|
import { type ModalProps } from "../types";
|
|
3
|
-
type OverlayComponent = ElementType<ModalProps<AnyObject>>;
|
|
4
2
|
/**
|
|
5
3
|
* Hook to manage overlay components like modals or flyouts.
|
|
6
4
|
* It provides a way to open an overlay with specified properties and handle its closure.
|
|
@@ -11,7 +9,8 @@ type OverlayComponent = ElementType<ModalProps<AnyObject>>;
|
|
|
11
9
|
* of the overlay when it is closed, allowing you to handle the result in a controlled manner.
|
|
12
10
|
*
|
|
13
11
|
* @param ModalOrFlyout - The component to be used as an overlay.
|
|
14
|
-
* @
|
|
12
|
+
* @param toggleOpen - If true, calling `openOverlay` while an overlay is already open will close the existing one instead of opening a new one.
|
|
13
|
+
* @returns An array containing the current overlay, a function to open it, and a boolean indicating if the overlay is open.
|
|
15
14
|
*
|
|
16
15
|
* @example
|
|
17
16
|
* ```jsx
|
|
@@ -25,5 +24,4 @@ type OverlayComponent = ElementType<ModalProps<AnyObject>>;
|
|
|
25
24
|
* <Overlay />
|
|
26
25
|
* ```
|
|
27
26
|
*/
|
|
28
|
-
export declare const useOverlayService: (ModalOrFlyout:
|
|
29
|
-
export {};
|
|
27
|
+
export declare const useOverlayService: <T extends AnyObject = AnyObject>(ModalOrFlyout: React.FunctionComponent<ModalProps<T>>) => [Overlay: React.FunctionComponent<Partial<T>>, openOverlay: (props?: Partial<T>) => Promise<AnyObject>, closeOverlay: ((args?: AnyObject) => void) | null];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-fabric/core",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.62",
|
|
4
4
|
"description": "RUF: Core package",
|
|
5
5
|
"author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@iconify-json/mdi": "~1.2.3",
|
|
40
40
|
"@iconify-json/svg-spinners": "~1.2.4",
|
|
41
41
|
"@iconify/tailwind4": "~1.2.1",
|
|
42
|
-
"@react-fabric/utilities": "^1.0.0-beta.
|
|
42
|
+
"@react-fabric/utilities": "^1.0.0-beta.62",
|
|
43
43
|
"@tailwindcss/postcss": "~4.1.16",
|
|
44
44
|
"boring-avatars": "~1.11.2",
|
|
45
45
|
"classnames": "~2.5.1",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"node": ">=18.12.0",
|
|
58
58
|
"npm": ">=8.19.0"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "9dce2fd9bb753d67e3f8adbf50be257b4bc64242"
|
|
61
61
|
}
|
|
@@ -292,7 +292,9 @@ export const Button = <Tag extends React.ElementType = "button">({
|
|
|
292
292
|
data-loading={busy || loading}
|
|
293
293
|
data-disabled={disabled}
|
|
294
294
|
>
|
|
295
|
-
{
|
|
295
|
+
{!disabled && hotKey && (
|
|
296
|
+
<HotKey keyCombo={hotKey} handler={hotKeyHandler.current} />
|
|
297
|
+
)}
|
|
296
298
|
<TooltipWrapper {...tooltipProps}>
|
|
297
299
|
<E
|
|
298
300
|
ref={mergeRefs(ref, refEl)}
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
useClick,
|
|
37
37
|
useDismiss,
|
|
38
38
|
useFloating,
|
|
39
|
+
useFloatingNodeId,
|
|
39
40
|
useFloatingTree,
|
|
40
41
|
useHover,
|
|
41
42
|
useInteractions,
|
|
@@ -116,6 +117,7 @@ const DropdownElement = ({
|
|
|
116
117
|
const arrowRef = useRef(null);
|
|
117
118
|
const [isOpen, setIsOpen] = useState(false);
|
|
118
119
|
const tree = useFloatingTree();
|
|
120
|
+
const nodeId = useFloatingNodeId();
|
|
119
121
|
|
|
120
122
|
const [anchor, panel] = useMemo<AnyObject[]>(
|
|
121
123
|
() => Children.toArray(children as AnyObject),
|
|
@@ -123,6 +125,7 @@ const DropdownElement = ({
|
|
|
123
125
|
);
|
|
124
126
|
|
|
125
127
|
const { refs, floatingStyles, context } = useFloating({
|
|
128
|
+
nodeId: `dropdown-${nodeId}`,
|
|
126
129
|
open: isOpen,
|
|
127
130
|
onOpenChange: (open, _, reason) => {
|
|
128
131
|
if (reason === "reference-press") return;
|
|
@@ -148,6 +151,7 @@ const DropdownElement = ({
|
|
|
148
151
|
enabled: !disabled,
|
|
149
152
|
handleClose: safePolygon({ blockPointerEvents: true }),
|
|
150
153
|
});
|
|
154
|
+
|
|
151
155
|
const dismiss = useDismiss(context, {
|
|
152
156
|
referencePress: true,
|
|
153
157
|
});
|
|
@@ -168,6 +172,11 @@ const DropdownElement = ({
|
|
|
168
172
|
return undefined;
|
|
169
173
|
}, [refs, isOpen, fitToParent]);
|
|
170
174
|
|
|
175
|
+
const dismissDropdown = useCallback(() => {
|
|
176
|
+
setIsOpen(false);
|
|
177
|
+
onClose?.();
|
|
178
|
+
}, []);
|
|
179
|
+
|
|
171
180
|
const tryClosing = useCallback(
|
|
172
181
|
(e: React.MouseEvent) => {
|
|
173
182
|
if (
|
|
@@ -259,7 +268,9 @@ const DropdownElement = ({
|
|
|
259
268
|
)}
|
|
260
269
|
onMouseUpCapture={tryClosing}
|
|
261
270
|
>
|
|
262
|
-
{panel
|
|
271
|
+
{cloneElement(panel, {
|
|
272
|
+
dismiss: dismissDropdown,
|
|
273
|
+
})}
|
|
263
274
|
</div>
|
|
264
275
|
{showArrow && (
|
|
265
276
|
<FloatingArrow
|
|
@@ -308,11 +319,17 @@ const DropdownElement = ({
|
|
|
308
319
|
* @see {@link https://adarshpastakia.github.io/react-fabric/?path=/docs/core-components-dropdown--docs} for more details.
|
|
309
320
|
* @see {@link https://floating-ui.com/docs/react} for more details on Floating UI.
|
|
310
321
|
*/
|
|
311
|
-
export const Dropdown = (props: DropdownProps) =>
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
322
|
+
export const Dropdown = (props: DropdownProps) => {
|
|
323
|
+
const tree = useFloatingTree();
|
|
324
|
+
if (tree) {
|
|
325
|
+
return <DropdownElement {...props} />;
|
|
326
|
+
}
|
|
327
|
+
return (
|
|
328
|
+
<FloatingTree>
|
|
329
|
+
<DropdownElement {...props} />
|
|
330
|
+
</FloatingTree>
|
|
331
|
+
);
|
|
332
|
+
};
|
|
316
333
|
|
|
317
334
|
/**
|
|
318
335
|
* A component that allows dismissing the dropdown when clicked.
|
|
@@ -191,29 +191,29 @@ export const Icon = ({
|
|
|
191
191
|
/** ***************** render icon *******************/
|
|
192
192
|
const iconEl = useMemo(() => {
|
|
193
193
|
if (isValidElement(icon)) return icon;
|
|
194
|
-
if (
|
|
195
|
-
|
|
194
|
+
if (isString(icon)) {
|
|
195
|
+
return isSvg ? (
|
|
196
|
+
<svg viewBox={viewBox}>
|
|
197
|
+
<path fill="currentColor" d={icon.toString()} />
|
|
198
|
+
</svg>
|
|
199
|
+
) : icon?.toString().length <= 4 ? (
|
|
200
|
+
<svg role="img">
|
|
201
|
+
<text
|
|
202
|
+
x="50%"
|
|
203
|
+
y="50%"
|
|
204
|
+
dy=".1em"
|
|
205
|
+
dominantBaseline="middle"
|
|
206
|
+
textAnchor="middle"
|
|
207
|
+
style={{ fontSize: SvgTextSize[icon.length] }}
|
|
208
|
+
>
|
|
209
|
+
{icon}
|
|
210
|
+
</text>
|
|
211
|
+
</svg>
|
|
212
|
+
) : (
|
|
213
|
+
<i className={`${icon}`} />
|
|
214
|
+
);
|
|
196
215
|
}
|
|
197
|
-
|
|
198
|
-
<svg viewBox={viewBox}>
|
|
199
|
-
<path fill="currentColor" d={icon.toString()} />
|
|
200
|
-
</svg>
|
|
201
|
-
) : icon?.toString().length <= 4 ? (
|
|
202
|
-
<svg role="img">
|
|
203
|
-
<text
|
|
204
|
-
x="50%"
|
|
205
|
-
y="50%"
|
|
206
|
-
dy=".1em"
|
|
207
|
-
dominantBaseline="middle"
|
|
208
|
-
textAnchor="middle"
|
|
209
|
-
style={{ fontSize: SvgTextSize[icon.length] }}
|
|
210
|
-
>
|
|
211
|
-
{icon}
|
|
212
|
-
</text>
|
|
213
|
-
</svg>
|
|
214
|
-
) : (
|
|
215
|
-
<i className={`${icon}`} />
|
|
216
|
-
);
|
|
216
|
+
throw Error("Invalid icon expected string");
|
|
217
217
|
}, [icon, isSvg, viewBox]);
|
|
218
218
|
|
|
219
219
|
return (
|
package/src/components/index.ts
CHANGED
|
@@ -23,10 +23,11 @@
|
|
|
23
23
|
|
|
24
24
|
export { ActionLabel } from "./actionLabel/ActionLabel";
|
|
25
25
|
export {
|
|
26
|
-
LoadingBars,
|
|
27
26
|
AnimationIndicator,
|
|
28
|
-
|
|
27
|
+
AnimationLoader,
|
|
28
|
+
LoadingBars,
|
|
29
29
|
LoadingLine,
|
|
30
|
+
LoadingSpinner,
|
|
30
31
|
Skeleton,
|
|
31
32
|
} from "./animations/Animations";
|
|
32
33
|
export { Avatar } from "./avatar/Avatar";
|
|
@@ -47,7 +48,7 @@ export { Divider } from "./divider/Divider";
|
|
|
47
48
|
export { Dropdown, DropdownDismiss } from "./dropdown/Dropdown";
|
|
48
49
|
export { DropdownTool } from "./dropdown/DropdownTool";
|
|
49
50
|
export { EmptyContent } from "./empty/EmptyContent";
|
|
50
|
-
export {
|
|
51
|
+
export { getIconProps, Icon } from "./icon/Icon";
|
|
51
52
|
export { Image, Video } from "./media/Media";
|
|
52
53
|
export { ContextMenu } from "./menu/ContextMenu";
|
|
53
54
|
export { Menu } from "./menu/Menu";
|
|
@@ -71,6 +71,7 @@ const MenuComponent = ({
|
|
|
71
71
|
trigger = "hover",
|
|
72
72
|
// @ts-expect-error ignore
|
|
73
73
|
ref,
|
|
74
|
+
forDropdown,
|
|
74
75
|
...rest
|
|
75
76
|
}: Partial<MenuProps>) => {
|
|
76
77
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -83,10 +84,10 @@ const MenuComponent = ({
|
|
|
83
84
|
const nodeId = useFloatingNodeId();
|
|
84
85
|
const parentId = useFloatingParentNodeId();
|
|
85
86
|
|
|
86
|
-
const isNested = parentId !== null;
|
|
87
|
+
const isNested = parentId !== null && !forDropdown;
|
|
87
88
|
|
|
88
89
|
const { floatingStyles, refs, context } = useFloating<HTMLButtonElement>({
|
|
89
|
-
nodeId
|
|
90
|
+
nodeId: `menu-${nodeId}`,
|
|
90
91
|
open: !isNested || isOpen,
|
|
91
92
|
onOpenChange(open, event, reason) {
|
|
92
93
|
isNested && setIsOpen(open);
|
|
@@ -177,7 +177,7 @@ export const MenuItem = <Tag extends React.ElementType = "button">({
|
|
|
177
177
|
}}
|
|
178
178
|
{...(minimal ? {} : aria)}
|
|
179
179
|
>
|
|
180
|
-
{hotKey && (
|
|
180
|
+
{!disabled && hotKey && (
|
|
181
181
|
<HotKey keyCombo={hotKey} handler={() => elRef.current?.click?.()} />
|
|
182
182
|
)}
|
|
183
183
|
{menuLabel}
|
|
@@ -45,7 +45,7 @@ export interface MenuItemProps extends CssProp, AriaProps, TestProps {
|
|
|
45
45
|
/**
|
|
46
46
|
* append label badge text
|
|
47
47
|
*/
|
|
48
|
-
appendLabel?: string | false;
|
|
48
|
+
appendLabel?: JSX.Element | string | number | false;
|
|
49
49
|
/**
|
|
50
50
|
* menu color
|
|
51
51
|
*/
|
|
@@ -83,6 +83,10 @@ export interface MenuItemProps extends CssProp, AriaProps, TestProps {
|
|
|
83
83
|
export interface MenuRootProps extends CssProp {
|
|
84
84
|
label?: never;
|
|
85
85
|
minimal?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* use this create a dropdown button within menu-item
|
|
88
|
+
*/
|
|
89
|
+
forDropdown?: boolean;
|
|
86
90
|
menuClassName?: never;
|
|
87
91
|
onClick?: (id: string) => CallbackReturn;
|
|
88
92
|
}
|
|
@@ -91,6 +95,7 @@ export interface MenuInnerProps extends MenuItemProps {
|
|
|
91
95
|
label: string;
|
|
92
96
|
minimal?: never;
|
|
93
97
|
trigger?: "hover" | "click";
|
|
98
|
+
forDropdown?: boolean;
|
|
94
99
|
/**
|
|
95
100
|
* floating menu className
|
|
96
101
|
*/
|
|
@@ -21,6 +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 { isEmpty } from "@react-fabric/utilities";
|
|
24
25
|
import classNames from "classnames";
|
|
25
26
|
import { useCallback } from "react";
|
|
26
27
|
import { HotKey } from "../../hotkeys/HotKey";
|
|
@@ -33,15 +34,21 @@ import {
|
|
|
33
34
|
type TestProps,
|
|
34
35
|
} from "../../types";
|
|
35
36
|
import { Icon } from "../icon/Icon";
|
|
36
|
-
import { isEmpty } from "@react-fabric/utilities";
|
|
37
37
|
|
|
38
38
|
export interface NavigatorProps
|
|
39
39
|
extends CssProp,
|
|
40
40
|
AriaProps,
|
|
41
41
|
TestProps,
|
|
42
42
|
Partial<ChildProp> {
|
|
43
|
+
/**
|
|
44
|
+
* item list length (ignore to enable infinite navigation)
|
|
45
|
+
*/
|
|
43
46
|
length?: number;
|
|
47
|
+
/**
|
|
48
|
+
* current item index (ignore to enable infinite navigation)
|
|
49
|
+
*/
|
|
44
50
|
current?: number;
|
|
51
|
+
|
|
45
52
|
disableKeyHandlers?: boolean;
|
|
46
53
|
/**
|
|
47
54
|
* navigator button color
|
|
@@ -87,7 +94,7 @@ export const Navigator = ({
|
|
|
87
94
|
}: NavigatorProps) => {
|
|
88
95
|
const navPrev = useCallback(
|
|
89
96
|
() => (isEmpty(current) || current !== 0) && onNavigate(-1),
|
|
90
|
-
[onNavigate, current],
|
|
97
|
+
[onNavigate, current, length],
|
|
91
98
|
);
|
|
92
99
|
const navNext = useCallback(
|
|
93
100
|
() => (isEmpty(current) || current + 1 < (length ?? 0)) && onNavigate(+1),
|
|
@@ -21,6 +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 { getValue } from "@react-fabric/utilities";
|
|
24
25
|
import classNames from "classnames";
|
|
25
26
|
import {
|
|
26
27
|
Children,
|
|
@@ -153,7 +154,7 @@ export const TabPanel = ({
|
|
|
153
154
|
}, [children]);
|
|
154
155
|
|
|
155
156
|
useEffect(() => {
|
|
156
|
-
setActive(activeTab);
|
|
157
|
+
setActive(getValue(activeTab ?? tabs[0]?.props.id));
|
|
157
158
|
}, [activeTab]);
|
|
158
159
|
|
|
159
160
|
const activeTabPanel = useMemo(() => {
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
import { isColor } from "@react-fabric/utilities";
|
|
25
25
|
import classNames from "classnames";
|
|
26
26
|
import { useMemo } from "react";
|
|
27
|
-
import { type ChildrenProp } from "../../types";
|
|
28
27
|
import { useApplicationContext } from "../../context/Global";
|
|
28
|
+
import { type ChildrenProp, type CssProp } from "../../types";
|
|
29
29
|
|
|
30
30
|
export interface ThemeProps {
|
|
31
31
|
/**
|
|
@@ -91,7 +91,8 @@ export const ThemeProvider = ({
|
|
|
91
91
|
tintColor,
|
|
92
92
|
colorScheme,
|
|
93
93
|
rounding,
|
|
94
|
-
|
|
94
|
+
className,
|
|
95
|
+
}: ThemeProps & ChildrenProp & CssProp) => {
|
|
95
96
|
const { currentColorScheme } = useApplicationContext();
|
|
96
97
|
const styles = useMemo(() => {
|
|
97
98
|
const ret: KeyValue = {};
|
|
@@ -125,6 +126,7 @@ export const ThemeProvider = ({
|
|
|
125
126
|
"fabric-themeProvider",
|
|
126
127
|
"contents theme-base",
|
|
127
128
|
branding,
|
|
129
|
+
className,
|
|
128
130
|
)}
|
|
129
131
|
>
|
|
130
132
|
{children}
|