@jetbrains/ring-ui 8.0.0-beta.1 → 8.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/babel.config.js +1 -9
  2. package/components/alert/alert-actions.d.ts +4 -0
  3. package/components/alert/alert-actions.js +5 -0
  4. package/components/alert/alert-heading.d.ts +4 -0
  5. package/components/alert/alert-heading.js +6 -0
  6. package/components/alert/alert.css +63 -22
  7. package/components/alert/alert.d.ts +14 -1
  8. package/components/alert/alert.js +34 -19
  9. package/components/alert/container.css +1 -2
  10. package/components/alert-service/alert-service.d.ts +2 -1
  11. package/components/alert-service/alert-service.js +8 -4
  12. package/components/auth/auth-core.d.ts +5 -9
  13. package/components/auth/auth-core.js +56 -15
  14. package/components/auth-dialog-service/auth-dialog-service.js +5 -2
  15. package/components/avatar/avatar-info.js +0 -2
  16. package/components/avatar/avatar-size.d.ts +0 -4
  17. package/components/avatar/avatar-size.js +0 -4
  18. package/components/avatar/avatar.js +0 -6
  19. package/components/avatar/fallback-avatar.js +0 -28
  20. package/components/avatar-stack/avatar-stack.js +1 -1
  21. package/components/banner/banner.css +3 -3
  22. package/components/button/button.css +4 -4
  23. package/components/button/button.d.ts +0 -4
  24. package/components/button/button.js +2 -7
  25. package/components/button-group/button-group.css +5 -5
  26. package/components/checkbox/checkbox.d.ts +1 -1
  27. package/components/collapse/collapse-content.d.ts +7 -0
  28. package/components/collapse/collapse-content.js +44 -11
  29. package/components/collapse/collapse-context.d.ts +2 -0
  30. package/components/collapse/collapse-context.js +2 -0
  31. package/components/collapse/collapse-control.js +2 -2
  32. package/components/collapse/collapse.css +8 -2
  33. package/components/collapse/collapse.d.ts +9 -0
  34. package/components/collapse/collapse.js +12 -3
  35. package/components/{expand → collapsible-group}/collapsible-group.css +7 -1
  36. package/components/collapsible-group/collapsible-group.d.ts +33 -0
  37. package/components/{expand → collapsible-group}/collapsible-group.js +13 -21
  38. package/components/confirm/confirm.js +12 -8
  39. package/components/confirm-service/confirm-service.js +5 -2
  40. package/components/data-list/data-list.d.ts +1 -1
  41. package/components/data-list/data-list.mock.d.ts +1 -1
  42. package/components/data-list/item.d.ts +1 -1
  43. package/components/data-list/selection.d.ts +1 -1
  44. package/components/data-list/selection.js +1 -1
  45. package/components/date-picker/consts.d.ts +1 -0
  46. package/components/date-picker/date-input.js +6 -2
  47. package/components/date-picker/months.js +2 -2
  48. package/components/date-picker/use-scroll-behavior.js +5 -6
  49. package/components/date-picker/years.js +2 -2
  50. package/components/dialog/dialog-controls.d.ts +13 -0
  51. package/components/dialog/dialog-controls.js +17 -0
  52. package/components/dialog/dialog-geometry.d.ts +31 -0
  53. package/components/dialog/dialog-geometry.js +48 -0
  54. package/components/dialog/dialog.css +166 -27
  55. package/components/dialog/dialog.d.ts +15 -7
  56. package/components/dialog/dialog.js +110 -29
  57. package/components/dropdown-menu/dropdown-menu.d.ts +4 -4
  58. package/components/dropdown-menu/dropdown-menu.js +4 -4
  59. package/components/editable-heading/editable-heading.d.ts +1 -2
  60. package/components/editable-heading/editable-heading.js +18 -19
  61. package/components/global/compose-refs.d.ts +2 -1
  62. package/components/global/compose-refs.js +24 -8
  63. package/components/global/create-stateful-context.js +5 -5
  64. package/components/global/focus-with-temporary-tabindex.d.ts +11 -0
  65. package/components/global/focus-with-temporary-tabindex.js +21 -0
  66. package/components/global/get-viewport-size.d.ts +5 -0
  67. package/components/global/get-viewport-size.js +5 -0
  68. package/components/global/intersection-observer-context.d.ts +31 -11
  69. package/components/global/intersection-observer-context.js +47 -28
  70. package/components/global/is-within-interactive-element.d.ts +6 -0
  71. package/components/global/is-within-interactive-element.js +26 -0
  72. package/components/global/is-within-navigable-element.d.ts +6 -0
  73. package/components/global/is-within-navigable-element.js +27 -0
  74. package/components/global/parse-css-duration.d.ts +5 -0
  75. package/components/global/parse-css-duration.js +13 -0
  76. package/components/global/rerender-hoc.d.ts +4 -2
  77. package/components/global/rerender-hoc.js +4 -4
  78. package/components/global/schedule-with-cleanup.d.ts +12 -0
  79. package/components/global/schedule-with-cleanup.js +34 -0
  80. package/components/{legacy-table/selection.d.ts → global/table-selection.d.ts} +14 -14
  81. package/components/{legacy-table/selection.js → global/table-selection.js} +2 -2
  82. package/components/global/theme.d.ts +4 -3
  83. package/components/global/theme.js +8 -8
  84. package/components/global/variables.css +18 -28
  85. package/components/global/variables.interface.d.ts +0 -4
  86. package/components/global/variables_dark.css +18 -25
  87. package/components/header/header.css +3 -3
  88. package/components/http/http.d.ts +2 -2
  89. package/components/http/http.js +6 -17
  90. package/components/i18n/i18n-context.js +1 -1
  91. package/components/i18n/i18n.d.ts +1 -0
  92. package/components/i18n/messages.json +1 -0
  93. package/components/icon/icon.css +0 -27
  94. package/components/icon/icon.d.ts +0 -1
  95. package/components/icon/icon.js +2 -4
  96. package/components/input/input.d.ts +1 -1
  97. package/components/island/adaptive-island-hoc.js +4 -4
  98. package/components/island/content.d.ts +7 -2
  99. package/components/island/content.js +5 -5
  100. package/components/island/header.js +1 -1
  101. package/components/legacy-table/cell.js +1 -1
  102. package/components/legacy-table/header-cell.js +1 -1
  103. package/components/legacy-table/header.js +1 -1
  104. package/components/legacy-table/multitable.d.ts +1 -1
  105. package/components/legacy-table/row.d.ts +1 -1
  106. package/components/legacy-table/row.js +1 -1
  107. package/components/legacy-table/selection-adapter.d.ts +3 -3
  108. package/components/legacy-table/selection-shortcuts-hoc.d.ts +5 -5
  109. package/components/legacy-table/simple-table.d.ts +2 -2
  110. package/components/legacy-table/simple-table.js +3 -3
  111. package/components/legacy-table/smart-table.d.ts +5 -5
  112. package/components/legacy-table/smart-table.js +3 -3
  113. package/components/legacy-table/table.js +1 -1
  114. package/components/list/consts.d.ts +0 -1
  115. package/components/list/consts.js +0 -1
  116. package/components/list/list.d.ts +0 -4
  117. package/components/login-dialog/service.js +5 -2
  118. package/components/panel/panel.css +1 -1
  119. package/components/popup/popup.d.ts +2 -0
  120. package/components/popup/popup.js +2 -2
  121. package/components/popup/popup.target.d.ts +3 -2
  122. package/components/popup/popup.target.js +4 -6
  123. package/components/query-assist/query-assist.d.ts +3 -1
  124. package/components/query-assist/query-assist.js +2 -2
  125. package/components/radio/radio-item.d.ts +3 -3
  126. package/components/radio/radio-item.js +3 -4
  127. package/components/radio/radio.d.ts +2 -2
  128. package/components/radio/radio.js +1 -1
  129. package/components/select/select-popup.d.ts +3 -2
  130. package/components/select/select-popup.js +3 -3
  131. package/components/select/select.d.ts +6 -2
  132. package/components/select/select.js +2 -4
  133. package/components/selection-toolbar/selection-toolbar.css +86 -0
  134. package/components/selection-toolbar/selection-toolbar.d.ts +11 -0
  135. package/components/selection-toolbar/selection-toolbar.js +23 -0
  136. package/components/slider/slider.js +4 -5
  137. package/components/tab-trap/tab-trap.d.ts +3 -3
  138. package/components/tab-trap/tab-trap.js +3 -5
  139. package/components/table/default-item-renderer.d.ts +41 -11
  140. package/components/table/default-item-renderer.js +60 -47
  141. package/components/table/internal/reorder-animation-context.d.ts +21 -0
  142. package/components/table/internal/reorder-animation-context.js +60 -0
  143. package/components/table/internal/reorder-handle.d.ts +9 -0
  144. package/components/table/internal/reorder-handle.js +334 -0
  145. package/components/table/internal/reorder-layout-context.d.ts +16 -0
  146. package/components/table/internal/reorder-layout-context.js +69 -0
  147. package/components/table/internal/table-header.d.ts +1 -0
  148. package/components/table/internal/table-header.js +143 -0
  149. package/components/table/internal/virtualization.d.ts +41 -0
  150. package/components/table/{table-virtualize.js → internal/virtualization.js} +82 -46
  151. package/components/table/item-virtualization.d.ts +37 -0
  152. package/components/table/item-virtualization.js +26 -0
  153. package/components/table/reorder-animation.d.ts +37 -0
  154. package/components/table/reorder-animation.js +11 -0
  155. package/components/table/reorder-item-layout.d.ts +32 -0
  156. package/components/table/reorder-item-layout.js +23 -0
  157. package/components/table/table-const.d.ts +8 -6
  158. package/components/table/table-const.js +7 -5
  159. package/components/table/table-primitives.d.ts +64 -0
  160. package/components/table/table-primitives.js +34 -0
  161. package/components/table/table-props.d.ts +304 -0
  162. package/components/table/table-props.js +1 -0
  163. package/components/table/table.css +179 -67
  164. package/components/table/table.d.ts +231 -224
  165. package/components/table/table.js +327 -2
  166. package/components/tag/tag.css +3 -3
  167. package/components/tags-input/tags-input.d.ts +3 -1
  168. package/components/tooltip/tooltip.d.ts +2 -1
  169. package/components/tooltip/tooltip.js +6 -5
  170. package/components/upload/upload.d.ts +4 -3
  171. package/components/upload/upload.js +3 -7
  172. package/components/user-agreement/service.js +5 -2
  173. package/components/user-agreement/user-agreement.css +2 -8
  174. package/components/user-agreement/user-agreement.js +8 -10
  175. package/components/user-card/smart-user-card-tooltip.d.ts +1 -1
  176. package/components/util-stories.d.ts +26 -0
  177. package/components/util-stories.js +61 -0
  178. package/package.json +47 -50
  179. package/components/content-layout/content-layout.css +0 -109
  180. package/components/content-layout/content-layout.d.ts +0 -20
  181. package/components/content-layout/content-layout.js +0 -40
  182. package/components/content-layout/sidebar.d.ts +0 -26
  183. package/components/content-layout/sidebar.js +0 -71
  184. package/components/date-picker/use-intersection-observer.d.ts +0 -6
  185. package/components/date-picker/use-intersection-observer.js +0 -48
  186. package/components/expand/collapsible-group.d.ts +0 -16
  187. package/components/global/composeRefs.d.ts +0 -6
  188. package/components/global/composeRefs.js +0 -7
  189. package/components/global/use-event-callback.d.ts +0 -1
  190. package/components/global/use-event-callback.js +0 -15
  191. package/components/grid/col.d.ts +0 -16
  192. package/components/grid/col.js +0 -35
  193. package/components/grid/grid.css +0 -920
  194. package/components/grid/grid.d.ts +0 -13
  195. package/components/grid/grid.js +0 -19
  196. package/components/grid/row.d.ts +0 -21
  197. package/components/grid/row.js +0 -41
  198. package/components/old-browsers-message/__mocks__/old-browsers-message.js +0 -1
  199. package/components/old-browsers-message/old-browsers-message-stop.d.ts +0 -1
  200. package/components/old-browsers-message/old-browsers-message-stop.js +0 -2
  201. package/components/old-browsers-message/old-browsers-message.css +0 -26
  202. package/components/old-browsers-message/old-browsers-message.d.ts +0 -5
  203. package/components/old-browsers-message/old-browsers-message.js +0 -86
  204. package/components/old-browsers-message/white-list.d.ts +0 -2
  205. package/components/old-browsers-message/white-list.js +0 -24
  206. package/components/table/table-base.d.ts +0 -24
  207. package/components/table/table-base.js +0 -79
  208. package/components/table/table-component.d.ts +0 -53
  209. package/components/table/table-component.js +0 -101
  210. package/components/table/table-virtualize.d.ts +0 -32
  211. /package/components/legacy-table/{table.css → legacy-table.css} +0 -0
