@ng-formworks/cssframework 17.2.7 → 18.0.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.
@@ -1,304 +0,0 @@
1
- import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
2
- import { FrameworkLibraryService, JsonSchemaFormService, addClasses, inArray } from '@ng-formworks/core';
3
- import _, { cloneDeep, map } from 'lodash';
4
- import { Subscription } from 'rxjs';
5
- import { css_fw } from './css-framework.defs';
6
- import { CssframeworkService } from './css-framework.service';
7
-
8
- @Component({
9
- selector: 'css-framework',
10
- templateUrl: './css-framework.component.html',
11
- styleUrls: ['./css-framework.component.scss'],
12
- encapsulation: ViewEncapsulation.None
13
- })
14
- export class CssFrameworkComponent implements OnInit, OnChanges,OnDestroy {
15
- frameworkInitialized = false;
16
- widgetOptions: any; // Options passed to child widget
17
- widgetLayoutNode: any; // layoutNode passed to child widget
18
- options: any; // Options used in this framework
19
- formControl: any = null;
20
- debugOutput: any = '';
21
- debug: any = '';
22
- parentArray: any = null;
23
- isOrderable = false;
24
- @Input() layoutNode: any;
25
- @Input() layoutIndex: number[];
26
- @Input() dataIndex: number[];
27
-
28
- @Input() widgetStyles: css_fw.widgetstyles;
29
-
30
-
31
-
32
-
33
-
34
- //TODO-move to ng-formworks/core utility.functions.ts
35
- applyCssClasses(type, widgetOptions, styleOptions) {
36
- //console.log("applyCssClasses for type:"+type);
37
- let cssClasses = this.widgetStyles[type];
38
- if (!cssClasses || _.isEmpty(cssClasses) ) {
39
- cssClasses = this.widgetStyles.default;
40
- }
41
- Object.keys(cssClasses).forEach(catName => {
42
- let classList = cssClasses[catName];
43
-
44
- if (classList.length) {
45
- widgetOptions[catName] = addClasses(widgetOptions[catName], classList);
46
- }
47
- if (styleOptions) {
48
- widgetOptions[catName] = addClasses(widgetOptions[catName], styleOptions);
49
- }
50
-
51
- })
52
- }
53
-
54
- flattenWidgetStyles(wstyles:css_fw.widgetstyles){
55
- var flattened:any={};
56
- let ignore=['__themes__'];
57
- Object.keys(wstyles).forEach(wkey=>{
58
- let wstyle=wstyles[wkey];
59
- if(ignore.indexOf(wkey)>=0){
60
- flattened[wkey]=wstyle;
61
- return;
62
- }
63
- if(_.isArray(wstyle)){
64
-
65
- flattened[wkey]=wstyle.join(" ");
66
- }
67
- if(_.isObject(wstyle)){//is csscategories
68
- flattened[wkey]=flattened[wkey]||{};
69
- Object.keys(wstyle).forEach(catName=>{
70
- let cssCat=wstyle[catName];
71
-
72
- if(_.isArray(cssCat)){
73
- flattened[wkey][catName]=cssCat.join(" ");
74
- }else{
75
- flattened[wkey][catName]=cssCat;
76
- }
77
- })
78
- }
79
- if(_.isString(wstyle)){
80
- flattened[wkey]=wstyle;
81
- }
82
- })
83
- return flattened
84
- }
85
-
86
- defaultStyling:css_fw.widgetstyles={
87
- array:{},
88
- default:{fieldHtmlClass: "cssfw-form-control"},
89
- __themes__:[{name:'notheme',text:'None'}],
90
- __remove_item__:"cssfw-remove-item",
91
- __array_item_nonref__:{
92
- "htmlClass": "cssfw-array-item-nonref"
93
- },
94
- __active__:{activeClass:"cssfw-active"},
95
- __array__:{htmlClass:"cssfw-array"},
96
- __control_label__:{labelHtmlClass:"cssfw-control-label"},
97
- __form_group__:{htmlClass: "cssfw-form-group"},
98
- __field_addon_left__:"cssfw-addon-left",
99
- __field_addon_right__:"cssfw-addon-right",
100
- __help_block__:"cssfw-help-block",
101
- __required_asterisk__:"cssfw-required-astersisk",
102
- __screen_reader__: "cssfw-screen-reader"
103
-
104
- }
105
-
106
-
107
-
108
-
109
- theme:string
110
- frameworkThemeSubs:Subscription;
111
- constructor(
112
- public changeDetector: ChangeDetectorRef,
113
- public jsf: JsonSchemaFormService,
114
- public jsfFLService:FrameworkLibraryService,
115
- public cssFWService:CssframeworkService
116
- /*@Inject(CSS_FRAMEWORK_CFG ) fwcfg: css_fw.frameworkcfg*/
117
-
118
- ) {
119
-
120
- let activeFramework:any=this.jsfFLService.activeFramework;
121
- let fwcfg=activeFramework.config||{};
122
- this.widgetStyles = Object.assign(this.defaultStyling,fwcfg.widgetstyles);
123
- let defaultTheme=this.widgetStyles.__themes__[0];
124
- let defaultThemeName=cssFWService.activeRequestedTheme||defaultTheme.name;
125
- this.theme=this.options?.theme|| defaultThemeName;
126
- this.frameworkThemeSubs=cssFWService.frameworkTheme$.subscribe(newTheme=>{
127
- this.theme=newTheme;
128
- })
129
-
130
- }
131
-
132
- ngOnDestroy(): void {
133
- this.frameworkThemeSubs.unsubscribe();
134
- this.frameworkThemeSubs=null;
135
- }
136
-
137
-
138
- get showRemoveButton(): boolean {
139
- if (!this.options.removable || this.options.readonly ||
140
- this.layoutNode.type === '$ref'
141
- ) {
142
- return false;
143
- }
144
- if (this.layoutNode.recursiveReference) {
145
- return true;
146
- }
147
- if (!this.layoutNode.arrayItem || !this.parentArray) {
148
- return false;
149
- }
150
- // If array length <= minItems, don't allow removing any items
151
- return this.parentArray.items.length - 1 <= this.parentArray.options.minItems ? false :
152
- // For removable list items, allow removing any item
153
- this.layoutNode.arrayItemType === 'list' ? true :
154
- // For removable tuple items, only allow removing last item in list
155
- this.layoutIndex[this.layoutIndex.length - 1] === this.parentArray.items.length - 2;
156
- }
157
-
158
- ngOnInit() {
159
- this.initializeFramework();
160
- if (this.layoutNode.arrayItem && this.layoutNode.type !== '$ref') {
161
- this.parentArray = this.jsf.getParentNode(this);
162
- if (this.parentArray) {
163
- this.isOrderable = this.layoutNode.arrayItemType === 'list' &&
164
- !this.options.readonly && this.parentArray.options.orderable;
165
- }
166
- }
167
- }
168
-
169
- ngOnChanges() {
170
- if (!this.frameworkInitialized) {
171
- this.initializeFramework();
172
- }
173
- }
174
-
175
- initializeFramework() {
176
- if (this.layoutNode) {
177
- this.options = cloneDeep(this.layoutNode.options);
178
- this.widgetLayoutNode = {
179
- ...this.layoutNode,
180
- options: cloneDeep(this.layoutNode.options)
181
- };
182
- this.widgetOptions = this.widgetLayoutNode.options;
183
- this.formControl = this.jsf.getFormControl(this);
184
-
185
- this.options.isInputWidget = inArray(this.layoutNode.type, [
186
- 'button', 'checkbox', 'checkboxes-inline', 'checkboxes', 'color',
187
- 'date', 'datetime-local', 'datetime', 'email', 'file', 'hidden',
188
- 'image', 'integer', 'month', 'number', 'password', 'radio',
189
- 'radiobuttons', 'radios-inline', 'radios', 'range', 'reset', 'search',
190
- 'select', 'submit', 'tel', 'text', 'textarea', 'time', 'url', 'week'
191
- ]);
192
-
193
- this.options.title = this.setTitle();
194
-
195
- this.options.htmlClass =
196
- addClasses(this.options.htmlClass, 'schema-form-' + this.layoutNode.type);
197
-
198
-
199
- if (this.layoutNode.type === 'array') {
200
- this.options.htmlClass = addClasses(this.options.htmlClass, this.widgetStyles.__array__.htmlClass);
201
- } else if (this.layoutNode.arrayItem && this.layoutNode.type !== '$ref') {
202
- this.options.htmlClass = addClasses(this.options.htmlClass, this.widgetStyles.__array_item_nonref__.htmlClass);
203
- } else {
204
- this.options.htmlClass = addClasses(this.options.htmlClass, this.widgetStyles.__form_group__.htmlClass);
205
- }
206
-
207
-
208
- /*
209
- this.options.htmlClass =
210
- this.layoutNode.type === 'array' ?
211
- addClasses(this.options.htmlClass, ['border','shadow-md','p-1']) :
212
- this.layoutNode.arrayItem && this.layoutNode.type !== '$ref' ?
213
- addClasses(this.options.htmlClass, ['border','shadow-md','p-1']) :
214
- addClasses(this.options.htmlClass, 'mb-1');
215
- */
216
-
217
- /*
218
- this.options.htmlClass =
219
- this.layoutNode.type === 'array' ?
220
- addClasses(this.options.htmlClass, this.widgetStyles.array.htmlClass):
221
- this.layoutNode.arrayItem && this.layoutNode.type !== '$ref' ?
222
- addClasses(this.options.htmlClass, this.widgetStyles.__array_item_nonref__.htmlClass):
223
- addClasses(this.options.htmlClass, this.widgetStyles.__form_group__.htmlClass);
224
- */
225
-
226
- this.widgetOptions.htmlClass = '';
227
- this.options.labelHtmlClass =
228
- addClasses(this.options.labelHtmlClass, this.widgetStyles.__control_label__.labelHtmlClass);
229
- this.widgetOptions.activeClass =
230
- addClasses(this.widgetOptions.activeClass, this.widgetStyles.__active__.activeClass);
231
- this.options.fieldAddonLeft =
232
- this.options.fieldAddonLeft || this.options.prepend;
233
- this.options.fieldAddonRight =
234
- this.options.fieldAddonRight || this.options.append;
235
-
236
- // Add asterisk to titles if required
237
- if (this.options.title && this.layoutNode.type !== 'tab' &&
238
- !this.options.notitle && this.options.required &&
239
- !this.options.title.includes('*')
240
- ) {
241
- let required_asterisk_class=this.widgetStyles.__required_asterisk__||'text-danger'
242
- this.options.title += ` <strong class="${required_asterisk_class}">*</strong>`;
243
- }
244
- if (this.layoutNode.type == 'optionfieldset') {
245
- this.options.messageLocation = 'top';
246
- }
247
- // Set miscelaneous styles and settings for each control type
248
- this.applyCssClasses(this.layoutNode.type, this.widgetOptions, this.options.style);
249
- if (this.formControl) {
250
- this.updateHelpBlock(this.formControl.status);
251
- this.formControl.statusChanges.subscribe(status => this.updateHelpBlock(status));
252
-
253
- if (this.options.debug) {
254
- const vars: any[] = [];
255
- this.debugOutput = map(vars, thisVar => JSON.stringify(thisVar, null, 2)).join('\n');
256
- }
257
- }
258
- this.frameworkInitialized = true;
259
- }
260
-
261
- }
262
-
263
- updateHelpBlock(status) {
264
- this.options.helpBlock = status === 'INVALID' &&
265
- this.options.enableErrorState && this.formControl.errors &&
266
- (this.formControl.dirty || this.options.feedbackOnRender) ?
267
- this.jsf.formatErrors(this.formControl.errors, this.options.validationMessages) :
268
- this.options.description || this.options.help || null;
269
- }
270
-
271
- setTitle(): string {
272
- switch (this.layoutNode.type) {
273
- case 'button':
274
- case 'checkbox':
275
- case 'section':
276
- case 'help':
277
- case 'msg':
278
- case 'submit':
279
- case 'message':
280
- case 'tabarray':
281
- case 'tabs':
282
- case '$ref':
283
- return null;
284
- case 'advancedfieldset':
285
- this.widgetOptions.expandable = true;
286
- this.widgetOptions.title = 'Advanced options';
287
- return null;
288
- case 'authfieldset':
289
- this.widgetOptions.expandable = true;
290
- this.widgetOptions.title = 'Authentication settings';
291
- return null;
292
- case 'fieldset':
293
- this.widgetOptions.title = this.options.title;
294
- return null;
295
- default:
296
- this.widgetOptions.title = null;
297
- return this.jsf.setItemTitle(this);
298
- }
299
- }
300
-
301
- removeItem() {
302
- this.jsf.removeItem(this);
303
- }
304
- }
@@ -1,78 +0,0 @@
1
- import { InjectionToken } from "@angular/core";
2
-
3
- export const CSS_FRAMEWORK_CFG = new InjectionToken<css_fw.frameworkcfg>('CSS_FRAMEWORK_CFG');
4
-
5
- export namespace css_fw{
6
-
7
- export type themeKV=
8
- {
9
- name:string,
10
- text:string
11
- }
12
-
13
- export class csscategories{
14
- fieldHtmlClass?:string|string[]
15
- labelHtmlClass?:string|string[]
16
- htmlClass?:string|string[]
17
- itemLabelHtmlClass?:string|string[]
18
- activeClass?:string|string[]
19
- }
20
-
21
- export type widgetstyles={
22
- '$ref'?:csscategories,
23
- 'alt-date'?:csscategories,
24
- 'alt-datetime'?:csscategories,
25
- __themes__?:themeKV[],
26
- __array_item_nonref__:csscategories,
27
- __form_group__:csscategories,
28
- __control_label__:csscategories,
29
- __active__:csscategories,
30
- __required_asterisk__:string,
31
- __array__:csscategories,
32
- '__remove_item__':string,
33
- __help_block__:string,
34
- __field_addon_left__:string
35
- __field_addon_right__:string,
36
- __screen_reader__:string,
37
- array:csscategories,
38
- authfieldset?:csscategories,
39
- advancedfieldset?:csscategories,
40
- button?:csscategories,
41
- checkbox?:csscategories,
42
- checkboxes?:csscategories,
43
- checkboxbuttons?:csscategories,
44
- 'checkboxes-inline'?:csscategories,
45
- date?:csscategories,
46
- 'datetime-local'?:csscategories,
47
- fieldset?:csscategories,
48
- integer?:csscategories,
49
- number?:csscategories,
50
- optionfieldset?:csscategories,
51
- password?:csscategories,
52
- radiobuttons?:csscategories,
53
- radio?:csscategories,
54
- radios?:csscategories,
55
- "radios-inline"?:csscategories,
56
- 'range'?:csscategories,
57
- section?:csscategories,
58
- selectfieldset?:csscategories,
59
- select?:csscategories,
60
- submit?:csscategories,
61
- text?:csscategories,
62
- tabs?:csscategories,
63
- tabarray?:csscategories,
64
- textarea?:csscategories,
65
- default:csscategories
66
- }
67
- export type frameworkcfg={
68
- name:string,
69
- text:string;
70
- stylesheets:string[],
71
- scripts?:string[],
72
- widgetstyles:widgetstyles,
73
- widgets?:any;
74
- }
75
-
76
-
77
-
78
- }
@@ -1,29 +0,0 @@
1
- import { CommonModule } from '@angular/common';
2
- import { NgModule } from '@angular/core';
3
- import { FrameworkLibraryService, JsonSchemaFormModule, JsonSchemaFormService, WidgetLibraryModule, WidgetLibraryService } from '@ng-formworks/core';
4
- import { CssFrameworkComponent } from './css-framework.component';
5
- import { CssframeworkService } from './css-framework.service';
6
-
7
-
8
-
9
- @NgModule({
10
- declarations: [
11
- CssFrameworkComponent
12
- ],
13
- imports: [
14
- JsonSchemaFormModule,
15
- CommonModule,
16
- WidgetLibraryModule,
17
- ],
18
- exports: [
19
- CssFrameworkComponent
20
- ],
21
- providers: [
22
- JsonSchemaFormService,
23
- FrameworkLibraryService,
24
- WidgetLibraryService,
25
- CssframeworkService
26
- // { provide: Framework, useClass: CssFramework, multi: true },
27
- ]
28
- })
29
- export class CssFrameworkModule { }
@@ -1,16 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
-
3
- import { CssframeworkService } from './css-framework.service';
4
-
5
- describe('CssframeworkService', () => {
6
- let service: CssframeworkService;
7
-
8
- beforeEach(() => {
9
- TestBed.configureTestingModule({});
10
- service = TestBed.inject(CssframeworkService);
11
- });
12
-
13
- it('should be created', () => {
14
- expect(service).toBeTruthy();
15
- });
16
- });
@@ -1,33 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { Observable, Subject } from 'rxjs';
3
-
4
- @Injectable({
5
- providedIn: 'root'
6
- })
7
- export class CssframeworkService {
8
-
9
- frameworkTheme$: Observable<string>;
10
- activeRequestedTheme:string;
11
- frameworkThemeSubject: Subject<string>;
12
- constructor() {
13
- this.frameworkThemeSubject = new Subject<string>();
14
- this.frameworkTheme$ = this.frameworkThemeSubject.asObservable();
15
- }
16
-
17
- //TODO-review: this acts as a public api to change the theme
18
- //but doesn't do the actual change, instead it relies on
19
- //the CssFramewkCoromponent having subscribed to listen
20
- //and perform the actual theme change
21
- requestThemeChange(themeName:string){
22
- this.frameworkThemeSubject.next(themeName);
23
- this.activeRequestedTheme=themeName;
24
- }
25
-
26
- //TODO-review:there's no way of knowing what the individual component instance
27
- //has set its theme to, this is just the theme made through the requestThemeChange
28
- //calls and not guaranteed to correspond to the actual theme set by the
29
- //component instance themselves
30
- getActiveRequestedTheme():string{
31
- return this.activeRequestedTheme;
32
- }
33
- }
@@ -1,99 +0,0 @@
1
- import { Inject, Injectable } from '@angular/core';
2
- import { Framework } from '@ng-formworks/core';
3
- import { CssFrameworkComponent } from './css-framework.component';
4
- import { CSS_FRAMEWORK_CFG, css_fw } from './css-framework.defs';
5
- import { CssframeworkService } from './css-framework.service';
6
-
7
-
8
-
9
- @Injectable()
10
- export class CssFramework extends Framework {
11
- name = 'css';
12
-
13
- framework:any = CssFrameworkComponent;
14
- config:css_fw.frameworkcfg
15
- constructor(@Inject(CSS_FRAMEWORK_CFG ) cfg:css_fw.frameworkcfg,public cssFWService:CssframeworkService){
16
- super();
17
-
18
- this.name=cfg.name;
19
- this.text=cfg.text||this.name;
20
- this.stylesheets=cfg.stylesheets;
21
- this.scripts=cfg.scripts;
22
- this.config=cfg;
23
- this.widgets=cfg.widgets;
24
- }
25
- getActiveTheme():css_fw.themeKV{
26
- let activeRequestedThemeName=this.cssFWService.getActiveRequestedTheme();
27
- let frameWorkThemes=this.config?.widgetstyles?.__themes__;
28
-
29
- let theme=frameWorkThemes && frameWorkThemes[0]
30
- if(activeRequestedThemeName){//if not set return first theme in config;
31
- theme={name:activeRequestedThemeName,text:activeRequestedThemeName};
32
- if(frameWorkThemes){
33
- let filtered=frameWorkThemes.filter(theme=>{return theme.name==activeRequestedThemeName});
34
- theme=(filtered && filtered[0])||theme;
35
- }
36
- }
37
- return theme;
38
- }
39
-
40
- requestThemeChange(name:string){
41
- this.cssFWService.requestThemeChange(name);
42
- }
43
-
44
- registerTheme(newTheme:css_fw.themeKV,overwrite:boolean=true):boolean{
45
- let themeList=this.config?.widgetstyles?.__themes__||[];
46
- let matchedThemes=themeList.filter(theme=>{return newTheme.name==theme.name});
47
- if(matchedThemes && matchedThemes[0]){
48
- if(overwrite){
49
- matchedThemes[0].text=newTheme.text;
50
- return true;
51
- }
52
- if(!overwrite){
53
- return false;
54
- }
55
-
56
- }
57
- if(!matchedThemes || matchedThemes.length==0){
58
- let cfg:any=this.config
59
- cfg.widgetstyles= this.config.widgetstyles||{};
60
- cfg.widgetstyles.__themes__=cfg.widgetstyles.__themes__||[];
61
- cfg.widgetstyles.__themes__.push(newTheme);
62
- return true;
63
- }
64
- };
65
-
66
- unregisterTheme(name:string):boolean{
67
- let themeList=this.config?.widgetstyles?.__themes__;
68
- let foundInd=-1;
69
- if(themeList){
70
- themeList.forEach((theme,ind)=>{
71
- if(name==theme.name){
72
- foundInd=ind;
73
- }
74
- });
75
- if(foundInd>=0){
76
- themeList.splice(foundInd,1);
77
- return true;
78
- }
79
- }
80
- return false;
81
- }
82
-
83
- getConfig():css_fw.frameworkcfg{
84
- return this.config;
85
- }
86
-
87
- /*
88
- stylesheets = [
89
- //TODO-enable for dev only
90
- cdn.tailwindcss.com/3.3.3'
91
- ];
92
-
93
-
94
- scripts = [
95
-
96
- ];
97
- */
98
-
99
- }
package/tsconfig.lib.json DELETED
@@ -1,14 +0,0 @@
1
- /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
- {
3
- "extends": "../../tsconfig.json",
4
- "compilerOptions": {
5
- "outDir": "../../out-tsc/lib",
6
- "declaration": true,
7
- "declarationMap": true,
8
- "inlineSources": true,
9
- "types": []
10
- },
11
- "exclude": [
12
- "**/*.spec.ts"
13
- ]
14
- }
@@ -1,10 +0,0 @@
1
- /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
- {
3
- "extends": "./tsconfig.lib.json",
4
- "compilerOptions": {
5
- "declarationMap": false
6
- },
7
- "angularCompilerOptions": {
8
- "compilationMode": "partial"
9
- }
10
- }
@@ -1,14 +0,0 @@
1
- /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
- {
3
- "extends": "../../tsconfig.json",
4
- "compilerOptions": {
5
- "outDir": "../../out-tsc/spec",
6
- "types": [
7
- "jasmine"
8
- ]
9
- },
10
- "include": [
11
- "**/*.spec.ts",
12
- "**/*.d.ts"
13
- ]
14
- }