@tsed/tailwind-formio 3.0.0-alpha.1 → 3.0.0-alpha.11

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.
@@ -0,0 +1,82 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ function useFetch(url, opts) {
4
+ const [data, setData] = useState(null);
5
+ const [loading, setLoading] = useState(true);
6
+ const [error, setError] = useState(null);
7
+
8
+ function fetchData() {
9
+ fetch(url, opts)
10
+ .then((res) => res.json())
11
+ .then((data) => {
12
+ setData(data);
13
+ setLoading(false);
14
+ })
15
+ .catch((err) => {
16
+ setError(err);
17
+ setLoading(false);
18
+ });
19
+ }
20
+
21
+ useEffect(() => {
22
+ fetchData();
23
+ }, [url, opts.method]);
24
+
25
+ return { data, loading, error, fetchData };
26
+ }
27
+
28
+ async function updateSubmission(model, submissionId, submission) {
29
+ const response = await fetch(`https://local.dev/form/${model}/submissions/${submissionId}`, {
30
+ method: "PUT",
31
+ headers: {
32
+ "Content-Type": "application/json",
33
+ Accept: "application/json"
34
+ },
35
+ body: JSON.stringify(submission)
36
+ });
37
+
38
+ const data = await response.json();
39
+
40
+ if (!response.ok) {
41
+ const error = new Error("Update submission failed");
42
+ error.errors = [data];
43
+ throw error;
44
+ }
45
+
46
+ return data;
47
+ }
48
+
49
+ export function useEditForm({ model, submissionId }) {
50
+ const form = useFetch(`https://local.dev/form/${model}`, {
51
+ method: "GET",
52
+ headers: {
53
+ "Content-Type": "application/json",
54
+ Accept: "application/json"
55
+ }
56
+ });
57
+
58
+ const submission = useFetch(`https://local.dev/form/${model}/submissions/${submissionId}`, {
59
+ method: "GET",
60
+ headers: {
61
+ "Content-Type": "application/json",
62
+ Accept: "application/json"
63
+ }
64
+ });
65
+
66
+ function onSubmit(submission) {
67
+ return updateSubmission(model, submissionId, submission.data).then((data) => {
68
+ return {
69
+ ...submission,
70
+ data
71
+ };
72
+ });
73
+ }
74
+
75
+ return {
76
+ form: form.data,
77
+ data: submission.data,
78
+ loading: form.loading || submission.loading,
79
+ error: form.error || submission.error,
80
+ onSubmit
81
+ };
82
+ }
package/styles/badge.css CHANGED
@@ -4,7 +4,7 @@ Requires one of the contextual, color modifier classes for `color` and
4
4
  */
5
5
 
6
6
  .badge {
7
- @apply inline-flex py-px px-1.5 font-bold text-center whitespace-nowrap items-center rounded transition-colors;
7
+ @apply inline-flex px-1.5 font-bold text-center whitespace-nowrap items-center rounded transition-colors;
8
8
  font-size: 75%;
9
9
 
10
10
  &:empty {
@@ -17,8 +17,8 @@ Requires one of the contextual, color modifier classes for `color` and
17
17
  }
18
18
 
19
19
  a .badge {
20
- &:hover, &:focus {
21
- @apply no-underline
20
+ &:hover, &:focus, &:active {
21
+ @apply no-underline text-white;
22
22
  }
23
23
  }
24
24
 
@@ -46,7 +46,7 @@ a .badge.bg-primary, .badge-hover.bg-primary {
46
46
 
47
47
  a .badge.bg-secondary, .badge-hover.bg-secondary {
48
48
  &:hover, &:focus {
49
- @apply hover:text-white hover:bg-secondary-800 focus:bg-secondary-800 hover:border-secondary-800 focus:border-secondary-800 focus:text-secondary-800;
49
+ @apply hover:text-white hover:bg-secondary-800 focus:bg-secondary-800 hover:border-secondary-800 focus:border-secondary-800;
50
50
  }
51
51
  }
52
52
 
@@ -153,6 +153,7 @@
153
153
  }
154
154
  }
155
155
  }
