react-science 0.19.2 → 0.20.0

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 (126) hide show
  1. package/lib/app/about/AboutDialogToolbarButton.js +10 -10
  2. package/lib/app/explorer/MeasurementExplorer.js +36 -43
  3. package/lib/app/helpers/react-plot.js +16 -13
  4. package/lib/app/kinds/iv/plot-view/IvPlotView.js +14 -13
  5. package/lib/app/panels/measurements/MeasurementCheckbox.js +10 -8
  6. package/lib/app/panels/measurements/MeasurementColorPreview.js +9 -7
  7. package/lib/app/panels/measurements/MeasurementsTable.js +81 -94
  8. package/lib/components/button/ButtonGroup.js +31 -43
  9. package/lib/components/color-picker/color-picker-dropdown/ColorPickerDropdown.js +18 -21
  10. package/lib/components/drop-zone/DropZone.js +48 -48
  11. package/lib/components/dropdown-menu/DropdownMenu.js +4 -4
  12. package/lib/components/forms/Input.js +150 -0
  13. package/lib/components/forms/context/FieldsContext.js +54 -0
  14. package/lib/components/forms/context/index.js +17 -0
  15. package/lib/components/forms/index.js +18 -0
  16. package/lib/components/index.js +1 -0
  17. package/lib/components/modal/ConfirmModal.js +40 -29
  18. package/lib/components/modal/Modal.js +45 -34
  19. package/lib/components/root-layout/RootLayout.js +1 -1
  20. package/lib/components/root-layout/css-reset/customPreflight.js +10 -3
  21. package/lib/components/spinner/FullSpinner.js +10 -7
  22. package/lib-esm/app/about/AboutDialogToolbarButton.d.ts +1 -1
  23. package/lib-esm/app/about/AboutDialogToolbarButton.d.ts.map +1 -1
  24. package/lib-esm/app/about/AboutDialogToolbarButton.js +7 -10
  25. package/lib-esm/app/about/AboutDialogToolbarButton.js.map +1 -1
  26. package/lib-esm/app/explorer/MeasurementExplorer.d.ts +2 -1
  27. package/lib-esm/app/explorer/MeasurementExplorer.d.ts.map +1 -1
  28. package/lib-esm/app/explorer/MeasurementExplorer.js +31 -41
  29. package/lib-esm/app/explorer/MeasurementExplorer.js.map +1 -1
  30. package/lib-esm/app/helpers/MeasurementPlot.js.map +1 -1
  31. package/lib-esm/app/helpers/react-plot.d.ts +4 -2
  32. package/lib-esm/app/helpers/react-plot.d.ts.map +1 -1
  33. package/lib-esm/app/helpers/react-plot.js +11 -11
  34. package/lib-esm/app/helpers/react-plot.js.map +1 -1
  35. package/lib-esm/app/kinds/iv/plot-view/IvPlotView.d.ts +2 -1
  36. package/lib-esm/app/kinds/iv/plot-view/IvPlotView.d.ts.map +1 -1
  37. package/lib-esm/app/kinds/iv/plot-view/IvPlotView.js +14 -13
  38. package/lib-esm/app/kinds/iv/plot-view/IvPlotView.js.map +1 -1
  39. package/lib-esm/app/panels/measurements/MeasurementCheckbox.d.ts +2 -1
  40. package/lib-esm/app/panels/measurements/MeasurementCheckbox.d.ts.map +1 -1
  41. package/lib-esm/app/panels/measurements/MeasurementCheckbox.js +4 -5
  42. package/lib-esm/app/panels/measurements/MeasurementCheckbox.js.map +1 -1
  43. package/lib-esm/app/panels/measurements/MeasurementColorPreview.d.ts +2 -1
  44. package/lib-esm/app/panels/measurements/MeasurementColorPreview.d.ts.map +1 -1
  45. package/lib-esm/app/panels/measurements/MeasurementColorPreview.js +4 -5
  46. package/lib-esm/app/panels/measurements/MeasurementColorPreview.js.map +1 -1
  47. package/lib-esm/app/panels/measurements/MeasurementsTable.d.ts +2 -1
  48. package/lib-esm/app/panels/measurements/MeasurementsTable.d.ts.map +1 -1
  49. package/lib-esm/app/panels/measurements/MeasurementsTable.js +81 -94
  50. package/lib-esm/app/panels/measurements/MeasurementsTable.js.map +1 -1
  51. package/lib-esm/components/button/ButtonGroup.d.ts +2 -2
  52. package/lib-esm/components/button/ButtonGroup.d.ts.map +1 -1
  53. package/lib-esm/components/button/ButtonGroup.js +28 -43
  54. package/lib-esm/components/button/ButtonGroup.js.map +1 -1
  55. package/lib-esm/components/color-picker/color-picker-dropdown/ColorPickerDropdown.d.ts +2 -1
  56. package/lib-esm/components/color-picker/color-picker-dropdown/ColorPickerDropdown.d.ts.map +1 -1
  57. package/lib-esm/components/color-picker/color-picker-dropdown/ColorPickerDropdown.js +16 -19
  58. package/lib-esm/components/color-picker/color-picker-dropdown/ColorPickerDropdown.js.map +1 -1
  59. package/lib-esm/components/drop-zone/DropZone.d.ts +2 -2
  60. package/lib-esm/components/drop-zone/DropZone.d.ts.map +1 -1
  61. package/lib-esm/components/drop-zone/DropZone.js +42 -45
  62. package/lib-esm/components/drop-zone/DropZone.js.map +1 -1
  63. package/lib-esm/components/dropdown-menu/DropdownMenu.js +4 -4
  64. package/lib-esm/components/dropdown-menu/DropdownMenu.js.map +1 -1
  65. package/lib-esm/components/forms/Input.d.ts +17 -0
  66. package/lib-esm/components/forms/Input.d.ts.map +1 -0
  67. package/lib-esm/components/forms/Input.js +144 -0
  68. package/lib-esm/components/forms/Input.js.map +1 -0
  69. package/lib-esm/components/forms/context/FieldsContext.d.ts +16 -0
  70. package/lib-esm/components/forms/context/FieldsContext.d.ts.map +1 -0
  71. package/lib-esm/components/forms/context/FieldsContext.js +47 -0
  72. package/lib-esm/components/forms/context/FieldsContext.js.map +1 -0
  73. package/lib-esm/components/forms/context/index.d.ts +2 -0
  74. package/lib-esm/components/forms/context/index.d.ts.map +1 -0
  75. package/lib-esm/components/forms/context/index.js +2 -0
  76. package/lib-esm/components/forms/context/index.js.map +1 -0
  77. package/lib-esm/components/forms/index.d.ts +3 -0
  78. package/lib-esm/components/forms/index.d.ts.map +1 -0
  79. package/lib-esm/components/forms/index.js +3 -0
  80. package/lib-esm/components/forms/index.js.map +1 -0
  81. package/lib-esm/components/index.d.ts +1 -0
  82. package/lib-esm/components/index.d.ts.map +1 -1
  83. package/lib-esm/components/index.js +1 -0
  84. package/lib-esm/components/index.js.map +1 -1
  85. package/lib-esm/components/modal/ConfirmModal.d.ts +1 -1
  86. package/lib-esm/components/modal/ConfirmModal.d.ts.map +1 -1
  87. package/lib-esm/components/modal/ConfirmModal.js +37 -29
  88. package/lib-esm/components/modal/ConfirmModal.js.map +1 -1
  89. package/lib-esm/components/modal/Modal.d.ts +4 -4
  90. package/lib-esm/components/modal/Modal.d.ts.map +1 -1
  91. package/lib-esm/components/modal/Modal.js +45 -34
  92. package/lib-esm/components/modal/Modal.js.map +1 -1
  93. package/lib-esm/components/root-layout/RootLayout.d.ts.map +1 -1
  94. package/lib-esm/components/root-layout/RootLayout.js +2 -2
  95. package/lib-esm/components/root-layout/RootLayout.js.map +1 -1
  96. package/lib-esm/components/root-layout/css-reset/customPreflight.d.ts +5 -1
  97. package/lib-esm/components/root-layout/css-reset/customPreflight.d.ts.map +1 -1
  98. package/lib-esm/components/root-layout/css-reset/customPreflight.js +6 -2
  99. package/lib-esm/components/root-layout/css-reset/customPreflight.js.map +1 -1
  100. package/lib-esm/components/spinner/FullSpinner.d.ts +7 -1
  101. package/lib-esm/components/spinner/FullSpinner.d.ts.map +1 -1
  102. package/lib-esm/components/spinner/FullSpinner.js +8 -8
  103. package/lib-esm/components/spinner/FullSpinner.js.map +1 -1
  104. package/package.json +1 -1
  105. package/src/app/about/AboutDialogToolbarButton.tsx +6 -9
  106. package/src/app/explorer/MeasurementExplorer.tsx +47 -59
  107. package/src/app/helpers/MeasurementPlot.tsx +1 -0
  108. package/src/app/helpers/react-plot.tsx +24 -19
  109. package/src/app/kinds/iv/plot-view/IvPlotView.tsx +18 -19
  110. package/src/app/panels/measurements/MeasurementCheckbox.tsx +3 -5
  111. package/src/app/panels/measurements/MeasurementColorPreview.tsx +4 -6
  112. package/src/app/panels/measurements/MeasurementsTable.tsx +112 -115
  113. package/src/components/button/ButtonGroup.tsx +30 -44
  114. package/src/components/color-picker/color-picker-dropdown/ColorPickerDropdown.tsx +19 -26
  115. package/src/components/drop-zone/DropZone.tsx +54 -56
  116. package/src/components/dropdown-menu/DropdownMenu.tsx +19 -17
  117. package/src/components/forms/Input.tsx +255 -0
  118. package/src/components/forms/context/FieldsContext.tsx +82 -0
  119. package/src/components/forms/context/index.ts +1 -0
  120. package/src/components/forms/index.ts +2 -0
  121. package/src/components/index.ts +1 -0
  122. package/src/components/modal/ConfirmModal.tsx +49 -44
  123. package/src/components/modal/Modal.tsx +54 -58
  124. package/src/components/root-layout/RootLayout.tsx +3 -7
  125. package/src/components/root-layout/css-reset/customPreflight.ts +6 -2
  126. package/src/components/spinner/FullSpinner.tsx +14 -9
