react-science 19.1.0 → 19.3.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 (197) hide show
  1. package/lib/components/accordion/accordion.js +1 -1
  2. package/lib/components/color-picker/react-color/ColorPicker.d.ts.map +1 -1
  3. package/lib/components/color-picker/react-color/ColorPicker.js +7 -5
  4. package/lib/components/color-picker/react-color/ColorPicker.js.map +1 -1
  5. package/lib/components/doi/doi.js +2 -2
  6. package/lib/components/doi/doi.js.map +1 -1
  7. package/lib/components/doi/doi_logo.d.ts +6 -0
  8. package/lib/components/doi/doi_logo.d.ts.map +1 -0
  9. package/lib/components/doi/doi_logo.js +16 -0
  10. package/lib/components/doi/doi_logo.js.map +1 -0
  11. package/lib/components/form/components/input/checkbox.d.ts +7 -0
  12. package/lib/components/form/components/input/checkbox.d.ts.map +1 -0
  13. package/lib/components/form/components/input/checkbox.js +26 -0
  14. package/lib/components/form/components/input/checkbox.js.map +1 -0
  15. package/lib/components/form/components/input/input.d.ts +7 -0
  16. package/lib/components/form/components/input/input.d.ts.map +1 -0
  17. package/lib/components/form/components/input/input.js +17 -0
  18. package/lib/components/form/components/input/input.js.map +1 -0
  19. package/lib/components/form/components/input/numeric_input.d.ts +9 -0
  20. package/lib/components/form/components/input/numeric_input.d.ts.map +1 -0
  21. package/lib/components/form/components/input/numeric_input.js +19 -0
  22. package/lib/components/form/components/input/numeric_input.js.map +1 -0
  23. package/lib/components/form/components/input/reset_button.d.ts +7 -0
  24. package/lib/components/form/components/input/reset_button.d.ts.map +1 -0
  25. package/lib/components/form/components/input/reset_button.js +9 -0
  26. package/lib/components/form/components/input/reset_button.js.map +1 -0
  27. package/lib/components/form/components/input/select.d.ts +11 -0
  28. package/lib/components/form/components/input/select.d.ts.map +1 -0
  29. package/lib/components/form/components/input/select.js +21 -0
  30. package/lib/components/form/components/input/select.js.map +1 -0
  31. package/lib/components/form/components/input/submit_button.d.ts +5 -0
  32. package/lib/components/form/components/input/submit_button.d.ts.map +1 -0
  33. package/lib/components/form/components/input/submit_button.js +11 -0
  34. package/lib/components/form/components/input/submit_button.js.map +1 -0
  35. package/lib/components/form/components/input/switch.d.ts +10 -0
  36. package/lib/components/form/components/input/switch.d.ts.map +1 -0
  37. package/lib/components/form/components/input/switch.js +24 -0
  38. package/lib/components/form/components/input/switch.js.map +1 -0
  39. package/lib/components/form/components/input_groups/form.d.ts +11 -0
  40. package/lib/components/form/components/input_groups/form.d.ts.map +1 -0
  41. package/lib/components/form/components/input_groups/form.js +17 -0
  42. package/lib/components/form/components/input_groups/form.js.map +1 -0
  43. package/lib/components/form/components/input_groups/form_group.d.ts +25 -0
  44. package/lib/components/form/components/input_groups/form_group.d.ts.map +1 -0
  45. package/lib/components/form/components/input_groups/form_group.js +45 -0
  46. package/lib/components/form/components/input_groups/form_group.js.map +1 -0
  47. package/lib/components/form/components/input_groups/select.d.ts +56 -0
  48. package/lib/components/form/components/input_groups/select.d.ts.map +1 -0
  49. package/lib/components/form/components/input_groups/select.js +26 -0
  50. package/lib/components/form/components/input_groups/select.js.map +1 -0
  51. package/lib/components/form/components/layout/Section.d.ts +9 -0
  52. package/lib/components/form/components/layout/Section.d.ts.map +1 -0
  53. package/lib/components/form/components/layout/Section.js +38 -0
  54. package/lib/components/form/components/layout/Section.js.map +1 -0
  55. package/lib/components/form/components/util/select.d.ts +20 -0
  56. package/lib/components/form/components/util/select.d.ts.map +1 -0
  57. package/lib/components/form/components/util/select.js +20 -0
  58. package/lib/components/form/components/util/select.js.map +1 -0
  59. package/lib/components/form/context/use_ts_form.d.ts +45 -0
  60. package/lib/components/form/context/use_ts_form.d.ts.map +1 -0
  61. package/lib/components/form/context/use_ts_form.js +29 -0
  62. package/lib/components/form/context/use_ts_form.js.map +1 -0
  63. package/lib/components/form/utils/use_field_id.d.ts +2 -0
  64. package/lib/components/form/utils/use_field_id.d.ts.map +1 -0
  65. package/lib/components/form/utils/use_field_id.js +5 -0
  66. package/lib/components/form/utils/use_field_id.js.map +1 -0
  67. package/lib/components/form/utils/use_intent.d.ts +3 -0
  68. package/lib/components/form/utils/use_intent.d.ts.map +1 -0
  69. package/lib/components/form/utils/use_intent.js +4 -0
  70. package/lib/components/form/utils/use_intent.js.map +1 -0
  71. package/lib/components/index.d.ts +3 -1
  72. package/lib/components/index.d.ts.map +1 -1
  73. package/lib/components/index.js +3 -1
  74. package/lib/components/index.js.map +1 -1
  75. package/lib/components/info-panel/InfoPanel.d.ts.map +1 -1
  76. package/lib/components/info-panel/InfoPanel.js +3 -3
  77. package/lib/components/info-panel/InfoPanel.js.map +1 -1
  78. package/lib/components/input/index.d.ts.map +1 -0
  79. package/lib/components/input/index.js.map +1 -0
  80. package/lib/components/{forms → input}/radio-button-group/RadioButton.d.ts.map +1 -1
  81. package/lib/components/{forms → input}/radio-button-group/RadioButton.js +4 -4
  82. package/lib/components/{forms → input}/radio-button-group/RadioButton.js.map +1 -1
  83. package/lib/components/{forms → input}/radio-button-group/RadioButtonGroup.d.ts.map +1 -1
  84. package/lib/components/{forms → input}/radio-button-group/RadioButtonGroup.js +2 -2
  85. package/lib/components/{forms → input}/radio-button-group/RadioButtonGroup.js.map +1 -1
  86. package/lib/components/{forms → input}/radio-button-group/index.d.ts.map +1 -1
  87. package/lib/components/input/radio-button-group/index.js.map +1 -0
  88. package/lib/components/input/styles.d.ts.map +1 -0
  89. package/lib/components/{forms → input}/styles.js.map +1 -1
  90. package/lib/components/{forms → input}/utils/SubText.d.ts.map +1 -1
  91. package/lib/components/{forms → input}/utils/SubText.js.map +1 -1
  92. package/lib/components/input/utils/index.d.ts.map +1 -0
  93. package/lib/components/input/utils/index.js.map +1 -0
  94. package/lib/components/{forms → input}/utils/use_input_id.d.ts.map +1 -1
  95. package/lib/components/{forms → input}/utils/use_input_id.js.map +1 -1
  96. package/lib/components/root-layout/css-reset/customPreflight.js +1 -1
  97. package/lib/components/split_pane/use_split_pane_size.d.ts.map +1 -1
  98. package/lib/components/split_pane/use_split_pane_size.js +47 -46
  99. package/lib/components/split_pane/use_split_pane_size.js.map +1 -1
  100. package/lib/components/svg/index.d.ts +5 -0
  101. package/lib/components/svg/index.d.ts.map +1 -0
  102. package/lib/components/svg/index.js +5 -0
  103. package/lib/components/svg/index.js.map +1 -0
  104. package/lib/components/svg/styled/svg_styled_line.d.ts +6 -0
  105. package/lib/components/svg/styled/svg_styled_line.d.ts.map +1 -0
  106. package/lib/components/svg/styled/svg_styled_line.js +7 -0
  107. package/lib/components/svg/styled/svg_styled_line.js.map +1 -0
  108. package/lib/components/svg/styled/svg_styled_path.d.ts +6 -0
  109. package/lib/components/svg/styled/svg_styled_path.d.ts.map +1 -0
  110. package/lib/components/svg/styled/svg_styled_path.js +7 -0
  111. package/lib/components/svg/styled/svg_styled_path.js.map +1 -0
  112. package/lib/components/svg/styled/svg_styled_text.d.ts +6 -0
  113. package/lib/components/svg/styled/svg_styled_text.d.ts.map +1 -0
  114. package/lib/components/svg/styled/svg_styled_text.js +6 -0
  115. package/lib/components/svg/styled/svg_styled_text.js.map +1 -0
  116. package/lib/components/svg/styled/svg_styled_types.d.ts +56 -0
  117. package/lib/components/svg/styled/svg_styled_types.d.ts.map +1 -0
  118. package/lib/components/svg/styled/svg_styled_types.js +2 -0
  119. package/lib/components/svg/styled/svg_styled_types.js.map +1 -0
  120. package/lib/components/svg/styled/svg_styled_utils.d.ts +3 -0
  121. package/lib/components/svg/styled/svg_styled_utils.d.ts.map +1 -0
  122. package/lib/components/svg/styled/svg_styled_utils.js +10 -0
  123. package/lib/components/svg/styled/svg_styled_utils.js.map +1 -0
  124. package/lib/components/table/reorder_rows/use_drop_monitor.d.ts.map +1 -1
  125. package/lib/components/table/reorder_rows/use_drop_monitor.js +33 -32
  126. package/lib/components/table/reorder_rows/use_drop_monitor.js.map +1 -1
  127. package/lib/components/toolbar/PanelPreferencesToolbar.js +1 -1
  128. package/lib/components/toolbar/Toolbar.d.ts.map +1 -1
  129. package/lib/components/toolbar/Toolbar.js +7 -5
  130. package/lib/components/toolbar/Toolbar.js.map +1 -1
  131. package/lib/components/toolbar/TooltipHelpContent.js +3 -3
  132. package/package.json +36 -33
  133. package/src/components/accordion/accordion.tsx +1 -1
  134. package/src/components/color-picker/react-color/ColorPicker.tsx +8 -6
  135. package/src/components/doi/doi.tsx +2 -2
  136. package/src/components/doi/{Logo.tsx → doi_logo.tsx} +9 -5
  137. package/src/components/form/components/input/checkbox.tsx +53 -0
  138. package/src/components/form/components/input/input.tsx +57 -0
  139. package/src/components/form/components/input/numeric_input.tsx +64 -0
  140. package/src/components/form/components/input/reset_button.tsx +19 -0
  141. package/src/components/form/components/input/select.tsx +54 -0
  142. package/src/components/form/components/input/submit_button.tsx +23 -0
  143. package/src/components/form/components/input/switch.tsx +55 -0
  144. package/src/components/form/components/input_groups/form.tsx +32 -0
  145. package/src/components/form/components/input_groups/form_group.tsx +126 -0
  146. package/src/components/form/components/input_groups/select.tsx +175 -0
  147. package/src/components/form/components/layout/Section.tsx +57 -0
  148. package/src/components/form/components/util/select.tsx +67 -0
  149. package/src/components/form/context/use_ts_form.ts +33 -0
  150. package/src/components/form/utils/use_field_id.ts +5 -0
  151. package/src/components/form/utils/use_intent.ts +5 -0
  152. package/src/components/index.ts +3 -1
  153. package/src/components/info-panel/InfoPanel.tsx +4 -3
  154. package/src/components/{forms → input}/radio-button-group/RadioButton.tsx +4 -4
  155. package/src/components/{forms → input}/radio-button-group/RadioButtonGroup.tsx +2 -2
  156. package/src/components/root-layout/css-reset/customPreflight.ts +1 -1
  157. package/src/components/split_pane/use_split_pane_size.tsx +54 -53
  158. package/src/components/svg/index.ts +4 -0
  159. package/src/components/svg/styled/svg_styled_line.tsx +27 -0
  160. package/src/components/svg/styled/svg_styled_path.tsx +29 -0
  161. package/src/components/svg/styled/svg_styled_text.tsx +12 -0
  162. package/src/components/svg/styled/svg_styled_types.ts +67 -0
  163. package/src/components/svg/styled/svg_styled_utils.ts +15 -0
  164. package/src/components/table/reorder_rows/use_drop_monitor.ts +41 -38
  165. package/src/components/toolbar/PanelPreferencesToolbar.tsx +1 -1
  166. package/src/components/toolbar/Toolbar.tsx +9 -5
  167. package/src/components/toolbar/TooltipHelpContent.tsx +3 -3
  168. package/lib/components/doi/Logo.d.ts +0 -6
  169. package/lib/components/doi/Logo.d.ts.map +0 -1
  170. package/lib/components/doi/Logo.js +0 -16
  171. package/lib/components/doi/Logo.js.map +0 -1
  172. package/lib/components/forms/index.d.ts.map +0 -1
  173. package/lib/components/forms/index.js.map +0 -1
  174. package/lib/components/forms/radio-button-group/index.js.map +0 -1
  175. package/lib/components/forms/styles.d.ts.map +0 -1
  176. package/lib/components/forms/utils/index.d.ts.map +0 -1
  177. package/lib/components/forms/utils/index.js.map +0 -1
  178. /package/lib/components/{forms → input}/index.d.ts +0 -0
  179. /package/lib/components/{forms → input}/index.js +0 -0
  180. /package/lib/components/{forms → input}/radio-button-group/RadioButton.d.ts +0 -0
  181. /package/lib/components/{forms → input}/radio-button-group/RadioButtonGroup.d.ts +0 -0
  182. /package/lib/components/{forms → input}/radio-button-group/index.d.ts +0 -0
  183. /package/lib/components/{forms → input}/radio-button-group/index.js +0 -0
  184. /package/lib/components/{forms → input}/styles.d.ts +0 -0
  185. /package/lib/components/{forms → input}/styles.js +0 -0
  186. /package/lib/components/{forms → input}/utils/SubText.d.ts +0 -0
  187. /package/lib/components/{forms → input}/utils/SubText.js +0 -0
  188. /package/lib/components/{forms → input}/utils/index.d.ts +0 -0
  189. /package/lib/components/{forms → input}/utils/index.js +0 -0
  190. /package/lib/components/{forms → input}/utils/use_input_id.d.ts +0 -0
  191. /package/lib/components/{forms → input}/utils/use_input_id.js +0 -0
  192. /package/src/components/{forms → input}/index.ts +0 -0
  193. /package/src/components/{forms → input}/radio-button-group/index.ts +0 -0
  194. /package/src/components/{forms → input}/styles.ts +0 -0
  195. /package/src/components/{forms → input}/utils/SubText.tsx +0 -0
  196. /package/src/components/{forms → input}/utils/index.ts +0 -0
  197. /package/src/components/{forms → input}/utils/use_input_id.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-science",
