WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 421809b

Browse files
committed
Added "Accordion" widget.
1 parent 7b8b107 commit 421809b

40 files changed

+1294
-135
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { IWidgetHandler } from "@paperbits/common/editing";
2+
import { IInjector, IInjectorModule } from "@paperbits/common/injection";
3+
import { IWidgetService } from "@paperbits/common/widgets";
4+
import { KnockoutComponentBinder } from "../ko";
5+
import { AccordionViewModel } from "./ko/accordion";
6+
import { AccordionEditor } from "./ko/accordionEditor";
7+
import { AccordionItemEditor } from "./ko/accordionItemEditor";
8+
import { AccordionItemSelector } from "./ko/accordionItemSelector";
9+
import { AccordionViewModelBinder } from "./ko/accordionViewModelBinder";
10+
import { AccordionItemViewModel } from "./ko/accordionItemViewModel";
11+
import { AccordionItemViewModelBinder } from "./ko/accordionItemViewModelBinder";
12+
import { AccordionHandlers } from "./accordionHandlers";
13+
import { AccordionItemHandlers } from "./accordionItemHandlers";
14+
import { AccordionModelBinder } from "./accordionModelBinder";
15+
import { AccordionItemModelBinder } from "./accordionItemModelBinder";
16+
import { AccordionStyleHandler } from "./accordionStyleHandler";
17+
import { AccordionModel, AccordionItemModel } from "./accordionModel";
18+
19+
export class AccordionDesignModule implements IInjectorModule {
20+
public register(injector: IInjector): void {
21+
console.log("Registering Accordion design module...");
22+
// Accordion components
23+
injector.bind("accordion", AccordionViewModel);
24+
injector.bind("accordionEditor", AccordionEditor);
25+
injector.bindSingleton("accordionModelBinder", AccordionModelBinder);
26+
injector.bindSingleton("accordionViewModelBinder", AccordionViewModelBinder);
27+
injector.bindSingleton("accordionHandler", AccordionHandlers);
28+
29+
// AccordionItem components
30+
injector.bind("accordionItem", AccordionItemViewModel);
31+
injector.bind("accordionItemEditor", AccordionItemEditor);
32+
injector.bind("accordionItemSelector", AccordionItemSelector);
33+
injector.bindSingleton("accordionItemModelBinder", AccordionItemModelBinder);
34+
injector.bindSingleton("accordionItemViewModelBinder", AccordionItemViewModelBinder);
35+
injector.bindSingleton("accordionItemHandler", AccordionItemHandlers);
36+
37+
injector.bindToCollection("widgetHandlers", AccordionItemHandlers, "accordionItemHandler");
38+
injector.bindToCollection("styleHandlers", AccordionStyleHandler);
39+
40+
const widgetService = injector.resolve<IWidgetService>("widgetService");
41+
42+
// Register Accordion widget
43+
widgetService.registerWidget("accordion", {
44+
modelDefinition: AccordionModel,
45+
componentBinder: KnockoutComponentBinder,
46+
componentDefinition: AccordionViewModel,
47+
modelBinder: AccordionModelBinder,
48+
viewModelBinder: AccordionViewModelBinder
49+
});
50+
51+
widgetService.registerWidgetEditor("accordion", {
52+
displayName: "Accordion",
53+
iconClass: "widget-icon widget-icon-accordion",
54+
requires: ["js", "interaction"],
55+
componentBinder: KnockoutComponentBinder,
56+
componentDefinition: AccordionEditor,
57+
handlerComponent: AccordionHandlers
58+
});
59+
60+
// Register AccordionItem widget
61+
widgetService.registerWidget("accordion-item", {
62+
modelDefinition: AccordionItemModel,
63+
componentBinder: KnockoutComponentBinder,
64+
componentDefinition: AccordionItemViewModel,
65+
modelBinder: AccordionItemModelBinder,
66+
viewModelBinder: AccordionItemViewModelBinder
67+
});
68+
69+
widgetService.registerWidgetEditor("accordion-item", {
70+
displayName: "Item",
71+
componentBinder: KnockoutComponentBinder,
72+
componentDefinition: AccordionItemEditor,
73+
handlerComponent: AccordionItemHandlers,
74+
selectable: false,
75+
draggable: false
76+
});
77+
}
78+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { IInjectorModule, IInjector } from "@paperbits/common/injection";
2+
import { IWidgetService } from "@paperbits/common/widgets";
3+
import { KnockoutComponentBinder } from "../ko";
4+
import { AccordionViewModel } from "./ko/accordion";
5+
import { AccordionItemViewModel } from "./ko/accordionItemViewModel";
6+
import { AccordionModelBinder } from "./accordionModelBinder";
7+
import { AccordionItemModelBinder } from "./accordionItemModelBinder";
8+
import { AccordionViewModelBinder } from "./ko/accordionViewModelBinder";
9+
import { AccordionItemViewModelBinder } from "./ko/accordionItemViewModelBinder";
10+
import { AccordionStyleHandler } from "./accordionStyleHandler";
11+
import { AccordionModel, AccordionItemModel } from "./accordionModel";
12+
13+
export class AccordionPublishModule implements IInjectorModule {
14+
public register(injector: IInjector): void {
15+
injector.bind("accordion", AccordionViewModel);
16+
injector.bind("accordionItem", AccordionItemViewModel);
17+
injector.bindSingleton("accordionModelBinder", AccordionModelBinder);
18+
injector.bindSingleton("accordionItemModelBinder", AccordionItemModelBinder);
19+
injector.bindSingleton("accordionViewModelBinder", AccordionViewModelBinder);
20+
injector.bindSingleton("accordionItemViewModelBinder", AccordionItemViewModelBinder);
21+
injector.bindToCollection("styleHandlers", AccordionStyleHandler);
22+
23+
const widgetService = injector.resolve<IWidgetService>("widgetService");
24+
25+
widgetService.registerWidget("accordion", {
26+
modelDefinition: AccordionModel,
27+
componentBinder: KnockoutComponentBinder,
28+
componentDefinition: AccordionViewModel,
29+
modelBinder: AccordionModelBinder,
30+
viewModelBinder: AccordionViewModelBinder
31+
});
32+
33+
widgetService.registerWidget("accordion-item", {
34+
modelDefinition: AccordionItemModel,
35+
componentBinder: KnockoutComponentBinder,
36+
componentDefinition: AccordionItemViewModel,
37+
modelBinder: AccordionItemModelBinder,
38+
viewModelBinder: AccordionItemViewModelBinder
39+
});
40+
}
41+
}

src/accordion/accordionContract.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Contract } from "@paperbits/common";
2+
import { LocalStyles } from "@paperbits/common/styles";
3+
4+
/**
5+
* Accordion contract.
6+
*/
7+
export interface AccordionContract extends Contract {
8+
/**
9+
* Local styles.
10+
*/
11+
styles?: LocalStyles;
12+
13+
/**
14+
* Accordion items.
15+
*/
16+
accordionItems: AccordionItemContract[];
17+
}
18+
19+
/**
20+
* Accordion item contract.
21+
*/
22+
export interface AccordionItemContract extends Contract {
23+
/**
24+
* Label on the accordion.
25+
*/
26+
label: string;
27+
28+
/**
29+
* Local styles.
30+
*/
31+
styles?: LocalStyles;
32+
}

