@panneau/forms 4.1.1 → 5.0.0-alpha.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 (70) hide show
  1. package/README.md +71 -0
  2. package/dist/ConflictDialog.css +55 -0
  3. package/dist/ConflictDialog.d.ts +23 -0
  4. package/dist/ConflictDialog.d.ts.map +1 -0
  5. package/dist/ConflictDialog.js +122 -0
  6. package/dist/ConflictDialog.js.map +1 -0
  7. package/dist/ConflictDialog.module.js +24 -0
  8. package/dist/ConflictDialog.module.js.map +1 -0
  9. package/dist/ErrorSummary.d.ts +18 -0
  10. package/dist/ErrorSummary.d.ts.map +1 -0
  11. package/dist/ErrorSummary.js +122 -0
  12. package/dist/ErrorSummary.js.map +1 -0
  13. package/dist/FieldErrorBoundary.d.ts +19 -0
  14. package/dist/FieldErrorBoundary.d.ts.map +1 -0
  15. package/dist/FieldErrorBoundary.js +20 -0
  16. package/dist/FieldErrorBoundary.js.map +1 -0
  17. package/dist/Form.css +151 -0
  18. package/dist/Form.d.ts +20 -0
  19. package/dist/Form.d.ts.map +1 -0
  20. package/dist/Form.js +41 -0
  21. package/dist/Form.js.map +1 -0
  22. package/dist/Form.module.js +44 -0
  23. package/dist/Form.module.js.map +1 -0
  24. package/dist/FormBinding.d.ts +8 -0
  25. package/dist/FormBinding.d.ts.map +1 -0
  26. package/dist/FormBinding.js +122 -0
  27. package/dist/FormBinding.js.map +1 -0
  28. package/dist/FormView.d.ts +48 -0
  29. package/dist/FormView.d.ts.map +1 -0
  30. package/dist/FormView.js +203 -0
  31. package/dist/FormView.js.map +1 -0
  32. package/dist/context.d.ts +15 -0
  33. package/dist/context.d.ts.map +1 -0
  34. package/dist/context.js +32 -0
  35. package/dist/context.js.map +1 -0
  36. package/dist/cx.d.ts +3 -0
  37. package/dist/cx.d.ts.map +1 -0
  38. package/dist/cx.js +9 -0
  39. package/dist/cx.js.map +1 -0
  40. package/dist/describe.d.ts +7 -0
  41. package/dist/describe.d.ts.map +1 -0
  42. package/dist/describe.js +17 -0
  43. package/dist/describe.js.map +1 -0
  44. package/dist/formatError.d.ts +8 -0
  45. package/dist/formatError.d.ts.map +1 -0
  46. package/dist/formatError.js +46 -0
  47. package/dist/formatError.js.map +1 -0
  48. package/dist/index.d.ts +10 -12
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +10 -90
  51. package/dist/layout/Layout.d.ts +9 -0
  52. package/dist/layout/Layout.d.ts.map +1 -0
  53. package/dist/layout/Layout.js +442 -0
  54. package/dist/layout/Layout.js.map +1 -0
  55. package/dist/locales/index.d.ts +15 -0
  56. package/dist/locales/index.d.ts.map +1 -0
  57. package/dist/locales/index.js +21 -0
  58. package/dist/locales/index.js.map +1 -0
  59. package/dist/messages.d.ts +2 -0
  60. package/dist/messages.d.ts.map +1 -0
  61. package/dist/messages.js +1 -0
  62. package/dist/paths.d.ts +15 -0
  63. package/dist/paths.d.ts.map +1 -0
  64. package/dist/paths.js +34 -0
  65. package/dist/paths.js.map +1 -0
  66. package/dist/unsaved.d.ts +22 -0
  67. package/dist/unsaved.d.ts.map +1 -0
  68. package/dist/unsaved.js +169 -0
  69. package/dist/unsaved.js.map +1 -0
  70. package/package.json +30 -60