@@ -0,0 +1,255 @@
1
+ import styled from '@emotion/styled';
2
+ import { CSSProperties, InputHTMLAttributes, ReactNode } from 'react';
3
+
4
+ import { FullSpinner } from '../index';
5
+
6
+ import { useFieldsContext } from './context/FieldsContext';
7
+
8
+ type InputVariant = 'default' | 'small';
9
+
10
+ interface StyledProps {
11
+ variant: InputVariant;
12
+ hasLeading: boolean;
13
+ hasTrailing: boolean;
14
+ }
15
+
16
+ const LabelStyled = styled.label<StyledProps>`
17
+ padding: ${(props) =>
18
+ props.variant === 'default'
19
+ ? props.hasTrailing
20
+ ? '2px 9px 4px 9px'
21
+ : '2px 9px'
22
+ : props.hasTrailing
23
+ ? '1px 7px 1px 7px'
24
+ : '1px 7px'};
25
+
26
+ font-size: ${(props) => (props.variant === 'small' ? '1em' : '1.125em')};
27
+ line-height: '17px';
28
+
29
+ background-color: white;
30
+ border-width: 1px;
31
+ align-items: center;
32
+ flex-direction: row;
33
+ flex: 1 1 0%;
34
+ display: flex;
35
+ position: relative;
36
+
37
+ border-top-right-radius: ${(props) =>
38
+ props.hasLeading && !props.hasTrailing && '0.375rem'};
39
+
40
+ border-bottom-right-radius: ${(props) =>
41
+ props.hasLeading && !props.hasTrailing && '0.375rem'};
42
+
43
+ border-top-left-radius: ${(props) =>
44
+ props.hasTrailing && !props.hasLeading && '0.375rem'};
45
+
46
+ border-bottom-left-radius: ${(props) =>
47
+ props.hasTrailing && !props.hasLeading && '0.375rem'};
48
+
49
+ border-radius: ${(props) =>
50
+ !props.hasLeading && !props.hasTrailing && '0.375rem'};
51
+
52
+ border-color: var(--custom-border-color);
53
+ `;
54
+
55
+ function getStyleColor(hasError: boolean, hasValid: boolean) {
56
+ if (hasError) {
57
+ return {
58
+ default: '#ffa39e',
59
+ hover: '#f95d55',
60
+ };
61
+ }
62
+
63
+ if (hasValid) {
64
+ return {
65
+ default: '#6adc24',
66
+ hover: '#62cb21',
67
+ };
68
+ }
69
+
70
+ return {
71
+ default: 'rgb(217, 217, 217)',
72
+ hover: '#4096ff',
73
+ };
74
+ }
75
+
76
+ const GroupStyled = styled.div<{ hasError: boolean; hasValid: boolean }>`
77
+ display: flex;
78
+ border-radius: 0.375rem;
79
+ margin-top: 0.25rem;
80
+
81
+ .addon {
82
+ color: ${({ hasError }) => hasError && '#f95d55'};
83
+ }
84
+
85
+ --custom-border-color: ${({ hasError, hasValid }) =>
86
+ getStyleColor(hasError, hasValid).default};
87
+
88
+ :hover,
89
+ :focus-within {
90
+ --custom-border-color: ${({ hasError, hasValid }) =>
91
+ getStyleColor(hasError, hasValid).hover};
92
+ }
93
+ `;
94
+
95
+ const InputStyled = styled.input`
96
+ padding: 0;
97
+ flex: 1 1 0%;
98
+ border: none;
99
+ position: relative;
100
+ outline: none;
101
+ `;
102
+
103
+ const LeadingAddonStyled = styled.div`
104
+ padding-left: 0.75rem;
105
+ padding-right: 0.75rem;
106
+ border-right-width: 0px;
107
+ border-width: 1px;
108
+ border-top-left-radius: 0.375rem;
109
+ border-bottom-left-radius: 0.375rem;
110
+ align-items: center;
111
+ display: inline-flex;
112
+
113
+ border-right: none;
114
+
115
+ border-color: var(--custom-border-color);
116
+ `;
117
+
118
+ const TrailingAddonStyled = styled.div`
119
+ padding-left: 0.75rem;
120
+ padding-right: 0.75rem;
121
+ border-left-width: 0px;
122
+ border-width: 1px;
123
+ border-top-right-radius: 0.375rem;
124
+ border-bottom-right-radius: 0.375rem;
125
+ align-items: center;
126
+ display: inline-flex;
127
+
128
+ border-left: none;
129
+
130
+ border-color: var(--custom-border-color);
131
+ `;
132
+
133
+ const LeadingInlineAddonStyled = styled.div`
134
+ display: flex;
135
+ align-items: center;
136
+ padding-right: 0.5rem;
137
+ `;
138
+
139
+ const TrailingInlineAddonStyled = styled.div`
140
+ display: flex;
141
+ align-items: center;
142
+ padding-left: 0.5rem;
143
+ `;
144
+
145
+ const RootInput = styled.div`
146
+ display: flex;
147
+ flex-direction: column;
148
+ gap: 2px;
149
+ `;
150
+
151
+ interface RenderAddon {
152
+ addon: ReactNode;
153
+ inline?: boolean;
154
+ }
155
+
156
+ export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
157
+ variant?: 'default' | 'small';
158
+
159
+ leadingAddon?: RenderAddon;
160
+ trailingAddon?: RenderAddon;
161
+
162
+ help?: string;
163
+ error?: string;
164
+ valid?: true | string;
165
+
166
+ loading?: boolean;
167
+ }
168
+
169
+ export function Input(props: InputProps) {
170
+ const {
171
+ variant: variantProps,
172
+ trailingAddon,
173
+ leadingAddon,
174
+ help,
175
+ error,
176
+ valid,
177
+ loading,
178
+ ...otherProps
179
+ } = props;
180
+
181
+ const { name, variant: contextVariant } = useFieldsContext();
182
+
183
+ const hasLeading = (leadingAddon && !leadingAddon.inline) || false;
184
+ const hasTrailing = (trailingAddon && !trailingAddon.inline) || false;
185
+ const variant = variantProps || contextVariant;
186
+
187
+ return (
188
+ <RootInput>
189
+ <GroupStyled hasError={!!error} hasValid={!!valid}>
190
+ {leadingAddon && !leadingAddon.inline && (
191
+ <LeadingAddonStyled>{leadingAddon.addon}</LeadingAddonStyled>
192
+ )}
193
+
194
+ <LabelStyled
195
+ variant={variant}
196
+ hasLeading={hasLeading}
197
+ hasTrailing={hasTrailing}
198
+ >
199
+ {leadingAddon?.inline && (
200
+ <LeadingInlineAddonStyled className="addon">
201
+ {leadingAddon.addon}
202
+ </LeadingInlineAddonStyled>
203
+ )}
204
+ <InputStyled id={name} name={name} {...otherProps} />
205
+ {trailingAddon?.inline && (
206
+ <TrailingInlineAddonStyled className="addon">
207
+ {trailingAddon.addon}
208
+ </TrailingInlineAddonStyled>
209
+ )}
210
+
211
+ {loading && (
212
+ <TrailingInlineAddonStyled
213
+ style={{ height: variant === 'default' ? 20 : 10 }}
214
+ >
215
+ <FullSpinner
216
+ height={variant === 'default' ? 20 : 10}
217
+ width={variant === 'default' ? 20 : 10}
218
+ />
219
+ </TrailingInlineAddonStyled>
220
+ )}
221
+ </LabelStyled>
222
+
223
+ {trailingAddon && !trailingAddon.inline && (
224
+ <TrailingAddonStyled>{trailingAddon.addon}</TrailingAddonStyled>
225
+ )}
226
+ </GroupStyled>
227
+
228
+ <SubText error={error} help={help} valid={valid} />
229
+ </RootInput>
230
+ );
231
+ }
232
+
233
+ function SubText(props: Pick<InputProps, 'help' | 'error' | 'valid'>) {
234
+ const { error, help, valid: validProps } = props;
235
+
236
+ const valid = typeof validProps === 'string' ? validProps : undefined;
237
+ const text = error || valid || help;
238
+
239
+ return <p style={{ color: getColor(error, validProps) }}>{text}</p>;
240
+ }
241
+
242
+ function getColor(
243
+ error?: string,
244
+ valid?: true | string,
245
+ ): CSSProperties['color'] {
246
+ if (error) {
247
+ return '#f95d55';
248
+ }
249
+
250
+ if (valid && typeof valid !== 'boolean') {
251
+ return '#62cb21';
252
+ }
253
+
254
+ return 'gray';
255
+ }
@@ -0,0 +1,82 @@
1
+ import styled from '@emotion/styled';
2
+ import { createContext, ReactNode, useContext, useMemo } from 'react';
3
+
4
+ interface FieldContext {
5
+ name?: string;
6
+ variant: 'default' | 'small';
7
+ }
8
+
9
+ interface FieldProps {
10
+ name: string;
11
+ label: string;
12
+ children: ReactNode;
13
+ variant?: 'default' | 'small';
14
+ required?: boolean;
15
+ }
16
+
17
+ const context = createContext<FieldContext | null>(null);
18
+
19
+ const FieldContextRoot = styled.div`
20
+ display: flex;
21
+ flex-flow: row;
22
+ min-width: 0;
23
+ margin: 0;
24
+ padding: 0;
25
+ gap: 5px;
26
+ `;
27
+
28
+ const Label = styled.label<{ variant: FieldProps['variant'] }>`
29
+ position: relative;
30
+ display: inline-flex;
31
+ max-width: 100%;
32
+ line-height: ${(props) => (props.variant === 'small' ? '28px' : '32px')};
33
+ font-size: ${(props) => (props.variant === 'small' ? '1em' : '1.125em')};
34
+ white-space: nowrap;
35
+ text-align: end;
36
+ `;
37
+
38
+ const LabelContainer = styled.div`
39
+ flex-grow: 0;
40
+ display: inline-block;
41
+ overflow: hidden;
42
+ text-align: end;
43
+ vertical-align: middle;
44
+ white-space: nowrap;
45
+ `;
46
+
47
+ const FieldContextRequired = styled.span`
48
+ color: red;
49
+ `;
50
+
51
+ export function useFieldsContext(): FieldContext {
52
+ const ctx = useContext(context);
53
+
54
+ if (!ctx) {
55
+ return { name: undefined, variant: 'default' };
56
+ }
57
+
58
+ return ctx;
59
+ }
60
+
61
+ export function Field(props: FieldProps) {
62
+ const { label, name, children, required, variant } = props;
63
+
64
+ const memoized = useMemo(() => {
65
+ return { name, variant: variant || 'default' };
66
+ }, [name, variant]);
67
+
68
+ return (
69
+ <context.Provider value={memoized}>
70
+ <FieldContextRoot>
71
+ <LabelContainer>
72
+ <Label htmlFor={name} variant={memoized.variant}>
73
+ {label} {required && <FieldContextRequired>*</FieldContextRequired>}
74
+ :{' '}
75
+ </Label>
76
+ </LabelContainer>
77
+
78
+ {children}
79
+ </FieldContextRoot>
80
+ </context.Provider>
81
+ );
82
+ }
@@ -0,0 +1 @@
1
+ export * from './FieldsContext';
@@ -0,0 +1,2 @@
1
+ export * from './Input';
2
+ export * from './context';
@@ -3,6 +3,7 @@ export * from './button/index';
3
3
  export * from './color-picker/index';
