@officesdk/design 0.1.13 → 0.1.15

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,4 +1,6 @@
1
1
  import React3, { forwardRef, useState, createContext, useEffect, useRef, useCallback, useContext, useMemo } from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import { lightTheme } from '@officesdk/design-theme';
2
4
  import baseStyled, { createGlobalStyle } from 'styled-components';
3
5
  import RcTooltip from 'rc-tooltip';
4
6
  import 'rc-tooltip/assets/bootstrap.css';
@@ -7,7 +9,6 @@ import VirtualList from 'rc-virtual-list';
7
9
  import 'rc-menu/assets/index.css';
8
10
  import RcDropdown from 'rc-dropdown';
9
11
  import 'rc-dropdown/assets/index.css';
10
- import ReactDOM from 'react-dom';
11
12
 
12
13
  var __defProp = Object.defineProperty;
13
14
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -34,11 +35,54 @@ var init_IconProvider = __esm({
34
35
  IconProvider.displayName = "IconProvider";
35
36
  }
36
37
  });
38
+ var globalConfig, globalIconRegistry, globalToastConfig, createDefaultRenderFunction, initUIConfig, getUIConfig, getGlobalIconRegistry, getGlobalToastConfig;
39
+ var init_configManager = __esm({
40
+ "src/UIConfigProvider/configManager.ts"() {
41
+ init_context();
42
+ globalConfig = null;
43
+ globalIconRegistry = null;
44
+ globalToastConfig = null;
45
+ createDefaultRenderFunction = () => {
46
+ return (element, container) => {
47
+ if ("createRoot" in ReactDOM) {
48
+ const { createRoot } = ReactDOM;
49
+ const root = createRoot(container);
50
+ root.render(element);
51
+ } else {
52
+ ReactDOM.render(element, container);
53
+ }
54
+ };
55
+ };
56
+ initUIConfig = (config) => {
57
+ globalConfig = config;
58
+ const renderFunction = createDefaultRenderFunction();
59
+ registerGlobalContext({
60
+ theme: config.theme,
61
+ render: renderFunction
62
+ });
63
+ globalIconRegistry = config.icons || null;
64
+ globalToastConfig = {
65
+ maxCount: config.toast?.maxCount ?? 5,
66
+ defaultDuration: config.toast?.defaultDuration ?? 3e3
67
+ };
68
+ };
69
+ getUIConfig = () => {
70
+ return globalConfig;
71
+ };
72
+ getGlobalIconRegistry = () => {
73
+ return globalIconRegistry;
74
+ };
75
+ getGlobalToastConfig = () => {
76
+ return globalToastConfig;
77
+ };
78
+ }
79
+ });
37
80
  var IconContainer, Icon;