3
- "version": "19.1.0",
3
+ "version": "19.3.0",
4
4
  "description": "React components to build scientific applications UI",
5
5
  "type": "module",
6
6
  "exports": {
@@ -56,56 +56,59 @@
56
56
  "react-dom": ">=18.0.0"
57
57
  },
58
58
  "dependencies": {
59
- "@atlaskit/pragmatic-drag-and-drop": "^1.7.4",
60
- "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.1",
59
+ "@atlaskit/pragmatic-drag-and-drop": "^1.7.7",
60
+ "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.2",
61
61
  "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0",
62
62
  "@emotion/styled": "^11.14.1",
63
63
  "@radix-ui/react-use-controllable-state": "^1.2.2",
64
+ "@tanstack/react-form": "^1.23.6",
64
65
  "@tanstack/react-table": "^8.21.3",
65
66
  "@tanstack/react-virtual": "^3.13.12",
66
67
  "d3-scale-chromatic": "^3.1.0",
67
- "react-d3-utils": "^3.1.1",
68
+ "react-d3-utils": "^3.1.2",
68
69
  "react-dropzone": "^14.3.8",
69
70
  "react-full-screen": "^1.1.1",
70
71
  "react-icons": "^5.5.0",
71
- "react-inspector": "^6.0.2",
72
+ "react-inspector": "^9.0.0",
72
73
  "tinycolor2": "^1.6.0",
73
- "ts-pattern": "^5.7.1"
74
+ "ts-pattern": "^5.8.0",
75
+ "zod": "^4.1.12"
74
76
  },