4
4
  export * from './drop-zone/index';
5
5
  export * from './dropdown-menu/index';
6
+ export * from './forms/index';
6
7
  export * from './fullscreen/index';
7
8
  export * from './header/index';
8
9
  export * from './hooks/index';
@@ -1,5 +1,4 @@
1
- /** @jsxImportSource @emotion/react */
2
- import { css } from '@emotion/react';
1
+ import styled from '@emotion/styled';
3
2
  import type { ReactNode } from 'react';
4
3
 
5
4
  import { Button } from '..';
@@ -20,6 +19,46 @@ interface ConfirmModalProps {
20
19
  maxWidth?: number;
21
20
  }
22
21
 
22
+ const ConfirmModalDialog = styled.dialog`
23
+ display: flex;
24
+ position: fixed;
25
+ background-color: transparent;
26
+
27
+ ::backdrop {
28
+ background-color: rgba(113, 113, 122, 0.75);
29
+ }
30
+ `;
31
+
32
+ const ConfirmModalOpened = styled.div<{
33
+ headerColor: string;
34
+ }>`
35
+ position: relative;
36
+ display: flex;
37
+ flex-direction: column;
38
+ background-color: white;
39
+ max-height: 90%;
40
+ width: 100%;
41
+ border-width: 1px;
42
+ border-color: transparent;
43
+ border-radius: 0.5rem;
44
+ box-shadow: 0 0 0 0, 0 8px 16px rgba(0, 0, 0, 0.3);
45
+ border-top: 10px solid ${({ headerColor }) => headerColor};
46
+ `;
47
+
48
+ const ConfirmModalChildrenRoot = styled.div<{ headerColor: string }>`
49
+ color: ${({ headerColor }) => headerColor};
50
+ display: flex;
51
+ flex: 1 1 0%;
52
+ `;
53
+
54
+ const ConfirmModalFooter = styled.div`
55
+ border-top: 2px solid rgb(247, 247, 247);
56
+ padding: 10px 20px 10px 20px;
57
+ display: flex;
58
+ flex-direction: row-reverse;
59
+ gap: 10px;
60
+ `;
61
+
23
62
  export function ConfirmModal(props: ConfirmModalProps) {
24
63
  const {
25
64
  isOpen,
@@ -43,48 +82,14 @@ export function ConfirmModal(props: ConfirmModalProps) {
43
82
  });
44
83
 
45
84
  return (
46
- <dialog
47
- ref={ref}
48
- style={{
49
- display: 'flex',
50
- position: 'fixed',
51
- backgroundColor: 'transparent',
52
- }}
53
- css={css`
54
- ::backdrop: rgba(113, 113, 122, 0.75);
55
- `}
56
- onClick={onClick}
57
- >
85
+ <ConfirmModalDialog ref={ref} onClick={onClick}>
58
86
  {isOpen ? (
59
- <div
60
- style={{
61
- position: 'relative',
62
- display: 'flex',
63
- flexDirection: 'column',
64
- backgroundColor: 'white',
65
- maxHeight: '90%',
66
- width: '100%',
67
- maxWidth: maxWidth || undefined,
68
- borderWidth: 1,
69
- borderColor: 'transparent',
70
- borderRadius: '0.5rem',
71
- boxShadow: '0 0 0 0,0 8px 16px rgba(0, 0, 0, 0.3)',
72
- borderTop: `10px solid ${headerColor}`,
73
- }}
74
- >
75
- <div style={{ color: headerColor, display: 'flex', flex: '1 1 0%' }}>
87
+ <ConfirmModalOpened headerColor={headerColor} style={{ maxWidth }}>
88
+ <ConfirmModalChildrenRoot headerColor={headerColor}>
76
89
  {children}
77
- </div>
90
+ </ConfirmModalChildrenRoot>
78
91
 
79
- <div
80
- style={{
81
- borderTop: '2px solid rgb(247, 247, 247)',
82
- padding: '10px 20px 10px 20px',
83
- display: 'flex',
84
- flexDirection: 'row-reverse',
85
- gap: 10,
86
- }}
87
- >
92
+ <ConfirmModalFooter>
88
93
  <Button
89
94
  onClick={onConfirm}
90
95
  backgroundColor={{
@@ -105,9 +110,9 @@ export function ConfirmModal(props: ConfirmModalProps) {
105
110
  >
106
111
  {cancelText}
107
112
  </Button>
108
- </div>
109
- </div>
113
+ </ConfirmModalFooter>
114
+ </ConfirmModalOpened>
110
115
  ) : null}
111
- </dialog>
116
+ </ConfirmModalDialog>
112
117
  );
113
118
  }
@@ -1,5 +1,4 @@
1
- /** @jsxImportSource @emotion/react */
2
- import { css } from '@emotion/react';
1
+ import styled from '@emotion/styled';
3
2
  import type { ReactElement, ReactNode } from 'react';
4
3
 
5
4
  import ModalCloseButton from './ModalCloseButton';
@@ -17,6 +16,47 @@ export interface ModalProps {
17
16
  height?: number;
18
17
  }
19
18
 
19
+ const DialogRoot = styled.dialog`
20
+ display: flex;
21
+ position: fixed;
22
+ background-color: transparent;
23
+
24
+ ::backdrop {
25
+ background-color: rgba(113, 113, 122, 0.75);
26
+ }
27
+ `;
28
+
29
+ const DialogOpened = styled.div`
30
+ position: relative;
31
+ display: flex;
32
+ flex-direction: column;
33
+ background-color: white;
34
+ max-height: 90%;
35
+ border-width: 1px;
36
+ border-color: transparent;
37
+ border-radius: 0.5rem;
38
+ box-shadow: 0 0 0 0, 0 8px 16px rgba(0, 0, 0, 0.3);
39
+ `;
40
+
41
+ const ModalHeaderStyled = styled.div`
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: space-between;
45
+ padding: 10px 20px 10px 20px;
46
+ border-bottom: 2px solid rgb(247, 247, 247);
47
+ `;
48
+
49
+ const ModalBodyStyled = styled.div`
50
+ display: flex;
51
+ flex: 1 1 0%;
52
+ overflow-y: auto;
53
+ `;
54
+
55
+ const ModalFooterStyled = styled.div`
56
+ border-top: 2px solid rgb(247, 247, 247);
57
+ padding: 10px 20px 10px 20px;
58
+ `;
59
+
20
60
  export function Modal(props: ModalProps) {
21
61
  const {
22
62
  isOpen,
@@ -24,11 +64,12 @@ export function Modal(props: ModalProps) {
24
64
  hasCloseButton = true,
25
65
  requestCloseOnBackdrop = true,
26
66
  requestCloseOnEsc = true,
27
- maxWidth,
67
+ children,
28
68
  width,
69
+ maxWidth,
29
70
  height,
30
- children,
31
71
  } = props;
72
+
32
73
  const { ref, onClick } = useDialog({
33
74
  isOpen,
34
75
  requestCloseOnEsc,
@@ -37,76 +78,31 @@ export function Modal(props: ModalProps) {
37
78
  });
38
79
 
39
80
  return (
40
- <dialog
41
- ref={ref}
42
- style={{
43
- display: 'flex',
44
- position: 'fixed',
45
- backgroundColor: 'transparent',
46
- }}
47
- css={css`
48
- ::backdrop: rgba(113, 113, 122, 0.75);
49
- `}
50
- onClick={onClick}
51
- >
81
+ <DialogRoot ref={ref} onClick={onClick}>
52
82
  {isOpen ? (
53
- <div
83
+ <DialogOpened
54
84
  style={{
55
- position: 'relative',
56
- display: 'flex',
57
- flexDirection: 'column',
58
- backgroundColor: 'white',
59
- maxHeight: '90%',
60
- width: width || '100%',
61
- maxWidth: maxWidth || undefined,
85
+ maxWidth,
62
86
  height: height || 'max-content',
63
- borderWidth: 1,
64
- borderColor: 'transparent',
65
- borderRadius: '0.5rem',
66
- boxShadow: '0 0 0 0,0 8px 16px rgba(0, 0, 0, 0.3)',
87
+ width: width || '100%',
67
88
  }}
68
89
  >
69
90
  {children}
70
91
  {hasCloseButton && <ModalCloseButton onClick={onRequestClose} />}
71
- </div>
92
+ </DialogOpened>
72
93
  ) : null}
73
- </dialog>
94
+ </DialogRoot>
74
95
  );
75
96
  }
76
97
 
77
98
  Modal.Header = function ModalHeader(props: { children: ReactNode }) {
78
- return (
79
- <div
80
- style={{
81
- display: 'flex',
82
- alignItems: 'center',
83
- justifyContent: 'space-between',
84
- padding: '10px 20px 10px 20px',
85
- borderBottom: '2px solid rgb(247, 247, 247)',
86
- }}
87
- >
88
- {props.children}
89
- </div>
90
- );
99
+ return <ModalHeaderStyled>{props.children}</ModalHeaderStyled>;
91
100
  };
92
101
 
93
102
  Modal.Body = function ModalBody(props: { children: ReactNode }) {
94
- return (
95
- <div style={{ display: 'flex', flex: '1 1 0%', overflowY: 'auto' }}>
96
- {props.children}
97
- </div>
98
- );
103
+ return <ModalBodyStyled>{props.children}</ModalBodyStyled>;
99
104
  };
100
105
 
101
106
  Modal.Footer = function ModalFooter(props: { children: ReactNode }) {
102
- return (
103
- <div
104
- style={{
105
- borderTop: '2px solid rgb(247, 247, 247)',
106
- padding: '10px 20px 10px 20px',
107
- }}
108
- >
109
- {props.children}
110
- </div>
111
- );
107
+ return <ModalFooterStyled>{props.children}</ModalFooterStyled>;
112
108
  };
@@ -8,7 +8,7 @@ import root from 'react-shadow/emotion.esm';
8
8
  import { AccordionProvider } from '../accordion/AccordionContext';
9
9
 
10
10
  import { RootLayoutProvider } from './RootLayoutContext';
11
- import { customDivPreflight } from './css-reset/customPreflight';
11
+ import { CustomDivPreflight } from './css-reset/customPreflight';
12
12
  import { preflight } from './css-reset/preflight';
13
13
  import { queryClient } from './queryClient';
14
14
 
@@ -37,17 +37,13 @@ export function RootLayout(props: RootLayoutProps) {
37
37
  return (
38
38
  <root.div style={{ ...style, ...props.style }}>
39
39
  <Global styles={preflight} />
40
- <div
41
- ref={ref}
42
- css={customDivPreflight}
43
- style={{ width: '100%', height: '100%', position: 'relative' }}
44
- >
40
+ <CustomDivPreflight ref={ref}>
45
41
  <RootLayoutProvider innerRef={rootRef}>
46
42
  <QueryClientProvider client={queryClient}>
47
43
  <AccordionProvider>{props.children}</AccordionProvider>
48
44
  </QueryClientProvider>
49
45
  </RootLayoutProvider>
50
- </div>
46
+ </CustomDivPreflight>
51
47
  </root.div>
52
48
  );
53
49
  }
@@ -1,7 +1,7 @@
1
- import { css } from '@emotion/react';
1
+ import styled from '@emotion/styled';
2
2
 
3
3
  // Applying global styles that apply to elements that are not part of the shadow DOM.
4
- export const customDivPreflight = css`
4
+ export const CustomDivPreflight = styled.div`
5
5
  /* html */
6
6
  line-height: 1.5;
7
7
  -webkit-text-size-adjust: 100%;
@@ -9,4 +9,8 @@ export const customDivPreflight = css`
9
9
  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
10
10
  'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
11
11
  'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
12
+
13
+ width: 100%;
14
+ height: 100%;
15
+ position: relative;
12
16
  `;