@mezzanine-ui/react 1.0.0-beta.2 → 1.0.0-beta.4
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/Anchor/Anchor.d.ts +51 -18
- package/Anchor/Anchor.js +15 -15
- package/Anchor/AnchorGroup.d.ts +34 -0
- package/Anchor/AnchorGroup.js +37 -0
- package/Anchor/AnchorItem.d.ts +30 -0
- package/Anchor/AnchorItem.js +65 -0
- package/Anchor/index.d.ts +2 -0
- package/Anchor/index.js +1 -0
- package/Anchor/utils.d.ts +13 -0
- package/Anchor/utils.js +95 -0
- package/AutoComplete/AutoComplete.d.ts +217 -0
- package/AutoComplete/AutoComplete.js +433 -0
- package/AutoComplete/index.d.ts +2 -0
- package/AutoComplete/index.js +1 -0
- package/AutoComplete/useAutoCompleteCreation.d.ts +33 -0
- package/AutoComplete/useAutoCompleteCreation.js +201 -0
- package/AutoComplete/useAutoCompleteKeyboard.d.ts +31 -0
- package/AutoComplete/useAutoCompleteKeyboard.js +149 -0
- package/AutoComplete/useAutoCompleteSearch.d.ts +16 -0
- package/AutoComplete/useAutoCompleteSearch.js +69 -0
- package/AutoComplete/useCreationTracker.d.ts +17 -0
- package/AutoComplete/useCreationTracker.js +47 -0
- package/Breadcrumb/Breadcrumb.js +16 -21
- package/Breadcrumb/BreadcrumbDropdown.d.ts +11 -0
- package/Breadcrumb/BreadcrumbDropdown.js +22 -0
- package/Breadcrumb/BreadcrumbItem.d.ts +2 -3
- package/Breadcrumb/BreadcrumbItem.js +13 -31
- package/Breadcrumb/BreadcrumbOverflowMenu.d.ts +7 -0
- package/Breadcrumb/BreadcrumbOverflowMenu.js +77 -0
- package/Breadcrumb/BreadcrumbOverflowMenuDropdown.d.ts +11 -0
- package/Breadcrumb/BreadcrumbOverflowMenuDropdown.js +21 -0
- package/Breadcrumb/BreadcrumbOverflowMenuItem.d.ts +3 -0
- package/Breadcrumb/BreadcrumbOverflowMenuItem.js +27 -0
- package/Breadcrumb/typings.d.ts +21 -39
- package/Button/Button.js +13 -11
- package/Button/index.d.ts +1 -1
- package/Button/typings.d.ts +27 -4
- package/Checkbox/index.d.ts +4 -5
- package/Checkbox/index.js +1 -5
- package/ContentHeader/ContentHeader.d.ts +160 -0
- package/ContentHeader/ContentHeader.js +54 -0
- package/ContentHeader/index.d.ts +2 -0
- package/ContentHeader/index.js +1 -0
- package/ContentHeader/utils.d.ts +23 -0
- package/ContentHeader/utils.js +215 -0
- package/Description/Description.d.ts +12 -22
- package/Description/Description.js +4 -24
- package/Dropdown/Dropdown.d.ts +46 -1
- package/Dropdown/Dropdown.js +99 -14
- package/Dropdown/DropdownAction.d.ts +1 -1
- package/Dropdown/DropdownAction.js +1 -4
- package/Dropdown/DropdownItem.d.ts +28 -1
- package/Dropdown/DropdownItem.js +56 -14
- package/Dropdown/DropdownItemCard.d.ts +2 -2
- package/Dropdown/DropdownItemCard.js +20 -16
- package/Dropdown/DropdownStatus.js +29 -0
- package/Dropdown/dropdownKeydownHandler.d.ts +2 -1
- package/Dropdown/dropdownKeydownHandler.js +73 -0
- package/Dropdown/highlightText.js +5 -1
- package/Dropdown/shortcutTextHandler.d.ts +24 -0
- package/Dropdown/shortcutTextHandler.js +171 -0
- package/Empty/Empty.js +2 -1
- package/Empty/icons/EmptyMainNotificationIcon.d.ts +4 -0
- package/Empty/icons/EmptyMainNotificationIcon.js +9 -0
- package/Empty/typings.d.ts +2 -2
- package/FilterArea/Filter.d.ts +32 -0
- package/FilterArea/Filter.js +23 -0
- package/FilterArea/FilterArea.d.ts +58 -0
- package/FilterArea/FilterArea.js +31 -0
- package/FilterArea/FilterLine.d.ts +11 -0
- package/FilterArea/FilterLine.js +13 -0
- package/FilterArea/index.d.ts +6 -0
- package/FilterArea/index.js +3 -0
- package/Form/FormField.js +3 -1
- package/Input/Input.d.ts +35 -7
- package/Input/Input.js +48 -14
- package/Input/index.d.ts +1 -1
- package/Modal/MediaPreviewModal.d.ts +54 -0
- package/Modal/MediaPreviewModal.js +158 -0
- package/Modal/Modal.d.ts +103 -11
- package/Modal/Modal.js +14 -9
- package/Modal/ModalBodyForVerification.d.ts +59 -0
- package/Modal/ModalBodyForVerification.js +99 -0
- package/Modal/ModalControl.d.ts +2 -2
- package/Modal/ModalControl.js +1 -1
- package/Modal/ModalFooter.d.ts +119 -1
- package/Modal/ModalFooter.js +15 -3
- package/Modal/ModalHeader.d.ts +26 -7
- package/Modal/ModalHeader.js +33 -7
- package/Modal/index.d.ts +6 -5
- package/Modal/index.js +2 -2
- package/Modal/useModalContainer.d.ts +12 -3
- package/Modal/useModalContainer.js +28 -6
- package/Navigation/Navigation.d.ts +7 -2
- package/Navigation/Navigation.js +36 -35
- package/Navigation/NavigationHeader.d.ts +4 -0
- package/Navigation/NavigationHeader.js +3 -2
- package/Navigation/NavigationOption.d.ts +8 -3
- package/Navigation/NavigationOption.js +46 -11
- package/Navigation/NavigationOptionCategory.js +1 -0
- package/Navigation/NavigationOverflowMenu.d.ts +6 -0
- package/Navigation/NavigationOverflowMenu.js +90 -0
- package/Navigation/NavigationOverflowMenuOption.d.ts +7 -0
- package/Navigation/NavigationOverflowMenuOption.js +68 -0
- package/Navigation/NavigationUserMenu.d.ts +4 -2
- package/Navigation/NavigationUserMenu.js +13 -5
- package/Navigation/context.d.ts +3 -2
- package/Navigation/useVisibleItems.d.ts +5 -0
- package/Navigation/useVisibleItems.js +54 -0
- package/NotificationCenter/NotificationCenter.d.ts +124 -0
- package/NotificationCenter/NotificationCenter.js +279 -0
- package/NotificationCenter/NotificationCenterDrawer.d.ts +109 -0
- package/NotificationCenter/index.d.ts +3 -0
- package/NotificationCenter/index.js +1 -0
- package/PageFooter/PageFooter.d.ts +19 -9
- package/PageFooter/PageFooter.js +10 -10
- package/PageHeader/PageHeader.d.ts +32 -25
- package/PageHeader/PageHeader.js +49 -43
- package/ResultState/ResultState.d.ts +9 -0
- package/ResultState/ResultState.js +36 -4
- package/Scrollbar/Scrollbar.d.ts +9 -0
- package/Scrollbar/Scrollbar.js +78 -0
- package/Scrollbar/index.d.ts +2 -0
- package/Scrollbar/index.js +1 -0
- package/Scrollbar/typings.d.ts +47 -0
- package/Select/SelectTrigger.js +5 -4
- package/Select/index.d.ts +0 -2
- package/Select/index.js +0 -1
- package/Select/typings.d.ts +6 -1
- package/Selection/Selection.js +1 -1
- package/Selection/SelectionGroup.d.ts +28 -0
- package/Slider/useSlider.js +1 -1
- package/Table/Table.d.ts +2 -120
- package/Table/Table.js +148 -53
- package/Table/TableContext.d.ts +11 -12
- package/Table/components/TableActionsCell.js +12 -4
- package/Table/components/TableBody.js +2 -1
- package/Table/components/TableBulkActions.js +1 -19
- package/Table/components/TableColGroup.d.ts +1 -4
- package/Table/components/TableColGroup.js +15 -16
- package/Table/components/TableCollectableCell.d.ts +17 -0
- package/Table/components/TableCollectableCell.js +54 -0
- package/Table/components/TableDragOrPinHandleCell.d.ts +20 -0
- package/Table/components/TableDragOrPinHandleCell.js +58 -0
- package/Table/components/TableExpandedRow.js +11 -2
- package/Table/components/TableHeader.js +12 -10
- package/Table/components/TableRow.js +38 -13
- package/Table/components/TableSelectionCell.js +1 -1
- package/Table/components/TableToggleableCell.d.ts +16 -0
- package/Table/components/TableToggleableCell.js +51 -0
- package/Table/components/index.d.ts +4 -1
- package/Table/components/index.js +3 -0
- package/Table/hooks/typings.d.ts +18 -4
- package/Table/hooks/useTableExpansion.d.ts +2 -2
- package/Table/hooks/useTableExpansion.js +5 -5
- package/Table/hooks/useTableFixedOffsets.d.ts +6 -2
- package/Table/hooks/useTableFixedOffsets.js +60 -26
- package/Table/hooks/useTableScroll.d.ts +9 -3
- package/Table/hooks/useTableScroll.js +34 -7
- package/Table/hooks/useTableVirtualization.d.ts +2 -1
- package/Table/hooks/useTableVirtualization.js +2 -8
- package/Table/index.d.ts +4 -3
- package/Table/index.js +3 -0
- package/Table/typings.d.ts +172 -0
- package/Table/utils/useTableRowSelection.js +13 -5
- package/Tag/TagGroup.d.ts +3 -0
- package/Tag/index.d.ts +2 -0
- package/Tag/index.js +1 -0
- package/Transition/Slide.d.ts +9 -2
- package/Transition/Slide.js +7 -4
- package/Tree/TreeNode.js +1 -1
- package/Upload/UploadPictureCard.js +1 -1
- package/index.d.ts +37 -21
- package/index.js +25 -11
- package/package.json +6 -4
- package/Modal/ModalActions.d.ts +0 -9
- package/Modal/ModalActions.js +0 -20
- package/Modal/ModalBody.d.ts +0 -7
- package/Modal/ModalBody.js +0 -14
- package/Notification/Notification.d.ts +0 -54
- package/Notification/Notification.js +0 -76
- package/Notification/index.d.ts +0 -3
- package/Notification/index.js +0 -1
- package/PageToolbar/PageToolbar.d.ts +0 -114
- package/PageToolbar/PageToolbar.js +0 -23
- package/PageToolbar/index.d.ts +0 -2
- package/PageToolbar/index.js +0 -1
- package/PageToolbar/utils.d.ts +0 -23
- package/PageToolbar/utils.js +0 -165
- package/Select/AutoComplete.d.ts +0 -107
- package/Select/AutoComplete.js +0 -114
- package/Table/components/TableDragHandleCell.d.ts +0 -11
- package/Table/components/TableDragHandleCell.js +0 -44
package/Anchor/Anchor.d.ts
CHANGED
|
@@ -1,30 +1,63 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { AnchorItemData } from './AnchorItem';
|
|
3
|
+
export interface AnchorPropsWithAnchors {
|
|
4
|
+
/**
|
|
5
|
+
* ```tsx
|
|
6
|
+
* interface AnchorItemData {
|
|
7
|
+
* autoScrollTo?: boolean;
|
|
8
|
+
* children?: AnchorItemData[];
|
|
9
|
+
* disabled?: boolean;
|
|
10
|
+
* href: string;
|
|
11
|
+
* id: string;
|
|
12
|
+
* name: string;
|
|
13
|
+
* onClick?: VoidFunction;
|
|
14
|
+
* title?: string;
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
anchors: AnchorItemData[];
|
|
19
|
+
children?: never;
|
|
20
|
+
}
|
|
21
|
+
export interface AnchorPropsWithChildren {
|
|
22
|
+
anchors?: never;
|
|
23
|
+
/**
|
|
24
|
+
* Whether to enable smooth scrolling to the target element when clicked.
|
|
25
|
+
*/
|
|
26
|
+
autoScrollTo?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Use nested `<Anchor>` components to create hierarchical navigation. <br />
|
|
29
|
+
* Only accepts `<Anchor>` components and text content as children. <br />
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <AnchorGroup>
|
|
32
|
+
* <Anchor href="#acr1">ACR 1</Anchor>
|
|
33
|
+
* <Anchor href="#acr2">
|
|
34
|
+
* anchor 2
|
|
35
|
+
* <Anchor href="#acr2-1">ACR 2-1</Anchor>
|
|
36
|
+
* <Anchor href="#acr2-2">ACR 2-2</Anchor>
|
|
37
|
+
* </Anchor>
|
|
38
|
+
* </AnchorGroup>
|
|
39
|
+
* ```
|
|
7
40
|
*/
|
|
8
|
-
|
|
41
|
+
children: string | ReactElement<AnchorPropsWithChildren, typeof Anchor> | Array<string | ReactElement<AnchorPropsWithChildren, typeof Anchor>>;
|
|
9
42
|
/**
|
|
10
|
-
*
|
|
43
|
+
* Whether the anchor is disabled.<br>
|
|
44
|
+
* If parent anchor is disabled, all its children will be disabled too. <br />
|
|
11
45
|
*/
|
|
12
|
-
|
|
13
|
-
id: string;
|
|
14
|
-
name: string;
|
|
15
|
-
}[];
|
|
46
|
+
disabled?: boolean;
|
|
16
47
|
/**
|
|
17
|
-
*
|
|
48
|
+
* Required when used as child component.
|
|
18
49
|
*/
|
|
19
|
-
|
|
50
|
+
href?: string;
|
|
20
51
|
/**
|
|
21
52
|
* Trigger when user click on any anchor.
|
|
22
53
|
*/
|
|
23
|
-
onClick?:
|
|
54
|
+
onClick?: VoidFunction;
|
|
55
|
+
title?: string;
|
|
24
56
|
}
|
|
57
|
+
export type AnchorProps = AnchorPropsWithAnchors | AnchorPropsWithChildren;
|
|
25
58
|
/**
|
|
26
|
-
* The
|
|
27
|
-
*
|
|
59
|
+
* The `mezzanine` Anchor component provides navigation menu for page sections with automatic hash tracking.
|
|
60
|
+
* Nested structure supports up to 3 levels; deeper levels will be ignored.
|
|
28
61
|
*/
|
|
29
|
-
declare
|
|
62
|
+
declare function Anchor(props: AnchorProps): import("react/jsx-runtime").JSX.Element;
|
|
30
63
|
export default Anchor;
|
package/Anchor/Anchor.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { Fragment } from 'react';
|
|
4
|
+
import AnchorItem from './AnchorItem.js';
|
|
5
|
+
import { parseChildren } from './utils.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* The
|
|
9
|
-
*
|
|
8
|
+
* The `mezzanine` Anchor component provides navigation menu for page sections with automatic hash tracking.
|
|
9
|
+
* Nested structure supports up to 3 levels; deeper levels will be ignored.
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
}
|
|
11
|
+
function Anchor(props) {
|
|
12
|
+
const anchorItems = 'anchors' in props && props.anchors
|
|
13
|
+
? props.anchors
|
|
14
|
+
: 'children' in props && props.children
|
|
15
|
+
? parseChildren(props.children, Anchor)
|
|
16
|
+
: [];
|
|
17
|
+
return (jsx(Fragment, { children: anchorItems.map((anchorItem) => (jsx(AnchorItem, { autoScrollTo: anchorItem.autoScrollTo, disabled: anchorItem.disabled, href: anchorItem.href, id: anchorItem.id, name: anchorItem.name, onClick: anchorItem.onClick, subAnchors: anchorItem.children, title: anchorItem.title }, anchorItem.id))) }));
|
|
18
|
+
}
|
|
19
19
|
|
|
20
20
|
export { Anchor as default };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import Anchor from './Anchor';
|
|
3
|
+
import type { AnchorPropsWithAnchors, AnchorPropsWithChildren } from './Anchor';
|
|
4
|
+
type AnchorElement = ReactElement<AnchorPropsWithChildren, typeof Anchor>;
|
|
5
|
+
type AnchorChildren = AnchorElement | AnchorElement[];
|
|
6
|
+
export type AnchorGroupPropsWithAnchors = AnchorPropsWithAnchors;
|
|
7
|
+
export interface AnchorGroupPropsWithChildren {
|
|
8
|
+
anchors?: never;
|
|
9
|
+
children: AnchorChildren;
|
|
10
|
+
}
|
|
11
|
+
type AnchorGroupBaseProps = AnchorGroupPropsWithAnchors | AnchorGroupPropsWithChildren;
|
|
12
|
+
export type AnchorGroupProps = AnchorGroupBaseProps & {
|
|
13
|
+
className?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The `mezzanine` AnchorGroup component renders a group of anchor links,
|
|
17
|
+
* configured via an `anchors` prop or parsed from `Anchor` child components.
|
|
18
|
+
*
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <AnchorGroup>
|
|
21
|
+
* <Anchor href="#section1">Section 1</Anchor>
|
|
22
|
+
* <Anchor href="#section2">Section 2</Anchor>
|
|
23
|
+
* </AnchorGroup>
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* ```tsx
|
|
27
|
+
* <AnchorGroup anchors={[
|
|
28
|
+
* { id: 'section1', name: 'Section 1', href: '#section1' },
|
|
29
|
+
* { id: 'section2', name: 'Section 2', href: '#section2' }
|
|
30
|
+
* ]} />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare const AnchorGroup: import("react").ForwardRefExoticComponent<AnchorGroupProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
34
|
+
export default AnchorGroup;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
import { anchorClasses } from '@mezzanine-ui/core/anchor';
|
|
5
|
+
import Anchor from './Anchor.js';
|
|
6
|
+
import { parseChildren } from './utils.js';
|
|
7
|
+
import cx from 'clsx';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The `mezzanine` AnchorGroup component renders a group of anchor links,
|
|
11
|
+
* configured via an `anchors` prop or parsed from `Anchor` child components.
|
|
12
|
+
*
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <AnchorGroup>
|
|
15
|
+
* <Anchor href="#section1">Section 1</Anchor>
|
|
16
|
+
* <Anchor href="#section2">Section 2</Anchor>
|
|
17
|
+
* </AnchorGroup>
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <AnchorGroup anchors={[
|
|
22
|
+
* { id: 'section1', name: 'Section 1', href: '#section1' },
|
|
23
|
+
* { id: 'section2', name: 'Section 2', href: '#section2' }
|
|
24
|
+
* ]} />
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
const AnchorGroup = forwardRef(function AnchorGroup(props, ref) {
|
|
28
|
+
const { className } = props;
|
|
29
|
+
const anchorItems = 'anchors' in props && props.anchors
|
|
30
|
+
? props.anchors
|
|
31
|
+
: 'children' in props && props.children
|
|
32
|
+
? parseChildren(props.children, Anchor)
|
|
33
|
+
: [];
|
|
34
|
+
return (jsx("div", { ref: ref, className: cx(anchorClasses.host, className), children: jsx(Anchor, { anchors: anchorItems }) }));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export { AnchorGroup as default };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface AnchorItemData {
|
|
2
|
+
autoScrollTo?: boolean;
|
|
3
|
+
children?: AnchorItemData[];
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
href: string;
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
onClick?: VoidFunction;
|
|
9
|
+
title?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface AnchorItemProps {
|
|
12
|
+
autoScrollTo?: boolean;
|
|
13
|
+
className?: string;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
href: string;
|
|
16
|
+
id: string;
|
|
17
|
+
level?: number;
|
|
18
|
+
name: string;
|
|
19
|
+
onClick?: VoidFunction;
|
|
20
|
+
parentAutoScrollTo?: boolean;
|
|
21
|
+
parentDisabled?: boolean;
|
|
22
|
+
subAnchors?: AnchorItemData[];
|
|
23
|
+
title?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Individual anchor link with hash tracking and smooth scrolling.
|
|
27
|
+
* Tracks active state from URL hash and inherits disabled state from parent.
|
|
28
|
+
*/
|
|
29
|
+
declare function AnchorItem({ autoScrollTo, className, disabled, href, id: _id, level, name, onClick, parentAutoScrollTo, parentDisabled, subAnchors, title, }: AnchorItemProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export default AnchorItem;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
|
+
import { anchorClasses } from '@mezzanine-ui/core/anchor';
|
|
5
|
+
import Typography from '../Typography/Typography.js';
|
|
6
|
+
import cx from 'clsx';
|
|
7
|
+
|
|
8
|
+
const MAX_CHILDREN_PER_LEVEL = 3;
|
|
9
|
+
/**
|
|
10
|
+
* Custom hook to track window.location.hash changes
|
|
11
|
+
*/
|
|
12
|
+
function useHash() {
|
|
13
|
+
const [hash, setHash] = useState(() => typeof window !== 'undefined' ? window.location.hash : '');
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const handleHashChange = () => {
|
|
16
|
+
setHash(window.location.hash);
|
|
17
|
+
};
|
|
18
|
+
window.addEventListener('hashchange', handleHashChange);
|
|
19
|
+
return () => {
|
|
20
|
+
window.removeEventListener('hashchange', handleHashChange);
|
|
21
|
+
};
|
|
22
|
+
}, []);
|
|
23
|
+
return hash;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Individual anchor link with hash tracking and smooth scrolling.
|
|
27
|
+
* Tracks active state from URL hash and inherits disabled state from parent.
|
|
28
|
+
*/
|
|
29
|
+
function AnchorItem({ autoScrollTo, className, disabled, href, id: _id, level = 1, name, onClick, parentAutoScrollTo = false, parentDisabled = false, subAnchors, title, }) {
|
|
30
|
+
const renderableChildren = subAnchors && subAnchors.length > 0 && level < MAX_CHILDREN_PER_LEVEL
|
|
31
|
+
? subAnchors.slice(0, MAX_CHILDREN_PER_LEVEL)
|
|
32
|
+
: undefined;
|
|
33
|
+
const currentHash = useHash();
|
|
34
|
+
const hashIndex = href.indexOf('#');
|
|
35
|
+
const itemHash = hashIndex !== -1 ? href.slice(hashIndex) : '';
|
|
36
|
+
const isActive = itemHash && currentHash === itemHash;
|
|
37
|
+
const isAutoScrollTo = parentAutoScrollTo || autoScrollTo;
|
|
38
|
+
const isDisabled = parentDisabled || disabled;
|
|
39
|
+
const handleClick = (event) => {
|
|
40
|
+
if (isDisabled) {
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// If href contains a hash, handle navigation manually to ensure hashchange event fires
|
|
45
|
+
if (itemHash && typeof window !== 'undefined') {
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
// Update the hash in the URL only if it's different
|
|
48
|
+
if (window.location.hash !== itemHash) {
|
|
49
|
+
window.history.pushState(null, '', itemHash);
|
|
50
|
+
window.dispatchEvent(new HashChangeEvent('hashchange'));
|
|
51
|
+
}
|
|
52
|
+
// Scroll to the target element if it exists and autoScrollTo is enabled
|
|
53
|
+
if (isAutoScrollTo) {
|
|
54
|
+
const targetElement = document.querySelector(itemHash);
|
|
55
|
+
if (targetElement) {
|
|
56
|
+
targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
onClick === null || onClick === void 0 ? void 0 : onClick();
|
|
61
|
+
};
|
|
62
|
+
return (jsxs(Fragment, { children: [jsx("a", { "aria-disabled": isDisabled, className: cx(anchorClasses.anchorItem, isActive && anchorClasses.anchorItemActive, isDisabled && anchorClasses.anchorItemDisabled, className), href: href, onClick: handleClick, tabIndex: isDisabled ? -1 : undefined, title: title, children: jsx(Typography, { color: "inherit", variant: "label-primary", children: name }) }), renderableChildren && (jsx("div", { className: anchorClasses.nested, children: renderableChildren.map((child) => (jsx(AnchorItem, { autoScrollTo: child.autoScrollTo, className: cx(level === 1 && anchorClasses.nestedLevel1, level === 2 && anchorClasses.nestedLevel2), disabled: child.disabled, href: child.href, id: child.id, level: level + 1, name: child.name, onClick: child.onClick, parentAutoScrollTo: isAutoScrollTo, parentDisabled: isDisabled, subAnchors: child.children, title: child.title }, child.id))) }))] }));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { AnchorItem as default };
|
package/Anchor/index.d.ts
CHANGED
package/Anchor/index.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import Anchor from './Anchor';
|
|
3
|
+
import type { AnchorItemData } from './AnchorItem';
|
|
4
|
+
type AnchorComponentType = typeof Anchor;
|
|
5
|
+
/**
|
|
6
|
+
* Extract text content from ReactNode, excluding Anchor components
|
|
7
|
+
*/
|
|
8
|
+
export declare function extractTextContent(node: ReactNode, AnchorComponent: AnchorComponentType): string;
|
|
9
|
+
/**
|
|
10
|
+
* Parse children to extract anchor data
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseChildren(children: ReactNode, AnchorComponent: AnchorComponentType): AnchorItemData[];
|
|
13
|
+
export {};
|
package/Anchor/utils.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Children, isValidElement } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extract text content from ReactNode, excluding Anchor components
|
|
5
|
+
*/
|
|
6
|
+
function extractTextContent(node, AnchorComponent) {
|
|
7
|
+
if (typeof node === 'string') {
|
|
8
|
+
return node;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(node)) {
|
|
11
|
+
return node.map((n) => extractTextContent(n, AnchorComponent)).join('');
|
|
12
|
+
}
|
|
13
|
+
if (isValidElement(node)) {
|
|
14
|
+
if (node.type === AnchorComponent) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
return extractTextContent(node.props.children, AnchorComponent);
|
|
18
|
+
}
|
|
19
|
+
return '';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse children to extract anchor data
|
|
23
|
+
*/
|
|
24
|
+
function parseChildren(children, AnchorComponent) {
|
|
25
|
+
const items = [];
|
|
26
|
+
Children.forEach(children, (child) => {
|
|
27
|
+
if (typeof child === 'string') {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (isValidElement(child) && child.type !== AnchorComponent) {
|
|
31
|
+
const displayName = typeof child.type === 'string'
|
|
32
|
+
? child.type
|
|
33
|
+
: child.type.displayName
|
|
34
|
+
|| child.type.name
|
|
35
|
+
|| 'Unknown';
|
|
36
|
+
console.warn(`[Anchor] Invalid child type: <${displayName}>. Only <Anchor> components or strings are allowed as children. This element will be ignored.`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (isValidElement(child) && child.type === AnchorComponent) {
|
|
40
|
+
const { children: nestedChildren, ...childProps } = child.props;
|
|
41
|
+
let href;
|
|
42
|
+
let id;
|
|
43
|
+
let name;
|
|
44
|
+
let nestedItems = [];
|
|
45
|
+
if ('anchors' in childProps && childProps.anchors) {
|
|
46
|
+
items.push(...childProps.anchors);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if ('href' in childProps) {
|
|
50
|
+
href = childProps.href;
|
|
51
|
+
}
|
|
52
|
+
if (!href) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (typeof nestedChildren === 'string') {
|
|
56
|
+
id = nestedChildren;
|
|
57
|
+
name = nestedChildren;
|
|
58
|
+
}
|
|
59
|
+
else if (isValidElement(nestedChildren)) {
|
|
60
|
+
nestedItems = parseChildren(nestedChildren, AnchorComponent);
|
|
61
|
+
if (nestedItems.length > 0) {
|
|
62
|
+
id = nestedItems[0].id;
|
|
63
|
+
name = nestedItems[0].name;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const textContent = extractTextContent(nestedChildren, AnchorComponent);
|
|
67
|
+
id = textContent;
|
|
68
|
+
name = textContent;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const parsedNested = parseChildren(nestedChildren, AnchorComponent);
|
|
73
|
+
if (parsedNested.length > 0) {
|
|
74
|
+
nestedItems = parsedNested;
|
|
75
|
+
}
|
|
76
|
+
const textContent = extractTextContent(nestedChildren, AnchorComponent);
|
|
77
|
+
id = textContent;
|
|
78
|
+
name = textContent;
|
|
79
|
+
}
|
|
80
|
+
items.push({
|
|
81
|
+
autoScrollTo: 'autoScrollTo' in childProps ? childProps.autoScrollTo : undefined,
|
|
82
|
+
children: nestedItems.length > 0 ? nestedItems : undefined,
|
|
83
|
+
disabled: 'disabled' in childProps ? childProps.disabled : undefined,
|
|
84
|
+
href,
|
|
85
|
+
id,
|
|
86
|
+
name,
|
|
87
|
+
onClick: 'onClick' in childProps ? childProps.onClick : undefined,
|
|
88
|
+
title: 'title' in childProps ? childProps.title : undefined,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return items;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { extractTextContent, parseChildren };
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { Dispatch, RefObject, SetStateAction } from 'react';
|
|
2
|
+
import { AutoCompleteSelector } from '@mezzanine-ui/core/autocomplete';
|
|
3
|
+
import { DropdownInputPosition } from '@mezzanine-ui/core/dropdown/dropdown';
|
|
4
|
+
import { PopperProps } from '../Popper';
|
|
5
|
+
import type { SelectTriggerInputProps, SelectTriggerProps } from '../Select/typings';
|
|
6
|
+
import { SelectValue } from '../Select/typings';
|
|
7
|
+
import { PickRenameMulti } from '../utils/general';
|
|
8
|
+
export interface AutoCompleteBaseProps extends Omit<SelectTriggerProps, 'active' | 'clearable' | 'forceHideSuffixActionIcon' | 'mode' | 'onClick' | 'onKeyDown' | 'onChange' | 'renderValue' | 'inputProps' | 'suffixActionIcon' | 'value'>, PickRenameMulti<Pick<PopperProps, 'options'>, {
|
|
9
|
+
options: 'popperOptions';
|
|
10
|
+
}> {
|
|
11
|
+
/**
|
|
12
|
+
* Set to true when options can be added dynamically
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
15
|
+
addable?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the data is fetched asynchronously.
|
|
18
|
+
* If true, input change will trigger loading until onSearch promise resolves.
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
asyncData?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Characters that can be used to separate multiple items when creating.
|
|
24
|
+
* When these characters are entered, they will trigger item creation.
|
|
25
|
+
* @default [',', '+', '\n']
|
|
26
|
+
*/
|
|
27
|
+
createSeparators?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Should the filter rules be disabled (If you need to control options filter by yourself)
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
disabledOptionsFilter?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The text of the dropdown empty status.
|
|
35
|
+
*/
|
|
36
|
+
emptyText?: string;
|
|
37
|
+
/**
|
|
38
|
+
* The id attribute of the input element.
|
|
39
|
+
*
|
|
40
|
+
* @important When using with react-hook-form or native forms, this prop is recommended.
|
|
41
|
+
*/
|
|
42
|
+
id?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Whether to keep search text visible after blur when no value is selected.
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
keepSearchTextOnBlur?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* The position of the input.
|
|
50
|
+
* @default 'outside'
|
|
51
|
+
*/
|
|
52
|
+
inputPosition?: DropdownInputPosition;
|
|
53
|
+
/**
|
|
54
|
+
* The other native props for input element.
|
|
55
|
+
*/
|
|
56
|
+
inputProps?: Omit<SelectTriggerInputProps, 'onChange' | 'placeholder' | 'role' | 'value' | `aria-${'controls' | 'expanded' | 'owns'}`>;
|
|
57
|
+
/**
|
|
58
|
+
* Whether the dropdown is in loading state.
|
|
59
|
+
* @default false
|
|
60
|
+
*/
|
|
61
|
+
loading?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* The text of the dropdown loading status.
|
|
64
|
+
*/
|
|
65
|
+
loadingText?: string;
|
|
66
|
+
/**
|
|
67
|
+
* The max height of the dropdown list.
|
|
68
|
+
*/
|
|
69
|
+
menuMaxHeight?: number | string;
|
|
70
|
+
/**
|
|
71
|
+
* The name attribute of the input element.
|
|
72
|
+
*
|
|
73
|
+
* @important When using with react-hook-form or native forms, this prop is recommended.
|
|
74
|
+
*
|
|
75
|
+
* @example With react-hook-form
|
|
76
|
+
* ```tsx
|
|
77
|
+
* const { register } = useForm();
|
|
78
|
+
* <AutoComplete name="autocomplete" {...register('autocomplete')} />
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
name?: string;
|
|
82
|
+
/**
|
|
83
|
+
* insert callback whenever insert icon is clicked
|
|
84
|
+
* receives the text to insert and current options, returns the updated options array
|
|
85
|
+
* should remove previously created but unselected options
|
|
86
|
+
* The returned options will be used to update the component's options prop
|
|
87
|
+
*/
|
|
88
|
+
onInsert?(text: string, currentOptions: SelectValue[]): SelectValue[];
|
|
89
|
+
/**
|
|
90
|
+
* The search event handler
|
|
91
|
+
* Can return a Promise for async data loading
|
|
92
|
+
*/
|
|
93
|
+
onSearch?(input: string): void | Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Callback fired on every input change (no debounce).
|
|
96
|
+
*/
|
|
97
|
+
onSearchTextChange?(text: string): void;
|
|
98
|
+
/**
|
|
99
|
+
* Callback fired when the dropdown visibility changes.
|
|
100
|
+
*/
|
|
101
|
+
onVisibilityChange?: (open: boolean) => void;
|
|
102
|
+
/**
|
|
103
|
+
* Whether the dropdown is open (controlled).
|
|
104
|
+
*/
|
|
105
|
+
open?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* The options that mapped autocomplete options
|
|
108
|
+
*/
|
|
109
|
+
options: SelectValue[];
|
|
110
|
+
/**
|
|
111
|
+
* select input placeholder
|
|
112
|
+
*/
|
|
113
|
+
placeholder?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Whether the selection is required.
|
|
116
|
+
* @default false
|
|
117
|
+
*/
|
|
118
|
+
required?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* The debounce time of the search event handler.
|
|
121
|
+
* @default 300
|
|
122
|
+
*/
|
|
123
|
+
searchDebounceTime?: number;
|
|
124
|
+
/**
|
|
125
|
+
* Imperative handle to control search text externally (e.g. reset or sync).
|
|
126
|
+
*/
|
|
127
|
+
searchTextControlRef?: RefObject<{
|
|
128
|
+
setSearchText: Dispatch<SetStateAction<string>>;
|
|
129
|
+
} | undefined>;
|
|
130
|
+
/**
|
|
131
|
+
* Whether to trim whitespace from created items.
|
|
132
|
+
* @default true
|
|
133
|
+
*/
|
|
134
|
+
trimOnCreate?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Custom text for the create action button.
|
|
137
|
+
* @default '建立 "{text}"'
|
|
138
|
+
*/
|
|
139
|
+
createActionText?: (text: string) => string;
|
|
140
|
+
/**
|
|
141
|
+
* Default template for the create action button text.
|
|
142
|
+
* Use this to customize the default text format when createActionText is not provided.
|
|
143
|
+
* The template should contain {text} placeholder which will be replaced with the actual text.
|
|
144
|
+
* @default '建立 "{text}"'
|
|
145
|
+
*/
|
|
146
|
+
createActionTextTemplate?: string;
|
|
147
|
+
/**
|
|
148
|
+
* The z-index of the dropdown.
|
|
149
|
+
*/
|
|
150
|
+
dropdownZIndex?: number | string;
|
|
151
|
+
/**
|
|
152
|
+
* Callback fired when the dropdown list reaches the bottom.
|
|
153
|
+
* Only fires when `menuMaxHeight` is set and the list is scrollable.
|
|
154
|
+
*/
|
|
155
|
+
onReachBottom?: () => void;
|
|
156
|
+
/**
|
|
157
|
+
* Callback fired when the dropdown list leaves the bottom.
|
|
158
|
+
* Only fires when `menuMaxHeight` is set and the list is scrollable.
|
|
159
|
+
*/
|
|
160
|
+
onLeaveBottom?: () => void;
|
|
161
|
+
}
|
|
162
|
+
export type AutoCompleteMultipleProps = AutoCompleteBaseProps & {
|
|
163
|
+
/**
|
|
164
|
+
* The default selection
|
|
165
|
+
*/
|
|
166
|
+
defaultValue?: SelectValue[];
|
|
167
|
+
/**
|
|
168
|
+
* Controls the layout of trigger.
|
|
169
|
+
*/
|
|
170
|
+
mode: 'multiple';
|
|
171
|
+
/**
|
|
172
|
+
* The change event handler of input element.
|
|
173
|
+
*/
|
|
174
|
+
onChange?(newOptions: SelectValue[]): void;
|
|
175
|
+
/**
|
|
176
|
+
* The selector of input.
|
|
177
|
+
* @default 'input'
|
|
178
|
+
*/
|
|
179
|
+
selector?: AutoCompleteSelector;
|
|
180
|
+
/**
|
|
181
|
+
* The value of selection.
|
|
182
|
+
* @default undefined
|
|
183
|
+
*/
|
|
184
|
+
value?: SelectValue[];
|
|
185
|
+
};
|
|
186
|
+
export type AutoCompleteSingleProps = AutoCompleteBaseProps & {
|
|
187
|
+
/**
|
|
188
|
+
* The default selection
|
|
189
|
+
*/
|
|
190
|
+
defaultValue?: SelectValue;
|
|
191
|
+
/**
|
|
192
|
+
* Controls the layout of trigger.
|
|
193
|
+
*/
|
|
194
|
+
mode?: 'single';
|
|
195
|
+
/**
|
|
196
|
+
* The change event handler of input element.
|
|
197
|
+
*/
|
|
198
|
+
onChange?(newOptions: SelectValue): void;
|
|
199
|
+
/**
|
|
200
|
+
* The selector of input.
|
|
201
|
+
* @default 'input'
|
|
202
|
+
*/
|
|
203
|
+
selector?: AutoCompleteSelector;
|
|
204
|
+
/**
|
|
205
|
+
* The value of selection.
|
|
206
|
+
* @default undefined
|
|
207
|
+
*/
|
|
208
|
+
value?: SelectValue | null;
|
|
209
|
+
};
|
|
210
|
+
export type AutoCompleteProps = AutoCompleteMultipleProps | AutoCompleteSingleProps;
|
|
211
|
+
/**
|
|
212
|
+
* The AutoComplete component for react. <br />
|
|
213
|
+
* Note that if you need search for ONLY given options, not included your typings,
|
|
214
|
+
* should considering using the `Select` component with `onSearch` prop.
|
|
215
|
+
*/
|
|
216
|
+
declare const AutoComplete: import("react").ForwardRefExoticComponent<AutoCompleteProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
217
|
+
export default AutoComplete;
|