38
81
  var init_Icon = __esm({
39
82
  "src/Icon/Icon.tsx"() {
40
83
  init_styled();
41
84
  init_IconProvider();
85
+ init_configManager();
42
86
  IconContainer = styled.span`
43
87
  display: inline-flex;
44
88
  align-items: center;
@@ -66,7 +110,9 @@ var init_Icon = __esm({
66
110
  style,
67
111
  onClick
68
112
  }) => {
69
- const registry = useIconRegistry();
113
+ const contextRegistry = useIconRegistry();
114
+ const globalRegistry = getGlobalIconRegistry();
115
+ const registry = contextRegistry || globalRegistry;
70
116
  let iconElement = children;
71
117
  if (!iconElement && src) {
72
118
  iconElement = /* @__PURE__ */ React3.createElement(
@@ -83,7 +129,9 @@ var init_Icon = __esm({
83
129
  if (IconComponent) {
84
130
  iconElement = /* @__PURE__ */ React3.createElement(IconComponent, null);
85
131
  } else if (process.env.NODE_ENV !== "production") {
86
- console.warn(`Icon "${name}" not found in registry. Make sure IconProvider is set up.`);
132
+ console.warn(
133
+ `Icon "${name}" not found in registry. Make sure IconProvider is set up or call initUIConfig() with icons.`
134
+ );
87
135
  }
88
136
  }
89
137
  if (!iconElement) {
@@ -511,14 +559,33 @@ var context_exports = {};
511
559
  __export(context_exports, {
512
560
  getGlobalRenderFunction: () => getGlobalRenderFunction,
513
561
  getGlobalTheme: () => getGlobalTheme,
514
- registerGlobalContext: () => registerGlobalContext
562
+ registerGlobalContext: () => registerGlobalContext,
563
+ registerGlobalTheme: () => registerGlobalTheme
515
564
  });
565
+ function deepMerge(target, ...sources) {
566
+ if (!sources.length) return target;
567
+ const source = sources.shift();
568
+ if (isObject(target) && isObject(source)) {
569
+ for (const key in source) {
570
+ if (isObject(source[key])) {
571
+ if (!target[key]) Object.assign(target, { [key]: {} });
572
+ deepMerge(target[key], source[key]);
573
+ } else {
574
+ Object.assign(target, { [key]: source[key] });
575
+ }
576
+ }
577
+ }
578
+ return deepMerge(target, ...sources);
579
+ }
580
+ function isObject(item) {
581
+ return item && typeof item === "object" && !Array.isArray(item);
582
+ }
516
583
  var globalTheme, registerGlobalTheme, getGlobalTheme, globalRenderFunction, getGlobalRenderFunction, registerGlobalContext;
517
584
  var init_context = __esm({
518
585
  "src/utils/context.ts"() {
519
- globalTheme = {};
586
+ globalTheme = lightTheme;
520
587
  registerGlobalTheme = (theme3) => {
521
- Object.assign(globalTheme, { ...globalTheme, ...theme3 });
588
+ deepMerge(globalTheme, theme3);
522
589
  };
523
590
  getGlobalTheme = () => {
524
591
  return globalTheme;
@@ -2014,7 +2081,17 @@ var InputWrapper2 = styled.div`
2014
2081
  boxShadow = sizeConfig?.boxShadowActive || "none";
2015
2082
  }
2016
2083
  }
2017
- if ($lineType === "outlined") {
2084
+ if ($lineType === "borderless") {
2085
+ return `
2086
+ border: none;
2087
+ background: transparent;
2088
+ box-shadow: none;
2089
+
2090
+ &:hover:not(:disabled) {
2091
+ background: transparent;
2092
+ }
2093
+ `;
2094
+ } else if ($lineType === "outlined") {
2018
2095
  return `
2019
2096
  border: 1px solid ${borderColor};
2020
2097
  background: ${background};
@@ -2644,34 +2721,6 @@ var Tabs = ({
2644
2721
  ))));
2645
2722
  };
2646
2723
  Tabs.displayName = "Tab";
2647
- var Tooltip = ({
2648
- content,
2649
- variant = "black",
2650
- size = "small",
2651
- children,
2652
- placement = "top",
2653
- trigger = ["hover"],
2654
- overlay,
2655
- overlayClassName,
2656
- getPopupContainer,
2657
- ...rest
2658
- }) => {
2659
- const overlayContent = React3.useMemo(() => /* @__PURE__ */ React3.createElement("div", null, content), [content]);
2660
- const variantClass = `tooltip-variant-${variant}`;
2661
- const sizeClass = variant === "white" ? `tooltip-size-${size}` : "";
2662
- const combinedClassName = [variantClass, sizeClass, overlayClassName].filter(Boolean).join(" ");
2663
- const tooltipProps = {
2664
- overlay: overlay ?? overlayContent,
2665
- placement,
2666
- trigger,
2667
- destroyTooltipOnHide: false,
2668
- overlayClassName: combinedClassName,
2669
- ...getPopupContainer && { getPopupContainer },
2670
- ...rest
2671
- };
2672
- return /* @__PURE__ */ React3.createElement(RcTooltip, { ...tooltipProps, prefixCls: "od-tooltip" }, children);
2673
- };
2674
- Tooltip.displayName = "Tooltip";
2675
2724
 
2676
2725
  // src/Tooltip/globalStyle.ts
2677
2726
  init_context();
@@ -3005,6 +3054,86 @@ var TooltipGlobalStyles = createGlobalStyle`
3005
3054
  }
3006
3055
  `;
3007
3056
 
3057
+ // src/utils/styleManager.ts
3058
+ init_context();
3059
+ var injectedStyles = /* @__PURE__ */ new Set();
3060
+ var styleManager = {
3061
+ /**
3062
+ * Inject global styles on demand
3063
+ * @param id Unique identifier for the style (e.g., 'od-tooltip-styles')
3064
+ * @param StyleComponent The styled component to inject
3065
+ */
3066
+ inject: (id, StyleComponent) => {
3067
+ if (injectedStyles.has(id) || typeof document === "undefined") {
3068
+ return;
3069
+ }
3070
+ if (document.getElementById(id)) {
3071
+ injectedStyles.add(id);
3072
+ return;
3073
+ }
3074
+ const renderFunction = getGlobalRenderFunction();
3075
+ if (!renderFunction) {
3076
+ console.warn(
3077
+ `Style injection failed for "${id}": render function not available. Please call initUIConfig() or use UIConfigProvider first.`
3078
+ );
3079
+ return;
3080
+ }
3081
+ const container = document.createElement("div");
3082
+ container.id = id;
3083
+ document.head.appendChild(container);
3084
+ renderFunction(
3085
+ React3.createElement(StyleComponent),
3086
+ container
3087
+ );
3088
+ injectedStyles.add(id);
3089
+ },
3090
+ /**
3091
+ * Check if styles have been injected
3092
+ */
3093
+ isInjected: (id) => {
3094
+ return injectedStyles.has(id) || typeof document !== "undefined" && !!document.getElementById(id);
3095
+ },
3096
+ /**
3097
+ * Reset injected styles (mainly for testing)
3098
+ */
3099
+ reset: () => {
3100
+ injectedStyles.clear();
3101
+ }
3102
+ };
3103
+
3104
+ // src/Tooltip/Tooltip.tsx
3105
+ var Tooltip = ({
3106
+ content,
3107
+ variant = "black",
3108
+ size = "small",
3109
+ children,
3110
+ placement = "top",
3111
+ trigger = ["hover"],
3112
+ overlay,
3113
+ overlayClassName,
3114
+ getPopupContainer,
3115
+ ...rest
3116
+ }) => {
3117
+ useEffect(() => {
3118
+ styleManager.inject("od-tooltip-styles", TooltipGlobalStyles);
3119
+ }, []);
3120
+ const overlayContent = React3.useMemo(() => /* @__PURE__ */ React3.createElement("div", null, content), [content]);
3121
+ const variantClass = `tooltip-variant-${variant}`;
3122
+ const sizeClass = variant === "white" ? `tooltip-size-${size}` : "";
3123
+ const combinedClassName = [variantClass, sizeClass, overlayClassName].filter(Boolean).join(" ");
3124
+ const tooltipProps = {
3125
+ overlay: overlay ?? overlayContent,
3126
+ placement,
3127
+ trigger,
3128
+ destroyTooltipOnHide: false,
3129
+ overlayClassName: combinedClassName,
3130
+ ...getPopupContainer && { getPopupContainer },
3131
+ ...rest
3132
+ };
3133
+ return /* @__PURE__ */ React3.createElement(RcTooltip, { ...tooltipProps, prefixCls: "od-tooltip" }, children);
3134
+ };
3135
+ Tooltip.displayName = "Tooltip";
3136
+
3008
3137
  // src/ToolbarButton/ToolbarButton.tsx
3009
3138
  init_styled();
3010
3139
  var ToolbarButtonContainer = styled.div`
@@ -3372,6 +3501,7 @@ var DropdownButtonContainer = styled.button`
3372
3501
  padding: ${sizeConfig.padding};
3373
3502
  gap: ${sizeConfig.gap};
3374
3503
  font-size: ${sizeConfig.fontSize};
3504
+ border-radius: ${sizeConfig.borderRadius};
3375
3505
  `;
3376
3506
  }}
