@mezzanine-ui/react 1.0.0-beta.1 → 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/Anchor/Anchor.d.ts +51 -18
  2. package/Anchor/Anchor.js +15 -15
  3. package/Anchor/AnchorGroup.d.ts +34 -0
  4. package/Anchor/AnchorGroup.js +37 -0
  5. package/Anchor/AnchorItem.d.ts +30 -0
  6. package/Anchor/AnchorItem.js +65 -0
  7. package/Anchor/index.d.ts +2 -0
  8. package/Anchor/index.js +1 -0
  9. package/Anchor/utils.d.ts +13 -0
  10. package/Anchor/utils.js +95 -0
  11. package/AutoComplete/AutoComplete.d.ts +194 -0
  12. package/AutoComplete/AutoComplete.js +419 -0
  13. package/AutoComplete/index.d.ts +2 -0
  14. package/AutoComplete/index.js +1 -0
  15. package/AutoComplete/useAutoCompleteCreation.d.ts +33 -0
  16. package/AutoComplete/useAutoCompleteCreation.js +201 -0
  17. package/AutoComplete/useAutoCompleteKeyboard.d.ts +31 -0
  18. package/AutoComplete/useAutoCompleteKeyboard.js +149 -0
  19. package/AutoComplete/useAutoCompleteSearch.d.ts +16 -0
  20. package/AutoComplete/useAutoCompleteSearch.js +69 -0
  21. package/AutoComplete/useCreationTracker.d.ts +17 -0
  22. package/AutoComplete/useCreationTracker.js +47 -0
  23. package/Badge/Badge.js +2 -2
  24. package/Breadcrumb/BreadcrumbItem.d.ts +1 -1
  25. package/Button/Button.js +13 -11
  26. package/Button/index.d.ts +1 -1
  27. package/Button/typings.d.ts +27 -4
  28. package/Description/Description.d.ts +30 -0
  29. package/Description/Description.js +13 -0
  30. package/Description/DescriptionContent.d.ts +41 -0
  31. package/Description/DescriptionContent.js +14 -0
  32. package/Description/DescriptionGroup.d.ts +13 -0
  33. package/Description/DescriptionGroup.js +12 -0
  34. package/Description/DescriptionTitle.d.ts +45 -0
  35. package/Description/DescriptionTitle.js +17 -0
  36. package/Description/index.d.ts +8 -0
  37. package/Description/index.js +4 -0
  38. package/Dropdown/Dropdown.d.ts +43 -3
  39. package/Dropdown/Dropdown.js +154 -35
  40. package/Dropdown/DropdownAction.d.ts +1 -1
  41. package/Dropdown/DropdownAction.js +1 -4
  42. package/Dropdown/DropdownItem.d.ts +21 -4
  43. package/Dropdown/DropdownItem.js +23 -10
  44. package/Dropdown/DropdownItemCard.d.ts +5 -5
  45. package/Dropdown/DropdownItemCard.js +11 -10
  46. package/Dropdown/DropdownStatus.d.ts +2 -2
  47. package/Dropdown/DropdownStatus.js +29 -0
  48. package/Dropdown/dropdownKeydownHandler.d.ts +2 -1
  49. package/Dropdown/dropdownKeydownHandler.js +73 -0
  50. package/Dropdown/highlightText.js +5 -1
  51. package/Dropdown/shortcutTextHandler.d.ts +24 -0
  52. package/Dropdown/shortcutTextHandler.js +171 -0
  53. package/Form/FormControlContext.d.ts +2 -2
  54. package/Form/FormField.d.ts +56 -4
  55. package/Form/FormField.js +10 -6
  56. package/Form/FormHintText.d.ts +24 -1
  57. package/Form/FormHintText.js +4 -4
  58. package/Form/FormLabel.d.ts +6 -3
  59. package/Form/FormLabel.js +5 -3
  60. package/Input/Input.d.ts +29 -3
  61. package/Input/Input.js +22 -6
  62. package/Input/PasswordStrengthIndicator/PasswordStrengthIndicator.js +1 -1
  63. package/Modal/Modal.d.ts +103 -11
  64. package/Modal/Modal.js +14 -9
  65. package/Modal/ModalBodyForVerification.d.ts +59 -0
  66. package/Modal/ModalBodyForVerification.js +99 -0
  67. package/Modal/ModalControl.d.ts +2 -2
  68. package/Modal/ModalControl.js +1 -1
  69. package/Modal/ModalFooter.d.ts +119 -1
  70. package/Modal/ModalFooter.js +15 -3
  71. package/Modal/ModalHeader.d.ts +26 -7
  72. package/Modal/ModalHeader.js +33 -7
  73. package/Modal/index.d.ts +4 -5
  74. package/Modal/index.js +1 -2
  75. package/Modal/useModalContainer.d.ts +12 -3
  76. package/Modal/useModalContainer.js +28 -6
  77. package/Navigation/CollapsedMenu.d.ts +6 -0
  78. package/Navigation/CollapsedMenu.js +16 -0
  79. package/Navigation/Navigation.d.ts +17 -3
  80. package/Navigation/Navigation.js +48 -33
  81. package/Navigation/NavigationFooter.js +4 -2
  82. package/Navigation/NavigationHeader.d.ts +11 -1
  83. package/Navigation/NavigationHeader.js +6 -3
  84. package/Navigation/NavigationOption.d.ts +3 -2
  85. package/Navigation/NavigationOption.js +45 -26
  86. package/Navigation/NavigationOptionCategory.js +20 -2
  87. package/Navigation/context.d.ts +2 -0
  88. package/Navigation/useVisibleItems.d.ts +5 -0
  89. package/Navigation/useVisibleItems.js +54 -0
  90. package/NotificationCenter/NotificationCenter.d.ts +124 -0
  91. package/NotificationCenter/NotificationCenter.js +259 -0
  92. package/NotificationCenter/NotificationCenterDrawer.d.ts +89 -0
  93. package/NotificationCenter/index.d.ts +3 -0
  94. package/NotificationCenter/index.js +1 -0
  95. package/PageFooter/PageFooter.d.ts +19 -9
  96. package/PageFooter/PageFooter.js +10 -10
  97. package/PageHeader/PageHeader.js +4 -12
  98. package/PageToolbar/PageToolbar.d.ts +2 -6
  99. package/PageToolbar/utils.js +4 -12
  100. package/Select/index.d.ts +0 -2
  101. package/Select/index.js +0 -1
  102. package/Slider/useSlider.js +1 -1
  103. package/Table/Table.d.ts +53 -15
  104. package/Table/Table.js +178 -82
  105. package/Table/TableContext.d.ts +18 -42
  106. package/Table/components/TableActionsCell.d.ts +26 -0
  107. package/Table/components/TableActionsCell.js +78 -0
  108. package/Table/components/TableBody.d.ts +2 -5
  109. package/Table/components/TableBody.js +16 -19
  110. package/Table/components/TableBulkActions.d.ts +15 -0
  111. package/Table/components/TableBulkActions.js +26 -0
  112. package/Table/components/TableCell.d.ts +2 -0
  113. package/Table/components/TableCell.js +42 -10
  114. package/Table/components/TableColGroup.js +10 -112
  115. package/Table/components/TableColumnTitleMenu.d.ts +6 -0
  116. package/Table/components/TableColumnTitleMenu.js +20 -0
  117. package/Table/components/TableDragHandleCell.d.ts +2 -0
  118. package/Table/components/TableDragHandleCell.js +8 -1
  119. package/Table/components/TableExpandCell.d.ts +2 -0
  120. package/Table/components/TableExpandCell.js +8 -1
  121. package/Table/components/TableExpandedRow.js +3 -2
  122. package/Table/components/TableHeader.d.ts +2 -4
  123. package/Table/components/TableHeader.js +11 -14
  124. package/Table/components/TableResizeHandle.js +3 -7
  125. package/Table/components/TableRow.js +54 -20
  126. package/Table/components/TableSelectionCell.d.ts +5 -0
  127. package/Table/components/TableSelectionCell.js +12 -1
  128. package/Table/components/index.d.ts +1 -0
  129. package/Table/components/index.js +1 -0
  130. package/Table/hooks/index.d.ts +1 -1
  131. package/Table/hooks/index.js +1 -1
  132. package/Table/hooks/useTableDataSource.d.ts +2 -2
  133. package/Table/hooks/useTableExpansion.js +0 -6
  134. package/Table/hooks/useTableFixedOffsets.d.ts +1 -1
  135. package/Table/hooks/useTableFixedOffsets.js +24 -26
  136. package/Table/hooks/useTableResizedColumns.d.ts +2 -0
  137. package/Table/hooks/useTableResizedColumns.js +22 -0
  138. package/Table/hooks/useTableScroll.d.ts +3 -1
  139. package/Table/hooks/useTableScroll.js +25 -19
  140. package/Table/hooks/useTableSelection.js +32 -8
  141. package/Table/hooks/useTableVirtualization.d.ts +1 -1
  142. package/Table/index.d.ts +4 -4
  143. package/Table/index.js +5 -3
  144. package/Table/utils/calculateColumnWidths.d.ts +28 -0
  145. package/Table/utils/calculateColumnWidths.js +80 -0
  146. package/Table/utils/index.d.ts +2 -0
  147. package/Table/utils/index.js +1 -0
  148. package/Table/utils/useTableRowSelection.d.ts +5 -5
  149. package/Table/utils/useTableRowSelection.js +14 -6
  150. package/Tag/TagGroup.d.ts +3 -0
  151. package/Tag/index.d.ts +2 -0
  152. package/Tag/index.js +1 -0
  153. package/Upload/UploadPictureCard.js +1 -1
  154. package/index.d.ts +36 -20
  155. package/index.js +26 -7
  156. package/package.json +4 -4
  157. package/utils/format-number-with-commas.d.ts +4 -0
  158. package/utils/format-number-with-commas.js +27 -0
  159. package/utils/parse-number-with-commas.d.ts +4 -0
  160. package/utils/parse-number-with-commas.js +22 -0
  161. package/Modal/ModalActions.d.ts +0 -9
  162. package/Modal/ModalActions.js +0 -20
  163. package/Modal/ModalBody.d.ts +0 -7
  164. package/Modal/ModalBody.js +0 -14
  165. package/Notification/Notification.d.ts +0 -54
  166. package/Notification/Notification.js +0 -76
  167. package/Notification/index.d.ts +0 -3
  168. package/Notification/index.js +0 -1
  169. package/Select/AutoComplete.d.ts +0 -107
  170. package/Select/AutoComplete.js +0 -114
  171. package/Table/hooks/useTableColumns.d.ts +0 -8
  172. package/Table/hooks/useTableColumns.js +0 -91
