@officesdk/design 0.2.13 → 0.2.14

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.
@@ -1604,6 +1604,10 @@ interface LoadingProps {
1604
1604
  * Whether to use fullscreen overlay mode
1605
1605
  */
1606
1606
  fullscreen?: boolean;
1607
+ /**
1608
+ * Whether overlay background should be transparent
1609
+ */
1610
+ transparent?: boolean;
1607
1611
  /**
1608
1612
  * Custom className
1609
1613
  */
@@ -1659,6 +1663,11 @@ interface LoadingProps {
1659
1663
  */
1660
1664
  declare const Loading: React$1.FC<LoadingProps>;
1661
1665
 
1666
+ interface LoadingOverlayProps extends Pick<LoadingProps, 'size' | 'spinning' | 'delay' | 'tip' | 'className' | 'indicator'> {
1667
+ transparent?: boolean;
1668
+ }
1669
+ declare const LoadingOverlay: React$1.FC<LoadingOverlayProps>;
1670
+
1662
1671
  type DeepPartial<T extends object> = {
1663
1672
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
1664
1673
  };
@@ -1945,4 +1954,4 @@ declare const styled: ThemedStyledInterface<Theme>;
1945
1954
 
1946
1955
  declare const getGlobalTheme: () => Theme;
1947
1956
 
1948
- export { type A11yConfig, type AnimationConfig, Button, type ButtonProps, Checkbox, type CheckboxProps, Dropdown, DropdownButton, type DropdownButtonProps, DropdownGlobalStyles, type DropdownProps, type I18nConfig, Icon, type IconComponent, type IconProps, IconProvider, type IconProviderProps, type IconRegistry, Input, type InputProps, Loading, type LoadingProps, Menu, type MenuDivider, MenuGlobalStyles, type MenuGroup, type MenuItem, type MenuItemType, type MenuProps, Modal, ModalGlobalStyles, type ModalProps, NumberInput, type NumberInputProps, Radio, type RadioProps, SearchInput, type SearchInputProps, Slider, type SliderProps, SpinButton, type SpinButtonProps, Switch, type SwitchProps, type TabItem, Tabs, type TabsProps, Toast, type ToastConfig, ToastContainer, type ToastContainerConfig, type ToastContainerProps, type ToastPosition, type ToastProps, ToolbarButton, type ToolbarButtonProps, Tooltip, type TooltipProps, type UIConfig, UIConfigProvider, type UIConfigProviderProps, UnderlinedInput, type InputProps as UnderlinedInputProps, type ZIndexConfig, createUIConfig, getGlobalIconRegistry, getGlobalTheme, getGlobalToastConfig, getUIConfig, initUIConfig, mergeUIConfig, styled, toast, useIconRegistry, useToast, useUIConfig };
1957
+ export { type A11yConfig, type AnimationConfig, Button, type ButtonProps, Checkbox, type CheckboxProps, Dropdown, DropdownButton, type DropdownButtonProps, DropdownGlobalStyles, type DropdownProps, type I18nConfig, Icon, type IconComponent, type IconProps, IconProvider, type IconProviderProps, type IconRegistry, Input, type InputProps, Loading, LoadingOverlay, type LoadingOverlayProps, type LoadingProps, Menu, type MenuDivider, MenuGlobalStyles, type MenuGroup, type MenuItem, type MenuItemType, type MenuProps, Modal, ModalGlobalStyles, type ModalProps, NumberInput, type NumberInputProps, Radio, type RadioProps, SearchInput, type SearchInputProps, Slider, type SliderProps, SpinButton, type SpinButtonProps, Switch, type SwitchProps, type TabItem, Tabs, type TabsProps, Toast, type ToastConfig, ToastContainer, type ToastContainerConfig, type ToastContainerProps, type ToastPosition, type ToastProps, ToolbarButton, type ToolbarButtonProps, Tooltip, type TooltipProps, type UIConfig, UIConfigProvider, type UIConfigProviderProps, UnderlinedInput, type InputProps as UnderlinedInputProps, type ZIndexConfig, createUIConfig, getGlobalIconRegistry, getGlobalTheme, getGlobalToastConfig, getUIConfig, initUIConfig, mergeUIConfig, styled, toast, useIconRegistry, useToast, useUIConfig };
@@ -4588,6 +4588,8 @@ var MenuContainer = styled.div`
4588
4588
  flex-direction: column;
4589
4589
  box-sizing: border-box;
4590
4590
  min-width: 220px;
4591
+ max-height: 100%;
4592
+ overflow: hidden;
4591
4593
 
4592
4594
  ${({ theme: theme2 }) => {
4593
4595
  const dropdownConfig = theme2.components?.dropdown;
@@ -4615,9 +4617,20 @@ var MenuContainer = styled.div`
4615
4617
  }
4616
4618
  `;
4617
4619
  var SearchBoxContainer = styled.div`
4620
+ flex-shrink: 0;
4618
4621
  padding: 8px 12px;
4619
4622
  border-bottom: 1px solid ${({ theme: theme2 }) => theme2.colors?.palettes?.transparency?.["10"]};
4620
4623
  `;
4624
+ var MenuScrollContainer = styled.div`
4625
+ flex: 1;
4626
+ min-height: 0;
4627
+ overflow-y: auto;
4628
+ overflow-x: hidden;
4629
+ `;
4630
+ var VirtualListContainer = styled.div`
4631
+ max-height: 100%;
4632
+ overflow: hidden;
4633
+ `;
4621
4634
  var MenuItemContent = styled.div`
4622
4635
  display: flex;
4623
4636
  align-items: center;
@@ -4841,7 +4854,7 @@ var Menu = ({
4841
4854
  };
4842
4855
  const itemHeight = size === "medium" ? 28 : 36;
4843
4856
  const menuKey = openKeys?.join(",") || "menu";
4844
- return /* @__PURE__ */ React3.createElement(MenuContainer, { className, style }, searchable && /* @__PURE__ */ React3.createElement(SearchBoxContainer, null, /* @__PURE__ */ React3.createElement(
4857
+ return /* @__PURE__ */ React3.createElement(MenuContainer, { className, style: { maxHeight, ...style } }, searchable && /* @__PURE__ */ React3.createElement(SearchBoxContainer, { "data-testid": "menu-search-container" }, /* @__PURE__ */ React3.createElement(
4845
4858
  Input,
4846
4859
  {
4847
4860
  lineType: "underlined",
@@ -4853,7 +4866,7 @@ var Menu = ({
4853
4866
  onClear: () => handleSearch(""),
4854
4867
  prefixNode: /* @__PURE__ */ React3.createElement(SearchIcon, null)
4855
4868
  }
4856
- )), virtual && filteredItems.length > 10 ? /* @__PURE__ */ React3.createElement(
4869
+ )), /* @__PURE__ */ React3.createElement(MenuScrollContainer, { "data-testid": "menu-scroll-container" }, virtual && filteredItems.length > 10 ? /* @__PURE__ */ React3.createElement(VirtualListContainer, null, /* @__PURE__ */ React3.createElement(
4857
4870
  VirtualList,
4858
4871
  {
4859
4872
  data: filteredItems,
@@ -4882,7 +4895,7 @@ var Menu = ({
4882
4895
  },
4883
4896
  renderItem(item)
4884
4897
  )
4885
- ) : /* @__PURE__ */ React3.createElement(
4898
+ )) : /* @__PURE__ */ React3.createElement(
4886
4899
  RcMenu,
4887
4900
  {
4888
4901
  key: menuKey,
@@ -4899,7 +4912,7 @@ var Menu = ({
4899
4912
  }
4900
4913
  },
4901
4914
  filteredItems.map(renderItem)
4902
- ));
4915
+ )));
4903
4916
  };
4904
4917
  Menu.displayName = "Menu";
4905
4918
  var Dropdown = ({
@@ -5097,6 +5110,7 @@ var Modal = ({
5097
5110
  maskType = "light",
5098
5111
  title,
5099
5112
  width,
5113
+ height,
5100
5114
  okText,
5101
5115
  cancelText,
5102
5116
  footer,
@@ -5127,9 +5141,8 @@ var Modal = ({
5127
5141
  const modalWidth = width ?? modalConfig[variant].defaultWidth;
5128
5142
  const classNames = {
5129
5143
  ...maskType === "dark" && { mask: `${prefixCls}-mask-dark` },
5130
- content: `${prefixCls}-content-${variant}`
5144
+ ...width === void 0 && height === void 0 && { content: `${prefixCls}-content-${variant}` }
5131
5145
  };
5132
- const styles = width !== void 0 ? { content: { width } } : void 0;
5133
5146
  const renderFooter = () => {
5134
5147
  if (footer !== void 0) return footer;
5135
5148
  return /* @__PURE__ */ React3.createElement(React3.Fragment, null, cancelText !== null && /* @__PURE__ */ React3.createElement(Button, { key: "cancel", variant: "outlined", colorType: "default", onClick: handleClose }, cancelText ?? "Cancel"), okText !== null && /* @__PURE__ */ React3.createElement(
@@ -5150,14 +5163,14 @@ var Modal = ({
5150
5163
  ...restProps,
5151
5164
  visible,
5152
5165
  title,
5153
- width: width === void 0 ? modalWidth : void 0,
5166
+ width: modalWidth,
5167
+ height,
5154
5168
  prefixCls,
5155
5169
  closable,
5156
5170
  closeIcon: closeIcon ?? /* @__PURE__ */ React3.createElement(Icon, { size: 19.2 }, /* @__PURE__ */ React3.createElement(CloseIcon, null)),
5157
5171
  mask,
5158
5172
  maskClosable,
5159
5173
  classNames,
5160
- styles,
5161
5174
  className,
5162
5175
  onClose: handleClose,
5163
5176
  footer: renderFooter()
@@ -5214,19 +5227,23 @@ var CSSSpinner = styled.div`
5214
5227
  `;
5215
5228
  }}
5216
5229
  `;
5217
- var LoadingContainer = styled.div`
5230
+ var LoadingInlineContainer = styled.span`
5218
5231
  display: inline-flex;
5219
5232
  flex-direction: column;
5220
5233
  align-items: center;
5221
5234
  justify-content: center;
5222
5235
  gap: ${({ $hasTip, theme: theme2 }) => $hasTip ? theme2.components.loading.indicator.gap : "0"};
5223
-
5224
- ${({ $fullscreen, theme: theme2 }) => $fullscreen && `
5225
- position: fixed;
5226
- inset: 0;
5227
- z-index: ${theme2.components.loading.fullscreen.zIndex};
5228
- background: ${theme2.components.loading.fullscreen.background};
5229
- `}
5236
+ `;
5237
+ var LoadingFullscreenContainer = styled.div`
5238
+ display: flex;
5239
+ flex-direction: column;
5240
+ align-items: center;
5241
+ justify-content: center;
5242
+ gap: ${({ $hasTip, theme: theme2 }) => $hasTip ? theme2.components.loading.indicator.gap : "0"};
5243
+ position: fixed;
5244
+ inset: 0;
5245
+ z-index: ${({ theme: theme2 }) => theme2.components.loading.fullscreen.zIndex};
5246
+ background: ${({ $transparent, theme: theme2 }) => $transparent ? "transparent" : theme2.components.loading.fullscreen.background};
5230
5247
  `;
5231
5248
  var Tip = styled.span`
5232
5249
  font-size: 14px;
@@ -5258,6 +5275,7 @@ var Loading = ({
5258
5275
  delay = 0,
5259
5276
  tip,
5260
5277
  fullscreen = false,
5278
+ transparent = false,
5261
5279
  className,
5262
5280
  children,
5263
5281
  indicator
@@ -5303,15 +5321,130 @@ var Loading = ({
5303
5321
  return /* @__PURE__ */ React3.createElement(Wrapper, { className }, /* @__PURE__ */ React3.createElement(WrapperContent, { $spinning: shouldShow }, children), shouldShow && /* @__PURE__ */ React3.createElement(WrapperOverlay, { $hasTip: !!tip }, renderSpinner()));
5304
5322
  }
5305
5323
  if (!shouldShow) return null;
5306
- return /* @__PURE__ */ React3.createElement(LoadingContainer, { $fullscreen: fullscreen, $hasTip: !!tip, className }, renderSpinner());
5324
+ if (fullscreen) {
5325
+ return /* @__PURE__ */ React3.createElement(LoadingFullscreenContainer, { $hasTip: !!tip, $transparent: transparent, className }, renderSpinner());
5326
+ }
5327
+ return /* @__PURE__ */ React3.createElement(LoadingInlineContainer, { $hasTip: !!tip, className }, renderSpinner());
5307
5328
  };
5308
5329
  Loading.displayName = "Loading";
5309
5330
 
5331
+ // src/Loading/LoadingOverlay.tsx
5332
+ init_styled();
5333
+ init_loading();
5334
+ init_context();
5335
+ var getIndicatorSize2 = (size, theme2) => {
5336
+ const sizeConfig = theme2.components.loading[size || "medium"];
5337
+ return `
5338
+ width: ${sizeConfig.size};
5339
+ height: ${sizeConfig.size};
5340
+ `;
5341
+ };
5342
+ var SpinnerImage2 = styled.img`
5343
+ display: inline-block;
5344
+ ${({ $size, theme: theme2 }) => getIndicatorSize2($size, theme2)}
5345
+ object-fit: contain;
5346
+ `;
5347
+ var CustomIndicatorWrapper2 = styled.span`
5348
+ display: inline-flex;
5349
+ align-items: center;
5350
+ justify-content: center;
5351
+ ${({ $size, theme: theme2 }) => getIndicatorSize2($size, theme2)}
5352
+ `;
5353
+ var CSSSpinner2 = styled.div`
5354
+ display: inline-block;
5355
+ border-radius: 50%;
5356
+ box-sizing: border-box;
5357
+
5358
+ ${({ $size, theme: theme2 }) => {
5359
+ const loadingConfig = theme2.components.loading;
5360
+ const sizeConfig = loadingConfig[$size || "medium"];
5361
+ const { color, animation } = loadingConfig.indicator;
5362
+ const sizeValue = Number.parseFloat(sizeConfig.size);
5363
+ const borderWidth = Math.max(2, Math.round((Number.isNaN(sizeValue) ? 24 : sizeValue) / 12));
5364
+ return `
5365
+ width: ${sizeConfig.size};
5366
+ height: ${sizeConfig.size};
5367
+ border: ${borderWidth}px solid rgba(0, 0, 0, 0.1);
5368
+ border-top-color: ${color};
5369
+ animation: loading-spin ${animation.duration} ${animation.timingFunction} infinite;
5370
+
5371
+ @keyframes loading-spin {
5372
+ from { transform: rotate(0deg); }
5373
+ to { transform: rotate(360deg); }
5374
+ }
5375
+ `;
5376
+ }}
5377
+ `;
5378
+ var OverlayContainer = styled.div`
5379
+ position: absolute;
5380
+ inset: 0;
5381
+ display: flex;
5382
+ flex-direction: column;
5383
+ align-items: center;
5384
+ justify-content: center;
5385
+ z-index: 1;
5386
+ background: ${({ $transparent, theme: theme2 }) => $transparent ? "transparent" : theme2.components.loading.wrapper.overlayBackground};
5387
+ gap: ${({ $hasTip, theme: theme2 }) => $hasTip ? theme2.components.loading.indicator.gap : "0"};
5388
+ `;
5389
+ var Tip2 = styled.span`
5390
+ font-size: 14px;
5391
+ line-height: 1.5;
5392
+ color: ${({ theme: theme2 }) => theme2.components.loading.tipColor};
5393
+ `;
5394
+ var LoadingOverlay = ({
5395
+ size = "medium",
5396
+ spinning = true,
5397
+ delay = 0,
5398
+ tip,
5399
+ className,
5400
+ indicator,
5401
+ transparent = false
5402
+ }) => {
5403
+ const [shouldShow, setShouldShow] = useState(delay === 0 && spinning);
5404
+ useEffect(() => {
5405
+ if (!spinning) {
5406
+ setShouldShow(false);
5407
+ return;
5408
+ }
5409
+ if (delay <= 0) {
5410
+ setShouldShow(true);
5411
+ return;
5412
+ }
5413
+ const timer = setTimeout(() => setShouldShow(true), delay);
5414
+ return () => clearTimeout(timer);
5415
+ }, [spinning, delay]);
5416
+ const renderIndicator = () => {
5417
+ const a11yProps = { role: "status", "aria-label": "Loading" };
5418
+ if (typeof indicator === "string") {
5419
+ return /* @__PURE__ */ React3.createElement(SpinnerImage2, { $size: size, src: indicator, alt: "Loading", ...a11yProps });
5420
+ }
5421
+ if (indicator) {
5422
+ return /* @__PURE__ */ React3.createElement(CustomIndicatorWrapper2, { $size: size, ...a11yProps }, indicator);
5423
+ }
5424
+ const { indicator: indicatorConfig } = getGlobalTheme().components.loading;
5425
+ if (indicatorConfig.defaultType === "css") {
5426
+ return /* @__PURE__ */ React3.createElement(CSSSpinner2, { $size: size, ...a11yProps });
5427
+ }
5428
+ return /* @__PURE__ */ React3.createElement(
5429
+ SpinnerImage2,
5430
+ {
5431
+ $size: size,
5432
+ src: indicatorConfig.defaultImage || loading_default,
5433
+ alt: "Loading",
5434
+ ...a11yProps
5435
+ }
5436
+ );
5437
+ };
5438
+ if (!shouldShow) return null;
5439
+ return /* @__PURE__ */ React3.createElement(OverlayContainer, { $hasTip: !!tip, $transparent: transparent, className }, renderIndicator(), tip && /* @__PURE__ */ React3.createElement(Tip2, null, tip));
5440
+ };
5441
+ LoadingOverlay.displayName = "LoadingOverlay";
5442
+
5310
5443
  // src/index.ts
5311
5444
  init_UIConfigProvider2();
5312
5445
  init_styled();
5313
5446
  init_context();
5314
5447
 
5315
- export { Button, Checkbox, Dropdown, DropdownButton2 as DropdownButton, DropdownGlobalStyles, Icon, IconProvider, Input, Loading, Menu, MenuGlobalStyles, Modal, ModalGlobalStyles, 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 };
5448
+ export { Button, Checkbox, Dropdown, DropdownButton2 as DropdownButton, DropdownGlobalStyles, Icon, IconProvider, Input, Loading, LoadingOverlay, Menu, MenuGlobalStyles, Modal, ModalGlobalStyles, 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 };
5316
5449
  //# sourceMappingURL=index.js.map
5317
5450
  //# sourceMappingURL=index.js.map