@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 };
@@ -4601,6 +4601,8 @@ var MenuContainer = exports.styled.div`
4601
4601
  flex-direction: column;
4602
4602
  box-sizing: border-box;
4603
4603
  min-width: 220px;
4604
+ max-height: 100%;
4605
+ overflow: hidden;
4604
4606
 
4605
4607
  ${({ theme: theme2 }) => {
4606
4608
  const dropdownConfig = theme2.components?.dropdown;
@@ -4628,9 +4630,20 @@ var MenuContainer = exports.styled.div`
4628
4630
  }
4629
4631
  `;
4630
4632
  var SearchBoxContainer = exports.styled.div`
4633
+ flex-shrink: 0;
4631
4634
  padding: 8px 12px;
4632
4635
  border-bottom: 1px solid ${({ theme: theme2 }) => theme2.colors?.palettes?.transparency?.["10"]};
4633
4636
  `;
4637
+ var MenuScrollContainer = exports.styled.div`
4638
+ flex: 1;
4639
+ min-height: 0;
4640
+ overflow-y: auto;
4641
+ overflow-x: hidden;
4642
+ `;
4643
+ var VirtualListContainer = exports.styled.div`
4644
+ max-height: 100%;
4645
+ overflow: hidden;
4646
+ `;
4634
4647
  var MenuItemContent = exports.styled.div`
4635
4648
  display: flex;
4636
4649
  align-items: center;
