• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SAP / ui5-webcomponents-react / 11378639275

17 Oct 2024 05:00AM CUT coverage: 87.181%. Remained the same
11378639275

push

github

web-flow
chore(deps): update coverallsapp/github-action action to v2.3.3 (#6504)

2884 of 3845 branches covered (75.01%)

5060 of 5804 relevant lines covered (87.18%)

94347.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

47.69
/packages/main/src/components/Modals/index.tsx
1
'use client';
2

3
import type { RefObject } from 'react';
4
import { createRef } from 'react';
5
import { createPortal } from 'react-dom';
6
import { useSyncExternalStore } from 'use-sync-external-store/shim/index.js';
7
import { getRandomId } from '../../internal/getRandomId.js';
8
import { ModalStore } from '../../internal/ModalStore.js';
9
import type {
10
  DialogDomRef,
11
  DialogPropTypes,
12
  MenuDomRef,
13
  MenuPropTypes,
14
  PopoverDomRef,
15
  PopoverPropTypes,
16
  ResponsivePopoverDomRef,
17
  ResponsivePopoverPropTypes,
18
  ToastDomRef,
19
  ToastPropTypes
20
} from '../../webComponents/index.js';
21
import { Dialog, Menu, Popover, ResponsivePopover, Toast } from '../../webComponents/index.js';
22
import type { MessageBoxPropTypes } from '../MessageBox/index.js';
23
import { MessageBox } from '../MessageBox/index.js';
24

25
type ModalReturnType<DomRef> = {
26
  ref: RefObject<DomRef>;
27
};
28

29
type ClosableModalReturnType<DomRef> = ModalReturnType<DomRef> & {
30
  close: () => void;
31
};
32

33
function showDialogFn(
34
  props: DialogPropTypes,
35
  container?: Element | DocumentFragment
36
): ClosableModalReturnType<DialogDomRef> {
37
  const id = getRandomId();
7✔
38
  const ref = createRef<DialogDomRef>();
7✔
39
  ModalStore.addModal({
7✔
40
    Component: Dialog,
41
    props: {
42
      ...props,
43
      open: true,
44
      onClose: (event) => {
45
        if (typeof props.onClose === 'function') {
7!
46
          props.onClose(event);
×
47
        }
48
        ModalStore.removeModal(id);
7✔
49
      }
50
    },
51
    ref,
52
    container,
53
    id
54
  });
55

56
  return {
7✔
57
    ref,
58
    close: () => {
59
      if (ref.current) {
7✔
60
        ref.current.open = false;
7✔
61
      }
62
    }
63
  };
64
}
65

66
function showPopoverFn(
67
  props: PopoverPropTypes,
68
  container?: Element | DocumentFragment
69
): ClosableModalReturnType<PopoverDomRef> {
70
  const id = getRandomId();
×
71
  const ref = createRef<PopoverDomRef>();
×
72
  ModalStore.addModal({
×
73
    Component: Popover,
74
    props: {
75
      ...props,
76

77
      open: true,
78
      onClose: (event) => {
79
        if (typeof props.onClose === 'function') {
×
80
          props.onClose(event);
×
81
        }
82
        ModalStore.removeModal(id);
×
83
      }
84
    },
85
    ref,
86
    container,
87
    id
88
  });
89

90
  return {
×
91
    ref,
92
    close: () => {
93
      if (ref.current) {
×
94
        ref.current.open = false;
×
95
      }
96
    }
97
  };
98
}
99

100
function showResponsivePopoverFn(
101
  props: ResponsivePopoverPropTypes,
102
  container?: Element | DocumentFragment
103
): ClosableModalReturnType<ResponsivePopoverDomRef> {
104
  const id = getRandomId();
×
105
  const ref = createRef<ResponsivePopoverDomRef>();
×
106
  ModalStore.addModal({
×
107
    Component: ResponsivePopover,
108
    props: {
109
      ...props,
110
      open: true,
111
      onClose: (event) => {
112
        if (typeof props.onClose === 'function') {
×
113
          props.onClose(event);
×
114
        }
115
        ModalStore.removeModal(id);
×
116
      }
117
    },
118
    ref,
119
    container,
120
    id
121
  });
122

123
  return {
×
124
    ref,
125
    close: () => {
126
      if (ref.current) {
×
127
        ref.current.open = false;
×
128
      }
129
    }
130
  };
131
}
132

133
function showMenuFn(props: MenuPropTypes, container?: Element | DocumentFragment): ClosableModalReturnType<MenuDomRef> {
134
  const id = getRandomId();
×
135
  const ref = createRef<MenuDomRef>();
×
136
  ModalStore.addModal({
×
137
    Component: Menu,
138
    props: {
139
      ...props,
140
      open: true,
141
      onClose: (event) => {
142
        if (typeof props.onClose === 'function') {
×
143
          props.onClose(event);
×
144
        }
145
        ModalStore.removeModal(id);
×
146
      }
147
    },
148
    ref,
149
    container,
150
    id
151
  });
152

153
  return {
×
154
    ref,
155
    close: () => {
156
      if (ref.current) {
×
157
        ref.current.open = false;
×
158
      }
159
    }
160
  };
161
}
162

163
function showMessageBoxFn(
164
  props: MessageBoxPropTypes,
165
  container?: Element | DocumentFragment
166
): ClosableModalReturnType<DialogDomRef> {
167
  const id = getRandomId();
3✔
168
  const ref = createRef<DialogDomRef>();
3✔
169
  ModalStore.addModal({
3✔
170
    // @ts-expect-error: props type safety is covered by the `props` property
171
    Component: MessageBox,
172
    props: {
173
      ...props,
174
      open: true,
175
      onClose: (event) => {
176
        if (typeof props.onClose === 'function') {
3!
177
          props.onClose(event);
×
178
        }
179
        ModalStore.removeModal(id);
3✔
180
      }
181
    },
182
    ref,
183
    container,
184
    id
185
  });
186

187
  return {
3✔
188
    ref,
189
    close: () => {
190
      if (ref.current) {
×
191
        ref.current.open = false;
×
192
      }
193
    }
194
  };
195
}
196

197
function showToastFn(props: ToastPropTypes, container?: Element | DocumentFragment): ModalReturnType<ToastDomRef> {
198
  const ref = createRef<ToastDomRef>();
2✔
199
  const id = getRandomId();
2✔
200
  ModalStore.addModal({
2✔
201
    Component: Toast,
202
    props: {
203
      ...props,
204
      open: true,
205
      onClose: (event) => {
206
        if (typeof props.onClose === 'function') {
×
207
          props.onClose(event);
×
208
        }
209
        ModalStore.removeModal(id);
×
210
      }
211
    },
212
    ref,
213
    container,
214
    id
215
  });
216

217
  return {
2✔
218
    ref
219
  };
220
}
221

222
/**
223
 * Utility class for opening modals in an imperative way.
224
 *
225
 * These static helper methods might be useful for showing e.g. Toasts or MessageBoxes after successful or failed
226
 * network calls.
227
 *
228
 * **In order to use these helpers, please make sure to render the `Modals` component somewhere in your application tree.**
229
 *
230
 * @since 0.22.2
231
 */
232
export function Modals() {
233
  const modals = useSyncExternalStore(ModalStore.subscribe, ModalStore.getSnapshot, ModalStore.getServerSnapshot);
34✔
234

235
  return (
34✔
236
    <>
237
      {modals.map((modal) => {
238
        if (modal?.Component) {
12✔
239
          if (modal.container) {
12✔
240
            return createPortal(
2✔
241
              // @ts-expect-error: ref is supported by all supported modals
242
              <modal.Component {...modal.props} ref={modal.ref} key={modal.id} data-id={modal.id} />,
243
              modal.container
244
            );
245
          }
246
          // @ts-expect-error: ref is supported by all supported modals
247
          return <modal.Component {...modal.props} ref={modal.ref} key={modal.id} data-id={modal.id} />;
10✔
248
        }
249
      })}
250
    </>
251
  );
252
}
253

254
Modals.displayName = 'Modals';
407✔
255

256
Modals.showDialog = showDialogFn;
407✔
257
Modals.showPopover = showPopoverFn;
407✔
258
Modals.showResponsivePopover = showResponsivePopoverFn;
407✔
259
Modals.showMenu = showMenuFn;
407✔
260
Modals.showMessageBox = showMessageBoxFn;
407✔
261
Modals.showToast = showToastFn;
407✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc