@web-atoms/web-controls 2.3.109 → 2.3.110

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 (236) hide show
  1. package/dist/animations/Animations.d.ts.map +1 -1
  2. package/dist/animations/Animations.js +34 -8
  3. package/dist/animations/Animations.js.map +1 -1
  4. package/dist/basic/Form.d.ts +29 -73
  5. package/dist/basic/Form.d.ts.map +1 -1
  6. package/dist/basic/Form.js +85 -283
  7. package/dist/basic/Form.js.map +1 -1
  8. package/dist/basic/FormField.d.ts +1 -0
  9. package/dist/basic/FormField.d.ts.map +1 -1
  10. package/dist/basic/FormField.js +3 -14
  11. package/dist/basic/FormField.js.map +1 -1
  12. package/dist/basic/InlinePopup.d.ts +1 -0
  13. package/dist/basic/InlinePopup.d.ts.map +1 -1
  14. package/dist/basic/InlinePopup.js +2 -4
  15. package/dist/basic/InlinePopup.js.map +1 -1
  16. package/dist/basic/ListRepeater.d.ts +1 -0
  17. package/dist/basic/ListRepeater.d.ts.map +1 -1
  18. package/dist/basic/ListRepeater.js +3 -8
  19. package/dist/basic/ListRepeater.js.map +1 -1
  20. package/dist/basic/MaskedInput.d.ts +1 -0
  21. package/dist/basic/MaskedInput.d.ts.map +1 -1
  22. package/dist/basic/MaskedInput.js +3 -8
  23. package/dist/basic/MaskedInput.js.map +1 -1
  24. package/dist/basic/MaskedInputDiv.d.ts +1 -0
  25. package/dist/basic/MaskedInputDiv.d.ts.map +1 -1
  26. package/dist/basic/MaskedInputDiv.js +3 -16
  27. package/dist/basic/MaskedInputDiv.js.map +1 -1
  28. package/dist/basic/OldForm.d.ts +79 -0
  29. package/dist/basic/OldForm.d.ts.map +1 -0
  30. package/dist/basic/OldForm.js +318 -0
  31. package/dist/basic/OldForm.js.map +1 -0
  32. package/dist/basic/PasswordBox.d.ts +1 -0
  33. package/dist/basic/PasswordBox.d.ts.map +1 -1
  34. package/dist/basic/PasswordBox.js +3 -8
  35. package/dist/basic/PasswordBox.js.map +1 -1
  36. package/dist/basic/PinchZoomView.d.ts +1 -0
  37. package/dist/basic/PinchZoomView.d.ts.map +1 -1
  38. package/dist/basic/PinchZoomView.js +3 -13
  39. package/dist/basic/PinchZoomView.js.map +1 -1
  40. package/dist/basic/PopupButton.d.ts +1 -0
  41. package/dist/basic/PopupButton.d.ts.map +1 -1
  42. package/dist/basic/PopupButton.js +3 -13
  43. package/dist/basic/PopupButton.js.map +1 -1
  44. package/dist/basic/RadioButtonList.d.ts +1 -0
  45. package/dist/basic/RadioButtonList.d.ts.map +1 -1
  46. package/dist/basic/RadioButtonList.js +4 -17
  47. package/dist/basic/RadioButtonList.js.map +1 -1
  48. package/dist/basic/Swipe.d.ts +1 -0
  49. package/dist/basic/Swipe.d.ts.map +1 -1
  50. package/dist/basic/Swipe.js +3 -9
  51. package/dist/basic/Swipe.js.map +1 -1
  52. package/dist/basic/Switch.d.ts +4 -0
  53. package/dist/basic/Switch.d.ts.map +1 -1
  54. package/dist/basic/Switch.js +4 -23
  55. package/dist/basic/Switch.js.map +1 -1
  56. package/dist/basic/TableRepeater.d.ts.map +1 -1
  57. package/dist/basic/TableRepeater.js +2 -7
  58. package/dist/basic/TableRepeater.js.map +1 -1
  59. package/dist/basic/TimeEditor.d.ts +1 -0
  60. package/dist/basic/TimeEditor.d.ts.map +1 -1
  61. package/dist/basic/TimeEditor.js +3 -13
  62. package/dist/basic/TimeEditor.js.map +1 -1
  63. package/dist/basic/TitleEditor.d.ts +1 -0
  64. package/dist/basic/TitleEditor.d.ts.map +1 -1
  65. package/dist/basic/TitleEditor.js +3 -8
  66. package/dist/basic/TitleEditor.js.map +1 -1
  67. package/dist/basic/ToggleButtonBar.d.ts +1 -0
  68. package/dist/basic/ToggleButtonBar.d.ts.map +1 -1
  69. package/dist/basic/ToggleButtonBar.js +3 -10
  70. package/dist/basic/ToggleButtonBar.js.map +1 -1
  71. package/dist/basic/Tooltip.d.ts +1 -0
  72. package/dist/basic/Tooltip.d.ts.map +1 -1
  73. package/dist/basic/Tooltip.js +3 -8
  74. package/dist/basic/Tooltip.js.map +1 -1
  75. package/dist/basic/styles/form-field-style.d.ts +2 -0
  76. package/dist/basic/styles/form-field-style.d.ts.map +1 -0
  77. package/dist/basic/styles/form-field-style.js +146 -0
  78. package/dist/basic/styles/form-field-style.js.map +1 -0
  79. package/dist/basic/styles/inline-popup-style.d.ts +2 -0
  80. package/dist/basic/styles/inline-popup-style.d.ts.map +1 -0
  81. package/dist/basic/styles/inline-popup-style.js +28 -0
  82. package/dist/basic/styles/inline-popup-style.js.map +1 -0
  83. package/dist/basic/styles/list-repeater-style.d.ts +2 -0
  84. package/dist/basic/styles/list-repeater-style.d.ts.map +1 -0
  85. package/dist/basic/styles/list-repeater-style.js +36 -0
  86. package/dist/basic/styles/list-repeater-style.js.map +1 -0
  87. package/dist/basic/styles/masked-input-div.d.ts +2 -0
  88. package/dist/basic/styles/masked-input-div.d.ts.map +1 -0
  89. package/dist/basic/styles/masked-input-div.js +52 -0
  90. package/dist/basic/styles/masked-input-div.js.map +1 -0
  91. package/dist/basic/styles/masked-input-style.d.ts +2 -0
  92. package/dist/basic/styles/masked-input-style.d.ts.map +1 -0
  93. package/dist/basic/styles/masked-input-style.js +19 -0
  94. package/dist/basic/styles/masked-input-style.js.map +1 -0
  95. package/dist/basic/styles/password-box-style.d.ts +2 -0
  96. package/dist/basic/styles/password-box-style.d.ts.map +1 -0
  97. package/dist/basic/styles/password-box-style.js +35 -0
  98. package/dist/basic/styles/password-box-style.js.map +1 -0
  99. package/dist/basic/styles/pinch-zoom-view-style.d.ts +2 -0
  100. package/dist/basic/styles/pinch-zoom-view-style.d.ts.map +1 -0
  101. package/dist/basic/styles/pinch-zoom-view-style.js +61 -0
  102. package/dist/basic/styles/pinch-zoom-view-style.js.map +1 -0
  103. package/dist/basic/styles/popup-button-style.d.ts +2 -0
  104. package/dist/basic/styles/popup-button-style.d.ts.map +1 -0
  105. package/dist/basic/styles/popup-button-style.js +40 -0
  106. package/dist/basic/styles/popup-button-style.js.map +1 -0
  107. package/dist/basic/styles/radio-button-list-style.d.ts +2 -0
  108. package/dist/basic/styles/radio-button-list-style.d.ts.map +1 -0
  109. package/dist/basic/styles/radio-button-list-style.js +44 -0
  110. package/dist/basic/styles/radio-button-list-style.js.map +1 -0
  111. package/dist/basic/styles/swipe-style.d.ts +2 -0
  112. package/dist/basic/styles/swipe-style.d.ts.map +1 -0
  113. package/dist/basic/styles/swipe-style.js +32 -0
  114. package/dist/basic/styles/swipe-style.js.map +1 -0
  115. package/dist/basic/styles/switch-style.d.ts +2 -0
  116. package/dist/basic/styles/switch-style.d.ts.map +1 -0
  117. package/dist/basic/styles/switch-style.js +127 -0
  118. package/dist/basic/styles/switch-style.js.map +1 -0
  119. package/dist/basic/styles/time-editor-style.d.ts +2 -0
  120. package/dist/basic/styles/time-editor-style.d.ts.map +1 -0
  121. package/dist/basic/styles/time-editor-style.js +64 -0
  122. package/dist/basic/styles/time-editor-style.js.map +1 -0
  123. package/dist/basic/styles/title-editor-style.d.ts +2 -0
  124. package/dist/basic/styles/title-editor-style.d.ts.map +1 -0
  125. package/dist/basic/styles/title-editor-style.js +45 -0
  126. package/dist/basic/styles/title-editor-style.js.map +1 -0
  127. package/dist/basic/styles/toggle-button-bar-style.d.ts +2 -0
  128. package/dist/basic/styles/toggle-button-bar-style.d.ts.map +1 -0
  129. package/dist/basic/styles/toggle-button-bar-style.js +48 -0
  130. package/dist/basic/styles/toggle-button-bar-style.js.map +1 -0
  131. package/dist/basic/styles/toggle-view-style.d.ts +2 -0
  132. package/dist/basic/styles/toggle-view-style.d.ts.map +1 -0
  133. package/dist/basic/styles/toggle-view-style.js +91 -0
  134. package/dist/basic/styles/toggle-view-style.js.map +1 -0
  135. package/dist/basic/styles/tooltip-style.d.ts +2 -0
  136. package/dist/basic/styles/tooltip-style.d.ts.map +1 -0
  137. package/dist/basic/styles/tooltip-style.js +21 -0
  138. package/dist/basic/styles/tooltip-style.js.map +1 -0
  139. package/dist/html-editor/InlineHtmlEditor.d.ts.map +1 -1
  140. package/dist/html-editor/InlineHtmlEditor.js +29 -7
  141. package/dist/html-editor/InlineHtmlEditor.js.map +1 -1
  142. package/dist/mobile-app/BottomPopup.d.ts.map +1 -1
  143. package/dist/mobile-app/BottomPopup.js +76 -14
  144. package/dist/mobile-app/BottomPopup.js.map +1 -1
  145. package/dist/mobile-app/MobileApp.d.ts.map +1 -1
  146. package/dist/mobile-app/MobileApp.js +226 -26
  147. package/dist/mobile-app/MobileApp.js.map +1 -1
  148. package/dist/player/AtomVideoPlayer.d.ts.map +1 -1
  149. package/dist/player/AtomVideoPlayer.js +160 -13
  150. package/dist/player/AtomVideoPlayer.js.map +1 -1
  151. package/dist/toggle-view/AtomToggleView.d.ts +1 -0
  152. package/dist/toggle-view/AtomToggleView.d.ts.map +1 -1
  153. package/dist/toggle-view/AtomToggleView.js +3 -16
  154. package/dist/toggle-view/AtomToggleView.js.map +1 -1
  155. package/dist/tsconfig.tsbuildinfo +1 -1
  156. package/package.json +2 -2
  157. package/src/animations/Animations.ts +32 -28
  158. package/src/basic/Form.tsx +89 -383
  159. package/src/basic/FormField.tsx +1 -117
  160. package/src/basic/InlinePopup.tsx +1 -16
  161. package/src/basic/ListRepeater.tsx +1 -26
  162. package/src/basic/MaskedInput.tsx +2 -17
  163. package/src/basic/MaskedInputDiv.tsx +2 -41
  164. package/src/basic/OldForm.tsx +424 -0
  165. package/src/basic/PasswordBox.tsx +1 -22
  166. package/src/basic/PinchZoomView.tsx +2 -41
  167. package/src/basic/PopupButton.tsx +1 -19
  168. package/src/basic/RadioButtonList.tsx +1 -17
  169. package/src/basic/Swipe.tsx +1 -21
  170. package/src/basic/Switch.tsx +2 -83
  171. package/src/basic/TableRepeater.tsx +0 -3
  172. package/src/basic/TimeEditor.tsx +2 -40
  173. package/src/basic/TitleEditor.tsx +1 -28
  174. package/src/basic/ToggleButtonBar.tsx +1 -30
  175. package/src/basic/Tooltip.tsx +2 -5
  176. package/src/basic/styles/form-field-style.ts +136 -0
  177. package/src/basic/styles/inline-popup-style.ts +19 -0
  178. package/src/basic/styles/list-repeater-style.ts +25 -0
  179. package/src/basic/styles/masked-input-div.ts +41 -0
  180. package/src/basic/styles/masked-input-style.ts +8 -0
  181. package/src/basic/styles/password-box-style.ts +24 -0
  182. package/src/basic/styles/pinch-zoom-view-style.ts +50 -0
  183. package/src/basic/styles/popup-button-style.ts +30 -0
  184. package/src/basic/styles/radio-button-list-style.ts +34 -0
  185. package/src/basic/styles/swipe-style.ts +22 -0
  186. package/src/basic/styles/switch-style.ts +116 -0
  187. package/src/basic/styles/time-editor-style.ts +53 -0
  188. package/src/basic/styles/title-editor-style.ts +34 -0
  189. package/src/basic/styles/toggle-button-bar-style.ts +37 -0
  190. package/src/basic/styles/toggle-view-style.ts +80 -0
  191. package/src/basic/styles/tooltip-style.ts +10 -0
  192. package/src/html-editor/InlineHtmlEditor.tsx +26 -16
  193. package/src/mobile-app/BottomPopup.tsx +73 -68
  194. package/src/mobile-app/MobileApp.tsx +227 -174
  195. package/src/player/AtomVideoPlayer.tsx +157 -141
  196. package/src/toggle-view/AtomToggleView.tsx +3 -53
  197. package/dist/basic/Form2.d.ts +0 -27
  198. package/dist/basic/Form2.d.ts.map +0 -1
  199. package/dist/basic/Form2.js +0 -120
  200. package/dist/basic/Form2.js.map +0 -1
  201. package/dist/basic/FormDialog.d.ts +0 -4
  202. package/dist/basic/FormDialog.d.ts.map +0 -1
  203. package/dist/basic/FormDialog.js +0 -32
  204. package/dist/basic/FormDialog.js.map +0 -1
  205. package/dist/basic/Input.d.ts +0 -5
  206. package/dist/basic/Input.d.ts.map +0 -1
  207. package/dist/basic/Input.js +0 -30
  208. package/dist/basic/Input.js.map +0 -1
  209. package/dist/basic/Mix.d.ts +0 -10
  210. package/dist/basic/Mix.d.ts.map +0 -1
  211. package/dist/basic/Mix.js +0 -31
  212. package/dist/basic/Mix.js.map +0 -1
  213. package/dist/basic/Panel.d.ts +0 -6
  214. package/dist/basic/Panel.d.ts.map +0 -1
  215. package/dist/basic/Panel.js +0 -37
  216. package/dist/basic/Panel.js.map +0 -1
  217. package/dist/basic/Row.d.ts +0 -15
  218. package/dist/basic/Row.d.ts.map +0 -1
  219. package/dist/basic/Row.js +0 -43
  220. package/dist/basic/Row.js.map +0 -1
  221. package/dist/switch/AtomSwitch.d.ts +0 -7
  222. package/dist/switch/AtomSwitch.d.ts.map +0 -1
  223. package/dist/switch/AtomSwitch.js +0 -42
  224. package/dist/switch/AtomSwitch.js.map +0 -1
  225. package/dist/switch/AtomSwitchStyle.d.ts +0 -8
  226. package/dist/switch/AtomSwitchStyle.d.ts.map +0 -1
  227. package/dist/switch/AtomSwitchStyle.js +0 -80
  228. package/dist/switch/AtomSwitchStyle.js.map +0 -1
  229. package/src/basic/Form2.tsx +0 -121
  230. package/src/basic/FormDialog.tsx +0 -28
  231. package/src/basic/Input.tsx +0 -30
  232. package/src/basic/Mix.tsx +0 -25
  233. package/src/basic/Panel.tsx +0 -43
  234. package/src/basic/Row.tsx +0 -49
  235. package/src/switch/AtomSwitch.tsx +0 -24
  236. package/src/switch/AtomSwitchStyle.ts +0 -71
