@ajsf/material 22.3.2 → 22.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/fesm2022/ajsf-material.mjs +49 -27
- package/fesm2022/ajsf-material.mjs.map +1 -1
- package/package.json +2 -2
- package/types/ajsf-material.d.ts +27 -22
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @ajsf/material
|
|
2
2
|
|
|
3
|
+
[](https://sonarcloud.io/summary/new_code?id=hamzahamidi_ajsf)
|
|
4
|
+
|
|
3
5
|
Angular Material framework for [AJSF](https://github.com/hamzahamidi/ajsf#readme), which builds Angular forms from JSON Schema.
|
|
4
6
|
|
|
5
7
|
## Getting started
|
|
@@ -63,10 +63,10 @@ class FlexLayoutRootComponent {
|
|
|
63
63
|
baseline: 'baseline', stretch: 'stretch',
|
|
64
64
|
}; }
|
|
65
65
|
getFlexBasis(node) {
|
|
66
|
-
return
|
|
66
|
+
return node?.options?.fxFlex || this.getFlexAttribute(node, 'flex-basis');
|
|
67
67
|
}
|
|
68
68
|
getMaxWidth(node) {
|
|
69
|
-
const fxFlex =
|
|
69
|
+
const fxFlex = node?.options?.fxFlex;
|
|
70
70
|
return fxFlex && `${fxFlex}`.trim().endsWith('%') ? fxFlex : null;
|
|
71
71
|
}
|
|
72
72
|
getAlignSelf(node) {
|
|
@@ -79,14 +79,14 @@ class FlexLayoutRootComponent {
|
|
|
79
79
|
return options.order || options.fxFlexOrder || null;
|
|
80
80
|
}
|
|
81
81
|
getOffset(node) {
|
|
82
|
-
return
|
|
82
|
+
return node?.options?.fxFlexOffset || null;
|
|
83
83
|
}
|
|
84
84
|
// Set attributes for flexbox child
|
|
85
85
|
// (container attributes are set in flex-layout-section.component)
|
|
86
86
|
getFlexAttribute(node, attribute) {
|
|
87
87
|
const index = ['flex-grow', 'flex-shrink', 'flex-basis'].indexOf(attribute);
|
|
88
|
-
return (
|
|
89
|
-
|
|
88
|
+
return (node.options?.flex || '').split(/\s+/)[index] ||
|
|
89
|
+
node.options?.[attribute] || ['1', '1', 'auto'][index];
|
|
90
90
|
}
|
|
91
91
|
showWidget(layoutNode) {
|
|
92
92
|
return this.jsf.evaluateCondition(layoutNode, this.dataIndex);
|
|
@@ -201,7 +201,7 @@ class FlexLayoutSectionComponent {
|
|
|
201
201
|
'space-evenly': 'space-evenly', stretch: 'stretch', baseline: 'baseline',
|
|
202
202
|
}; }
|
|
203
203
|
fxAlign(position) {
|
|
204
|
-
const value = `${
|
|
204
|
+
const value = `${this.options?.fxLayoutAlign || ''}`.trim().split(/\s+/)[position];
|
|
205
205
|
return FlexLayoutSectionComponent.ALIGN[value] || null;
|
|
206
206
|
}
|
|
207
207
|
getJustifyContent() {
|
|
@@ -223,10 +223,11 @@ class FlexLayoutSectionComponent {
|
|
|
223
223
|
case 'display':
|
|
224
224
|
return flexActive ? 'flex' : 'initial';
|
|
225
225
|
case 'flex-direction':
|
|
226
|
-
case 'flex-wrap':
|
|
226
|
+
case 'flex-wrap': {
|
|
227
227
|
const index = ['flex-direction', 'flex-wrap'].indexOf(attribute);
|
|
228
228
|
return (this.options['flex-flow'] || '').split(/\s+/)[index] ||
|
|
229
229
|
this.options[attribute] || ['column', 'nowrap'][index];
|
|
230
|
+
}
|
|
230
231
|
case 'justify-content':
|
|
231
232
|
case 'align-items':
|
|
232
233
|
case 'align-content':
|
|
@@ -574,7 +575,7 @@ class MaterialAddReferenceComponent {
|
|
|
574
575
|
}
|
|
575
576
|
get showAddButton() {
|
|
576
577
|
return !this.layoutNode.arrayItem ||
|
|
577
|
-
this.layoutIndex
|
|
578
|
+
this.layoutIndex.at(-1) < this.options.maxItems;
|
|
578
579
|
}
|
|
579
580
|
addItem(event) {
|
|
580
581
|
event.preventDefault();
|
|
@@ -1431,11 +1432,15 @@ class MaterialDesignFrameworkComponent {
|
|
|
1431
1432
|
return false;
|
|
1432
1433
|
}
|
|
1433
1434
|
// If array length <= minItems, don't allow removing any items
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1435
|
+
if (this.parentArray.items.length - 1 <= this.parentArray.options.minItems) {
|
|
1436
|
+
return false;
|
|
1437
|
+
}
|
|
1438
|
+
// For removable list items, allow removing any item
|
|
1439
|
+
if (this.layoutNode.arrayItemType === 'list') {
|
|
1440
|
+
return true;
|
|
1441
|
+
}
|
|
1442
|
+
// For removable tuple items, only allow removing last item in list
|
|
1443
|
+
return this.layoutIndex.at(-1) === this.parentArray.items.length - 2;
|
|
1439
1444
|
}
|
|
1440
1445
|
ngOnInit() {
|
|
1441
1446
|
this.initializeFramework();
|
|
@@ -1486,17 +1491,17 @@ class MaterialDesignFrameworkComponent {
|
|
|
1486
1491
|
}
|
|
1487
1492
|
}
|
|
1488
1493
|
updateTitle() {
|
|
1489
|
-
this.widgetLayoutNode.options.title = this.jsf.parseText(this.dynamicTitle, this.jsf.getFormControlValue(this), this.jsf.getFormControlGroup(this).value, this.dataIndex
|
|
1494
|
+
this.widgetLayoutNode.options.title = this.jsf.parseText(this.dynamicTitle, this.jsf.getFormControlValue(this), this.jsf.getFormControlGroup(this).value, this.dataIndex.at(-1));
|
|
1490
1495
|
}
|
|
1491
1496
|
removeItem() {
|
|
1492
1497
|
this.jsf.removeItem(this);
|
|
1493
1498
|
}
|
|
1494
1499
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MaterialDesignFrameworkComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.JsonSchemaFormService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1495
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: MaterialDesignFrameworkComponent, isStandalone: false, selector: "material-design-framework", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, usesOnChanges: true, ngImport: i0, template: "<div\n [class.array-item]=\"widgetLayoutNode?.arrayItem && widgetLayoutNode?.type !== '$ref'\"\n [orderable]=\"isOrderable\"\n [dataIndex]=\"dataIndex\"\n [layoutIndex]=\"layoutIndex\"\n [layoutNode]=\"widgetLayoutNode\">\n @if (showRemoveButton) {\n <svg\n
|
|
1500
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: MaterialDesignFrameworkComponent, isStandalone: false, selector: "material-design-framework", inputs: { layoutNode: "layoutNode", layoutIndex: "layoutIndex", dataIndex: "dataIndex" }, usesOnChanges: true, ngImport: i0, template: "<div\n [class.array-item]=\"widgetLayoutNode?.arrayItem && widgetLayoutNode?.type !== '$ref'\"\n [orderable]=\"isOrderable\"\n [dataIndex]=\"dataIndex\"\n [layoutIndex]=\"layoutIndex\"\n [layoutNode]=\"widgetLayoutNode\">\n @if (showRemoveButton) {\n <button\n type=\"button\"\n class=\"close-button\"\n aria-label=\"Remove item\"\n (click)=\"removeItem()\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n height=\"18\" width=\"18\" viewBox=\"0 0 24 24\"\n aria-hidden=\"true\">\n <path\n d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z\"/>\n </svg>\n </button>\n }\n <select-widget-widget\n [dataIndex]=\"dataIndex\"\n [layoutIndex]=\"layoutIndex\"\n [layoutNode]=\"widgetLayoutNode\"></select-widget-widget>\n</div>\n@if (widgetLayoutNode?.arrayItem && widgetLayoutNode?.type !== '$ref') {\n <div class=\"spacer\"></div>\n}\n", styles: [".array-item{border-radius:2px;box-shadow:0 3px 1px -2px #0003,0 2px 2px #00000024,0 1px 5px #0000001f;padding:6px;position:relative;transition:box-shadow .28s cubic-bezier(.4,0,.2,1)}.close-button{background:transparent;border:0;cursor:pointer;padding:0;position:absolute;top:6px;right:6px;fill:#0006;opacity:0;pointer-events:none;z-index:500}.close-button:hover{fill:#000c}.array-item:hover>.close-button,.array-item:focus-within>.close-button{opacity:1;pointer-events:auto}.spacer{margin:6px 0}[draggable=true]:hover{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;cursor:move;z-index:10}[draggable=true].drag-target-top{box-shadow:0 -2px #000;position:relative;z-index:20}[draggable=true].drag-target-bottom{box-shadow:0 2px #000;position:relative;z-index:20}\n"], dependencies: [{ kind: "component", type: i1.SelectWidgetComponent, selector: "select-widget-widget", inputs: ["layoutNode", "layoutIndex", "dataIndex"] }, { kind: "directive", type: i1.OrderableDirective, selector: "[orderable]", inputs: ["orderable", "layoutNode", "layoutIndex", "dataIndex"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
1496
1501
|
}
|
|
1497
1502
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MaterialDesignFrameworkComponent, decorators: [{
|
|
1498
1503
|
type: Component,
|
|
1499
|
-
args: [{ selector: 'material-design-framework', changeDetection: ChangeDetectionStrategy.Eager, standalone: false, template: "<div\n [class.array-item]=\"widgetLayoutNode?.arrayItem && widgetLayoutNode?.type !== '$ref'\"\n [orderable]=\"isOrderable\"\n [dataIndex]=\"dataIndex\"\n [layoutIndex]=\"layoutIndex\"\n [layoutNode]=\"widgetLayoutNode\">\n @if (showRemoveButton) {\n <svg\n
|
|
1504
|
+
args: [{ selector: 'material-design-framework', changeDetection: ChangeDetectionStrategy.Eager, standalone: false, template: "<div\n [class.array-item]=\"widgetLayoutNode?.arrayItem && widgetLayoutNode?.type !== '$ref'\"\n [orderable]=\"isOrderable\"\n [dataIndex]=\"dataIndex\"\n [layoutIndex]=\"layoutIndex\"\n [layoutNode]=\"widgetLayoutNode\">\n @if (showRemoveButton) {\n <button\n type=\"button\"\n class=\"close-button\"\n aria-label=\"Remove item\"\n (click)=\"removeItem()\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n height=\"18\" width=\"18\" viewBox=\"0 0 24 24\"\n aria-hidden=\"true\">\n <path\n d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z\"/>\n </svg>\n </button>\n }\n <select-widget-widget\n [dataIndex]=\"dataIndex\"\n [layoutIndex]=\"layoutIndex\"\n [layoutNode]=\"widgetLayoutNode\"></select-widget-widget>\n</div>\n@if (widgetLayoutNode?.arrayItem && widgetLayoutNode?.type !== '$ref') {\n <div class=\"spacer\"></div>\n}\n", styles: [".array-item{border-radius:2px;box-shadow:0 3px 1px -2px #0003,0 2px 2px #00000024,0 1px 5px #0000001f;padding:6px;position:relative;transition:box-shadow .28s cubic-bezier(.4,0,.2,1)}.close-button{background:transparent;border:0;cursor:pointer;padding:0;position:absolute;top:6px;right:6px;fill:#0006;opacity:0;pointer-events:none;z-index:500}.close-button:hover{fill:#000c}.array-item:hover>.close-button,.array-item:focus-within>.close-button{opacity:1;pointer-events:auto}.spacer{margin:6px 0}[draggable=true]:hover{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;cursor:move;z-index:10}[draggable=true].drag-target-top{box-shadow:0 -2px #000;position:relative;z-index:20}[draggable=true].drag-target-bottom{box-shadow:0 2px #000;position:relative;z-index:20}\n"] }]
|
|
1500
1505
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.JsonSchemaFormService }], propDecorators: { layoutNode: [{
|
|
1501
1506
|
type: Input
|
|
1502
1507
|
}], layoutIndex: [{
|
|
@@ -1968,7 +1973,13 @@ class MaterialOneOfComponent {
|
|
|
1968
1973
|
const type = this.layoutNode.type;
|
|
1969
1974
|
this.isFieldset = (type === 'selectfieldset' || type === 'optionfieldset')
|
|
1970
1975
|
&& Array.isArray(this.layoutNode.items) && this.layoutNode.items.length > 0;
|
|
1971
|
-
|
|
1976
|
+
this.initializeSelectList();
|
|
1977
|
+
this.initializeFieldsetValueMap();
|
|
1978
|
+
this.initializeControl();
|
|
1979
|
+
this.selectInitialFieldsetValue();
|
|
1980
|
+
}
|
|
1981
|
+
initializeSelectList() {
|
|
1982
|
+
if (this.isFieldset && !this.hasExplicitFieldsetOptions()) {
|
|
1972
1983
|
this.selectList = this.layoutNode.items.map((item, i) => ({
|
|
1973
1984
|
name: item.options?.legend || item.options?.title || item.name || `Option ${i + 1}`,
|
|
1974
1985
|
value: i
|
|
@@ -1977,26 +1988,37 @@ class MaterialOneOfComponent {
|
|
|
1977
1988
|
else {
|
|
1978
1989
|
this.selectList = buildTitleMap(this.options.titleMap || this.options.enumNames, this.options.enum, !!this.options.required, !!this.options.flatList);
|
|
1979
1990
|
}
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1991
|
+
}
|
|
1992
|
+
initializeFieldsetValueMap() {
|
|
1993
|
+
if (!this.isFieldset || !this.hasExplicitFieldsetOptions()) {
|
|
1994
|
+
return;
|
|
1995
|
+
}
|
|
1996
|
+
let index = 0;
|
|
1997
|
+
for (const entry of this.selectList) {
|
|
1998
|
+
if (entry.value == null || entry.value === '') {
|
|
1999
|
+
continue;
|
|
2000
|
+
}
|
|
2001
|
+
if (index === 0) {
|
|
2002
|
+
this.selectedValue = entry.value;
|
|
1989
2003
|
}
|
|
2004
|
+
this.fieldsetValueMap.set(entry.value, index++);
|
|
1990
2005
|
}
|
|
1991
|
-
|
|
2006
|
+
}
|
|
2007
|
+
initializeControl() {
|
|
2008
|
+
if (!this.isFieldset || this.hasExplicitFieldsetOptions()) {
|
|
1992
2009
|
this.jsf.initializeControl(this, !this.options.readonly);
|
|
1993
2010
|
}
|
|
2011
|
+
}
|
|
2012
|
+
selectInitialFieldsetValue() {
|
|
1994
2013
|
if (this.isFieldset && this.controlValue != null) {
|
|
1995
2014
|
this.selectedValue = this.controlValue;
|
|
1996
2015
|
this._selectedItem = this.fieldsetValueMap.get(this.controlValue)
|
|
1997
2016
|
?? (typeof this.controlValue === 'number' ? this.controlValue : 0);
|
|
1998
2017
|
}
|
|
1999
2018
|
}
|
|
2019
|
+
hasExplicitFieldsetOptions() {
|
|
2020
|
+
return this.options.titleMap || this.options.enum;
|
|
2021
|
+
}
|
|
2000
2022
|
selectChild(event) {
|
|
2001
2023
|
this.selectedValue = event.value;
|
|
2002
2024
|
this._selectedItem =
|