@@ -4854,7 +4867,7 @@ var Menu = ({
4854
4867
  };
4855
4868
  const itemHeight = size === "medium" ? 28 : 36;
4856
4869
  const menuKey = openKeys?.join(",") || "menu";
4857
- return /* @__PURE__ */ React3__default.default.createElement(MenuContainer, { className, style }, searchable && /* @__PURE__ */ React3__default.default.createElement(SearchBoxContainer, null, /* @__PURE__ */ React3__default.default.createElement(
4870
+ return /* @__PURE__ */ React3__default.default.createElement(MenuContainer, { className, style: { maxHeight, ...style } }, searchable && /* @__PURE__ */ React3__default.default.createElement(SearchBoxContainer, { "data-testid": "menu-search-container" }, /* @__PURE__ */ React3__default.default.createElement(
4858
4871
  Input,
4859
4872
  {
4860
4873
  lineType: "underlined",
@@ -4866,7 +4879,7 @@ var Menu = ({
4866
4879
  onClear: () => handleSearch(""),
4867
4880
  prefixNode: /* @__PURE__ */ React3__default.default.createElement(icons.SearchIcon, null)
4868
4881
  }
4869
- )), virtual && filteredItems.length > 10 ? /* @__PURE__ */ React3__default.default.createElement(
4882
+ )), /* @__PURE__ */ React3__default.default.createElement(MenuScrollContainer, { "data-testid": "menu-scroll-container" }, virtual && filteredItems.length > 10 ? /* @__PURE__ */ React3__default.default.createElement(VirtualListContainer, null, /* @__PURE__ */ React3__default.default.createElement(
4870
4883
  VirtualList__default.default,
4871
4884
  {
4872
4885
  data: filteredItems,
@@ -4895,7 +4908,7 @@ var Menu = ({
4895
4908
  },
4896
4909
  renderItem(item)
4897
4910
  )
4898
- ) : /* @__PURE__ */ React3__default.default.createElement(
4911
+ )) : /* @__PURE__ */ React3__default.default.createElement(
4899
4912
  RcMenu__default.default,
4900
4913
  {
4901
4914
  key: menuKey,
@@ -4912,7 +4925,7 @@ var Menu = ({
4912
4925
  }
4913
4926
  },
4914
4927
  filteredItems.map(renderItem)
4915
- ));
4928
+ )));
4916
4929
  };
4917
4930
  Menu.displayName = "Menu";
4918
4931
  var Dropdown = ({
@@ -5110,6 +5123,7 @@ var Modal = ({
5110
5123
  maskType = "light",
5111
5124
  title,
5112
5125
  width,
5126
+ height,
5113
5127
  okText,
5114
5128
  cancelText,
5115
5129
  footer,
@@ -5140,9 +5154,8 @@ var Modal = ({
5140
5154
  const modalWidth = width ?? modalConfig[variant].defaultWidth;
5141
5155
  const classNames = {
5142
5156
  ...maskType === "dark" && { mask: `${prefixCls}-mask-dark` },
5143
- content: `${prefixCls}-content-${variant}`
5157
+ ...width === void 0 && height === void 0 && { content: `${prefixCls}-content-${variant}` }
5144
5158
  };
5145
- const styles = width !== void 0 ? { content: { width } } : void 0;
5146
5159
  const renderFooter = () => {
5147
5160
  if (footer !== void 0) return footer;
5148
5161
  return /* @__PURE__ */ React3__default.default.createElement(React3__default.default.Fragment, null, cancelText !== null && /* @__PURE__ */ React3__default.default.createElement(exports.Button, { key: "cancel", variant: "outlined", colorType: "default", onClick: handleClose }, cancelText ?? "Cancel"), okText !== null && /* @__PURE__ */ React3__default.default.createElement(
@@ -5163,14 +5176,14 @@ var Modal = ({
5163
5176
  ...restProps,
5164
5177
  visible,
5165
5178
  title,
5166
- width: width === void 0 ? modalWidth : void 0,
5179
+ width: modalWidth,
5180
+ height,
5167
5181
  prefixCls,
5168
5182
  closable,
5169
5183
  closeIcon: closeIcon ?? /* @__PURE__ */ React3__default.default.createElement(exports.Icon, { size: 19.2 }, /* @__PURE__ */ React3__default.default.createElement(icons.CloseIcon, null)),
5170
5184
  mask,
5171
5185
  maskClosable,
5172
5186
  classNames,
5173
- styles,
5174
5187
  className,
5175
5188
  onClose: handleClose,
5176
5189
  footer: renderFooter()
@@ -5227,19 +5240,23 @@ var CSSSpinner = exports.styled.div`
5227
5240
  `;
5228
5241
  }}
5229
5242
  `;
5230
- var LoadingContainer = exports.styled.div`
5243
+ var LoadingInlineContainer = exports.styled.span`
5231
5244
  display: inline-flex;
5232
5245
  flex-direction: column;
5233
5246
  align-items: center;
5234
5247
  justify-content: center;
5235
5248
  gap: ${({ $hasTip, theme: theme2 }) => $hasTip ? theme2.components.loading.indicator.gap : "0"};
5236
-
5237
- ${({ $fullscreen, theme: theme2 }) => $fullscreen && `
5238
- position: fixed;
5239
- inset: 0;
5240
- z-index: ${theme2.components.loading.fullscreen.zIndex};
5241
- background: ${theme2.components.loading.fullscreen.background};
5242
- `}
5249
+ `;
5250
+ var LoadingFullscreenContainer = exports.styled.div`
5251
+ display: flex;
5252
+ flex-direction: column;
5253
+ align-items: center;
5254
+ justify-content: center;
5255
+ gap: ${({ $hasTip, theme: theme2 }) => $hasTip ? theme2.components.loading.indicator.gap : "0"};
5256
+ position: fixed;
5257
+ inset: 0;
5258
+ z-index: ${({ theme: theme2 }) => theme2.components.loading.fullscreen.zIndex};
5259
+ background: ${({ $transparent, theme: theme2 }) => $transparent ? "transparent" : theme2.components.loading.fullscreen.background};
5243
5260
  `;
5244
5261
  var Tip = exports.styled.span`
5245
5262
  font-size: 14px;
@@ -5271,6 +5288,7 @@ var Loading = ({
5271
5288
  delay = 0,
5272
5289
  tip,
5273
5290
  fullscreen = false,
5291
+ transparent = false,
5274
5292
  className,
5275
5293
  children,
5276
5294
  indicator
@@ -5316,10 +5334,125 @@ var Loading = ({
5316
5334
  return /* @__PURE__ */ React3__default.default.createElement(Wrapper, { className }, /* @__PURE__ */ React3__default.default.createElement(WrapperContent, { $spinning: shouldShow }, children), shouldShow && /* @__PURE__ */ React3__default.default.createElement(WrapperOverlay, { $hasTip: !!tip }, renderSpinner()));
5317
5335
  }
5318
5336
  if (!shouldShow) return null;
5319
- return /* @__PURE__ */ React3__default.default.createElement(LoadingContainer, { $fullscreen: fullscreen, $hasTip: !!tip, className }, renderSpinner());
5337
+ if (fullscreen) {
5338
+ return /* @__PURE__ */ React3__default.default.createElement(LoadingFullscreenContainer, { $hasTip: !!tip, $transparent: transparent, className }, renderSpinner());
5339
+ }
5340
+ return /* @__PURE__ */ React3__default.default.createElement(LoadingInlineContainer, { $hasTip: !!tip, className }, renderSpinner());
5320
5341
  };
5321
5342
  Loading.displayName = "Loading";
5322
5343
 
5344
+ // src/Loading/LoadingOverlay.tsx
5345
+ init_styled();
5346
+ init_loading();
5347
+ init_context();
5348
+ var getIndicatorSize2 = (size, theme2) => {
5349
+ const sizeConfig = theme2.components.loading[size || "medium"];
5350
+ return `
5351
+ width: ${sizeConfig.size};
5352
+ height: ${sizeConfig.size};
5353
+ `;
5354
+ };
5355
+ var SpinnerImage2 = exports.styled.img`
5356
+ display: inline-block;
5357
+ ${({ $size, theme: theme2 }) => getIndicatorSize2($size, theme2)}
5358
+ object-fit: contain;
5359
+ `;
5360
+ var CustomIndicatorWrapper2 = exports.styled.span`
5361
+ display: inline-flex;
5362
+ align-items: center;
5363
+ justify-content: center;
5364
+ ${({ $size, theme: theme2 }) => getIndicatorSize2($size, theme2)}
5365
+ `;
5366
+ var CSSSpinner2 = exports.styled.div`
5367
+ display: inline-block;
5368
+ border-radius: 50%;
5369
+ box-sizing: border-box;
5370
+
5371
+ ${({ $size, theme: theme2 }) => {
5372
+ const loadingConfig = theme2.components.loading;
5373
+ const sizeConfig = loadingConfig[$size || "medium"];
5374
+ const { color, animation } = loadingConfig.indicator;
5375
+ const sizeValue = Number.parseFloat(sizeConfig.size);
5376
+ const borderWidth = Math.max(2, Math.round((Number.isNaN(sizeValue) ? 24 : sizeValue) / 12));
5377
+ return `
5378
+ width: ${sizeConfig.size};
5379
+ height: ${sizeConfig.size};
5380
+ border: ${borderWidth}px solid rgba(0, 0, 0, 0.1);
5381
+ border-top-color: ${color};
5382
+ animation: loading-spin ${animation.duration} ${animation.timingFunction} infinite;
5383
+
5384
+ @keyframes loading-spin {
5385
+ from { transform: rotate(0deg); }
5386
+ to { transform: rotate(360deg); }
5387
+ }
5388
+ `;
5389
+ }}
5390
+ `;
5391
+ var OverlayContainer = exports.styled.div`
5392
+ position: absolute;
5393
+ inset: 0;
5394
+ display: flex;
5395
+ flex-direction: column;
5396
+ align-items: center;
5397
+ justify-content: center;
5398
+ z-index: 1;
5399
+ background: ${({ $transparent, theme: theme2 }) => $transparent ? "transparent" : theme2.components.loading.wrapper.overlayBackground};
5400
+ gap: ${({ $hasTip, theme: theme2 }) => $hasTip ? theme2.components.loading.indicator.gap : "0"};
5401
+ `;
5402
+ var Tip2 = exports.styled.span`
5403
+ font-size: 14px;
5404
+ line-height: 1.5;
5405
+ color: ${({ theme: theme2 }) => theme2.components.loading.tipColor};
5406
+ `;
5407
+ var LoadingOverlay = ({
5408
+ size = "medium",
5409
+ spinning = true,
5410
+ delay = 0,
5411
+ tip,
5412
+ className,
5413
+ indicator,
5414
+ transparent = false
5415
+ }) => {
5416
+ const [shouldShow, setShouldShow] = React3.useState(delay === 0 && spinning);
5417
+ React3.useEffect(() => {
5418
+ if (!spinning) {
5419
+ setShouldShow(false);
5420
+ return;
5421
+ }
5422
+ if (delay <= 0) {
5423
+ setShouldShow(true);
5424
+ return;
5425
+ }
5426
+ const timer = setTimeout(() => setShouldShow(true), delay);
5427
+ return () => clearTimeout(timer);
5428
+ }, [spinning, delay]);
5429
+ const renderIndicator = () => {
5430
+ const a11yProps = { role: "status", "aria-label": "Loading" };
5431
+ if (typeof indicator === "string") {
5432
+ return /* @__PURE__ */ React3__default.default.createElement(SpinnerImage2, { $size: size, src: indicator, alt: "Loading", ...a11yProps });
5433
+ }
5434
+ if (indicator) {
5435
+ return /* @__PURE__ */ React3__default.default.createElement(CustomIndicatorWrapper2, { $size: size, ...a11yProps }, indicator);
5436
+ }
5437
+ const { indicator: indicatorConfig } = exports.getGlobalTheme().components.loading;
5438
+ if (indicatorConfig.defaultType === "css") {
5439
+ return /* @__PURE__ */ React3__default.default.createElement(CSSSpinner2, { $size: size, ...a11yProps });
5440
+ }
5441
+ return /* @__PURE__ */ React3__default.default.createElement(
5442
+ SpinnerImage2,
5443
+ {
5444
+ $size: size,
5445
+ src: indicatorConfig.defaultImage || loading_default,
5446
+ alt: "Loading",
5447
+ ...a11yProps
5448
+ }
5449
+ );
5450
+ };
5451
+ if (!shouldShow) return null;
5452
+ return /* @__PURE__ */ React3__default.default.createElement(OverlayContainer, { $hasTip: !!tip, $transparent: transparent, className }, renderIndicator(), tip && /* @__PURE__ */ React3__default.default.createElement(Tip2, null, tip));
5453
+ };
5454
+ LoadingOverlay.displayName = "LoadingOverlay";
5455
+
5323
5456
  // src/index.ts
5324
5457
  init_UIConfigProvider2();
5325
5458
  init_styled();
@@ -5331,6 +5464,7 @@ exports.DropdownButton = DropdownButton2;
5331
5464
  exports.DropdownGlobalStyles = DropdownGlobalStyles;
5332
5465
  exports.Input = Input;
5333
5466
  exports.Loading = Loading;
5467
+ exports.LoadingOverlay = LoadingOverlay;
5334
5468
  exports.Menu = Menu;
5335
5469
  exports.MenuGlobalStyles = MenuGlobalStyles;
5336
5470
  exports.Modal = Modal;