75
77
  "devDependencies": {
76
78
  "@blueprintjs/core": "6.0.0",
77
79
  "@blueprintjs/icons": "6.0.0",
78
80
  "@blueprintjs/select": "6.0.0",
79
- "@floating-ui/react": "^0.27.13",
80
- "@playwright/experimental-ct-react": "^1.54.1",
81
- "@playwright/test": "^1.54.1",
82
- "@storybook/addon-docs": "^9.0.16",
83
- "@storybook/react-vite": "^9.0.16",
84
- "@tanstack/react-query": "^5.83.0",
81
+ "@floating-ui/react": "^0.27.16",
82
+ "@playwright/experimental-ct-react": "^1.56.0",
83
+ "@playwright/test": "^1.56.0",
84
+ "@storybook/addon-docs": "^9.1.10",
85
+ "@storybook/react-vite": "^9.1.10",
86
+ "@tanstack/react-query": "^5.90.2",
85
87
  "@types/babel__core": "^7.20.5",
86
88
  "@types/d3-scale-chromatic": "^3.1.0",
87
- "@types/node": "^24.0.13",
89
+ "@types/node": "^24.7.0",
88
90
  "@types/react": "^18.3.12",
89
91
  "@types/react-dom": "^18.3.1",
90
92
  "@types/tinycolor2": "^1.4.6",
91
- "@vitejs/plugin-react": "^4.6.0",
93
+ "@vitejs/plugin-react": "^5.0.4",
92
94
  "@vitest/coverage-v8": "^3.2.4",
95
+ "@zakodium/tsconfig": "^1.0.2",
93
96
  "biologic-converter": "^0.6.0",
94
97
  "cheminfo-font": "^1.13.1",
95
98
  "cheminfo-types": "^1.8.1",
96
- "cross-env": "^7.0.3",
97
- "eslint": "^9.31.0",
98
- "eslint-config-zakodium": "^16.0.0",
99
- "eslint-plugin-storybook": "^9.0.16",
100
- "fifo-logger": "^2.0.0",
99
+ "cross-env": "^10.1.0",
100
+ "eslint": "^9.37.0",
101
+ "eslint-config-zakodium": "^17.0.0",
102
+ "eslint-plugin-storybook": "^9.1.10",
103
+ "fifo-logger": "^2.0.1",
101
104
  "filelist-utils": "^1.11.3",
102
- "immer": "^10.1.1",
103
- "jcampconverter": "^11.0.3",
104
- "ml-gsd": "^13.0.1",
105
+ "immer": "^10.1.3",
106
+ "jcampconverter": "^11.1.0",
107
+ "ml-gsd": "^13.1.0",
105
108
  "ml-peak-shape-generator": "^4.2.0",
106
- "ml-signal-processing": "^2.0.0",
107
- "ml-spectra-processing": "^14.13.0",
108
- "ms-spectrum": "^3.9.0",
109
+ "ml-signal-processing": "^2.1.0",
110
+ "ml-spectra-processing": "^14.18.0",
111
+ "ms-spectrum": "^3.9.2",
109
112
  "netcdfjs": "^3.0.0",
110
113
  "postcss-styled-syntax": "^0.7.1",
111
114
  "prettier": "^3.6.2",
@@ -113,20 +116,20 @@
113
116
  "react-dom": "^18.3.1",
114
117
  "react-error-boundary": "^6.0.0",
115
118
  "react-kbs": "^2.1.1",
116
- "react-ocl": "^8.0.0",
117
- "react-plot": "^3.1.0",
119
+ "react-ocl": "^8.2.0",
120
+ "react-plot": "^3.1.1",
118
121
  "rimraf": "^6.0.1",
119
122
  "spc-parser": "^1.0.0",
120
- "storybook": "^9.0.16",
121
- "stylelint": "^16.21.1",
122
- "stylelint-config-standard": "^38.0.0",
123
- "typescript": "^5.8.3",
124
- "vite": "^7.0.4",
123
+ "storybook": "^9.1.10",
124
+ "stylelint": "^16.25.0",
125
+ "stylelint-config-standard": "^39.0.1",
126
+ "typescript": "^5.9.3",
127
+ "vite": "^7.1.9",
125
128
  "vitest": "^3.2.4",
126
129
  "wdf-parser": "^0.3.0"
127
130
  },
