ding-react-admin 2.0.8 → 2.0.9

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 (69) hide show
  1. package/dist/index.css +1 -1
  2. package/dist/index.js +1564 -1139
  3. package/dist/src/crud/InlineFormSet.d.ts +6 -2
  4. package/dist/src/crud/InlineFormSet.d.ts.map +1 -1
  5. package/dist/src/crud/ResourceList.d.ts +6 -1
  6. package/dist/src/crud/ResourceList.d.ts.map +1 -1
  7. package/dist/src/crud/context/FilterContext.d.ts +4 -1
  8. package/dist/src/crud/context/FilterContext.d.ts.map +1 -1
  9. package/dist/src/crud/fields/BooleanField.d.ts +2 -1
  10. package/dist/src/crud/fields/BooleanField.d.ts.map +1 -1
  11. package/dist/src/crud/fields/DateField.d.ts.map +1 -1
  12. package/dist/src/crud/fields/DateTimeField.d.ts +5 -0
  13. package/dist/src/crud/fields/DateTimeField.d.ts.map +1 -0
  14. package/dist/src/crud/fields/ReferenceField.d.ts +3 -1
  15. package/dist/src/crud/fields/ReferenceField.d.ts.map +1 -1
  16. package/dist/src/crud/fields/ReferenceManyField.d.ts +4 -1
  17. package/dist/src/crud/fields/ReferenceManyField.d.ts.map +1 -1
  18. package/dist/src/crud/fields/TextAreaField.d.ts +19 -0
  19. package/dist/src/crud/fields/TextAreaField.d.ts.map +1 -0
  20. package/dist/src/crud/fields/TimeField.d.ts +11 -0
  21. package/dist/src/crud/fields/TimeField.d.ts.map +1 -0
  22. package/dist/src/crud/filters/ReferenceFilter.d.ts +1 -1
  23. package/dist/src/crud/filters/ReferenceFilter.d.ts.map +1 -1
  24. package/dist/src/crud/filters/TextFilter.d.ts +9 -1
  25. package/dist/src/crud/filters/TextFilter.d.ts.map +1 -1
  26. package/dist/src/crud/index.d.ts +6 -1
  27. package/dist/src/crud/index.d.ts.map +1 -1
  28. package/dist/src/crud/types.d.ts +9 -0
  29. package/dist/src/crud/types.d.ts.map +1 -1
  30. package/dist/src/crud/utils/parseDayjsValue.d.ts +3 -0
  31. package/dist/src/crud/utils/parseDayjsValue.d.ts.map +1 -0
  32. package/dist/src/crud/utils/referenceSelectDropdownProps.d.ts +11 -0
  33. package/dist/src/crud/utils/referenceSelectDropdownProps.d.ts.map +1 -0
  34. package/dist/src/crud/utils/useDebouncedValue.d.ts +3 -0
  35. package/dist/src/crud/utils/useDebouncedValue.d.ts.map +1 -0
  36. package/dist/src/index.d.ts +3 -3
  37. package/dist/src/index.d.ts.map +1 -1
  38. package/dist/src/layouts/AdminLayout.d.ts +1 -1
  39. package/dist/src/layouts/AdminLayout.d.ts.map +1 -1
  40. package/dist/src/layouts/navMenuItems.d.ts +3 -0
  41. package/dist/src/layouts/navMenuItems.d.ts.map +1 -1
  42. package/dist/src/types.d.ts +16 -0
  43. package/dist/src/types.d.ts.map +1 -1
  44. package/package.json +1 -1
  45. package/src/components/NavMenuLabel.tsx +1 -1
  46. package/src/components/navMenu.css +107 -0
  47. package/src/context/AppThemeProvider.tsx +1 -1
  48. package/src/crud/InlineFormSet.tsx +32 -14
  49. package/src/crud/ResourceList.tsx +211 -35
  50. package/src/crud/context/FilterContext.tsx +7 -1
  51. package/src/crud/fields/BooleanField.tsx +3 -1
  52. package/src/crud/fields/DateField.tsx +6 -4
  53. package/src/crud/fields/DateTimeField.tsx +9 -0
  54. package/src/crud/fields/ReferenceField.tsx +10 -0
  55. package/src/crud/fields/ReferenceManyField.tsx +13 -1
  56. package/src/crud/fields/TextAreaField.tsx +58 -0
  57. package/src/crud/fields/TimeField.tsx +48 -0
  58. package/src/crud/filters/ReferenceFilter.tsx +10 -0
  59. package/src/crud/filters/TextFilter.tsx +80 -9
  60. package/src/crud/index.ts +9 -1
  61. package/src/crud/resourceListTable.css +113 -0
  62. package/src/crud/types.ts +9 -0
  63. package/src/crud/utils/parseDayjsValue.ts +14 -0
  64. package/src/crud/utils/referenceSelectDropdownProps.ts +30 -0
  65. package/src/crud/utils/useDebouncedValue.ts +17 -0
  66. package/src/index.ts +7 -0
  67. package/src/layouts/AdminLayout.tsx +43 -6
  68. package/src/layouts/navMenuItems.tsx +11 -2
  69. package/src/types.ts +17 -0
