@officesdk/design 0.1.14 → 0.1.16

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.
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var React3 = require('react');
4
+ var ReactDOM = require('react-dom');
5
+ var designTheme = require('@officesdk/design-theme');
4
6
  var baseStyled = require('styled-components');
5
7
  var RcTooltip = require('rc-tooltip');
6
8
  require('rc-tooltip/assets/bootstrap.css');
@@ -9,17 +11,16 @@ var VirtualList = require('rc-virtual-list');
9
11
  require('rc-menu/assets/index.css');
10
12
  var RcDropdown = require('rc-dropdown');
11
13
  require('rc-dropdown/assets/index.css');
12
- var ReactDOM = require('react-dom');
13
14
 
14
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
16
 
16
17
  var React3__default = /*#__PURE__*/_interopDefault(React3);
18
+ var ReactDOM__default = /*#__PURE__*/_interopDefault(ReactDOM);
17
19
  var baseStyled__default = /*#__PURE__*/_interopDefault(baseStyled);
18
20
  var RcTooltip__default = /*#__PURE__*/_interopDefault(RcTooltip);
19
21
  var RcMenu__default = /*#__PURE__*/_interopDefault(RcMenu);
20
22
  var VirtualList__default = /*#__PURE__*/_interopDefault(VirtualList);
21
23
  var RcDropdown__default = /*#__PURE__*/_interopDefault(RcDropdown);
22
- var ReactDOM__default = /*#__PURE__*/_interopDefault(ReactDOM);
23
24
 
24
25
  var __defProp = Object.defineProperty;
25
26
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -46,11 +47,54 @@ var init_IconProvider = __esm({
46
47
  exports.IconProvider.displayName = "IconProvider";
47
48
  }
48
49
  });
50
+ var globalConfig, globalIconRegistry, globalToastConfig, createDefaultRenderFunction; exports.initUIConfig = void 0; exports.getUIConfig = void 0; exports.getGlobalIconRegistry = void 0; exports.getGlobalToastConfig = void 0;
51
+ var init_configManager = __esm({
52
+ "src/UIConfigProvider/configManager.ts"() {
53
+ init_context();
54
+ globalConfig = null;
55
+ globalIconRegistry = null;
56
+ globalToastConfig = null;
57
+ createDefaultRenderFunction = () => {
58
+ return (element, container) => {
59
+ if ("createRoot" in ReactDOM__default.default) {
60
+ const { createRoot } = ReactDOM__default.default;
61
+ const root = createRoot(container);
62
+ root.render(element);
63
+ } else {
64
+ ReactDOM__default.default.render(element, container);
65
+ }
66
+ };
67
+ };
68
+ exports.initUIConfig = (config) => {
69
+ globalConfig = config;
70
+ const renderFunction = createDefaultRenderFunction();
71
+ registerGlobalContext({
72
+ theme: config.theme,
73
+ render: renderFunction
74
+ });
75
+ globalIconRegistry = config.icons || null;
76
+ globalToastConfig = {
77
+ maxCount: config.toast?.maxCount ?? 5,
78
+ defaultDuration: config.toast?.defaultDuration ?? 3e3
79
+ };
80
+ };
81
+ exports.getUIConfig = () => {
82
+ return globalConfig;
83
+ };
84
+ exports.getGlobalIconRegistry = () => {
85
+ return globalIconRegistry;
86
+ };
87
+ exports.getGlobalToastConfig = () => {
88
+ return globalToastConfig;
89
+ };
90
+ }
91
+ });
49
92
  var IconContainer; exports.Icon = void 0;