@@ -1,424 +1,130 @@
1
1
  import Bind from "@web-atoms/core/dist/core/Bind";
2
- import Command from "@web-atoms/core/dist/core/Command";
3
- import XNode from "@web-atoms/core/dist/core/XNode";
4
- import StyleRule from "@web-atoms/core/dist/style/StyleRule";
5
- import { ChildEnumerator } from "@web-atoms/core/dist/web/core/AtomUI";
6
- import CSS from "@web-atoms/core/dist/web/styles/CSS";
7
- import FormField from "./FormField";
8
- import IElement from "./IElement";
9
- import ToggleButtonBar from "./ToggleButtonBar";
10
- export const FormButtonBar = ToggleButtonBar;
2
+ import XNode, { elementFactorySymbol } from "@web-atoms/core/dist/core/XNode";
3
+ import styled from "@web-atoms/core/dist/style/styled";
11
4
 
12
- const css = CSS(StyleRule()
13
- .verticalFlexLayout({ alignItems: "stretch" })
14
- .displayNone(" .field-error:empty")
15
- .displayNone(":not([data-wa-show-errors=yes]) .field-error:not(:empty)")
16
- .child(StyleRule("button")
17
- .alignSelf("flex-start")
18
- )
19
- .and(StyleRule("[data-scrollable=true]")
20
- .justifyContent("flex-start")
21
- .overflow("auto")
22
- )
23
- , "*[data-wa-form=wa-form]");
5
+ styled.css `
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: var(--spacing, 5px);
24
9
 
25
- export interface ISubmitButton {
26
- eventClick: any;
27
- class?: string;
28
- [key: string]: any;
29
- }
30
-
31
- export interface ISubmitAction extends IElement {
32
- action: "submit";
33
- eventClick?: any;
34
- "event-click"?: any;
35
- }
36
-
37
- export interface ICancelAction extends IElement {
38
- action: "cancel";
39
- eventClick?: any;
40
- "event-click"?: any;
41
- }
42
-
43
- export type IFormAction = ISubmitAction | ICancelAction;
44
-
45
- /**
46
- * This is just a decorator, you must have a child button for this to work
47
- * @param action submit | cancel
48
- * @param node child node where action will be applied
49
- * @returns XNode
50
- */
51
- export function FormAction(
52
- {
53
- action = "submit",
54
- eventClick,
55
- "event-click": eventClick2,
56
- ... a
57
- }: IFormAction,
58
- node: XNode) {
59
- const attributes = node.attributes ??= {};
60
- attributes["data-wa-form-action"] = action;
61
- const e = attributes["event-click"] || attributes.eventClick;
62
- if (e) {
63
- attributes["event-submit"] = e;
64
- delete attributes["event-click"];
65
- delete attributes.eventClick;
66
- }
67
- eventClick ??= eventClick2;
68
- if (action === "submit" && eventClick) {
69
- attributes.eventSubmit = eventClick;
70
- }
71
- node.attributes = { ... a, ... attributes};
72
- return node;
73
- }
74
-
75
- /**
76
- * @deprecated Use Form with eventSubmit and button with data-event="submit"
77
- */
78
- export function SubmitAction(a: IElement, node: XNode) {
79
- (a as any).action = "submit";
80
- return FormAction(a as any, node);
81
- }
82
-
83
- /**
84
- * @deprecated Use Form with eventSubmit and button with data-event="submit"
85
- */
86
- export function CancelAction(a: IElement, node: XNode) {
87
- (a as any).action = "cancel";
88
- return FormAction(a as any, node);
89
- }
90
-
91
- /**
92
- * @deprecated Use Form with eventSubmit and button with data-event="submit"
93
- */
94
- export function SubmitButton(
95
- { eventClick,
96
- ... others}: ISubmitButton,
97
- ... nodes: XNode[]) {
98
- return <button
99
- data-wa-form-action="submit"
100
- eventSubmit={eventClick} { ... others }>{ ... nodes}</button>;
101
- }
102
-
103
- function findSubmitAction(e: Event) {
104
- let button = e.target as HTMLElement;
105
- if (e.type === "submit") {
106
- e.preventDefault();
107
- button = (e as SubmitEvent).submitter;
108
- }
109
- while (button) {
110
- const action = button.dataset.waFormAction ?? button.dataset.event;
111
- if (/submit|cancel/i.test(action)) {
112
- return { button, action };
10
+ &[data-valid=true] {
11
+ & .field-error:not(:empty) {
12
+ display: none;
113
13
  }
114
- button = button.parentElement;
115
- }
116
- return { button };
117
- }
118
-
119
- const submitFormHandler = (form: HTMLElement) => {
120
- if (!form.dataset.waShowErrors) {
121
- form.dataset.waShowErrors = "yes";
122
- }
123
- setTimeout(() => {
124
- const all = Array.from(form.getElementsByClassName("field-error"));
125
- for (const iterator of all) {
126
- if (iterator.textContent) {
127
- alert(form.dataset?.errorMessage ?? "Please fix all validations");
128
- return;
129
- }
14
+ & > .error-message {
15
+ display: none;
130
16
  }
131
- form.dispatchEvent(new CustomEvent("submitForm"));
132
- }, 100);
133
- };
134
-
135
- const checkValidity = (handler) => (e: MouseEvent) => {
136
-
137
- const form = e.currentTarget as HTMLFormElement;
138
-
139
- const { button, action } = findSubmitAction(e);
140
- if (!button) {
141
- return;
142
17
  }
143
18
 
144
- if (handler) {
145
- submitFormHandler(form);
146
- return;
19
+ & > .error-message {
20
+ padding: var(--spacing-small, 2px);
21
+ padding-left: var(--spacing-large, 10px);
22
+ padding-right: var(--spacing-large, 10px);
23
+ background-color: red;
24
+ border-radius: 9999px;
25
+ color: white;
26
+ position: sticky;
147
27
  }
28
+ `.installGlobal("[data-form=form]");
148
29
 
