habarico 7.3.0-beta.3 → 7.3.0-beta.5
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/README.md +2 -28
- package/lib/index.cjs +54 -23
- package/lib/index.cjs.map +1 -1
- package/lib/index.esm.js +54 -23
- package/lib/index.esm.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ or 19.
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
14
|
+
npm install habarico
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Peer dependencies (React, React Admin, MUI) are not bundled — install them in the project at the
|
|
@@ -21,28 +21,6 @@ same versions the library declares.
|
|
|
21
21
|
> data router. Let `SchemaAdmin` create one itself, or wrap it in `createBrowserRouter` — a legacy
|
|
22
22
|
> `<BrowserRouter>` silently disables the guard.
|
|
23
23
|
|
|
24
|
-
## Local development against a checkout
|
|
25
|
-
|
|
26
|
-
To run a project against your working copy instead of the published package, link it from the
|
|
27
|
-
project directory — the free library first, the paid one second:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
pydev link-library <path-to-libs>/habarico-base/node <path-to-libs>/habarico-enterprise/node-enterprise
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
`<path-to-libs>` is the directory holding your library checkouts — the same placeholder the Ruby services use in their compose files. Relative or absolute, both work.
|
|
34
|
-
|
|
35
|
-
Link only what you develop; either package works on its own. When you link both, the order matters —
|
|
36
|
-
`habarico-enterprise` resolves its own `habarico` through the project, so the free library
|
|
37
|
-
has to be linked first or both end up with their own copy of React.
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
pnpm watch # in the library you edit
|
|
41
|
-
pydev unlink-library <same paths>
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
See [Installation](https://docs.habarico.com/node/installation) for the details.
|
|
45
|
-
|
|
46
24
|
## Quick start
|
|
47
25
|
|
|
48
26
|
```tsx
|
|
@@ -77,7 +55,7 @@ is only a quick start.
|
|
|
77
55
|
|
|
78
56
|
| Section | What it covers |
|
|
79
57
|
| --- | --- |
|
|
80
|
-
| [Installation](https://docs.habarico.com/node/installation) |
|
|
58
|
+
| [Installation](https://docs.habarico.com/node/installation) | Peer dependencies and the router requirement |
|
|
81
59
|
| [Base components](https://docs.habarico.com/node/base-components/) | `SchemaAdmin` and `SchemaResource` — every prop |
|
|
82
60
|
| [View components](https://docs.habarico.com/node/view-components/) | List, show, create, edit and action views |
|
|
83
61
|
| [Providers](https://docs.habarico.com/node/providers/) | Auth, data and schema providers, and the customisation registries |
|
|
@@ -91,10 +69,6 @@ The backends serving those schemas are documented at
|
|
|
91
69
|
[docs.habarico.com/ruby/intro](https://docs.habarico.com/ruby/intro); the contract between them is the
|
|
92
70
|
[API reference](https://docs.habarico.com/api).
|
|
93
71
|
|
|
94
|
-
The architecture of the library itself — its four layers and what belongs where — is documented in
|
|
95
|
-
`src/foundation/README.md`, `src/design/README.md`, `src/admin/README.md` and
|
|
96
|
-
`src/schema/README.md`, next to the code they describe.
|
|
97
|
-
|
|
98
72
|
## License
|
|
99
73
|
|
|
100
74
|
[MIT](LICENSE)
|
package/lib/index.cjs
CHANGED
|
@@ -55441,6 +55441,7 @@ const MenuItem = ({
|
|
|
55441
55441
|
highlighted,
|
|
55442
55442
|
sub,
|
|
55443
55443
|
dropdown,
|
|
55444
|
+
expanded,
|
|
55444
55445
|
tooltip,
|
|
55445
55446
|
onMouseEnter,
|
|
55446
55447
|
onMouseLeave,
|
|
@@ -55450,12 +55451,13 @@ const MenuItem = ({
|
|
|
55450
55451
|
const isLight = theme.palette.mode === "light";
|
|
55451
55452
|
const activeText = isLight ? theme.palette.primary.dark : theme.palette.primary.light;
|
|
55452
55453
|
const activeIcon = isLight ? theme.palette.primary.main : theme.palette.primary.lighter;
|
|
55454
|
+
const isGroup = !!item.items?.length;
|
|
55455
|
+
const linkProps = isGroup ? { "aria-expanded": !!expanded } : { component: RouterLink, href: item.href };
|
|
55453
55456
|
return /* @__PURE__ */ jsxRuntime.jsx(material.Tooltip, { title: tooltip, placement: "right", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
55454
55457
|
material.ListItemButton,
|
|
55455
55458
|
{
|
|
55456
55459
|
disableGutters: true,
|
|
55457
|
-
|
|
55458
|
-
href: item.href,
|
|
55460
|
+
...linkProps,
|
|
55459
55461
|
onMouseEnter,
|
|
55460
55462
|
onMouseLeave,
|
|
55461
55463
|
onClick,
|
|
@@ -55504,6 +55506,7 @@ const MenuItemWithPopper = ({ children, onClick, ...rest }) => {
|
|
|
55504
55506
|
const isOverSubMenuRef = React.useRef(false);
|
|
55505
55507
|
const openTimeoutRef = React.useRef(void 0);
|
|
55506
55508
|
const closeTimeoutRef = React.useRef(void 0);
|
|
55509
|
+
const openedByClickRef = React.useRef(false);
|
|
55507
55510
|
const closeIfNotOver = React.useCallback(() => {
|
|
55508
55511
|
clearTimeout(closeTimeoutRef.current);
|
|
55509
55512
|
closeTimeoutRef.current = setTimeout(() => {
|
|
@@ -55517,9 +55520,22 @@ const MenuItemWithPopper = ({ children, onClick, ...rest }) => {
|
|
|
55517
55520
|
isOverMenuRef.current = true;
|
|
55518
55521
|
const target = e.currentTarget;
|
|
55519
55522
|
openTimeoutRef.current = setTimeout(() => {
|
|
55523
|
+
openedByClickRef.current = false;
|
|
55520
55524
|
setAnchorEl(target);
|
|
55521
55525
|
}, POPOVER_OPEN_DEBOUNCE);
|
|
55522
55526
|
}, []);
|
|
55527
|
+
const togglePopper = React.useCallback(
|
|
55528
|
+
(e) => {
|
|
55529
|
+
clearTimeout(openTimeoutRef.current);
|
|
55530
|
+
clearTimeout(closeTimeoutRef.current);
|
|
55531
|
+
const target = e.currentTarget;
|
|
55532
|
+
const close = Boolean(anchorEl) && openedByClickRef.current;
|
|
55533
|
+
openedByClickRef.current = !close;
|
|
55534
|
+
setAnchorEl(close ? null : target);
|
|
55535
|
+
onClick?.(e);
|
|
55536
|
+
},
|
|
55537
|
+
[anchorEl, onClick]
|
|
55538
|
+
);
|
|
55523
55539
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
55524
55540
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
55525
55541
|
MenuItem,
|
|
@@ -55531,7 +55547,8 @@ const MenuItemWithPopper = ({ children, onClick, ...rest }) => {
|
|
|
55531
55547
|
isOverMenuRef.current = false;
|
|
55532
55548
|
closeIfNotOver();
|
|
55533
55549
|
},
|
|
55534
|
-
onClick
|
|
55550
|
+
onClick: togglePopper,
|
|
55551
|
+
expanded: Boolean(anchorEl)
|
|
55535
55552
|
}
|
|
55536
55553
|
),
|
|
55537
55554
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -55629,8 +55646,39 @@ const MenuListCollapsed = ({ items, level, onItemClick }) => {
|
|
|
55629
55646
|
const SUB_INDENT = 40;
|
|
55630
55647
|
const ELBOW_WIDTH = 16;
|
|
55631
55648
|
const ELBOW_RADIUS = 10;
|
|
55632
|
-
const
|
|
55649
|
+
const MenuListFullItem = ({ item, level, onItemClick }) => {
|
|
55633
55650
|
const { isActive, isExpanded } = useActiveExpanded();
|
|
55651
|
+
const pathname = usePathname();
|
|
55652
|
+
const routeExpanded = isExpanded(item);
|
|
55653
|
+
const [open, setOpen] = React.useState(routeExpanded);
|
|
55654
|
+
const [syncedPathname, setSyncedPathname] = React.useState(pathname);
|
|
55655
|
+
if (syncedPathname !== pathname) {
|
|
55656
|
+
setSyncedPathname(pathname);
|
|
55657
|
+
if (routeExpanded) setOpen(true);
|
|
55658
|
+
}
|
|
55659
|
+
const active = isActive(item);
|
|
55660
|
+
const isGroup = !!item.items?.length;
|
|
55661
|
+
const highlighted = !active && isGroup && open;
|
|
55662
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
55663
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
55664
|
+
MenuItem,
|
|
55665
|
+
{
|
|
55666
|
+
item,
|
|
55667
|
+
active,
|
|
55668
|
+
highlighted,
|
|
55669
|
+
expanded: isGroup ? open : void 0,
|
|
55670
|
+
sub: level >= 1,
|
|
55671
|
+
collapsed: false,
|
|
55672
|
+
onClick: () => {
|
|
55673
|
+
if (isGroup) setOpen((value) => !value);
|
|
55674
|
+
onItemClick?.(item);
|
|
55675
|
+
}
|
|
55676
|
+
}
|
|
55677
|
+
),
|
|
55678
|
+
isGroup && /* @__PURE__ */ jsxRuntime.jsx(material.Collapse, { in: open, children: /* @__PURE__ */ jsxRuntime.jsx(MenuListFull, { items: item.items, onItemClick, level: level + 1 }) })
|
|
55679
|
+
] });
|
|
55680
|
+
};
|
|
55681
|
+
const MenuListFull = ({ items, level, onItemClick }) => {
|
|
55634
55682
|
const theme = material.useTheme();
|
|
55635
55683
|
const isSub = level >= 1;
|
|
55636
55684
|
const lineColor = varAlpha(theme.palette.grey["500Channel"], 0.32);
|
|
@@ -55651,9 +55699,7 @@ const MenuListFull = ({ items, level, onItemClick }) => {
|
|
|
55651
55699
|
position: isSub ? "relative" : void 0
|
|
55652
55700
|
},
|
|
55653
55701
|
children: items.map((item, index) => {
|
|
55654
|
-
|
|
55655
|
-
const highlighted = !active && !!item.items?.length && isExpanded(item);
|
|
55656
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
55702
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
55657
55703
|
material.ListItem,
|
|
55658
55704
|
{
|
|
55659
55705
|
disableGutters: true,
|
|
@@ -55684,22 +55730,7 @@ const MenuListFull = ({ items, level, onItemClick }) => {
|
|
|
55684
55730
|
}
|
|
55685
55731
|
}
|
|
55686
55732
|
},
|
|
55687
|
-
children:
|
|
55688
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
55689
|
-
MenuItem,
|
|
55690
|
-
{
|
|
55691
|
-
item,
|
|
55692
|
-
active,
|
|
55693
|
-
highlighted,
|
|
55694
|
-
sub: isSub,
|
|
55695
|
-
collapsed: false,
|
|
55696
|
-
onClick: () => {
|
|
55697
|
-
onItemClick?.(item);
|
|
55698
|
-
}
|
|
55699
|
-
}
|
|
55700
|
-
),
|
|
55701
|
-
item.items && /* @__PURE__ */ jsxRuntime.jsx(material.Collapse, { in: isExpanded(item), children: /* @__PURE__ */ jsxRuntime.jsx(MenuListFull, { items: item.items, onItemClick, level: level + 1 }) })
|
|
55702
|
-
]
|
|
55733
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(MenuListFullItem, { item, level, onItemClick })
|
|
55703
55734
|
},
|
|
55704
55735
|
index
|
|
55705
55736
|
);
|