50
93
  var init_Icon = __esm({
51
94
  "src/Icon/Icon.tsx"() {
52
95
  init_styled();
53
96
  init_IconProvider();
97
+ init_configManager();
54
98
  IconContainer = exports.styled.span`
55
99
  display: inline-flex;
56
100
  align-items: center;
@@ -78,7 +122,9 @@ var init_Icon = __esm({
78
122
  style,
79
123
  onClick
80
124
  }) => {
81
- const registry = exports.useIconRegistry();
125
+ const contextRegistry = exports.useIconRegistry();
126
+ const globalRegistry = exports.getGlobalIconRegistry();
127
+ const registry = contextRegistry || globalRegistry;
82
128
  let iconElement = children;
83
129
  if (!iconElement && src) {
84
130
  iconElement = /* @__PURE__ */ React3__default.default.createElement(
@@ -95,7 +141,9 @@ var init_Icon = __esm({
95
141
  if (IconComponent) {
96
142
  iconElement = /* @__PURE__ */ React3__default.default.createElement(IconComponent, null);
97
143
  } else if (process.env.NODE_ENV !== "production") {
98
- console.warn(`Icon "${name}" not found in registry. Make sure IconProvider is set up.`);
144
+ console.warn(
145
+ `Icon "${name}" not found in registry. Make sure IconProvider is set up or call initUIConfig() with icons.`
146
+ );
99
147
  }
100
148
  }
101
149
  if (!iconElement) {
@@ -523,14 +571,36 @@ var context_exports = {};
523
571
  __export(context_exports, {
524
572
  getGlobalRenderFunction: () => getGlobalRenderFunction,
525
573
  getGlobalTheme: () => exports.getGlobalTheme,
526
- registerGlobalContext: () => registerGlobalContext
574
+ registerGlobalContext: () => registerGlobalContext,
575
+ registerGlobalTheme: () => registerGlobalTheme
527
576
  });
577
+ function deepMerge(target, ...sources) {
578
+ if (!sources.length) return target;
579
+ const source = sources.shift();
580
+ if (isObject(target) && isObject(source)) {
581
+ for (const key in source) {
582
+ if (isObject(source[key])) {
583
+ if (!target[key]) Object.assign(target, { [key]: {} });
584
+ deepMerge(target[key], source[key]);
585
+ } else {
586
+ Object.assign(target, { [key]: source[key] });
587
+ }
588
+ }
589
+ }
590
+ return deepMerge(target, ...sources);
591
+ }
592
+ function isObject(item) {
593
+ return item && typeof item === "object" && !Array.isArray(item);
594
+ }
528
595
  var globalTheme, registerGlobalTheme; exports.getGlobalTheme = void 0; var globalRenderFunction, getGlobalRenderFunction, registerGlobalContext;
529
596
  var init_context = __esm({
530
597
  "src/utils/context.ts"() {
531
- globalTheme = {};
598
+ globalTheme = designTheme.lightTheme;
532
599
  registerGlobalTheme = (theme3) => {
533
- Object.assign(globalTheme, { ...globalTheme, ...theme3 });
600
+ deepMerge(
601
+ globalTheme,
602
+ theme3
603
+ );
534
604
  };
535
605
  exports.getGlobalTheme = () => {
536
606
  return globalTheme;
@@ -1152,7 +1222,7 @@ var init_NumberInput = __esm({
1152
1222
  DownArrow = () => /* @__PURE__ */ React3__default.default.createElement("svg", { viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React3__default.default.createElement("path", { d: "M7 9.5L3.5 5.5H10.5L7 9.5Z", fill: "currentColor" }));
1153
1223
  exports.NumberInput = ({
1154
1224
  value: controlledValue,
1155
- defaultValue = 0,
1225
+ defaultValue,
1156
1226
  min = -Infinity,
1157
1227
  max = Infinity,
1158
1228
  step = 1,
@@ -1163,6 +1233,7 @@ var init_NumberInput = __esm({
1163
1233
  formatter,
1164
1234
  parser,
1165
1235
  unit,
1236
+ placeholder,
1166
1237
  onChange,
1167
1238
  className,
1168
1239
  style
@@ -1174,6 +1245,9 @@ var init_NumberInput = __esm({
1174
1245
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
1175
1246
  const formatValue = React3.useCallback(
1176
1247
  (val) => {
1248
+ if (val === void 0) {
1249
+ return "";
1250
+ }
1177
1251
  if (formatter) {
1178
1252
  return formatter(val);
1179
1253
  }
@@ -1201,6 +1275,9 @@ var init_NumberInput = __esm({
1201
1275
  }, [value, isFocused, formatValue]);
1202
1276
  const clampValue = React3.useCallback(
1203
1277
  (val) => {
1278
+ if (val === void 0) {
1279
+ return void 0;
1280
+ }
1204
1281
  return Math.max(min, Math.min(max, val));
1205
1282
  },
1206
1283
  [min, max]
@@ -1217,27 +1294,39 @@ var init_NumberInput = __esm({
1217
1294
  );
1218
1295
  const increment = React3.useCallback(() => {
1219
1296
  if (disabled) return;
1220
- handleValueChange(value + step);
1297
+ const currentValue = value ?? 0;
1298
+ handleValueChange(currentValue + step);
1221
1299
  }, [disabled, value, step, handleValueChange]);
1222
1300
  const decrement = React3.useCallback(() => {
1223
1301
  if (disabled) return;
1224
- handleValueChange(value - step);
1302
+ const currentValue = value ?? 0;
1303
+ handleValueChange(currentValue - step);
1225
1304
  }, [disabled, value, step, handleValueChange]);
1226
1305
  const handleInputChange = React3.useCallback((e) => {
1227
1306
  setDisplayValue(e.target.value);
1228
1307
  }, []);
1229
1308
  const handleBlur = React3.useCallback(() => {
1230
1309
  setIsFocused(false);
1231
- const parsed = parseValue(displayValue);
1232
- if (parsed !== null) {
1233
- handleValueChange(parsed);
1310
+ const trimmedValue = displayValue.trim();
1311
+ if (trimmedValue === "") {
1312
+ handleValueChange(void 0);
1313
+ setDisplayValue("");
1234
1314
  } else {
1235
- setDisplayValue(formatValue(value));
1315
+ const parsed = parseValue(trimmedValue);
1316
+ if (parsed !== null) {
1317
+ handleValueChange(parsed);
1318
+ } else {
1319
+ setDisplayValue(formatValue(value));
1320
+ }
1236
1321
  }
1237
1322
  }, [displayValue, parseValue, handleValueChange, value, formatValue]);
1238
1323
  const handleFocus = React3.useCallback(() => {
1239
1324
  setIsFocused(true);
1240
- setDisplayValue(String(value));
1325
+ if (value !== void 0) {
1326
+ setDisplayValue(String(value));
1327
+ } else {
1328
+ setDisplayValue("");
1329
+ }
1241
1330
  }, [value]);
1242
1331
  const handleKeyDown = React3.useCallback(
1243
1332
  (e) => {
@@ -1274,6 +1363,7 @@ var init_NumberInput = __esm({
1274
1363
  onBlur: handleBlur,
1275
1364
  onKeyDown: handleKeyDown,
1276
1365
  disabled,
1366
+ placeholder,
1277
1367
  $size: size,
1278
1368
  $disabled: disabled
1279
1369
  }
@@ -1332,7 +1422,7 @@ var init_SpinButton = __esm({
1332
1422
  display: flex;
1333
1423
  align-items: center;
1334
1424
  padding: ${({ $size }) => $size === "small" ? "7px 0" : "7px 0"};
1335
- padding-right: ${({ $size }) => $size === "small" ? "83px" : "72px"};
1425
+ padding-right: ${({ $size }) => $size === "small" ? "8px" : "8px"};
1336
1426
  min-width: 0;
1337
1427
  `;
1338
1428
  exports.SpinButton = ({
@@ -1355,8 +1445,12 @@ var init_SpinButton = __esm({
1355
1445
  const [internalValue, setInternalValue] = React3.useState(controlledValue ?? defaultValue);
1356
1446
  const value = controlledValue !== void 0 ? controlledValue : internalValue;
1357
1447
  const handleValueChange = React3.useCallback(
1358
- (newValue) => {
1359
- if (newValue === null) return;
1448
+ (fixedValue, rawValue) => {
1449
+ const newValue = rawValue === void 0 ? fixedValue ?? 0 : fixedValue ?? 0;
1450
+ if (newValue === null) {
1451
+ onChange?.(null);
1452
+ return;
1453
+ }
1360
1454
  if (controlledValue === void 0) {
1361
1455
  setInternalValue(newValue);
1362
1456
  }
@@ -2666,34 +2760,6 @@ var Tabs = ({
2666
2760
  ))));
2667
2761
  };
2668
2762
  Tabs.displayName = "Tab";
2669
- var Tooltip = ({
2670
- content,
2671
- variant = "black",
2672
- size = "small",
2673
- children,
2674
- placement = "top",
2675
- trigger = ["hover"],
2676
- overlay,
2677
- overlayClassName,
2678
- getPopupContainer,
2679
- ...rest
2680
- }) => {
2681
- const overlayContent = React3__default.default.useMemo(() => /* @__PURE__ */ React3__default.default.createElement("div", null, content), [content]);
2682
- const variantClass = `tooltip-variant-${variant}`;
2683
- const sizeClass = variant === "white" ? `tooltip-size-${size}` : "";
2684
- const combinedClassName = [variantClass, sizeClass, overlayClassName].filter(Boolean).join(" ");
2685
- const tooltipProps = {
2686
- overlay: overlay ?? overlayContent,
2687
- placement,
2688
- trigger,
2689
- destroyTooltipOnHide: false,
2690
- overlayClassName: combinedClassName,
2691
- ...getPopupContainer && { getPopupContainer },
2692
- ...rest
2693
- };
2694
- return /* @__PURE__ */ React3__default.default.createElement(RcTooltip__default.default, { ...tooltipProps, prefixCls: "od-tooltip" }, children);
2695
- };
2696
- Tooltip.displayName = "Tooltip";
2697
2763
 
2698
2764
  // src/Tooltip/globalStyle.ts
2699
2765
  init_context();
@@ -3027,6 +3093,86 @@ var TooltipGlobalStyles = baseStyled.createGlobalStyle`
3027
3093
  }
3028
3094
  `;
3029
3095
 
3096
+ // src/utils/styleManager.ts
3097
+ init_context();
3098
+ var injectedStyles = /* @__PURE__ */ new Set();
3099
+ var styleManager = {
3100
+ /**
3101
+ * Inject global styles on demand
3102
+ * @param id Unique identifier for the style (e.g., 'od-tooltip-styles')
3103
+ * @param StyleComponent The styled component to inject
3104
+ */
3105
+ inject: (id, StyleComponent) => {
3106
+ if (injectedStyles.has(id) || typeof document === "undefined") {
3107
+ return;
3108
+ }
3109
+ if (document.getElementById(id)) {
3110
+ injectedStyles.add(id);
3111
+ return;
3112
+ }
3113
+ const renderFunction = getGlobalRenderFunction();
3114
+ if (!renderFunction) {
3115
+ console.warn(
3116
+ `Style injection failed for "${id}": render function not available. Please call initUIConfig() or use UIConfigProvider first.`
3117
+ );
3118
+ return;
3119
+ }
3120
+ const container = document.createElement("div");
3121
+ container.id = id;
3122
+ document.head.appendChild(container);
3123
+ renderFunction(
3124
+ React3__default.default.createElement(StyleComponent),
3125
+ container
3126
+ );
3127
+ injectedStyles.add(id);
3128
+ },
3129
+ /**
3130
+ * Check if styles have been injected
3131
+ */
3132
+ isInjected: (id) => {
3133
+ return injectedStyles.has(id) || typeof document !== "undefined" && !!document.getElementById(id);
3134
+ },
3135
+ /**
3136
+ * Reset injected styles (mainly for testing)
3137
+ */
3138
+ reset: () => {
3139
+ injectedStyles.clear();
3140
+ }
3141
+ };
3142
+
3143
+ // src/Tooltip/Tooltip.tsx
3144
+ var Tooltip = ({
3145
+ content,
3146
+ variant = "black",
3147
+ size = "small",
3148
+ children,
3149
+ placement = "top",
3150
+ trigger = ["hover"],
3151
+ overlay,
3152
+ overlayClassName,
3153
+ getPopupContainer,
3154
+ ...rest
3155
+ }) => {
3156
+ React3.useEffect(() => {
3157
+ styleManager.inject("od-tooltip-styles", TooltipGlobalStyles);
3158
+ }, []);
3159
+ const overlayContent = React3__default.default.useMemo(() => /* @__PURE__ */ React3__default.default.createElement("div", null, content), [content]);
3160
+ const variantClass = `tooltip-variant-${variant}`;
3161
+ const sizeClass = variant === "white" ? `tooltip-size-${size}` : "";
3162
+ const combinedClassName = [variantClass, sizeClass, overlayClassName].filter(Boolean).join(" ");
3163
+ const tooltipProps = {
3164
+ overlay: overlay ?? overlayContent,
3165
+ placement,
3166
+ trigger,
3167
+ destroyTooltipOnHide: false,
3168
+ overlayClassName: combinedClassName,
3169
+ ...getPopupContainer && { getPopupContainer },
3170
+ ...rest
3171
+ };
3172
+ return /* @__PURE__ */ React3__default.default.createElement(RcTooltip__default.default, { ...tooltipProps, prefixCls: "od-tooltip" }, children);
3173
+ };
3174
+ Tooltip.displayName = "Tooltip";
3175
+
3030
3176
  // src/ToolbarButton/ToolbarButton.tsx
3031
3177
  init_styled();
3032
3178
  var ToolbarButtonContainer = exports.styled.div`
@@ -3394,6 +3540,7 @@ var DropdownButtonContainer = exports.styled.button`
3394
3540
  padding: ${sizeConfig.padding};
3395
3541
  gap: ${sizeConfig.gap};
3396
3542
  font-size: ${sizeConfig.fontSize};
3543
+ border-radius: ${sizeConfig.borderRadius};
3397
3544
  `;
3398
3545
  }}
3399
3546
 
@@ -3405,7 +3552,6 @@ var DropdownButtonContainer = exports.styled.button`
3405
3552
  background = config.background.disabled;
3406
3553
  }
3407
3554
  let border = "none";
3408
- const borderRadius = config.borderRadius || "4px";
3409
3555
  if ($variant === "framed") {
3410
3556
  const borderColor = $error ? theme3.colors?.palettes?.red?.["6"] : theme3.colors?.palettes?.transparency?.["10"];
3411
3557
  border = `1px solid ${borderColor}`;
@@ -3414,7 +3560,6 @@ var DropdownButtonContainer = exports.styled.button`
3414
3560
  return `
3415
3561
  background: ${background};
3416
3562
  border: ${border};
3417
- border-radius: ${borderRadius};
3418
3563
  color: ${color};
3419
3564
 
3420
3565
  &:hover:not(:disabled) {
@@ -3578,501 +3723,110 @@ DropdownButton2.displayName = "DropdownButton";
3578
3723
  // src/dropdown/Menu.tsx
3579
3724
  init_styled();
3580
3725
  init_Icon2();
3581
- var MenuContainer = exports.styled.div`
3582
- display: flex;
3583
- flex-direction: column;
3584
- box-sizing: border-box;
3585
- min-width: 220px;
3586
3726
 
3587
- ${({ theme: theme3 }) => {
3588
- const dropdownConfig = theme3.components?.dropdown;
3589
- const menuConfig = theme3.components?.menu;
3590
- return `
3591
- background: ${dropdownConfig?.background || "#fff"};
3592
- border: ${menuConfig?.border?.width || "1px"} solid ${menuConfig?.border?.color || "rgba(65, 70, 75, 0.1)"};
3593
- border-radius: ${menuConfig?.border?.radius || "4px"};
3594
- box-shadow: ${dropdownConfig?.boxShadow || "0 2px 8px rgba(0, 0, 0, 0.15)"};
3595
- `;
3596
- }}
3727
+ // src/dropdown/globalStyle.ts
3728
+ init_context();
3729
+ var theme2 = exports.getGlobalTheme();
3730
+ var DropdownGlobalStyles = baseStyled.createGlobalStyle`
3731
+ /* Dropdown container */
3732
+ .od-dropdown {
3733
+ position: absolute;
3734
+ z-index: 1050;
3735
+ }
3597
3736
 
3598
- /* Ensure virtual list container has proper width */
3599
- .rc-virtual-list {
3600
- width: 100%;
3737
+ .od-dropdown-hidden {
3738
+ display: none;
3601
3739
  }
3602
3740
 
3603
- .rc-virtual-list-holder {
3604
- width: 100%;
3741
+ /* Dropdown slide animations */
3742
+ .od-dropdown-slide-up-enter,
3743
+ .od-dropdown-slide-up-appear {
3744
+ animation-duration: 0.2s;
3745
+ animation-fill-mode: both;
3746
+ animation-play-state: paused;
3605
3747
  }
3606
3748
 
3607
- .rc-virtual-list-holder-inner {
3608
- width: 100%;
3749
+ .od-dropdown-slide-up-leave {
3750
+ animation-duration: 0.2s;
3751
+ animation-fill-mode: both;
3752
+ animation-play-state: paused;
3753
+ }
3754
+
3755
+ .od-dropdown-slide-up-enter.od-dropdown-slide-up-enter-active,
3756
+ .od-dropdown-slide-up-appear.od-dropdown-slide-up-appear-active {
3757
+ animation-name: rcDropdownSlideUpIn;
3758
+ animation-play-state: running;
3759
+ }
3760
+
3761
+ .od-dropdown-slide-up-leave.od-dropdown-slide-up-leave-active {
3762
+ animation-name: rcDropdownSlideUpOut;
3763
+ animation-play-state: running;
3764
+ }
3765
+
3766
+ @keyframes rcDropdownSlideUpIn {
3767
+ 0% {
3768
+ opacity: 0;
3769
+ transform: scaleY(0.8);
3770
+ }
3771
+ 100% {
3772
+ opacity: 1;
3773
+ transform: scaleY(1);
3774
+ }
3775
+ }
3776
+
3777
+ @keyframes rcDropdownSlideUpOut {
3778
+ 0% {
3779
+ opacity: 1;
3780
+ transform: scaleY(1);
3781
+ }
3782
+ 100% {
3783
+ opacity: 0;
3784
+ transform: scaleY(0.8);
3785
+ }
3609
3786
  }
3610
3787
  `;
3611
- var SearchBoxContainer = exports.styled.div`
3612
- padding: 8px 12px;
3613
- border-bottom: 1px solid ${({ theme: theme3 }) => theme3.colors?.palettes?.transparency?.["10"]};
3614
- `;
3615
- var SearchIcon = () => /* @__PURE__ */ React3__default.default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ React3__default.default.createElement(
3616
- "path",
3617
- {
3618
- d: "M7.33333 12.6667C10.2789 12.6667 12.6667 10.2789 12.6667 7.33333C12.6667 4.38781 10.2789 2 7.33333 2C4.38781 2 2 4.38781 2 7.33333C2 10.2789 4.38781 12.6667 7.33333 12.6667Z",
3619
- stroke: "currentColor",
3620
- strokeWidth: "1.5",
3621
- strokeLinecap: "round",
3622
- strokeLinejoin: "round"
3788
+ var MenuGlobalStyles = baseStyled.createGlobalStyle`
3789
+ /* Base menu container */
3790
+ .od-menu {
3791
+ margin: 0;
3792
+ padding: ${() => theme2.components?.dropdown?.padding || "4px 0"};
3793
+ list-style: none;
3794
+ outline: none;
3795
+ box-shadow: none;
3796
+ background: transparent;
3797
+ border: none;
3623
3798
  }
3624
- ), /* @__PURE__ */ React3__default.default.createElement(
3625
- "path",
3626
- {
3627
- d: "M14 14L11.1 11.1",
3628
- stroke: "currentColor",
3629
- strokeWidth: "1.5",
3630
- strokeLinecap: "round",
3631
- strokeLinejoin: "round"
3799
+
3800
+ .od-menu-hidden {
3801
+ display: none;
3632
3802
  }
3633
- ));
3634
- var MenuItemContent = exports.styled.div`
3635
- display: flex;
3636
- align-items: center;
3637
- width: 100%;
3638
3803
 
3639
- ${({ theme: theme3 }) => {
3640
- const config = theme3.components?.menu?.menuItem;
3804
+ /* Menu item */
3805
+ .od-menu-item {
3806
+ position: relative;
3807
+ display: flex;
3808
+ align-items: center;
3809
+ margin: 0;
3810
+ cursor: pointer;
3811
+ transition: background-color 0.15s ease;
3812
+ user-select: none;
3813
+ list-style: none;
3814
+
3815
+ ${() => {
3816
+ const config = theme2.components?.menu?.menuItem;
3641
3817
  return `
3642
- gap: ${config?.layout?.gap || "8px"};
3643
- `;
3818
+ padding: ${config?.layout?.padding || "6px 12px"};
3819
+ background: ${config?.background?.normal || "transparent"};
3820
+ `;
3644
3821
  }}
3645
- `;
3646
- var IconContainer2 = exports.styled.div`
3647
- display: flex;
3648
- align-items: center;
3649
- justify-content: center;
3650
- flex-shrink: 0;
3822
+ }
3651
3823
 
3652
- ${({ theme: theme3 }) => {
3653
- const iconSize = theme3.components?.menu?.menuItem?.icon?.size;
3824
+ .od-menu-item:hover {
3825
+ ${() => {
3826
+ const config = theme2.components?.menu?.menuItem;
3654
3827
  return `
3655
- width: ${iconSize?.width || "18px"};
3656
- height: ${iconSize?.height || "18px"};
3657
-
3658
- svg, img {
3659
- width: 100%;
3660
- height: 100%;
3661
- }
3662
- `;
3663
- }}
3664
- `;
3665
- var ContentBlock2 = exports.styled.div`
3666
- display: flex;
3667
- flex: 1;
3668
- align-items: center;
3669
- justify-content: space-between;
3670
- gap: 16px;
3671
- min-width: 0;
3672
- `;
3673
- var LabelText2 = exports.styled.div`
3674
- flex: 1;
3675
- min-width: 0;
3676
- overflow: hidden;
3677
- text-overflow: ellipsis;
3678
- white-space: nowrap;
3679
- line-height: 20px;
3680
-
3681
- ${({ $size, $disabled, theme: theme3 }) => {
3682
- const config = theme3.components?.menu?.menuItem;
3683
- const sizeConfig = config?.size?.[$size];
3684
- const colorConfig = config?.label?.color;
3685
- const fontSize = sizeConfig?.label?.fontSize || "13px";
3686
- const color = $disabled ? colorConfig?.disabled || "rgba(65, 70, 75, 0.3)" : colorConfig?.normal || "#41464b";
3687
- return `
3688
- font-size: ${fontSize};
3689
- color: ${color};
3690
- `;
3691
- }}
3692
- `;
3693
- var DescriptionText = exports.styled.div`
3694
- flex: 0 0 auto;
3695
- white-space: nowrap;
3696
- line-height: 20px;
3697
- text-align: right;
3698
-
3699
- ${({ $size, $disabled, theme: theme3 }) => {
3700
- const config = theme3.components?.menu?.menuItem;
3701
- const sizeConfig = config?.size?.[$size];
3702
- const colorConfig = config?.description?.color;
3703
- const fontSize = sizeConfig?.description?.fontSize || "10px";
3704
- const color = $disabled ? colorConfig?.disabled || "rgba(65, 70, 75, 0.3)" : colorConfig?.normal || "rgba(65, 70, 75, 0.6)";
3705
- return `
3706
- font-size: ${fontSize};
3707
- color: ${color};
3708
- `;
3709
- }}
3710
- `;
3711
- var ActiveIconContainer = exports.styled.div`
3712
- display: flex;
3713
- align-items: center;
3714
- justify-content: center;
3715
- flex-shrink: 0;
3716
-
3717
- ${({ $size, theme: theme3 }) => {
3718
- const sizeConfig = theme3.components?.menu?.menuItem?.size?.[$size];
3719
- const iconSize = sizeConfig?.activeIcon?.size;
3720
- return `
3721
- width: ${iconSize?.width || "18px"};
3722
- height: ${iconSize?.height || "18px"};
3723
- `;
3724
- }}
3725
-
3726
- ${({ $visible, $placeholder }) => {
3727
- if (!$visible && !$placeholder) {
3728
- return "display: none;";
3729
- }
3730
- if ($placeholder && !$visible) {
3731
- return "visibility: hidden;";
3732
- }
3733
- return "";
3734
- }}
3735
- `;
3736
- var NextLevelIconContainer = exports.styled.div`
3737
- display: flex;
3738
- align-items: center;
3739
- justify-content: center;
3740
- flex-shrink: 0;
3741
-
3742
- ${({ $size, theme: theme3 }) => {
3743
- const sizeConfig = theme3.components?.menu?.menuItem?.size?.[$size];
3744
- const iconSize = sizeConfig?.nextLevelIcon?.size;
3745
- return `
3746
- width: ${iconSize?.width || "18px"};
3747
- height: ${iconSize?.height || "18px"};
3748
- `;
3749
- }}
3750
- `;
3751
- var CheckmarkIcon = () => /* @__PURE__ */ React3__default.default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" }, /* @__PURE__ */ React3__default.default.createElement(
3752
- "path",
3753
- {
3754
- d: "M14.25 5.25L7.125 12.375L3.75 9",
3755
- stroke: "#41464B",
3756
- strokeWidth: "1.5",
3757
- strokeLinecap: "round",
3758
- strokeLinejoin: "round"
3759
- }
3760
- ));
3761
- var ArrowIcon2 = () => /* @__PURE__ */ React3__default.default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" }, /* @__PURE__ */ React3__default.default.createElement(
3762
- "path",
3763
- {
3764
- d: "M6.75 4.5L11.25 9L6.75 13.5",
3765
- stroke: "#41464B",
3766
- strokeWidth: "1.5",
3767
- strokeLinecap: "round",
3768
- strokeLinejoin: "round"
3769
- }
3770
- ));
3771
- var Menu = ({
3772
- items,
3773
- selectedKeys = [],
3774
- openKeys,
3775
- size = "large",
3776
- searchable = false,
3777
- searchPlaceholder = "Enter search content",
3778
- maxHeight = 300,
3779
- virtual = false,
3780
- reserveActiveIconSpace = true,
3781
- onSelect,
3782
- onSearch,
3783
- onOpenChange,
3784
- className,
3785
- style
3786
- }) => {
3787
- const [searchValue, setSearchValue] = React3.useState("");
3788
- const handleSearch = (value) => {
3789
- setSearchValue(value);
3790
- onSearch?.(value);
3791
- };
3792
- const filteredItems = React3.useMemo(() => {
3793
- if (!searchValue) return items;
3794
- const searchLower = searchValue.toLowerCase();
3795
- const filterMenuItem = (item) => {
3796
- if (item.label.toLowerCase().includes(searchLower) || item.description?.toLowerCase().includes(searchLower)) {
3797
- return item;
3798
- }
3799
- if (item.children && item.children.length > 0) {
3800
- const filteredChildren = item.children.map((child) => filterMenuItem(child)).filter(Boolean);
3801
- if (filteredChildren.length > 0) {
3802
- return { ...item, children: filteredChildren };
3803
- }
3804
- }
3805
- return null;
3806
- };
3807
- const filterItem = (item) => {
3808
- if (item.type === "divider") return null;
3809
- if (item.type === "group") {
3810
- const filteredChildren = item.children.map((child) => filterMenuItem(child)).filter(Boolean);
3811
- if (filteredChildren.length > 0) {
3812
- return { ...item, children: filteredChildren };
3813
- }
3814
- return null;
3815
- }
3816
- return filterMenuItem(item);
3817
- };
3818
- return items.map((item) => filterItem(item)).filter(Boolean);
3819
- }, [items, searchValue]);
3820
- const renderMenuItemContent = (item, reserveSpace) => {
3821
- const isSelected = item.selected || selectedKeys.includes(item.key);
3822
- const isSelectable = item.selectable !== false;
3823
- const shouldShowActiveIcon = isSelectable && isSelected;
3824
- const shouldReserveSpace = reserveSpace || isSelectable;
3825
- const iconElement = item.icon ? /* @__PURE__ */ React3__default.default.createElement(IconContainer2, { $size: size }, typeof item.icon === "string" ? /* @__PURE__ */ React3__default.default.createElement(exports.Icon, { src: item.icon }) : item.icon) : null;
3826
- return /* @__PURE__ */ React3__default.default.createElement(MenuItemContent, { $size: size }, iconElement, /* @__PURE__ */ React3__default.default.createElement(ContentBlock2, null, /* @__PURE__ */ React3__default.default.createElement(LabelText2, { $size: size, $disabled: !!item.disabled }, item.label), item.description && /* @__PURE__ */ React3__default.default.createElement(DescriptionText, { $size: size, $disabled: !!item.disabled }, item.description)), /* @__PURE__ */ React3__default.default.createElement(
3827
- ActiveIconContainer,
3828
- {
3829
- $size: size,
3830
- $visible: shouldShowActiveIcon,
3831
- $placeholder: shouldReserveSpace && !shouldShowActiveIcon
3832
- },
3833
- shouldShowActiveIcon && /* @__PURE__ */ React3__default.default.createElement(CheckmarkIcon, null)
3834
- ), item.children && item.children.length > 0 && /* @__PURE__ */ React3__default.default.createElement(NextLevelIconContainer, { $size: size }, /* @__PURE__ */ React3__default.default.createElement(ArrowIcon2, null)));
3835
- };
3836
- const renderItem = (item) => {
3837
- if (item.type === "divider") {
3838
- return /* @__PURE__ */ React3__default.default.createElement(RcMenu.Divider, { key: item.key });
3839
- }
3840
- if (item.type === "group") {
3841
- return /* @__PURE__ */ React3__default.default.createElement(RcMenu.ItemGroup, { key: item.key, title: item.label }, item.children.map((child) => renderMenuItem(child)));
3842
- }
3843
- return renderMenuItem(item);
3844
- };
3845
- const renderMenuItem = (item) => {
3846
- if (item.children && item.children.length > 0) {
3847
- return /* @__PURE__ */ React3__default.default.createElement(
3848
- RcMenu.SubMenu,
3849
- {
3850
- key: item.key,
3851
- title: renderMenuItemContent(item, reserveActiveIconSpace),
3852
- disabled: item.disabled,
3853
- popupOffset: [5, 0]
3854
- },
3855
- item.children.map((child) => renderMenuItem(child))
3856
- );
3857
- }
3858
- return /* @__PURE__ */ React3__default.default.createElement(
3859
- RcMenu.MenuItem,
3860
- {
3861
- key: item.key,
3862
- disabled: item.disabled,
3863
- onClick: () => {
3864
- item.onClick?.(item.key);
3865
- onSelect?.(item.key);
3866
- }
3867
- },
3868
- renderMenuItemContent(item, reserveActiveIconSpace)
3869
- );
3870
- };
3871
- const itemHeight = size === "medium" ? 28 : 36;
3872
- const menuKey = openKeys?.join(",") || "menu";
3873
- return /* @__PURE__ */ React3__default.default.createElement(MenuContainer, { className, style }, searchable && /* @__PURE__ */ React3__default.default.createElement(SearchBoxContainer, null, /* @__PURE__ */ React3__default.default.createElement(
3874
- Input,
3875
- {
3876
- lineType: "underlined",
3877
- size: "small",
3878
- placeholder: searchPlaceholder,
3879
- value: searchValue,
3880
- onChange: (e) => handleSearch(e.target.value),
3881
- clearable: true,
3882
- onClear: () => handleSearch(""),
3883
- prefixNode: /* @__PURE__ */ React3__default.default.createElement(SearchIcon, null)
3884
- }
3885
- )), virtual && filteredItems.length > 10 ? /* @__PURE__ */ React3__default.default.createElement(
3886
- VirtualList__default.default,
3887
- {
3888
- data: filteredItems,
3889
- height: maxHeight,
3890
- itemHeight,
3891
- itemKey: "key",
3892
- fullHeight: false,
3893
- style: { width: "100%" }
3894
- },
3895
- (item) => /* @__PURE__ */ React3__default.default.createElement(
3896
- RcMenu__default.default,
3897
- {
3898
- key: menuKey,
3899
- prefixCls: "od-menu",
3900
- mode: "vertical",
3901
- selectedKeys,
3902
- openKeys,
3903
- onOpenChange,
3904
- triggerSubMenuAction: "hover",
3905
- expandIcon: null,
3906
- style: {
3907
- border: "none",
3908
- background: "transparent",
3909
- padding: 0
3910
- }
3911
- },
3912
- renderItem(item)
3913
- )
3914
- ) : /* @__PURE__ */ React3__default.default.createElement(
3915
- RcMenu__default.default,
3916
- {
3917
- key: menuKey,
3918
- prefixCls: "od-menu",
3919
- mode: "vertical",
3920
- selectedKeys,
3921
- openKeys,
3922
- onOpenChange,
3923
- triggerSubMenuAction: "hover",
3924
- expandIcon: null,
3925
- style: {
3926
- border: "none",
3927
- background: "transparent"
3928
- }
3929
- },
3930
- filteredItems.map(renderItem)
3931
- ));
3932
- };
3933
- Menu.displayName = "Menu";
3934
- var Dropdown = ({
3935
- overlay,
3936
- trigger = ["click"],
3937
- placement = "bottomLeft",
3938
- visible: controlledVisible,
3939
- defaultVisible = false,
3940
- onVisibleChange,
3941
- children,
3942
- overlayClassName,
3943
- getPopupContainer,
3944
- ...rest
3945
- }) => {
3946
- const [internalVisible, setInternalVisible] = React3.useState(defaultVisible);
3947
- const isControlled = controlledVisible !== void 0;
3948
- const isVisible = isControlled ? controlledVisible : internalVisible;
3949
- const handleVisibleChange = (visible) => {
3950
- if (!isControlled) {
3951
- setInternalVisible(visible);
3952
- }
3953
- onVisibleChange?.(visible);
3954
- };
3955
- return /* @__PURE__ */ React3__default.default.createElement(
3956
- RcDropdown__default.default,
3957
- {
3958
- overlay: overlay || /* @__PURE__ */ React3__default.default.createElement("div", null),
3959
- trigger,
3960
- placement,
3961
- visible: isVisible,
3962
- onVisibleChange: handleVisibleChange,
3963
- prefixCls: "od-dropdown",
3964
- overlayClassName,
3965
- getPopupContainer,
3966
- ...rest
3967
- },
3968
- children
3969
- );
3970
- };
3971
- Dropdown.displayName = "Dropdown";
3972
-
3973
- // src/dropdown/globalStyle.ts
3974
- init_context();
3975
- var theme2 = exports.getGlobalTheme();
3976
- var DropdownGlobalStyles = baseStyled.createGlobalStyle`
3977
- /* Dropdown container */
3978
- .od-dropdown {
3979
- position: absolute;
3980
- z-index: 1050;
3981
- }
3982
-
3983
- .od-dropdown-hidden {
3984
- display: none;
3985
- }
3986
-
3987
- /* Dropdown slide animations */
3988
- .od-dropdown-slide-up-enter,
3989
- .od-dropdown-slide-up-appear {
3990
- animation-duration: 0.2s;
3991
- animation-fill-mode: both;
3992
- animation-play-state: paused;
3993
- }
3994
-
3995
- .od-dropdown-slide-up-leave {
3996
- animation-duration: 0.2s;
3997
- animation-fill-mode: both;
3998
- animation-play-state: paused;
3999
- }
4000
-
4001
- .od-dropdown-slide-up-enter.od-dropdown-slide-up-enter-active,
4002
- .od-dropdown-slide-up-appear.od-dropdown-slide-up-appear-active {
4003
- animation-name: rcDropdownSlideUpIn;
4004
- animation-play-state: running;
4005
- }
4006
-
4007
- .od-dropdown-slide-up-leave.od-dropdown-slide-up-leave-active {
4008
- animation-name: rcDropdownSlideUpOut;
4009
- animation-play-state: running;
4010
- }
4011
-
4012
- @keyframes rcDropdownSlideUpIn {
4013
- 0% {
4014
- opacity: 0;
4015
- transform: scaleY(0.8);
4016
- }
4017
- 100% {
4018
- opacity: 1;
4019
- transform: scaleY(1);
4020
- }
4021
- }
4022
-
4023
- @keyframes rcDropdownSlideUpOut {
4024
- 0% {
4025
- opacity: 1;
4026
- transform: scaleY(1);
4027
- }
4028
- 100% {
4029
- opacity: 0;
4030
- transform: scaleY(0.8);
4031
- }
4032
- }
4033
- `;
4034
- var MenuGlobalStyles = baseStyled.createGlobalStyle`
4035
- /* Base menu container */
4036
- .od-menu {
4037
- margin: 0;
4038
- padding: ${() => theme2.components?.dropdown?.padding || "4px 0"};
4039
- list-style: none;
4040
- outline: none;
4041
- box-shadow: none;
4042
- background: transparent;
4043
- border: none;
4044
- }
4045
-
4046
- .od-menu-hidden {
4047
- display: none;
4048
- }
4049
-
4050
- /* Menu item */
4051
- .od-menu-item {
4052
- position: relative;
4053
- display: flex;
4054
- align-items: center;
4055
- margin: 0;
4056
- cursor: pointer;
4057
- transition: background-color 0.15s ease;
4058
- user-select: none;
4059
- list-style: none;
4060
-
4061
- ${() => {
4062
- const config = theme2.components?.menu?.menuItem;
4063
- return `
4064
- padding: ${config?.layout?.padding || "6px 12px"};
4065
- background: ${config?.background?.normal || "transparent"};
4066
- `;
4067
- }}
4068
- }
4069
-
4070
- .od-menu-item:hover {
4071
- ${() => {
4072
- const config = theme2.components?.menu?.menuItem;
4073
- return `
4074
- background: ${config?.background?.hover || "rgba(65, 70, 75, 0.05)"};
4075
- `;
3828
+ background: ${config?.background?.hover || "rgba(65, 70, 75, 0.05)"};
3829
+ `;
4076
3830
  }}
4077
3831
  }
4078
3832
 
@@ -4245,38 +3999,438 @@ var MenuGlobalStyles = baseStyled.createGlobalStyle`
4245
3999
  transition: max-height 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
4246
4000
  }
4247
4001
 
4248
- .od-menu-submenu-inline-collapsed-active {
4249
- max-height: 1000px;
4250
- }
4002
+ .od-menu-submenu-inline-collapsed-active {
4003
+ max-height: 1000px;
4004
+ }
4005
+ `;
4006
+
4007
+ // src/dropdown/Menu.tsx
4008
+ var MenuContainer = exports.styled.div`
4009
+ display: flex;
4010
+ flex-direction: column;
4011
+ box-sizing: border-box;
4012
+ min-width: 220px;
4013
+
4014
+ ${({ theme: theme3 }) => {
4015
+ const dropdownConfig = theme3.components?.dropdown;
4016
+ const menuConfig = theme3.components?.menu;
4017
+ return `
4018
+ background: ${dropdownConfig?.background || "#fff"};
4019
+ border: ${menuConfig?.border?.width || "1px"} solid ${menuConfig?.border?.color || "rgba(65, 70, 75, 0.1)"};
4020
+ border-radius: ${menuConfig?.border?.radius || "4px"};
4021
+ box-shadow: ${dropdownConfig?.boxShadow || "0 2px 8px rgba(0, 0, 0, 0.15)"};
4022
+ `;
4023
+ }}
4024
+
4025
+ /* Ensure virtual list container has proper width */
4026
+ .rc-virtual-list {
4027
+ width: 100%;
4028
+ }
4029
+
4030
+ .rc-virtual-list-holder {
4031
+ width: 100%;
4032
+ }
4033
+
4034
+ .rc-virtual-list-holder-inner {
4035
+ width: 100%;
4036
+ }
4037
+ `;
4038
+ var SearchBoxContainer = exports.styled.div`
4039
+ padding: 8px 12px;
4040
+ border-bottom: 1px solid ${({ theme: theme3 }) => theme3.colors?.palettes?.transparency?.["10"]};
4041
+ `;
4042
+ var SearchIcon = () => /* @__PURE__ */ React3__default.default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ React3__default.default.createElement(
4043
+ "path",
4044
+ {
4045
+ d: "M7.33333 12.6667C10.2789 12.6667 12.6667 10.2789 12.6667 7.33333C12.6667 4.38781 10.2789 2 7.33333 2C4.38781 2 2 4.38781 2 7.33333C2 10.2789 4.38781 12.6667 7.33333 12.6667Z",
4046
+ stroke: "currentColor",
4047
+ strokeWidth: "1.5",
4048
+ strokeLinecap: "round",
4049
+ strokeLinejoin: "round"
4050
+ }
4051
+ ), /* @__PURE__ */ React3__default.default.createElement(
4052
+ "path",
4053
+ {
4054
+ d: "M14 14L11.1 11.1",
4055
+ stroke: "currentColor",
4056
+ strokeWidth: "1.5",
4057
+ strokeLinecap: "round",
4058
+ strokeLinejoin: "round"
4059
+ }
4060
+ ));
4061
+ var MenuItemContent = exports.styled.div`
4062
+ display: flex;
4063
+ align-items: center;
4064
+ width: 100%;
4065
+
4066
+ ${({ theme: theme3 }) => {
4067
+ const config = theme3.components?.menu?.menuItem;
4068
+ return `
4069
+ gap: ${config?.layout?.gap || "8px"};
4070
+ `;
4071
+ }}
4072
+ `;
4073
+ var IconContainer2 = exports.styled.div`
4074
+ display: flex;
4075
+ align-items: center;
4076
+ justify-content: center;
4077
+ flex-shrink: 0;
4078
+
4079
+ ${({ theme: theme3 }) => {
4080
+ const iconSize = theme3.components?.menu?.menuItem?.icon?.size;
4081
+ return `
4082
+ width: ${iconSize?.width || "18px"};
4083
+ height: ${iconSize?.height || "18px"};
4084
+
4085
+ svg, img {
4086
+ width: 100%;
4087
+ height: 100%;
4088
+ }
4089
+ `;
4090
+ }}
4091
+ `;
4092
+ var ContentBlock2 = exports.styled.div`
4093
+ display: flex;
4094
+ flex: 1;
4095
+ align-items: center;
4096
+ justify-content: space-between;
4097
+ gap: 16px;
4098
+ min-width: 0;
4099
+ `;
4100
+ var LabelText2 = exports.styled.div`
4101
+ flex: 1;
4102
+ min-width: 0;
4103
+ overflow: hidden;
4104
+ text-overflow: ellipsis;
4105
+ white-space: nowrap;
4106
+ line-height: 20px;
4107
+
4108
+ ${({ $size, $disabled, theme: theme3 }) => {
4109
+ const config = theme3.components?.menu?.menuItem;
4110
+ const sizeConfig = config?.size?.[$size];
4111
+ const colorConfig = config?.label?.color;
4112
+ const fontSize = sizeConfig?.label?.fontSize || "13px";
4113
+ const color = $disabled ? colorConfig?.disabled || "rgba(65, 70, 75, 0.3)" : colorConfig?.normal || "#41464b";
4114
+ return `
4115
+ font-size: ${fontSize};
4116
+ color: ${color};
4117
+ `;
4118
+ }}
4119
+ `;
4120
+ var DescriptionText = exports.styled.div`
4121
+ flex: 0 0 auto;
4122
+ white-space: nowrap;
4123
+ line-height: 20px;
4124
+ text-align: right;
4125
+
4126
+ ${({ $size, $disabled, theme: theme3 }) => {
4127
+ const config = theme3.components?.menu?.menuItem;
4128
+ const sizeConfig = config?.size?.[$size];
4129
+ const colorConfig = config?.description?.color;
4130
+ const fontSize = sizeConfig?.description?.fontSize || "10px";
4131
+ const color = $disabled ? colorConfig?.disabled || "rgba(65, 70, 75, 0.3)" : colorConfig?.normal || "rgba(65, 70, 75, 0.6)";
4132
+ return `
4133
+ font-size: ${fontSize};
4134
+ color: ${color};
4135
+ `;
4136
+ }}
4137
+ `;
4138
+ var ActiveIconContainer = exports.styled.div`
4139
+ display: flex;
4140
+ align-items: center;
4141
+ justify-content: center;
4142
+ flex-shrink: 0;
4143
+
4144
+ ${({ $size, theme: theme3 }) => {
4145
+ const sizeConfig = theme3.components?.menu?.menuItem?.size?.[$size];
4146
+ const iconSize = sizeConfig?.activeIcon?.size;
4147
+ return `
4148
+ width: ${iconSize?.width || "18px"};
4149
+ height: ${iconSize?.height || "18px"};
4150
+ `;
4151
+ }}
4152
+
4153
+ ${({ $visible, $placeholder }) => {
4154
+ if (!$visible && !$placeholder) {
4155
+ return "display: none;";
4156
+ }
4157
+ if ($placeholder && !$visible) {
4158
+ return "visibility: hidden;";
4159
+ }
4160
+ return "";
4161
+ }}
4162
+ `;
4163
+ var NextLevelIconContainer = exports.styled.div`
4164
+ display: flex;
4165
+ align-items: center;
4166
+ justify-content: center;
4167
+ flex-shrink: 0;
4168
+
4169
+ ${({ $size, theme: theme3 }) => {
4170
+ const sizeConfig = theme3.components?.menu?.menuItem?.size?.[$size];
4171
+ const iconSize = sizeConfig?.nextLevelIcon?.size;
4172
+ return `
4173
+ width: ${iconSize?.width || "18px"};
4174
+ height: ${iconSize?.height || "18px"};
4175
+ `;
4176
+ }}
4251
4177
  `;
4178
+ var CheckmarkIcon = () => /* @__PURE__ */ React3__default.default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" }, /* @__PURE__ */ React3__default.default.createElement(
4179
+ "path",
4180
+ {
4181
+ d: "M14.25 5.25L7.125 12.375L3.75 9",
4182
+ stroke: "#41464B",
4183
+ strokeWidth: "1.5",
4184
+ strokeLinecap: "round",
4185
+ strokeLinejoin: "round"
4186
+ }
4187
+ ));
4188
+ var ArrowIcon2 = () => /* @__PURE__ */ React3__default.default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none" }, /* @__PURE__ */ React3__default.default.createElement(
4189
+ "path",
4190
+ {
4191
+ d: "M6.75 4.5L11.25 9L6.75 13.5",
4192
+ stroke: "#41464B",
4193
+ strokeWidth: "1.5",
4194
+ strokeLinecap: "round",
4195
+ strokeLinejoin: "round"
4196
+ }
4197
+ ));
4198
+ var Menu = ({
4199
+ items,
4200
+ selectedKeys = [],
4201
+ openKeys,
4202
+ size = "large",
4203
+ searchable = false,
4204
+ searchPlaceholder = "Enter search content",
4205
+ maxHeight = 300,
4206
+ virtual = false,
4207
+ reserveActiveIconSpace = true,
4208
+ onSelect,
4209
+ onSearch,
4210
+ onOpenChange,
4211
+ className,
4212
+ style
4213
+ }) => {
4214
+ React3.useEffect(() => {
4215
+ styleManager.inject("od-menu-styles", MenuGlobalStyles);
4216
+ }, []);
4217
+ const [searchValue, setSearchValue] = React3.useState("");
4218
+ const handleSearch = (value) => {
4219
+ setSearchValue(value);
4220
+ onSearch?.(value);
4221
+ };
4222
+ const filteredItems = React3.useMemo(() => {
4223
+ if (!searchValue) return items;
4224
+ const searchLower = searchValue.toLowerCase();
4225
+ const filterMenuItem = (item) => {
4226
+ if (item.label.toLowerCase().includes(searchLower) || item.description?.toLowerCase().includes(searchLower)) {
4227
+ return item;
4228
+ }
4229
+ if (item.children && item.children.length > 0) {
4230
+ const filteredChildren = item.children.map((child) => filterMenuItem(child)).filter(Boolean);
4231
+ if (filteredChildren.length > 0) {
4232
+ return { ...item, children: filteredChildren };
4233
+ }
4234
+ }
4235
+ return null;
4236
+ };
4237
+ const filterItem = (item) => {
4238
+ if (item.type === "divider") return null;
4239
+ if (item.type === "group") {
4240
+ const filteredChildren = item.children.map((child) => filterMenuItem(child)).filter(Boolean);
4241
+ if (filteredChildren.length > 0) {
4242
+ return { ...item, children: filteredChildren };
4243
+ }
4244
+ return null;
4245
+ }
4246
+ return filterMenuItem(item);
4247
+ };
4248
+ return items.map((item) => filterItem(item)).filter(Boolean);
4249
+ }, [items, searchValue]);
4250
+ const renderMenuItemContent = (item, reserveSpace) => {
4251
+ const isSelected = item.selected || selectedKeys.includes(item.key);
4252
+ const isSelectable = item.selectable !== false;
4253
+ const shouldShowActiveIcon = isSelectable && isSelected;
4254
+ const shouldReserveSpace = reserveSpace || isSelectable;
4255
+ const iconElement = item.icon ? /* @__PURE__ */ React3__default.default.createElement(IconContainer2, { $size: size }, typeof item.icon === "string" ? /* @__PURE__ */ React3__default.default.createElement(exports.Icon, { src: item.icon }) : item.icon) : null;
4256
+ return /* @__PURE__ */ React3__default.default.createElement(MenuItemContent, { $size: size }, iconElement, /* @__PURE__ */ React3__default.default.createElement(ContentBlock2, null, /* @__PURE__ */ React3__default.default.createElement(LabelText2, { $size: size, $disabled: !!item.disabled }, item.label), item.description && /* @__PURE__ */ React3__default.default.createElement(DescriptionText, { $size: size, $disabled: !!item.disabled }, item.description)), /* @__PURE__ */ React3__default.default.createElement(
4257
+ ActiveIconContainer,
4258
+ {
4259
+ $size: size,
4260
+ $visible: shouldShowActiveIcon,
4261
+ $placeholder: shouldReserveSpace && !shouldShowActiveIcon
4262
+ },
4263
+ shouldShowActiveIcon && /* @__PURE__ */ React3__default.default.createElement(CheckmarkIcon, null)
4264
+ ), item.children && item.children.length > 0 && /* @__PURE__ */ React3__default.default.createElement(NextLevelIconContainer, { $size: size }, /* @__PURE__ */ React3__default.default.createElement(ArrowIcon2, null)));
4265
+ };
4266
+ const renderItem = (item) => {
4267
+ if (item.type === "divider") {
4268
+ return /* @__PURE__ */ React3__default.default.createElement(RcMenu.Divider, { key: item.key });
4269
+ }
4270
+ if (item.type === "group") {
4271
+ return /* @__PURE__ */ React3__default.default.createElement(RcMenu.ItemGroup, { key: item.key, title: item.label }, item.children.map((child) => renderMenuItem(child)));
4272
+ }
4273
+ return renderMenuItem(item);
4274
+ };
4275
+ const renderMenuItem = (item) => {
4276
+ if (item.children && item.children.length > 0) {
4277
+ return /* @__PURE__ */ React3__default.default.createElement(
4278
+ RcMenu.SubMenu,
4279
+ {
4280
+ key: item.key,
4281
+ title: renderMenuItemContent(item, reserveActiveIconSpace),
4282
+ disabled: item.disabled,
4283
+ popupOffset: [5, 0]
4284
+ },
4285
+ item.children.map((child) => renderMenuItem(child))
4286
+ );
4287
+ }
4288
+ return /* @__PURE__ */ React3__default.default.createElement(
4289
+ RcMenu.MenuItem,
4290
+ {
4291
+ key: item.key,
4292
+ disabled: item.disabled,
4293
+ onClick: () => {
4294
+ item.onClick?.(item.key);
4295
+ onSelect?.(item.key);
4296
+ }
4297
+ },
4298
+ renderMenuItemContent(item, reserveActiveIconSpace)
4299
+ );
4300
+ };
4301
+ const itemHeight = size === "medium" ? 28 : 36;
4302
+ const menuKey = openKeys?.join(",") || "menu";
4303
+ return /* @__PURE__ */ React3__default.default.createElement(MenuContainer, { className, style }, searchable && /* @__PURE__ */ React3__default.default.createElement(SearchBoxContainer, null, /* @__PURE__ */ React3__default.default.createElement(
4304
+ Input,
4305
+ {
4306
+ lineType: "underlined",
4307
+ size: "small",
4308
+ placeholder: searchPlaceholder,
4309
+ value: searchValue,
4310
+ onChange: (e) => handleSearch(e.target.value),
4311
+ clearable: true,
4312
+ onClear: () => handleSearch(""),
4313
+ prefixNode: /* @__PURE__ */ React3__default.default.createElement(SearchIcon, null)
4314
+ }
4315
+ )), virtual && filteredItems.length > 10 ? /* @__PURE__ */ React3__default.default.createElement(
4316
+ VirtualList__default.default,
4317
+ {
4318
+ data: filteredItems,
4319
+ height: maxHeight,
4320
+ itemHeight,
4321
+ itemKey: "key",
4322
+ fullHeight: false,
4323
+ style: { width: "100%" }
4324
+ },
4325
+ (item) => /* @__PURE__ */ React3__default.default.createElement(
4326
+ RcMenu__default.default,
4327
+ {
4328
+ key: menuKey,
4329
+ prefixCls: "od-menu",
4330
+ mode: "vertical",
4331
+ selectedKeys,
4332
+ openKeys,
4333
+ onOpenChange,
4334
+ triggerSubMenuAction: "hover",
4335
+ expandIcon: null,
4336
+ style: {
4337
+ border: "none",
4338
+ background: "transparent",
4339
+ padding: 0
4340
+ }
4341
+ },
4342
+ renderItem(item)
4343
+ )
4344
+ ) : /* @__PURE__ */ React3__default.default.createElement(
4345
+ RcMenu__default.default,
4346
+ {
4347
+ key: menuKey,
4348
+ prefixCls: "od-menu",
4349
+ mode: "vertical",
4350
+ selectedKeys,
4351
+ openKeys,
4352
+ onOpenChange,
4353
+ triggerSubMenuAction: "hover",
4354
+ expandIcon: null,
4355
+ style: {
4356
+ border: "none",
4357
+ background: "transparent"
4358
+ }
4359
+ },
4360
+ filteredItems.map(renderItem)
4361
+ ));
4362
+ };
4363
+ Menu.displayName = "Menu";
4364
+ var Dropdown = ({
4365
+ overlay,
4366
+ trigger = ["click"],
4367
+ placement = "bottomLeft",
4368
+ visible: controlledVisible,
4369
+ defaultVisible = false,
4370
+ onVisibleChange,
4371
+ children,
4372
+ overlayClassName,
4373
+ getPopupContainer,
4374
+ ...rest
4375
+ }) => {
4376
+ React3.useEffect(() => {
4377
+ styleManager.inject("od-dropdown-styles", DropdownGlobalStyles);
4378
+ }, []);
4379
+ const [internalVisible, setInternalVisible] = React3.useState(defaultVisible);
4380
+ const isControlled = controlledVisible !== void 0;
4381
+ const isVisible = isControlled ? controlledVisible : internalVisible;
4382
+ const handleVisibleChange = (visible) => {
4383
+ if (!isControlled) {
4384
+ setInternalVisible(visible);
4385
+ }
4386
+ onVisibleChange?.(visible);
4387
+ };
4388
+ return /* @__PURE__ */ React3__default.default.createElement(
4389
+ RcDropdown__default.default,
4390
+ {
4391
+ overlay: overlay || /* @__PURE__ */ React3__default.default.createElement("div", null),
4392
+ trigger,
4393
+ placement,
4394
+ visible: isVisible,
4395
+ onVisibleChange: handleVisibleChange,
4396
+ prefixCls: "od-dropdown",
4397
+ overlayClassName,
4398
+ getPopupContainer,
4399
+ ...rest
4400
+ },
4401
+ children
4402
+ );
4403
+ };
4404
+ Dropdown.displayName = "Dropdown";
4252
4405
 
4253
4406
  // src/UIConfigProvider/UIConfigProvider.tsx
4254
4407
  init_IconProvider();
4408
+ init_configManager();
4255
4409
  init_context();
4256
4410
  var UIConfigContext = React3.createContext(null);
4257
4411
  var UIConfigProvider = ({ config, children }) => {
4258
- const { icons = {}, toast: toast2 = {} } = config;
4259
- const renderFunction = (element, container) => {
4260
- if ("createRoot" in ReactDOM__default.default) {
4261
- const { createRoot } = ReactDOM__default.default;
4262
- const root = createRoot(container);
4263
- root.render(element);
4264
- } else {
4265
- ReactDOM__default.default.render(element, container);
4266
- }
4267
- };
4268
- registerGlobalContext({
4269
- theme: config.theme,
4270
- render: renderFunction
4271
- });
4412
+ React3.useEffect(() => {
4413
+ const renderFunction = (element, container) => {
4414
+ if ("createRoot" in ReactDOM__default.default) {
4415
+ const { createRoot } = ReactDOM__default.default;
4416
+ const root = createRoot(container);
4417
+ root.render(element);
4418
+ } else {
4419
+ ReactDOM__default.default.render(element, container);
4420
+ }
4421
+ };
4422
+ registerGlobalContext({
4423
+ theme: config.theme,
4424
+ render: renderFunction
4425
+ });
4426
+ exports.initUIConfig(config);
4427
+ }, [config]);
4428
+ const { icons = {} } = config;
4272
4429
  const toastConfig = {
4273
- maxCount: toast2.maxCount ?? 5,
4274
- defaultDuration: toast2.defaultDuration ?? 3e3
4430
+ maxCount: config.toast?.maxCount ?? 5,
4431
+ defaultDuration: config.toast?.defaultDuration ?? 3e3
4275
4432
  };
4276
- const TooltipStyles = TooltipGlobalStyles;
4277
- const MenuStyles = MenuGlobalStyles;
4278
- const DropdownStyles = DropdownGlobalStyles;
4279
- return /* @__PURE__ */ React3__default.default.createElement(UIConfigContext.Provider, { value: config }, /* @__PURE__ */ React3__default.default.createElement(TooltipStyles, null), /* @__PURE__ */ React3__default.default.createElement(MenuStyles, null), /* @__PURE__ */ React3__default.default.createElement(DropdownStyles, null), /* @__PURE__ */ React3__default.default.createElement(exports.IconProvider, { icons }, /* @__PURE__ */ React3__default.default.createElement(
4433
+ return /* @__PURE__ */ React3__default.default.createElement(UIConfigContext.Provider, { value: config }, /* @__PURE__ */ React3__default.default.createElement(exports.IconProvider, { icons }, /* @__PURE__ */ React3__default.default.createElement(
4280
4434
  ToastContainer2,
4281
4435
  {
4282
4436
  maxCount: toastConfig.maxCount,
@@ -4287,10 +4441,7 @@ var UIConfigProvider = ({ config, children }) => {
4287
4441
  };
4288
4442
  var useUIConfig = () => {
4289
4443
  const context = React3.useContext(UIConfigContext);
4290
- if (!context) {
4291
- throw new Error("useUIConfig must be used within UIConfigProvider");
4292
- }
4293
- return context;
4444
+ return context || exports.getUIConfig();
4294
4445
  };
4295
4446
  UIConfigProvider.displayName = "UIConfigProvider";
4296
4447
 
@@ -4361,6 +4512,9 @@ var mergeUIConfig = (baseConfig, ...configs) => {
4361
4512
  return merged;
4362
4513
  };
4363
4514
 
4515
+ // src/UIConfigProvider/index.ts
4516
+ init_configManager();
4517
+
4364
4518
  // src/index.ts
4365
4519
  init_styled();
4366
4520
  init_context();