@elle96/ng-json-schema-manager 0.1.1 → 0.1.3
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, EventEmitter, Output, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, NgModule } from '@angular/core';
|
|
2
|
+
import { Injectable, EventEmitter, Output, Input, ChangeDetectionStrategy, ViewEncapsulation, Component, PLATFORM_ID, Inject, NgModule } from '@angular/core';
|
|
3
3
|
import * as i4 from '@angular/forms';
|
|
4
4
|
import { FormGroup, FormArray, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
5
5
|
import Ajv from 'ajv';
|
|
@@ -8,7 +8,7 @@ import Ajv2020 from 'ajv/dist/2020';
|
|
|
8
8
|
import addFormats from 'ajv-formats';
|
|
9
9
|
import AjvDraft04 from 'ajv-draft-04';
|
|
10
10
|
import * as i3 from '@angular/common';
|
|
11
|
-
import { CommonModule } from '@angular/common';
|
|
11
|
+
import { CommonModule, isPlatformBrowser } from '@angular/common';
|
|
12
12
|
|
|
13
13
|
class JsonSchemaFormService {
|
|
14
14
|
buildControl(schema, value, required = false) {
|
|
@@ -582,6 +582,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
582
582
|
class JsonSchemaNodeComponent {
|
|
583
583
|
schemaService;
|
|
584
584
|
validation;
|
|
585
|
+
cdr;
|
|
585
586
|
schema;
|
|
586
587
|
control;
|
|
587
588
|
label = '';
|
|
@@ -596,34 +597,38 @@ class JsonSchemaNodeComponent {
|
|
|
596
597
|
selectedAnyOf = new Set();
|
|
597
598
|
newPropertyKey = '';
|
|
598
599
|
propertyError = '';
|
|
599
|
-
|
|
600
|
+
valueSub;
|
|
601
|
+
constructor(schemaService, validation, cdr) {
|
|
600
602
|
this.schemaService = schemaService;
|
|
601
603
|
this.validation = validation;
|
|
604
|
+
this.cdr = cdr;
|
|
602
605
|
}
|
|
603
606
|
ngOnInit() {
|
|
604
|
-
if (this.schema.anyOf?.length)
|
|
607
|
+
if (this.schema.anyOf?.length)
|
|
605
608
|
this.selectedAnyOf.add(0);
|
|
606
|
-
|
|
609
|
+
// Subscribe to value changes to trigger CD for OnPush (needed for toggle visual state)
|
|
610
|
+
this.valueSub = this.control.valueChanges.subscribe(() => this.cdr.markForCheck());
|
|
611
|
+
}
|
|
612
|
+
ngOnDestroy() {
|
|
613
|
+
this.valueSub?.unsubscribe();
|
|
607
614
|
}
|
|
608
|
-
/**
|
|
609
|
-
* Determina se un figlio di un object è "semplice" (primitive/enum/bool),
|
|
610
|
-
* quindi può stare in griglia 2-col, oppure "complesso" (object/array/combinator)
|
|
611
|
-
* che deve occupare la larghezza piena.
|
|
612
|
-
*/
|
|
613
615
|
isSimpleChild(key) {
|
|
614
|
-
const
|
|
615
|
-
if (
|
|
616
|
+
const s = this.schemaForKey(key);
|
|
617
|
+
if (s.oneOf?.length || s.anyOf?.length || s.allOf?.length)
|
|
616
618
|
return false;
|
|
617
|
-
const t = this.schemaService.resolveType(
|
|
619
|
+
const t = this.schemaService.resolveType(s);
|
|
618
620
|
return t !== 'object' && t !== 'array';
|
|
619
621
|
}
|
|
620
622
|
badgeClass(badge) {
|
|
621
|
-
|
|
622
|
-
'
|
|
623
|
-
|
|
624
|
-
'
|
|
625
|
-
|
|
626
|
-
|
|
623
|
+
if (badge === 'Deprecated')
|
|
624
|
+
return 'jsm-badge--deprecated';
|
|
625
|
+
if (badge === 'Read-only' || badge === 'Nullable')
|
|
626
|
+
return 'jsm-badge--readonly';
|
|
627
|
+
if (badge === 'Write-only')
|
|
628
|
+
return 'jsm-badge--writeonly';
|
|
629
|
+
if (badge === 'Not constraint')
|
|
630
|
+
return 'jsm-badge--not';
|
|
631
|
+
return 'jsm-badge--nullable';
|
|
627
632
|
}
|
|
628
633
|
get nodeKind() {
|
|
629
634
|
if (this.schema.oneOf?.length)
|
|
@@ -632,10 +637,10 @@ class JsonSchemaNodeComponent {
|
|
|
632
637
|
return 'anyOf';
|
|
633
638
|
if (this.schema.allOf?.length)
|
|
634
639
|
return 'allOf';
|
|
635
|
-
const
|
|
636
|
-
if (
|
|
640
|
+
const r = this.resolvedType;
|
|
641
|
+
if (r === 'object')
|
|
637
642
|
return 'object';
|
|
638
|
-
if (
|
|
643
|
+
if (r === 'array')
|
|
639
644
|
return 'array';
|
|
640
645
|
return 'primitive';
|
|
641
646
|
}
|
|
@@ -671,12 +676,8 @@ class JsonSchemaNodeComponent {
|
|
|
671
676
|
get controlAsArray() { return this.control; }
|
|
672
677
|
get arrayControls() { return this.controlAsArray.controls; }
|
|
673
678
|
get objectKeys() { return Object.keys(this.controlAsGroup.controls); }
|
|
674
|
-
get simpleKeys() {
|
|
675
|
-
|
|
676
|
-
}
|
|
677
|
-
get complexKeys() {
|
|
678
|
-
return this.objectKeys.filter(k => !this.isSimpleChild(k));
|
|
679
|
-
}
|
|
679
|
+
get simpleKeys() { return this.objectKeys.filter(k => this.isSimpleChild(k)); }
|
|
680
|
+
get complexKeys() { return this.objectKeys.filter(k => !this.isSimpleChild(k)); }
|
|
680
681
|
get canAddProperty() {
|
|
681
682
|
if (!this.allowAdditionalProperties)
|
|
682
683
|
return false;
|
|
@@ -684,25 +685,25 @@ class JsonSchemaNodeComponent {
|
|
|
684
685
|
}
|
|
685
686
|
get errorsForPath() { return this.errorsMap.get(this.path) ?? []; }
|
|
686
687
|
get metaBadges() {
|
|
687
|
-
const
|
|
688
|
+
const b = [];
|
|
688
689
|
if (this.effectiveSchema.deprecated)
|
|
689
|
-
|
|
690
|
+
b.push('Deprecated');
|
|
690
691
|
if (this.effectiveSchema.readOnly)
|
|
691
|
-
|
|
692
|
+
b.push('Read-only');
|
|
692
693
|
if (this.effectiveSchema.writeOnly)
|
|
693
|
-
|
|
694
|
+
b.push('Write-only');
|
|
694
695
|
if (this.effectiveSchema.nullable)
|
|
695
|
-
|
|
696
|
+
b.push('Nullable');
|
|
696
697
|
if (this.effectiveSchema.not)
|
|
697
|
-
|
|
698
|
-
return
|
|
698
|
+
b.push('Not constraint');
|
|
699
|
+
return b;
|
|
699
700
|
}
|
|
700
701
|
get activeVariant() {
|
|
701
702
|
if (this.schema.oneOf?.length)
|
|
702
703
|
return this.schema.oneOf[this.selectedOneOf] ?? null;
|
|
703
704
|
if (this.schema.anyOf?.length) {
|
|
704
|
-
const
|
|
705
|
-
return
|
|
705
|
+
const sel = Array.from(this.selectedAnyOf).map(i => this.schema.anyOf[i]);
|
|
706
|
+
return sel.length ? this.mergeSchemas(sel) : this.schema.anyOf[0] ?? null;
|
|
706
707
|
}
|
|
707
708
|
if (this.schema.allOf?.length)
|
|
708
709
|
return this.mergeSchemas([this.schema, ...this.schema.allOf]);
|
|
@@ -713,9 +714,7 @@ class JsonSchemaNodeComponent {
|
|
|
713
714
|
}
|
|
714
715
|
isRequired(key) { return this.effectiveSchema.required?.includes(key) ?? false; }
|
|
715
716
|
schemaForKey(key) {
|
|
716
|
-
return
|
|
717
|
-
this.schemaService.resolveDynamicSchema(this.effectiveSchema, key) ??
|
|
718
|
-
{});
|
|
717
|
+
return this.effectiveSchema.properties?.[key] ?? this.schemaService.resolveDynamicSchema(this.effectiveSchema, key) ?? {};
|
|
719
718
|
}
|
|
720
719
|
isDynamicKey(key) { return !this.effectiveSchema.properties?.[key]; }
|
|
721
720
|
pathForChild(key) {
|
|
@@ -729,8 +728,7 @@ class JsonSchemaNodeComponent {
|
|
|
729
728
|
return;
|
|
730
729
|
}
|
|
731
730
|
if (this.effectiveSchema.propertyNames) {
|
|
732
|
-
|
|
733
|
-
if (nameErrors.length) {
|
|
731
|
+
if (this.validation.validate(this.effectiveSchema.propertyNames, key).length) {
|
|
734
732
|
this.propertyError = 'Property name does not match schema constraints.';
|
|
735
733
|
return;
|
|
736
734
|
}
|
|
@@ -739,20 +737,19 @@ class JsonSchemaNodeComponent {
|
|
|
739
737
|
this.propertyError = 'Property already exists.';
|
|
740
738
|
return;
|
|
741
739
|
}
|
|
742
|
-
const
|
|
743
|
-
if (!
|
|
740
|
+
const s = this.schemaService.resolveDynamicSchema(this.effectiveSchema, key);
|
|
741
|
+
if (!s) {
|
|
744
742
|
this.propertyError = 'This property is not allowed by the schema.';
|
|
745
743
|
return;
|
|
746
744
|
}
|
|
747
|
-
|
|
748
|
-
this.controlAsGroup.addControl(key, control);
|
|
745
|
+
this.controlAsGroup.addControl(key, this.schemaService.buildControl(s, undefined, false));
|
|
749
746
|
this.newPropertyKey = '';
|
|
750
747
|
}
|
|
751
748
|
removeDynamicKey(key) { this.controlAsGroup.removeControl(key); }
|
|
752
749
|
schemaForIndex(index) {
|
|
753
|
-
const
|
|
754
|
-
if (
|
|
755
|
-
return
|
|
750
|
+
const p = this.effectiveSchema.prefixItems ?? [];
|
|
751
|
+
if (p[index])
|
|
752
|
+
return p[index];
|
|
756
753
|
if (this.effectiveSchema.items && this.effectiveSchema.items !== true)
|
|
757
754
|
return this.effectiveSchema.items;
|
|
758
755
|
if (this.effectiveSchema.additionalItems && this.effectiveSchema.additionalItems !== true)
|
|
@@ -762,17 +759,14 @@ class JsonSchemaNodeComponent {
|
|
|
762
759
|
return {};
|
|
763
760
|
}
|
|
764
761
|
get canAddArrayItem() {
|
|
765
|
-
return !(this.effectiveSchema.items === false ||
|
|
766
|
-
this.effectiveSchema.additionalItems === false ||
|
|
767
|
-
this.effectiveSchema.unevaluatedItems === false);
|
|
762
|
+
return !(this.effectiveSchema.items === false || this.effectiveSchema.additionalItems === false || this.effectiveSchema.unevaluatedItems === false);
|
|
768
763
|
}
|
|
769
764
|
addArrayItem() {
|
|
770
765
|
if (!this.canAddArrayItem)
|
|
771
766
|
return;
|
|
772
|
-
const
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
formArray.markAsDirty();
|
|
767
|
+
const fa = this.controlAsArray;
|
|
768
|
+
fa.push(this.schemaService.buildControl(this.schemaForIndex(fa.length), undefined, false));
|
|
769
|
+
fa.markAsDirty();
|
|
776
770
|
}
|
|
777
771
|
removeArrayItem(index) {
|
|
778
772
|
this.controlAsArray.removeAt(index);
|
|
@@ -788,9 +782,9 @@ class JsonSchemaNodeComponent {
|
|
|
788
782
|
this.selectedAnyOf.delete(index);
|
|
789
783
|
else
|
|
790
784
|
this.selectedAnyOf.add(index);
|
|
791
|
-
const
|
|
792
|
-
if (
|
|
793
|
-
this.replaceControl(this.schemaService.buildControl(
|
|
785
|
+
const v = this.activeVariant;
|
|
786
|
+
if (v)
|
|
787
|
+
this.replaceControl(this.schemaService.buildControl(v, this.control.value, this.required));
|
|
794
788
|
}
|
|
795
789
|
replaceControl(control) {
|
|
796
790
|
if (this.parent) {
|
|
@@ -806,12 +800,12 @@ class JsonSchemaNodeComponent {
|
|
|
806
800
|
}
|
|
807
801
|
childControl(key) { return this.controlAsGroup.get(key); }
|
|
808
802
|
get effectiveSchema() {
|
|
809
|
-
let
|
|
810
|
-
if (
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
return
|
|
803
|
+
let s = this.schema;
|
|
804
|
+
if (s.allOf?.length)
|
|
805
|
+
s = this.mergeSchemas([s, ...s.allOf]);
|
|
806
|
+
s = this.applyConditional(s);
|
|
807
|
+
s = this.applyDependencies(s);
|
|
808
|
+
return s;
|
|
815
809
|
}
|
|
816
810
|
applyConditional(schema) {
|
|
817
811
|
if (!schema.if)
|
|
@@ -827,80 +821,67 @@ class JsonSchemaNodeComponent {
|
|
|
827
821
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
828
822
|
return schema;
|
|
829
823
|
let merged = { ...schema };
|
|
830
|
-
const
|
|
824
|
+
const keys = Object.keys(value);
|
|
831
825
|
if (schema.dependentRequired) {
|
|
832
|
-
for (const
|
|
833
|
-
const
|
|
834
|
-
if (
|
|
835
|
-
merged = this.mergeSchemas([merged, { required }]);
|
|
826
|
+
for (const k of keys) {
|
|
827
|
+
const r = schema.dependentRequired[k];
|
|
828
|
+
if (r?.length)
|
|
829
|
+
merged = this.mergeSchemas([merged, { required: r }]);
|
|
836
830
|
}
|
|
837
831
|
}
|
|
838
832
|
if (schema.dependentSchemas) {
|
|
839
|
-
for (const
|
|
840
|
-
const
|
|
841
|
-
if (
|
|
842
|
-
merged = this.mergeSchemas([merged,
|
|
833
|
+
for (const k of keys) {
|
|
834
|
+
const d = schema.dependentSchemas[k];
|
|
835
|
+
if (d)
|
|
836
|
+
merged = this.mergeSchemas([merged, d]);
|
|
843
837
|
}
|
|
844
838
|
}
|
|
845
839
|
if (schema.dependencies) {
|
|
846
|
-
for (const
|
|
847
|
-
const
|
|
848
|
-
if (Array.isArray(
|
|
849
|
-
merged = this.mergeSchemas([merged, { required:
|
|
850
|
-
else if (
|
|
851
|
-
merged = this.mergeSchemas([merged,
|
|
840
|
+
for (const k of keys) {
|
|
841
|
+
const d = schema.dependencies[k];
|
|
842
|
+
if (Array.isArray(d))
|
|
843
|
+
merged = this.mergeSchemas([merged, { required: d }]);
|
|
844
|
+
else if (d)
|
|
845
|
+
merged = this.mergeSchemas([merged, d]);
|
|
852
846
|
}
|
|
853
847
|
}
|
|
854
848
|
return merged;
|
|
855
849
|
}
|
|
856
850
|
mergeSchemas(schemas) {
|
|
857
|
-
return schemas.reduce((acc,
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
}
|
|
870
|
-
return merged;
|
|
871
|
-
}, {});
|
|
851
|
+
return schemas.reduce((acc, s) => ({
|
|
852
|
+
...acc, ...s,
|
|
853
|
+
properties: { ...(acc.properties ?? {}), ...(s.properties ?? {}) },
|
|
854
|
+
patternProperties: { ...(acc.patternProperties ?? {}), ...(s.patternProperties ?? {}) },
|
|
855
|
+
required: Array.from(new Set([...(acc.required ?? []), ...(s.required ?? [])])),
|
|
856
|
+
...(acc.type && s.type ? {
|
|
857
|
+
type: Array.from(new Set([
|
|
858
|
+
...(Array.isArray(acc.type) ? acc.type : [acc.type]),
|
|
859
|
+
...(Array.isArray(s.type) ? s.type : [s.type]),
|
|
860
|
+
]))
|
|
861
|
+
} : {}),
|
|
862
|
+
}), {});
|
|
872
863
|
}
|
|
873
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: JsonSchemaNodeComponent, deps: [{ token: JsonSchemaFormService }, { token: JsonSchemaValidationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
864
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: JsonSchemaNodeComponent, deps: [{ token: JsonSchemaFormService }, { token: JsonSchemaValidationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
874
865
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: JsonSchemaNodeComponent, isStandalone: true, selector: "jsm-schema-node", inputs: { schema: "schema", control: "control", label: "label", required: "required", path: "path", errorsMap: "errorsMap", parent: "parent", controlKey: "controlKey", allowAdditionalProperties: "allowAdditionalProperties" }, outputs: { controlReplaced: "controlReplaced" }, ngImport: i0, template: `
|
|
875
866
|
<ng-container [ngSwitch]="nodeKind">
|
|
876
867
|
|
|
877
|
-
<!--
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
<div *ngSwitchCase="'oneOf'" class="rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm overflow-hidden">
|
|
881
|
-
<div class="flex items-start justify-between px-4 py-3 bg-slate-50 dark:bg-slate-800/60 border-b border-slate-200 dark:border-slate-700">
|
|
868
|
+
<!-- ═══ oneOf ═══ -->
|
|
869
|
+
<div *ngSwitchCase="'oneOf'" class="jsm-combinator">
|
|
870
|
+
<div class="jsm-combinator-header">
|
|
882
871
|
<div>
|
|
883
|
-
<p class="
|
|
884
|
-
<p *ngIf="schema.description" class="
|
|
872
|
+
<p class="jsm-combinator-title">{{ schema.title || label }}</p>
|
|
873
|
+
<p *ngIf="schema.description" class="jsm-combinator-hint">{{ schema.description }}</p>
|
|
885
874
|
</div>
|
|
886
|
-
<span class="
|
|
875
|
+
<span class="jsm-combinator-badge jsm-badge--oneof">oneOf</span>
|
|
887
876
|
</div>
|
|
888
|
-
<div class="
|
|
889
|
-
<button
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
[class.text-indigo-600]="selectedOneOf === i"
|
|
895
|
-
[class.dark:text-indigo-400]="selectedOneOf === i"
|
|
896
|
-
[class.font-semibold]="selectedOneOf === i"
|
|
897
|
-
[class.border-transparent]="selectedOneOf !== i"
|
|
898
|
-
[class.text-slate-500]="selectedOneOf !== i"
|
|
899
|
-
[class.dark:text-slate-400]="selectedOneOf !== i"
|
|
900
|
-
(click)="selectedOneOf = i; onOneOfChange()"
|
|
901
|
-
>{{ option.title || ('Option ' + (i + 1)) }}</button>
|
|
877
|
+
<div class="jsm-oneof-tabs">
|
|
878
|
+
<button *ngFor="let option of schema.oneOf; let i = index" type="button"
|
|
879
|
+
class="jsm-tab" [class.jsm-tab--active]="selectedOneOf === i"
|
|
880
|
+
(click)="selectedOneOf = i; onOneOfChange()">
|
|
881
|
+
{{ option.title || ('Option ' + (i + 1)) }}
|
|
882
|
+
</button>
|
|
902
883
|
</div>
|
|
903
|
-
<div class="
|
|
884
|
+
<div class="jsm-combinator-body" *ngIf="activeVariant">
|
|
904
885
|
<jsm-schema-node [schema]="activeVariant" [control]="control" [parent]="parent" [controlKey]="controlKey"
|
|
905
886
|
[path]="path" [errorsMap]="errorsMap" [label]="label" [required]="required"
|
|
906
887
|
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
@@ -908,36 +889,23 @@ class JsonSchemaNodeComponent {
|
|
|
908
889
|
</div>
|
|
909
890
|
</div>
|
|
910
891
|
|
|
911
|
-
<!--
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
<div *ngSwitchCase="'anyOf'" class="rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm overflow-hidden">
|
|
915
|
-
<div class="flex items-start justify-between px-4 py-3 bg-slate-50 dark:bg-slate-800/60 border-b border-slate-200 dark:border-slate-700">
|
|
892
|
+
<!-- ═══ anyOf ═══ -->
|
|
893
|
+
<div *ngSwitchCase="'anyOf'" class="jsm-combinator">
|
|
894
|
+
<div class="jsm-combinator-header">
|
|
916
895
|
<div>
|
|
917
|
-
<p class="
|
|
918
|
-
<p *ngIf="schema.description" class="
|
|
896
|
+
<p class="jsm-combinator-title">{{ schema.title || label }}</p>
|
|
897
|
+
<p *ngIf="schema.description" class="jsm-combinator-hint">{{ schema.description }}</p>
|
|
919
898
|
</div>
|
|
920
|
-
<span class="
|
|
899
|
+
<span class="jsm-combinator-badge jsm-badge--anyof">anyOf</span>
|
|
921
900
|
</div>
|
|
922
|
-
<div class="
|
|
923
|
-
<label
|
|
924
|
-
|
|
925
|
-
class="
|
|
926
|
-
[class.border-indigo-400]="selectedAnyOf.has(i)"
|
|
927
|
-
[class.bg-indigo-50]="selectedAnyOf.has(i)"
|
|
928
|
-
[class.dark:bg-indigo-900/30]="selectedAnyOf.has(i)"
|
|
929
|
-
[class.text-indigo-700]="selectedAnyOf.has(i)"
|
|
930
|
-
[class.dark:text-indigo-400]="selectedAnyOf.has(i)"
|
|
931
|
-
[class.border-slate-200]="!selectedAnyOf.has(i)"
|
|
932
|
-
[class.dark:border-slate-600]="!selectedAnyOf.has(i)"
|
|
933
|
-
[class.text-slate-600]="!selectedAnyOf.has(i)"
|
|
934
|
-
[class.dark:text-slate-400]="!selectedAnyOf.has(i)"
|
|
935
|
-
>
|
|
936
|
-
<input type="checkbox" class="h-3.5 w-3.5 accent-indigo-600" [checked]="selectedAnyOf.has(i)" (change)="toggleAnyOf(i)" />
|
|
901
|
+
<div class="jsm-anyof-options">
|
|
902
|
+
<label *ngFor="let option of schema.anyOf; let i = index"
|
|
903
|
+
class="jsm-anyof-option" [class.jsm-anyof-option--active]="selectedAnyOf.has(i)">
|
|
904
|
+
<input type="checkbox" class="sr-only" [checked]="selectedAnyOf.has(i)" (change)="toggleAnyOf(i)" />
|
|
937
905
|
{{ option.title || ('Option ' + (i + 1)) }}
|
|
938
906
|
</label>
|
|
939
907
|
</div>
|
|
940
|
-
<div class="
|
|
908
|
+
<div class="jsm-combinator-body" *ngIf="activeVariant">
|
|
941
909
|
<jsm-schema-node [schema]="activeVariant" [control]="control" [parent]="parent" [controlKey]="controlKey"
|
|
942
910
|
[path]="path" [errorsMap]="errorsMap" [label]="label" [required]="required"
|
|
943
911
|
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
@@ -945,19 +913,17 @@ class JsonSchemaNodeComponent {
|
|
|
945
913
|
</div>
|
|
946
914
|
</div>
|
|
947
915
|
|
|
948
|
-
<!--
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
<div *ngSwitchCase="'allOf'" class="rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm overflow-hidden">
|
|
952
|
-
<div class="flex items-start justify-between px-4 py-3 bg-slate-50 dark:bg-slate-800/60 border-b border-slate-200 dark:border-slate-700">
|
|
916
|
+
<!-- ═══ allOf ═══ -->
|
|
917
|
+
<div *ngSwitchCase="'allOf'" class="jsm-combinator">
|
|
918
|
+
<div class="jsm-combinator-header">
|
|
953
919
|
<div>
|
|
954
|
-
<p class="
|
|
955
|
-
<p *ngIf="schema.description" class="
|
|
920
|
+
<p class="jsm-combinator-title">{{ schema.title || label }}</p>
|
|
921
|
+
<p *ngIf="schema.description" class="jsm-combinator-hint">{{ schema.description }}</p>
|
|
956
922
|
</div>
|
|
957
|
-
<span class="
|
|
923
|
+
<span class="jsm-combinator-badge jsm-badge--allof">allOf</span>
|
|
958
924
|
</div>
|
|
959
|
-
<div class="
|
|
960
|
-
<div *ngFor="let subSchema of mergedAllOf; let i = index" class="
|
|
925
|
+
<div class="jsm-combinator-body">
|
|
926
|
+
<div *ngFor="let subSchema of mergedAllOf; let i = index" class="jsm-allof-section">
|
|
961
927
|
<jsm-schema-node [schema]="subSchema" [control]="control" [parent]="parent" [controlKey]="controlKey"
|
|
962
928
|
[path]="path" [errorsMap]="errorsMap" [label]="subSchema.title || ('Section ' + (i + 1))" [required]="required"
|
|
963
929
|
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
@@ -966,145 +932,95 @@ class JsonSchemaNodeComponent {
|
|
|
966
932
|
</div>
|
|
967
933
|
</div>
|
|
968
934
|
|
|
969
|
-
<!--
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
o "complessi" (object/array/oneOf/anyOf/allOf).
|
|
974
|
-
- I semplici vanno in griglia 2 colonne (sm:grid-cols-2).
|
|
975
|
-
- I complessi vanno sempre in colonna piena (col-span-2).
|
|
976
|
-
═══════════════════════════════════════════════════════════ -->
|
|
977
|
-
<fieldset *ngSwitchCase="'object'" class="rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm p-4 transition-shadow focus-within:border-indigo-300 dark:focus-within:border-indigo-600 focus-within:ring-2 focus-within:ring-indigo-100 dark:focus-within:ring-indigo-900/40">
|
|
978
|
-
<legend class="px-2 text-sm font-bold text-slate-800 dark:text-slate-200">{{ schema.title || label }}</legend>
|
|
935
|
+
<!-- ═══ object ═══ -->
|
|
936
|
+
<fieldset *ngSwitchCase="'object'" class="jsm-fieldset">
|
|
937
|
+
<legend class="jsm-legend">{{ schema.title || label }}</legend>
|
|
938
|
+
<p *ngIf="schema.description" class="jsm-field-hint" style="margin-bottom:.75rem;margin-top:.25rem;">{{ schema.description }}</p>
|
|
979
939
|
|
|
980
|
-
<
|
|
981
|
-
|
|
982
|
-
<div *ngIf="metaBadges.length" class="flex flex-wrap gap-1.5 mb-3">
|
|
983
|
-
<span *ngFor="let badge of metaBadges"
|
|
984
|
-
class="rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide"
|
|
985
|
-
[ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
940
|
+
<div *ngIf="metaBadges.length" class="jsm-badge-row" style="margin-bottom:.75rem;">
|
|
941
|
+
<span *ngFor="let badge of metaBadges" class="jsm-badge" [ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
986
942
|
</div>
|
|
987
943
|
|
|
988
|
-
|
|
989
|
-
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4" [formGroup]="controlAsGroup">
|
|
944
|
+
<div class="jsm-obj-grid" [formGroup]="controlAsGroup">
|
|
990
945
|
<ng-container *ngFor="let key of simpleKeys">
|
|
991
|
-
<div
|
|
992
|
-
<div *ngIf="isDynamicKey(key)"
|
|
993
|
-
class="
|
|
994
|
-
<
|
|
995
|
-
<button type="button"
|
|
996
|
-
class="rounded px-1.5 py-0.5 text-xs font-semibold text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
|
|
997
|
-
(click)="removeDynamicKey(key)">Remove</button>
|
|
946
|
+
<div style="display:flex;flex-direction:column;gap:.25rem;">
|
|
947
|
+
<div *ngIf="isDynamicKey(key)" class="jsm-dynamic-key-header">
|
|
948
|
+
<span class="jsm-dynamic-key-label">{{ key }}</span>
|
|
949
|
+
<button type="button" class="jsm-btn-danger" (click)="removeDynamicKey(key)">Remove</button>
|
|
998
950
|
</div>
|
|
999
|
-
<jsm-schema-node
|
|
1000
|
-
[
|
|
1001
|
-
[
|
|
1002
|
-
|
|
1003
|
-
[controlKey]="key"
|
|
1004
|
-
[path]="pathForChild(key)"
|
|
1005
|
-
[errorsMap]="errorsMap"
|
|
1006
|
-
[label]="key"
|
|
1007
|
-
[required]="isRequired(key)"
|
|
1008
|
-
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
1009
|
-
(controlReplaced)="controlReplaced.emit($event)">
|
|
1010
|
-
</jsm-schema-node>
|
|
951
|
+
<jsm-schema-node [schema]="schemaForKey(key)" [control]="childControl(key)" [parent]="controlAsGroup"
|
|
952
|
+
[controlKey]="key" [path]="pathForChild(key)" [errorsMap]="errorsMap" [label]="key"
|
|
953
|
+
[required]="isRequired(key)" [allowAdditionalProperties]="allowAdditionalProperties"
|
|
954
|
+
(controlReplaced)="controlReplaced.emit($event)"></jsm-schema-node>
|
|
1011
955
|
</div>
|
|
1012
956
|
</ng-container>
|
|
1013
957
|
</div>
|
|
1014
958
|
|
|
1015
|
-
|
|
1016
|
-
<div class="space-y-4 mt-4" *ngIf="complexKeys.length > 0" [formGroup]="controlAsGroup">
|
|
959
|
+
<div class="jsm-obj-complex" *ngIf="complexKeys.length > 0" [formGroup]="controlAsGroup">
|
|
1017
960
|
<ng-container *ngFor="let key of complexKeys">
|
|
1018
|
-
<div
|
|
1019
|
-
<div *ngIf="isDynamicKey(key)"
|
|
1020
|
-
class="
|
|
1021
|
-
<
|
|
1022
|
-
<button type="button"
|
|
1023
|
-
class="rounded px-1.5 py-0.5 text-xs font-semibold text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
|
|
1024
|
-
(click)="removeDynamicKey(key)">Remove</button>
|
|
961
|
+
<div style="display:flex;flex-direction:column;gap:.25rem;">
|
|
962
|
+
<div *ngIf="isDynamicKey(key)" class="jsm-dynamic-key-header">
|
|
963
|
+
<span class="jsm-dynamic-key-label">{{ key }}</span>
|
|
964
|
+
<button type="button" class="jsm-btn-danger" (click)="removeDynamicKey(key)">Remove</button>
|
|
1025
965
|
</div>
|
|
1026
|
-
<jsm-schema-node
|
|
1027
|
-
[
|
|
1028
|
-
[
|
|
1029
|
-
|
|
1030
|
-
[controlKey]="key"
|
|
1031
|
-
[path]="pathForChild(key)"
|
|
1032
|
-
[errorsMap]="errorsMap"
|
|
1033
|
-
[label]="key"
|
|
1034
|
-
[required]="isRequired(key)"
|
|
1035
|
-
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
1036
|
-
(controlReplaced)="controlReplaced.emit($event)">
|
|
1037
|
-
</jsm-schema-node>
|
|
966
|
+
<jsm-schema-node [schema]="schemaForKey(key)" [control]="childControl(key)" [parent]="controlAsGroup"
|
|
967
|
+
[controlKey]="key" [path]="pathForChild(key)" [errorsMap]="errorsMap" [label]="key"
|
|
968
|
+
[required]="isRequired(key)" [allowAdditionalProperties]="allowAdditionalProperties"
|
|
969
|
+
(controlReplaced)="controlReplaced.emit($event)"></jsm-schema-node>
|
|
1038
970
|
</div>
|
|
1039
971
|
</ng-container>
|
|
1040
972
|
</div>
|
|
1041
973
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
<
|
|
1045
|
-
|
|
1046
|
-
<
|
|
1047
|
-
class="flex-1 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100 placeholder:text-slate-400 dark:placeholder:text-slate-500 px-3 py-1.5 text-sm shadow-sm outline-none transition hover:border-slate-400 dark:hover:border-slate-500 focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100 dark:focus:ring-indigo-900/40"
|
|
1048
|
-
[(ngModel)]="newPropertyKey" placeholder="propertyName" />
|
|
1049
|
-
<button type="button"
|
|
1050
|
-
class="rounded-lg bg-indigo-600 px-3 py-1.5 text-sm font-semibold text-white shadow-sm transition hover:bg-indigo-700 active:scale-95"
|
|
1051
|
-
(click)="addDynamicProperty()">Add</button>
|
|
974
|
+
<div *ngIf="canAddProperty" class="jsm-add-prop">
|
|
975
|
+
<p class="jsm-add-prop-label">Add property</p>
|
|
976
|
+
<div class="jsm-add-prop-row">
|
|
977
|
+
<input class="jsm-input jsm-input--sm" style="flex:1;" [(ngModel)]="newPropertyKey" placeholder="propertyName" />
|
|
978
|
+
<button type="button" class="jsm-btn-primary" (click)="addDynamicProperty()">Add</button>
|
|
1052
979
|
</div>
|
|
1053
|
-
<p *ngIf="propertyError" class="
|
|
1054
|
-
|
|
1055
|
-
<svg class="w-3.5 h-3.5 shrink-0" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/><path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
980
|
+
<p *ngIf="propertyError" class="jsm-error-msg">
|
|
981
|
+
<svg class="jsm-error-icon" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/><path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1056
982
|
{{ propertyError }}
|
|
1057
983
|
</p>
|
|
1058
984
|
</div>
|
|
1059
985
|
|
|
1060
|
-
<div *ngIf="errorsForPath.length" class="
|
|
1061
|
-
<p *ngFor="let error of errorsForPath" class="
|
|
1062
|
-
<svg class="
|
|
986
|
+
<div *ngIf="errorsForPath.length" class="jsm-error-list" style="margin-top:.75rem;">
|
|
987
|
+
<p *ngFor="let error of errorsForPath" class="jsm-error-msg">
|
|
988
|
+
<svg class="jsm-error-icon" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/><path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1063
989
|
{{ error }}
|
|
1064
990
|
</p>
|
|
1065
991
|
</div>
|
|
1066
992
|
</fieldset>
|
|
1067
993
|
|
|
1068
|
-
<!--
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
<div *ngSwitchCase="'array'" class="space-y-3">
|
|
1072
|
-
<div class="flex items-start justify-between gap-2">
|
|
994
|
+
<!-- ═══ array ═══ -->
|
|
995
|
+
<div *ngSwitchCase="'array'" class="jsm-array-block">
|
|
996
|
+
<div class="jsm-array-header">
|
|
1073
997
|
<div>
|
|
1074
|
-
<p class="
|
|
1075
|
-
{{ schema.title || label }}<span *ngIf="required"
|
|
998
|
+
<p class="jsm-array-title">
|
|
999
|
+
{{ schema.title || label }}<span *ngIf="required" style="color:#ef4444;margin-left:.125rem;">*</span>
|
|
1076
1000
|
</p>
|
|
1077
|
-
<p *ngIf="schema.description" class="
|
|
1001
|
+
<p *ngIf="schema.description" class="jsm-field-hint">{{ schema.description }}</p>
|
|
1078
1002
|
</div>
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
class="shrink-0 flex items-center gap-1 rounded-lg bg-indigo-600 px-3 py-1.5 text-xs font-semibold text-white shadow-sm transition hover:bg-indigo-700 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed"
|
|
1082
|
-
(click)="addArrayItem()" [disabled]="!canAddArrayItem">
|
|
1083
|
-
<svg class="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1003
|
+
<button type="button" class="jsm-btn-primary" (click)="addArrayItem()" [disabled]="!canAddArrayItem">
|
|
1004
|
+
<svg style="width:.875rem;height:.875rem;flex-shrink:0;" viewBox="0 0 16 16" fill="none"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1084
1005
|
Add item
|
|
1085
1006
|
</button>
|
|
1086
1007
|
</div>
|
|
1087
1008
|
|
|
1088
|
-
<div *ngIf="effectiveSchema.contains" class="
|
|
1009
|
+
<div *ngIf="effectiveSchema.contains" class="jsm-contains-hint">
|
|
1089
1010
|
Must contain matching item(s)
|
|
1090
1011
|
<span *ngIf="effectiveSchema.minContains"> · min {{ effectiveSchema.minContains }}</span>
|
|
1091
1012
|
<span *ngIf="effectiveSchema.maxContains"> · max {{ effectiveSchema.maxContains }}</span>
|
|
1092
1013
|
</div>
|
|
1093
1014
|
|
|
1094
|
-
<div *ngIf="metaBadges.length" class="
|
|
1095
|
-
<span *ngFor="let badge of metaBadges"
|
|
1096
|
-
class="rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide"
|
|
1097
|
-
[ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1015
|
+
<div *ngIf="metaBadges.length" class="jsm-badge-row">
|
|
1016
|
+
<span *ngFor="let badge of metaBadges" class="jsm-badge" [ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1098
1017
|
</div>
|
|
1099
1018
|
|
|
1100
|
-
<div class="
|
|
1101
|
-
<div *ngFor="let item of arrayControls; let i = index"
|
|
1102
|
-
class="
|
|
1103
|
-
|
|
1104
|
-
<
|
|
1105
|
-
<button type="button"
|
|
1106
|
-
class="rounded-md border border-red-200 dark:border-red-800 px-2 py-0.5 text-xs font-semibold text-red-600 dark:text-red-400 transition hover:bg-red-50 dark:hover:bg-red-900/20"
|
|
1107
|
-
(click)="removeArrayItem(i)">Remove</button>
|
|
1019
|
+
<div class="jsm-array-items" *ngIf="arrayControls.length > 0; else emptyArray">
|
|
1020
|
+
<div *ngFor="let item of arrayControls; let i = index" class="jsm-array-item">
|
|
1021
|
+
<div class="jsm-array-item-header">
|
|
1022
|
+
<span class="jsm-array-index">{{ i + 1 }}</span>
|
|
1023
|
+
<button type="button" class="jsm-btn-danger" (click)="removeArrayItem(i)">Remove</button>
|
|
1108
1024
|
</div>
|
|
1109
1025
|
<jsm-schema-node [schema]="schemaForIndex(i)" [control]="item" [parent]="controlAsArray"
|
|
1110
1026
|
[controlKey]="i" [path]="pathForChild(i)" [errorsMap]="errorsMap" [label]="label + ' item'"
|
|
@@ -1114,124 +1030,72 @@ class JsonSchemaNodeComponent {
|
|
|
1114
1030
|
</div>
|
|
1115
1031
|
|
|
1116
1032
|
<ng-template #emptyArray>
|
|
1117
|
-
<div class="
|
|
1118
|
-
No items yet — click "Add item" to start.
|
|
1119
|
-
</div>
|
|
1033
|
+
<div class="jsm-empty-array">No items yet — click "Add item" to start.</div>
|
|
1120
1034
|
</ng-template>
|
|
1121
1035
|
|
|
1122
|
-
<div *ngIf="errorsForPath.length" class="
|
|
1123
|
-
<p *ngFor="let error of errorsForPath" class="
|
|
1124
|
-
<svg class="
|
|
1036
|
+
<div *ngIf="errorsForPath.length" class="jsm-error-list">
|
|
1037
|
+
<p *ngFor="let error of errorsForPath" class="jsm-error-msg">
|
|
1038
|
+
<svg class="jsm-error-icon" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/><path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1125
1039
|
{{ error }}
|
|
1126
1040
|
</p>
|
|
1127
1041
|
</div>
|
|
1128
1042
|
</div>
|
|
1129
1043
|
|
|
1130
|
-
<!--
|
|
1131
|
-
|
|
1132
|
-
Icona errore solo nei messaggi di validazione.
|
|
1133
|
-
Icona chevron nel select: funzionale (indica dropdown).
|
|
1134
|
-
═══════════════════════════════════════════════════════════ -->
|
|
1135
|
-
<div *ngSwitchDefault class="space-y-1.5">
|
|
1044
|
+
<!-- ═══ primitive ═══ -->
|
|
1045
|
+
<div *ngSwitchDefault class="jsm-field">
|
|
1136
1046
|
<ng-container *ngIf="inputKind !== 'checkbox'">
|
|
1137
|
-
<label class="
|
|
1138
|
-
{{ schema.title || label }}<span *ngIf="required" class="
|
|
1047
|
+
<label class="jsm-field-label">
|
|
1048
|
+
{{ schema.title || label }}<span *ngIf="required" class="jsm-required">*</span>
|
|
1139
1049
|
</label>
|
|
1140
|
-
<p *ngIf="schema.description" class="
|
|
1050
|
+
<p *ngIf="schema.description" class="jsm-field-hint">{{ schema.description }}</p>
|
|
1141
1051
|
</ng-container>
|
|
1142
1052
|
|
|
1143
|
-
<div *ngIf="metaBadges.length" class="
|
|
1144
|
-
<span *ngFor="let badge of metaBadges"
|
|
1145
|
-
class="rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide"
|
|
1146
|
-
[ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1053
|
+
<div *ngIf="metaBadges.length" class="jsm-badge-row">
|
|
1054
|
+
<span *ngFor="let badge of metaBadges" class="jsm-badge" [ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1147
1055
|
</div>
|
|
1148
1056
|
|
|
1149
1057
|
<ng-container [ngSwitch]="inputKind">
|
|
1058
|
+
<input *ngSwitchCase="'text'" class="jsm-input"
|
|
1059
|
+
[class.jsm-input--error]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1060
|
+
[attr.type]="inputType" [attr.placeholder]="schema.title || label"
|
|
1061
|
+
[formControl]="controlAsFormControl" />
|
|
1150
1062
|
|
|
1151
|
-
<
|
|
1152
|
-
class="
|
|
1153
|
-
[class.border-slate-300]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1154
|
-
[class.dark:border-slate-600]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1155
|
-
[class.focus:border-indigo-400]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1156
|
-
[class.focus:ring-indigo-100]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1157
|
-
[class.dark:focus:ring-indigo-900/40]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1158
|
-
[class.border-red-300]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1159
|
-
[class.dark:border-red-700]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1160
|
-
[class.bg-red-50]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1161
|
-
[class.dark:bg-red-900/20]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1162
|
-
[class.focus:border-red-400]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1163
|
-
[class.focus:ring-red-100]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1164
|
-
[attr.type]="inputType"
|
|
1165
|
-
[attr.placeholder]="schema.title || label"
|
|
1166
|
-
[formControl]="controlAsFormControl"
|
|
1167
|
-
/>
|
|
1168
|
-
|
|
1169
|
-
<textarea *ngSwitchCase="'textarea'" rows="4"
|
|
1170
|
-
class="w-full resize-y rounded-lg border bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100 placeholder:text-slate-400 dark:placeholder:text-slate-500 px-3 py-2 text-sm shadow-sm outline-none transition hover:border-slate-400 dark:hover:border-slate-500 focus:ring-2"
|
|
1171
|
-
[class.border-slate-300]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1172
|
-
[class.dark:border-slate-600]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1173
|
-
[class.focus:border-indigo-400]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1174
|
-
[class.focus:ring-indigo-100]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1175
|
-
[class.dark:focus:ring-indigo-900/40]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1176
|
-
[class.border-red-300]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1177
|
-
[class.dark:border-red-700]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1178
|
-
[class.bg-red-50]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1179
|
-
[class.dark:bg-red-900/20]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1180
|
-
[class.focus:border-red-400]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1181
|
-
[class.focus:ring-red-100]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1063
|
+
<textarea *ngSwitchCase="'textarea'" rows="4" class="jsm-textarea"
|
|
1064
|
+
[class.jsm-textarea--error]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1182
1065
|
[attr.placeholder]="schema.title || label"
|
|
1183
|
-
[formControl]="controlAsFormControl"
|
|
1184
|
-
></textarea>
|
|
1066
|
+
[formControl]="controlAsFormControl"></textarea>
|
|
1185
1067
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
class="w-full appearance-none rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100 px-3 py-2 pr-8 text-sm shadow-sm outline-none transition hover:border-slate-400 dark:hover:border-slate-500 focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100 dark:focus:ring-indigo-900/40"
|
|
1190
|
-
[class.border-red-300]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1191
|
-
[class.dark:border-red-700]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1192
|
-
[class.bg-red-50]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1193
|
-
[class.dark:bg-red-900/20]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1068
|
+
<div *ngSwitchCase="'select'" class="jsm-select-wrap">
|
|
1069
|
+
<select class="jsm-select"
|
|
1070
|
+
[class.jsm-select--error]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1194
1071
|
[formControl]="controlAsFormControl">
|
|
1195
1072
|
<option *ngFor="let option of effectiveSchema.enum" [ngValue]="option">{{ option }}</option>
|
|
1196
1073
|
</select>
|
|
1197
|
-
<svg class="
|
|
1198
|
-
viewBox="0 0 16 16" fill="none">
|
|
1074
|
+
<svg class="jsm-select-chevron" viewBox="0 0 16 16" fill="none">
|
|
1199
1075
|
<path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1200
1076
|
</svg>
|
|
1201
1077
|
</div>
|
|
1202
1078
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
<span class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors"
|
|
1206
|
-
[class.bg-indigo-600]="controlAsFormControl.value"
|
|
1207
|
-
[class.bg-slate-300]="!controlAsFormControl.value"
|
|
1208
|
-
[class.dark:bg-slate-600]="!controlAsFormControl.value">
|
|
1079
|
+
<label *ngSwitchCase="'checkbox'" class="jsm-toggle-label">
|
|
1080
|
+
<span class="jsm-toggle-track" [class.jsm-on]="controlAsFormControl.value">
|
|
1209
1081
|
<input type="checkbox" class="sr-only" [formControl]="controlAsFormControl" />
|
|
1210
|
-
<span class="
|
|
1211
|
-
[class.translate-x-4]="controlAsFormControl.value"
|
|
1212
|
-
[class.translate-x-0.5]="!controlAsFormControl.value"></span>
|
|
1082
|
+
<span class="jsm-toggle-thumb"></span>
|
|
1213
1083
|
</span>
|
|
1214
|
-
<span class="
|
|
1215
|
-
{{ schema.title || label }}<span *ngIf="required" class="
|
|
1084
|
+
<span class="jsm-toggle-text">
|
|
1085
|
+
{{ schema.title || label }}<span *ngIf="required" class="jsm-required">*</span>
|
|
1216
1086
|
</span>
|
|
1217
1087
|
</label>
|
|
1218
|
-
|
|
1219
1088
|
</ng-container>
|
|
1220
1089
|
|
|
1221
|
-
<p *ngIf="inputKind === 'checkbox' && schema.description" class="
|
|
1222
|
-
|
|
1223
|
-
<p *ngIf="effectiveSchema.
|
|
1224
|
-
e.g. {{ effectiveSchema.examples?.[0] }}
|
|
1225
|
-
</p>
|
|
1226
|
-
|
|
1227
|
-
<p *ngIf="effectiveSchema.contentMediaType" class="text-[11px] text-slate-400 dark:text-slate-500">
|
|
1090
|
+
<p *ngIf="inputKind === 'checkbox' && schema.description" class="jsm-field-hint">{{ schema.description }}</p>
|
|
1091
|
+
<p *ngIf="effectiveSchema.examples?.length" class="jsm-example">e.g. {{ effectiveSchema.examples?.[0] }}</p>
|
|
1092
|
+
<p *ngIf="effectiveSchema.contentMediaType" class="jsm-example">
|
|
1228
1093
|
{{ effectiveSchema.contentMediaType }}<span *ngIf="effectiveSchema.contentEncoding"> ({{ effectiveSchema.contentEncoding }})</span>
|
|
1229
1094
|
</p>
|
|
1230
1095
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
<svg class="w-3.5 h-3.5 shrink-0" viewBox="0 0 16 16" fill="none">
|
|
1096
|
+
<div *ngIf="errorsForPath.length && controlAsFormControl.dirty" class="jsm-error-list">
|
|
1097
|
+
<p *ngFor="let error of errorsForPath" class="jsm-error-msg">
|
|
1098
|
+
<svg class="jsm-error-icon" viewBox="0 0 16 16" fill="none">
|
|
1235
1099
|
<circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/>
|
|
1236
1100
|
<path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
1237
1101
|
</svg>
|
|
@@ -1241,45 +1105,30 @@ class JsonSchemaNodeComponent {
|
|
|
1241
1105
|
</div>
|
|
1242
1106
|
|
|
1243
1107
|
</ng-container>
|
|
1244
|
-
`, isInline: true, dependencies: [{ kind: "component", type: JsonSchemaNodeComponent, selector: "jsm-schema-node", inputs: ["schema", "control", "label", "required", "path", "errorsMap", "parent", "controlKey", "allowAdditionalProperties"], outputs: ["controlReplaced"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1108
|
+
`, isInline: true, styles: [".jsm-field{display:flex;flex-direction:column;gap:.375rem}.jsm-field-label{display:block;font-size:.8125rem;font-weight:600;color:#374151}.jsm-field-hint{font-size:.75rem;color:#6b7280;margin:0;line-height:1.4}.jsm-required{color:#ef4444;margin-left:.125rem}.jsm-example{font-size:.6875rem;color:#9ca3af}.jsm-input,.jsm-textarea,.jsm-select{width:100%;border-radius:.5rem;border:1.5px solid #d1d5db;background:Canvas;padding:.5rem .75rem;font-size:.875rem;color:CanvasText;outline:none;box-shadow:0 1px 2px #0000000a;transition:border-color .15s,box-shadow .15s;font-family:inherit;box-sizing:border-box}.jsm-input:hover,.jsm-textarea:hover,.jsm-select:hover{border-color:#9ca3af}.jsm-input:focus,.jsm-textarea:focus,.jsm-select:focus{border-color:#6366f1;box-shadow:0 0 0 3px #6366f126}.jsm-input--error,.jsm-textarea--error,.jsm-select--error{border-color:#f87171!important;background:#fff5f5}.jsm-input--error:focus,.jsm-textarea--error:focus,.jsm-select--error:focus{box-shadow:0 0 0 3px #f8717133!important}.jsm-textarea{resize:vertical;min-height:6rem}.jsm-select-wrap{position:relative}.jsm-select{appearance:none;padding-right:2.25rem;cursor:pointer}.jsm-select-chevron{position:absolute;right:.625rem;top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:#9ca3af;pointer-events:none}.jsm-toggle-label{display:inline-flex;align-items:center;gap:.625rem;cursor:pointer;-webkit-user-select:none;user-select:none}.jsm-toggle-track{position:relative;display:inline-flex;align-items:center;width:2.25rem;height:1.25rem;border-radius:9999px;flex-shrink:0;background:#d1d5db;transition:background .2s}.jsm-toggle-track.jsm-on{background:#4f46e5}.jsm-toggle-thumb{display:inline-block;width:1rem;height:1rem;border-radius:9999px;background:#fff;box-shadow:0 1px 3px #0003;transform:translate(.125rem);transition:transform .2s}.jsm-toggle-track.jsm-on .jsm-toggle-thumb{transform:translate(1.125rem)}.jsm-toggle-text{font-size:.875rem;font-weight:500;color:#374151}.jsm-btn-primary{display:inline-flex;align-items:center;gap:.25rem;padding:.375rem .75rem;border-radius:.5rem;font-size:.8125rem;font-weight:600;background:#4f46e5;color:#fff;border:none;cursor:pointer;box-shadow:0 1px 2px #4f46e54d;transition:background .15s,transform .1s,box-shadow .15s;white-space:nowrap;font-family:inherit}.jsm-btn-primary:hover{background:#4338ca;transform:translateY(-1px);box-shadow:0 3px 8px #4f46e54d}.jsm-btn-primary:active{transform:translateY(0)}.jsm-btn-primary:disabled{opacity:.45;cursor:not-allowed;transform:none}.jsm-btn-danger{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:.375rem;font-size:.75rem;font-weight:600;background:transparent;color:#dc2626;border:1.5px solid #fca5a5;cursor:pointer;transition:background .15s,border-color .15s;font-family:inherit}.jsm-btn-danger:hover{background:#fee2e2;border-color:#f87171}.jsm-error-list{display:flex;flex-direction:column;gap:.25rem;margin-top:.25rem}.jsm-error-msg{display:flex;align-items:center;gap:.375rem;font-size:.75rem;color:#dc2626;font-weight:500}.jsm-error-icon{width:.875rem;height:.875rem;flex-shrink:0}.jsm-badge-row{display:flex;flex-wrap:wrap;gap:.375rem}.jsm-badge{display:inline-flex;align-items:center;border-radius:9999px;padding:.125rem .5rem;font-size:.6875rem;font-weight:600;letter-spacing:.02em;text-transform:uppercase}.jsm-badge--deprecated{background:#fef3c7;color:#92400e}.jsm-badge--readonly{background:#f1f5f9;color:#475569}.jsm-badge--writeonly{background:#dbeafe;color:#1e40af}.jsm-badge--not{background:#fee2e2;color:#991b1b}.jsm-badge--nullable{background:#f3f4f6;color:#6b7280}.jsm-fieldset{border:1.5px solid #e5e7eb;border-radius:.875rem;padding:1.25rem;background:transparent;box-shadow:0 1px 3px #0000000f;transition:box-shadow .2s;box-sizing:border-box}.jsm-fieldset:focus-within{border-color:#c7d2fe;box-shadow:0 0 0 3px #6366f114,0 1px 3px #0000000f}.jsm-legend{display:inline-flex;align-items:center;gap:.375rem;padding:0 .5rem;font-size:.875rem;font-weight:700;color:#1f2937}.jsm-obj-grid{display:grid;grid-template-columns:1fr;gap:1rem}@media (min-width:640px){.jsm-obj-grid{grid-template-columns:repeat(2,1fr)}}.jsm-obj-complex{display:flex;flex-direction:column;gap:1rem;margin-top:1rem}.jsm-dynamic-key-header{display:flex;align-items:center;justify-content:space-between;padding:.25rem .5rem;background:#f9fafb;border-radius:.375rem;border:1px dashed #d1d5db;margin-bottom:.25rem}.jsm-dynamic-key-label{font-size:.75rem;font-weight:600;color:#6b7280;font-family:monospace}.jsm-add-prop{margin-top:1rem;padding:.875rem;background:#f9fafb;border-radius:.625rem;border:1.5px dashed #d1d5db;display:flex;flex-direction:column;gap:.5rem}.jsm-add-prop-label{font-size:.75rem;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.04em}.jsm-add-prop-row{display:flex;gap:.5rem;align-items:center}.jsm-input--sm{padding:.375rem .625rem;font-size:.8125rem}.jsm-array-block{display:flex;flex-direction:column;gap:.75rem}.jsm-array-header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem}.jsm-array-title{font-size:.875rem;font-weight:700;color:#1f2937;display:flex;align-items:center;gap:.375rem}.jsm-array-items{display:flex;flex-direction:column;gap:.75rem}.jsm-array-item{border:1.5px solid #e5e7eb;border-radius:.75rem;padding:.875rem;background:transparent;box-shadow:0 1px 2px #0000000a;transition:border-color .15s,box-shadow .15s}.jsm-array-item:focus-within{border-color:#c7d2fe;box-shadow:0 0 0 3px #6366f114}.jsm-array-item-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.jsm-array-index{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:9999px;background:#eef2ff;color:#4f46e5;font-size:.6875rem;font-weight:700}.jsm-empty-array{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:2rem 1rem;border:1.5px dashed #e5e7eb;border-radius:.75rem;color:#9ca3af;font-size:.8125rem;text-align:center}.jsm-contains-hint{display:flex;align-items:center;gap:.375rem;font-size:.75rem;color:#6366f1;background:#eef2ff;border-radius:.375rem;padding:.375rem .625rem}.jsm-combinator{border:1.5px solid #e5e7eb;border-radius:.875rem;overflow:hidden;background:transparent;box-shadow:0 1px 3px #0000000f}.jsm-combinator-header{display:flex;align-items:flex-start;justify-content:space-between;padding:.875rem 1rem;background:#00000008;border-bottom:1.5px solid #e5e7eb}.jsm-combinator-title{font-size:.875rem;font-weight:700;color:#1f2937}.jsm-combinator-body{padding:1rem}.jsm-combinator-hint{font-size:.75rem;color:#6b7280;margin:.25rem 0 0}.jsm-oneof-tabs{display:flex;overflow-x:auto;border-bottom:1.5px solid #e5e7eb}.jsm-tab{padding:.5rem 1rem;font-size:.8125rem;font-weight:500;color:#6b7280;border:none;background:transparent;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1.5px;transition:color .15s,border-color .15s;white-space:nowrap;font-family:inherit}.jsm-tab:hover{color:#4f46e5}.jsm-tab--active{color:#4f46e5;border-bottom-color:#4f46e5;font-weight:600}.jsm-anyof-options{display:flex;flex-wrap:wrap;gap:.5rem;padding:.75rem 1rem;border-bottom:1.5px solid #e5e7eb}.jsm-anyof-option{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border-radius:9999px;border:1.5px solid #e5e7eb;font-size:.8125rem;font-weight:500;color:#6b7280;cursor:pointer;transition:all .15s;background:transparent}.jsm-anyof-option:hover{border-color:#a5b4fc;color:#4f46e5}.jsm-anyof-option--active{border-color:#6366f1;background:#eef2ff;color:#4f46e5}.jsm-allof-section{border-left:3px solid #e0e7ff;padding-left:1rem}.jsm-combinator-badge{display:inline-flex;align-items:center;border-radius:9999px;padding:.125rem .5rem;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;flex-shrink:0;margin-left:.75rem}.jsm-badge--oneof{background:#dbeafe;color:#1e40af}.jsm-badge--anyof{background:#ede9fe;color:#5b21b6}.jsm-badge--allof{background:#ccfbf1;color:#065f46}.dark .jsm-field-label{color:#d1d5db}.dark .jsm-field-hint{color:#9ca3af}.dark .jsm-toggle-track{background:#475569}.dark .jsm-toggle-track.jsm-on{background:#4f46e5}.dark .jsm-toggle-text{color:#d1d5db}.dark .jsm-input,.dark .jsm-textarea,.dark .jsm-select{border-color:#475569;color:#f1f5f9}.dark .jsm-input:focus,.dark .jsm-textarea:focus,.dark .jsm-select:focus{border-color:#6366f1;box-shadow:0 0 0 3px #6366f133}.dark .jsm-input--error,.dark .jsm-textarea--error,.dark .jsm-select--error{border-color:#f87171!important;background:#f871711a}.dark .jsm-fieldset{border-color:#334155}.dark .jsm-fieldset:focus-within{border-color:#6366f1}.dark .jsm-legend{color:#f1f5f9}.dark .jsm-combinator{border-color:#334155}.dark .jsm-combinator-header{background:#ffffff0a;border-color:#334155}.dark .jsm-combinator-title{color:#f1f5f9}.dark .jsm-oneof-tabs{border-color:#334155}.dark .jsm-tab{color:#94a3b8}.dark .jsm-tab--active{color:#818cf8;border-bottom-color:#818cf8}.dark .jsm-anyof-options{border-color:#334155}.dark .jsm-anyof-option{border-color:#334155;color:#94a3b8;background:#0f172a}.dark .jsm-anyof-option--active{border-color:#6366f1;background:#6366f126;color:#818cf8}.dark .jsm-allof-section{border-left-color:#3730a3}.dark .jsm-array-item{border-color:#334155}.dark .jsm-array-item:focus-within{border-color:#6366f1}.dark .jsm-array-index{background:#6366f133;color:#818cf8}.dark .jsm-empty-array{border-color:#334155;color:#64748b}.dark .jsm-contains-hint{background:#6366f126;color:#818cf8}.dark .jsm-add-prop{background:#1e293b66;border-color:#475569}.dark .jsm-add-prop-label{color:#64748b}.dark .jsm-dynamic-key-header{background:#1e293b80;border-color:#475569}.dark .jsm-dynamic-key-label{color:#94a3b8}.dark .jsm-error-msg{color:#f87171}.dark .jsm-array-title{color:#f1f5f9}.dark .jsm-badge--deprecated{background:#d9770633;color:#fbbf24}.dark .jsm-badge--readonly{background:#1e293b;color:#94a3b8}.dark .jsm-badge--writeonly{background:#2563eb33;color:#60a5fa}.dark .jsm-badge--not{background:#dc262633;color:#f87171}.dark .jsm-badge--nullable{background:#1e293b;color:#94a3b8}.dark .jsm-select-chevron{color:#64748b}\n"], dependencies: [{ kind: "component", type: JsonSchemaNodeComponent, selector: "jsm-schema-node", inputs: ["schema", "control", "label", "required", "path", "errorsMap", "parent", "controlKey", "allowAdditionalProperties"], outputs: ["controlReplaced"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1245
1109
|
}
|
|
1246
1110
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: JsonSchemaNodeComponent, decorators: [{
|
|
1247
1111
|
type: Component,
|
|
1248
|
-
args: [{
|
|
1249
|
-
selector: 'jsm-schema-node',
|
|
1250
|
-
standalone: true,
|
|
1251
|
-
imports: [CommonModule, FormsModule, ReactiveFormsModule],
|
|
1252
|
-
encapsulation: ViewEncapsulation.None,
|
|
1253
|
-
template: `
|
|
1112
|
+
args: [{ selector: 'jsm-schema-node', standalone: true, imports: [CommonModule, FormsModule, ReactiveFormsModule], encapsulation: ViewEncapsulation.None, template: `
|
|
1254
1113
|
<ng-container [ngSwitch]="nodeKind">
|
|
1255
1114
|
|
|
1256
|
-
<!--
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
<div *ngSwitchCase="'oneOf'" class="rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm overflow-hidden">
|
|
1260
|
-
<div class="flex items-start justify-between px-4 py-3 bg-slate-50 dark:bg-slate-800/60 border-b border-slate-200 dark:border-slate-700">
|
|
1115
|
+
<!-- ═══ oneOf ═══ -->
|
|
1116
|
+
<div *ngSwitchCase="'oneOf'" class="jsm-combinator">
|
|
1117
|
+
<div class="jsm-combinator-header">
|
|
1261
1118
|
<div>
|
|
1262
|
-
<p class="
|
|
1263
|
-
<p *ngIf="schema.description" class="
|
|
1119
|
+
<p class="jsm-combinator-title">{{ schema.title || label }}</p>
|
|
1120
|
+
<p *ngIf="schema.description" class="jsm-combinator-hint">{{ schema.description }}</p>
|
|
1264
1121
|
</div>
|
|
1265
|
-
<span class="
|
|
1122
|
+
<span class="jsm-combinator-badge jsm-badge--oneof">oneOf</span>
|
|
1266
1123
|
</div>
|
|
1267
|
-
<div class="
|
|
1268
|
-
<button
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
[class.text-indigo-600]="selectedOneOf === i"
|
|
1274
|
-
[class.dark:text-indigo-400]="selectedOneOf === i"
|
|
1275
|
-
[class.font-semibold]="selectedOneOf === i"
|
|
1276
|
-
[class.border-transparent]="selectedOneOf !== i"
|
|
1277
|
-
[class.text-slate-500]="selectedOneOf !== i"
|
|
1278
|
-
[class.dark:text-slate-400]="selectedOneOf !== i"
|
|
1279
|
-
(click)="selectedOneOf = i; onOneOfChange()"
|
|
1280
|
-
>{{ option.title || ('Option ' + (i + 1)) }}</button>
|
|
1124
|
+
<div class="jsm-oneof-tabs">
|
|
1125
|
+
<button *ngFor="let option of schema.oneOf; let i = index" type="button"
|
|
1126
|
+
class="jsm-tab" [class.jsm-tab--active]="selectedOneOf === i"
|
|
1127
|
+
(click)="selectedOneOf = i; onOneOfChange()">
|
|
1128
|
+
{{ option.title || ('Option ' + (i + 1)) }}
|
|
1129
|
+
</button>
|
|
1281
1130
|
</div>
|
|
1282
|
-
<div class="
|
|
1131
|
+
<div class="jsm-combinator-body" *ngIf="activeVariant">
|
|
1283
1132
|
<jsm-schema-node [schema]="activeVariant" [control]="control" [parent]="parent" [controlKey]="controlKey"
|
|
1284
1133
|
[path]="path" [errorsMap]="errorsMap" [label]="label" [required]="required"
|
|
1285
1134
|
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
@@ -1287,36 +1136,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1287
1136
|
</div>
|
|
1288
1137
|
</div>
|
|
1289
1138
|
|
|
1290
|
-
<!--
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
<div *ngSwitchCase="'anyOf'" class="rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm overflow-hidden">
|
|
1294
|
-
<div class="flex items-start justify-between px-4 py-3 bg-slate-50 dark:bg-slate-800/60 border-b border-slate-200 dark:border-slate-700">
|
|
1139
|
+
<!-- ═══ anyOf ═══ -->
|
|
1140
|
+
<div *ngSwitchCase="'anyOf'" class="jsm-combinator">
|
|
1141
|
+
<div class="jsm-combinator-header">
|
|
1295
1142
|
<div>
|
|
1296
|
-
<p class="
|
|
1297
|
-
<p *ngIf="schema.description" class="
|
|
1143
|
+
<p class="jsm-combinator-title">{{ schema.title || label }}</p>
|
|
1144
|
+
<p *ngIf="schema.description" class="jsm-combinator-hint">{{ schema.description }}</p>
|
|
1298
1145
|
</div>
|
|
1299
|
-
<span class="
|
|
1146
|
+
<span class="jsm-combinator-badge jsm-badge--anyof">anyOf</span>
|
|
1300
1147
|
</div>
|
|
1301
|
-
<div class="
|
|
1302
|
-
<label
|
|
1303
|
-
|
|
1304
|
-
class="
|
|
1305
|
-
[class.border-indigo-400]="selectedAnyOf.has(i)"
|
|
1306
|
-
[class.bg-indigo-50]="selectedAnyOf.has(i)"
|
|
1307
|
-
[class.dark:bg-indigo-900/30]="selectedAnyOf.has(i)"
|
|
1308
|
-
[class.text-indigo-700]="selectedAnyOf.has(i)"
|
|
1309
|
-
[class.dark:text-indigo-400]="selectedAnyOf.has(i)"
|
|
1310
|
-
[class.border-slate-200]="!selectedAnyOf.has(i)"
|
|
1311
|
-
[class.dark:border-slate-600]="!selectedAnyOf.has(i)"
|
|
1312
|
-
[class.text-slate-600]="!selectedAnyOf.has(i)"
|
|
1313
|
-
[class.dark:text-slate-400]="!selectedAnyOf.has(i)"
|
|
1314
|
-
>
|
|
1315
|
-
<input type="checkbox" class="h-3.5 w-3.5 accent-indigo-600" [checked]="selectedAnyOf.has(i)" (change)="toggleAnyOf(i)" />
|
|
1148
|
+
<div class="jsm-anyof-options">
|
|
1149
|
+
<label *ngFor="let option of schema.anyOf; let i = index"
|
|
1150
|
+
class="jsm-anyof-option" [class.jsm-anyof-option--active]="selectedAnyOf.has(i)">
|
|
1151
|
+
<input type="checkbox" class="sr-only" [checked]="selectedAnyOf.has(i)" (change)="toggleAnyOf(i)" />
|
|
1316
1152
|
{{ option.title || ('Option ' + (i + 1)) }}
|
|
1317
1153
|
</label>
|
|
1318
1154
|
</div>
|
|
1319
|
-
<div class="
|
|
1155
|
+
<div class="jsm-combinator-body" *ngIf="activeVariant">
|
|
1320
1156
|
<jsm-schema-node [schema]="activeVariant" [control]="control" [parent]="parent" [controlKey]="controlKey"
|
|
1321
1157
|
[path]="path" [errorsMap]="errorsMap" [label]="label" [required]="required"
|
|
1322
1158
|
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
@@ -1324,19 +1160,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1324
1160
|
</div>
|
|
1325
1161
|
</div>
|
|
1326
1162
|
|
|
1327
|
-
<!--
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
<div *ngSwitchCase="'allOf'" class="rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm overflow-hidden">
|
|
1331
|
-
<div class="flex items-start justify-between px-4 py-3 bg-slate-50 dark:bg-slate-800/60 border-b border-slate-200 dark:border-slate-700">
|
|
1163
|
+
<!-- ═══ allOf ═══ -->
|
|
1164
|
+
<div *ngSwitchCase="'allOf'" class="jsm-combinator">
|
|
1165
|
+
<div class="jsm-combinator-header">
|
|
1332
1166
|
<div>
|
|
1333
|
-
<p class="
|
|
1334
|
-
<p *ngIf="schema.description" class="
|
|
1167
|
+
<p class="jsm-combinator-title">{{ schema.title || label }}</p>
|
|
1168
|
+
<p *ngIf="schema.description" class="jsm-combinator-hint">{{ schema.description }}</p>
|
|
1335
1169
|
</div>
|
|
1336
|
-
<span class="
|
|
1170
|
+
<span class="jsm-combinator-badge jsm-badge--allof">allOf</span>
|
|
1337
1171
|
</div>
|
|
1338
|
-
<div class="
|
|
1339
|
-
<div *ngFor="let subSchema of mergedAllOf; let i = index" class="
|
|
1172
|
+
<div class="jsm-combinator-body">
|
|
1173
|
+
<div *ngFor="let subSchema of mergedAllOf; let i = index" class="jsm-allof-section">
|
|
1340
1174
|
<jsm-schema-node [schema]="subSchema" [control]="control" [parent]="parent" [controlKey]="controlKey"
|
|
1341
1175
|
[path]="path" [errorsMap]="errorsMap" [label]="subSchema.title || ('Section ' + (i + 1))" [required]="required"
|
|
1342
1176
|
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
@@ -1345,145 +1179,95 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1345
1179
|
</div>
|
|
1346
1180
|
</div>
|
|
1347
1181
|
|
|
1348
|
-
<!--
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
o "complessi" (object/array/oneOf/anyOf/allOf).
|
|
1353
|
-
- I semplici vanno in griglia 2 colonne (sm:grid-cols-2).
|
|
1354
|
-
- I complessi vanno sempre in colonna piena (col-span-2).
|
|
1355
|
-
═══════════════════════════════════════════════════════════ -->
|
|
1356
|
-
<fieldset *ngSwitchCase="'object'" class="rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm p-4 transition-shadow focus-within:border-indigo-300 dark:focus-within:border-indigo-600 focus-within:ring-2 focus-within:ring-indigo-100 dark:focus-within:ring-indigo-900/40">
|
|
1357
|
-
<legend class="px-2 text-sm font-bold text-slate-800 dark:text-slate-200">{{ schema.title || label }}</legend>
|
|
1358
|
-
|
|
1359
|
-
<p *ngIf="schema.description" class="text-xs text-slate-500 dark:text-slate-400 mb-3 mt-1">{{ schema.description }}</p>
|
|
1182
|
+
<!-- ═══ object ═══ -->
|
|
1183
|
+
<fieldset *ngSwitchCase="'object'" class="jsm-fieldset">
|
|
1184
|
+
<legend class="jsm-legend">{{ schema.title || label }}</legend>
|
|
1185
|
+
<p *ngIf="schema.description" class="jsm-field-hint" style="margin-bottom:.75rem;margin-top:.25rem;">{{ schema.description }}</p>
|
|
1360
1186
|
|
|
1361
|
-
<div *ngIf="metaBadges.length" class="
|
|
1362
|
-
<span *ngFor="let badge of metaBadges"
|
|
1363
|
-
class="rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide"
|
|
1364
|
-
[ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1187
|
+
<div *ngIf="metaBadges.length" class="jsm-badge-row" style="margin-bottom:.75rem;">
|
|
1188
|
+
<span *ngFor="let badge of metaBadges" class="jsm-badge" [ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1365
1189
|
</div>
|
|
1366
1190
|
|
|
1367
|
-
|
|
1368
|
-
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4" [formGroup]="controlAsGroup">
|
|
1191
|
+
<div class="jsm-obj-grid" [formGroup]="controlAsGroup">
|
|
1369
1192
|
<ng-container *ngFor="let key of simpleKeys">
|
|
1370
|
-
<div
|
|
1371
|
-
<div *ngIf="isDynamicKey(key)"
|
|
1372
|
-
class="
|
|
1373
|
-
<
|
|
1374
|
-
<button type="button"
|
|
1375
|
-
class="rounded px-1.5 py-0.5 text-xs font-semibold text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
|
|
1376
|
-
(click)="removeDynamicKey(key)">Remove</button>
|
|
1193
|
+
<div style="display:flex;flex-direction:column;gap:.25rem;">
|
|
1194
|
+
<div *ngIf="isDynamicKey(key)" class="jsm-dynamic-key-header">
|
|
1195
|
+
<span class="jsm-dynamic-key-label">{{ key }}</span>
|
|
1196
|
+
<button type="button" class="jsm-btn-danger" (click)="removeDynamicKey(key)">Remove</button>
|
|
1377
1197
|
</div>
|
|
1378
|
-
<jsm-schema-node
|
|
1379
|
-
[
|
|
1380
|
-
[
|
|
1381
|
-
|
|
1382
|
-
[controlKey]="key"
|
|
1383
|
-
[path]="pathForChild(key)"
|
|
1384
|
-
[errorsMap]="errorsMap"
|
|
1385
|
-
[label]="key"
|
|
1386
|
-
[required]="isRequired(key)"
|
|
1387
|
-
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
1388
|
-
(controlReplaced)="controlReplaced.emit($event)">
|
|
1389
|
-
</jsm-schema-node>
|
|
1198
|
+
<jsm-schema-node [schema]="schemaForKey(key)" [control]="childControl(key)" [parent]="controlAsGroup"
|
|
1199
|
+
[controlKey]="key" [path]="pathForChild(key)" [errorsMap]="errorsMap" [label]="key"
|
|
1200
|
+
[required]="isRequired(key)" [allowAdditionalProperties]="allowAdditionalProperties"
|
|
1201
|
+
(controlReplaced)="controlReplaced.emit($event)"></jsm-schema-node>
|
|
1390
1202
|
</div>
|
|
1391
1203
|
</ng-container>
|
|
1392
1204
|
</div>
|
|
1393
1205
|
|
|
1394
|
-
|
|
1395
|
-
<div class="space-y-4 mt-4" *ngIf="complexKeys.length > 0" [formGroup]="controlAsGroup">
|
|
1206
|
+
<div class="jsm-obj-complex" *ngIf="complexKeys.length > 0" [formGroup]="controlAsGroup">
|
|
1396
1207
|
<ng-container *ngFor="let key of complexKeys">
|
|
1397
|
-
<div
|
|
1398
|
-
<div *ngIf="isDynamicKey(key)"
|
|
1399
|
-
class="
|
|
1400
|
-
<
|
|
1401
|
-
<button type="button"
|
|
1402
|
-
class="rounded px-1.5 py-0.5 text-xs font-semibold text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
|
|
1403
|
-
(click)="removeDynamicKey(key)">Remove</button>
|
|
1208
|
+
<div style="display:flex;flex-direction:column;gap:.25rem;">
|
|
1209
|
+
<div *ngIf="isDynamicKey(key)" class="jsm-dynamic-key-header">
|
|
1210
|
+
<span class="jsm-dynamic-key-label">{{ key }}</span>
|
|
1211
|
+
<button type="button" class="jsm-btn-danger" (click)="removeDynamicKey(key)">Remove</button>
|
|
1404
1212
|
</div>
|
|
1405
|
-
<jsm-schema-node
|
|
1406
|
-
[
|
|
1407
|
-
[
|
|
1408
|
-
|
|
1409
|
-
[controlKey]="key"
|
|
1410
|
-
[path]="pathForChild(key)"
|
|
1411
|
-
[errorsMap]="errorsMap"
|
|
1412
|
-
[label]="key"
|
|
1413
|
-
[required]="isRequired(key)"
|
|
1414
|
-
[allowAdditionalProperties]="allowAdditionalProperties"
|
|
1415
|
-
(controlReplaced)="controlReplaced.emit($event)">
|
|
1416
|
-
</jsm-schema-node>
|
|
1213
|
+
<jsm-schema-node [schema]="schemaForKey(key)" [control]="childControl(key)" [parent]="controlAsGroup"
|
|
1214
|
+
[controlKey]="key" [path]="pathForChild(key)" [errorsMap]="errorsMap" [label]="key"
|
|
1215
|
+
[required]="isRequired(key)" [allowAdditionalProperties]="allowAdditionalProperties"
|
|
1216
|
+
(controlReplaced)="controlReplaced.emit($event)"></jsm-schema-node>
|
|
1417
1217
|
</div>
|
|
1418
1218
|
</ng-container>
|
|
1419
1219
|
</div>
|
|
1420
1220
|
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
<
|
|
1424
|
-
|
|
1425
|
-
<
|
|
1426
|
-
class="flex-1 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100 placeholder:text-slate-400 dark:placeholder:text-slate-500 px-3 py-1.5 text-sm shadow-sm outline-none transition hover:border-slate-400 dark:hover:border-slate-500 focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100 dark:focus:ring-indigo-900/40"
|
|
1427
|
-
[(ngModel)]="newPropertyKey" placeholder="propertyName" />
|
|
1428
|
-
<button type="button"
|
|
1429
|
-
class="rounded-lg bg-indigo-600 px-3 py-1.5 text-sm font-semibold text-white shadow-sm transition hover:bg-indigo-700 active:scale-95"
|
|
1430
|
-
(click)="addDynamicProperty()">Add</button>
|
|
1221
|
+
<div *ngIf="canAddProperty" class="jsm-add-prop">
|
|
1222
|
+
<p class="jsm-add-prop-label">Add property</p>
|
|
1223
|
+
<div class="jsm-add-prop-row">
|
|
1224
|
+
<input class="jsm-input jsm-input--sm" style="flex:1;" [(ngModel)]="newPropertyKey" placeholder="propertyName" />
|
|
1225
|
+
<button type="button" class="jsm-btn-primary" (click)="addDynamicProperty()">Add</button>
|
|
1431
1226
|
</div>
|
|
1432
|
-
<p *ngIf="propertyError" class="
|
|
1433
|
-
|
|
1434
|
-
<svg class="w-3.5 h-3.5 shrink-0" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/><path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1227
|
+
<p *ngIf="propertyError" class="jsm-error-msg">
|
|
1228
|
+
<svg class="jsm-error-icon" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/><path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1435
1229
|
{{ propertyError }}
|
|
1436
1230
|
</p>
|
|
1437
1231
|
</div>
|
|
1438
1232
|
|
|
1439
|
-
<div *ngIf="errorsForPath.length" class="
|
|
1440
|
-
<p *ngFor="let error of errorsForPath" class="
|
|
1441
|
-
<svg class="
|
|
1233
|
+
<div *ngIf="errorsForPath.length" class="jsm-error-list" style="margin-top:.75rem;">
|
|
1234
|
+
<p *ngFor="let error of errorsForPath" class="jsm-error-msg">
|
|
1235
|
+
<svg class="jsm-error-icon" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/><path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1442
1236
|
{{ error }}
|
|
1443
1237
|
</p>
|
|
1444
1238
|
</div>
|
|
1445
1239
|
</fieldset>
|
|
1446
1240
|
|
|
1447
|
-
<!--
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
<div *ngSwitchCase="'array'" class="space-y-3">
|
|
1451
|
-
<div class="flex items-start justify-between gap-2">
|
|
1241
|
+
<!-- ═══ array ═══ -->
|
|
1242
|
+
<div *ngSwitchCase="'array'" class="jsm-array-block">
|
|
1243
|
+
<div class="jsm-array-header">
|
|
1452
1244
|
<div>
|
|
1453
|
-
<p class="
|
|
1454
|
-
{{ schema.title || label }}<span *ngIf="required"
|
|
1245
|
+
<p class="jsm-array-title">
|
|
1246
|
+
{{ schema.title || label }}<span *ngIf="required" style="color:#ef4444;margin-left:.125rem;">*</span>
|
|
1455
1247
|
</p>
|
|
1456
|
-
<p *ngIf="schema.description" class="
|
|
1248
|
+
<p *ngIf="schema.description" class="jsm-field-hint">{{ schema.description }}</p>
|
|
1457
1249
|
</div>
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
class="shrink-0 flex items-center gap-1 rounded-lg bg-indigo-600 px-3 py-1.5 text-xs font-semibold text-white shadow-sm transition hover:bg-indigo-700 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed"
|
|
1461
|
-
(click)="addArrayItem()" [disabled]="!canAddArrayItem">
|
|
1462
|
-
<svg class="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1250
|
+
<button type="button" class="jsm-btn-primary" (click)="addArrayItem()" [disabled]="!canAddArrayItem">
|
|
1251
|
+
<svg style="width:.875rem;height:.875rem;flex-shrink:0;" viewBox="0 0 16 16" fill="none"><path d="M8 3v10M3 8h10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1463
1252
|
Add item
|
|
1464
1253
|
</button>
|
|
1465
1254
|
</div>
|
|
1466
1255
|
|
|
1467
|
-
<div *ngIf="effectiveSchema.contains" class="
|
|
1256
|
+
<div *ngIf="effectiveSchema.contains" class="jsm-contains-hint">
|
|
1468
1257
|
Must contain matching item(s)
|
|
1469
1258
|
<span *ngIf="effectiveSchema.minContains"> · min {{ effectiveSchema.minContains }}</span>
|
|
1470
1259
|
<span *ngIf="effectiveSchema.maxContains"> · max {{ effectiveSchema.maxContains }}</span>
|
|
1471
1260
|
</div>
|
|
1472
1261
|
|
|
1473
|
-
<div *ngIf="metaBadges.length" class="
|
|
1474
|
-
<span *ngFor="let badge of metaBadges"
|
|
1475
|
-
class="rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide"
|
|
1476
|
-
[ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1262
|
+
<div *ngIf="metaBadges.length" class="jsm-badge-row">
|
|
1263
|
+
<span *ngFor="let badge of metaBadges" class="jsm-badge" [ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1477
1264
|
</div>
|
|
1478
1265
|
|
|
1479
|
-
<div class="
|
|
1480
|
-
<div *ngFor="let item of arrayControls; let i = index"
|
|
1481
|
-
class="
|
|
1482
|
-
|
|
1483
|
-
<
|
|
1484
|
-
<button type="button"
|
|
1485
|
-
class="rounded-md border border-red-200 dark:border-red-800 px-2 py-0.5 text-xs font-semibold text-red-600 dark:text-red-400 transition hover:bg-red-50 dark:hover:bg-red-900/20"
|
|
1486
|
-
(click)="removeArrayItem(i)">Remove</button>
|
|
1266
|
+
<div class="jsm-array-items" *ngIf="arrayControls.length > 0; else emptyArray">
|
|
1267
|
+
<div *ngFor="let item of arrayControls; let i = index" class="jsm-array-item">
|
|
1268
|
+
<div class="jsm-array-item-header">
|
|
1269
|
+
<span class="jsm-array-index">{{ i + 1 }}</span>
|
|
1270
|
+
<button type="button" class="jsm-btn-danger" (click)="removeArrayItem(i)">Remove</button>
|
|
1487
1271
|
</div>
|
|
1488
1272
|
<jsm-schema-node [schema]="schemaForIndex(i)" [control]="item" [parent]="controlAsArray"
|
|
1489
1273
|
[controlKey]="i" [path]="pathForChild(i)" [errorsMap]="errorsMap" [label]="label + ' item'"
|
|
@@ -1493,124 +1277,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1493
1277
|
</div>
|
|
1494
1278
|
|
|
1495
1279
|
<ng-template #emptyArray>
|
|
1496
|
-
<div class="
|
|
1497
|
-
No items yet — click "Add item" to start.
|
|
1498
|
-
</div>
|
|
1280
|
+
<div class="jsm-empty-array">No items yet — click "Add item" to start.</div>
|
|
1499
1281
|
</ng-template>
|
|
1500
1282
|
|
|
1501
|
-
<div *ngIf="errorsForPath.length" class="
|
|
1502
|
-
<p *ngFor="let error of errorsForPath" class="
|
|
1503
|
-
<svg class="
|
|
1283
|
+
<div *ngIf="errorsForPath.length" class="jsm-error-list">
|
|
1284
|
+
<p *ngFor="let error of errorsForPath" class="jsm-error-msg">
|
|
1285
|
+
<svg class="jsm-error-icon" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/><path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
|
1504
1286
|
{{ error }}
|
|
1505
1287
|
</p>
|
|
1506
1288
|
</div>
|
|
1507
1289
|
</div>
|
|
1508
1290
|
|
|
1509
|
-
<!--
|
|
1510
|
-
|
|
1511
|
-
Icona errore solo nei messaggi di validazione.
|
|
1512
|
-
Icona chevron nel select: funzionale (indica dropdown).
|
|
1513
|
-
═══════════════════════════════════════════════════════════ -->
|
|
1514
|
-
<div *ngSwitchDefault class="space-y-1.5">
|
|
1291
|
+
<!-- ═══ primitive ═══ -->
|
|
1292
|
+
<div *ngSwitchDefault class="jsm-field">
|
|
1515
1293
|
<ng-container *ngIf="inputKind !== 'checkbox'">
|
|
1516
|
-
<label class="
|
|
1517
|
-
{{ schema.title || label }}<span *ngIf="required" class="
|
|
1294
|
+
<label class="jsm-field-label">
|
|
1295
|
+
{{ schema.title || label }}<span *ngIf="required" class="jsm-required">*</span>
|
|
1518
1296
|
</label>
|
|
1519
|
-
<p *ngIf="schema.description" class="
|
|
1297
|
+
<p *ngIf="schema.description" class="jsm-field-hint">{{ schema.description }}</p>
|
|
1520
1298
|
</ng-container>
|
|
1521
1299
|
|
|
1522
|
-
<div *ngIf="metaBadges.length" class="
|
|
1523
|
-
<span *ngFor="let badge of metaBadges"
|
|
1524
|
-
class="rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide"
|
|
1525
|
-
[ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1300
|
+
<div *ngIf="metaBadges.length" class="jsm-badge-row">
|
|
1301
|
+
<span *ngFor="let badge of metaBadges" class="jsm-badge" [ngClass]="badgeClass(badge)">{{ badge }}</span>
|
|
1526
1302
|
</div>
|
|
1527
1303
|
|
|
1528
1304
|
<ng-container [ngSwitch]="inputKind">
|
|
1305
|
+
<input *ngSwitchCase="'text'" class="jsm-input"
|
|
1306
|
+
[class.jsm-input--error]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1307
|
+
[attr.type]="inputType" [attr.placeholder]="schema.title || label"
|
|
1308
|
+
[formControl]="controlAsFormControl" />
|
|
1529
1309
|
|
|
1530
|
-
<
|
|
1531
|
-
class="
|
|
1532
|
-
[class.border-slate-300]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1533
|
-
[class.dark:border-slate-600]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1534
|
-
[class.focus:border-indigo-400]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1535
|
-
[class.focus:ring-indigo-100]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1536
|
-
[class.dark:focus:ring-indigo-900/40]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1537
|
-
[class.border-red-300]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1538
|
-
[class.dark:border-red-700]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1539
|
-
[class.bg-red-50]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1540
|
-
[class.dark:bg-red-900/20]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1541
|
-
[class.focus:border-red-400]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1542
|
-
[class.focus:ring-red-100]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1543
|
-
[attr.type]="inputType"
|
|
1310
|
+
<textarea *ngSwitchCase="'textarea'" rows="4" class="jsm-textarea"
|
|
1311
|
+
[class.jsm-textarea--error]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1544
1312
|
[attr.placeholder]="schema.title || label"
|
|
1545
|
-
[formControl]="controlAsFormControl"
|
|
1546
|
-
/>
|
|
1313
|
+
[formControl]="controlAsFormControl"></textarea>
|
|
1547
1314
|
|
|
1548
|
-
<
|
|
1549
|
-
class="
|
|
1550
|
-
|
|
1551
|
-
[class.dark:border-slate-600]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1552
|
-
[class.focus:border-indigo-400]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1553
|
-
[class.focus:ring-indigo-100]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1554
|
-
[class.dark:focus:ring-indigo-900/40]="!(errorsForPath.length && controlAsFormControl.dirty)"
|
|
1555
|
-
[class.border-red-300]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1556
|
-
[class.dark:border-red-700]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1557
|
-
[class.bg-red-50]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1558
|
-
[class.dark:bg-red-900/20]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1559
|
-
[class.focus:border-red-400]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1560
|
-
[class.focus:ring-red-100]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1561
|
-
[attr.placeholder]="schema.title || label"
|
|
1562
|
-
[formControl]="controlAsFormControl"
|
|
1563
|
-
></textarea>
|
|
1564
|
-
|
|
1565
|
-
<!-- select: il chevron SVG è funzionale, indica che è un dropdown -->
|
|
1566
|
-
<div *ngSwitchCase="'select'" class="relative">
|
|
1567
|
-
<select
|
|
1568
|
-
class="w-full appearance-none rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-900 dark:text-slate-100 px-3 py-2 pr-8 text-sm shadow-sm outline-none transition hover:border-slate-400 dark:hover:border-slate-500 focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100 dark:focus:ring-indigo-900/40"
|
|
1569
|
-
[class.border-red-300]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1570
|
-
[class.dark:border-red-700]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1571
|
-
[class.bg-red-50]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1572
|
-
[class.dark:bg-red-900/20]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1315
|
+
<div *ngSwitchCase="'select'" class="jsm-select-wrap">
|
|
1316
|
+
<select class="jsm-select"
|
|
1317
|
+
[class.jsm-select--error]="errorsForPath.length && controlAsFormControl.dirty"
|
|
1573
1318
|
[formControl]="controlAsFormControl">
|
|
1574
1319
|
<option *ngFor="let option of effectiveSchema.enum" [ngValue]="option">{{ option }}</option>
|
|
1575
1320
|
</select>
|
|
1576
|
-
<svg class="
|
|
1577
|
-
viewBox="0 0 16 16" fill="none">
|
|
1321
|
+
<svg class="jsm-select-chevron" viewBox="0 0 16 16" fill="none">
|
|
1578
1322
|
<path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
1579
1323
|
</svg>
|
|
1580
1324
|
</div>
|
|
1581
1325
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
<span class="relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors"
|
|
1585
|
-
[class.bg-indigo-600]="controlAsFormControl.value"
|
|
1586
|
-
[class.bg-slate-300]="!controlAsFormControl.value"
|
|
1587
|
-
[class.dark:bg-slate-600]="!controlAsFormControl.value">
|
|
1326
|
+
<label *ngSwitchCase="'checkbox'" class="jsm-toggle-label">
|
|
1327
|
+
<span class="jsm-toggle-track" [class.jsm-on]="controlAsFormControl.value">
|
|
1588
1328
|
<input type="checkbox" class="sr-only" [formControl]="controlAsFormControl" />
|
|
1589
|
-
<span class="
|
|
1590
|
-
[class.translate-x-4]="controlAsFormControl.value"
|
|
1591
|
-
[class.translate-x-0.5]="!controlAsFormControl.value"></span>
|
|
1329
|
+
<span class="jsm-toggle-thumb"></span>
|
|
1592
1330
|
</span>
|
|
1593
|
-
<span class="
|
|
1594
|
-
{{ schema.title || label }}<span *ngIf="required" class="
|
|
1331
|
+
<span class="jsm-toggle-text">
|
|
1332
|
+
{{ schema.title || label }}<span *ngIf="required" class="jsm-required">*</span>
|
|
1595
1333
|
</span>
|
|
1596
1334
|
</label>
|
|
1597
|
-
|
|
1598
1335
|
</ng-container>
|
|
1599
1336
|
|
|
1600
|
-
<p *ngIf="inputKind === 'checkbox' && schema.description" class="
|
|
1601
|
-
|
|
1602
|
-
<p *ngIf="effectiveSchema.
|
|
1603
|
-
e.g. {{ effectiveSchema.examples?.[0] }}
|
|
1604
|
-
</p>
|
|
1605
|
-
|
|
1606
|
-
<p *ngIf="effectiveSchema.contentMediaType" class="text-[11px] text-slate-400 dark:text-slate-500">
|
|
1337
|
+
<p *ngIf="inputKind === 'checkbox' && schema.description" class="jsm-field-hint">{{ schema.description }}</p>
|
|
1338
|
+
<p *ngIf="effectiveSchema.examples?.length" class="jsm-example">e.g. {{ effectiveSchema.examples?.[0] }}</p>
|
|
1339
|
+
<p *ngIf="effectiveSchema.contentMediaType" class="jsm-example">
|
|
1607
1340
|
{{ effectiveSchema.contentMediaType }}<span *ngIf="effectiveSchema.contentEncoding"> ({{ effectiveSchema.contentEncoding }})</span>
|
|
1608
1341
|
</p>
|
|
1609
1342
|
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
<svg class="w-3.5 h-3.5 shrink-0" viewBox="0 0 16 16" fill="none">
|
|
1343
|
+
<div *ngIf="errorsForPath.length && controlAsFormControl.dirty" class="jsm-error-list">
|
|
1344
|
+
<p *ngFor="let error of errorsForPath" class="jsm-error-msg">
|
|
1345
|
+
<svg class="jsm-error-icon" viewBox="0 0 16 16" fill="none">
|
|
1614
1346
|
<circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.5"/>
|
|
1615
1347
|
<path d="M8 5v3.5M8 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
|
1616
1348
|
</svg>
|
|
@@ -1620,10 +1352,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1620
1352
|
</div>
|
|
1621
1353
|
|
|
1622
1354
|
</ng-container>
|
|
1623
|
-
`,
|
|
1624
|
-
|
|
1625
|
-
}]
|
|
1626
|
-
}], ctorParameters: () => [{ type: JsonSchemaFormService }, { type: JsonSchemaValidationService }], propDecorators: { schema: [{
|
|
1355
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".jsm-field{display:flex;flex-direction:column;gap:.375rem}.jsm-field-label{display:block;font-size:.8125rem;font-weight:600;color:#374151}.jsm-field-hint{font-size:.75rem;color:#6b7280;margin:0;line-height:1.4}.jsm-required{color:#ef4444;margin-left:.125rem}.jsm-example{font-size:.6875rem;color:#9ca3af}.jsm-input,.jsm-textarea,.jsm-select{width:100%;border-radius:.5rem;border:1.5px solid #d1d5db;background:Canvas;padding:.5rem .75rem;font-size:.875rem;color:CanvasText;outline:none;box-shadow:0 1px 2px #0000000a;transition:border-color .15s,box-shadow .15s;font-family:inherit;box-sizing:border-box}.jsm-input:hover,.jsm-textarea:hover,.jsm-select:hover{border-color:#9ca3af}.jsm-input:focus,.jsm-textarea:focus,.jsm-select:focus{border-color:#6366f1;box-shadow:0 0 0 3px #6366f126}.jsm-input--error,.jsm-textarea--error,.jsm-select--error{border-color:#f87171!important;background:#fff5f5}.jsm-input--error:focus,.jsm-textarea--error:focus,.jsm-select--error:focus{box-shadow:0 0 0 3px #f8717133!important}.jsm-textarea{resize:vertical;min-height:6rem}.jsm-select-wrap{position:relative}.jsm-select{appearance:none;padding-right:2.25rem;cursor:pointer}.jsm-select-chevron{position:absolute;right:.625rem;top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:#9ca3af;pointer-events:none}.jsm-toggle-label{display:inline-flex;align-items:center;gap:.625rem;cursor:pointer;-webkit-user-select:none;user-select:none}.jsm-toggle-track{position:relative;display:inline-flex;align-items:center;width:2.25rem;height:1.25rem;border-radius:9999px;flex-shrink:0;background:#d1d5db;transition:background .2s}.jsm-toggle-track.jsm-on{background:#4f46e5}.jsm-toggle-thumb{display:inline-block;width:1rem;height:1rem;border-radius:9999px;background:#fff;box-shadow:0 1px 3px #0003;transform:translate(.125rem);transition:transform .2s}.jsm-toggle-track.jsm-on .jsm-toggle-thumb{transform:translate(1.125rem)}.jsm-toggle-text{font-size:.875rem;font-weight:500;color:#374151}.jsm-btn-primary{display:inline-flex;align-items:center;gap:.25rem;padding:.375rem .75rem;border-radius:.5rem;font-size:.8125rem;font-weight:600;background:#4f46e5;color:#fff;border:none;cursor:pointer;box-shadow:0 1px 2px #4f46e54d;transition:background .15s,transform .1s,box-shadow .15s;white-space:nowrap;font-family:inherit}.jsm-btn-primary:hover{background:#4338ca;transform:translateY(-1px);box-shadow:0 3px 8px #4f46e54d}.jsm-btn-primary:active{transform:translateY(0)}.jsm-btn-primary:disabled{opacity:.45;cursor:not-allowed;transform:none}.jsm-btn-danger{display:inline-flex;align-items:center;gap:.25rem;padding:.25rem .5rem;border-radius:.375rem;font-size:.75rem;font-weight:600;background:transparent;color:#dc2626;border:1.5px solid #fca5a5;cursor:pointer;transition:background .15s,border-color .15s;font-family:inherit}.jsm-btn-danger:hover{background:#fee2e2;border-color:#f87171}.jsm-error-list{display:flex;flex-direction:column;gap:.25rem;margin-top:.25rem}.jsm-error-msg{display:flex;align-items:center;gap:.375rem;font-size:.75rem;color:#dc2626;font-weight:500}.jsm-error-icon{width:.875rem;height:.875rem;flex-shrink:0}.jsm-badge-row{display:flex;flex-wrap:wrap;gap:.375rem}.jsm-badge{display:inline-flex;align-items:center;border-radius:9999px;padding:.125rem .5rem;font-size:.6875rem;font-weight:600;letter-spacing:.02em;text-transform:uppercase}.jsm-badge--deprecated{background:#fef3c7;color:#92400e}.jsm-badge--readonly{background:#f1f5f9;color:#475569}.jsm-badge--writeonly{background:#dbeafe;color:#1e40af}.jsm-badge--not{background:#fee2e2;color:#991b1b}.jsm-badge--nullable{background:#f3f4f6;color:#6b7280}.jsm-fieldset{border:1.5px solid #e5e7eb;border-radius:.875rem;padding:1.25rem;background:transparent;box-shadow:0 1px 3px #0000000f;transition:box-shadow .2s;box-sizing:border-box}.jsm-fieldset:focus-within{border-color:#c7d2fe;box-shadow:0 0 0 3px #6366f114,0 1px 3px #0000000f}.jsm-legend{display:inline-flex;align-items:center;gap:.375rem;padding:0 .5rem;font-size:.875rem;font-weight:700;color:#1f2937}.jsm-obj-grid{display:grid;grid-template-columns:1fr;gap:1rem}@media (min-width:640px){.jsm-obj-grid{grid-template-columns:repeat(2,1fr)}}.jsm-obj-complex{display:flex;flex-direction:column;gap:1rem;margin-top:1rem}.jsm-dynamic-key-header{display:flex;align-items:center;justify-content:space-between;padding:.25rem .5rem;background:#f9fafb;border-radius:.375rem;border:1px dashed #d1d5db;margin-bottom:.25rem}.jsm-dynamic-key-label{font-size:.75rem;font-weight:600;color:#6b7280;font-family:monospace}.jsm-add-prop{margin-top:1rem;padding:.875rem;background:#f9fafb;border-radius:.625rem;border:1.5px dashed #d1d5db;display:flex;flex-direction:column;gap:.5rem}.jsm-add-prop-label{font-size:.75rem;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.04em}.jsm-add-prop-row{display:flex;gap:.5rem;align-items:center}.jsm-input--sm{padding:.375rem .625rem;font-size:.8125rem}.jsm-array-block{display:flex;flex-direction:column;gap:.75rem}.jsm-array-header{display:flex;align-items:flex-start;justify-content:space-between;gap:.5rem}.jsm-array-title{font-size:.875rem;font-weight:700;color:#1f2937;display:flex;align-items:center;gap:.375rem}.jsm-array-items{display:flex;flex-direction:column;gap:.75rem}.jsm-array-item{border:1.5px solid #e5e7eb;border-radius:.75rem;padding:.875rem;background:transparent;box-shadow:0 1px 2px #0000000a;transition:border-color .15s,box-shadow .15s}.jsm-array-item:focus-within{border-color:#c7d2fe;box-shadow:0 0 0 3px #6366f114}.jsm-array-item-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.jsm-array-index{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:9999px;background:#eef2ff;color:#4f46e5;font-size:.6875rem;font-weight:700}.jsm-empty-array{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:2rem 1rem;border:1.5px dashed #e5e7eb;border-radius:.75rem;color:#9ca3af;font-size:.8125rem;text-align:center}.jsm-contains-hint{display:flex;align-items:center;gap:.375rem;font-size:.75rem;color:#6366f1;background:#eef2ff;border-radius:.375rem;padding:.375rem .625rem}.jsm-combinator{border:1.5px solid #e5e7eb;border-radius:.875rem;overflow:hidden;background:transparent;box-shadow:0 1px 3px #0000000f}.jsm-combinator-header{display:flex;align-items:flex-start;justify-content:space-between;padding:.875rem 1rem;background:#00000008;border-bottom:1.5px solid #e5e7eb}.jsm-combinator-title{font-size:.875rem;font-weight:700;color:#1f2937}.jsm-combinator-body{padding:1rem}.jsm-combinator-hint{font-size:.75rem;color:#6b7280;margin:.25rem 0 0}.jsm-oneof-tabs{display:flex;overflow-x:auto;border-bottom:1.5px solid #e5e7eb}.jsm-tab{padding:.5rem 1rem;font-size:.8125rem;font-weight:500;color:#6b7280;border:none;background:transparent;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1.5px;transition:color .15s,border-color .15s;white-space:nowrap;font-family:inherit}.jsm-tab:hover{color:#4f46e5}.jsm-tab--active{color:#4f46e5;border-bottom-color:#4f46e5;font-weight:600}.jsm-anyof-options{display:flex;flex-wrap:wrap;gap:.5rem;padding:.75rem 1rem;border-bottom:1.5px solid #e5e7eb}.jsm-anyof-option{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border-radius:9999px;border:1.5px solid #e5e7eb;font-size:.8125rem;font-weight:500;color:#6b7280;cursor:pointer;transition:all .15s;background:transparent}.jsm-anyof-option:hover{border-color:#a5b4fc;color:#4f46e5}.jsm-anyof-option--active{border-color:#6366f1;background:#eef2ff;color:#4f46e5}.jsm-allof-section{border-left:3px solid #e0e7ff;padding-left:1rem}.jsm-combinator-badge{display:inline-flex;align-items:center;border-radius:9999px;padding:.125rem .5rem;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;flex-shrink:0;margin-left:.75rem}.jsm-badge--oneof{background:#dbeafe;color:#1e40af}.jsm-badge--anyof{background:#ede9fe;color:#5b21b6}.jsm-badge--allof{background:#ccfbf1;color:#065f46}.dark .jsm-field-label{color:#d1d5db}.dark .jsm-field-hint{color:#9ca3af}.dark .jsm-toggle-track{background:#475569}.dark .jsm-toggle-track.jsm-on{background:#4f46e5}.dark .jsm-toggle-text{color:#d1d5db}.dark .jsm-input,.dark .jsm-textarea,.dark .jsm-select{border-color:#475569;color:#f1f5f9}.dark .jsm-input:focus,.dark .jsm-textarea:focus,.dark .jsm-select:focus{border-color:#6366f1;box-shadow:0 0 0 3px #6366f133}.dark .jsm-input--error,.dark .jsm-textarea--error,.dark .jsm-select--error{border-color:#f87171!important;background:#f871711a}.dark .jsm-fieldset{border-color:#334155}.dark .jsm-fieldset:focus-within{border-color:#6366f1}.dark .jsm-legend{color:#f1f5f9}.dark .jsm-combinator{border-color:#334155}.dark .jsm-combinator-header{background:#ffffff0a;border-color:#334155}.dark .jsm-combinator-title{color:#f1f5f9}.dark .jsm-oneof-tabs{border-color:#334155}.dark .jsm-tab{color:#94a3b8}.dark .jsm-tab--active{color:#818cf8;border-bottom-color:#818cf8}.dark .jsm-anyof-options{border-color:#334155}.dark .jsm-anyof-option{border-color:#334155;color:#94a3b8;background:#0f172a}.dark .jsm-anyof-option--active{border-color:#6366f1;background:#6366f126;color:#818cf8}.dark .jsm-allof-section{border-left-color:#3730a3}.dark .jsm-array-item{border-color:#334155}.dark .jsm-array-item:focus-within{border-color:#6366f1}.dark .jsm-array-index{background:#6366f133;color:#818cf8}.dark .jsm-empty-array{border-color:#334155;color:#64748b}.dark .jsm-contains-hint{background:#6366f126;color:#818cf8}.dark .jsm-add-prop{background:#1e293b66;border-color:#475569}.dark .jsm-add-prop-label{color:#64748b}.dark .jsm-dynamic-key-header{background:#1e293b80;border-color:#475569}.dark .jsm-dynamic-key-label{color:#94a3b8}.dark .jsm-error-msg{color:#f87171}.dark .jsm-array-title{color:#f1f5f9}.dark .jsm-badge--deprecated{background:#d9770633;color:#fbbf24}.dark .jsm-badge--readonly{background:#1e293b;color:#94a3b8}.dark .jsm-badge--writeonly{background:#2563eb33;color:#60a5fa}.dark .jsm-badge--not{background:#dc262633;color:#f87171}.dark .jsm-badge--nullable{background:#1e293b;color:#94a3b8}.dark .jsm-select-chevron{color:#64748b}\n"] }]
|
|
1356
|
+
}], ctorParameters: () => [{ type: JsonSchemaFormService }, { type: JsonSchemaValidationService }, { type: i0.ChangeDetectorRef }], propDecorators: { schema: [{
|
|
1627
1357
|
type: Input,
|
|
1628
1358
|
args: [{ required: true }]
|
|
1629
1359
|
}], control: [{
|
|
@@ -1647,6 +1377,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1647
1377
|
type: Output
|
|
1648
1378
|
}] } });
|
|
1649
1379
|
|
|
1380
|
+
// AUTO-GENERATED — do not edit manually. Run: node scripts/generate-lib-styles.mjs
|
|
1381
|
+
const JSM_CSS = "/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer theme, base, components, utilities;\n@layer theme {\n :root, :host {\n --font-sans: ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\",\n \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\",\n \"Courier New\", monospace;\n --color-red-50: oklch(97.1% 0.013 17.38);\n --color-red-300: oklch(80.8% 0.114 19.571);\n --color-red-700: oklch(50.5% 0.213 27.518);\n --color-red-900: oklch(39.6% 0.141 25.723);\n --color-amber-50: oklch(98.7% 0.022 95.277);\n --color-amber-200: oklch(92.4% 0.12 95.746);\n --color-amber-300: oklch(87.9% 0.169 91.605);\n --color-amber-400: oklch(82.8% 0.189 84.429);\n --color-amber-600: oklch(66.6% 0.179 58.318);\n --color-amber-700: oklch(55.5% 0.163 48.998);\n --color-amber-800: oklch(47.3% 0.137 46.201);\n --color-amber-900: oklch(41.4% 0.112 45.904);\n --color-emerald-50: oklch(97.9% 0.021 166.113);\n --color-emerald-400: oklch(76.5% 0.177 163.223);\n --color-emerald-700: oklch(50.8% 0.118 165.612);\n --color-emerald-900: oklch(37.8% 0.077 168.94);\n --color-indigo-100: oklch(93% 0.034 272.788);\n --color-indigo-300: oklch(78.5% 0.115 274.713);\n --color-indigo-400: oklch(67.3% 0.182 276.935);\n --color-indigo-500: oklch(58.5% 0.233 277.117);\n --color-indigo-600: oklch(51.1% 0.262 276.966);\n --color-indigo-700: oklch(45.7% 0.24 277.023);\n --color-indigo-900: oklch(35.9% 0.144 278.697);\n --color-rose-50: oklch(96.9% 0.015 12.422);\n --color-rose-400: oklch(71.2% 0.194 13.428);\n --color-rose-500: oklch(64.5% 0.246 16.439);\n --color-rose-600: oklch(58.6% 0.253 17.585);\n --color-rose-700: oklch(51.4% 0.222 16.935);\n --color-rose-900: oklch(41% 0.159 10.272);\n --color-slate-50: oklch(98.4% 0.003 247.858);\n --color-slate-100: oklch(96.8% 0.007 247.896);\n --color-slate-200: oklch(92.9% 0.013 255.508);\n --color-slate-300: oklch(86.9% 0.022 252.894);\n --color-slate-400: oklch(70.4% 0.04 256.788);\n --color-slate-500: oklch(55.4% 0.046 257.417);\n --color-slate-600: oklch(44.6% 0.043 257.281);\n --color-slate-700: oklch(37.2% 0.044 257.287);\n --color-slate-800: oklch(27.9% 0.041 260.031);\n --color-slate-900: oklch(20.8% 0.042 265.755);\n --color-slate-950: oklch(12.9% 0.042 264.695);\n --color-white: #fff;\n --spacing: 0.25rem;\n --container-2xl: 42rem;\n --container-3xl: 48rem;\n --container-6xl: 72rem;\n --text-xs: 0.75rem;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 1.25rem;\n --text-xl--line-height: calc(1.75 / 1.25);\n --text-3xl: 1.875rem;\n --text-3xl--line-height: calc(2.25 / 1.875);\n --text-4xl: 2.25rem;\n --text-4xl--line-height: calc(2.5 / 2.25);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --tracking-tight: -0.025em;\n --tracking-wide: 0.025em;\n --radius-lg: 0.5rem;\n --radius-xl: 0.75rem;\n --radius-2xl: 1rem;\n --animate-spin: spin 1s linear infinite;\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n }\n}\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type=\"button\"], [type=\"reset\"], [type=\"submit\"]), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=\"until-found\"])) {\n display: none !important;\n }\n}\n@layer utilities {\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border-width: 0;\n }\n .relative {\n position: relative;\n }\n .col-span-2 {\n grid-column: span 2 / span 2;\n }\n .mx-auto {\n margin-inline: auto;\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .mb-4 {\n margin-bottom: calc(var(--spacing) * 4);\n }\n .contents {\n display: contents;\n }\n .flex {\n display: flex;\n }\n .grid {\n display: grid;\n }\n .inline {\n display: inline;\n }\n .inline-block {\n display: inline-block;\n }\n .inline-flex {\n display: inline-flex;\n }\n .table {\n display: table;\n }\n .h-3 {\n height: calc(var(--spacing) * 3);\n }\n .h-3\\.5 {\n height: calc(var(--spacing) * 3.5);\n }\n .h-4 {\n height: calc(var(--spacing) * 4);\n }\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n .h-40 {\n height: calc(var(--spacing) * 40);\n }\n .h-56 {\n height: calc(var(--spacing) * 56);\n }\n .min-h-screen {\n min-height: 100vh;\n }\n .w-3 {\n width: calc(var(--spacing) * 3);\n }\n .w-3\\.5 {\n width: calc(var(--spacing) * 3.5);\n }\n .w-4 {\n width: calc(var(--spacing) * 4);\n }\n .w-9 {\n width: calc(var(--spacing) * 9);\n }\n .w-full {\n width: 100%;\n }\n .max-w-2xl {\n max-width: var(--container-2xl);\n }\n .max-w-3xl {\n max-width: var(--container-3xl);\n }\n .max-w-6xl {\n max-width: var(--container-6xl);\n }\n .flex-shrink {\n flex-shrink: 1;\n }\n .shrink-0 {\n flex-shrink: 0;\n }\n .border-collapse {\n border-collapse: collapse;\n }\n .translate-x-0 {\n --tw-translate-x: calc(var(--spacing) * 0);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .translate-x-0\\.5 {\n --tw-translate-x: calc(var(--spacing) * 0.5);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .translate-x-4 {\n --tw-translate-x: calc(var(--spacing) * 4);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .transform {\n transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);\n }\n .animate-spin {\n animation: var(--animate-spin);\n }\n .cursor-pointer {\n cursor: pointer;\n }\n .resize {\n resize: both;\n }\n .grid-cols-1 {\n grid-template-columns: repeat(1, minmax(0, 1fr));\n }\n .flex-col {\n flex-direction: column;\n }\n .items-center {\n align-items: center;\n }\n .justify-between {\n justify-content: space-between;\n }\n .justify-center {\n justify-content: center;\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-3 {\n gap: calc(var(--spacing) * 3);\n }\n .gap-4 {\n gap: calc(var(--spacing) * 4);\n }\n .gap-6 {\n gap: calc(var(--spacing) * 6);\n }\n .space-y-0 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-0\\.5 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 0.5) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 0.5) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-1 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-2 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-3 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-4 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-5 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-6 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-10 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 10) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 10) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .rounded {\n border-radius: 0.25rem;\n }\n .rounded-2xl {\n border-radius: var(--radius-2xl);\n }\n .rounded-full {\n border-radius: calc(infinity * 1px);\n }\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n .rounded-xl {\n border-radius: var(--radius-xl);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-2 {\n border-style: var(--tw-border-style);\n border-width: 2px;\n }\n .border-amber-200 {\n border-color: var(--color-amber-200);\n }\n .border-amber-300 {\n border-color: var(--color-amber-300);\n }\n .border-red-300 {\n border-color: var(--color-red-300);\n }\n .border-red-700 {\n border-color: var(--color-red-700);\n }\n .border-slate-100 {\n border-color: var(--color-slate-100);\n }\n .border-slate-200 {\n border-color: var(--color-slate-200);\n }\n .border-slate-300 {\n border-color: var(--color-slate-300);\n }\n .border-t-slate-900 {\n border-top-color: var(--color-slate-900);\n }\n .bg-amber-50 {\n background-color: var(--color-amber-50);\n }\n .bg-emerald-50 {\n background-color: var(--color-emerald-50);\n }\n .bg-indigo-600 {\n background-color: var(--color-indigo-600);\n }\n .bg-red-50 {\n background-color: var(--color-red-50);\n }\n .bg-red-900 {\n background-color: var(--color-red-900);\n }\n .bg-red-900\\/20 {\n background-color: color-mix(in srgb, oklch(39.6% 0.141 25.723) 20%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-red-900) 20%, transparent);\n }\n }\n .bg-rose-50 {\n background-color: var(--color-rose-50);\n }\n .bg-slate-50 {\n background-color: var(--color-slate-50);\n }\n .bg-slate-300 {\n background-color: var(--color-slate-300);\n }\n .bg-slate-900 {\n background-color: var(--color-slate-900);\n }\n .bg-white {\n background-color: var(--color-white);\n }\n .bg-white\\/70 {\n background-color: color-mix(in srgb, #fff 70%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 70%, transparent);\n }\n }\n .bg-white\\/90 {\n background-color: color-mix(in srgb, #fff 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 90%, transparent);\n }\n }\n .p-3 {\n padding: calc(var(--spacing) * 3);\n }\n .p-4 {\n padding: calc(var(--spacing) * 4);\n }\n .p-5 {\n padding: calc(var(--spacing) * 5);\n }\n .p-6 {\n padding: calc(var(--spacing) * 6);\n }\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-6 {\n padding-inline: calc(var(--spacing) * 6);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n }\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n .py-2\\.5 {\n padding-block: calc(var(--spacing) * 2.5);\n }\n .py-6 {\n padding-block: calc(var(--spacing) * 6);\n }\n .py-8 {\n padding-block: calc(var(--spacing) * 8);\n }\n .py-10 {\n padding-block: calc(var(--spacing) * 10);\n }\n .font-mono {\n font-family: var(--font-mono);\n }\n .text-3xl {\n font-size: var(--text-3xl);\n line-height: var(--tw-leading, var(--text-3xl--line-height));\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n .text-\\[10px\\] {\n font-size: 10px;\n }\n .text-\\[11px\\] {\n font-size: 11px;\n }\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n .tracking-\\[0\\.2em\\] {\n --tw-tracking: 0.2em;\n letter-spacing: 0.2em;\n }\n .tracking-tight {\n --tw-tracking: var(--tracking-tight);\n letter-spacing: var(--tracking-tight);\n }\n .tracking-wide {\n --tw-tracking: var(--tracking-wide);\n letter-spacing: var(--tracking-wide);\n }\n .whitespace-pre-wrap {\n white-space: pre-wrap;\n }\n .text-amber-600 {\n color: var(--color-amber-600);\n }\n .text-amber-700 {\n color: var(--color-amber-700);\n }\n .text-amber-800 {\n color: var(--color-amber-800);\n }\n .text-emerald-700 {\n color: var(--color-emerald-700);\n }\n .text-indigo-500 {\n color: var(--color-indigo-500);\n }\n .text-rose-500 {\n color: var(--color-rose-500);\n }\n .text-rose-600 {\n color: var(--color-rose-600);\n }\n .text-rose-700 {\n color: var(--color-rose-700);\n }\n .text-slate-400 {\n color: var(--color-slate-400);\n }\n .text-slate-500 {\n color: var(--color-slate-500);\n }\n .text-slate-600 {\n color: var(--color-slate-600);\n }\n .text-slate-700 {\n color: var(--color-slate-700);\n }\n .text-slate-800 {\n color: var(--color-slate-800);\n }\n .text-slate-900 {\n color: var(--color-slate-900);\n }\n .text-white {\n color: var(--color-white);\n }\n .uppercase {\n text-transform: uppercase;\n }\n .italic {\n font-style: italic;\n }\n .underline {\n text-decoration-line: underline;\n }\n .opacity-25 {\n opacity: 25%;\n }\n .opacity-75 {\n opacity: 75%;\n }\n .shadow {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-sm {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n .backdrop-blur {\n --tw-backdrop-blur: blur(8px);\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .backdrop-filter {\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-all {\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-transform {\n transition-property: transform, translate, scale, rotate;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .duration-200 {\n --tw-duration: 200ms;\n transition-duration: 200ms;\n }\n .focus-within\\:border-indigo-300 {\n &:focus-within {\n border-color: var(--color-indigo-300);\n }\n }\n .focus-within\\:ring-2 {\n &:focus-within {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .hover\\:-translate-y-0\\.5 {\n &:hover {\n @media (hover: hover) {\n --tw-translate-y: calc(var(--spacing) * -0.5);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n }\n }\n .hover\\:border-slate-300 {\n &:hover {\n @media (hover: hover) {\n border-color: var(--color-slate-300);\n }\n }\n }\n .hover\\:border-slate-400 {\n &:hover {\n @media (hover: hover) {\n border-color: var(--color-slate-400);\n }\n }\n }\n .hover\\:bg-slate-50 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-slate-50);\n }\n }\n }\n .hover\\:bg-slate-800 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-slate-800);\n }\n }\n }\n .hover\\:text-rose-700 {\n &:hover {\n @media (hover: hover) {\n color: var(--color-rose-700);\n }\n }\n }\n .hover\\:shadow {\n &:hover {\n @media (hover: hover) {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n }\n .hover\\:shadow-lg {\n &:hover {\n @media (hover: hover) {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n }\n .hover\\:shadow-md {\n &:hover {\n @media (hover: hover) {\n --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n }\n .focus\\:border-indigo-400 {\n &:focus {\n border-color: var(--color-indigo-400);\n }\n }\n .focus\\:ring-2 {\n &:focus {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .focus\\:ring-indigo-100 {\n &:focus {\n --tw-ring-color: var(--color-indigo-100);\n }\n }\n .focus\\:ring-indigo-500 {\n &:focus {\n --tw-ring-color: var(--color-indigo-500);\n }\n }\n .focus\\:ring-slate-900 {\n &:focus {\n --tw-ring-color: var(--color-slate-900);\n }\n }\n .focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n .sm\\:grid-cols-2 {\n @media (width >= 40rem) {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n }\n .md\\:grid-cols-2 {\n @media (width >= 48rem) {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n }\n .md\\:flex-row {\n @media (width >= 48rem) {\n flex-direction: row;\n }\n }\n .md\\:items-center {\n @media (width >= 48rem) {\n align-items: center;\n }\n }\n .md\\:justify-between {\n @media (width >= 48rem) {\n justify-content: space-between;\n }\n }\n .md\\:p-6 {\n @media (width >= 48rem) {\n padding: calc(var(--spacing) * 6);\n }\n }\n .md\\:text-4xl {\n @media (width >= 48rem) {\n font-size: var(--text-4xl);\n line-height: var(--tw-leading, var(--text-4xl--line-height));\n }\n }\n .lg\\:grid-cols-\\[360px\\,1fr\\] {\n @media (width >= 64rem) {\n grid-template-columns: 360px,1fr;\n }\n }\n .dark\\:border-amber-700 {\n &:where(.dark, .dark *) {\n border-color: var(--color-amber-700);\n }\n }\n .dark\\:border-amber-800 {\n &:where(.dark, .dark *) {\n border-color: var(--color-amber-800);\n }\n }\n .dark\\:border-slate-600 {\n &:where(.dark, .dark *) {\n border-color: var(--color-slate-600);\n }\n }\n .dark\\:border-slate-700 {\n &:where(.dark, .dark *) {\n border-color: var(--color-slate-700);\n }\n }\n .dark\\:border-t-indigo-400 {\n &:where(.dark, .dark *) {\n border-top-color: var(--color-indigo-400);\n }\n }\n .dark\\:bg-amber-900\\/20 {\n &:where(.dark, .dark *) {\n background-color: color-mix(in srgb, oklch(41.4% 0.112 45.904) 20%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-amber-900) 20%, transparent);\n }\n }\n }\n .dark\\:bg-emerald-900\\/30 {\n &:where(.dark, .dark *) {\n background-color: color-mix(in srgb, oklch(37.8% 0.077 168.94) 30%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-emerald-900) 30%, transparent);\n }\n }\n }\n .dark\\:bg-indigo-600 {\n &:where(.dark, .dark *) {\n background-color: var(--color-indigo-600);\n }\n }\n .dark\\:bg-rose-900\\/30 {\n &:where(.dark, .dark *) {\n background-color: color-mix(in srgb, oklch(41% 0.159 10.272) 30%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-rose-900) 30%, transparent);\n }\n }\n }\n .dark\\:bg-slate-600 {\n &:where(.dark, .dark *) {\n background-color: var(--color-slate-600);\n }\n }\n .dark\\:bg-slate-700 {\n &:where(.dark, .dark *) {\n background-color: var(--color-slate-700);\n }\n }\n .dark\\:bg-slate-800 {\n &:where(.dark, .dark *) {\n background-color: var(--color-slate-800);\n }\n }\n .dark\\:bg-slate-800\\/50 {\n &:where(.dark, .dark *) {\n background-color: color-mix(in srgb, oklch(27.9% 0.041 260.031) 50%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-slate-800) 50%, transparent);\n }\n }\n }\n .dark\\:bg-slate-800\\/60 {\n &:where(.dark, .dark *) {\n background-color: color-mix(in srgb, oklch(27.9% 0.041 260.031) 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-slate-800) 60%, transparent);\n }\n }\n }\n .dark\\:bg-slate-900 {\n &:where(.dark, .dark *) {\n background-color: var(--color-slate-900);\n }\n }\n .dark\\:bg-slate-900\\/90 {\n &:where(.dark, .dark *) {\n background-color: color-mix(in srgb, oklch(20.8% 0.042 265.755) 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-slate-900) 90%, transparent);\n }\n }\n }\n .dark\\:bg-slate-950 {\n &:where(.dark, .dark *) {\n background-color: var(--color-slate-950);\n }\n }\n .dark\\:text-amber-300 {\n &:where(.dark, .dark *) {\n color: var(--color-amber-300);\n }\n }\n .dark\\:text-amber-400 {\n &:where(.dark, .dark *) {\n color: var(--color-amber-400);\n }\n }\n .dark\\:text-emerald-400 {\n &:where(.dark, .dark *) {\n color: var(--color-emerald-400);\n }\n }\n .dark\\:text-indigo-400 {\n &:where(.dark, .dark *) {\n color: var(--color-indigo-400);\n }\n }\n .dark\\:text-rose-400 {\n &:where(.dark, .dark *) {\n color: var(--color-rose-400);\n }\n }\n .dark\\:text-slate-100 {\n &:where(.dark, .dark *) {\n color: var(--color-slate-100);\n }\n }\n .dark\\:text-slate-200 {\n &:where(.dark, .dark *) {\n color: var(--color-slate-200);\n }\n }\n .dark\\:text-slate-300 {\n &:where(.dark, .dark *) {\n color: var(--color-slate-300);\n }\n }\n .dark\\:text-slate-400 {\n &:where(.dark, .dark *) {\n color: var(--color-slate-400);\n }\n }\n .dark\\:text-slate-500 {\n &:where(.dark, .dark *) {\n color: var(--color-slate-500);\n }\n }\n .dark\\:text-white {\n &:where(.dark, .dark *) {\n color: var(--color-white);\n }\n }\n .dark\\:hover\\:border-slate-500 {\n &:where(.dark, .dark *) {\n &:hover {\n @media (hover: hover) {\n border-color: var(--color-slate-500);\n }\n }\n }\n }\n .dark\\:hover\\:bg-indigo-700 {\n &:where(.dark, .dark *) {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-indigo-700);\n }\n }\n }\n }\n .dark\\:hover\\:bg-slate-700 {\n &:where(.dark, .dark *) {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-slate-700);\n }\n }\n }\n }\n .dark\\:focus\\:ring-indigo-900\\/40 {\n &:where(.dark, .dark *) {\n &:focus {\n --tw-ring-color: color-mix(in srgb, oklch(35.9% 0.144 278.697) 40%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-ring-color: color-mix(in oklab, var(--color-indigo-900) 40%, transparent);\n }\n }\n }\n }\n}\n@property --tw-translate-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-rotate-x {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-rotate-y {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-rotate-z {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-skew-x {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-skew-y {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-space-y-reverse {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-border-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-font-weight {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-tracking {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: \"<length>\";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: \"*\";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-outline-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-backdrop-blur {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-brightness {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-contrast {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-grayscale {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-hue-rotate {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-invert {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-opacity {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-saturate {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-sepia {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-duration {\n syntax: \"*\";\n inherits: false;\n}\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-space-y-reverse: 0;\n --tw-border-style: solid;\n --tw-font-weight: initial;\n --tw-tracking: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-outline-style: solid;\n --tw-backdrop-blur: initial;\n --tw-backdrop-brightness: initial;\n --tw-backdrop-contrast: initial;\n --tw-backdrop-grayscale: initial;\n --tw-backdrop-hue-rotate: initial;\n --tw-backdrop-invert: initial;\n --tw-backdrop-opacity: initial;\n --tw-backdrop-saturate: initial;\n --tw-backdrop-sepia: initial;\n --tw-duration: initial;\n }\n }\n}\n";
|
|
1382
|
+
|
|
1383
|
+
const STYLE_ID = 'jsm-tailwind-styles';
|
|
1384
|
+
class JsonSchemaStylesService {
|
|
1385
|
+
platformId;
|
|
1386
|
+
injected = false;
|
|
1387
|
+
constructor(platformId) {
|
|
1388
|
+
this.platformId = platformId;
|
|
1389
|
+
}
|
|
1390
|
+
inject() {
|
|
1391
|
+
if (this.injected || !isPlatformBrowser(this.platformId))
|
|
1392
|
+
return;
|
|
1393
|
+
if (typeof document === 'undefined')
|
|
1394
|
+
return;
|
|
1395
|
+
if (document.getElementById(STYLE_ID)) {
|
|
1396
|
+
this.injected = true;
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
const style = document.createElement('style');
|
|
1400
|
+
style.id = STYLE_ID;
|
|
1401
|
+
style.textContent = JSM_CSS;
|
|
1402
|
+
document.head.appendChild(style);
|
|
1403
|
+
this.injected = true;
|
|
1404
|
+
}
|
|
1405
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: JsonSchemaStylesService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1406
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: JsonSchemaStylesService, providedIn: 'root' });
|
|
1407
|
+
}
|
|
1408
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: JsonSchemaStylesService, decorators: [{
|
|
1409
|
+
type: Injectable,
|
|
1410
|
+
args: [{ providedIn: 'root' }]
|
|
1411
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1412
|
+
type: Inject,
|
|
1413
|
+
args: [PLATFORM_ID]
|
|
1414
|
+
}] }] });
|
|
1415
|
+
|
|
1650
1416
|
class JsonSchemaFormComponent {
|
|
1651
1417
|
schemaService;
|
|
1652
1418
|
resolver;
|
|
@@ -1666,10 +1432,11 @@ class JsonSchemaFormComponent {
|
|
|
1666
1432
|
schemaErrorList = [];
|
|
1667
1433
|
loading = false;
|
|
1668
1434
|
valueSub;
|
|
1669
|
-
constructor(schemaService, resolver, validation) {
|
|
1435
|
+
constructor(schemaService, resolver, validation, stylesService) {
|
|
1670
1436
|
this.schemaService = schemaService;
|
|
1671
1437
|
this.resolver = resolver;
|
|
1672
1438
|
this.validation = validation;
|
|
1439
|
+
stylesService.inject();
|
|
1673
1440
|
}
|
|
1674
1441
|
ngOnChanges(changes) {
|
|
1675
1442
|
if (changes['schema'] || changes['value'] || changes['data']) {
|
|
@@ -1739,7 +1506,7 @@ class JsonSchemaFormComponent {
|
|
|
1739
1506
|
this.valueChange.emit(this.rootControl.value);
|
|
1740
1507
|
});
|
|
1741
1508
|
}
|
|
1742
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: JsonSchemaFormComponent, deps: [{ token: JsonSchemaFormService }, { token: JsonSchemaResolverService }, { token: JsonSchemaValidationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1509
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: JsonSchemaFormComponent, deps: [{ token: JsonSchemaFormService }, { token: JsonSchemaResolverService }, { token: JsonSchemaValidationService }, { token: JsonSchemaStylesService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1743
1510
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: JsonSchemaFormComponent, isStandalone: true, selector: "jsm-json-schema-form", inputs: { schema: "schema", value: "value", data: "data", allowAdditionalProperties: "allowAdditionalProperties" }, outputs: { formReady: "formReady", valueChange: "valueChange", schemaReady: "schemaReady", schemaErrors: "schemaErrors" }, usesOnChanges: true, ngImport: i0, template: `
|
|
1744
1511
|
<div class="jsm-root">
|
|
1745
1512
|
<form class="w-full space-y-5">
|
|
@@ -1855,7 +1622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1855
1622
|
</form>
|
|
1856
1623
|
</div>
|
|
1857
1624
|
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".jsm-root *,.jsm-root *:before,.jsm-root *:after{box-sizing:border-box}.jsm-root input,.jsm-root textarea,.jsm-root select,.jsm-root button{font-family:inherit;font-size:inherit;line-height:inherit}.jsm-root input[type=number]::-webkit-inner-spin-button,.jsm-root input[type=number]::-webkit-outer-spin-button{opacity:1}.jsm-root input:not([type=checkbox]):not([type=radio]):not(.sr-only),.jsm-root textarea,.jsm-root select{border-width:1.5px!important;border-style:solid!important}\n"] }]
|
|
1858
|
-
}], ctorParameters: () => [{ type: JsonSchemaFormService }, { type: JsonSchemaResolverService }, { type: JsonSchemaValidationService }], propDecorators: { schema: [{
|
|
1625
|
+
}], ctorParameters: () => [{ type: JsonSchemaFormService }, { type: JsonSchemaResolverService }, { type: JsonSchemaValidationService }, { type: JsonSchemaStylesService }], propDecorators: { schema: [{
|
|
1859
1626
|
type: Input,
|
|
1860
1627
|
args: [{ required: true }]
|
|
1861
1628
|
}], value: [{
|
|
@@ -1891,5 +1658,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1891
1658
|
* Generated bundle index. Do not edit.
|
|
1892
1659
|
*/
|
|
1893
1660
|
|
|
1894
|
-
export { JsonSchemaFormComponent, JsonSchemaFormModule, JsonSchemaFormService, JsonSchemaNodeComponent, JsonSchemaResolverService, JsonSchemaValidationService };
|
|
1661
|
+
export { JsonSchemaFormComponent, JsonSchemaFormModule, JsonSchemaFormService, JsonSchemaNodeComponent, JsonSchemaResolverService, JsonSchemaStylesService, JsonSchemaValidationService };
|
|
1895
1662
|
//# sourceMappingURL=elle96-ng-json-schema-manager.mjs.map
|