3377
3507
 
@@ -3383,7 +3513,6 @@ var DropdownButtonContainer = styled.button`
3383
3513
  background = config.background.disabled;
3384
3514
  }
3385
3515
  let border = "none";
3386
- const borderRadius = config.borderRadius || "4px";
3387
3516
  if ($variant === "framed") {
3388
3517
  const borderColor = $error ? theme3.colors?.palettes?.red?.["6"] : theme3.colors?.palettes?.transparency?.["10"];
3389
3518
  border = `1px solid ${borderColor}`;
@@ -3392,7 +3521,6 @@ var DropdownButtonContainer = styled.button`
3392
3521
  return `
3393
3522
  background: ${background};
3394
3523
  border: ${border};
3395
- border-radius: ${borderRadius};
3396
3524
  color: ${color};
3397
3525
 
3398
3526
  &:hover:not(:disabled) {
@@ -3556,90 +3684,372 @@ DropdownButton2.displayName = "DropdownButton";
3556
3684
  // src/dropdown/Menu.tsx
3557
3685
  init_styled();
3558
3686
  init_Icon2();
3559
- var MenuContainer = styled.div`
3560
- display: flex;
3561
- flex-direction: column;
3562
- box-sizing: border-box;
3563
- min-width: 220px;
3564
3687
 
3565
- ${({ theme: theme3 }) => {
3566
- const dropdownConfig = theme3.components?.dropdown;
3567
- const menuConfig = theme3.components?.menu;
3568
- return `
3569
- background: ${dropdownConfig?.background || "#fff"};
3570
- border: ${menuConfig?.border?.width || "1px"} solid ${menuConfig?.border?.color || "rgba(65, 70, 75, 0.1)"};
3571
- border-radius: ${menuConfig?.border?.radius || "4px"};
3572
- box-shadow: ${dropdownConfig?.boxShadow || "0 2px 8px rgba(0, 0, 0, 0.15)"};
3573
- `;
3574
- }}
3688
+ // src/dropdown/globalStyle.ts
3689
+ init_context();
3690
+ var theme2 = getGlobalTheme();
3691
+ var DropdownGlobalStyles = createGlobalStyle`
3692
+ /* Dropdown container */
3693
+ .od-dropdown {
3694
+ position: absolute;
3695
+ z-index: 1050;
3696
+ }
3575
3697
 
3576
- /* Ensure virtual list container has proper width */
3577
- .rc-virtual-list {
3578
- width: 100%;
3698
+ .od-dropdown-hidden {
3699
+ display: none;
3579
3700
  }
3580
3701
 
3581
- .rc-virtual-list-holder {
3582
- width: 100%;
3702
+ /* Dropdown slide animations */
3703
+ .od-dropdown-slide-up-enter,
3704
+ .od-dropdown-slide-up-appear {
3705
+ animation-duration: 0.2s;
3706
+ animation-fill-mode: both;
3707
+ animation-play-state: paused;
3583
3708
  }
3584
3709
 
3585
- .rc-virtual-list-holder-inner {
3586
- width: 100%;
3710
+ .od-dropdown-slide-up-leave {
3711
+ animation-duration: 0.2s;
3712
+ animation-fill-mode: both;
3713
+ animation-play-state: paused;
3714
+ }
3715
+
3716
+ .od-dropdown-slide-up-enter.od-dropdown-slide-up-enter-active,
3717
+ .od-dropdown-slide-up-appear.od-dropdown-slide-up-appear-active {
3718
+ animation-name: rcDropdownSlideUpIn;
3719
+ animation-play-state: running;
3720
+ }
3721
+
3722
+ .od-dropdown-slide-up-leave.od-dropdown-slide-up-leave-active {
3723
+ animation-name: rcDropdownSlideUpOut;
3724
+ animation-play-state: running;
3725
+ }
3726
+
3727
+ @keyframes rcDropdownSlideUpIn {
3728
+ 0% {
3729
+ opacity: 0;
3730
+ transform: scaleY(0.8);
3731
+ }
3732
+ 100% {
3733
+ opacity: 1;
3734
+ transform: scaleY(1);
3735
+ }
3736
+ }
3737
+
3738
+ @keyframes rcDropdownSlideUpOut {
3739
+ 0% {
3740
+ opacity: 1;
3741
+ transform: scaleY(1);
3742
+ }
3743
+ 100% {
3744
+ opacity: 0;
3745
+ transform: scaleY(0.8);
3746
+ }
3587
3747
  }
3588
3748
  `;