src/accordion/accordionHandlers.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { IContextCommandSet, ViewManager } from "@paperbits/common/ui";
2+
import { openWidgetEditorCommand, splitter, switchToParentCommand } from "@paperbits/common/ui/commands";
3+
import { IWidgetHandler, WidgetContext } from "@paperbits/common/editing";
4+
import { AccordionItemModel, AccordionModel } from "./accordionModel";
5+
import { EventManager, Events } from "@paperbits/common/events";
6+
7+
8+
export class AccordionHandlers implements IWidgetHandler<AccordionModel> {
9+
constructor(
10+
private readonly viewManager: ViewManager,
11+
private readonly eventManager: EventManager
12+
) { }
13+
14+
public async getWidgetModel(): Promise<AccordionModel> {
15+
const model = new AccordionModel();
16+
model.accordionItems.push(new AccordionItemModel("Item 1"));
17+
model.accordionItems.push(new AccordionItemModel("Item 2"));
18+
model.accordionItems.push(new AccordionItemModel("Item 3"));
19+
20+
return model;
21+
}
22+
23+
public getContextCommands(context: WidgetContext): IContextCommandSet {
24+
const accordionContextualEditor: IContextCommandSet = {
25+
hoverCommands: null,
26+
defaultCommand: null,
27+
deleteCommand: {
28+
controlType: "toolbox-button",
29+
tooltip: "Delete accordion",
30+
callback: () => {
31+
context.parentModel.widgets.remove(context.model);
32+
context.parentBinding.applyChanges();
33+
this.viewManager.clearContextualCommands();
34+
this.eventManager.dispatchEvent(Events.ContentUpdate);
35+
}
36+
},
37+
selectCommands: [
38+
openWidgetEditorCommand(context, "Edit accordion"),
39+
splitter(),
40+
// {
41+
// controlType: "toolbox-button",
42+
// displayName: activeAccordion.label,
43+
// },
44+
// {
45+
// tooltip: "Select accordion",
46+
// iconClass: "paperbits-icon paperbits-small-down",
47+
// controlType: "toolbox-dropdown",
48+
// component: {
49+
// name: "accordion-item-selector",
50+
// params: {
51+
// activeAccordionItemModel: activeAccordion,
52+
// accordionItemModels: context.binding.model.accordionItems,
53+
// onSelect: (item: AccordionItemModel): void => {
54+
// const index = context.binding.model.accordionItems.indexOf(item);
55+
// context.binding["setActiveItem"](index);
56+
// this.viewManager.clearContextualCommands();
57+
// },
58+
// onCreate: (): void => {
59+
// context.binding.model.accordionItems.push(new AccordionItemModel());
60+
61+
// const index = context.binding.model.accordionItems.length - 1;
62+
63+
// context.binding.applyChanges();
64+
// context.binding["setActiveItem"](index);
65+
66+
// this.viewManager.clearContextualCommands();
67+
// this.eventManager.dispatchEvent(Events.ContentUpdate);
68+
// }
69+
// }
70+
// }
71+
// },
72+
// {
73+
// controlType: "toolbox-splitter"
74+
// },
75+
switchToParentCommand(context)]
76+
};
77+
78+
return accordionContextualEditor;
79+
}
80+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { IContextCommandSet, ViewManager } from "@paperbits/common/ui";
2+
import { WidgetContext } from "@paperbits/common/editing";
3+
import { EventManager, Events } from "@paperbits/common/events";
4+
import { SectionModel } from "../section";
5+
import { AccordionItemModel } from "./accordionModel";
6+
import { WidgetModel } from "@paperbits/common/widgets";
7+
8+
9+
export class AccordionItemHandlers {
10+
constructor(
11+
private readonly viewManager: ViewManager,
12+
private readonly eventManager: EventManager
13+
) { }
14+
15+
public getContextCommands(context: WidgetContext): IContextCommandSet {
16+
const contextualEditor: IContextCommandSet = {
17+
color: "#2b87da",
18+
hoverCommands: [],
19+
deleteCommand: null,
20+
selectCommands: [
21+
{
22+
controlType: "toolbox-button",
23+
displayName: "Edit accordion",
24+
callback: () => this.viewManager.openWidgetEditor(context.parentBinding)
25+
},
26+
{
27+
controlType: "toolbox-splitter"
28+
},
29+
{
30+
controlType: "toolbox-button",
31+
displayName: context.binding.model.label,
32+
tooltip: "Accordion settings",
33+
position: "top right",
34+
color: "#607d8b",
35+
callback: () => this.viewManager.openWidgetEditor(context.binding)
36+
},
37+
{
38+
tooltip: "Select accordion",
39+
iconClass: "paperbits-icon paperbits-small-down",
40+
controlType: "toolbox-dropdown",
41+
component: {
42+
name: "accordion-item-selector",
43+
params: {
44+
activeAccordionItemModel: context.model,
45+
accordionItemModels: context.parentBinding.model.accordionItems,
46+
// onSelect: (item: AccordionItemModel): void => {
47+
// const parent = context.gridItem.getParent();
48+
// const index = parent.binding.model.accordionItems.indexOf(item);
49+
// parent.getChildren()[index].select(true);
50+
// },
51+
onCreate: (): void => {
52+
context.parentBinding.model.accordionItems.push(new AccordionItemModel(`Item ${context.parentBinding.model.accordionItems.length + 1}`));
53+
context.parentBinding.applyChanges();
54+
55+
this.viewManager.clearContextualCommands();
56+
this.eventManager.dispatchEvent(Events.ContentUpdate);
57+
}
58+
}
59+
}
60+
},
61+
{
62+
controlType: "toolbox-splitter"
63+
}
64+
]
65+
};
66+
67+
if (context.parentModel["accordionItems"].length > 1) {
68+
contextualEditor.deleteCommand = {
69+
controlType: "toolbox-button",
70+
tooltip: "Delete item",
71+
color: "#607d8b",
72+
callback: () => {
73+
context.parentModel["accordionItems"].remove(context.model);
74+
context.parentBinding.applyChanges();
75+
this.viewManager.clearContextualCommands();
76+
this.eventManager.dispatchEvent(Events.ContentUpdate);
77+
}
78+
};
79+
}
80+
else {
81+
const accordionParentBinding = context.gridItem.getParent().getParent().binding;
82+
const accordionParentModel = accordionParentBinding.model;
83+
const accordionModel = context.gridItem.getParent().binding.model;
84+
85+
contextualEditor.deleteCommand = {
86+
controlType: "toolbox-button",
87+
tooltip: "Delete accordion",
88+
callback: () => {
89+
accordionParentModel.widgets.remove(accordionModel);
90+
accordionParentBinding.applyChanges();
91+
this.viewManager.clearContextualCommands();
92+
this.eventManager.dispatchEvent(Events.ContentUpdate);
93+
}
94+
};
95+
}
96+
97+
if (context.model.widgets.length === 0) {
98+
contextualEditor.hoverCommands.push({
99+
controlType: "toolbox-button",
100+
color: "#607d8b",
101+
iconClass: "paperbits-icon paperbits-simple-add",
102+
position: "center",
103+
tooltip: "Add widget",
104+
component: {
105+
name: "widget-selector",
106+
params: {
107+
onRequest: () => context.providers,
108+
onSelect: (widget: WidgetModel) => {
109+
context.model.widgets.push(widget);
110+
context.binding.applyChanges();
111+
this.eventManager.dispatchEvent(Events.ContentUpdate);
112+
this.viewManager.clearContextualCommands();
113+
}
114+
}
115+
}
116+
});
117+
}
118+
119+
return contextualEditor;
120+
}
121+
}

0 commit comments

Comments
 (0)