@memberjunction/ng-tabstrip 2.32.1 → 2.33.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 +305 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
# Tab Strip Component
|
|
2
|
+
|
|
3
|
+
A lightweight and flexible Angular tab strip component for MemberJunction applications. This component provides a simple but powerful way to create tabbed interfaces with support for dynamic tabs, custom tab content, and tab management.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Simple API**: Easy to use and customize
|
|
8
|
+
- **Closeable Tabs**: Option to enable tab closing
|
|
9
|
+
- **Scrollable Tabs**: Automatically handles overflow with scrolling buttons
|
|
10
|
+
- **Event-driven**: Rich event system for tab selection and management
|
|
11
|
+
- **Context Menu Support**: Handle right-click events on tabs
|
|
12
|
+
- **Responsive Design**: Adapts to different screen sizes
|
|
13
|
+
- **Tab Navigation**: Methods for tab selection, scrolling, and visibility
|
|
14
|
+
- **Dynamic Content**: Support for dynamically changing tab content
|
|
15
|
+
- **Customizable**: Configure tab appearance and behavior
|
|
16
|
+
- **Lightweight**: Minimal dependencies and overhead
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @memberjunction/ng-tabstrip
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Import the Module
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { MJTabStripModule } from '@memberjunction/ng-tabstrip';
|
|
30
|
+
|
|
31
|
+
@NgModule({
|
|
32
|
+
imports: [
|
|
33
|
+
MJTabStripModule,
|
|
34
|
+
// other imports
|
|
35
|
+
],
|
|
36
|
+
// ...
|
|
37
|
+
})
|
|
38
|
+
export class YourModule { }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Basic Component Usage
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<mj-tabstrip
|
|
45
|
+
[SelectedTabIndex]="selectedTab"
|
|
46
|
+
(TabSelected)="onTabSelected($event)"
|
|
47
|
+
(BeforeTabClosed)="onBeforeTabClosed($event)">
|
|
48
|
+
|
|
49
|
+
<!-- Tab headers -->
|
|
50
|
+
<mj-tab [Name]="'Overview'" [TabCloseable]="false">Overview</mj-tab>
|
|
51
|
+
<mj-tab [Name]="'Details'" [TabCloseable]="true">Details</mj-tab>
|
|
52
|
+
<mj-tab [Name]="'Settings'" [TabCloseable]="true">Settings</mj-tab>
|
|
53
|
+
|
|
54
|
+
<!-- Tab bodies -->
|
|
55
|
+
<mj-tab-body>
|
|
56
|
+
<h2>Overview Content</h2>
|
|
57
|
+
<p>This is the overview tab content...</p>
|
|
58
|
+
</mj-tab-body>
|
|
59
|
+
|
|
60
|
+
<mj-tab-body>
|
|
61
|
+
<h2>Details Content</h2>
|
|
62
|
+
<p>This is the details tab content...</p>
|
|
63
|
+
</mj-tab-body>
|
|
64
|
+
|
|
65
|
+
<mj-tab-body>
|
|
66
|
+
<h2>Settings Content</h2>
|
|
67
|
+
<p>This is the settings tab content...</p>
|
|
68
|
+
</mj-tab-body>
|
|
69
|
+
</mj-tabstrip>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Dynamic Tabs Example
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { Component } from '@angular/core';
|
|
76
|
+
import { TabEvent, TabCancelableEvent, TabClosedEvent } from '@memberjunction/ng-tabstrip';
|
|
77
|
+
|
|
78
|
+
@Component({
|
|
79
|
+
selector: 'app-dynamic-tabs',
|
|
80
|
+
template: `
|
|
81
|
+
<div class="tab-container">
|
|
82
|
+
<button (click)="addNewTab()">Add Tab</button>
|
|
83
|
+
|
|
84
|
+
<mj-tabstrip
|
|
85
|
+
[SelectedTabIndex]="selectedTabIndex"
|
|
86
|
+
(TabSelected)="onTabSelected($event)"
|
|
87
|
+
(BeforeTabClosed)="onBeforeTabClosed($event)"
|
|
88
|
+
(TabClosed)="onTabClosed($event)"
|
|
89
|
+
#tabStrip>
|
|
90
|
+
|
|
91
|
+
<mj-tab
|
|
92
|
+
*ngFor="let tab of tabs"
|
|
93
|
+
[Name]="tab.name"
|
|
94
|
+
[TabCloseable]="tab.closeable"
|
|
95
|
+
[Visible]="tab.visible"
|
|
96
|
+
[ID]="tab.id">
|
|
97
|
+
{{tab.title}}
|
|
98
|
+
</mj-tab>
|
|
99
|
+
|
|
100
|
+
<mj-tab-body *ngFor="let tab of tabs">
|
|
101
|
+
<div class="tab-content">
|
|
102
|
+
<h3>{{tab.title}} Content</h3>
|
|
103
|
+
<p>{{tab.content}}</p>
|
|
104
|
+
<button (click)="updateTabContent(tab.id)">Update Content</button>
|
|
105
|
+
</div>
|
|
106
|
+
</mj-tab-body>
|
|
107
|
+
</mj-tabstrip>
|
|
108
|
+
</div>
|
|
109
|
+
`,
|
|
110
|
+
styles: [`
|
|
111
|
+
.tab-container {
|
|
112
|
+
height: 500px;
|
|
113
|
+
border: 1px solid #ccc;
|
|
114
|
+
padding: 10px;
|
|
115
|
+
}
|
|
116
|
+
.tab-content {
|
|
117
|
+
padding: 20px;
|
|
118
|
+
}
|
|
119
|
+
`]
|
|
120
|
+
})
|
|
121
|
+
export class DynamicTabsComponent {
|
|
122
|
+
selectedTabIndex = 0;
|
|
123
|
+
|
|
124
|
+
tabs = [
|
|
125
|
+
{
|
|
126
|
+
id: 1,
|
|
127
|
+
name: 'home',
|
|
128
|
+
title: 'Home',
|
|
129
|
+
content: 'Welcome to the home tab',
|
|
130
|
+
closeable: false,
|
|
131
|
+
visible: true
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 2,
|
|
135
|
+
name: 'reports',
|
|
136
|
+
title: 'Reports',
|
|
137
|
+
content: 'View your reports here',
|
|
138
|
+
closeable: true,
|
|
139
|
+
visible: true
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
id: 3,
|
|
143
|
+
name: 'settings',
|
|
144
|
+
title: 'Settings',
|
|
145
|
+
content: 'Configure your settings',
|
|
146
|
+
closeable: true,
|
|
147
|
+
visible: true
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
nextTabId = 4;
|
|
152
|
+
|
|
153
|
+
addNewTab() {
|
|
154
|
+
const newTab = {
|
|
155
|
+
id: this.nextTabId++,
|
|
156
|
+
name: `tab-${Date.now()}`,
|
|
157
|
+
title: `New Tab ${this.nextTabId-1}`,
|
|
158
|
+
content: `This is the content for new tab ${this.nextTabId-1}`,
|
|
159
|
+
closeable: true,
|
|
160
|
+
visible: true
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
this.tabs.push(newTab);
|
|
164
|
+
// Need to wait for next tick to select the new tab
|
|
165
|
+
setTimeout(() => {
|
|
166
|
+
this.selectedTabIndex = this.tabs.length - 1;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
updateTabContent(tabId: number) {
|
|
171
|
+
const tab = this.tabs.find(t => t.id === tabId);
|
|
172
|
+
if (tab) {
|
|
173
|
+
tab.content = `Updated content at ${new Date().toLocaleTimeString()}`;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
onTabSelected(event: TabEvent) {
|
|
178
|
+
console.log('Tab selected:', event.index, event.tab?.Name);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
onBeforeTabClosed(event: TabCancelableEvent) {
|
|
182
|
+
// Optionally prevent closing specific tabs
|
|
183
|
+
if (event.tab?.Name === 'important-tab') {
|
|
184
|
+
event.cancel = true;
|
|
185
|
+
alert('This tab cannot be closed!');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
onTabClosed(event: TabClosedEvent) {
|
|
190
|
+
// Remove the tab from our array
|
|
191
|
+
const index = this.tabs.findIndex(t => t.id === event.tab?.ID);
|
|
192
|
+
if (index >= 0) {
|
|
193
|
+
this.tabs.splice(index, 1);
|
|
194
|
+
// Signal that we're done processing
|
|
195
|
+
event.done();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## API Reference
|
|
202
|
+
|
|
203
|
+
### MJTabStripComponent
|
|
204
|
+
|
|
205
|
+
The main component that contains and manages the tabs.
|
|
206
|
+
|
|
207
|
+
#### Inputs
|
|
208
|
+
|
|
209
|
+
- `SelectedTabIndex`: number - The index of the selected tab
|
|
210
|
+
- `FillWidth`: boolean - Whether the tab strip should fill its container width (default: true)
|
|
211
|
+
- `FillHeight`: boolean - Whether the tab strip should fill its container height (default: true)
|
|
212
|
+
- `ScrollAmount`: number - Pixels to scroll when using scroll buttons (default: 150)
|
|
213
|
+
|
|
214
|
+
#### Outputs
|
|
215
|
+
|
|
216
|
+
- `BeforeTabSelected`: EventEmitter<TabCancelableEvent> - Fires before a tab is selected
|
|
217
|
+
- `TabSelected`: EventEmitter<TabEvent> - Fires when a tab is selected
|
|
218
|
+
- `BeforeTabClosed`: EventEmitter<TabCancelableEvent> - Fires before a tab is closed
|
|
219
|
+
- `TabClosed`: EventEmitter<TabClosedEvent> - Fires when a tab is closed
|
|
220
|
+
- `TabContextMenu`: EventEmitter<TabContextMenuEvent> - Fires when a tab is right-clicked
|
|
221
|
+
- `TabScrolled`: EventEmitter<void> - Fires when the tab strip is scrolled
|
|
222
|
+
- `ResizeContainer`: EventEmitter<void> - Fires when the tab strip suggests a container resize
|
|
223
|
+
|
|
224
|
+
#### Methods
|
|
225
|
+
|
|
226
|
+
- `SelectTabByName(tabName: string)`: Selects a tab by its name
|
|
227
|
+
- `GetTabByName(tabName: string)`: Gets a tab component by its name
|
|
228
|
+
- `CloseTab(tabIndex: number)`: Closes a tab by its index
|
|
229
|
+
- `scrollLeft()`: Scrolls the tab strip to the left
|
|
230
|
+
- `scrollRight()`: Scrolls the tab strip to the right
|
|
231
|
+
- `scrollIntoView(tabIndex: number)`: Scrolls to make a specific tab visible
|
|
232
|
+
- `RefreshTabs()`: Refreshes the tab strip after dynamic changes
|
|
233
|
+
|
|
234
|
+
#### Properties
|
|
235
|
+
|
|
236
|
+
- `Tabs`: MJTabComponent[] - Array of tab components
|
|
237
|
+
- `TabBodies`: MJTabBodyComponent[] - Array of tab body components
|
|
238
|
+
|
|
239
|
+
### MJTabComponent
|
|
240
|
+
|
|
241
|
+
Represents a tab header in the tab strip.
|
|
242
|
+
|
|
243
|
+
#### Inputs
|
|
244
|
+
|
|
245
|
+
- `Name`: string - The name of the tab (used for finding tabs by name)
|
|
246
|
+
- `ID`: any - Custom identifier for the tab
|
|
247
|
+
- `Props`: any - Additional properties to associate with the tab
|
|
248
|
+
- `TabCloseable`: boolean - Whether the tab can be closed (default: false)
|
|
249
|
+
- `Visible`: boolean - Whether the tab is visible (default: true)
|
|
250
|
+
- `TabSelected`: boolean - Whether the tab is selected (managed by the tab strip)
|
|
251
|
+
|
|
252
|
+
#### Methods
|
|
253
|
+
|
|
254
|
+
- `selectTab()`: Selects this tab
|
|
255
|
+
- `closeTab(event: MouseEvent)`: Closes this tab
|
|
256
|
+
|
|
257
|
+
### MJTabBodyComponent
|
|
258
|
+
|
|
259
|
+
Represents the content area for a tab.
|
|
260
|
+
|
|
261
|
+
#### Inputs
|
|
262
|
+
|
|
263
|
+
- `TabVisible`: boolean - Whether the tab body is visible (managed by the tab strip)
|
|
264
|
+
- `FillWidth`: boolean - Whether the tab body should fill its container width (default: true)
|
|
265
|
+
- `FillHeight`: boolean - Whether the tab body should fill its container height (default: true)
|
|
266
|
+
|
|
267
|
+
### Event Types
|
|
268
|
+
|
|
269
|
+
#### TabEvent
|
|
270
|
+
|
|
271
|
+
Base event type for tab operations.
|
|
272
|
+
|
|
273
|
+
- `index`: number - The index of the tab
|
|
274
|
+
- `tab`: MJTabComponent - Reference to the tab component
|
|
275
|
+
- `body`: MJTabBodyComponent - Reference to the tab body component
|
|
276
|
+
|
|
277
|
+
#### TabCancelableEvent
|
|
278
|
+
|
|
279
|
+
Event type that allows cancellation of an operation.
|
|
280
|
+
|
|
281
|
+
- All properties from TabEvent
|
|
282
|
+
- `cancel`: boolean - Set to true to cancel the operation
|
|
283
|
+
|
|
284
|
+
#### TabClosedEvent
|
|
285
|
+
|
|
286
|
+
Event type for tab closure.
|
|
287
|
+
|
|
288
|
+
- All properties from TabEvent
|
|
289
|
+
- `newTabIndex`: number - The suggested new tab index after closing
|
|
290
|
+
- `done`: (error?: any) => {} - Callback that must be called when processing is complete
|
|
291
|
+
|
|
292
|
+
#### TabContextMenuEvent
|
|
293
|
+
|
|
294
|
+
Event type for context menu events.
|
|
295
|
+
|
|
296
|
+
- All properties from TabEvent
|
|
297
|
+
- `mouseEvent`: MouseEvent - The original mouse event
|
|
298
|
+
|
|
299
|
+
## Styling
|
|
300
|
+
|
|
301
|
+
The component includes basic CSS that can be customized to match your application's design.
|
|
302
|
+
|
|
303
|
+
## Dependencies
|
|
304
|
+
|
|
305
|
+
- `@memberjunction/ng-container-directives`: For container directives
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-tabstrip",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.33.0",
|
|
4
4
|
"description": "MemberJunction: Very simple tab strip component used in the MJ Explorer app and reusable anywhere else in an Angular project.",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@angular/core": "18.0.2"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@memberjunction/ng-container-directives": "2.
|
|
26
|
+
"@memberjunction/ng-container-directives": "2.33.0",
|
|
27
27
|
"tslib": "^2.3.0"
|
|
28
28
|
},
|
|
29
29
|
"sideEffects": false
|