@tsed/tailwind-formio 1.11.0 → 1.12.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 (139) hide show
  1. package/dist/tailwind.js +1 -1
  2. package/gulpfile.js +24 -22
  3. package/lib/index.d.ts +19 -0
  4. package/lib/templates/index.d.ts +19 -0
  5. package/lib/templates/tailwind/address/form.ejs.js +3 -1
  6. package/lib/templates/tailwind/address/html.ejs.js +16 -0
  7. package/lib/templates/tailwind/alert/form.ejs.js +27 -0
  8. package/lib/templates/tailwind/alert/index.d.ts +6 -0
  9. package/lib/templates/tailwind/alert/index.js +4 -0
  10. package/lib/templates/tailwind/builderComponent/form.ejs.js +6 -6
  11. package/lib/templates/tailwind/builderEditForm/form.ejs.js +20 -20
  12. package/lib/templates/tailwind/builderSidebarGroup/form.ejs.js +3 -3
  13. package/lib/templates/tailwind/button/form.ejs.js +12 -2
  14. package/lib/templates/tailwind/checkbox/form.ejs.js +12 -2
  15. package/lib/templates/tailwind/columns/form.ejs.js +1 -1
  16. package/lib/templates/tailwind/componentModal/form.ejs.js +31 -3
  17. package/lib/templates/tailwind/datagrid/form.ejs.js +29 -13
  18. package/lib/templates/tailwind/datagrid/html.ejs.js +3 -3
  19. package/lib/templates/tailwind/day/form.ejs.js +21 -1
  20. package/lib/templates/tailwind/dialog/form.ejs.js +1 -1
  21. package/lib/templates/tailwind/editgrid/form.ejs.js +4 -4
  22. package/lib/templates/tailwind/editgrid/html.ejs.js +2 -2
  23. package/lib/templates/tailwind/editgridTable/form.ejs.js +69 -0
  24. package/lib/templates/tailwind/editgridTable/html.ejs.js +59 -0
  25. package/lib/templates/tailwind/editgridTable/index.d.ts +5 -0
  26. package/lib/templates/tailwind/editgridTable/index.js +5 -0
  27. package/lib/templates/tailwind/errorsList/form.ejs.js +25 -0
  28. package/lib/templates/tailwind/errorsList/index.d.ts +4 -0
  29. package/lib/templates/tailwind/errorsList/index.js +4 -0
  30. package/lib/templates/tailwind/field/align.ejs.js +1 -1
  31. package/lib/templates/tailwind/field/form.ejs.js +6 -2
  32. package/lib/templates/tailwind/fieldset/form.ejs.js +6 -6
  33. package/lib/templates/tailwind/file/form.ejs.js +37 -13
  34. package/lib/templates/tailwind/iconClass.d.ts +1 -0
  35. package/lib/templates/tailwind/iconClass.js +2 -1
  36. package/lib/templates/tailwind/index.d.ts +19 -0
  37. package/lib/templates/tailwind/index.js +14 -4
  38. package/lib/templates/tailwind/input/form.ejs.js +62 -32
  39. package/lib/templates/tailwind/label/form.ejs.js +14 -4
  40. package/lib/templates/tailwind/message/form.ejs.js +6 -2
  41. package/lib/templates/tailwind/modalPreview/form.ejs.js +16 -4
  42. package/lib/templates/tailwind/multiValueTable/form.ejs.js +1 -1
  43. package/lib/templates/tailwind/panel/form.ejs.js +18 -4
  44. package/lib/templates/tailwind/pdfBuilder/form.ejs.js +1 -1
  45. package/lib/templates/tailwind/radio/form.ejs.js +32 -6
  46. package/lib/templates/tailwind/radio/html.ejs.js +2 -2
  47. package/lib/templates/tailwind/resourceAdd/form.ejs.js +1 -1
  48. package/lib/templates/tailwind/select/form.ejs.js +14 -2
  49. package/lib/templates/tailwind/selectOption/form.ejs.js +3 -3
  50. package/lib/templates/tailwind/selectOption/html.ejs.js +1 -1
  51. package/lib/templates/tailwind/signature/form.ejs.js +3 -3
  52. package/lib/templates/tailwind/survey/form.ejs.js +26 -6
  53. package/lib/templates/tailwind/tab/flat.ejs.js +1 -1
  54. package/lib/templates/tailwind/tab/form.ejs.js +14 -8
  55. package/lib/templates/tailwind/table/form.ejs.js +3 -1
  56. package/lib/templates/tailwind/tableComponents/form.ejs.js +15 -0
  57. package/lib/templates/tailwind/tableComponents/index.d.ts +4 -0
  58. package/lib/templates/tailwind/tableComponents/index.js +4 -0
  59. package/lib/templates/tailwind/webform/builder.ejs.js +1 -1
  60. package/lib/templates/tailwind/wizard/builder.ejs.js +1 -1
  61. package/lib/templates/tailwind/wizard/form.ejs.js +33 -6
  62. package/lib/templates/tailwind/wizardHeader/form.ejs.js +21 -7
  63. package/lib/templates/tailwind/wizardHeaderClassic/form.ejs.js +29 -0
  64. package/lib/templates/tailwind/wizardHeaderClassic/index.d.ts +4 -0
  65. package/lib/templates/tailwind/wizardHeaderClassic/index.js +4 -0
  66. package/lib/templates/tailwind/wizardHeaderVertical/form.ejs.js +31 -0
  67. package/lib/templates/tailwind/wizardHeaderVertical/index.d.ts +4 -0
  68. package/lib/templates/tailwind/wizardHeaderVertical/index.js +4 -0
  69. package/lib/templates/tailwind/wizardNav/form.ejs.js +44 -20
  70. package/package.json +2 -5
  71. package/readme.md +96 -115
  72. package/src/templates/stories/builder.stories.js +8 -23
  73. package/src/templates/stories/pagination.stories.js +1 -6
  74. package/src/templates/stories/wizard.stories.js +8 -23
  75. package/src/templates/tailwind/address/form.ejs +1 -0
  76. package/src/templates/tailwind/address/html.ejs +1 -0
  77. package/src/templates/tailwind/alert/form.ejs +10 -0
  78. package/src/templates/tailwind/alert/index.js +3 -0
  79. package/src/templates/tailwind/builderComponent/form.ejs +42 -6
  80. package/src/templates/tailwind/builderEditForm/form.ejs +53 -49
  81. package/src/templates/tailwind/builderSidebarGroup/form.ejs +3 -3
  82. package/src/templates/tailwind/button/form.ejs +6 -3
  83. package/src/templates/tailwind/checkbox/form.ejs +5 -1
  84. package/src/templates/tailwind/columns/form.ejs +1 -1
  85. package/src/templates/tailwind/componentModal/form.ejs +12 -3
  86. package/src/templates/tailwind/datagrid/form.ejs +13 -12
  87. package/src/templates/tailwind/datagrid/html.ejs +2 -2
  88. package/src/templates/tailwind/day/form.ejs +10 -1
  89. package/src/templates/tailwind/dialog/form.ejs +2 -2
  90. package/src/templates/tailwind/editgrid/form.ejs +3 -3
  91. package/src/templates/tailwind/editgrid/html.ejs +2 -2
  92. package/src/templates/tailwind/editgridTable/form.ejs +55 -0
  93. package/src/templates/tailwind/editgridTable/html.ejs +49 -0
  94. package/src/templates/tailwind/editgridTable/index.ts +4 -0
  95. package/src/templates/tailwind/errorsList/form.ejs +19 -0
  96. package/src/templates/tailwind/errorsList/index.ts +3 -0
  97. package/src/templates/tailwind/field/align.ejs +1 -1
  98. package/src/templates/tailwind/field/form.ejs +1 -1
  99. package/src/templates/tailwind/fieldset/form.ejs +5 -4
  100. package/src/templates/tailwind/file/form.ejs +35 -11
  101. package/src/templates/tailwind/iconClass.ts +3 -6
  102. package/src/templates/tailwind/index.ts +14 -4
  103. package/src/templates/tailwind/input/form.ejs +47 -34
  104. package/src/templates/tailwind/label/form.ejs +7 -2
  105. package/src/templates/tailwind/message/form.ejs +1 -1
  106. package/src/templates/tailwind/modalPreview/form.ejs +13 -2
  107. package/src/templates/tailwind/multiValueTable/form.ejs +1 -1
  108. package/src/templates/tailwind/panel/form.ejs +12 -4
  109. package/src/templates/tailwind/pdfBuilder/form.ejs +0 -1
  110. package/src/templates/tailwind/radio/form.ejs +16 -6
  111. package/src/templates/tailwind/radio/html.ejs +2 -2
  112. package/src/templates/tailwind/resourceAdd/form.ejs +1 -1
  113. package/src/templates/tailwind/select/form.ejs +5 -0
  114. package/src/templates/tailwind/selectOption/form.ejs +2 -2
  115. package/src/templates/tailwind/selectOption/html.ejs +1 -1
  116. package/src/templates/tailwind/signature/form.ejs +3 -3
  117. package/src/templates/tailwind/survey/form.ejs +13 -3
  118. package/src/templates/tailwind/tab/flat.ejs +1 -1
  119. package/src/templates/tailwind/tab/form.ejs +11 -5
  120. package/src/templates/tailwind/table/form.ejs +1 -0
  121. package/src/templates/tailwind/tableComponents/form.ejs +5 -0
  122. package/src/templates/tailwind/tableComponents/index.ts +3 -0
  123. package/src/templates/tailwind/webform/builder.ejs +1 -1
  124. package/src/templates/tailwind/wizard/builder.ejs +1 -1
  125. package/src/templates/tailwind/wizard/form.ejs +28 -7
  126. package/src/templates/tailwind/wizardHeader/form.ejs +9 -4
  127. package/src/templates/tailwind/wizardHeaderClassic/form.ejs +16 -0
  128. package/src/templates/tailwind/wizardHeaderClassic/index.ts +3 -0
  129. package/src/templates/tailwind/wizardHeaderVertical/form.ejs +14 -0
  130. package/src/templates/tailwind/wizardHeaderVertical/index.ts +3 -0
  131. package/src/templates/tailwind/wizardNav/form.ejs +27 -21
  132. package/styles/choices.css +3 -0
  133. package/styles/fieldset.css +5 -0
  134. package/styles/form.css +3 -0
  135. package/styles/index.css +1 -0
  136. package/styles/tables.css +9 -1
  137. package/tsconfig.json +3 -14
  138. package/.eslintrc +0 -40
  139. package/.prettierrc +0 -10