@@ -5,7 +5,7 @@ import { Component } from 'react';
5
5
  import { type FocusSensorOuterProps } from '../global/focus-sensor-hoc';
6
6
  import { type SelectionShortcutsAddProps, type SelectionShortcutsOuterProps } from '../legacy-table/selection-shortcuts-hoc';
7
7
  import { type DisableHoverAddProps } from '../legacy-table/disable-hover-hoc';
8
- import { type SelectionItem } from '../legacy-table/selection';
8
+ import { type SelectionItem } from '../global/table-selection';
9
9
  import { type FormattedItem, moreLessButtonStates } from './item';
10
10
  export interface DataListBaseProps<T extends SelectionItem> {
11
11
  data: readonly T[];
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
- import { type SelectionItem } from '../legacy-table/selection';
2
+ import { type SelectionItem } from '../global/table-selection';
3
3
  export interface Item extends SelectionItem {
4
4
  title: ReactNode;
5
5
  collapsible?: boolean;
@@ -1,5 +1,5 @@
1
1
  import { PureComponent, type ReactNode } from 'react';
2
- import { type SelectionItem } from '../legacy-table/selection';
2
+ import { type SelectionItem } from '../global/table-selection';
3
3
  import type Selection from './selection';
4
4
  export declare enum moreLessButtonStates {
5
5
  UNUSED = 0,
@@ -1,4 +1,4 @@
1
- import TableSelection, { type CloneWithConfig, type SelectionItem, type TableSelectionConfig } from '../legacy-table/selection';
1
+ import TableSelection, { type CloneWithConfig, type SelectionItem, type TableSelectionConfig } from '../global/table-selection';
2
2
  interface DataListSelectionConfig<T extends SelectionItem> extends TableSelectionConfig<T> {
3
3
  partialSelected?: Set<T> | undefined;
4
4
  }
@@ -1,4 +1,4 @@
1
- import TableSelection from '../legacy-table/selection';
1
+ import TableSelection from '../global/table-selection';
2
2
  export default class Selection extends TableSelection {
3
3
  _partialSelected;
4
4
  constructor({ partialSelected = new Set(), ...props }) {
@@ -34,6 +34,7 @@ export interface DateInputTranslations {
34
34
  addSecondDate?: string;
35
35
  addTime?: string;
36
36
  selectName?: string;
37
+ selectDate?: string;
37
38
  }
38
39
  export interface DateSpecificPopupProps {
39
40
  withTime?: false | undefined;
@@ -47,7 +47,7 @@ export default class DateInput extends React.PureComponent {
47
47
  };
48
48
  render() {
49
49
  const { active, divider, text, time, name, hoverDate, date, displayFormat, translations, onActivate, onClear, fromPlaceholder, toPlaceholder, timePlaceholder, locale, } = this.props;
50
- const { translate } = this.context;
50
+ const { messages, translate } = this.context;
51
51
  let displayText = '';
52
52
  if (active && hoverDate) {
53
53
  displayText = displayFormat(hoverDate, locale);
@@ -70,7 +70,11 @@ export default class DateInput extends React.PureComponent {
70
70
  case 'time':
71
71
  return timePlaceholder || (translations?.addTime ?? translate('addTime'));
72
72
  default:
73
- return (translations?.selectName ?? translate('selectName'))
73
+ return (translations?.selectDate ??
74
+ translations?.selectName ??
75
+ messages.selectDate ??
76
+ messages.selectName ??
77
+ translate('selectDate'))
74
78
  .replace('%name%', name)
75
79
  .replace('{{name}}', name);
76
80
  }
@@ -29,9 +29,9 @@ const intersectionObserverRootMargin = units.cellSize * 2;
29
29
  export default function Months(props) {
30
30
  const { scrollDate, setScrollDate, locale } = props;
31
31
  const { containerRef, items } = useScrollBehavior(scrollDate, setScrollDate, locale, 'monthsScroll', scrollArith, scheduleScroll);
32
- return (<IntersectionObserverContext.Provider value={useIntersectionObserverHandle(containerRef, intersectionObserverRootMargin)}>
32
+ return (<IntersectionObserverContext value={useIntersectionObserverHandle(containerRef, intersectionObserverRootMargin)}>
33
33
  <div className={styles.months} ref={containerRef} data-test='ring-date-popup--months'>
34
34
  {items.map(month => (<Month {...props} month={month} key={+month}/>))}
35
35
  </div>
36
- </IntersectionObserverContext.Provider>);
36
+ </IntersectionObserverContext>);
37
37
  }
@@ -1,11 +1,10 @@
1
- import { useEffect, useLayoutEffect, useRef, useState } from 'react';
1
+ import { useEffect, useEffectEvent, useLayoutEffect, useRef, useState } from 'react';
2
2
  import units, { isSafariOnIPhone, scrollerReRenderDelayIPhone } from './consts';
3
- import useEventCallback from '../global/use-event-callback';
4
3
  export function useScrollBehavior(scrollDate, onContainerScroll, locale, selfScrollDateSource, arith, scheduleScroll) {
5
4
  const [items, setItems] = useState(() => arith.getItems(scrollDate.date));
6
5
  const [scrollTop, setScrollTop] = useState(() => arith.getScrollTop(items, scrollDate.date, locale));
7
6
  const containerRef = useRef(null);
8
- const syncSelfState = useEventCallback((newScrollDate) => {
7
+ const syncSelfState = useEffectEvent((newScrollDate) => {
9
8
  const newScrollTopOnExistingItems = arith.getScrollTop(items, newScrollDate, locale);
10
9
  if (isNearEdge(newScrollTopOnExistingItems, containerRef.current)) {
11
10
  const { newItems, newScrollTop } = arith.getItemsAndScrollTop(newScrollDate, locale);
@@ -28,7 +27,7 @@ export function useScrollBehavior(scrollDate, onContainerScroll, locale, selfScr
28
27
  if (scrollDate.source === selfScrollDateSource)
29
28
  return;
30
29
  syncSelfState(scrollDate.date);
31
- }, [scrollDate, selfScrollDateSource, syncSelfState]);
30
+ }, [scrollDate, selfScrollDateSource]);
32
31
  const ignoreNextScrollEventRef = useRef(true);
33
32
  useLayoutEffect(function setContainerScrollFromState() {
34
33
  const container = containerRef.current;
@@ -38,7 +37,7 @@ export function useScrollBehavior(scrollDate, onContainerScroll, locale, selfScr
38
37
  container.scrollTop = scrollTop;
39
38
  }, [items, scrollTop]);
40
39
  const updateStateTimerRef = useRef(null);
41
- const handleScroll = useEventCallback(() => {
40
+ const handleScroll = useEffectEvent(() => {
42
41
  scheduleScroll(() => {
43
42
  if (updateStateTimerRef.current != null) {
44
43
  window.clearTimeout(updateStateTimerRef.current);
@@ -83,7 +82,7 @@ export function useScrollBehavior(scrollDate, onContainerScroll, locale, selfScr
83
82
  updateStateTimerRef.current = null;
84
83
  }
85
84
  };
86
- }, [handleScroll]);
85
+ }, []);
87
86
  return { containerRef, items };
88
87
  }
89
88
  function isNearEdge(scrollTop, container) {
@@ -87,11 +87,11 @@ export default function Years({ scrollDate, setScrollDate }) {
87
87
  }, yearsAnimationDuration);
88
88
  }, [localScrollDate.date, setScrollDate]);
89
89
  const { containerRef, items } = useScrollBehavior(localScrollDate, syncCalendarScrollDate, undefined, 'yearsScroll', scrollArith, scheduleScroll);
90
- return (<IntersectionObserverContext.Provider value={useIntersectionObserverHandle(containerRef, intersectionObserverRootMargin)}>
90
+ return (<IntersectionObserverContext value={useIntersectionObserverHandle(containerRef, intersectionObserverRootMargin)}>
91
91
  <div className={styles.years} ref={containerRef} data-test='ring-date-popup--years'>
92
92
  {items.map(year => (<Year year={year} scrollDate={localScrollDate.date} handleYearClick={handleYearClick} key={+year}/>))}
93
93
  </div>
94
- </IntersectionObserverContext.Provider>);
94
+ </IntersectionObserverContext>);
95
95
  }
96
96
  function Year({ year, scrollDate, handleYearClick, }) {
97
97
  const buttonRef = useRef(null);
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import type { InteractionDirection } from './dialog-geometry';
3
+ interface DialogControlsProps {
4
+ movable: boolean | undefined;
5
+ resizable: boolean | undefined;
6
+ showCloseButton: boolean;
7
+ closeButtonTitle: string | undefined;
8
+ onCloseClick: React.MouseEventHandler<HTMLElement>;
9
+ onStartInteraction: (event: React.PointerEvent<HTMLElement>, direction: InteractionDirection) => void;
10
+ onStopInteraction: React.PointerEventHandler<HTMLElement>;
11
+ }
12
+ export default function DialogControls({ movable, resizable, showCloseButton, closeButtonTitle, onCloseClick, onStartInteraction, onStopInteraction, }: DialogControlsProps): React.JSX.Element;
13
+ export {};
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+ import closeIcon from '@jetbrains/icons/close';
3
+ import resizeIcon from '@jetbrains/icons/resize-corner-12px';
4
+ import Button from '../button/button';
5
+ import Icon from '../icon/icon';
6
+ import styles from './dialog.css';
7
+ const resizeDirections = ['n', 'ne', 'e', 's', 'sw', 'w', 'nw', 'se'];
8
+ export default function DialogControls({ movable, resizable, showCloseButton, closeButtonTitle, onCloseClick, onStartInteraction, onStopInteraction, }) {
9
+ return (<>
10
+ {movable && (<div aria-hidden='true' className={styles.moveHandle} data-ring-dialog-move-handle='' data-test='ring-dialog-move-handle' onLostPointerCapture={onStopInteraction}/>)}
11
+ {showCloseButton && (<Button icon={closeIcon} data-test='ring-dialog-close-button' className={styles.closeButton} iconClassName={styles.closeIcon} onClick={onCloseClick} title={closeButtonTitle} aria-label={closeButtonTitle || 'close dialog'}/>)}
12
+ {resizable && (<>
13
+ {resizeDirections.map(direction => (<div aria-hidden='true' className={styles.resizeHandle} data-resize-direction={direction} data-test={`ring-dialog-resize-handle-${direction}`} key={direction} onPointerDown={event => onStartInteraction(event, direction)} onPointerUp={onStopInteraction} onPointerCancel={onStopInteraction} onLostPointerCapture={onStopInteraction}/>))}
14
+ <Icon aria-hidden='true' className={styles.resizeMarker} data-test='ring-dialog-resize-marker' glyph={resizeIcon}/>
15
+ </>)}
16
+ </>);
17
+ }
@@ -0,0 +1,31 @@
1
+ export type ResizeDirection = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';
2
+ export type InteractionDirection = 'move' | ResizeDirection;
3
+ export interface Geometry {
4
+ left: number;
5
+ top: number;
6
+ width: number;
7
+ height: number;
8
+ }
9
+ export interface DialogState {
10
+ shortcutsScope: string;
11
+ geometry: Geometry | null;
12
+ resized: boolean;
13
+ }
14
+ export interface Interaction {
15
+ pointerId: number;
16
+ direction: InteractionDirection;
17
+ startX: number;
18
+ startY: number;
19
+ minWidth: number;
20
+ minHeight: number;
21
+ geometry: Geometry;
22
+ }
23
+ export declare const getNativeTabIndex: (autoFocusFirst: boolean | undefined) => -1 | undefined;
24
+ export declare const getTrapDisabled: (trapFocus: boolean, trapDisabled: boolean | undefined) => boolean;
25
+ export declare const getResizeMinimum: (element: Element) => {
26
+ minWidth: number;
27
+ minHeight: number;
28
+ };
29
+ export declare const moveGeometry: (start: Geometry, dx: number, dy: number, viewportWidth: number, viewportHeight: number) => Geometry;
30
+ export declare const fitGeometry: (geometry: Geometry, viewportWidth: number, viewportHeight: number) => Geometry;
31
+ export declare const resizeGeometry: ({ geometry: start, direction, minWidth, minHeight }: Interaction, dx: number, dy: number, viewportWidth: number, viewportHeight: number) => Geometry;
@@ -0,0 +1,48 @@
1
+ const MIN_WIDTH = 256;
2
+ const MIN_HEIGHT = 160;
3
+ const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
4
+ export const getNativeTabIndex = (autoFocusFirst) => (autoFocusFirst ? undefined : -1);
5
+ export const getTrapDisabled = (trapFocus, trapDisabled) => trapDisabled ?? !trapFocus;
6
+ export const getResizeMinimum = (element) => {
7
+ const { minWidth, minHeight } = getComputedStyle(element);
8
+ const parsedWidth = parseFloat(minWidth);
9
+ const parsedHeight = parseFloat(minHeight);
10
+ return {
11
+ minWidth: Number.isNaN(parsedWidth) ? MIN_WIDTH : parsedWidth,
12
+ minHeight: Number.isNaN(parsedHeight) ? MIN_HEIGHT : parsedHeight,
13
+ };
14
+ };
15
+ export const moveGeometry = (start, dx, dy, viewportWidth, viewportHeight) => ({
16
+ ...start,
17
+ left: clamp(start.left + dx, 0, Math.max(0, viewportWidth - start.width)),
18
+ top: clamp(start.top + dy, 0, Math.max(0, viewportHeight - start.height)),
19
+ });
20
+ export const fitGeometry = (geometry, viewportWidth, viewportHeight) => {
21
+ const width = Math.min(geometry.width, viewportWidth);
22
+ const height = Math.min(geometry.height, viewportHeight);
23
+ return {
24
+ left: clamp(geometry.left, 0, Math.max(0, viewportWidth - width)),
25
+ top: clamp(geometry.top, 0, Math.max(0, viewportHeight - height)),
26
+ width,
27
+ height,
28
+ };
29
+ };
30
+ export const resizeGeometry = ({ geometry: start, direction, minWidth, minHeight }, dx, dy, viewportWidth, viewportHeight) => {
31
+ let left = start.left;
32
+ let right = start.left + start.width;
33
+ let top = start.top;
34
+ let bottom = start.top + start.height;
35
+ if (direction.includes('w')) {
36
+ left = clamp(start.left + dx, 0, right - Math.min(minWidth, right));
37
+ }
38
+ else if (direction.includes('e')) {
39
+ right = clamp(right + dx, left + Math.min(minWidth, viewportWidth - left), viewportWidth);
40
+ }
41
+ if (direction.includes('n')) {
42
+ top = clamp(start.top + dy, 0, bottom - Math.min(minHeight, bottom));
43
+ }
44
+ else if (direction.includes('s')) {
45
+ bottom = clamp(bottom + dy, top + Math.min(minHeight, viewportHeight - top), viewportHeight);
46
+ }
47
+ return { left, top, width: right - left, height: bottom - top };
48
+ };
@@ -1,6 +1,6 @@
1
1
  @import '../global/variables.css';
2
2
 
3
- @value header, scrollableWrapper from '../island/island.css';
3
+ @value content as islandContent, header, title as islandTitle, scrollableWrapper from '../island/island.css';
4
4
  @value panel from '../panel/panel.css';
5
5
 
6
6
  .container {
@@ -41,40 +41,58 @@
41
41
  }
42
42
 
43
43
  .content {
44
+ --dialog-padding: calc(var(--ring-unit) * 2.5);
45
+
44
46
  position: relative;
45
47
 
46
- width: calc(var(--ring-unit) * 58);
47
- min-height: calc(var(--ring-unit) * 15);
48
+ box-sizing: border-box;
49
+ width: calc(var(--ring-unit) * 57.5);
50
+ min-width: var(--ring-dialog-min-width, calc(var(--ring-unit) * 32));
51
+ min-height: var(--ring-dialog-min-height, calc(var(--ring-unit) * 20));
48
52
  margin: auto;
53
+ padding: var(--dialog-padding);
49
54
 
50
55
  cursor: default;
51
56
  overflow-wrap: break-word;
52
57
 
53
58
  & .scrollableWrapper {
54
- padding-bottom: var(--ring-unit);
59
+ padding: var(--ring-unit) var(--dialog-padding) 0;
60
+ }
61
+
62
+ & .islandContent {
63
+ width: calc(100% + var(--dialog-padding) * 2);
64
+ min-height: calc(var(--ring-unit) * 5);
65
+ margin-inline: calc(var(--dialog-padding) * -1);
55
66
  }
56
67
 
57
68
  & .panel {
58
- margin-top: 0;
59
- padding: calc(var(--ring-unit) * 2) calc(var(--ring-unit) * 4) calc(var(--ring-unit) * 4);
69
+ margin-top: auto;
70
+ padding: calc(var(--ring-unit) * 3) 0 0;
60
71
 
61
- border-top: 0;
72
+ text-align: end;
62
73
 
74
+ border-top: 0;
63
75
  background-color: transparent;
64
76
  }
65
77
 
66
78
  /* stylelint-disable-next-line selector-max-specificity */
67
79
  & .panel > button:not(:last-child) {
68
- margin-right: var(--ring-unit);
80
+ margin-inline-end: var(--ring-unit);
69
81
  }
70
82
  }
71
83
 
72
- .contentCloseButtonOutside {
73
- max-width: calc(100dvw - var(--ring-unit) * 8);
84
+ .content {
85
+ max-width: calc(100dvw - var(--ring-unit) * 4);
86
+ max-height: calc(100dvh - var(--ring-unit) * 8);
74
87
  }
75
88
 
76
- .contentCloseButtonInside {
77
- max-width: calc(100dvw - var(--ring-unit) * 4);
89
+ .resized .content.content {
90
+ width: 100%;
91
+ min-width: 0;
92
+ max-width: none;
93
+ height: 100%;
94
+ min-height: 0;
95
+ max-height: none;
78
96
  }
79
97
 
80
98
  .content.content {
@@ -91,10 +109,6 @@
91
109
  cursor: pointer;
92
110
  }
93
111
 
94
- .closeIconOutside.closeIconOutside {
95
- color: var(--ring-icon-hover-color);
96
- }
97
-
98
112
  .clickableOverlay:hover + * .closeIcon {
99
113
  color: var(--ring-link-hover-color);
100
114
  }
@@ -105,18 +119,132 @@
105
119
 
106
120
  .closeButton.closeButton {
107
121
  position: absolute;
122
+ z-index: var(--ring-fixed-z-index);
123
+ inset-block-start: calc(var(--ring-unit) * 2);
124
+ inset-inline-end: calc(var(--ring-unit) * 2);
108
125
 
109
126
  line-height: calc(var(--ring-unit) * 2);
110
127
  }
111
128
 
112
- .closeButtonOutside {
129
+ .moveHandle {
130
+ position: absolute;
131
+ z-index: var(--ring-fixed-z-index);
132
+ top: 0;
133
+ right: 0;
134
+ left: 0;
135
+
136
+ height: var(--dialog-padding);
137
+
138
+ cursor: move;
139
+ touch-action: none;
140
+ }
141
+
142
+ .movable .header {
143
+ cursor: move;
144
+ touch-action: none;
145
+ }
146
+
147
+ .resizeHandle {
148
+ position: absolute;
149
+ z-index: var(--ring-fixed-z-index);
150
+
151
+ touch-action: none;
152
+ }
153
+
154
+ .resizeHandle[data-resize-direction='n'],
155
+ .resizeHandle[data-resize-direction='s'] {
156
+ right: var(--ring-unit);
157
+ left: var(--ring-unit);
158
+
159
+ height: var(--ring-unit);
160
+
161
+ cursor: ns-resize;
162
+ }
163
+
164
+ .resizeHandle[data-resize-direction='n'] {
165
+ top: calc(var(--ring-unit) * -0.5);
166
+ }
167
+
168
+ .resizeHandle[data-resize-direction='s'] {
169
+ bottom: calc(var(--ring-unit) * -0.5);
170
+ }
171
+
172
+ .resizeHandle[data-resize-direction='e'],
173
+ .resizeHandle[data-resize-direction='w'] {
113
174
  top: var(--ring-unit);
114
- right: calc(var(--ring-unit) * -3);
175
+ bottom: var(--ring-unit);
176
+
177
+ width: var(--ring-unit);
178
+
179
+ cursor: ew-resize;
115
180
  }
116
181
 
117
- .closeButtonInside {
118
- top: calc(var(--ring-unit) * 2);
119
- right: calc(var(--ring-unit) * 2);
182
+ .resizeHandle[data-resize-direction='e'] {
183
+ right: calc(var(--ring-unit) * -0.5);
184
+ }
185
+
186
+ .resizeHandle[data-resize-direction='w'] {
187
+ left: calc(var(--ring-unit) * -0.5);
188
+ }
189
+
190
+ .resizeHandle[data-resize-direction='ne'],
191
+ .resizeHandle[data-resize-direction='se'],
192
+ .resizeHandle[data-resize-direction='sw'],
193
+ .resizeHandle[data-resize-direction='nw'] {
194
+ width: calc(var(--ring-unit) * 1.5);
195
+ height: calc(var(--ring-unit) * 1.5);
196
+ }
197
+
198
+ .resizeHandle[data-resize-direction='ne'] {
199
+ top: calc(var(--ring-unit) * -0.5);
200
+ right: calc(var(--ring-unit) * -0.5);
201
+
202
+ cursor: nesw-resize;
203
+ }
204
+
205
+ .resizeHandle[data-resize-direction='se'] {
206
+ right: calc(var(--ring-unit) * -0.5);
207
+ bottom: calc(var(--ring-unit) * -0.5);
208
+
209
+ width: calc(var(--ring-unit) * 2.5);
210
+ height: calc(var(--ring-unit) * 2.5);
211
+
212
+ cursor: nwse-resize;
213
+ }
214
+
215
+ .resizeHandle[data-resize-direction='sw'] {
216
+ bottom: calc(var(--ring-unit) * -0.5);
217
+ left: calc(var(--ring-unit) * -0.5);
218
+
219
+ cursor: nesw-resize;
220
+ }
221
+
222
+ .resizeHandle[data-resize-direction='nw'] {
223
+ top: calc(var(--ring-unit) * -0.5);
224
+ left: calc(var(--ring-unit) * -0.5);
225
+
226
+ cursor: nwse-resize;
227
+ }
228
+
229
+ .resizeMarker {
230
+ position: absolute;
231
+ bottom: calc(var(--ring-unit) * 0.5);
232
+ inset-inline-end: calc(var(--ring-unit) * 0.5);
233
+
234
+ display: flex;
235
+ align-items: center;
236
+ justify-content: center;
237
+
238
+ width: calc(var(--ring-unit) * 1.5);
239
+ height: calc(var(--ring-unit) * 1.5);
240
+
241
+ pointer-events: none;
242
+
243
+ color: var(--ring-secondary-color);
244
+
245
+ &:dir(rtl) {
246
+ transform: scaleX(-1);
247
+ }
120
248
  }
121
249
 
122
250
  .documentWithoutScroll {
@@ -141,16 +269,27 @@
141
269
  }
142
270
 
143
271
  .innerContainer .header {
144
- padding-top: calc(var(--ring-unit) * 4);
272
+ width: calc(100% + var(--dialog-padding) * 2);
273
+ margin-inline: calc(var(--dialog-padding) * -1);
145
274
 
146
- font-size: 24px;
147
- line-height: 28px;
275
+ padding-block: 0;
276
+ padding-inline: var(--dialog-padding) calc(var(--dialog-padding) + var(--ring-unit) * 3);
277
+ padding-block-start: 0 !important;
278
+
279
+ font-size: calc(var(--ring-unit) * 2.5);
280
+ line-height: calc(var(--ring-unit) * 3);
148
281
  }
149
282
 
150
- .dense .header {
151
- padding-top: calc(var(--ring-unit) * 2);
283
+ .innerContainer .islandTitle {
284
+ float: none;
285
+
286
+ text-align: start;
287
+ }
288
+
289
+ .dense {
290
+ --dialog-padding: calc(var(--ring-unit) * 2);
152
291
  }
153
292
 
154
293
  .dense .panel {
155
- padding-bottom: calc(var(--ring-unit) * 2);
294
+ padding-top: calc(var(--ring-unit) * 2);
156
295
  }
@@ -1,6 +1,7 @@
1
1
  import { PureComponent } from 'react';
2
2
  import * as React from 'react';
3
- import TabTrap, { type TabTrapProps } from '../tab-trap/tab-trap';
3
+ import { type TabTrapObject, type TabTrapProps } from '../tab-trap/tab-trap';
4
+ import { type DialogState, type Interaction, type InteractionDirection } from './dialog-geometry';
4
5
  import type { ShortcutsScopeOptions } from '../shortcuts/core';
5
6
  export interface DialogProps extends Partial<TabTrapProps> {
6
7
  show: boolean;
@@ -11,8 +12,9 @@ export interface DialogProps extends Partial<TabTrapProps> {
11
12
  onCloseAttempt: (event: React.MouseEvent<HTMLElement> | KeyboardEvent) => void;
12
13
  showCloseButton: boolean;
13
14
  shortcutOptions: ShortcutsScopeOptions;
14
- closeButtonInside: boolean;
15
15
  closeButtonTitle?: string;
16
+ movable?: boolean;
17
+ resizable?: boolean;
16
18
  trapFocus: boolean;
17
19
  contentClassName?: string | null | undefined;
18
20
  portalTarget?: Element | null | undefined;
@@ -22,11 +24,9 @@ export interface DialogProps extends Partial<TabTrapProps> {
22
24
  modal?: boolean;
23
25
  preventBodyScroll?: boolean;
24
26
  }
25
- export default class Dialog extends PureComponent<DialogProps> {
27
+ export default class Dialog extends PureComponent<DialogProps, DialogState> {
26
28
  static defaultProps: Partial<DialogProps>;
27
- state: {
28
- shortcutsScope: string;
29
- };
29
+ state: DialogState;
30
30
  componentDidMount(): void;
31
31
  componentDidUpdate(prevProps: DialogProps): void;
32
32
  componentWillUnmount(): void;
@@ -43,8 +43,16 @@ export default class Dialog extends PureComponent<DialogProps> {
43
43
  esc: (event: KeyboardEvent) => void;
44
44
  };
45
45
  dialog?: HTMLElement | null;
46
- dialogRef: (tabTrap: TabTrap | null) => void;
46
+ dialogRef: (tabTrapObj: TabTrapObject | null) => void;
47
47
  nativeDialog: React.RefObject<HTMLDialogElement | null>;
48
+ innerContainer: React.RefObject<HTMLDivElement | null>;
49
+ interaction: Interaction | null;
50
+ resizeMinimum: Pick<Interaction, 'minWidth' | 'minHeight'> | null;
51
+ fitGeometryToViewport: () => void;
52
+ startInteraction: (event: React.PointerEvent<HTMLElement>, direction: InteractionDirection) => void;
53
+ continueInteraction: (event: React.PointerEvent<HTMLElement>) => void;
54
+ stopInteraction: (event: React.PointerEvent<HTMLElement>) => void;
55
+ startMove: (event: React.PointerEvent<HTMLElement>) => void;
48
56
  render(): false | React.JSX.Element;
49
57
  }
50
58
  export type DialogAttrs = React.JSX.LibraryManagedAttributes<typeof Dialog, DialogProps>;