@@ -29,7 +29,7 @@ import {
29
29
  } from "./navFilter";
30
30
  import { navItemsToAntdItems } from "./navMenuItems";
31
31
  import { filterNavByPermission } from "../permissions/resourcePermissions";
32
- import type { AdminLayoutProps, NavItem } from "../types";
32
+ import type { AdminLayoutProps, NavItem, NavMenuItemDivider } from "../types";
33
33
  import "../components/navMenu.css";
34
34
 
35
35
  const LIGHT_SIDEBAR_BG = "#001529";
@@ -87,15 +87,36 @@ type NavMenuProps = {
87
87
  openKeys?: string[];
88
88
  onOpenChange?: (keys: string[]) => void;
89
89
  onNavigate: (key: string) => void;
90
+ wrapLabels?: boolean;
91
+ itemDivider?: NavMenuItemDivider;
90
92
  };
91
93
 
92
- type SiderNavPanelProps = NavMenuProps & {
94
+ function navMenuClassName({
95
+ wrapLabels,
96
+ itemDivider = "none",
97
+ }: {
98
+ wrapLabels?: boolean;
99
+ itemDivider?: NavMenuItemDivider;
100
+ }): string {
101
+ const classes = ["ding-admin-nav-menu"];
102
+ if (wrapLabels) classes.push("ding-admin-nav-menu--wrap-labels");
103
+ if (itemDivider === "full") {
104
+ classes.push("ding-admin-nav-menu--item-divider-full");
105
+ } else if (itemDivider === "inset") {
106
+ classes.push("ding-admin-nav-menu--item-divider-inset");
107
+ }
108
+ return classes.join(" ");
109
+ }
110
+
111
+ type SiderNavPanelProps = Omit<NavMenuProps, "wrapLabels" | "itemDivider"> & {
93
112
  navQuery: string;
94
113
  onNavQueryChange: (value: string) => void;
95
114
  showNavSearch: boolean;
96
115
  navSearchPlaceholder?: string;
97
116
  scrollVariant: "default" | "on-dark";
98
117
  searchVariant: "on-dark" | "app";
118
+ wrapLabels?: boolean;
119
+ itemDivider?: NavMenuItemDivider;
99
120
  };
100
121
 
101
122
  function SiderNavPanel({
@@ -111,6 +132,8 @@ function SiderNavPanel({
111
132
  navSearchPlaceholder,
112
133
  scrollVariant,
113
134
  searchVariant,
135
+ wrapLabels,
136
+ itemDivider,
114
137
  }: SiderNavPanelProps) {
115
138
  return (
116
139
  <>
@@ -138,6 +161,8 @@ function SiderNavPanel({
138
161
  openKeys={openKeys}
139
162
  onOpenChange={onOpenChange}
140
163
  onNavigate={onNavigate}
164
+ wrapLabels={wrapLabels}
165
+ itemDivider={itemDivider}
141
166
  />
142
167
  </ScrollableArea>
143
168
  </>
@@ -151,15 +176,17 @@ function NavMenu({
151
176
  openKeys,
152
177
  onOpenChange,
153
178
  onNavigate,
179
+ wrapLabels,
180
+ itemDivider,
154
181
  }: NavMenuProps) {
155
182
  return (
156
183
  <Menu
157
- className="ding-admin-nav-menu"
184
+ className={navMenuClassName({ wrapLabels, itemDivider })}
158
185
  mode="inline"
159
186
  theme="dark"
160
187
  inlineCollapsed={inlineCollapsed}
161
188
  selectedKeys={selectedKeys}
162
- tooltip={{ placement: "right", mouseEnterDelay: 1 }}
189
+ tooltip={{ placement: "right", mouseEnterDelay: 0 }}
163
190
  {...(!inlineCollapsed && openKeys !== undefined && onOpenChange
164
191
  ? { openKeys, onOpenChange }
165
192
  : {})}
@@ -181,6 +208,7 @@ export function AdminLayout({
181
208
  loginPath = "/login",
182
209
  siderCollapsedStorageKey = DEFAULT_SIDER_KEY,
183
210
  navSearch = true,
211
+ navMenu,
184
212
  }: AdminLayoutProps) {
185
213
  const navigate = useNavigate();
186
214
  const location = useLocation();
@@ -200,6 +228,9 @@ export function AdminLayout({
200
228
  const navSearchEnabled = navSearch !== false;
201
229
  const navSearchPlaceholder =
202
230
  typeof navSearch === "object" ? navSearch.placeholder : undefined;
231
+ const navMenuWrapLabels = navMenu?.wrapLabels !== false;
232
+ const navMenuItemDivider: NavMenuItemDivider =
233
+ navMenu?.itemDivider ?? "inset";
203
234
 
204
235
  const drawerTitle = mobileDrawerTitle ?? brand;
205
236
 
@@ -260,9 +291,11 @@ export function AdminLayout({
260
291
  const menuItems: MenuProps["items"] = useMemo(
261
292
  () =>
262
293
  navItemsToAntdItems(displayNavItems, {
263
- showLabelTooltip: !collapsed,
294
+ showLabelTooltip: !collapsed && !navMenuWrapLabels,
295
+ wrapLabels: navMenuWrapLabels && !collapsed,
296
+ collapsed,
264
297
  }),
265
- [displayNavItems, collapsed],
298
+ [displayNavItems, collapsed, navMenuWrapLabels],
266
299
  );
267
300
 
268
301
  const filteredOpenKeys = useMemo(
@@ -388,6 +421,8 @@ export function AdminLayout({
388
421
  navSearchPlaceholder={navSearchPlaceholder}
389
422
  scrollVariant={siderScrollVariant}
390
423
  searchVariant={siderSearchVariant}
424
+ wrapLabels={navMenuWrapLabels}
425
+ itemDivider={navMenuItemDivider}
391
426
  />
392
427
  </div>
393
428
  </Layout.Sider>
@@ -436,6 +471,8 @@ export function AdminLayout({
436
471
  navSearchPlaceholder={navSearchPlaceholder}
437
472
  scrollVariant={siderScrollVariant}
438
473
  searchVariant={siderSearchVariant}
474
+ wrapLabels={navMenuWrapLabels}
475
+ itemDivider={navMenuItemDivider}
439
476
  />
440
477
  </div>
441
478
  </Drawer>
@@ -5,9 +5,16 @@ import { getNavItemLabel } from "./navFilter";
5
5
 
6
6
  export function navItemsToAntdItems(
7
7
  items: NavItem[],
8
- options?: { showLabelTooltip?: boolean },
8
+ options?: {
9
+ showLabelTooltip?: boolean;
10
+ wrapLabels?: boolean;
11
+ /** Collapsed sider: native `title` for icon tooltips only. */
12
+ collapsed?: boolean;
13
+ },
9
14
  ): NonNullable<MenuProps["items"]> {
10
15
  const showLabelTooltip = options?.showLabelTooltip !== false;
16
+ const wrapLabels = options?.wrapLabels === true;
17
+ const collapsed = options?.collapsed === true;
11
18
 
12
19
  return items.map((item) => {
13
20
  const IconComp = item.Icon;
@@ -16,6 +23,8 @@ export function navItemsToAntdItems(
16
23
  const label =
17
24
  title && showLabelTooltip ? (
18
25
  <NavMenuLabel label={item.label} title={title} />
26
+ ) : wrapLabels ? (
27
+ <NavMenuLabel label={item.label} title="" />
19
28
  ) : (
20
29
  item.label
21
30
  );
@@ -23,7 +32,7 @@ export function navItemsToAntdItems(
23
32
  // Expanded: NavMenuLabel tooltip only (omit `title` to avoid native DOM tooltip).
24
33
  // Collapsed: string title for the sider icon tooltip.
25
34
  const itemTitle: { title?: string } =
26
- !showLabelTooltip && title ? { title } : {};
35
+ collapsed && title ? { title } : {};
27
36
 
28
37
  if (item.children?.length) {
29
38
  return {
package/src/types.ts CHANGED
@@ -66,6 +66,8 @@ export type AppThemeProviderProps = {
66
66
  densityStorageKey?: string;
67
67
  };
68
68
 
69
+ export type NavMenuItemDivider = "none" | "full" | "inset";
70
+
69
71
  export type AdminLayoutProps = {
70
72
  navItems: NavItem[];
71
73
  /** Shown in sider header when expanded; drawer title on mobile. */
@@ -87,6 +89,21 @@ export type AdminLayoutProps = {
87
89
  * Use an object to customize the placeholder.
88
90
  */
89
91
  navSearch?: boolean | { placeholder?: string };
92
+ /**
93
+ * Sidebar menu presentation.
94
+ */
95
+ navMenu?: {
96
+ /**
97
+ * Wrap long labels onto multiple lines instead of truncating with ellipsis.
98
+ * Default **`true`**. Pass **`false`** for ellipsis + Ant Design hover tooltip.
99
+ */
100
+ wrapLabels?: boolean;
101
+ /**
102
+ * Divider between sibling rows at each submenu level.
103
+ * Default **`"inset"`**.
104
+ */
105
+ itemDivider?: NavMenuItemDivider;
106
+ };
90
107
  };
91
108
 
92
109
  export type { AuthPageLayoutProps } from "./layouts/AuthPageLayout";