@@ -1,4 +1,10 @@
1
+ {% if (ctx.options.vpat) { %}
2
+ <span tabindex="-1" class="sr-only" id="invisible-{{ctx.instance.id}}-{{ctx.component.key}}"></span>
3
+ {% } %}
1
4
  {% if (!ctx.self.imageUpload) { %}
5
+ {% if (ctx.options.vpat) { %}
6
+ <div>{{(!ctx.component.filePattern || ctx.component.filePattern === '*') ? 'Any file types are allowed' : ctx.t('Allowed file types: ') + ctx.component.filePattern}}</div>
7
+ {% } %}
2
8
  <ul class="list-group list-group-striped">
3
9
  <li class="list-group-item list-group-header hidden-xs hidden-sm">
4
10
  <div class="grid grid-cols-12 gap-4">
@@ -16,13 +22,15 @@
16
22
  <li class="list-group-item">
17
23
  <div class="grid grid-cols-12 gap-4">
18
24
  {% if (!ctx.disabled) { %}
19
- <div class="md:col-span-1"><i class="{{ctx.iconClass('remove')}}" ref="removeLink"></i></div>
25
+ <div class="md:col-span-1"><i tabindex="0" class="{{ctx.iconClass('remove')}}" ref="removeLink"></i></div>
20
26
  {% } %}
21
27
  <div class="md:col-span-{% if (ctx.self.hasTypes) { %}7{% } else { %}9{% } %}">
22
28
  {% if (ctx.component.uploadOnly) { %}
23
29
  {{file.originalName || file.name}}
24
30
  {% } else { %}
25
- <a href="{{file.url || '#'}}" target="_blank" ref="fileLink">{{file.originalName || file.name}}</a>
31
+ <a href="{{file.url || '#'}}" target="_blank" ref="fileLink">
32
+ <span class="sr-only">{{ctx.t('Press to open ')}}</span>{{file.originalName || file.name}}
33
+ </a>
26
34
  {% } %}
27
35
  </div>
28
36
  <div class="md:col-span-2">{{ctx.fileSize(file.size)}}</div>
@@ -30,7 +38,7 @@
30
38
  <div class="md:col-span-2">
31
39
  <select class="file-type" ref="fileType">
32
40
  {% ctx.component.fileTypes.map(function(type) { %}
33
- <option class="test" value="{{ type.value }}" {% if (type.label === file.fileType) { %}selected="selected"{% } %}>{{ type.label }}</option>
41
+ <option class="test" value="{{ type.value }}" {% if (type.label === file.fileType) { %}selected="selected"{% } %}>{{ctx.t(type.label)}}</option>
34
42
  {% }); %}
35
43
  </select>
36
44
  </div>
@@ -49,7 +57,7 @@
49
57
  <span>
50
58
  <img ref="fileImage" src="" alt="{{file.originalName || file.name}}" style="width:{{ctx.component.imageSize}}px">
51
59
  {% if (!ctx.disabled) { %}
52
- <i class="{{ctx.iconClass('remove')}}" ref="removeLink"></i>
60
+ <i tabindex="0" class="{{ctx.iconClass('remove')}}" ref="removeLink"></i>
53
61
  {% } %}
54
62
  </span>
55
63
  </div>
@@ -63,16 +71,27 @@
63
71
  <button class="btn btn-primary" ref="cameraButton"><i class="fa fa-camera"></i> {{ctx.t('Camera')}}</button>
64
72
  </div>
65
73
  {% } else if (!ctx.self.cameraMode) { %}
66
- <div class="fileSelector" ref="fileDrop" {{ctx.fileDropHidden ? 'hidden' : ''}}>
74
+ <div class="fileSelector" ref="fileDrop" {{ctx.fileDropHidden ?'hidden' : ''}}>
67
75
  <i class="{{ctx.iconClass('cloud-upload')}}"></i> {{ctx.t('Drop files to attach,')}}
68
- {% if (ctx.self.imageUpload) { %}
69
- <a href="#" ref="toggleCameraMode"><i class="{{ctx.iconClass('camera')}}"></i> {{ctx.t('Use Camera,')}}</a>
76
+ {% if (ctx.self.imageUpload && ctx.component.webcam) { %}
77
+ <a href="#" ref="toggleCameraMode"><i class="{{ctx.iconClass('camera')}}"></i> {{ctx.t('use camera')}}</a>
70
78
  {% } %}
71
- {{ctx.t('or')}} <a href="#" ref="fileBrowse" class="browse">{{ctx.t('browse')}}</a>
79
+ {{ctx.t('or')}}
80
+ <a href="#" ref="fileBrowse" class="browse">
81
+ {{ctx.t('browse')}}
82
+ <span class="sr-only">
83
+ {{ctx.t('Browse to attach file for ' + ctx.component.label + '. ' +
84
+ (ctx.component.description ? ctx.component.description + '. ' : '') +
85
+ ((!ctx.component.filePattern || ctx.component.filePattern === '*') ? 'Any file types are allowed' : ctx.t('Allowed file types: ') + ctx.component.filePattern))}}
86
+ </span>
87
+ </a>
88
+ <div ref="fileProcessingLoader" class="loader-wrapper">
89
+ <div class="loader text-center"></div>
90
+ </div>
72
91
  </div>
73
92
  {% } else { %}
74
- <div>
75
- <video class="video" autoplay="true" ref="videoPlayer"></video>
93
+ <div class="video-container">
94
+ <video class="video" autoplay="true" ref="videoPlayer" tabindex="-1"></video>
76
95
  </div>
77
96
  <button class="btn btn-primary" ref="takePictureButton"><i class="fa fa-camera"></i> {{ctx.t('Take Picture')}}</button>
78
97
  <button class="btn btn-primary" ref="toggleCameraMode">{{ctx.t('Switch to file upload')}}</button>
@@ -81,7 +100,12 @@
81
100
  {% ctx.statuses.forEach(function(status) { %}
82
101
  <div class="file {{ctx.statuses.status === 'error' ? ' has-error' : ''}}">
83
102
  <div class="grid grid-cols-12 gap-4">
84
- <div class="fileName col-form-label sm:col-span-10">{{status.originalName}} <i class="{{ctx.iconClass('remove')}}" ref="fileStatusRemove"></i></div>
103
+ <div class="fileName col-form-label sm:col-span-10">{{status.originalName}}
104
+ <i class="{{ctx.iconClass('remove')}}" ref="fileStatusRemove">
105
+ <span class="sr-only">{{ctx.t('Remove button. Press to remove ' + status.originalName || status.name + '.')}}</span>
106
+ <span class="sr-only">{{status.message ? status.message.replace(';', '.') : ''}}</span>
107
+ </i>
108
+ </div>
85
109
  <div class="fileSize col-form-label sm:col-span-2 text-right">{{ctx.fileSize(status.size)}}</div>
86
110
  </div>
87
111
  <div class="grid grid-cols-12 gap-4">
@@ -48,14 +48,11 @@ export const ICONS = {
48
48
  cubes: "bxs-cube",
49
49
  stop: "bx-stop",
50
50
  "check-square": "bx-checkbox-checked",
51
- "remove-circle": "bx-x-circle"
51
+ "remove-circle": "bx-x",
52
+ bars: "bx-menu"
52
53
  };
53
54
 
54
- export default (
55
- iconset: string | undefined,
56
- name: string,
57
- spinning?: boolean
58
- ) => {
55
+ export default (iconset: string | undefined, name: string, spinning?: boolean) => {
59
56
  if (iconset === "bx") {
60
57
  if (ICONS[name]) {
61
58
  name = ICONS[name];
@@ -13,11 +13,13 @@ import columns from "./columns";
13
13
  import component from "./component";
14
14
  import componentModal from "./componentModal";
15
15
  import components from "./components";
16
+ import tableComponents from "./tableComponents";
16
17
  import container from "./container";
17
18
  import datagrid from "./datagrid";
18
19
  import day from "./day";
19
20
  import dialog from "./dialog";
20
21
  import editgrid from "./editgrid";
22
+ import editgridTable from "./editgridTable";
21
23
  import field from "./field";
22
24
  import fieldset from "./fieldset";
23
25
  import file from "./file";
@@ -54,8 +56,12 @@ import webform from "./webform";
54
56
  import well from "./well";
55
57
  import wizard from "./wizard";
56
58
  import wizardHeader from "./wizardHeader";
59
+ import wizardHeaderClassic from "./wizardHeaderClassic";
60
+ import wizardHeaderVertical from "./wizardHeaderVertical";
57
61
  import wizardNav from "./wizardNav";
58
62
  import cssClasses from "./cssClasses";
63
+ import errorsList from "./errorsList";
64
+ import alert from "./alert";
59
65
 
60
66
  export default {
61
67
  transform(type: string, text: string) {
@@ -65,9 +71,7 @@ export default {
65
71
  switch (type) {
66
72
  case "class":
67
73
  // eslint-disable-next-line no-prototype-builtins
68
- return this.cssClasses.hasOwnProperty(text.toString())
69
- ? this.cssClasses[text.toString()]
70
- : text;
74
+ return this.cssClasses.hasOwnProperty(text.toString()) ? this.cssClasses[text.toString()] : text;
71
75
  }
72
76
  return text;
73
77
  },
@@ -89,11 +93,13 @@ export default {
89
93
  component,
90
94
  componentModal,
91
95
  components,
96
+ tableComponents,
92
97
  container,
93
98
  datagrid,
94
99
  day,
95
100
  dialog,
96
101
  editgrid,
102
+ editgridTable,
97
103
  field,
98
104
  fieldset,
99
105
  file,
@@ -129,5 +135,9 @@ export default {
129
135
  well,
130
136
  wizard,
131
137
  wizardHeader,
132
- wizardNav
138
+ wizardHeaderClassic,
139
+ wizardHeaderVertical,
140
+ wizardNav,
141
+ errorsList,
142
+ alert
133
143
  };
@@ -1,46 +1,59 @@
1
1
  {% if (ctx.prefix || ctx.suffix) { %}
2
2
  <div class="input-group">
3
- {% } %}
4
- {% if (ctx.prefix) { %}
5
- <div class="input-group-prepend" ref="prefix">
6
- <span class="input-group-text">
7
- {% if(ctx.prefix instanceof HTMLElement){ %}
8
- {{ ctx.t(ctx.prefix.outerHTML) }}
9
- {% } else{ %}
10
- {{ ctx.t(ctx.prefix) }}
11
- {% } %}
12
- </span>
13
- </div>
14
- {% } %}
15
- {% if (!ctx.component.editor && !ctx.component.wysiwyg) { %}
16
- <{{ctx.input.type}}
17
- ref="{{ctx.input.ref ? ctx.input.ref : 'input'}}"
18
- {% for (var attr in ctx.input.attr) { %}
19
- {{attr}}="{{ctx.input.attr[attr]}}"
20
3
  {% } %}
21
- id="{{ctx.instance.id}}-{{ctx.component.key}}"
22
- >{{ctx.input.content}}</{{ctx.input.type}}>
4
+ {% if (ctx.prefix) { %}
5
+ <div class="input-group-prepend" ref="prefix">
6
+ <span class="input-group-text">
7
+ {% if(ctx.prefix instanceof HTMLElement){ %}
8
+ {{ ctx.t(ctx.prefix.outerHTML, { _userInput: true }) }}
9
+ {% } else{ %}
10
+ {{ ctx.t(ctx.prefix, { _userInput: true }) }}
11
+ {% } %}
12
+ </span>
13
+ </div>
14
+ {% } %}
15
+ {% if (!ctx.component.editor && !ctx.component.wysiwyg) { %}
16
+ <{{ctx.input.type}}
17
+ ref="{{ctx.input.ref ? ctx.input.ref : 'input'}}"
18
+ {% for (var attr in ctx.input.attr) { %}
19
+ {{attr}}="{{ctx.input.attr[attr]}}"
20
+ {% } %}
21
+ id="{{ctx.instance.id}}-{{ctx.component.key}}"
22
+ aria-labelledby="l-{{ctx.instance.id}}-{{ctx.component.key}} {% if (ctx.component.description) { %}d-{{ctx.instance.id}}-{{ctx.component.key}}{% } %}"
23
+ aria-required="{{ctx.input.ref === 'input' || !ctx.input.ref ? ctx.component.validate.required :
24
+ ctx.component.fields && ctx.component.fields[ctx.input.ref] && ctx.component.fields[ctx.input.ref].required || false}}"
25
+ >{{ctx.input.content}}</{{ctx.input.type}}>
26
+ {% if (ctx.hasValueMaskInput) { %}
27
+ <input ref="valueMaskInput" />
28
+ {% } %}
23
29
  {% } %}
24
30
  {% if (ctx.component.editor || ctx.component.wysiwyg) { %}
25
- <div ref="input"></div>
26
- {% } %}
27
- {% if (ctx.component.showCharCount) { %}
28
- <span class="text-muted pull-right" ref="charcount"></span>
31
+ <div ref="input"></div>
29
32
  {% } %}
30
- {% if (ctx.component.showWordCount) { %}
31
- <span class="text-muted pull-right" ref="wordcount"></span>
33
+ {% if (ctx.component.type === 'datetime') { %}
34
+ <span aria-live="assertive" id="{{ctx.instance.id}}-liveRegion" class="sr-only" ref="liveRegion"></span>
32
35
  {% } %}
33
36
  {% if (ctx.suffix) { %}
34
- <div class="input-group-append" ref="suffix">
35
- <span class="input-group-text">
36
- {% if(ctx.suffix instanceof HTMLElement){ %}
37
- {{ ctx.t(ctx.suffix.outerHTML) }}
38
- {% } else{ %}
39
- {{ ctx.t(ctx.suffix) }}
40
- {% } %}
41
- </span>
42
- </div>
37
+ <div class="input-group-append" ref="suffix">
38
+ <span class="input-group-text">
39
+ {% if(ctx.suffix instanceof HTMLElement){ %}
40
+ {{ ctx.t(ctx.suffix.outerHTML, { _userInput: true }) }}
41
+ {% } else{ %}
42
+ {{ ctx.t(ctx.suffix, { _userInput: true }) }}
43
+ {% } %}
44
+ </span>
45
+ </div>
43
46
  {% } %}
44
47
  {% if (ctx.prefix || ctx.suffix) { %}
48
+ </div>
49
+ {% } %}
50
+ {% if (ctx.component.showCharCount || ctx.component.showWordCount) { %}
51
+ <div class="form-text {{ctx.component.description ? 'pull-right' : 'text-right'}}">
52
+ {% if (ctx.component.showCharCount) { %}
53
+ <span class="text-muted" ref="charcount" aria-live="polite"></span>
54
+ {% } %}
55
+ {% if (ctx.component.showWordCount) { %}
56
+ <span class="text-muted" ref="wordcount" aria-live="polite"></span>
57
+ {% } %}
45
58
  </div>
46
59
  {% } %}
@@ -1,9 +1,14 @@
1
1
  <label
2
+ ref="label"
2
3
  class="col-form-label {{ctx.label.className}}"
3
4
  for="{{ctx.instance.id}}-{{ctx.component.key}}"
5
+ id="l-{{ctx.instance.id}}-{{ctx.component.key}}"
4
6
  >
5
- {{ ctx.t(ctx.component.label) }}
7
+ {{ ctx.t(ctx.component.label, { _userInput: true }) }}
8
+ {% if (ctx.component.type === 'number' || ctx.component.type === 'phoneNumber' || ctx.component.type === 'currency') { %}
9
+ <span class='sr-only'>, {{ctx.t('numeric only')}},</span>
10
+ {% } %}
6
11
  {% if (ctx.component.tooltip) { %}
7
- <i ref="tooltip" class="{{ctx.iconClass('question-sign')}}" data-tooltip="{{ctx.component.tooltip}}"></i>
12
+ <i ref="tooltip" tabindex="0" class="{{ctx.iconClass('question-sign')}} text-muted" data-tooltip="{{ctx.component.tooltip}}"></i>
8
13
  {% } %}
9
14
  </label>
@@ -1 +1 @@
1
- <div class="form-text {{ctx.level}}">{{ctx.message}}</div>
1
+ <div id="e-{{ctx.instance.id}}-{{ctx.key}}" class="form-text {{ctx.level || 'error'}}">{{ctx.message}}</div>
@@ -1,4 +1,15 @@
1
- <label class="control-label">{{ ctx.t(ctx.component.label) }}</label><br>
2
- <button lang='en' class='btn btn-light btn-md open-modal-button' ref='openModal'>
1
+ <label id="l-{{ctx.component.key}}" class="control-label {{ ctx.label.className }}">
2
+ {{ ctx.t(ctx.component.label, { _userInput: true }) }}<span ref="modalLabelValue" class="sr-only">. {{ ctx.component.type === 'signature' ? ctx.self.getValueAsString(ctx.previewText) : ctx.previewText }}</span>
3
+ </label><br>
4
+ <span class="sr-only" ref="modalPreviewLiveRegion" aria-live="assertive"></span>
5
+ <button
6
+ lang="en"
7
+ class="btn btn-light btn-md open-modal-button form-control {{ctx.openModalBtnClasses || ''}}"
8
+ ref="openModal"
9
+ aria-labelledby="l-{{ctx.component.key}}"
10
+ >
3
11
  {{ ctx.previewText }}
4
12
  </button>
13
+ <div class="formio-errors invalid-feedback">
14
+ {{ ctx.messages }}
15
+ </div>
@@ -4,7 +4,7 @@
4
4
  {% if (!ctx.disabled) { %}
5
5
  <tr>
6
6
  <td colspan="2">
7
- <button class="btn btn-primary formio-button-add-another" ref="addButton"><i class="{{ctx.iconClass('plus')}}"></i> {{ctx.t(ctx.addAnother)}}</button>
7
+ <button class="btn btn-primary formio-button-add-another" ref="addButton"><i class="{{ctx.iconClass('plus')}}"></i> {{ctx.t(ctx.addAnother, { _userInput: true })}}</button>
8
8
  </td>
9
9
  </tr>
10
10
  {% } %}
@@ -1,21 +1,29 @@
1
1
  <div class="mb-2 card border">
2
2
  {% if (!ctx.component.hideLabel || ctx.builder || ctx.component.collapsible || ctx.component.tooltip) { %}
3
- <div class="card-header {{ctx.transform('class', 'bg-' + ctx.component.theme)}}" ref="header">
3
+ <div class="card-header {{ctx.transform('class', 'bg-' + ctx.component.theme)}}"
4
+ {% if (ctx.component.collapsible) { %}
5
+ tabindex="0"
6
+ {% } %}
7
+ role="button"
8
+ aria-expanded="{{ctx.component.collapsible ? !ctx.collapsed : true}}"
9
+ aria-controls="{{ctx.instance.id}}-{{ctx.component.key}}"
10
+ ref="header"
11
+ >
4
12
  <span class="mb-0 card-title {% if (ctx.component.theme && ctx.component.theme !== 'default') { %}text-light{% } %}">
5
13
  {% if (ctx.component.collapsible) { %}
6
14
  <i class="formio-collapse-icon {{ctx.iconClass(ctx.collapsed ? 'plus-square-o' : 'minus-square-o')}} text-muted" data-title="Collapse Panel"></i>
7
15
  {% } %}
8
16
  {% if (!ctx.component.hideLabel || ctx.builder) { %}
9
- {{ctx.t(ctx.component.title)}}
17
+ {{ctx.t(ctx.component.title, { _userInput: true })}}
10
18
  {% } %}
11
19
  {% if (ctx.component.tooltip) { %}
12
- <i ref="tooltip" class="{{ctx.iconClass('question-sign')}}" data-tooltip="{{ctx.component.tooltip}}"></i>
20
+ <i ref="tooltip" tabindex="0" class="{{ctx.iconClass('question-sign')}} text-muted" data-tooltip="{{ctx.component.tooltip}}"></i>
13
21
  {% } %}
14
22
  </span>
15
23
  </div>
16
24
  {% } %}
17
25
  {% if (!ctx.collapsed || ctx.builder) { %}
18
- <div class="card-body" ref="{{ctx.nestedKey}}">
26
+ <div class="card-body" ref="{{ctx.nestedKey}}" id="{{ctx.instance.id}}-{{ctx.component.key}}">
19
27
  {{ctx.children}}
20
28
  </div>
21
29
  {% } %}
@@ -1,5 +1,4 @@
1
1
  <div class="formio builder grid grid-cols-12 gap-4 formbuilder">
2
- <div class="loader-wrapper" ref="sidebar-loader"><div class="loader text-center"></div></div>
3
2
  <div class="col-span-12 xs:col-span-4 sm:col-span-3 md:col-span-2 formcomponents">
4
3
  {{ctx.sidebar}}
5
4
  </div>
@@ -1,9 +1,18 @@
1
- <div class="form-radio radio">
1
+ <div
2
+ class="form-radio radio"
3
+ ref="radioGroup"
4
+ role="{{ctx.component.type === 'selectboxes' ? 'group' : 'radiogroup'}}"
5
+ aria-required="{{ctx.input.component.validate.required}}"
6
+ aria-labelledby="l-{{ctx.instance.id}}-{{ctx.component.key}}"
7
+ {% if (ctx.component.description) { %}
8
+ aria-describedby="d-{{ctx.instance.id}}-{{ctx.component.key}}"
9
+ {% } %}
10
+ >
2
11
  {% ctx.values.forEach(function(item) { %}
3
- <div class="form-check{{ctx.inline ? '-inline' : ''}}" ref="wrapper">
4
- <label class="form-check-label label-position-{{ ctx.component.optionsLabelPosition }}" for="{{ctx.id}}{{ctx.row}}-{{item.value}}">
12
+ <div class="{{ctx.input.attr.type}} {{ ctx.component.optionsLabelPosition && ctx.component.optionsLabelPosition !== 'right' ? 'pl-0' : ''}} form-check{{ctx.inline ? '-inline' : ''}}" ref="wrapper">
13
+ <label class="form-check-label label-position-{{ ctx.component.optionsLabelPosition }}" for="{{ctx.instance.root && ctx.instance.root.id}}-{{ctx.id}}-{{ctx.row}}-{{item.value}}">
5
14
  {% if (ctx.component.optionsLabelPosition === 'left' || ctx.component.optionsLabelPosition === 'top') { %}
6
- <span>{{ctx.t(item.label)}}</span>
15
+ <span>{{ctx.t(item.label, { _userInput: true })}}</span>
7
16
  {% } %}
8
17
  <{{ctx.input.type}}
9
18
  ref="input"
@@ -17,10 +26,11 @@
17
26
  {% if (item.disabled) { %}
18
27
  disabled=true
19
28
  {% } %}
20
- id="{{ctx.id}}{{ctx.row}}-{{item.value}}"
29
+ id="{{ctx.instance.root && ctx.instance.root.id}}-{{ctx.id}}-{{ctx.row}}-{{item.value}}"
30
+ role="{{ctx.component.type === 'selectboxes' ? 'checkbox' : 'radio'}}"
21
31
  >
22
32
  {% if (!ctx.component.optionsLabelPosition || ctx.component.optionsLabelPosition === 'right' || ctx.component.optionsLabelPosition === 'bottom') { %}
23
- <span>{{ctx.t(item.label)}}</span>
33
+ <span>{{ctx.t(item.label, { _userInput: true })}}</span>
24
34
  {% } %}
25
35
  </label>
26
36
  </div>
@@ -1,4 +1,4 @@
1
1
  <div ref="value">
2
- {% var filtered = ctx.values.filter(function(item) {return ctx.value === item.value || (typeof ctx.value === 'object' && ctx.value.hasOwnProperty(item.value) && ctx.value[item.value])}).map(function(item) { return ctx.t(item.label)}).join(', ') %}
2
+ {% var filtered = ctx.values.filter(function(item) {return ctx.value === item.value || (typeof ctx.value === 'object' && ctx.value.hasOwnProperty(item.value) && ctx.value[item.value])}).map(function(item) { return ctx.t(item.label, { _userInput: true })}).join(', ') %}
3
3
  {{ filtered }}
4
- </div>
4
+ </div>
@@ -9,7 +9,7 @@
9
9
  <td colspan="2">
10
10
  <button class="btn btn-primary formio-button-add-resource" ref="addResource">
11
11
  <i class="{{ctx.iconClass('plus')}} mr-1"></i>
12
- {{ctx.t(ctx.component.addResourceLabel || 'Add Resource')}}
12
+ {{ctx.t(ctx.component.addResourceLabel || 'Add Resource', { _userInput: true })}}
13
13
  </button>
14
14
  </td>
15
15
  </tr>
@@ -7,6 +7,10 @@
7
7
  {% if (!ctx.input.attr.id) { %}
8
8
  id="{{ctx.instance.id}}-{{ctx.component.key}}"
9
9
  {% } %}
10
+ {% if (ctx.component.description) { %}
11
+ aria-describedby="d-{{ctx.instance.id}}-{{ctx.component.key}}"
12
+ {% } %}
13
+ aria-required="{{ctx.input.ref === 'selectContainer' || !ctx.input.ref ? ctx.input.component.validate.required : ctx.component.fields[ctx.input.ref].required}}"
10
14
  >{{ctx.selectOptions}}</select>
11
15
  <input type="text"
12
16
  class="formio-select-autocomplete-input"
@@ -15,4 +19,5 @@
15
19
  autocomplete="{{ctx.input.attr.autocomplete}}"
16
20
  {% } %}
17
21
  tabindex="-1"
22
+ aria-label="{{ctx.t('autocomplete')}}"
18
23
  />
@@ -1,8 +1,8 @@
1
1
  <option {{ ctx.selected ? 'selected="selected"' : '' }}
2
- value="{{ctx.useId ? ctx.id : ctx.option.value}}"
2
+ value='{{ctx.useId ? ctx.id : ctx.option.value}}'
3
3
  {% for (var attr in ctx.attrs) { %}
4
4
  {{attr}}="{{ctx.attrs[attr]}}"
5
5
  {% } %}
6
6
  >
7
- {{ctx.t(ctx.option.label)}}
7
+ {{ctx.t(ctx.option.label, { _userInput: true })}}
8
8
  </option>
@@ -1 +1 @@
1
- {% if (ctx.selected) { %}{{ctx.t(ctx.option.label)}}{% } %}
1
+ {% if (ctx.selected) { %}{{ctx.t(ctx.option.label, { _userInput: true })}}{% } %}
@@ -8,16 +8,16 @@
8
8
  <button class="btn btn-sm btn-light signature-pad-refresh" ref="refresh">
9
9
  <i class="{{ctx.iconClass('refresh')}}"></i>
10
10
  </button>
11
- <canvas class="signature-pad-canvas" height="{{ctx.component.height}}" ref="canvas"></canvas>
11
+ <canvas class="signature-pad-canvas" style="display: none;" height="{{ctx.component.height}}" ref="canvas"></canvas>
12
12
  {% if (ctx.required) { %}
13
13
  <span class="form-control-feedback field-required-inline text-danger">
14
14
  <i class="{{ctx.iconClass('asterisk')}}"></i>
15
15
  </span>
16
16
  {% } %}
17
- <img style="width: 100%;display: none;" ref="signatureImage">
17
+ <img style="width: 100%;display: inherit;" ref="signatureImage">
18
18
  </div>
19
19
  {% if (ctx.component.footer) { %}
20
20
  <div class="signature-pad-footer">
21
- {{ctx.t(ctx.component.footer)}}
21
+ {{ctx.t(ctx.component.footer, { _userInput: true })}}
22
22
  </div>
23
23
  {% } %}
@@ -1,16 +1,26 @@
1
- <table class="table table-striped table-bordered">
1
+ <table class="table table-striped table-bordered" aria-labelledby="l-{{ctx.instance.id}}-{{ctx.component.key}}">
2
2
  <thead>
3
3
  <tr>
4
4
  <th></th>
5
5
  {% ctx.component.values.forEach(function(value) { %}
6
- <th style="text-align: center;">{{ctx.t(value.label)}}</th>
6
+ <th style="text-align: center;">
7
+ {{ctx.t(value.label, { _userInput: true })}}
8
+ {% if (value.tooltip) { %}
9
+ <i ref="tooltip" class="{{ctx.iconClass('question-sign')}} text-muted" data-tooltip="{{value.tooltip}}"></i>
10
+ {% } %}
11
+ </th>
7
12
  {% }) %}
8
13
  </tr>
9
14
  </thead>
10
15
  <tbody>
11
16
  {% ctx.component.questions.forEach(function(question) { %}
12
17
  <tr>
13
- <td>{{ctx.t(question.label)}}</td>
18
+ <td>
19
+ {{ctx.t(question.label)}}
20
+ {% if (question.tooltip) { %}
21
+ <i ref="tooltip" class="{{ctx.iconClass('question-sign')}} text-muted" data-tooltip="{{question.tooltip}}"></i>
22
+ {% } %}
23
+ </td>
14
24
  {% ctx.component.values.forEach(function(value) { %}
15
25
  <td style="text-align: center;">
16
26
  <input type="radio" name="{{ ctx.self.getInputName(question) }}" value="{{value.value}}" id="{{ctx.key}}-{{question.value}}-{{value.value}}" ref="input">
@@ -1,7 +1,7 @@
1
1
  {% ctx.component.components.forEach(function(tab, index) { %}
2
2
  <div class="mb-2 card border">
3
3
  <div class="card-header bg-default">
4
- <h4 class="mb-0 card-title">{{ ctx.t(tab.label) }}</h4>
4
+ <h4 class="mb-0 card-title">{{ ctx.t(tab.label, { _userInput: true }) }}</h4>
5
5
  </div>
6
6
  <div
7
7
  class="card-body"
@@ -1,9 +1,15 @@
1
- <div class="card card-tabs">
1
+ <div class="card card-tabs { ctx.component.verticalLayout ? ' card-vertical' : ''}}">
2
2
  <div class="card-header card-header-tabs">
3
- <ul class="nav nav-tabs">
3
+ <ul class="nav nav-tabs {{ ctx.component.verticalLayout ? ' nav-tabs-vertical' : ''}}" role="tablist">
4
4
  {% ctx.component.components.forEach(function(tab, index) { %}
5
- <li class="nav-item {{ ctx.currentTab === index ? ' active' : ''}}" role="presentation" ref="{{ctx.tabLikey}}">
6
- <a class="nav-link" href="#{{tab.key}}" ref="{{ctx.tabLinkKey}}">{{ctx.t(tab.label)}}</a>
5
+ <li class="nav-item {{ ctx.currentTab === index ? ' active' : ''}}" role="tab" ref="{{ctx.tabLikey}}">
6
+ <a
7
+ class="nav-link{{ ctx.currentTab === index ? ' active' : ''}}{{ ctx.component.verticalLayout ? ' nav-link-vertical' : ''}}"
8
+ href="#{{tab.key}}"
9
+ ref="{{ctx.tabLinkKey}}"
10
+ >
11
+ {{ctx.t(tab.label, { _userInput: true })}}
12
+ </a>
7
13
  <div class="nav-border"></div>
8
14
  </li>
9
15
  {% }) %}
@@ -12,7 +18,7 @@
12
18
  {% ctx.component.components.forEach(function(tab, index) { %}
13
19
  <div
14
20
  role="tabpanel"
15
- class="card-body card-body-tabs tab-pane{{ ctx.currentTab === index ? ' active' : ''}}"
21
+ class="card-body tab-pane{{ ctx.currentTab === index ? ' active' : ''}}"
16
22
  style="display: {{ctx.currentTab === index ? 'block' : 'none'}}"
17
23
  ref="{{ctx.tabKey}}"
18
24
  >
@@ -4,6 +4,7 @@
4
4
  {{ ctx.component.hover ? 'table-hover' : ''}}
5
5
  {{ ctx.component.condensed ? 'table-sm' : ''}}
6
6
  ">
7
+ <caption class="sr-only">{{ctx.t(ctx.component.label)}}</caption>
7
8
  {% if (ctx.component.header && ctx.component.header.length > 0) { %}
8
9
  <thead>
9
10
  <tr>
@@ -0,0 +1,5 @@
1
+ {% ctx.children.forEach(function(component) { %}
2
+ <td class="editgrid-table-column">
3
+ {{ component }}
4
+ </td>
5
+ {% }) %}
@@ -0,0 +1,3 @@
1
+ import form from "./form.ejs";
2
+
3
+ export default { form };
@@ -1 +1 @@
1
- <div class="text-muted text-center p-2">{{ ctx.t(ctx.component.title) }}</div>
1
+ <div class="text-muted text-center p-2">{{ ctx.t(ctx.component.title, { _userInput: true }) }}</div>
@@ -1 +1 @@
1
- <div class="text-muted text-center p-2">{{ ctx.t(ctx.component.title) }}</div>
1
+ <div class="text-muted text-center p-2">{{ ctx.t(ctx.component.title, { _userInput: true }) }}</div>
@@ -1,9 +1,30 @@
1
1
  <div class="{{ctx.className}}">
2
- <div style="position: relative;">
3
- {{ ctx.wizardHeader }}
4
- <div class="wizard-page" ref="{{ctx.wizardKey}}">
5
- {{ctx.components}}
2
+ <div style="position: relative;">
3
+ {% if (ctx.wizardHeaderType === 'wizardHeaderVertical') { %}
4
+ <div class="row">
5
+ {% if (ctx.wizardHeaderLocation !== 'right') { %}
6
+ <div class="col-sm-2">
7
+ {{ ctx.wizardHeader }}
8
+ </div>
9
+ {% } %}
10
+ <div class="wizard-page col-sm-10" ref="{{ctx.wizardKey}}">
11
+ {{ctx.components}}
12
+ </div>
13
+ {% if (ctx.wizardHeaderLocation === 'right') { %}
14
+ <div class="col-sm-2">
15
+ {{ ctx.wizardHeader }}
16
+ </div>
17
+ {% } %}
18
+ </div>
19
+ <div class="col-sm-offset-2 col-sm-10 {{ctx.wizardHeaderLocation === 'right' ? 'col-sm-offset-0 col-md-offset-0' : ''}}">
20
+ {{ ctx.wizardNav }}
21
+ </div>
22
+ {% } else { %}
23
+ {{ ctx.wizardHeader }}
24
+ <div class="wizard-page" ref="{{ctx.wizardKey}}">
25
+ {{ctx.components}}
26
+ </div>
27
+ {{ ctx.wizardNav }}
28
+ {% } %}
6
29
  </div>
7
- {{ ctx.wizardNav }}
8
- </div>
9
- </div>
30
+ </div>
@@ -1,8 +1,13 @@
1
- <nav aria-label="navigation" id="{{ ctx.wizardKey }}-header">
2
- <ul class="reset-list pagination">
1
+ <nav aria-label="Wizard navigation" id="{{ ctx.wizardKey }}-header" ref="{{ctx.wizardKey}}-header">
2
+ <ul class="pagination" role="tablist">
3
3
  {% ctx.panels.forEach(function(panel, index) { %}
4
- <li class="page-item {{ctx.currentPage === index ? ' active' : ''}}" style="">
5
- <span class="page-link" ref="{{ctx.wizardKey}}-link">{{ctx.t(panel.title)}}</span>
4
+ <li class="page-item{{ctx.currentPage === index ? ' active' : ''}}" style="cursor: pointer;">
5
+ <button tabindex="0" data-index="{{index}}" role="tab" class="page-link" ref="{{ctx.wizardKey}}-link">
6
+ {{ctx.t(panel.title, { _userInput: true })}}
7
+ {% if (panel.tooltip && ctx.currentPage === index) { %}
8
+ <i ref="{{ctx.wizardKey}}-tooltip" class="{{ctx.iconClass('question-sign')}} text-muted" data-tooltip="{{panel.tooltip}}"></i>
9
+ {% } %}
10
+ </button>
6
11
  </li>
7
12
  {% }) %}
8
13
  </ul>