3589
- var SearchBoxContainer = styled.div`
3590
- padding: 8px 12px;
3591
- border-bottom: 1px solid ${({ theme: theme3 }) => theme3.colors?.palettes?.transparency?.["10"]};
3592
- `;
3593
- var SearchIcon = () => /* @__PURE__ */ React3.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ React3.createElement(
3594
- "path",
3595
- {
3596
- 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",
3597
- stroke: "currentColor",
3598
- strokeWidth: "1.5",
3599
- strokeLinecap: "round",
3600
- strokeLinejoin: "round"
3749
+ var MenuGlobalStyles = createGlobalStyle`
3750
+ /* Base menu container */
3751
+ .od-menu {
3752
+ margin: 0;
3753
+ padding: ${() => theme2.components?.dropdown?.padding || "4px 0"};
3754
+ list-style: none;
3755
+ outline: none;
3756
+ box-shadow: none;
3757
+ background: transparent;
3758
+ border: none;
3601
3759
  }
3602
- ), /* @__PURE__ */ React3.createElement(
3603
- "path",
3604
- {
3605
- d: "M14 14L11.1 11.1",
3606
- stroke: "currentColor",
3607
- strokeWidth: "1.5",
3608
- strokeLinecap: "round",
3609
- strokeLinejoin: "round"
3760
+
3761
+ .od-menu-hidden {
3762
+ display: none;
3610
3763
  }
3611
- ));
3612
- var MenuItemContent = styled.div`
3613
- display: flex;
3614
- align-items: center;
3615
- width: 100%;
3616
3764
 
3617
- ${({ theme: theme3 }) => {
3618
- const config = theme3.components?.menu?.menuItem;
3765
+ /* Menu item */
3766
+ .od-menu-item {
3767
+ position: relative;
3768
+ display: flex;
3769
+ align-items: center;
3770
+ margin: 0;
3771
+ cursor: pointer;
3772
+ transition: background-color 0.15s ease;
3773
+ user-select: none;
3774
+ list-style: none;
3775
+
3776
+ ${() => {
3777
+ const config = theme2.components?.menu?.menuItem;
3619
3778
  return `
3620
- gap: ${config?.layout?.gap || "8px"};
3621
- `;
3779
+ padding: ${config?.layout?.padding || "6px 12px"};
3780
+ background: ${config?.background?.normal || "transparent"};
3781
+ `;
3622
3782
  }}
3623
- `;
3624
- var IconContainer2 = styled.div`
3625
- display: flex;
3626
- align-items: center;
3627
- justify-content: center;
3628
- flex-shrink: 0;
3783
+ }
3629
3784
 
3630
- ${({ theme: theme3 }) => {
3631
- const iconSize = theme3.components?.menu?.menuItem?.icon?.size;
3785
+ .od-menu-item:hover {
3786
+ ${() => {
3787
+ const config = theme2.components?.menu?.menuItem;
3632
3788
  return `
3633
- width: ${iconSize?.width || "18px"};
3634
- height: ${iconSize?.height || "18px"};
3789
+ background: ${config?.background?.hover || "rgba(65, 70, 75, 0.05)"};
3790
+ `;
3791
+ }}
3792
+ }
3635
3793
 
3636
- svg, img {
3637
- width: 100%;
3638
- height: 100%;
3639
- }
3640
- `;
3794
+ .od-menu-item-active,
3795
+ .od-menu-item-selected {
3796
+ ${() => {
3797
+ const config = theme2.components?.menu?.menuItem;
3798
+ return `
3799
+ background: ${config?.background?.active || "rgba(65, 70, 75, 0.1)"};
3800
+ `;
3641
3801
  }}
3642
- `;
3802
+ }
3803
+
3804
+ .od-menu-item-disabled {
3805
+ cursor: not-allowed;
3806
+ ${() => {
3807
+ const config = theme2.components?.menu?.menuItem;
3808
+ return `
3809
+ background: ${config?.background?.disabled || "transparent"};
3810
+ `;
3811
+ }}
3812
+ }
3813
+
3814
+ .od-menu-item-disabled:hover {
3815
+ ${() => {
3816
+ const config = theme2.components?.menu?.menuItem;
3817
+ return `
3818
+ background: ${config?.background?.disabled || "transparent"};
3819
+ `;
3820
+ }}
3821
+ }
3822
+
3823
+ /* SubMenu */
3824
+ .od-menu-submenu {
3825
+ position: relative;
3826
+ list-style: none;
3827
+ }
3828
+
3829
+ .od-menu-submenu-title {
3830
+ position: relative;
3831
+ display: flex;
3832
+ align-items: center;
3833
+ margin: 0;
3834
+ cursor: pointer;
3835
+ transition: background-color 0.15s ease;
3836
+ user-select: none;
3837
+
3838
+ ${() => {
3839
+ const config = theme2.components?.menu?.menuItem;
3840
+ return `
3841
+ padding: ${config?.layout?.padding || "6px 12px"};
3842
+ background: ${config?.background?.normal || "transparent"};
3843
+ `;
3844
+ }}
3845
+ }
3846
+
3847
+ .od-menu-submenu-title:hover {
3848
+ ${() => {
3849
+ const config = theme2.components?.menu?.menuItem;
3850
+ return `
3851
+ background: ${config?.background?.hover || "rgba(65, 70, 75, 0.05)"};
3852
+ `;
3853
+ }}
3854
+ }
3855
+
3856
+ .od-menu-submenu-open > .od-menu-submenu-title {
3857
+ ${() => {
3858
+ const config = theme2.components?.menu?.menuItem;
3859
+ return `
3860
+ background: ${config?.background?.active || "rgba(65, 70, 75, 0.1)"};
3861
+ `;
3862
+ }}
3863
+ }
3864
+
3865
+ .od-menu-submenu-disabled .od-menu-submenu-title {
3866
+ cursor: not-allowed;
3867
+ ${() => {
3868
+ const config = theme2.components?.menu?.menuItem;
3869
+ return `
3870
+ background: ${config?.background?.disabled || "transparent"};
3871
+ `;
3872
+ }}
3873
+ }
3874
+
3875
+ /* Submenu popup */
3876
+ .od-menu-submenu-popup {
3877
+ position: absolute;
3878
+ z-index: 1050;
3879
+ }
3880
+
3881
+ /* Submenu popup positioning - add 5px gap */
3882
+ .od-menu-submenu-placement-rightTop,
3883
+ .od-menu-submenu-placement-rightBottom {
3884
+ padding-left: 5px;
3885
+ }
3886
+
3887
+ .od-menu-submenu-placement-leftTop,
3888
+ .od-menu-submenu-placement-leftBottom {
3889
+ padding-right: 5px;
3890
+ }
3891
+
3892
+ .od-menu-submenu > .od-menu {
3893
+ ${() => {
3894
+ const dropdownConfig = theme2.components?.dropdown;
3895
+ const menuConfig = theme2.components?.menu;
3896
+ return `
3897
+ background: ${dropdownConfig?.background || "#fff"};
3898
+ border: ${menuConfig?.border?.width || "1px"} solid ${menuConfig?.border?.color || "rgba(65, 70, 75, 0.1)"};
3899
+ border-radius: ${menuConfig?.border?.radius || "4px"};
3900
+ box-shadow: ${dropdownConfig?.boxShadow || "0 2px 8px rgba(0, 0, 0, 0.15)"};
3901
+ `;
3902
+ }}
3903
+ }
3904
+
3905
+ /* Item Group */
3906
+ .od-menu-item-group-title {
3907
+ padding: 8px 12px 4px;
3908
+ user-select: none;
3909
+ list-style: none;
3910
+
3911
+ ${() => {
3912
+ const config = theme2.components?.menu?.groupTitle;
3913
+ return `
3914
+ font-size: ${config?.fontSize || "12px"};
3915
+ font-weight: ${config?.fontWeight || "500"};
3916
+ color: ${config?.color || "rgba(65, 70, 75, 0.6)"};
3917
+ line-height: 20px;
3918
+ `;
3919
+ }}
3920
+ }
3921
+
3922
+ .od-menu-item-group-list {
3923
+ margin: 0;
3924
+ padding: 0;
3925
+ list-style: none;
3926
+ }
3927
+
3928
+ /* Divider */
3929
+ .od-menu-item-divider {
3930
+ overflow: hidden;
3931
+ line-height: 0;
3932
+ list-style: none;
3933
+
3934
+ ${() => {
3935
+ const config = theme2.components?.menu?.divider;
3936
+ return `
3937
+ height: ${config?.height || "1px"};
3938
+ background: ${config?.background || "rgba(65, 70, 75, 0.1)"};
3939
+ margin: ${config?.margin || "4px 0"};
3940
+ `;
3941
+ }}
3942
+ }
3943
+
3944
+ /* Animation */
3945
+ .od-menu-submenu-inline {
3946
+ border: 0;
3947
+ box-shadow: none;
3948
+ }
3949
+
3950
+ .od-menu-submenu-inline > .od-menu {
3951
+ padding: 0;
3952
+ border: 0;
3953
+ box-shadow: none;
3954
+ }
3955
+
3956
+ /* Collapse animation */
3957
+ .od-menu-submenu-inline-collapsed {
3958
+ max-height: 0;
3959
+ overflow: hidden;
3960
+ transition: max-height 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
3961
+ }
3962
+
3963
+ .od-menu-submenu-inline-collapsed-active {
3964
+ max-height: 1000px;
3965
+ }
3966
+ `;
3967
+
3968
+ // src/dropdown/Menu.tsx
3969
+ var MenuContainer = styled.div`
3970
+ display: flex;
3971
+ flex-direction: column;
3972
+ box-sizing: border-box;
3973
+ min-width: 220px;
3974
+
3975
+ ${({ theme: theme3 }) => {
3976
+ const dropdownConfig = theme3.components?.dropdown;
3977
+ const menuConfig = theme3.components?.menu;
3978
+ return `
3979
+ background: ${dropdownConfig?.background || "#fff"};
3980
+ border: ${menuConfig?.border?.width || "1px"} solid ${menuConfig?.border?.color || "rgba(65, 70, 75, 0.1)"};
3981
+ border-radius: ${menuConfig?.border?.radius || "4px"};
3982
+ box-shadow: ${dropdownConfig?.boxShadow || "0 2px 8px rgba(0, 0, 0, 0.15)"};
3983
+ `;
3984
+ }}
3985
+
3986
+ /* Ensure virtual list container has proper width */
3987
+ .rc-virtual-list {
3988
+ width: 100%;
3989
+ }
3990
+
3991
+ .rc-virtual-list-holder {
3992
+ width: 100%;
3993
+ }
3994
+
3995
+ .rc-virtual-list-holder-inner {
3996
+ width: 100%;
3997
+ }
3998
+ `;
3999
+ var SearchBoxContainer = styled.div`
4000
+ padding: 8px 12px;
4001
+ border-bottom: 1px solid ${({ theme: theme3 }) => theme3.colors?.palettes?.transparency?.["10"]};
4002
+ `;
4003
+ var SearchIcon = () => /* @__PURE__ */ React3.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ React3.createElement(
4004
+ "path",
4005
+ {
4006
+ 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",
4007
+ stroke: "currentColor",
4008
+ strokeWidth: "1.5",
4009
+ strokeLinecap: "round",
4010
+ strokeLinejoin: "round"
4011
+ }
4012
+ ), /* @__PURE__ */ React3.createElement(
4013
+ "path",
4014
+ {
4015
+ d: "M14 14L11.1 11.1",
4016
+ stroke: "currentColor",
4017
+ strokeWidth: "1.5",
4018
+ strokeLinecap: "round",
4019
+ strokeLinejoin: "round"
4020
+ }
4021
+ ));
4022
+ var MenuItemContent = styled.div`
4023
+ display: flex;
4024
+ align-items: center;
4025
+ width: 100%;
4026
+
4027
+ ${({ theme: theme3 }) => {
4028
+ const config = theme3.components?.menu?.menuItem;
4029
+ return `
4030
+ gap: ${config?.layout?.gap || "8px"};
4031
+ `;
4032
+ }}
4033
+ `;
4034
+ var IconContainer2 = styled.div`
4035
+ display: flex;
4036
+ align-items: center;
4037
+ justify-content: center;
4038
+ flex-shrink: 0;
4039
+
4040
+ ${({ theme: theme3 }) => {
4041
+ const iconSize = theme3.components?.menu?.menuItem?.icon?.size;
4042
+ return `
4043
+ width: ${iconSize?.width || "18px"};
4044
+ height: ${iconSize?.height || "18px"};
4045
+
4046
+ svg, img {
4047
+ width: 100%;
4048
+ height: 100%;
4049
+ }
4050
+ `;
4051
+ }}
4052
+ `;
3643
4053
  var ContentBlock2 = styled.div`
3644
4054
  display: flex;
3645
4055
  flex: 1;
@@ -3762,6 +4172,9 @@ var Menu = ({
3762
4172
  className,
3763
4173
  style
3764
4174
  }) => {
4175
+ useEffect(() => {
4176
+ styleManager.inject("od-menu-styles", MenuGlobalStyles);
4177
+ }, []);
3765
4178
  const [searchValue, setSearchValue] = useState("");
3766
4179
  const handleSearch = (value) => {
3767
4180
  setSearchValue(value);
@@ -3921,6 +4334,9 @@ var Dropdown = ({
3921
4334
  getPopupContainer,
3922
4335
  ...rest
3923
4336
  }) => {
4337
+ useEffect(() => {
4338
+ styleManager.inject("od-dropdown-styles", DropdownGlobalStyles);
4339
+ }, []);
3924
4340
  const [internalVisible, setInternalVisible] = useState(defaultVisible);
3925
4341
  const isControlled = controlledVisible !== void 0;
3926
4342
  const isVisible = isControlled ? controlledVisible : internalVisible;
@@ -3948,313 +4364,34 @@ var Dropdown = ({
3948
4364
  };
3949
4365
  Dropdown.displayName = "Dropdown";
3950
4366
 
3951
- // src/dropdown/globalStyle.ts
3952
- init_context();
3953
- var theme2 = getGlobalTheme();
3954
- var DropdownGlobalStyles = createGlobalStyle`
3955
- /* Dropdown container */
3956
- .od-dropdown {
3957
- position: absolute;
3958
- z-index: 1050;
3959
- }
3960
-
3961
- .od-dropdown-hidden {
3962
- display: none;
3963
- }
3964
-
3965
- /* Dropdown slide animations */
3966
- .od-dropdown-slide-up-enter,
3967
- .od-dropdown-slide-up-appear {
3968
- animation-duration: 0.2s;
3969
- animation-fill-mode: both;
3970
- animation-play-state: paused;
3971
- }
3972
-
3973
- .od-dropdown-slide-up-leave {
3974
- animation-duration: 0.2s;
3975
- animation-fill-mode: both;
3976
- animation-play-state: paused;
3977
- }
3978
-
3979
- .od-dropdown-slide-up-enter.od-dropdown-slide-up-enter-active,
3980
- .od-dropdown-slide-up-appear.od-dropdown-slide-up-appear-active {
3981
- animation-name: rcDropdownSlideUpIn;
3982
- animation-play-state: running;
3983
- }
3984
-
3985
- .od-dropdown-slide-up-leave.od-dropdown-slide-up-leave-active {
3986
- animation-name: rcDropdownSlideUpOut;
3987
- animation-play-state: running;
3988
- }
3989
-
3990
- @keyframes rcDropdownSlideUpIn {
3991
- 0% {
3992
- opacity: 0;
3993
- transform: scaleY(0.8);
3994
- }
3995
- 100% {
3996
- opacity: 1;
3997
- transform: scaleY(1);
3998
- }
3999
- }
4000
-
4001
- @keyframes rcDropdownSlideUpOut {
4002
- 0% {
4003
- opacity: 1;
4004
- transform: scaleY(1);
4005
- }
4006
- 100% {
4007
- opacity: 0;
4008
- transform: scaleY(0.8);
4009
- }
4010
- }
4011
- `;
4012
- var MenuGlobalStyles = createGlobalStyle`
4013
- /* Base menu container */
4014
- .od-menu {
4015
- margin: 0;
4016
- padding: ${() => theme2.components?.dropdown?.padding || "4px 0"};
4017
- list-style: none;
4018
- outline: none;
4019
- box-shadow: none;
4020
- background: transparent;
4021
- border: none;
4022
- }
4023
-
4024
- .od-menu-hidden {
4025
- display: none;
4026
- }
4027
-
4028
- /* Menu item */
4029
- .od-menu-item {
4030
- position: relative;
4031
- display: flex;
4032
- align-items: center;
4033
- margin: 0;
4034
- cursor: pointer;
4035
- transition: background-color 0.15s ease;
4036
- user-select: none;
4037
- list-style: none;
4038
-
4039
- ${() => {
4040
- const config = theme2.components?.menu?.menuItem;
4041
- return `
4042
- padding: ${config?.layout?.padding || "6px 12px"};
4043
- background: ${config?.background?.normal || "transparent"};
4044
- `;
4045
- }}
4046
- }
4047
-
4048
- .od-menu-item:hover {
4049
- ${() => {
4050
- const config = theme2.components?.menu?.menuItem;
4051
- return `
4052
- background: ${config?.background?.hover || "rgba(65, 70, 75, 0.05)"};
4053
- `;
4054
- }}
4055
- }
4056
-
4057
- .od-menu-item-active,
4058
- .od-menu-item-selected {
4059
- ${() => {
4060
- const config = theme2.components?.menu?.menuItem;
4061
- return `
4062
- background: ${config?.background?.active || "rgba(65, 70, 75, 0.1)"};
4063
- `;
4064
- }}
4065
- }
4066
-
4067
- .od-menu-item-disabled {
4068
- cursor: not-allowed;
4069
- ${() => {
4070
- const config = theme2.components?.menu?.menuItem;
4071
- return `
4072
- background: ${config?.background?.disabled || "transparent"};
4073
- `;
4074
- }}
4075
- }
4076
-
4077
- .od-menu-item-disabled:hover {
4078
- ${() => {
4079
- const config = theme2.components?.menu?.menuItem;
4080
- return `
4081
- background: ${config?.background?.disabled || "transparent"};
4082
- `;
4083
- }}
4084
- }
4085
-
4086
- /* SubMenu */
4087
- .od-menu-submenu {
4088
- position: relative;
4089
- list-style: none;
4090
- }
4091
-
4092
- .od-menu-submenu-title {
4093
- position: relative;
4094
- display: flex;
4095
- align-items: center;
4096
- margin: 0;
4097
- cursor: pointer;
4098
- transition: background-color 0.15s ease;
4099
- user-select: none;
4100
-
4101
- ${() => {
4102
- const config = theme2.components?.menu?.menuItem;
4103
- return `
4104
- padding: ${config?.layout?.padding || "6px 12px"};
4105
- background: ${config?.background?.normal || "transparent"};
4106
- `;
4107
- }}
4108
- }
4109
-
4110
- .od-menu-submenu-title:hover {
4111
- ${() => {
4112
- const config = theme2.components?.menu?.menuItem;
4113
- return `
4114
- background: ${config?.background?.hover || "rgba(65, 70, 75, 0.05)"};
4115
- `;
4116
- }}
4117
- }
4118
-
4119
- .od-menu-submenu-open > .od-menu-submenu-title {
4120
- ${() => {
4121
- const config = theme2.components?.menu?.menuItem;
4122
- return `
4123
- background: ${config?.background?.active || "rgba(65, 70, 75, 0.1)"};
4124
- `;
4125
- }}
4126
- }
4127
-
4128
- .od-menu-submenu-disabled .od-menu-submenu-title {
4129
- cursor: not-allowed;
4130
- ${() => {
4131
- const config = theme2.components?.menu?.menuItem;
4132
- return `
4133
- background: ${config?.background?.disabled || "transparent"};
4134
- `;
4135
- }}
4136
- }
4137
-
4138
- /* Submenu popup */
4139
- .od-menu-submenu-popup {
4140
- position: absolute;
4141
- z-index: 1050;
4142
- }
4143
-
4144
- /* Submenu popup positioning - add 5px gap */
4145
- .od-menu-submenu-placement-rightTop,
4146
- .od-menu-submenu-placement-rightBottom {
4147
- padding-left: 5px;
4148
- }
4149
-
4150
- .od-menu-submenu-placement-leftTop,
4151
- .od-menu-submenu-placement-leftBottom {
4152
- padding-right: 5px;
4153
- }
4154
-
4155
- .od-menu-submenu > .od-menu {
4156
- ${() => {
4157
- const dropdownConfig = theme2.components?.dropdown;
4158
- const menuConfig = theme2.components?.menu;
4159
- return `
4160
- background: ${dropdownConfig?.background || "#fff"};
4161
- border: ${menuConfig?.border?.width || "1px"} solid ${menuConfig?.border?.color || "rgba(65, 70, 75, 0.1)"};
4162
- border-radius: ${menuConfig?.border?.radius || "4px"};
4163
- box-shadow: ${dropdownConfig?.boxShadow || "0 2px 8px rgba(0, 0, 0, 0.15)"};
4164
- `;
4165
- }}
4166
- }
4167
-
4168
- /* Item Group */
4169
- .od-menu-item-group-title {
4170
- padding: 8px 12px 4px;
4171
- user-select: none;
4172
- list-style: none;
4173
-
4174
- ${() => {
4175
- const config = theme2.components?.menu?.groupTitle;
4176
- return `
4177
- font-size: ${config?.fontSize || "12px"};
4178
- font-weight: ${config?.fontWeight || "500"};
4179
- color: ${config?.color || "rgba(65, 70, 75, 0.6)"};
4180
- line-height: 20px;
4181
- `;
4182
- }}
4183
- }
4184
-
4185
- .od-menu-item-group-list {
4186
- margin: 0;
4187
- padding: 0;
4188
- list-style: none;
4189
- }
4190
-
4191
- /* Divider */
4192
- .od-menu-item-divider {
4193
- overflow: hidden;
4194
- line-height: 0;
4195
- list-style: none;
4196
-
4197
- ${() => {
4198
- const config = theme2.components?.menu?.divider;
4199
- return `
4200
- height: ${config?.height || "1px"};
4201
- background: ${config?.background || "rgba(65, 70, 75, 0.1)"};
4202
- margin: ${config?.margin || "4px 0"};
4203
- `;
4204
- }}
4205
- }
4206
-
4207
- /* Animation */
4208
- .od-menu-submenu-inline {
4209
- border: 0;
4210
- box-shadow: none;
4211
- }
4212
-
4213
- .od-menu-submenu-inline > .od-menu {
4214
- padding: 0;
4215
- border: 0;
4216
- box-shadow: none;
4217
- }
4218
-
4219
- /* Collapse animation */
4220
- .od-menu-submenu-inline-collapsed {
4221
- max-height: 0;
4222
- overflow: hidden;
4223
- transition: max-height 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
4224
- }
4225
-
4226
- .od-menu-submenu-inline-collapsed-active {
4227
- max-height: 1000px;
4228
- }
4229
- `;
4230
-
4231
4367
  // src/UIConfigProvider/UIConfigProvider.tsx
4232
4368
  init_IconProvider();
4369
+ init_configManager();
4233
4370
  init_context();
4234
4371
  var UIConfigContext = createContext(null);
4235
4372
  var UIConfigProvider = ({ config, children }) => {
4236
- const { icons = {}, toast: toast2 = {} } = config;
4237
- const renderFunction = (element, container) => {
4238
- if ("createRoot" in ReactDOM) {
4239
- const { createRoot } = ReactDOM;
4240
- const root = createRoot(container);
4241
- root.render(element);
4242
- } else {
4243
- ReactDOM.render(element, container);
4244
- }
4245
- };
4246
- registerGlobalContext({
4247
- theme: config.theme,
4248
- render: renderFunction
4249
- });
4373
+ useEffect(() => {
4374
+ const renderFunction = (element, container) => {
4375
+ if ("createRoot" in ReactDOM) {
4376
+ const { createRoot } = ReactDOM;
4377
+ const root = createRoot(container);
4378
+ root.render(element);
4379
+ } else {
4380
+ ReactDOM.render(element, container);
4381
+ }
4382
+ };
4383
+ registerGlobalContext({
4384
+ theme: config.theme,
4385
+ render: renderFunction
4386
+ });
4387
+ initUIConfig(config);
4388
+ }, [config]);
4389
+ const { icons = {} } = config;
4250
4390
  const toastConfig = {
4251
- maxCount: toast2.maxCount ?? 5,
4252
- defaultDuration: toast2.defaultDuration ?? 3e3
4391
+ maxCount: config.toast?.maxCount ?? 5,
4392
+ defaultDuration: config.toast?.defaultDuration ?? 3e3
4253
4393
  };
4254
- const TooltipStyles = TooltipGlobalStyles;
4255
- const MenuStyles = MenuGlobalStyles;
4256
- const DropdownStyles = DropdownGlobalStyles;
4257
- return /* @__PURE__ */ React3.createElement(UIConfigContext.Provider, { value: config }, /* @__PURE__ */ React3.createElement(TooltipStyles, null), /* @__PURE__ */ React3.createElement(MenuStyles, null), /* @__PURE__ */ React3.createElement(DropdownStyles, null), /* @__PURE__ */ React3.createElement(IconProvider, { icons }, /* @__PURE__ */ React3.createElement(
4394
+ return /* @__PURE__ */ React3.createElement(UIConfigContext.Provider, { value: config }, /* @__PURE__ */ React3.createElement(IconProvider, { icons }, /* @__PURE__ */ React3.createElement(
4258
4395
  ToastContainer2,
4259
4396
  {
4260
4397
  maxCount: toastConfig.maxCount,
@@ -4265,10 +4402,7 @@ var UIConfigProvider = ({ config, children }) => {
4265
4402
  };
4266
4403
  var useUIConfig = () => {
4267
4404
  const context = useContext(UIConfigContext);
4268
- if (!context) {
4269
- throw new Error("useUIConfig must be used within UIConfigProvider");
4270
- }
4271
- return context;
4405
+ return context || getUIConfig();
4272
4406
  };
4273
4407
  UIConfigProvider.displayName = "UIConfigProvider";
4274
4408
 
@@ -4339,10 +4473,13 @@ var mergeUIConfig = (baseConfig, ...configs) => {
4339
4473
  return merged;
4340
4474
  };
4341
4475
 
4476
+ // src/UIConfigProvider/index.ts
4477
+ init_configManager();
4478
+
4342
4479
  // src/index.ts
4343
4480
  init_styled();
4344
4481
  init_context();
4345
4482
 
4346
- export { Button, Checkbox, Dropdown, DropdownButton2 as DropdownButton, DropdownGlobalStyles, Icon, IconProvider, Input, Menu, MenuGlobalStyles, NumberInput, Radio, SearchInput, Slider, SpinButton, Switch, Tabs, Toast, ToastContainer2 as ToastContainer, ToolbarButton, Tooltip, UIConfigProvider, UnderlinedInput, createUIConfig, getGlobalTheme, mergeUIConfig, styled, toast, useIconRegistry, useToast, useUIConfig };
4483
+ export { Button, Checkbox, Dropdown, DropdownButton2 as DropdownButton, DropdownGlobalStyles, Icon, IconProvider, Input, Menu, MenuGlobalStyles, NumberInput, Radio, SearchInput, Slider, SpinButton, Switch, Tabs, Toast, ToastContainer2 as ToastContainer, ToolbarButton, Tooltip, UIConfigProvider, UnderlinedInput, createUIConfig, getGlobalIconRegistry, getGlobalTheme, getGlobalToastConfig, getUIConfig, initUIConfig, mergeUIConfig, styled, toast, useIconRegistry, useToast, useUIConfig };
4347
4484
  //# sourceMappingURL=index.js.map
4348
4485
  //# sourceMappingURL=index.js.map