@@ -0,0 +1,169 @@
1
+ import { messages } from "./messages.js";
2
+ import { c } from "react/compiler-runtime";
3
+ import { Button, Dialog, usePanneauIntl } from "@panneau/ui";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { useEffect, useRef, useState } from "react";
6
+ //#region src/unsaved.tsx
7
+ /**
8
+ * Asks the browser to confirm before the page is closed or reloaded while `dirty` is true. Forms
9
+ * use it by default.
10
+ */
11
+ function useBeforeUnloadGuard(dirty) {
12
+ const $ = c(3);
13
+ let t0;
14
+ let t1;
15
+ if ($[0] !== dirty) {
16
+ t0 = () => {
17
+ if (!dirty) return;
18
+ const listener = _temp;
19
+ window.addEventListener("beforeunload", listener);
20
+ return () => window.removeEventListener("beforeunload", listener);
21
+ };
22
+ t1 = [dirty];
23
+ $[0] = dirty;
24
+ $[1] = t0;
25
+ $[2] = t1;
26
+ } else {
27
+ t0 = $[1];
28
+ t1 = $[2];
29
+ }
30
+ useEffect(t0, t1);
31
+ }
32
+ function _temp(event) {
33
+ event.preventDefault();
34
+ event.returnValue = "";
35
+ }
36
+ /**
37
+ * Guards in-app navigation while a form has unsaved changes. Call `confirmLeave()` from the
38
+ * router's navigation guard (or before closing a panel), and render `dialog`. The page itself is
39
+ * guarded by `useBeforeUnloadGuard()`.
40
+ */
41
+ function useLeaveConfirmation(dirty) {
42
+ const $ = c(29);
43
+ const intl = usePanneauIntl();
44
+ const [open, setOpen] = useState(false);
45
+ const resolver = useRef(null);
46
+ let t0;
47
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
48
+ t0 = (leave) => {
49
+ resolver.current?.(leave);
50
+ resolver.current = null;
51
+ setOpen(false);
52
+ };
53
+ $[0] = t0;
54
+ } else t0 = $[0];
55
+ const answer = t0;
56
+ let t1;
57
+ if ($[1] !== dirty) {
58
+ t1 = () => {
59
+ if (!dirty) return Promise.resolve(true);
60
+ resolver.current?.(false);
61
+ setOpen(true);
62
+ return new Promise((resolve) => {
63
+ resolver.current = resolve;
64
+ });
65
+ };
66
+ $[1] = dirty;
67
+ $[2] = t1;
68
+ } else t1 = $[2];
69
+ let t2;
70
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
71
+ t2 = (isOpen) => {
72
+ if (!isOpen) answer(false);
73
+ };
74
+ $[3] = t2;
75
+ } else t2 = $[3];
76
+ let t3;
77
+ if ($[4] !== intl) {
78
+ t3 = intl.formatMessage(messages.leaveTitle);
79
+ $[4] = intl;
80
+ $[5] = t3;
81
+ } else t3 = $[5];
82
+ let t4;
83
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
84
+ t4 = () => answer(false);
85
+ $[6] = t4;
86
+ } else t4 = $[6];
87
+ let t5;
88
+ if ($[7] !== intl) {
89
+ t5 = intl.formatMessage(messages.stay);
90
+ $[7] = intl;
91
+ $[8] = t5;
92
+ } else t5 = $[8];
93
+ let t6;
94
+ if ($[9] !== t5) {
95
+ t6 = /* @__PURE__ */ jsx(Button, {
96
+ onPress: t4,
97
+ autoFocus: true,
98
+ children: t5
99
+ });
100
+ $[9] = t5;
101
+ $[10] = t6;
102
+ } else t6 = $[10];
103
+ let t7;
104
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
105
+ t7 = () => answer(true);
106
+ $[11] = t7;
107
+ } else t7 = $[11];
108
+ let t8;
109
+ if ($[12] !== intl) {
110
+ t8 = intl.formatMessage(messages.leave);
111
+ $[12] = intl;
112
+ $[13] = t8;
113
+ } else t8 = $[13];
114
+ let t9;
115
+ if ($[14] !== t8) {
116
+ t9 = /* @__PURE__ */ jsx(Button, {
117
+ variant: "danger",
118
+ onPress: t7,
119
+ children: t8
120
+ });
121
+ $[14] = t8;
122
+ $[15] = t9;
123
+ } else t9 = $[15];
124
+ let t10;
125
+ if ($[16] !== t6 || $[17] !== t9) {
126
+ t10 = /* @__PURE__ */ jsxs(Fragment, { children: [t6, t9] });
127
+ $[16] = t6;
128
+ $[17] = t9;
129
+ $[18] = t10;
130
+ } else t10 = $[18];
131
+ let t11;
132
+ if ($[19] !== intl) {
133
+ t11 = intl.formatMessage(messages.leaveMessage);
134
+ $[19] = intl;
135
+ $[20] = t11;
136
+ } else t11 = $[20];
137
+ let t12;
138
+ if ($[21] !== open || $[22] !== t10 || $[23] !== t11 || $[24] !== t3) {
139
+ t12 = /* @__PURE__ */ jsx(Dialog, {
140
+ isOpen: open,
141
+ onOpenChange: t2,
142
+ role: "alertdialog",
143
+ size: "sm",
144
+ title: t3,
145
+ footer: t10,
146
+ children: t11
147
+ });
148
+ $[21] = open;
149
+ $[22] = t10;
150
+ $[23] = t11;
151
+ $[24] = t3;
152
+ $[25] = t12;
153
+ } else t12 = $[25];
154
+ let t13;
155
+ if ($[26] !== t1 || $[27] !== t12) {
156
+ t13 = {
157
+ confirmLeave: t1,
158
+ dialog: t12
159
+ };
160
+ $[26] = t1;
161
+ $[27] = t12;
162
+ $[28] = t13;
163
+ } else t13 = $[28];
164
+ return t13;
165
+ }
166
+ //#endregion
167
+ export { useBeforeUnloadGuard, useLeaveConfirmation };
168
+
169
+ //# sourceMappingURL=unsaved.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsaved.js","names":["open","_c","_Fragment"],"sources":["../src/unsaved.tsx"],"sourcesContent":["import { type ReactNode, useEffect, useRef, useState } from 'react';\n\nimport { Button, Dialog, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from './messages';\n\n/**\n * Asks the browser to confirm before the page is closed or reloaded while `dirty` is true. Forms\n * use it by default.\n */\nexport function useBeforeUnloadGuard(dirty: boolean): void {\n useEffect(() => {\n if (!dirty) {\n return undefined;\n }\n const listener = (event: BeforeUnloadEvent) => {\n event.preventDefault();\n // Older browsers show the dialog only with a return value.\n event.returnValue = '';\n };\n window.addEventListener('beforeunload', listener);\n return () => window.removeEventListener('beforeunload', listener);\n }, [dirty]);\n}\n\nexport interface LeaveConfirmation {\n /**\n * Resolves `true` when leaving is fine: right away without unsaved changes, or once the user\n * chose to leave in the dialog.\n */\n confirmLeave: () => Promise<boolean>;\n /** The dialog to render, while it is open. */\n dialog: ReactNode;\n}\n\n/**\n * Guards in-app navigation while a form has unsaved changes. Call `confirmLeave()` from the\n * router's navigation guard (or before closing a panel), and render `dialog`. The page itself is\n * guarded by `useBeforeUnloadGuard()`.\n */\nexport function useLeaveConfirmation(dirty: boolean): LeaveConfirmation {\n const intl = usePanneauIntl();\n const [open, setOpen] = useState(false);\n const resolver = useRef<((leave: boolean) => void) | null>(null);\n const answer = (leave: boolean) => {\n resolver.current?.(leave);\n resolver.current = null;\n setOpen(false);\n };\n return {\n confirmLeave: () => {\n if (!dirty) {\n return Promise.resolve(true);\n }\n resolver.current?.(false);\n setOpen(true);\n return new Promise<boolean>((resolve) => {\n resolver.current = resolve;\n });\n },\n dialog: (\n <Dialog\n isOpen={open}\n onOpenChange={(isOpen) => {\n if (!isOpen) {\n answer(false);\n }\n }}\n role=\"alertdialog\"\n size=\"sm\"\n title={intl.formatMessage(messages.leaveTitle)}\n footer={\n <>\n <Button onPress={() => answer(false)} autoFocus>\n {intl.formatMessage(messages.stay)}\n </Button>\n <Button variant=\"danger\" onPress={() => answer(true)}>\n {intl.formatMessage(messages.leave)}\n </Button>\n </>\n }\n >\n {intl.formatMessage(messages.leaveMessage)}\n </Dialog>\n ),\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,83 +1,53 @@
1
1
  {
2
2
  "name": "@panneau/forms",
3
- "version": "4.1.1",
4
- "description": "",
5
- "keywords": [
6
- "javascript"
7
- ],
8
- "homepage": "https://github.com/folkloreinc/panneau-js",
3
+ "version": "5.0.0-alpha.0",
4
+ "description": "Forms of Panneau: fields in a layout, driven by the form state of @panneau/core, with errors, unsaved changes and version conflicts.",
5
+ "type": "module",
6
+ "license": "MIT",
9
7
  "repository": {
10
8
  "type": "git",
11
- "url": "git+https://github.com/folkloreinc/panneau-js.git"
12
- },
13
- "license": "ISC",
14
- "author": {
15
- "name": "Folklore",
16
- "email": "info@folklore.email"
9
+ "url": "git+https://github.com/folkloreinc/panneau-js.git",
10
+ "directory": "packages/forms"
17
11
  },
18
- "contributors": [
19
- {
20
- "name": "David Mongeau-Petitpas",
21
- "email": "dmp@folklore.email"
22
- },
23
- {
24
- "name": "Nicolas Roy-Bourdages",
25
- "email": "nrb@folklore.email"
26
- },
27
- {
28
- "name": "Julien Carignan",
29
- "email": "jc@folklore.email"
30
- },
31
- {
32
- "name": "Théo Gjini",
33
- "email": "tg@folklore.email"
34
- }
35
- ],
36
12
  "sideEffects": [
37
- "**/*.css"
13
+ "*.css"
38
14
  ],
39
- "type": "module",
40
15
  "exports": {
41
16
  ".": {
17
+ "@panneau/source": "./src/index.ts",
42
18
  "types": "./dist/index.d.ts",
43
- "style": "./assets/css/styles.css",
44
19
  "default": "./dist/index.js"
45
20
  },
46
- "./assets/css/styles": "./assets/css/styles.css",
47
- "./assets/css/styles.css": "./assets/css/styles.css"
21
+ "./locales": {
22
+ "@panneau/source": "./src/locales/index.ts",
23
+ "types": "./dist/locales/index.d.ts",
24
+ "default": "./dist/locales/index.js"
25
+ },
26
+ "./package.json": "./package.json"
48
27
  },
49
- "module": "dist/index.js",
50
- "types": "dist/index.d.ts",
51
- "style": "assets/css/styles.css",
52
28
  "files": [
53
- "dist",
54
- "assets"
29
+ "dist"
55
30
  ],
56
31
  "scripts": {
57
- "build": "../../scripts/prepare-package.sh --types",
58
- "css": "../../scripts/build-packages-styles.js --pattern='@panneau/form-*' ./src/styles.css.ejs ./assets/css/styles.css",
59
- "prepublishOnly": "npm run build"
32
+ "build": "vite build && tsc -p tsconfig.build.json",
33
+ "typecheck": "tsc --noEmit",
34
+ "api": "tsc -p tsconfig.build.json && node ../../scripts/api-report.js"
60
35
  },
61
- "dependencies": {
62
- "@babel/runtime": "^7.28.6",
63
- "@panneau/core": "^4.1.1",
64
- "@panneau/form-auth": "^4.1.1",
65
- "@panneau/form-horizontal": "^4.1.1",
66
- "@panneau/form-inline": "^4.1.1",
67
- "@panneau/form-normal": "^4.1.1",
68
- "@panneau/form-two-pane": "^4.1.1",
69
- "lodash-es": "^4.17.21"
70
- },
71
- "devDependencies": {
72
- "react": "^19.2.0",
73
- "react-dom": "^19.0.0"
36
+ "publishConfig": {
37
+ "access": "public"
74
38
  },
75
39
  "peerDependencies": {
76
40
  "react": "^19.2.0",
77
- "react-dom": "^19.0.0"
41
+ "react-intl": "^12.0.0"
78
42
  },
79
- "publishConfig": {
80
- "access": "public"
43
+ "dependencies": {
44
+ "@panneau/core": "5.0.0-alpha.0",
45
+ "@panneau/fields": "5.0.0-alpha.0",
46
+ "@panneau/intl": "5.0.0-alpha.0",
47
+ "@panneau/protocol": "5.0.0-alpha.0",
48
+ "@panneau/ui": "5.0.0-alpha.0"
81
49
  },
82
- "gitHead": "28b394278cffa0c927989873dd4b3f184635ceff"
50
+ "devDependencies": {
51
+ "@panneau/data": "5.0.0-alpha.0"
52
+ }
83
53
  }