@@ -1,30 +1,63 @@
1
- import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
2
- export interface AnchorProps extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'onClick'> {
3
- /** The current active anchor ID */
4
- activeAnchorId?: string;
5
- /** Whether apply ellipsis or not
6
- * @default false
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
- ellipsis?: boolean;
41
+ children: string | ReactElement<AnchorPropsWithChildren, typeof Anchor> | Array<string | ReactElement<AnchorPropsWithChildren, typeof Anchor>>;
9
42
  /**
10
- * Anchor list.
43
+ * Whether the anchor is disabled.<br>
44
+ * If parent anchor is disabled, all its children will be disabled too. <br />
11
45
  */
12
- list: {
13
- id: string;
14
- name: string;
15
- }[];
46
+ disabled?: boolean;
16
47
  /**
17
- * The maximum width for anchor container. This might be useful when you need to set `ellipsis: true`.
48
+ * Required when used as child component.
18
49
  */
19
- maxWidth?: number;
50
+ href?: string;
20
51
  /**
21
52
  * Trigger when user click on any anchor.
22
53
  */
23
- onClick?: (nextAnchorId: string) => void;
54
+ onClick?: VoidFunction;
55
+ title?: string;
24
56
  }
57
+ export type AnchorProps = AnchorPropsWithAnchors | AnchorPropsWithChildren;
25
58
  /**
26
- * The react component for `mezzanine` anchor.
27
- * This component should always be full width of its parent.
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 const Anchor: import("react").ForwardRefExoticComponent<AnchorProps & import("react").RefAttributes<HTMLDivElement>>;
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
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { forwardRef } from 'react';
3
- import { anchorClasses } from '@mezzanine-ui/core/anchor';
4
- import Typography from '../Typography/Typography.js';
5
- import cx from 'clsx';
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 react component for `mezzanine` anchor.
9
- * This component should always be full width of its parent.
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
- const Anchor = forwardRef(function Anchor(props, ref) {
12
- const { activeAnchorId, className, ellipsis = false, list, maxWidth, onClick, style, ...rest } = props;
13
- const resolvedStyle = {
14
- ...(style || {}),
15
- ...(maxWidth ? { maxWidth: `${maxWidth}px` } : {}),
16
- };
17
- return (jsxs("div", { ref: ref, className: cx(anchorClasses.host, className), style: resolvedStyle, ...rest, children: [jsx("div", { className: anchorClasses.bar }), list.map((anchor) => (jsx("button", { type: "button", onClick: () => onClick === null || onClick === void 0 ? void 0 : onClick(anchor.id), className: cx(anchorClasses.anchor, activeAnchorId === anchor.id && anchorClasses.anchorActive), children: jsx(Typography, { variant: "input3", color: "inherit", ellipsis: ellipsis, children: anchor.name }) }, anchor.id)))] }));
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
@@ -1,2 +1,4 @@
1
+ export type { AnchorGroupProps } from './AnchorGroup';
2
+ export { default as AnchorGroup } from './AnchorGroup';
1
3
  export type { AnchorProps } from './Anchor';
2
4
  export { default } from './Anchor';
package/Anchor/index.js CHANGED
@@ -1 +1,2 @@
1
+ export { default as AnchorGroup } from './AnchorGroup.js';
1
2
  export { default } from './Anchor.js';
@@ -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 {};
@@ -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,194 @@
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
+ * The position of the input.
45
+ * @default 'outside'
46
+ */
47
+ inputPosition?: DropdownInputPosition;
48
+ /**
49
+ * The other native props for input element.
50
+ */
51
+ inputProps?: Omit<SelectTriggerInputProps, 'onChange' | 'placeholder' | 'role' | 'value' | `aria-${'controls' | 'expanded' | 'owns'}`>;
52
+ /**
53
+ * Whether the dropdown is in loading state.
54
+ * @default false
55
+ */
56
+ loading?: boolean;
57
+ /**
58
+ * The text of the dropdown loading status.
59
+ */
60
+ loadingText?: string;
61
+ /**
62
+ * The max height of the dropdown list.
63
+ */
64
+ menuMaxHeight?: number | string;
65
+ /**
66
+ * The name attribute of the input element.
67
+ *
68
+ * @important When using with react-hook-form or native forms, this prop is recommended.
69
+ *
70
+ * @example With react-hook-form
71
+ * ```tsx
72
+ * const { register } = useForm();
73
+ * <AutoComplete name="autocomplete" {...register('autocomplete')} />
74
+ * ```
75
+ */
76
+ name?: string;
77
+ /**
78
+ * insert callback whenever insert icon is clicked
79
+ * receives the text to insert and current options, returns the updated options array
80
+ * should remove previously created but unselected options
81
+ * The returned options will be used to update the component's options prop
82
+ */
83
+ onInsert?(text: string, currentOptions: SelectValue[]): SelectValue[];
84
+ /**
85
+ * The search event handler
86
+ * Can return a Promise for async data loading
87
+ */
88
+ onSearch?(input: string): void | Promise<void>;
89
+ /**
90
+ * Callback fired when the dropdown visibility changes.
91
+ */
92
+ onVisibilityChange?: (open: boolean) => void;
93
+ /**
94
+ * Whether the dropdown is open (controlled).
95
+ */
96
+ open?: boolean;
97
+ /**
98
+ * The options that mapped autocomplete options
99
+ */
100
+ options: SelectValue[];
101
+ /**
102
+ * select input placeholder
103
+ */
104
+ placeholder?: string;
105
+ /**
106
+ * Whether the selection is required.
107
+ * @default false
108
+ */
109
+ required?: boolean;
110
+ /**
111
+ * The debounce time of the search event handler.
112
+ * @default 300
113
+ */
114
+ searchDebounceTime?: number;
115
+ /**
116
+ * Imperative handle to control search text externally (e.g. reset or sync).
117
+ */
118
+ searchTextControlRef?: RefObject<{
119
+ setSearchText: Dispatch<SetStateAction<string>>;
120
+ } | undefined>;
121
+ /**
122
+ * Whether to trim whitespace from created items.
123
+ * @default true
124
+ */
125
+ trimOnCreate?: boolean;
126
+ /**
127
+ * Custom text for the create action button.
128
+ * @default '建立 "{text}"'
129
+ */
130
+ createActionText?: (text: string) => string;
131
+ /**
132
+ * Default template for the create action button text.
133
+ * Use this to customize the default text format when createActionText is not provided.
134
+ * The template should contain {text} placeholder which will be replaced with the actual text.
135
+ * @default '建立 "{text}"'
136
+ */
137
+ createActionTextTemplate?: string;
138
+ }
139
+ export type AutoCompleteMultipleProps = AutoCompleteBaseProps & {
140
+ /**
141
+ * The default selection
142
+ */
143
+ defaultValue?: SelectValue[];
144
+ /**
145
+ * Controls the layout of trigger.
146
+ */
147
+ mode: 'multiple';
148
+ /**
149
+ * The change event handler of input element.
150
+ */
151
+ onChange?(newOptions: SelectValue[]): void;
152
+ /**
153
+ * The selector of input.
154
+ * @default 'input'
155
+ */
156
+ selector?: AutoCompleteSelector;
157
+ /**
158
+ * The value of selection.
159
+ * @default undefined
160
+ */
161
+ value?: SelectValue[];
162
+ };
163
+ export type AutoCompleteSingleProps = AutoCompleteBaseProps & {
164
+ /**
165
+ * The default selection
166
+ */
167
+ defaultValue?: SelectValue;
168
+ /**
169
+ * Controls the layout of trigger.
170
+ */
171
+ mode?: 'single';
172
+ /**
173
+ * The change event handler of input element.
174
+ */
175
+ onChange?(newOptions: SelectValue): void;
176
+ /**
177
+ * The selector of input.
178
+ * @default 'input'
179
+ */
180
+ selector?: AutoCompleteSelector;
181
+ /**
182
+ * The value of selection.
183
+ * @default undefined
184
+ */
185
+ value?: SelectValue | null;
186
+ };
187
+ export type AutoCompleteProps = AutoCompleteMultipleProps | AutoCompleteSingleProps;
188
+ /**
189
+ * The AutoComplete component for react. <br />
190
+ * Note that if you need search for ONLY given options, not included your typings,
191
+ * should considering using the `Select` component with `onSearch` prop.
192
+ */
193
+ declare const AutoComplete: import("react").ForwardRefExoticComponent<AutoCompleteProps & import("react").RefAttributes<HTMLDivElement>>;
194
+ export default AutoComplete;