128
131
  "volta": {
129
- "node": "24.4.0"
132
+ "node": "24.9.0"
130
133
  },
131
134
  "overrides": {
132
135
  "storybook": "$storybook"
@@ -82,7 +82,7 @@ const AccordionItemHeader = styled.div`
82
82
  justify-content: space-between;
83
83
  padding-left: 12px;
84
84
 
85
- &:hover {
85
+ :hover {
86
86
  background: white
87
87
  linear-gradient(${Colors.LIGHT_GRAY4} 5%, ${Colors.LIGHT_GRAY2} 100%)
88
88
  repeat scroll 0 0;
@@ -1,5 +1,5 @@
1
1
  import type { CSSProperties } from 'react';
2
- import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { useCallback, useRef, useState } from 'react';
3
3
 
4
4
  import { debounce } from '../../utils/index.js';
5
5
  import { defaultColorPalette } from '../palette.js';
@@ -152,17 +152,19 @@ export function ColorPicker(props: ColorPickerProps) {
152
152
  style = {},
153
153
  } = props;
154
154
 
155
- const [state, setState] = useState(colorHelper.toState(color, 0));
156
-
157
155
  const debounceRef = useRef(
158
156
  debounce((fn: any, data: ChangeCallbackProps, event: Event) => {
159
157
  fn(data, event);
160
158
  }, 100),
161
159
  );
162
160
 
163
- useEffect(() => {
164
- setState((prevState) => colorHelper.toState(color, prevState.oldHue));
165
- }, [color]);
161
+ const [state, setState] = useState(() => colorHelper.toState(color, 0));
162
+
163
+ const [previousColor, setPreviousColor] = useState(color);
164
+ if (color !== previousColor) {
165
+ setPreviousColor(color);
166
+ setState(colorHelper.toState(color, 0));
167
+ }
166
168
 
167
169
  const handleChange = useCallback(
168
170
  (data: any, event: any) => {
@@ -1,6 +1,6 @@
1
1
  import { match } from 'ts-pattern';
2
2
 
3
- import { Logo } from './Logo.js';
3
+ import { DoiLogo } from './doi_logo.js';
4
4
  import { normalizeDOI } from './utils.js';
5
5
 
6
6
  type DOISize = 'small' | 'medium' | 'large';
@@ -21,7 +21,7 @@ export function DOI(props: DOIProps) {
21
21
  target="_blank"
22
22
  rel="noreferrer"
23
23
  >
24
- <Logo size={getDOISize(size)} />
24
+ <DoiLogo size={getDOISize(size)} />
25
25
  </a>
26
26
  );
27
27
  }
@@ -1,6 +1,6 @@
1
1
  import styled from '@emotion/styled';
2
2
 
3
- const Svg = styled.svg<{ size: string }>`
3
+ const DoiLogoSvg = styled.svg<{ size: string }>`
4
4
  display: inline-flex;
5
5
  ${(props) => {
6
6
  return `
@@ -10,15 +10,19 @@ const Svg = styled.svg<{ size: string }>`
10
10
  }}
11
11
  `;
12
12
 
13
- interface LogoProps {
13
+ interface DoiLogoProps {
14
14
  size: string;
15
15
  }
16
16
 
17
- export function Logo(props: LogoProps) {
17
+ export function DoiLogo(props: DoiLogoProps) {
18
18
  const { size } = props;
19
19
 
20
20
  return (
21
- <Svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 130 130" size={size}>
21
+ <DoiLogoSvg
22
+ xmlns="http://www.w3.org/2000/svg"
23
+ viewBox="0 0 130 130"
24
+ size={size}
25
+ >
22
26
  <circle fill="#fcb425" cx="65" cy="65" r="64" />
23
27
  <path
24
28
  fill="##231f20"
@@ -28,6 +32,6 @@ export function Logo(props: LogoProps) {
28
32
  fill="#fff"
29
33
  d="m 105.42764,25.617918 c -1.97184,0 -3.64919,0.69142 -5.03204,2.074271 -1.357247,1.357245 -2.035864,3.021779 -2.035864,4.993633 0,1.971835 0.678617,3.649193 2.035864,5.032034 1.38285,1.382861 3.0602,2.074281 5.03204,2.074281 1.99744,0 3.67479,-0.678627 5.03203,-2.035861 1.38285,-1.382861 2.07428,-3.073012 2.07428,-5.070454 0,-1.971854 -0.69143,-3.636388 -2.07428,-4.993633 -1.38285,-1.382851 -3.0602,-2.074271 -5.03203,-2.074271 z M 74.219383,45.507921 c -7.323992,0 -12.970625,2.283009 -16.939921,6.848949 -3.277876,3.782438 -4.916803,8.118252 -4.916803,13.008406 0,5.430481 1.626124,10.009834 4.878383,13.738236 3.943689,4.538918 9.475093,6.808622 16.59421,6.808622 7.093512,0 12.612122,-2.269704 16.555801,-6.808622 3.252259,-3.728402 4.878393,-8.1993 4.878393,-13.413648 0,-5.160323 -1.638938,-9.604602 -4.916803,-13.332994 -4.020509,-4.56594 -9.398263,-6.848949 -16.13326,-6.848949 z m 24.908603,1.386686 0,37.634676 12.599304,0 0,-37.634676 -12.599304,0 z M 73.835252,56.975981 c 2.304752,0 4.263793,0.852337 5.877124,2.554426 1.638928,1.675076 2.458402,3.727881 2.458402,6.159457 0,2.458578 -0.806671,4.538022 -2.419992,6.240111 -1.613331,1.675086 -3.585175,2.514099 -5.915534,2.514099 -2.612051,0 -4.737546,-1.027366 -6.376474,-3.080682 -1.331637,-1.648053 -1.997451,-3.539154 -1.997451,-5.673528 0,-2.107362 0.665814,-3.985138 1.997451,-5.633201 1.638928,-2.053316 3.764423,-3.080682 6.376474,-3.080682 z"
30
34
  />
31
- </Svg>
35
+ </DoiLogoSvg>
32
36
  );
33
37
  }
@@ -0,0 +1,53 @@
1
+ import type { CheckboxProps as BPCheckboxProps } from '@blueprintjs/core';
2
+ import { Checkbox as BPCheckbox } from '@blueprintjs/core';
3
+ import styled from '@emotion/styled';
4
+ import type { ChangeEvent } from 'react';
5
+
6
+ import { useFieldContext } from '../../context/use_ts_form.js';
7
+ import { getIntent } from '../../utils/use_intent.js';
8
+ import { FormGroup } from '../input_groups/form_group.js';
9
+
10
+ type CheckboxProps = Omit<BPCheckboxProps, 'defaultChecked' | 'name'> & {
11
+ helpText?: string;
12
+ };
13
+
14
+ // Keep the margin top for space between inputs. But remove the margin bottom for helperText
15
+ const StyledCheckbox = styled(BPCheckbox)<CheckboxProps>`
16
+ margin-bottom: 0 !important;
17
+ width: fit-content;
18
+ `;
19
+
20
+ export function Checkbox(props: CheckboxProps) {
21
+ const { helpText, label } = props;
22
+ const field = useFieldContext<boolean>();
23
+ const error = field
24
+ .getMeta()
25
+ .errors.map((e) => e.message)
26
+ .at(0);
27
+
28
+ const intent = getIntent(error);
29
+
30
+ function onChange(event: ChangeEvent<HTMLInputElement>) {
31
+ const checked = event.target.checked;
32
+ return field.handleChange(checked);
33
+ }
34
+
35
+ return (
36
+ <FormGroup
37
+ name={field.name}
38
+ intent={intent}
39
+ error={error}
40
+ fullWidth
41
+ helpText={helpText}
42
+ >
43
+ <StyledCheckbox
44
+ label={label}
45
+ name={field.name}
46
+ value={String(field.state.value)}
47
+ onChange={onChange}
48
+ onBlur={field.handleBlur}
49
+ defaultChecked={field.state.value}
50
+ />
51
+ </FormGroup>
52
+ );
53
+ }
@@ -0,0 +1,57 @@
1
+ import { InputGroup } from '@blueprintjs/core';
2
+ import type { ChangeEvent } from 'react';
3
+
4
+ import { useFieldContext } from '../../context/use_ts_form.js';
5
+ import type { FormGroupInputProps } from '../input_groups/form_group.js';
6
+ import { FormGroup } from '../input_groups/form_group.js';
7
+
8
+ interface InputProps extends FormGroupInputProps {
9
+ type?: string;
10
+ }
11
+
12
+ export function Input(props: InputProps) {
13
+ const {
14
+ label,
15
+ required,
16
+ placeholder,
17
+ type = 'text',
18
+ helpText,
19
+ layout,
20
+ fullWidth,
21
+ } = props;
22
+
23
+ const field = useFieldContext<string>();
24
+ const error = field
25
+ .getMeta()
26
+ .errors.map((e) => e.message)
27
+ .at(0);
28
+
29
+ function onChange(event: ChangeEvent<HTMLInputElement>) {
30
+ return field.handleChange(event.target.value);
31
+ }
32
+
33
+ return (
34
+ <FormGroup
35
+ name={field.name}
36
+ label={label}
37
+ intent={error ? 'danger' : 'none'}
38
+ required={required}
39
+ error={error}
40
+ helpText={helpText}
41
+ layout={layout}
42
+ fullWidth={fullWidth}
43
+ >
44
+ <InputGroup
45
+ id={field.name}
46
+ name={field.name}
47
+ required={required}
48
+ type={type}
49
+ onChange={onChange}
50
+ onBlur={field.handleBlur}
51
+ intent={error ? 'danger' : 'none'}
52
+ value={field.state.value}
53
+ placeholder={placeholder}
54
+ />
55
+ </FormGroup>
56
+ );
57
+ }
@@ -0,0 +1,64 @@
1
+ import { NumericInput as BPNumericInput } from '@blueprintjs/core';
2
+
3
+ import { useFieldContext } from '../../context/use_ts_form.js';
4
+ import { getIntent } from '../../utils/use_intent.js';
5
+ import type { FormGroupInputProps } from '../input_groups/form_group.js';
6
+ import { FormGroup } from '../input_groups/form_group.js';
7
+
8
+ interface NumericInputProps extends FormGroupInputProps {
9
+ step?: number;
10
+ min?: number;
11
+ max?: number;
12
+ }
13
+
14
+ export function NumericInput(props: NumericInputProps) {
15
+ const {
16
+ label,
17
+ required,
18
+ helpText,
19
+ placeholder,
20
+ step,
21
+ min,
22
+ max,
23
+ layout,
24
+ fullWidth,
25
+ } = props;
26
+
27
+ const field = useFieldContext<string>();
28
+ const error = field
29
+ .getMeta()
30
+ .errors.map((e) => e.message)
31
+ .at(0);
32
+
33
+ const intent = getIntent(error);
34
+
35
+ function onChange(_: number, valueAsString: string) {
36
+ return field.handleChange(valueAsString);
37
+ }
38
+
39
+ return (
40
+ <FormGroup
41
+ name={field.name}
42
+ label={label}
43
+ intent={intent}
44
+ required={required}
45
+ helpText={helpText}
46
+ layout={layout}
47
+ error={error}
48
+ fullWidth={fullWidth}
49
+ >
50
+ <BPNumericInput
51
+ id={field.name}
52
+ name={field.name}
53
+ stepSize={step}
54
+ min={min}
55
+ max={max}
56
+ value={field.state.value ?? ''}
57
+ onValueChange={onChange}
58
+ intent={intent}
59
+ placeholder={placeholder}
60
+ required={required}
61
+ />
62
+ </FormGroup>
63
+ );
64
+ }
@@ -0,0 +1,19 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ import { Button } from '../../../button/index.js';
4
+ import { useFormContext } from '../../context/use_ts_form.js';
5
+
6
+ interface ResetButtonProps {
7
+ children: ReactNode;
8
+ }
9
+
10
+ export function ResetButton(props: ResetButtonProps) {
11
+ const { children } = props;
12
+ const form = useFormContext();
13
+
14
+ return (
15
+ <Button intent="danger" type="reset" onClick={() => form.reset()}>
16
+ {children}
17
+ </Button>
18
+ );
19
+ }
@@ -0,0 +1,54 @@
1
+ import { useFieldContext } from '../../context/use_ts_form.js';
2
+ import { getIntent } from '../../utils/use_intent.js';
3
+ import type { FormGroupInputProps } from '../input_groups/form_group.js';
4
+ import { FormGroup } from '../input_groups/form_group.js';
5
+ import { Select as SelectInput } from '../input_groups/select.js';
6
+ import type { SelectId } from '../util/select.js';
7
+
8
+ interface SelectOptionType {
9
+ label: string;
10
+ value: string;
11
+ }
12
+
13
+ interface SelectProps extends Omit<FormGroupInputProps, 'placeholder'> {
14
+ items: SelectOptionType[];
15
+ }
16
+
17
+ export function Select(props: SelectProps) {
18
+ const { label, items, required, helpText, layout, fullWidth } = props;
19
+
20
+ const field = useFieldContext<SelectId>();
21
+ const error = field
22
+ .getMeta()
23
+ .errors.map((e) => e.message)
24
+ .at(0);
25
+
26
+ const intent = getIntent(error);
27
+
28
+ function onItemSelect(selected: SelectId | undefined) {
29
+ if (!selected) return;
30
+ return field.handleChange(selected);
31
+ }
32
+
33
+ return (
34
+ <FormGroup
35
+ name={field.name}
36
+ required={required}
37
+ label={label}
38
+ intent={intent}
39
+ helpText={helpText}
40
+ error={error}
41
+ layout={layout}
42
+ fullWidth={fullWidth}
43
+ >
44
+ <SelectInput
45
+ onBlur={field.handleBlur}
46
+ items={items}
47
+ selected={field.state.value}
48
+ onChange={onItemSelect}
49
+ intent={intent}
50
+ name={field.name}
51
+ />
52
+ </FormGroup>
53
+ );
54
+ }
@@ -0,0 +1,23 @@
1
+ import { useStore } from '@tanstack/react-form';
2
+
3
+ import type { ButtonProps } from '../../../button/index.js';
4
+ import { Button } from '../../../button/index.js';
5
+ import { useFormContext } from '../../context/use_ts_form.js';
6
+
7
+ type SubmitButtonProps = ButtonProps;
8
+
9
+ export function SubmitButton(props: SubmitButtonProps) {
10
+ const { intent, ...otherProps } = props;
11
+
12
+ const form = useFormContext();
13
+ const isSubmitting = useStore(form.store, (state) => state.isSubmitting);
14
+
15
+ return (
16
+ <Button
17
+ {...otherProps}
18
+ intent={intent ?? 'primary'}
19
+ type="submit"
20
+ disabled={isSubmitting}
21
+ />
22
+ );
23
+ }
@@ -0,0 +1,55 @@
1
+ import { Switch as BPSwitch } from '@blueprintjs/core';
2
+ import styled from '@emotion/styled';
3
+ import type { ChangeEvent } from 'react';
4
+
5
+ import { useFieldContext } from '../../context/use_ts_form.js';
6
+ import type { Layout } from '../input_groups/form.js';
7
+ import { FormGroup } from '../input_groups/form_group.js';
8
+
9
+ interface SwitchProps {
10
+ label?: string;
11
+ helpText?: string;
12
+ fullWidth?: boolean;
13
+ layout?: Layout;
14
+ }
15
+
16
+ const StyledSwitch = styled(BPSwitch)`
17
+ margin: 0 !important;
18
+ height: 30px;
19
+ display: flex;
20
+ align-items: center;
21
+ `;
22
+
23
+ export function Switch(props: SwitchProps) {
24
+ const { label, layout, helpText, fullWidth } = props;
25
+
26
+ const field = useFieldContext<boolean>();
27
+ const error = field
28
+ .getMeta()
29
+ .errors.map((e) => e.message)
30
+ .at(0);
31
+
32
+ function onChange(event: ChangeEvent<HTMLInputElement>) {
33
+ return field.handleChange(event.target.checked);
34
+ }
35
+
36
+ return (
37
+ <FormGroup
38
+ name={field.name}
39
+ error={error}
40
+ intent={error ? 'danger' : undefined}
41
+ label={label}
42
+ layout={layout}
43
+ helpText={helpText}
44
+ fullWidth={fullWidth}
45
+ >
46
+ <StyledSwitch
47
+ name={field.name}
48
+ id={field.name}
49
+ checked={field.state.value}
50
+ onChange={onChange}
51
+ onBlur={field.handleBlur}
52
+ />
53
+ </FormGroup>
54
+ );
55
+ }
@@ -0,0 +1,32 @@
1
+ import type { FormHTMLAttributes, ReactNode } from 'react';
2
+ import { createContext, useContext, useMemo } from 'react';
3
+
4
+ export type Layout = 'inline' | 'stacked';
5
+
6
+ export interface FormProps extends FormHTMLAttributes<HTMLFormElement> {
7
+ children: ReactNode;
8
+ layout?: Layout;
9
+ }
10
+
11
+ const formContext = createContext<{ layout: Layout }>({
12
+ layout: 'stacked',
13
+ });
14
+
15
+ // eslint-disable-next-line react-refresh/only-export-components
16
+ export function useFormContext() {
17
+ return useContext(formContext);
18
+ }
19
+
20
+ export function Form(props: FormProps) {
21
+ const { children, layout = 'stacked', ...otherProps } = props;
22
+
23
+ const contextValue = useMemo(() => {
24
+ return { layout };
25
+ }, [layout]);
26
+
27
+ return (
28
+ <formContext.Provider value={contextValue}>
29
+ <form {...otherProps}>{children}</form>
30
+ </formContext.Provider>
31
+ );
32
+ }