@svadmin/lite 0.5.0 → 0.7.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.
- package/README.md +190 -9
- package/dist/compatibility.d.ts +23 -0
- package/dist/compatibility.js +95 -0
- package/dist/components/LiteDynamicFormList.svelte +169 -0
- package/dist/components/LiteDynamicFormList.svelte.d.ts +45 -0
- package/dist/components/LiteFilterBuilder.svelte +205 -0
- package/dist/components/LiteFilterBuilder.svelte.d.ts +19 -0
- package/dist/components/LiteShowField.svelte +52 -22
- package/dist/components/LiteShowField.svelte.d.ts +3 -2
- package/dist/components/LiteTable.svelte +89 -36
- package/dist/components/LiteTable.svelte.d.ts +3 -2
- package/dist/components/LiteTransfer.svelte +185 -0
- package/dist/components/LiteTransfer.svelte.d.ts +18 -0
- package/dist/components/compatibility/LiteCapabilityBoundary.svelte +51 -0
- package/dist/components/compatibility/LiteCapabilityBoundary.svelte.d.ts +13 -0
- package/dist/components/compatibility/LiteClipboardFallback.svelte +16 -0
- package/dist/components/compatibility/LiteClipboardFallback.svelte.d.ts +8 -0
- package/dist/components/compatibility/LiteComputeFallback.svelte +50 -0
- package/dist/components/compatibility/LiteComputeFallback.svelte.d.ts +14 -0
- package/dist/components/compatibility/LiteDirectoryUpload.svelte +44 -0
- package/dist/components/compatibility/LiteDirectoryUpload.svelte.d.ts +11 -0
- package/dist/components/compatibility/LiteOrderedList.svelte +47 -0
- package/dist/components/compatibility/LiteOrderedList.svelte.d.ts +14 -0
- package/dist/components/compatibility/LiteRealtimeStatus.svelte +43 -0
- package/dist/components/compatibility/LiteRealtimeStatus.svelte.d.ts +11 -0
- package/dist/components/compatibility/LiteVisualFallback.svelte +80 -0
- package/dist/components/compatibility/LiteVisualFallback.svelte.d.ts +18 -0
- package/dist/components/compatibility/index.d.ts +7 -0
- package/dist/components/compatibility/index.js +7 -0
- package/dist/components/fields/LiteAvatarField.svelte +127 -0
- package/dist/components/fields/LiteAvatarField.svelte.d.ts +21 -0
- package/dist/components/fields/LiteCascader.svelte +119 -0
- package/dist/components/fields/LiteCascader.svelte.d.ts +24 -0
- package/dist/components/fields/LiteCodeField.svelte +71 -0
- package/dist/components/fields/LiteCodeField.svelte.d.ts +16 -0
- package/dist/components/fields/LiteCopyField.svelte +74 -0
- package/dist/components/fields/LiteCopyField.svelte.d.ts +18 -0
- package/dist/components/fields/LiteCurrencyField.svelte +126 -0
- package/dist/components/fields/LiteCurrencyField.svelte.d.ts +21 -0
- package/dist/components/fields/LiteDateRangeField.svelte +147 -0
- package/dist/components/fields/LiteDateRangeField.svelte.d.ts +26 -0
- package/dist/components/fields/LitePercentField.svelte +124 -0
- package/dist/components/fields/LitePercentField.svelte.d.ts +17 -0
- package/dist/components/fields/LitePhoneField.svelte +81 -0
- package/dist/components/fields/LitePhoneField.svelte.d.ts +17 -0
- package/dist/components/fields/LiteRatingField.svelte +105 -0
- package/dist/components/fields/LiteRatingField.svelte.d.ts +16 -0
- package/dist/components/fields/LiteTreeSelect.svelte +143 -0
- package/dist/components/fields/LiteTreeSelect.svelte.d.ts +23 -0
- package/dist/components/fields/index.d.ts +12 -0
- package/dist/components/fields/index.js +10 -0
- package/dist/components/pages/LiteCreatePage.svelte +15 -6
- package/dist/components/pages/LiteCreatePage.svelte.d.ts +1 -1
- package/dist/components/pages/LiteEditPage.svelte +18 -9
- package/dist/components/pages/LiteEditPage.svelte.d.ts +1 -1
- package/dist/components/pages/LiteListPage.svelte +99 -27
- package/dist/components/pages/LiteListPage.svelte.d.ts +4 -2
- package/dist/components/pages/LiteShowPage.svelte +19 -10
- package/dist/components/pages/LiteShowPage.svelte.d.ts +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.js +8 -1
- package/dist/lite.css +444 -0
- package/dist/schema-generator.js +15 -4
- package/dist/server-adapter.d.ts +18 -1
- package/dist/server-adapter.js +73 -16
- package/package.json +5 -4
package/dist/lite.css
CHANGED
|
@@ -174,6 +174,21 @@ a:hover {
|
|
|
174
174
|
background: #f8fafc;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
.lite-page-header {
|
|
178
|
+
display: flex;
|
|
179
|
+
align-items: flex-start;
|
|
180
|
+
justify-content: space-between;
|
|
181
|
+
margin-bottom: 20px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.lite-page-title {
|
|
185
|
+
margin: 0;
|
|
186
|
+
font-size: 24px;
|
|
187
|
+
line-height: 1.25;
|
|
188
|
+
font-weight: 600;
|
|
189
|
+
color: #0f172a;
|
|
190
|
+
}
|
|
191
|
+
|
|
177
192
|
.lite-header {
|
|
178
193
|
display: flex;
|
|
179
194
|
align-items: center;
|
|
@@ -189,6 +204,40 @@ a:hover {
|
|
|
189
204
|
letter-spacing: -0.025em;
|
|
190
205
|
}
|
|
191
206
|
|
|
207
|
+
|
|
208
|
+
/* ─── Breadcrumbs ──────────────────────────────────────────── */
|
|
209
|
+
.lite-breadcrumbs {
|
|
210
|
+
margin-bottom: 16px;
|
|
211
|
+
}
|
|
212
|
+
.lite-breadcrumbs ol {
|
|
213
|
+
display: flex;
|
|
214
|
+
align-items: center;
|
|
215
|
+
flex-wrap: wrap;
|
|
216
|
+
list-style: none;
|
|
217
|
+
padding: 0;
|
|
218
|
+
margin: 0;
|
|
219
|
+
}
|
|
220
|
+
.lite-breadcrumbs li {
|
|
221
|
+
display: flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
font-size: 13px;
|
|
224
|
+
color: #64748b;
|
|
225
|
+
}
|
|
226
|
+
.lite-breadcrumbs a {
|
|
227
|
+
color: #64748b;
|
|
228
|
+
}
|
|
229
|
+
.lite-breadcrumbs a:hover {
|
|
230
|
+
color: #0f172a;
|
|
231
|
+
}
|
|
232
|
+
.lite-breadcrumbs .current {
|
|
233
|
+
color: #0f172a;
|
|
234
|
+
font-weight: 500;
|
|
235
|
+
}
|
|
236
|
+
.lite-breadcrumb-sep {
|
|
237
|
+
margin: 0 8px;
|
|
238
|
+
color: #cbd5e1;
|
|
239
|
+
}
|
|
240
|
+
|
|
192
241
|
/* ─── Cards ────────────────────────────────────────────────── */
|
|
193
242
|
.lite-card {
|
|
194
243
|
background: #fff;
|
|
@@ -747,6 +796,174 @@ textarea.lite-input {
|
|
|
747
796
|
justify-content: flex-end;
|
|
748
797
|
}
|
|
749
798
|
|
|
799
|
+
/* ─── Compatibility Fallbacks ─────────────────────────────── */
|
|
800
|
+
.lite-compatibility {
|
|
801
|
+
border: 1px solid #e2e8f0;
|
|
802
|
+
border-radius: 8px;
|
|
803
|
+
background: #fff;
|
|
804
|
+
margin-bottom: 16px;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
.lite-compatibility-header,
|
|
808
|
+
.lite-section-header,
|
|
809
|
+
.lite-realtime-status {
|
|
810
|
+
display: flex;
|
|
811
|
+
align-items: flex-start;
|
|
812
|
+
justify-content: space-between;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
.lite-compatibility-header {
|
|
816
|
+
padding: 14px 16px;
|
|
817
|
+
border-bottom: 1px solid #e2e8f0;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.lite-compatibility-header h2,
|
|
821
|
+
.lite-section-header h2,
|
|
822
|
+
.lite-ordered-list h2 {
|
|
823
|
+
margin: 0;
|
|
824
|
+
font-size: 15px;
|
|
825
|
+
font-weight: 600;
|
|
826
|
+
color: #0f172a;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
.lite-compatibility-header p,
|
|
830
|
+
.lite-section-header p {
|
|
831
|
+
margin: 4px 0 0;
|
|
832
|
+
color: #64748b;
|
|
833
|
+
font-size: 12px;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
.lite-compatibility-body {
|
|
837
|
+
padding: 16px;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
.lite-visual-fallback {
|
|
841
|
+
padding: 0;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
.lite-visual-fallback .lite-section-header {
|
|
845
|
+
padding: 14px 16px;
|
|
846
|
+
border-bottom: 1px solid #e2e8f0;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
.lite-visual-snapshot {
|
|
850
|
+
padding: 16px;
|
|
851
|
+
border-bottom: 1px solid #e2e8f0;
|
|
852
|
+
text-align: center;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
.lite-visual-snapshot img {
|
|
856
|
+
display: inline-block;
|
|
857
|
+
max-width: 100%;
|
|
858
|
+
height: auto;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
.lite-table-scroll {
|
|
862
|
+
overflow-x: auto;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
.lite-muted {
|
|
866
|
+
color: #64748b;
|
|
867
|
+
font-size: 12px;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.lite-realtime-status {
|
|
871
|
+
align-items: center;
|
|
872
|
+
padding: 10px 12px;
|
|
873
|
+
border: 1px solid #e2e8f0;
|
|
874
|
+
border-radius: 6px;
|
|
875
|
+
background: #fff;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.lite-realtime-status > div > * + * {
|
|
879
|
+
margin-left: 8px;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.lite-directory-upload {
|
|
883
|
+
border: 1px solid #e2e8f0;
|
|
884
|
+
border-radius: 8px;
|
|
885
|
+
padding: 16px;
|
|
886
|
+
background: #fff;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
.lite-directory-upload legend {
|
|
890
|
+
padding: 0 6px;
|
|
891
|
+
font-size: 14px;
|
|
892
|
+
font-weight: 600;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
.lite-ordered-list {
|
|
896
|
+
padding: 16px;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
.lite-ordered-list ol {
|
|
900
|
+
margin: 12px 0 0;
|
|
901
|
+
padding-left: 24px;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
.lite-ordered-list li {
|
|
905
|
+
padding: 10px 0 10px 4px;
|
|
906
|
+
border-bottom: 1px solid #f1f5f9;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
.lite-ordered-list li > div:first-child {
|
|
910
|
+
margin-bottom: 8px;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
.lite-ordered-list li span {
|
|
914
|
+
display: block;
|
|
915
|
+
margin-top: 2px;
|
|
916
|
+
color: #64748b;
|
|
917
|
+
font-size: 12px;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
.lite-compute-fallback {
|
|
921
|
+
padding: 16px;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
.lite-clipboard-fallback {
|
|
925
|
+
margin-bottom: 0;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
.lite-dashboard-stats,
|
|
929
|
+
.lite-dashboard-split,
|
|
930
|
+
.lite-resource-links {
|
|
931
|
+
display: flex;
|
|
932
|
+
flex-wrap: wrap;
|
|
933
|
+
margin-left: -8px;
|
|
934
|
+
margin-right: -8px;
|
|
935
|
+
margin-bottom: 24px;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
.lite-dashboard-stats > *,
|
|
939
|
+
.lite-dashboard-split > *,
|
|
940
|
+
.lite-resource-links > * {
|
|
941
|
+
margin-left: 8px;
|
|
942
|
+
margin-right: 8px;
|
|
943
|
+
margin-bottom: 16px;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
.lite-dashboard-stats > * {
|
|
947
|
+
flex: 1 1 220px;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
.lite-dashboard-split > *:first-child {
|
|
951
|
+
flex: 2 1 480px;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
.lite-dashboard-split > *:last-child {
|
|
955
|
+
flex: 1 1 240px;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
.lite-resource-links {
|
|
959
|
+
padding: 16px 8px 0;
|
|
960
|
+
margin-bottom: 0;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
.lite-resource-links > * {
|
|
964
|
+
flex: 1 1 200px;
|
|
965
|
+
}
|
|
966
|
+
|
|
750
967
|
/* ─── Login Page ───────────────────────────────────────────── */
|
|
751
968
|
.lite-login-wrapper {
|
|
752
969
|
display: flex;
|
|
@@ -849,6 +1066,211 @@ textarea.lite-input {
|
|
|
849
1066
|
.lite-mt-0 { margin-top: 0; }
|
|
850
1067
|
.lite-mb-lg { margin-bottom: 24px; }
|
|
851
1068
|
|
|
1069
|
+
/* ─── Avatar ───────────────────────────────────────────────── */
|
|
1070
|
+
.lite-avatar-wrapper {
|
|
1071
|
+
display: inline-flex;
|
|
1072
|
+
align-items: center;
|
|
1073
|
+
}
|
|
1074
|
+
.lite-avatar-container {
|
|
1075
|
+
position: relative;
|
|
1076
|
+
display: inline-block;
|
|
1077
|
+
vertical-align: middle;
|
|
1078
|
+
flex-shrink: 0;
|
|
1079
|
+
}
|
|
1080
|
+
.lite-avatar {
|
|
1081
|
+
display: inline-flex;
|
|
1082
|
+
align-items: center;
|
|
1083
|
+
justify-content: center;
|
|
1084
|
+
background: #f1f5f9;
|
|
1085
|
+
color: #64748b;
|
|
1086
|
+
font-weight: 500;
|
|
1087
|
+
overflow: hidden;
|
|
1088
|
+
vertical-align: middle;
|
|
1089
|
+
}
|
|
1090
|
+
.lite-avatar-circle { border-radius: 50%; }
|
|
1091
|
+
.lite-avatar-square { border-radius: 6px; }
|
|
1092
|
+
|
|
1093
|
+
.lite-avatar-xs { width: 20px; height: 20px; font-size: 10px; }
|
|
1094
|
+
.lite-avatar-sm { width: 28px; height: 28px; font-size: 12px; }
|
|
1095
|
+
.lite-avatar-default { width: 36px; height: 36px; font-size: 14px; }
|
|
1096
|
+
.lite-avatar-lg { width: 44px; height: 44px; font-size: 16px; }
|
|
1097
|
+
|
|
1098
|
+
.lite-avatar-img {
|
|
1099
|
+
width: 100%;
|
|
1100
|
+
height: 100%;
|
|
1101
|
+
object-fit: cover;
|
|
1102
|
+
}
|
|
1103
|
+
.lite-avatar-dot {
|
|
1104
|
+
position: absolute;
|
|
1105
|
+
bottom: 0;
|
|
1106
|
+
right: 0;
|
|
1107
|
+
border-radius: 50%;
|
|
1108
|
+
border: 2px solid #ffffff;
|
|
1109
|
+
}
|
|
1110
|
+
.lite-avatar-dot-xs { width: 6px; height: 6px; }
|
|
1111
|
+
.lite-avatar-dot-sm { width: 8px; height: 8px; }
|
|
1112
|
+
.lite-avatar-dot-default { width: 10px; height: 10px; }
|
|
1113
|
+
.lite-avatar-dot-lg { width: 12px; height: 12px; }
|
|
1114
|
+
|
|
1115
|
+
.lite-avatar-status-online, .lite-avatar-status-success { background: #22c55e; }
|
|
1116
|
+
.lite-avatar-status-busy, .lite-avatar-status-error { background: #ef4444; }
|
|
1117
|
+
.lite-avatar-status-warning, .lite-avatar-status-away { background: #f59e0b; }
|
|
1118
|
+
.lite-avatar-status-offline, .lite-avatar-status-neutral { background: #94a3b8; }
|
|
1119
|
+
|
|
1120
|
+
.lite-avatar-text-block {
|
|
1121
|
+
display: inline-flex;
|
|
1122
|
+
flex-direction: column;
|
|
1123
|
+
margin-left: 10px;
|
|
1124
|
+
text-align: left;
|
|
1125
|
+
vertical-align: middle;
|
|
1126
|
+
}
|
|
1127
|
+
.lite-avatar-name {
|
|
1128
|
+
font-size: 13px;
|
|
1129
|
+
font-weight: 500;
|
|
1130
|
+
color: #0f172a;
|
|
1131
|
+
line-height: 1.2;
|
|
1132
|
+
}
|
|
1133
|
+
.lite-avatar-subtitle {
|
|
1134
|
+
font-size: 11px;
|
|
1135
|
+
color: #64748b;
|
|
1136
|
+
line-height: 1.2;
|
|
1137
|
+
margin-top: 2px;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
/* ─── Code Block ───────────────────────────────────────────── */
|
|
1141
|
+
.lite-code-block {
|
|
1142
|
+
border: 1px solid #e2e8f0;
|
|
1143
|
+
border-radius: 6px;
|
|
1144
|
+
background: #f8fafc;
|
|
1145
|
+
overflow: hidden;
|
|
1146
|
+
margin: 4px 0;
|
|
1147
|
+
}
|
|
1148
|
+
.lite-code-header {
|
|
1149
|
+
padding: 4px 10px;
|
|
1150
|
+
background: #f1f5f9;
|
|
1151
|
+
border-bottom: 1px solid #e2e8f0;
|
|
1152
|
+
font-size: 11px;
|
|
1153
|
+
}
|
|
1154
|
+
.lite-code-pre {
|
|
1155
|
+
margin: 0;
|
|
1156
|
+
padding: 10px 12px;
|
|
1157
|
+
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
|
1158
|
+
font-size: 12px;
|
|
1159
|
+
line-height: 1.5;
|
|
1160
|
+
overflow-x: auto;
|
|
1161
|
+
overflow-y: auto;
|
|
1162
|
+
color: #0f172a;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/* ─── Copy Field ───────────────────────────────────────────── */
|
|
1166
|
+
.lite-copy-field {
|
|
1167
|
+
display: inline-flex;
|
|
1168
|
+
align-items: center;
|
|
1169
|
+
}
|
|
1170
|
+
.lite-copy-text {
|
|
1171
|
+
font-size: 13px;
|
|
1172
|
+
color: #0f172a;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
/* ─── Currency & Numbers ───────────────────────────────────── */
|
|
1176
|
+
.lite-currency-field {
|
|
1177
|
+
display: inline-flex;
|
|
1178
|
+
align-items: center;
|
|
1179
|
+
font-size: 13px;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/* ─── Date Range ───────────────────────────────────────────── */
|
|
1183
|
+
.lite-date-range {
|
|
1184
|
+
display: inline-flex;
|
|
1185
|
+
align-items: center;
|
|
1186
|
+
font-size: 13px;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
/* ─── Percentage & Progress ────────────────────────────────── */
|
|
1190
|
+
.lite-percent-container {
|
|
1191
|
+
display: inline-flex;
|
|
1192
|
+
align-items: center;
|
|
1193
|
+
}
|
|
1194
|
+
.lite-progress-track {
|
|
1195
|
+
display: inline-block;
|
|
1196
|
+
width: 64px;
|
|
1197
|
+
height: 6px;
|
|
1198
|
+
background: #e2e8f0;
|
|
1199
|
+
border-radius: 3px;
|
|
1200
|
+
overflow: hidden;
|
|
1201
|
+
margin-left: 8px;
|
|
1202
|
+
vertical-align: middle;
|
|
1203
|
+
}
|
|
1204
|
+
.lite-progress-fill {
|
|
1205
|
+
display: block;
|
|
1206
|
+
height: 100%;
|
|
1207
|
+
background: #4f46e5;
|
|
1208
|
+
border-radius: 3px;
|
|
1209
|
+
}
|
|
1210
|
+
.lite-progress-success { background: #22c55e; }
|
|
1211
|
+
.lite-progress-warning { background: #f59e0b; }
|
|
1212
|
+
.lite-progress-danger { background: #ef4444; }
|
|
1213
|
+
.lite-progress-info { background: #3b82f6; }
|
|
1214
|
+
|
|
1215
|
+
/* ─── Phone Field ──────────────────────────────────────────── */
|
|
1216
|
+
.lite-phone-container {
|
|
1217
|
+
display: inline-flex;
|
|
1218
|
+
align-items: center;
|
|
1219
|
+
font-size: 13px;
|
|
1220
|
+
}
|
|
1221
|
+
.lite-phone-icon {
|
|
1222
|
+
margin-right: 6px;
|
|
1223
|
+
font-size: 12px;
|
|
1224
|
+
}
|
|
1225
|
+
.lite-phone-link {
|
|
1226
|
+
color: #4f46e5;
|
|
1227
|
+
font-weight: 500;
|
|
1228
|
+
text-decoration: none;
|
|
1229
|
+
}
|
|
1230
|
+
.lite-phone-link:hover {
|
|
1231
|
+
text-decoration: underline;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/* ─── Rating Field ─────────────────────────────────────────── */
|
|
1235
|
+
.lite-rating-container {
|
|
1236
|
+
display: inline-flex;
|
|
1237
|
+
align-items: center;
|
|
1238
|
+
}
|
|
1239
|
+
.lite-rating {
|
|
1240
|
+
display: inline-flex;
|
|
1241
|
+
align-items: center;
|
|
1242
|
+
}
|
|
1243
|
+
.lite-rating-star {
|
|
1244
|
+
display: inline-block;
|
|
1245
|
+
margin-right: 2px;
|
|
1246
|
+
line-height: 1;
|
|
1247
|
+
}
|
|
1248
|
+
.lite-rating-star-full, .lite-rating-star-half {
|
|
1249
|
+
color: #f59e0b;
|
|
1250
|
+
}
|
|
1251
|
+
.lite-rating-star-empty {
|
|
1252
|
+
color: #cbd5e1;
|
|
1253
|
+
}
|
|
1254
|
+
.lite-rating-sm { font-size: 12px; }
|
|
1255
|
+
.lite-rating-default { font-size: 14px; }
|
|
1256
|
+
.lite-rating-lg { font-size: 18px; }
|
|
1257
|
+
.lite-rating-value {
|
|
1258
|
+
margin-left: 6px;
|
|
1259
|
+
font-size: 13px;
|
|
1260
|
+
color: #0f172a;
|
|
1261
|
+
font-weight: 500;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
/* ─── Semantic Tone Utilities ──────────────────────────────── */
|
|
1265
|
+
.lite-font-mono {
|
|
1266
|
+
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
|
1267
|
+
}
|
|
1268
|
+
.lite-text-success { color: #16a34a; font-weight: 500; }
|
|
1269
|
+
.lite-text-warning { color: #d97706; font-weight: 500; }
|
|
1270
|
+
.lite-text-danger { color: #dc2626; font-weight: 500; }
|
|
1271
|
+
.lite-text-info { color: #2563eb; font-weight: 500; }
|
|
1272
|
+
.lite-text-primary { color: #4f46e5; font-weight: 500; }
|
|
1273
|
+
|
|
852
1274
|
/* ─── Responsive ───────────────────────────────────────────── */
|
|
853
1275
|
@media (max-width: 768px) {
|
|
854
1276
|
.lite-wrapper {
|
|
@@ -860,6 +1282,11 @@ textarea.lite-input {
|
|
|
860
1282
|
.lite-mobile-nav {
|
|
861
1283
|
display: block;
|
|
862
1284
|
}
|
|
1285
|
+
.lite-mobile-nav-links {
|
|
1286
|
+
max-height: 240px;
|
|
1287
|
+
overflow-y: auto;
|
|
1288
|
+
border-top: 1px solid #f1f5f9;
|
|
1289
|
+
}
|
|
863
1290
|
.lite-main {
|
|
864
1291
|
padding: 16px;
|
|
865
1292
|
}
|
|
@@ -873,6 +1300,23 @@ textarea.lite-input {
|
|
|
873
1300
|
.lite-header h1 {
|
|
874
1301
|
margin-bottom: 12px;
|
|
875
1302
|
}
|
|
1303
|
+
.lite-page-header {
|
|
1304
|
+
display: block;
|
|
1305
|
+
}
|
|
1306
|
+
.lite-page-header > .lite-btn {
|
|
1307
|
+
margin-top: 12px;
|
|
1308
|
+
}
|
|
1309
|
+
.lite-compatibility-header,
|
|
1310
|
+
.lite-section-header,
|
|
1311
|
+
.lite-realtime-status {
|
|
1312
|
+
display: block;
|
|
1313
|
+
}
|
|
1314
|
+
.lite-compatibility-header .lite-badge,
|
|
1315
|
+
.lite-section-header > .lite-badge,
|
|
1316
|
+
.lite-section-header > .lite-btn,
|
|
1317
|
+
.lite-realtime-status > .lite-btn {
|
|
1318
|
+
margin-top: 10px;
|
|
1319
|
+
}
|
|
876
1320
|
}
|
|
877
1321
|
|
|
878
1322
|
/* ─── Print ────────────────────────────────────────────────── */
|
package/dist/schema-generator.js
CHANGED
|
@@ -49,6 +49,7 @@ function coerceAndValidateField(field, value, mode, withinArray = false, path =
|
|
|
49
49
|
const issues = [];
|
|
50
50
|
let coerced = value;
|
|
51
51
|
switch (field.type) {
|
|
52
|
+
case "currency":
|
|
52
53
|
case "number": {
|
|
53
54
|
if (coerced === undefined || coerced === null || coerced === "") {
|
|
54
55
|
coerced = undefined;
|
|
@@ -57,7 +58,7 @@ function coerceAndValidateField(field, value, mode, withinArray = false, path =
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
else if (typeof coerced === "string") {
|
|
60
|
-
const trimmed = coerced.trim();
|
|
61
|
+
const trimmed = coerced.trim().replace(/^[$€£¥₹]/u, "");
|
|
61
62
|
if (trimmed === "") {
|
|
62
63
|
coerced = undefined;
|
|
63
64
|
if (field.required) {
|
|
@@ -251,7 +252,7 @@ function coerceAndValidateField(field, value, mode, withinArray = false, path =
|
|
|
251
252
|
}
|
|
252
253
|
case "phone": {
|
|
253
254
|
if (typeof coerced === "string" && coerced.length > 0) {
|
|
254
|
-
if (!/^[+\d\s()-]
|
|
255
|
+
if (!/^[+\d\s()-]*$/u.test(coerced)) {
|
|
255
256
|
issues.push({ path, message: `${field.label} must be a valid phone number` });
|
|
256
257
|
}
|
|
257
258
|
}
|
|
@@ -309,7 +310,13 @@ function coerceAndValidateField(field, value, mode, withinArray = false, path =
|
|
|
309
310
|
break;
|
|
310
311
|
}
|
|
311
312
|
// Check required
|
|
312
|
-
if (field.type !== "number"
|
|
313
|
+
if (field.type !== "number"
|
|
314
|
+
&& field.type !== "currency"
|
|
315
|
+
&& field.type !== "boolean"
|
|
316
|
+
&& field.type !== "array"
|
|
317
|
+
&& field.type !== "file"
|
|
318
|
+
&& field.type !== "image"
|
|
319
|
+
&& field.type !== "images") {
|
|
313
320
|
if (field.required && !hasRequiredValue(coerced)) {
|
|
314
321
|
issues.push({ path, message: `${field.label} is required` });
|
|
315
322
|
}
|
|
@@ -339,6 +346,7 @@ export function fieldsToTypeBoxSchema(fields, mode = "create") {
|
|
|
339
346
|
activeFields.push(field);
|
|
340
347
|
switch (field.type) {
|
|
341
348
|
case "number":
|
|
349
|
+
case "currency":
|
|
342
350
|
shape[field.key] = field.required ? Type.Number() : Type.Optional(Type.Number());
|
|
343
351
|
break;
|
|
344
352
|
case "boolean":
|
|
@@ -434,7 +442,9 @@ export const resourceToZodSchema = resourceToTypeBoxSchema;
|
|
|
434
442
|
*/
|
|
435
443
|
export function fieldToInputType(field) {
|
|
436
444
|
switch (field.type) {
|
|
437
|
-
case "number":
|
|
445
|
+
case "number":
|
|
446
|
+
case "currency": return "text";
|
|
447
|
+
case "color": return "color";
|
|
438
448
|
case "email": return "text";
|
|
439
449
|
case "url": return "text";
|
|
440
450
|
case "phone": return "tel";
|
|
@@ -464,6 +474,7 @@ export function fieldToPlaceholder(field) {
|
|
|
464
474
|
case "url": return "https://example.com";
|
|
465
475
|
case "phone": return "+1 (555) 000-0000";
|
|
466
476
|
case "number": return "0";
|
|
477
|
+
case "currency": return "0.00";
|
|
467
478
|
default: return "";
|
|
468
479
|
}
|
|
469
480
|
}
|
package/dist/server-adapter.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export interface ListLoaderResult {
|
|
|
24
24
|
currentSort?: string;
|
|
25
25
|
currentOrder?: 'asc' | 'desc';
|
|
26
26
|
currentSearch?: string;
|
|
27
|
+
currentFilters?: Record<string, string>;
|
|
27
28
|
resource: ResourceDefinition;
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
@@ -157,11 +158,27 @@ export declare function createAuthActions(authProvider: AuthProvider): {
|
|
|
157
158
|
* This helper does not imply that Svelte 5 or the consuming app supports IE11.
|
|
158
159
|
*/
|
|
159
160
|
export declare function isLegacyBrowser(userAgent: string): boolean;
|
|
161
|
+
export interface LegacyRedirectOptions {
|
|
162
|
+
/** Route prefix that contains the standalone SSR Lite application. */
|
|
163
|
+
litePrefix?: string;
|
|
164
|
+
/** Optional route prefix occupied by the modern SPA, for example `/admin`. */
|
|
165
|
+
spaPrefix?: string;
|
|
166
|
+
/** Paths that must remain outside automatic legacy routing. */
|
|
167
|
+
exclude?: string[];
|
|
168
|
+
/** Override the SPA-to-Lite path mapping without changing SPA code. */
|
|
169
|
+
mapPath?: (pathname: string) => string;
|
|
170
|
+
status?: 302 | 307;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Computes a legacy redirect without importing or modifying the modern SPA.
|
|
174
|
+
* This pure helper can be used from non-SvelteKit server middleware.
|
|
175
|
+
*/
|
|
176
|
+
export declare function getLegacyRedirectLocation(request: Pick<Request, 'method' | 'headers'>, url: URL, options?: string | LegacyRedirectOptions): string | undefined;
|
|
160
177
|
/**
|
|
161
178
|
* Creates an opt-in SvelteKit hook that redirects detected IE11 user agents.
|
|
162
179
|
* Consumers remain responsible for their own transpilation and browser support.
|
|
163
180
|
*/
|
|
164
|
-
export declare function createLegacyRedirectHook(
|
|
181
|
+
export declare function createLegacyRedirectHook(options?: string | LegacyRedirectOptions): ({ event, resolve }: {
|
|
165
182
|
event: RequestEvent;
|
|
166
183
|
resolve: (event: RequestEvent) => Promise<Response>;
|
|
167
184
|
}) => Promise<Response>;
|
package/dist/server-adapter.js
CHANGED
|
@@ -19,6 +19,16 @@ function listRequestState(url, resource) {
|
|
|
19
19
|
: resource.defaultSort?.order ?? 'asc';
|
|
20
20
|
return { page, pageSize, sort, order, search: url.searchParams.get('q') ?? undefined };
|
|
21
21
|
}
|
|
22
|
+
function listRequestFilterValues(resource, url) {
|
|
23
|
+
const values = {};
|
|
24
|
+
for (const field of resource.fields) {
|
|
25
|
+
const raw = url.searchParams.get(`filter_${field.key}`) ?? (field.key !== "q" && field.key !== "sort" && field.key !== "order" && field.key !== "page" ? url.searchParams.get(field.key) : null);
|
|
26
|
+
if (raw != null && raw.trim() !== "") {
|
|
27
|
+
values[field.key] = raw.trim();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return values;
|
|
31
|
+
}
|
|
22
32
|
function listRequestFilters(resource, url) {
|
|
23
33
|
const filters = [];
|
|
24
34
|
const search = url.searchParams.get('q') ?? undefined;
|
|
@@ -76,6 +86,7 @@ export function createListLoader(dp, resource) {
|
|
|
76
86
|
currentSort: sort,
|
|
77
87
|
currentOrder: order,
|
|
78
88
|
currentSearch: search,
|
|
89
|
+
currentFilters: listRequestFilterValues(resource, url),
|
|
79
90
|
resource,
|
|
80
91
|
};
|
|
81
92
|
};
|
|
@@ -343,28 +354,74 @@ export function createAuthActions(authProvider) {
|
|
|
343
354
|
export function isLegacyBrowser(userAgent) {
|
|
344
355
|
return /MSIE|Trident|rv:11/.test(userAgent);
|
|
345
356
|
}
|
|
357
|
+
function normalizeRoutePrefix(prefix) {
|
|
358
|
+
const segments = prefix.split('/').filter(Boolean);
|
|
359
|
+
return segments.length > 0 ? `/${segments.join('/')}` : '/';
|
|
360
|
+
}
|
|
361
|
+
function pathWithinPrefix(pathname, prefix) {
|
|
362
|
+
return prefix === '/' || pathname === prefix || pathname.startsWith(`${prefix}/`);
|
|
363
|
+
}
|
|
364
|
+
function redirectOptions(options) {
|
|
365
|
+
const configured = typeof options === 'string' ? { litePrefix: options } : options;
|
|
366
|
+
return {
|
|
367
|
+
litePrefix: normalizeRoutePrefix(configured.litePrefix ?? '/lite'),
|
|
368
|
+
spaPrefix: normalizeRoutePrefix(configured.spaPrefix ?? '/'),
|
|
369
|
+
exclude: (configured.exclude ?? []).map(normalizeRoutePrefix),
|
|
370
|
+
mapPath: configured.mapPath,
|
|
371
|
+
status: configured.status ?? 302,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Computes a legacy redirect without importing or modifying the modern SPA.
|
|
376
|
+
* This pure helper can be used from non-SvelteKit server middleware.
|
|
377
|
+
*/
|
|
378
|
+
export function getLegacyRedirectLocation(request, url, options = '/lite') {
|
|
379
|
+
const configured = redirectOptions(options);
|
|
380
|
+
const userAgent = request.headers.get('user-agent') ?? '';
|
|
381
|
+
const acceptsHtml = request.headers.get('accept')?.includes('text/html') === true;
|
|
382
|
+
const isDocumentRequest = (request.method === 'GET' || request.method === 'HEAD') && acceptsHtml;
|
|
383
|
+
if (!isLegacyBrowser(userAgent) || !isDocumentRequest)
|
|
384
|
+
return undefined;
|
|
385
|
+
if (pathWithinPrefix(url.pathname, configured.litePrefix))
|
|
386
|
+
return undefined;
|
|
387
|
+
if (configured.exclude.some((prefix) => pathWithinPrefix(url.pathname, prefix)))
|
|
388
|
+
return undefined;
|
|
389
|
+
if (!configured.mapPath
|
|
390
|
+
&& configured.spaPrefix !== '/'
|
|
391
|
+
&& !pathWithinPrefix(url.pathname, configured.spaPrefix))
|
|
392
|
+
return undefined;
|
|
393
|
+
let mappedPath;
|
|
394
|
+
if (configured.mapPath) {
|
|
395
|
+
mappedPath = configured.mapPath(url.pathname);
|
|
396
|
+
}
|
|
397
|
+
else if (configured.spaPrefix !== '/' && pathWithinPrefix(url.pathname, configured.spaPrefix)) {
|
|
398
|
+
mappedPath = url.pathname.slice(configured.spaPrefix.length) || '/';
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
mappedPath = url.pathname;
|
|
402
|
+
}
|
|
403
|
+
const normalizedMappedPath = mappedPath.startsWith('/') ? mappedPath : `/${mappedPath}`;
|
|
404
|
+
const location = configured.litePrefix === '/'
|
|
405
|
+
? normalizedMappedPath
|
|
406
|
+
: `${configured.litePrefix}${normalizedMappedPath === '/' ? '' : normalizedMappedPath}`;
|
|
407
|
+
return `${location}${url.search}`;
|
|
408
|
+
}
|
|
346
409
|
/**
|
|
347
410
|
* Creates an opt-in SvelteKit hook that redirects detected IE11 user agents.
|
|
348
411
|
* Consumers remain responsible for their own transpilation and browser support.
|
|
349
412
|
*/
|
|
350
|
-
export function createLegacyRedirectHook(
|
|
351
|
-
const
|
|
352
|
-
const normalizedPrefix = prefixSegments.length > 0 ? `/${prefixSegments.join('/')}` : '/';
|
|
413
|
+
export function createLegacyRedirectHook(options = '/lite') {
|
|
414
|
+
const configured = redirectOptions(options);
|
|
353
415
|
return async ({ event, resolve }) => {
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
const isDocumentRequest = (event.request.method === 'GET' || event.request.method === 'HEAD')
|
|
357
|
-
&& acceptsHtml;
|
|
358
|
-
const isWithinLite = normalizedPrefix === '/'
|
|
359
|
-
|| event.url.pathname === normalizedPrefix
|
|
360
|
-
|| event.url.pathname.startsWith(`${normalizedPrefix}/`);
|
|
361
|
-
if (isLegacyBrowser(ua) && isDocumentRequest && !isWithinLite) {
|
|
362
|
-
const targetPath = normalizedPrefix === '/'
|
|
363
|
-
? event.url.pathname
|
|
364
|
-
: `${normalizedPrefix}${event.url.pathname}`;
|
|
416
|
+
const location = getLegacyRedirectLocation(event.request, event.url, configured);
|
|
417
|
+
if (location) {
|
|
365
418
|
return new Response(null, {
|
|
366
|
-
status:
|
|
367
|
-
headers: {
|
|
419
|
+
status: configured.status,
|
|
420
|
+
headers: {
|
|
421
|
+
Location: location,
|
|
422
|
+
'Cache-Control': 'private, no-store',
|
|
423
|
+
Vary: 'User-Agent',
|
|
424
|
+
},
|
|
368
425
|
});
|
|
369
426
|
}
|
|
370
427
|
return resolve(event);
|