149
- // if (button.tagName === "BUTTON" && e.type !== "submit") {
150
- // // as submit will be followed, we would ignore this only if the tag is button
151
- // return;
152
- // }
153
- if (action === "cancel") {
154
- form.dataset.waShowErrors = "";
30
+ const checkClick = (e: MouseEvent) => {
31
+ const form = e.currentTarget as HTMLDivElement;
32
+ const target = e.target as HTMLButtonElement;
33
+ if (!/submit/i.test(target.type ?? target.getAttribute("data-type") )) {
155
34
  return;
156
35
  }
157
- if (!form.dataset.waShowErrors) {
158
- form.dataset.waShowErrors = "yes";
159
- }
160
-
36
+ form.setAttribute("data-show-validation", "true");
161
37
  setTimeout(() => {
162
38
  const all = Array.from(form.getElementsByClassName("field-error"));
163
39
  for (const iterator of all) {
164
40
  if (iterator.textContent) {
165
- alert(form.dataset?.errorMessage ?? "Please fix all validations");
41
+ form.setAttribute("data-valid", "false");
166
42
  return;
167
43
  }
168
44
  }
169
- button.dispatchEvent(new CustomEvent("submit"));
45
+ form.setAttribute("data-valid", "true");
46
+ target.dispatchEvent(new CustomEvent(form.getAttribute("data-submit-event"), { bubbles: true, cancelable: true }));
170
47
  }, 100);
171
48
  };
172
49
 
173
- const moveNext = (handler) => (e: KeyboardEvent) => {
174
- if (!/enter|submit|return/i.test(e.key)) {
175
- return;
176
- }
177
- const element = e.target as HTMLElement;
178
- if (!element.tagName) {
179
- return;
180
- }
181
- if (handler) {
182
- if (/^INPUT$/.test(element.tagName)) {
183
- submitFormHandler(e.currentTarget as HTMLElement);
184
- }
185
- return;
186
- }
187
- if (element.dataset.waFormAction === "submit") {
188
- element.dispatchEvent(new MouseEvent("click"));
189
- return;
190
- }
191
- if (/input/i.test(element.tagName)) {
192
- e.preventDefault();
193
- element.dispatchEvent(new KeyboardEvent("keypress", {
194
- key: "tab"
195
- }));
196
- }
197
- };
198
-
199
- document.body.addEventListener("click", (e: MouseEvent) => {
200
- let start = e.target as HTMLElement;
201
- let id;
202
- while (start) {
203
- id = start.dataset.submitFormId;
204
- if (id) {
205
- break;
206
- }
207
- start = start.parentElement;
208
- }
209
- if (!start) {
210
- return;
211
- }
212
- const form = document.body.querySelector(`[data-form-id="${id}"]`);
213
- submitFormHandler(form as HTMLElement);
214
- });
215
-
216
- export interface IForm {
217
- id?: number;
218
- class?: any;
219
- scrollable?: boolean ;
50
+ export interface IForm2 {
220
51
  /**
221
- * If set, when an enter key is pressed on
222
- * non textarea element, form will be submitted automatically
52
+ * The event that will be dispatched, default is `submitForm`
223
53
  */
224
- eventSubmit?: any;
54
+ "data-submit-event"?: string;
225
55
  /**
226
- * By default it is true, when user presses enter button on an input
227
- * the focus will move on to the next input element
56
+ * Validation will be displayed if set to true, default is false.
57
+ * It will be set to true if button with type=submit or data-type=submit will be clicked.
228
58
  */
229
- focusNextOnEnter?: boolean;
230
- [key: string]: any;
231
-
232
- submitCommand?: Command;
233
- }
234
-
235
- let formId = 0;
236
-
237
- const formGroupSymbol = Symbol("formGroup");
59
+ "data-show-validation"?: "true" | "false"
60
+ /**
61
+ * Default error message to be displayed if any field contains error.
62
+ */
63
+ "data-error-message"?: string;
238
64
 
239
- export interface IFormGroup {
240
- group: string;
241
- // header?: string;
242
- // icon?: string;
65
+ /**
66
+ * Please change your form style to catch event-submit-form
67
+ */
68
+ eventSubmit?: never;
69
+ /**
70
+ * Please change your form style to catch event-submit-form
71
+ */
72
+ submitCommand?: never;
243
73
  }
244
74
 
245
- export function FormGroup(
246
- fg: IFormGroup,
247
- ... nodes: XNode[]
248
- ) {
249
- fg[formGroupSymbol] = true;
75
+ export default function Form({
76
+ "data-submit-event": submitEvent = "submitForm",
77
+ "data-show-validation": showValidation = "false",
78
+ "data-error-message": errorMessage = "Please fix all validations",
79
+ ... a
80
+ }: IForm2, ... nodes: XNode[]) {
250
81
  return <div
251
- { ... fg}>
82
+ { ... a}
83
+ data-submit-event={submitEvent}
84
+ data-form="form"
85
+ data-valid="true"
86
+ data-show-validation={showValidation}
87
+ data-error-message={errorMessage}
88
+ event-click={checkClick}>
89
+ <div class="error-message" text={errorMessage}/>
252
90
  { ... nodes}
253
91
  </div>;
254
92
  }
255
93
 
256
- export default function Form(
257
- {
258
- id = formId++,
259
- focusNextOnEnter = true,
260
- scrollable,
261
- eventSubmit,
262
- submitCommand,
263
- ... a
264
- }: IForm,
265
- ... nodes: XNode[]) {
266
- if (focusNextOnEnter) {
267
- a.eventKeypress = moveNext(eventSubmit);
268
- }
269
- a["data-form-id"] = id;
270
- a["data-scrollable"] = !!scrollable;
271
- if (!eventSubmit) {
272
- a["data-wa-show-errors"] = "yes";
273
- }
274
- if (submitCommand) {
275
- a["event-" + submitCommand.name] = checkValidity(eventSubmit);
276
- }
277
- const fields = [];
278
- for (const iterator of nodes) {
279
- if (!iterator) {
280
- continue;
281
- }
282
- const ca = iterator.attributes as any;
283
- if (ca?.[formGroupSymbol]) {
284
- for (const child of iterator.children) {
285
- const cha = child.attributes ??= {};
286
- cha["data-group"] = ca.group;
287
- fields.push(child);
288
- }
289
- continue;
290
- }
291
- fields.push(iterator);
292
- }
293
-
294
- return <div
295
- data-wa-form="wa-form"
296
- { ... a}
297
- eventSubmitForm={eventSubmit}
298
- eventClick={checkValidity(eventSubmit)}>
299
- { ... fields}
300
- </div>;
301
- }
94
+ type Func = (... p: any[]) => any;
302
95
 
303
- export interface IFormLayout extends IForm {
304
- header?: XNode;
305
- footer?: XNode;
96
+ export interface IValidator {
97
+ value: Func;
98
+ message?: (value: string, label: string) => string;
99
+ isValid?: (value: string, element: HTMLElement) => boolean;
306
100
  }
307
101
 
308
- CSS(StyleRule()
309
- .display("grid")
310
- .alignSelf("stretch")
311
- .justifyContent("stretch" as any)
312
- .flex("1 1 100%")
313
- .gridTemplateRows("auto 1fr auto")
314
- .gridTemplateColumns("1fr")
315
- .child(StyleRule("[data-element=header]")
316
- .gridRowStart("1")
317
- )
318
- .child(StyleRule("[data-element=content]")
319
- .gridRowStart("2")
320
- .overflow("auto")
321
- .child(StyleRule("div")
322
- .verticalFlexLayout({ alignItems: "stretch", gap: 10 })
323
- )
324
- )
325
- .child(StyleRule("[data-element=footer]")
326
- .gridRowStart("3")
327
- )
328
- , "*[data-form-layout=form-layout]");
329
-
330
- const elementType = Symbol.for("elementType");
331
-
332
- export function FormLayout(
333
- {
334
- id = formId++,
335
- focusNextOnEnter = true,
336
- scrollable,
337
- eventSubmit,
338
- header,
339
- footer,
340
- ... a
341
- }: IFormLayout,
342
- ... nodes: XNode[]) {
343
- if (focusNextOnEnter) {
344
- a.eventKeypress = moveNext(eventSubmit);
345
- }
346
- a["data-form-id"] = id;
347
- a["data-scrollable"] = !!scrollable;
348
- if (!eventSubmit) {
349
- a["data-wa-show-errors"] = "yes";
350
- }
351
-
352
- const fields = [];
353
- for (const iterator of nodes) {
354
- if (!iterator) {
355
- continue;
356
- }
357
-
358
- const et = iterator[elementType];
359
- if (et !== void 0) {
360
- if (et === "header") {
361
- header = iterator;
362
- delete iterator[elementType];
363
- continue;
364
- }
365
- if (et === "footer") {
366
- footer = iterator;
367
- delete iterator[elementType];
368
- continue;
102
+ export const BindError = ({
103
+ value,
104
+ message = (v, l) => `${l} is invalid`,
105
+ isValid = (v, e) => !!v,
106
+ }: IValidator) => {
107
+ function f2 (sender, element: HTMLElement) {
108
+ const isRequired = element.parentElement.querySelector(`[data-required]`);
109
+ const msg = value.call(this, sender);
110
+ if (!msg) {
111
+ if (!isRequired) {
112
+ return "";
369
113
  }
370
114
  }
371
-
372
- const ca = iterator.attributes as any;
373
- if (ca?.[formGroupSymbol]) {
374
- for (const child of iterator.children) {
375
- const cha = child.attributes ??= {};
376
- cha["data-group"] = ca.group;
377
- fields.push(child);
378
- }
379
- continue;
115
+ if (isValid(msg, element)) {
116
+ return "";
380
117
  }
381
- fields.push(iterator);
382
- }
383
-
384
- if (header) {
385
- const ha = header.attributes ??= {};
386
- ha["data-element"] = "header";
387
- }
388
-
389
- if (footer) {
390
- const ha = footer.attributes ??= {};
391
- ha["data-element"] = "footer";
392
- }
393
-
394
- return <div
395
- data-wa-form="wa-form"
396
- data-form-layout="form-layout"
397
- { ... a}
398
- eventSubmitForm={eventSubmit}
399
- eventClick={checkValidity(eventSubmit)}>
400
- { header }
401
- <div data-element="content">
402
- <div>
403
- { ... fields}
404
- </div>
405
- </div>
406
- { footer }
407
- </div>;
118
+ return message(msg, element.parentElement.querySelector(`[data-element=label]`)?.textContent || "This field ");
119
+ };
120
+ f2.toString = () => value.toString();
121
+ return Bind.oneWay(f2);
408
122
  }
409
123
 
410
- FormLayout.Footer = ({}, child: XNode) => {
411
- child[elementType] = "footer";
412
- return child;
413
- };
414
-
415
- FormLayout.Header = ({}, child: XNode) => {
416
- child[elementType] = "header";
417
- return child;
418
- };
419
-
420
- Form.newId = () => formId++;
421
-
422
- Form.submitId = (id: number) => ({
423
- "data-submit-form-id": id.toString()
424
- });
124
+ export const BindEmailError = ({
125
+ value,
126
+ message = (v, l) => `${l} is not a valid email address`,
127
+ isValid = (v, e) => /[^\@]+\@[^\@]+\.[^\@]+/i.test(v),
128
+ }: IValidator) => {
129
+ return BindError({ value, message, isValid });
130
+ }
@@ -9,6 +9,7 @@ import StyleRule from "@web-atoms/core/dist/style/StyleRule";
9
9
  import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
10
10
  import PopupService, { PopupWindow } from "@web-atoms/core/dist/web/services/PopupService";
11
11
  import CSS from "@web-atoms/core/dist/web/styles/CSS";
12
+ import "./styles/form-field-style";
12
13
 
13
14
  export interface IFormField {
14
15
  label: string | XNode;
@@ -31,123 +32,6 @@ export interface IFormField {
31
32
  [key: string]: any;
32
33
  }
33
34
 
34
- const css = CSS(StyleRule()
35
- .display("grid")
36
- .alignItems("center")
37
- .gridTemplateColumns("auto 1fr auto auto")
38
- .gridTemplateRows("auto auto auto")
39
- .child(StyleRule("[data-element=label]")
40
- .gridRow("1")
41
- .gridColumn("1")
42
- )
43
- .child(StyleRule("[data-element=content]")
44
- .gridRowStart("2")
45
- .gridColumnStart("1")
46
- .gridColumnEnd("span 2")
47
- .marginTop(5)
48
- .marginBottom(5)
49
- )
50
- .and(StyleRule("[data-border=true]")
51
- .nested(StyleRule("input")
52
- .border("none")
53
- .outline("none")
54
- )
55
- .nested(StyleRule("textarea")
56
- .border("none")
57
- .outline("none")
58
- )
59
- .nested(StyleRule("select")
60
- .border("none")
61
- )
62
- )
63
- .child(StyleRule("i[data-border=border]")
64
- .gridColumnStart("1")
65
- .gridColumnEnd("span 3")
66
- .gridRowStart("3")
67
- .alignSelf("flex-end")
68
- .borderBottomStyle("solid")
69
- .borderBottomWidth("1px")
70
- .borderBottomColor(Colors.lightGray)
71
- )
72
- .and(StyleRule("[data-focused=true]")
73
- .child(StyleRule("i[data-border=border]")
74
- .borderBottomColor(Colors.black)
75
- )
76
- )
77
- .child(StyleRule("i[data-help=help]")
78
- .gridRowStart("2")
79
- .gridColumnStart("3")
80
- .padding(5)
81
- .fontSize("x-large")
82
- .cursor("pointer")
83
- .marginLeft("auto")
84
- .color(Colors.lightGreen)
85
- )
86
- .child(StyleRule(".field-error")
87
- .gridRowStart("4")
88
- .gridColumnStart("1")
89
- .gridColumnEnd("span 3")
90
- .padding(5)
91
- .margin(5)
92
- .borderRadius(9999)
93
- .backgroundColor(Colors.red)
94
- .color(Colors.white)
95
- .fontSize("smaller")
96
- .and(StyleRule(":empty")
97
- .display("none")
98
- )
99
- )
100
- .child(StyleRule("span[data-required=required]")
101
- .gridColumnStart("2")
102
- .gridRow("1")
103
- .visibility("hidden")
104
- .color(Colors.red)
105
- .and(StyleRule(".true")
106
- .visibility("visible")
107
- )
108
- )
109
- .and(StyleRule("[data-layout=horizontal]")
110
- .gridTemplateColumns("auto auto 1fr auto")
111
- .gridTemplateRows("auto auto")
112
- .child(StyleRule("label.label")
113
- .gridRowStart("2")
114
- .marginRight(5)
115
- .marginBottom(5)
116
- )
117
- .child(StyleRule("[data-content=content]")
118
- .gridRowStart("2")
119
- .gridColumnStart("3")
120
- .marginTop(0)
121
- .marginBottom(5)
122
- )
123
- .child(StyleRule("i[data-help=help]")
124
- .gridRowStart("2")
125
- .gridColumnStart("4")
126
- )
127
- .child(StyleRule(".field-error")
128
- .gridRowStart("4")
129
- .gridColumnStart("1")
130
- .gridColumnEnd("span 3")
131
- )
132
- .child(StyleRule("span[data-required=required]")
133
- .gridRowStart("2")
134
- .gridColumnStart("2")
135
- .marginRight(5)
136
- .display("none")
137
- .color(Colors.red)
138
- .and(StyleRule(".true")
139
- .display("inline")
140
- )
141
- )
142
- )
143
- , "div[data-wa-form-field=wa-form-field]");
144
-
145
- CSS(StyleRule()
146
- .overflow("auto")
147
- .padding(10)
148
- .verticalFlexLayout({ alignItems: "center", justifyContent: "flex-start"})
149
- , "div[data-form-field-help=help-window]");
150
-
151
35
  // let id = 1;
152
36
  // const generateId = (name: string) => {
153
37
  // return `${name.replace(/[\W_]+/g, "-")}-${id++}`;
@@ -10,22 +10,7 @@ import { IPopupOptions } from "@web-atoms/core/dist/web/services/PopupService";
10
10
  import CSS from "@web-atoms/core/dist/web/styles/CSS";
11
11
  import IElement from "./IElement";
12
12
 
13
- CSS(StyleRule()
14
- .position("absolute")
15
- .borderRadius(5)
16
- .padding(5)
17
- .border("solid 1px lightgray")
18
- .defaultBoxShadow()
19
- .zIndex(5000)
20
- .backgroundColor("var(--primary-bg, white)")
21
- .color("var(--primary-color, darkgray)")
22
- .left(0)
23
- , "*[data-inline-popup=inline-popup]");
24
-
25
- CSS(StyleRule()
26
- .right(0)
27
- .left("unset")
28
- , "*[data-alignment=bottom-right] > [data-inline-popup=inline-popup]");
13
+ import "./styles/inline-popup-style";
29
14
 
30
15
  function closeHandler(
31
16
  opener: HTMLElement,