156
+
156
157
  &[data-type=select-multiple] {
157
158
  &:after {
158
159
  @apply h-0 w-0 border-solid absolute border-0 h-full top-0 m-0 right-1.5;
@@ -168,14 +169,16 @@
168
169
  @apply pb-0;
169
170
  }
170
171
  }
171
- }
172
172
 
173
- .choices__list--multiple .choices__item {
174
- @apply rounded-sm;
173
+ .choices__list--multiple .choices__item {
174
+ @apply rounded-md bg-primary border-0 text-xs py-1 px-2;
175
+ font-weight: 600;
176
+ }
175
177
  }
176
178
 
177
- .is-open .choices__inner , .is-flipped.is-open .choices__inner {
178
- @apply rounded-md rounded-b-none;
179
+
180
+ .is-open .choices__inner, .is-flipped.is-open .choices__inner {
181
+ @apply rounded-md;
179
182
  }
180
183
 
181
184
  .choices__list {
@@ -188,7 +191,8 @@
188
191
  .choices__item {
189
192
  @apply w-full;
190
193
  }
191
- .choices__item.choices__item--selectable{
194
+
195
+ .choices__item.choices__item--selectable {
192
196
  margin-bottom: -0.375rem;
193
197
  }
194
198
  }
@@ -201,12 +205,13 @@
201
205
  }
202
206
 
203
207
  .choices__item {
204
- @apply inline-block align-middle rounded py-1 px-2.5 text-xs font-semibold mr-1 mb-1 bg-primary-500 border-1 border-solid border-primary-600 text-white ;
208
+ @apply inline-flex align-middle rounded py-1 px-2.5 text-xs font-semibold mr-1 mb-1 bg-primary-500 border-1 border-solid border-primary-600 text-white ;
205
209
  word-break: break-all;
206
210
  box-sizing: border-box;
207
211
 
208
212
  &.is-highlighted {
209
213
  @apply bg-secondary-500 border-secondary-600;
214
+
210
215
  .choices__button {
211
216
  @apply border-secondary-600;
212
217
  }
@@ -214,8 +219,8 @@
214
219
  }
215
220
  }
216
221
 
217
- &--dropdown {
218
- @apply invisible absolute z-5 w-full bg-white border-1 border-solid border-gray-300 rounded overflow-hidden break-all top-full;
222
+ &--dropdown[aria-expanded=true] {
223
+ @apply invisible absolute z-5 w-full bg-white border-1 border-solid border-gray-300 rounded-md overflow-hidden break-all top-full;
219
224
  will-change: visibility;
220
225
 
221
226
  &.is-active {
@@ -310,7 +315,6 @@
310
315
  }
311
316
  }
312
317
 
313
-
314
318
  .choices__heading {
315
319
  @apply font-semibold p-2.5 border-solid border-gray-200 text-gray-600;
316
320
  font-size: inherit;
@@ -337,3 +341,34 @@
337
341
  .choices__placeholder {
338
342
  @apply opacity-50;
339
343
  }
344
+
345
+ /**
346
+ * Choices Size rendering
347
+ */
348
+ .form-group.-size-small {
349
+ .choices {
350
+ .choices__inner {
351
+ @apply px-2;
352
+ padding-top: 3px;
353
+ min-height: 32px;
354
+ font-size: 14px;
355
+ }
356
+
357
+ &[data-type*=select-one] .choices__inner {
358
+ padding-bottom: 1px;
359
+ }
360
+
361
+ .choices__list--multiple .choices__item {
362
+ @apply py-0.5 px-1 text-xs;
363
+ margin-bottom: 3px;
364
+ }
365
+
366
+ .choices__input {
367
+ margin-bottom: 1px;
368
+ }
369
+ &[data-type*=select-multiple] .choices__button,
370
+ &[data-type*=text] .choices__button{
371
+ margin: 0 -2px 0 6px;
372
+ }
373
+ }
374
+ }
@@ -1,17 +1,16 @@
1
+ .form-edit-container {
2
+ @apply flex flex-col space-y-5;
3
+ }
4
+
1
5
  .form-edit {
2
- @apply border-b-1 border-solid border-gray-200 sm:flex mb-5;
6
+ @apply flex space-y-5 space-x-5 pb-5;
7
+ @apply border-b-1 border-solid border-gray-200;
3
8
 
4
9
  &__settings {
5
- @apply flex-1 flex flex-wrap -mx-2;
6
-
10
+ @apply flex-1 grid grid-cols-3 gap-5;
7
11
  > div {
8
12
  > .form-group {
9
- @apply pb-0 px-2 w-full sm:w-auto;
10
- min-width: 25%;
11
-
12
- &:last-child {
13
- @apply mb-5;
14
- }
13
+ @apply pb-0 w-full sm:w-auto;
15
14
 
16
15
  .form-text {
17
16
  @apply p-0 h-0 -mb-1;
@@ -21,24 +20,17 @@
21
20
  }
22
21
 
23
22
  &__actions {
24
- @apply flex flex-col justify-end mb-2;
23
+ @apply flex flex-col justify-center;
24
+
25
25
  .btn-save {
26
- @apply mb-4 leading-normal;
26
+ @apply leading-normal;
27
27
  }
28
28
 
29
29
  > div {
30
- @apply flex flex-col pl-5;
31
-
32
- > * {
33
- @apply mb-3;
34
- }
30
+ @apply flex flex-col space-y-5;
35
31
 
36
32
  > div {
37
- @apply flex flex-row -mx-2;
38
-
39
- > * {
40
- @apply mx-2;
41
- }
33
+ @apply flex flex-row space-x-3;
42
34
  }
43
35
  }
44
36
  }
package/styles/form.css CHANGED
@@ -23,14 +23,19 @@
23
23
  @apply mb-5;
24
24
  }
25
25
 
26
+
26
27
  .form-control {
27
28
  @apply appearance-none bg-white leading-normal px-3 py-2 block w-full rounded-md border-1 border-gray-300 shadow-sm;
29
+ }
28
30
 
29
- &.form-control-sm {
31
+ .form-group.-size-small {
32
+ .form-control {
30
33
  @apply px-2 py-1 text-sm;
34
+ min-height: 32px;
31
35
  }
32
36
  }
33
37
 
38
+
34
39
  .form-control:disabled, .form-control[readonly] {
35
40
  @apply bg-gray-200 border-transparent shadow-none;
36
41
  }
@@ -148,7 +153,7 @@ textarea.form-control {
148
153
  }
149
154
 
150
155
  .field-required:after {
151
- @apply z-1 ml-1;
156
+ @apply z-0 ml-1;
152
157
  }
153
158
 
154
159
  .formio-component hr,
package/styles/index.css CHANGED
@@ -5,6 +5,7 @@
5
5
  @import "card.css";
6
6
  @import "form.css";
7
7
  @import "choices.css";
8
+ @import "react-select.css";
8
9
  @import "input-group.css";
9
10
  @import "checkbox.css";
10
11
  @import "tooltip.css";
@@ -0,0 +1,105 @@
1
+
2
+ .react-select-container {
3
+ display: block;
4
+ flex: 1;
5
+
6
+ .react-select__control {
7
+ @apply appearance-none bg-white leading-normal w-full rounded-md border-1 border-gray-300;
8
+
9
+ &--is-focused {
10
+ @apply outline-none border-primary-300 ring ring-primary-50 ring-opacity-50;
11
+ outline-offset: theme('outline.none[1]');
12
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
13
+ border-color: theme('colors.blue.600');
14
+ }
15
+ }
16
+
17
+ .react-select__multi-value {
18
+ @apply bg-primary-600 text-white rounded-md;
19
+
20
+ &__label {
21
+ @apply text-white text-xs py-1 px-2;
22
+ font-weight: 600;
23
+ }
24
+
25
+ &__remove {
26
+ @apply opacity-80;
27
+
28
+ &:hover {
29
+ @apply bg-transparent text-white opacity-100;
30
+ }
31
+ }
32
+ }
33
+
34
+ .react-select__value-container.react-select__value-container--is-multi {
35
+ @apply px-2 py-1;
36
+ }
37
+ }
38
+
39
+ .form-group.-with-before {
40
+ .react-select-container .react-select__control {
41
+ border-top-left-radius: 0;
42
+ border-bottom-left-radius: 0;
43
+ }
44
+ }
45
+
46
+ .form-group.-with-after {
47
+ .react-select-container .react-select__control {
48
+ border-top-right-radius: 0;
49
+ border-bottom-right-radius: 0;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * React Select size rendering
55
+ */
56
+ .form-group.-size-small {
57
+ .react-select-container {
58
+ .react-select__control {
59
+ min-height: 28px;
60
+ }
61
+
62
+ .react-select__value-container {
63
+ padding-top: 0;
64
+ padding-bottom: 0;
65
+ }
66
+
67
+ .react-select__indicator {
68
+ padding: 3px;
69
+ }
70
+
71
+ .react-select__multi-value {
72
+ &__label {
73
+ @apply text-white text-xs py-0.5 px-1;
74
+ font-weight: 600;
75
+ }
76
+
77
+ &__remove {
78
+ @apply opacity-80;
79
+
80
+ &:hover {
81
+ @apply bg-transparent text-white opacity-100;
82
+ }
83
+ }
84
+ }
85
+
86
+ .react-select__input-container {
87
+ margin-top: 1px;
88
+ margin-bottom: 1px;
89
+ }
90
+
91
+ .react-select__placeholder {
92
+ @apply text-gray-500;
93
+ }
94
+
95
+ .react-select__option,
96
+ .react-select__placeholder,
97
+ .react-select__single-value {
98
+ @apply text-sm;
99
+ }
100
+
101
+ .react-select__value-container.react-select__value-container--is-multi {
102
+ @apply px-1 py-0;
103
+ }
104
+ }
105
+ }
package/styles/tables.css CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  th,
7
7
  td {
8
- @apply p-3 align-top text-left border-t-1 border-solid border-gray-300;
8
+ @apply p-3 align-top text-left border-t-1 border-solid border-gray-300 dark:border-gray-700;
9
9
 
10
10
  &.align-middle {
11
11
  vertical-align: middle;
@@ -17,23 +17,30 @@
17
17
  }
18
18
 
19
19
  thead th {
20
- @apply border-b-2 border-solid border-gray-300;
20
+ @apply border-b-2 border-solid border-gray-300 dark:border-gray-700;
21
21
  border-style: solid;
22
22
  }
23
23
 
24
24
  tbody + tbody {
25
- @apply border-t-2 border-solid border-gray-300;
25
+ @apply border-t-2 border-solid border-gray-300 dark:border-gray-700;
26
26
  border-style: solid;
27
27
  }
28
28
  }
29
29
 
30
30
  .table-cell-header {
31
+ @apply flex flex-col space-y-2;
31
32
  &__label {
32
- @apply flex;
33
+ @apply flex items-center justify-center;
34
+
33
35
  > span:first-child {
34
36
  @apply flex-1;
35
37
  }
36
38
  }
39
+
40
+ &__sort {
41
+ @apply flex items-center justify-center;
42
+ }
43
+
37
44
  &__filter {
38
45
  @apply mt-1;
39
46
  }
@@ -51,11 +58,11 @@
51
58
  /* Border versions - Add or remove borders all around the table and between all the columns. */
52
59
 
53
60
  .table-bordered {
54
- @apply border-1 border-solid border-gray-300;
61
+ @apply border-1 border-solid border-gray-300 dark:border-gray-700;
55
62
 
56
63
  th,
57
64
  td {
58
- @apply border-1 border-solid border-gray-300;
65
+ @apply border-1 border-solid border-gray-300 dark:border-gray-700;
59
66
  }
60
67
 
61
68
  thead {
@@ -79,7 +86,7 @@
79
86
 
80
87
  .table-striped {
81
88
  tbody tr:nth-of-type(odd) {
82
- @apply bg-gray-100;
89
+ @apply bg-gray-100 dark:bg-gray-800;
83
90
  }
84
91
  }
85
92
 
@@ -87,69 +94,29 @@
87
94
 
88
95
  .table-hover {
89
96
  tbody tr {
90
- @apply hover:text-gray-900 hover:bg-gray-200;
97
+ @apply hover:text-gray-900 hover:bg-gray-200 dark:hover:bg-gray-700 dark:hover:text-gray-100;
91
98
  }
92
99
  }
93
100
 
94
101
  .table-group {
95
- @apply border-1 border-gray-300;
102
+ @apply border-1 border-gray-300 dark:border-gray-700;
103
+
104
+ &.border-top-0 {
105
+ @apply border-t-0;
106
+ }
107
+
96
108
  .table {
97
109
  @apply border-t-0 mb-0;
98
110
  thead th {
99
111
  @apply border-t-0;
100
112
  }
101
113
  }
114
+
102
115
  .pagination-group {
103
- @apply border-t-1 border-gray-300 p-3;
116
+ @apply border-t-1 border-gray-300 dark:border-gray-700 p-3;
104
117
  }
105
118
  }
106
- /*
107
- // Dark styles
108
- //
109
- // Same table markup, but inverted color scheme: dark background and light text.
110
-
111
- // stylelint-disable-next-line no-duplicate-selectors
112
- //.table {
113
- // .thead-dark {
114
- // th {
115
- // color: $table-dark-color;
116
- // background-color: $table-dark-bg;
117
- // border-color: $table-dark-border-color;
118
- // }
119
- // }
120
- //
121
- // .thead-light {
122
- // th {
123
- // color: $table-head-color;
124
- // background-color: $table-head-bg;
125
- // border-color: $table-border-color;
126
- // }
127
- // }
128
- //}*/
129
- /*
130
- // Responsive tables
131
- //
132
- // Generate series of `.table-responsive-*` classes for configuring the screen
133
- // size of where your table will overflow.
134
119
 
135
120
  .table-responsive {
136
- @each $breakpoint in map-keys($grid-breakpoints) {
137
- $next: breakpoint-next($breakpoint, $grid-breakpoints);
138
- $infix: breakpoint-infix($next, $grid-breakpoints);
139
-
140
- &#{$infix} {
141
- @include media-breakpoint-down($breakpoint) {
142
- display: block;
143
- width: 100%;
144
- overflow-x: auto;
145
- -webkit-overflow-scrolling: touch;
146
-
147
- // Prevent double border on horizontal scroll due to use of `display: block;`
148
- > .table-bordered {
149
- border: 0;
150
- }
151
- }
152
- }
153
- }
121
+ @apply block w-full overflow-x-auto;
154
122
  }
155
- */
package/styles/tabs.css CHANGED
@@ -1,63 +1,81 @@
1
1
  .tw-tabs {
2
- &__header {
3
- @apply overflow-auto;
2
+ &__header {
3
+ @apply overflow-auto;
4
4
 
5
- &-wrapper {
6
- @apply relative flex items-center pt-1 px-1;
7
- }
8
- &-border {
9
- @apply border-b-1 border-gray-300 absolute bottom-0 left-0 right-0 z-1;
10
- }
11
- }
5
+ &-wrapper{
6
+ @apply relative flex items-center pt-1 gap-1;
12
7
 
13
- &__button {
14
- @apply flex items-center border-1 border-b-0 border-gray-300 relative outline-none focus:outline-none bg-gray-100 text-gray-700 hover:text-secondary focus:text-secondary px-4 py-2;
8
+ > [role="tablist"] {
9
+ @apply relative flex items-center gap-1;
10
+ }
11
+ }
15
12
 
16
- &-label {
17
- @apply text-sm whitespace-nowrap;
18
- }
19
- &-icon {
20
- @apply mr-2 -ml-1 -mt-px;
21
- }
13
+ .btn {
14
+ @apply px-3;
15
+ }
22
16
 
23
- &-border {
24
- @apply border-transparent z-1 absolute top-0 right-0 left-0 border-t-2;
25
- &.-active {
26
- @apply border-primary;
27
- }
28
- }
29
- &-wrapper {
30
- @apply relative mr-1;
31
-
32
- &:last-child{
33
- @apply mr-0;
34
- }
35
-
36
- &.-active {
37
- @apply z-2;
38
- }
39
- &.-back{
40
- @apply -ml-2 mr-0;
41
- }
17
+ &-border {
18
+ @apply border-b-1 border-gray-300 absolute bottom-0 left-0 right-0 z-1;
19
+ }
42
20
  }
43
21
 
44
- &.-active {
45
- @apply text-primary bg-white;
22
+ &__button {
23
+ @apply flex items-center border-1 border-b-0 border-gray-300 relative outline-none focus:outline-none bg-gray-100 text-gray-700 hover:text-secondary focus:text-secondary px-4 py-2;
24
+
25
+ &-label {
26
+ @apply text-sm whitespace-nowrap;
27
+ }
28
+
29
+ &-icon {
30
+ @apply mr-2 -ml-1 -mt-px;
31
+ }
32
+
33
+ &-border {
34
+ @apply border-transparent z-1 absolute top-0 right-0 left-0 border-t-2;
35
+ }
36
+
37
+ &-wrapper {
38
+ @apply relative ;
39
+
40
+ &.-active {
41
+ @apply z-2;
42
+
43
+ .tw-tabs__button {
44
+ @apply text-primary bg-white;
45
+ }
46
+
47
+ .tw-tabs__button-border {
48
+ @apply border-primary;
49
+ }
50
+ }
51
+
52
+ &.-reverse {
53
+ .tw-tabs__button {
54
+ @apply bg-white;
55
+
56
+ &.-active {
57
+ @apply bg-gray-100;
58
+ }
59
+ }
60
+ }
61
+ }
46
62
  }
47
63
 
48
- &.-reverse {
49
- @apply bg-white;
50
- &.-active {
51
- @apply bg-gray-100;
52
- }
64
+ &__body {
65
+ @apply grid grid-rows-1 overflow-hidden;
53
66
  }
54
67
 
55
- &.-back {
56
- @apply text-secondary bg-white px-2 border-transparent;
68
+ &__panel {
69
+ @apply col-start-1 col-end-1 row-start-1 row-end-1 transition-all duration-300 ease-in-out;
70
+
71
+ &.-active {
72
+ @apply z-1 opacity-100 visible;
73
+ height: auto;
74
+ }
57
75
 
58
- .tabs__button-icon {
59
- @apply m-0;
60
- }
76
+ &:not(.-active) {
77
+ @apply z-0 opacity-0 invisible;
78
+ height: 0;
79
+ }
61
80
  }
62
- }
63
81
  }
package/tsconfig.app.json CHANGED
@@ -6,6 +6,6 @@
6
6
  "declaration": false,
7
7
  "composite": false
8
8
  },
9
- "include": ["src/**/*.ts", "src/**/*.tsx", "vite.config.mts", "tailwind.config.ts"],
9
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
10
10
  "exclude": ["node_modules", "dist", "src/**/*.spec.ts", "src/**/*.spec.tsx"]
11
11
  }