@kodaris/krubble-app-components 1.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.
- package/LICENSE +14 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/krubble-app.bundled.js +3572 -0
- package/dist/krubble-app.bundled.js.map +1 -0
- package/dist/krubble-app.bundled.min.js +2005 -0
- package/dist/krubble-app.bundled.min.js.map +1 -0
- package/dist/krubble-app.umd.js +3577 -0
- package/dist/krubble-app.umd.js.map +1 -0
- package/dist/krubble-app.umd.min.js +2005 -0
- package/dist/krubble-app.umd.min.js.map +1 -0
- package/dist/scaffold/nav-item-edit.d.ts +34 -0
- package/dist/scaffold/nav-item-edit.d.ts.map +1 -0
- package/dist/scaffold/nav-item-edit.js +216 -0
- package/dist/scaffold/nav-item-edit.js.map +1 -0
- package/dist/scaffold.d.ts +368 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +1853 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/screen-detail.d.ts +34 -0
- package/dist/screen-detail.d.ts.map +1 -0
- package/dist/screen-detail.js +104 -0
- package/dist/screen-detail.js.map +1 -0
- package/dist/screen-nav.d.ts +93 -0
- package/dist/screen-nav.d.ts.map +1 -0
- package/dist/screen-nav.js +297 -0
- package/dist/screen-nav.js.map +1 -0
- package/dist/shell.d.ts +104 -0
- package/dist/shell.d.ts.map +1 -0
- package/dist/shell.js +860 -0
- package/dist/shell.js.map +1 -0
- package/dist/subbar.d.ts +34 -0
- package/dist/subbar.d.ts.map +1 -0
- package/dist/subbar.js +133 -0
- package/dist/subbar.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { LitElement, html, css } from 'lit';
|
|
8
|
+
import { customElement, state } from 'lit/decorators.js';
|
|
9
|
+
import '@kodaris/krubble-components';
|
|
10
|
+
let KRNavItemEdit = class KRNavItemEdit extends LitElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.label = '';
|
|
14
|
+
this.icon = '';
|
|
15
|
+
this.url = '';
|
|
16
|
+
this.active = true;
|
|
17
|
+
}
|
|
18
|
+
connectedCallback() {
|
|
19
|
+
super.connectedCallback();
|
|
20
|
+
if (this.data) {
|
|
21
|
+
this.label = this.data.label || '';
|
|
22
|
+
this.icon = this.data.icon || '';
|
|
23
|
+
this.url = this.data.url || '';
|
|
24
|
+
this.active = this.data.active !== false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
handleLabelInput(e) {
|
|
28
|
+
const textField = e.target;
|
|
29
|
+
this.label = textField.value;
|
|
30
|
+
}
|
|
31
|
+
handleIconInput(e) {
|
|
32
|
+
const textField = e.target;
|
|
33
|
+
this.icon = textField.value;
|
|
34
|
+
}
|
|
35
|
+
handleUrlInput(e) {
|
|
36
|
+
const textField = e.target;
|
|
37
|
+
this.url = textField.value;
|
|
38
|
+
}
|
|
39
|
+
handleActiveChange(e) {
|
|
40
|
+
this.active = e.target.checked;
|
|
41
|
+
}
|
|
42
|
+
handleCancel() {
|
|
43
|
+
this.dialogRef.close(undefined);
|
|
44
|
+
}
|
|
45
|
+
handleSave() {
|
|
46
|
+
this.dialogRef.close({
|
|
47
|
+
label: this.label,
|
|
48
|
+
icon: this.icon || undefined,
|
|
49
|
+
url: this.url || undefined,
|
|
50
|
+
active: this.active,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
handleKeyDown(e) {
|
|
54
|
+
if (e.key === 'Enter') {
|
|
55
|
+
this.handleSave();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
render() {
|
|
59
|
+
return html `
|
|
60
|
+
<h2>Edit Navigation Item</h2>
|
|
61
|
+
|
|
62
|
+
<div class="form-group">
|
|
63
|
+
<kr-text-field
|
|
64
|
+
label="Label"
|
|
65
|
+
name="label"
|
|
66
|
+
.value=${this.label}
|
|
67
|
+
@input=${this.handleLabelInput}
|
|
68
|
+
@keydown=${this.handleKeyDown}
|
|
69
|
+
placeholder="Enter label"
|
|
70
|
+
></kr-text-field>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="form-group">
|
|
74
|
+
<kr-text-field
|
|
75
|
+
label="Icon (emoji or SVG)"
|
|
76
|
+
name="icon"
|
|
77
|
+
.value=${this.icon}
|
|
78
|
+
@input=${this.handleIconInput}
|
|
79
|
+
@keydown=${this.handleKeyDown}
|
|
80
|
+
placeholder="e.g. 📊 or <svg>...</svg>"
|
|
81
|
+
></kr-text-field>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div class="form-group">
|
|
85
|
+
<kr-text-field
|
|
86
|
+
label="URL"
|
|
87
|
+
name="url"
|
|
88
|
+
.value=${this.url}
|
|
89
|
+
@input=${this.handleUrlInput}
|
|
90
|
+
@keydown=${this.handleKeyDown}
|
|
91
|
+
placeholder="e.g. /ci/my-page or https://..."
|
|
92
|
+
></kr-text-field>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div class="form-group">
|
|
96
|
+
<div class="checkbox-group">
|
|
97
|
+
<input
|
|
98
|
+
type="checkbox"
|
|
99
|
+
id="active"
|
|
100
|
+
.checked=${this.active}
|
|
101
|
+
@change=${this.handleActiveChange}
|
|
102
|
+
/>
|
|
103
|
+
<label class="checkbox-label" for="active">Visible in navigation</label>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div class="actions">
|
|
108
|
+
<button class="btn-cancel" @click=${this.handleCancel}>Cancel</button>
|
|
109
|
+
<button class="btn-save" @click=${this.handleSave}>Save</button>
|
|
110
|
+
</div>
|
|
111
|
+
`;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
KRNavItemEdit.styles = css `
|
|
115
|
+
:host {
|
|
116
|
+
display: block;
|
|
117
|
+
width: 360px;
|
|
118
|
+
padding: 24px;
|
|
119
|
+
color: rgba(255, 255, 255, 0.9);
|
|
120
|
+
|
|
121
|
+
/* Dark theme for kr-text-field */
|
|
122
|
+
--kr-text-field-label-color: rgba(255, 255, 255, 0.7);
|
|
123
|
+
--kr-text-field-border-color: rgba(255, 255, 255, 0.1);
|
|
124
|
+
--kr-text-field-bg: rgba(255, 255, 255, 0.05);
|
|
125
|
+
--kr-text-field-color: #ffffff;
|
|
126
|
+
--kr-text-field-focus-border-color: #beea4e;
|
|
127
|
+
--kr-text-field-focus-ring-color: rgba(190, 234, 78, 0.1);
|
|
128
|
+
--kr-text-field-placeholder-color: rgba(255, 255, 255, 0.3);
|
|
129
|
+
--kr-text-field-helper-color: rgba(255, 255, 255, 0.5);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
h2 {
|
|
133
|
+
margin: 0 0 24px 0;
|
|
134
|
+
font-size: 18px;
|
|
135
|
+
font-weight: 600;
|
|
136
|
+
color: #ffffff;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.form-group {
|
|
140
|
+
margin-bottom: 20px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.checkbox-group {
|
|
144
|
+
display: flex;
|
|
145
|
+
align-items: center;
|
|
146
|
+
gap: 10px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
input[type="checkbox"] {
|
|
150
|
+
width: 18px;
|
|
151
|
+
height: 18px;
|
|
152
|
+
accent-color: #beea4e;
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.checkbox-label {
|
|
157
|
+
font-size: 14px;
|
|
158
|
+
color: rgba(255, 255, 255, 0.9);
|
|
159
|
+
cursor: pointer;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.actions {
|
|
163
|
+
display: flex;
|
|
164
|
+
gap: 12px;
|
|
165
|
+
justify-content: flex-end;
|
|
166
|
+
margin-top: 28px;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
button {
|
|
170
|
+
padding: 10px 20px;
|
|
171
|
+
border-radius: 6px;
|
|
172
|
+
font-size: 14px;
|
|
173
|
+
font-weight: 500;
|
|
174
|
+
font-family: inherit;
|
|
175
|
+
cursor: pointer;
|
|
176
|
+
transition: all 0.15s ease;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.btn-cancel {
|
|
180
|
+
background: rgba(255, 255, 255, 0.05);
|
|
181
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
182
|
+
color: rgba(255, 255, 255, 0.8);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.btn-cancel:hover {
|
|
186
|
+
background: rgba(255, 255, 255, 0.1);
|
|
187
|
+
color: #ffffff;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.btn-save {
|
|
191
|
+
background: #beea4e;
|
|
192
|
+
border: none;
|
|
193
|
+
color: #10172a;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.btn-save:hover {
|
|
197
|
+
background: #d4f472;
|
|
198
|
+
}
|
|
199
|
+
`;
|
|
200
|
+
__decorate([
|
|
201
|
+
state()
|
|
202
|
+
], KRNavItemEdit.prototype, "label", void 0);
|
|
203
|
+
__decorate([
|
|
204
|
+
state()
|
|
205
|
+
], KRNavItemEdit.prototype, "icon", void 0);
|
|
206
|
+
__decorate([
|
|
207
|
+
state()
|
|
208
|
+
], KRNavItemEdit.prototype, "url", void 0);
|
|
209
|
+
__decorate([
|
|
210
|
+
state()
|
|
211
|
+
], KRNavItemEdit.prototype, "active", void 0);
|
|
212
|
+
KRNavItemEdit = __decorate([
|
|
213
|
+
customElement('kr-nav-item-edit')
|
|
214
|
+
], KRNavItemEdit);
|
|
215
|
+
export { KRNavItemEdit };
|
|
216
|
+
//# sourceMappingURL=nav-item-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nav-item-edit.js","sourceRoot":"","sources":["../../src/scaffold/nav-item-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import type { KRSubbarBreadcrumb } from './subbar.js';
|
|
3
|
+
/**
|
|
4
|
+
* Navigation item interface
|
|
5
|
+
*/
|
|
6
|
+
export interface KRNavItem {
|
|
7
|
+
/** Type of nav entry - 'item' for links, 'group' for expandable sections, 'section' for non-interactive headers */
|
|
8
|
+
type: 'item' | 'group' | 'section';
|
|
9
|
+
/** Unique identifier */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Display label */
|
|
12
|
+
label: string;
|
|
13
|
+
/** Icon - can be emoji or SVG string */
|
|
14
|
+
icon?: string;
|
|
15
|
+
/** URL to navigate to (for type: 'item') */
|
|
16
|
+
url?: string;
|
|
17
|
+
/** Whether this item is visible (false = hidden via customization) */
|
|
18
|
+
active?: boolean;
|
|
19
|
+
/** Sort order for customization (lower = higher in list) */
|
|
20
|
+
order?: number;
|
|
21
|
+
/** Parent group ID, or null for top-level items (used in delta for reordering) */
|
|
22
|
+
parentId?: string | null;
|
|
23
|
+
/** Child navigation items (for type: 'group') */
|
|
24
|
+
children?: KRNavItem[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Computed nav item with preferences applied.
|
|
28
|
+
*
|
|
29
|
+
* Unlike `KRNavItem`, this is a flat structure without nested `children`.
|
|
30
|
+
* Instead, items reference their parent via `parentId`. The `order` and
|
|
31
|
+
* `parentId` fields are required (resolved from preferences or defaults).
|
|
32
|
+
*
|
|
33
|
+
* Returned by `getComputedNav()` and used for rendering and drag/drop.
|
|
34
|
+
*/
|
|
35
|
+
export interface KRNavItemFlat {
|
|
36
|
+
id: string;
|
|
37
|
+
type: 'item' | 'group' | 'section';
|
|
38
|
+
label: string;
|
|
39
|
+
icon?: string;
|
|
40
|
+
url?: string;
|
|
41
|
+
active?: boolean;
|
|
42
|
+
order: number;
|
|
43
|
+
parentId: string | null;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* User profile interface
|
|
47
|
+
*/
|
|
48
|
+
export interface KRUser {
|
|
49
|
+
/** User's display name */
|
|
50
|
+
name: string;
|
|
51
|
+
/** User's email or role */
|
|
52
|
+
email?: string;
|
|
53
|
+
/** Avatar URL or initials will be generated from name */
|
|
54
|
+
avatar?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Application shell component with nav drawer and main content area.
|
|
58
|
+
*
|
|
59
|
+
* ## Features
|
|
60
|
+
* - Collapsible navigation drawer with hierarchical items (groups and items)
|
|
61
|
+
* - User profile display in footer with customization menu
|
|
62
|
+
* - Edit mode for customizing navigation (rename, reorder, hide items, add custom items)
|
|
63
|
+
* - Drag and drop reordering in edit mode
|
|
64
|
+
* - Persistence of customizations via preference API (global/organization level)
|
|
65
|
+
*
|
|
66
|
+
* ## Nav Customization
|
|
67
|
+
* Users can customize the navigation by clicking their profile and selecting
|
|
68
|
+
* "Customize Navigation". This enters edit mode where users can:
|
|
69
|
+
* - Right-click items to edit label, icon, or visibility
|
|
70
|
+
* - Right-click to add new items above/below existing items
|
|
71
|
+
* - Drag and drop to reorder items or move them between groups
|
|
72
|
+
*
|
|
73
|
+
* Customizations are stored globally and apply to all users.
|
|
74
|
+
*
|
|
75
|
+
* ## Preference Storage
|
|
76
|
+
* Preferences are stored as JSON with the following structure:
|
|
77
|
+
* ```json
|
|
78
|
+
* {
|
|
79
|
+
* "nav": {
|
|
80
|
+
* "itemId": { "label": "Custom Label", "icon": "...", "active": true, "order": 0 },
|
|
81
|
+
* "custom-123": { "type": "item", "label": "New Item", "url": "/path", ... }
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* The `nav` object is a delta - it only contains overrides for existing items
|
|
87
|
+
* or definitions for custom items (prefixed with "custom-").
|
|
88
|
+
*
|
|
89
|
+
* ## API Endpoints Used
|
|
90
|
+
* - GET `/api/system/preference/json/scaffold?global=true` - load preferences
|
|
91
|
+
* - POST `/api/system/preference/json/scaffold?global=true` - create new preference
|
|
92
|
+
* - PUT `/api/system/preference/json/scaffold/{uuid}?global=true` - update existing preference
|
|
93
|
+
*
|
|
94
|
+
* @slot - The main content
|
|
95
|
+
*
|
|
96
|
+
* @property {string} logo - URL for the logo image
|
|
97
|
+
* @property {string} title - Title text to display instead of logo
|
|
98
|
+
* @property {'light'|'dark'} scheme - Color scheme: 'light' (default) or 'dark'
|
|
99
|
+
* @property {KRNavItem[]} nav - Navigation items as JSON array
|
|
100
|
+
* @property {KRUser} user - User profile data
|
|
101
|
+
*
|
|
102
|
+
*
|
|
103
|
+
* TODO
|
|
104
|
+
* - Don't hardcode breadcrumbs
|
|
105
|
+
* - Look at renderNormalFooter and renderEditFooter and see if that is what we want to do
|
|
106
|
+
*/
|
|
107
|
+
export declare class KRScaffold extends LitElement {
|
|
108
|
+
static styles: import("lit").CSSResult;
|
|
109
|
+
/**
|
|
110
|
+
* HTTP client for API calls
|
|
111
|
+
*/
|
|
112
|
+
private http;
|
|
113
|
+
/**
|
|
114
|
+
* Default icon for nav items without an icon (shown at top level)
|
|
115
|
+
*/
|
|
116
|
+
private defaultNavItemIcon;
|
|
117
|
+
private boundHandleMouseMove;
|
|
118
|
+
private boundHandleMouseUp;
|
|
119
|
+
private navItemsExpanded;
|
|
120
|
+
private navQuery;
|
|
121
|
+
private activeNavItemId;
|
|
122
|
+
private isNavScrolled;
|
|
123
|
+
private isNavOpened;
|
|
124
|
+
private isEditing;
|
|
125
|
+
private isUserMenuOpen;
|
|
126
|
+
private pref;
|
|
127
|
+
private draggedNavItemId;
|
|
128
|
+
private navItemDropTargetId;
|
|
129
|
+
private navItemDropPosition;
|
|
130
|
+
private pendingRequests;
|
|
131
|
+
private originalFetch;
|
|
132
|
+
private originalXhrOpen;
|
|
133
|
+
private navItemDragPreview;
|
|
134
|
+
private navItemDragStartY;
|
|
135
|
+
private isNavItemDragging;
|
|
136
|
+
private navItemDragExpandTimeout;
|
|
137
|
+
private navInitialized;
|
|
138
|
+
logo: string;
|
|
139
|
+
title: string;
|
|
140
|
+
scheme: 'light' | 'dark';
|
|
141
|
+
nav: KRNavItem[];
|
|
142
|
+
navIconsDisplayed: boolean;
|
|
143
|
+
navExpanded: boolean;
|
|
144
|
+
user: KRUser | null;
|
|
145
|
+
/**
|
|
146
|
+
* Whether to show the subbar with menu toggle
|
|
147
|
+
*/
|
|
148
|
+
subbar: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Breadcrumbs to display in the subbar
|
|
151
|
+
*/
|
|
152
|
+
breadcrumbs: KRSubbarBreadcrumb[];
|
|
153
|
+
constructor();
|
|
154
|
+
connectedCallback(): void;
|
|
155
|
+
updated(changedProperties: Map<string, unknown>): void;
|
|
156
|
+
disconnectedCallback(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Installs global interceptors for fetch and XMLHttpRequest to track pending HTTP requests.
|
|
159
|
+
* Updates `pendingRequests` state when requests start/complete.
|
|
160
|
+
*/
|
|
161
|
+
private installFetchInterceptor;
|
|
162
|
+
/**
|
|
163
|
+
* Restores the original fetch and XMLHttpRequest functions.
|
|
164
|
+
*/
|
|
165
|
+
private uninstallFetchInterceptor;
|
|
166
|
+
/**
|
|
167
|
+
* Returns the computed navigation as a flat array with preferences applied.
|
|
168
|
+
*
|
|
169
|
+
* Transforms the hierarchical `nav` property into a flat list where each item
|
|
170
|
+
* has a `parentId` reference instead of nested `children`. Merges user
|
|
171
|
+
* preference overrides (label, icon, url, active, order, parentId) and
|
|
172
|
+
* includes any custom items added via the edit dialog.
|
|
173
|
+
*
|
|
174
|
+
* @returns Flat array of nav items with preferences applied
|
|
175
|
+
*/
|
|
176
|
+
private getComputedNav;
|
|
177
|
+
/**
|
|
178
|
+
* Returns nav items for a given parent, filtered and sorted for rendering.
|
|
179
|
+
*
|
|
180
|
+
* Filters the computed nav to items matching the parentId, sorts by order,
|
|
181
|
+
* hides inactive items in normal mode, and applies the search query filter.
|
|
182
|
+
* Groups are shown if their label matches or if they have matching children.
|
|
183
|
+
*
|
|
184
|
+
* @param parentId - The parent ID to filter by (null for top-level items)
|
|
185
|
+
* @returns Filtered and sorted nav items ready for rendering
|
|
186
|
+
*/
|
|
187
|
+
private getNavItemChildren;
|
|
188
|
+
/**
|
|
189
|
+
* Handles search input changes for filtering nav items.
|
|
190
|
+
*
|
|
191
|
+
* When a search query is entered, automatically expands any groups that
|
|
192
|
+
* contain matching children so users can see the results. When the search
|
|
193
|
+
* is cleared, collapses all groups back to their default state.
|
|
194
|
+
*
|
|
195
|
+
* @param e - The input event from the search field
|
|
196
|
+
*/
|
|
197
|
+
private handleNavQueryChange;
|
|
198
|
+
/**
|
|
199
|
+
* Clears the search query.
|
|
200
|
+
*/
|
|
201
|
+
private handleNavQueryClear;
|
|
202
|
+
private handleMenuClick;
|
|
203
|
+
/**
|
|
204
|
+
* Handles scroll on nav content to show/hide header shadow.
|
|
205
|
+
*/
|
|
206
|
+
private handleNavScroll;
|
|
207
|
+
/**
|
|
208
|
+
* Toggles the expanded/collapsed state of a nav group with animation.
|
|
209
|
+
* Uses the Web Animations API to animate height transitions.
|
|
210
|
+
* When collapsing, the `nav-group--expanded` class is removed after animation completes.
|
|
211
|
+
* When expanding, the class is added immediately before animation starts.
|
|
212
|
+
*
|
|
213
|
+
* @param itemId - The unique identifier of the nav group to toggle
|
|
214
|
+
*/
|
|
215
|
+
private toggleNavItem;
|
|
216
|
+
/**
|
|
217
|
+
* Handles click events on navigation items.
|
|
218
|
+
*
|
|
219
|
+
* For groups, toggles the expanded/collapsed state.
|
|
220
|
+
* For items, dispatches a cancelable `nav-item-click` custom event.
|
|
221
|
+
*
|
|
222
|
+
* If a listener calls `preventDefault()` on the custom event, native browser
|
|
223
|
+
* navigation is prevented. Otherwise, the default `<a href>` navigation
|
|
224
|
+
* proceeds normally.
|
|
225
|
+
*
|
|
226
|
+
* The `@krubble/angular` package provides `KRScaffoldDirective` which
|
|
227
|
+
* automatically listens for this event and handles navigation using
|
|
228
|
+
* Angular's router. Import `KrubbleModule` in your Angular app to enable
|
|
229
|
+
* SPA navigation without page reloads.
|
|
230
|
+
*
|
|
231
|
+
* @param e - The original click event
|
|
232
|
+
* @param item - The nav item that was clicked
|
|
233
|
+
*/
|
|
234
|
+
private handleNavItemClick;
|
|
235
|
+
/**
|
|
236
|
+
* Updates the active nav item highlight based on the current URL.
|
|
237
|
+
*
|
|
238
|
+
* Compares the first path segment of `window.location.pathname` with each
|
|
239
|
+
* nav item's URL to find a match. When found, highlights that item and
|
|
240
|
+
* expands its parent group if nested.
|
|
241
|
+
*
|
|
242
|
+
* Called automatically by `KRScaffoldDirective` on Angular route changes.
|
|
243
|
+
*/
|
|
244
|
+
updateActiveNavItem(): void;
|
|
245
|
+
private startEditing;
|
|
246
|
+
private cancelEditing;
|
|
247
|
+
private resetPref;
|
|
248
|
+
private savePref;
|
|
249
|
+
private loadPref;
|
|
250
|
+
private handleNavItemContextMenu;
|
|
251
|
+
/**
|
|
252
|
+
* Opens the nav item edit dialog for customizing an item's properties.
|
|
253
|
+
*
|
|
254
|
+
* Opens `KRNavItemEdit` dialog pre-populated with the item's current values.
|
|
255
|
+
* When the user saves, merges the result into the nav delta to persist
|
|
256
|
+
* customizations like label, icon, URL, and visibility.
|
|
257
|
+
*
|
|
258
|
+
* @param item - The nav item to edit
|
|
259
|
+
*/
|
|
260
|
+
private openNavItemEdit;
|
|
261
|
+
/**
|
|
262
|
+
* Adds a new custom nav item relative to an existing item.
|
|
263
|
+
*
|
|
264
|
+
* Creates a placeholder item in the nav delta, shifts existing siblings
|
|
265
|
+
* to make room, then opens the edit dialog so the user can configure
|
|
266
|
+
* the new item's label, icon, and URL.
|
|
267
|
+
*
|
|
268
|
+
* @param targetItem - The existing item to position relative to
|
|
269
|
+
* @param position - Whether to insert 'above' or 'below' the target item
|
|
270
|
+
*/
|
|
271
|
+
private addNavItem;
|
|
272
|
+
/**
|
|
273
|
+
* Initiates a potential drag operation when mouse is pressed on a nav item.
|
|
274
|
+
*
|
|
275
|
+
* Only active in edit mode. Records the starting position and sets up
|
|
276
|
+
* document-level listeners for mouse move and mouse up events. The actual
|
|
277
|
+
* drag doesn't start until the mouse moves more than 5 pixels.
|
|
278
|
+
*
|
|
279
|
+
* @param e - The mouse event
|
|
280
|
+
* @param item - The nav item being pressed
|
|
281
|
+
*/
|
|
282
|
+
private handleNavItemMouseDown;
|
|
283
|
+
/**
|
|
284
|
+
* Handles mouse movement during a nav item drag operation.
|
|
285
|
+
*
|
|
286
|
+
* Initiates dragging after the mouse moves more than 5 pixels (to distinguish
|
|
287
|
+
* from clicks), creates a floating preview element that follows the cursor,
|
|
288
|
+
* and updates the drop target indicator based on mouse position.
|
|
289
|
+
*
|
|
290
|
+
* @param e - The mouse event
|
|
291
|
+
*/
|
|
292
|
+
private handleMouseMove;
|
|
293
|
+
/**
|
|
294
|
+
* Handles the end of a nav item drag operation.
|
|
295
|
+
*
|
|
296
|
+
* Removes document-level mouse listeners, executes the drop if there's a valid
|
|
297
|
+
* target, and cleans up all drag-related state.
|
|
298
|
+
*/
|
|
299
|
+
private handleMouseUp;
|
|
300
|
+
/**
|
|
301
|
+
* Determines where a dragged nav item would be dropped based on mouse position.
|
|
302
|
+
*
|
|
303
|
+
* Loops through all nav items and checks if the mouse is hovering over one.
|
|
304
|
+
* For groups, the item is divided into thirds (above/center/below) where
|
|
305
|
+
* "center" means drop into the group. For regular items, it's halves (above/below).
|
|
306
|
+
*
|
|
307
|
+
* Also handles auto-expanding collapsed groups when hovering over their center,
|
|
308
|
+
* and validates drops (e.g., prevents dropping a group into another group).
|
|
309
|
+
*
|
|
310
|
+
* Updates `navItemDropTargetId` and `navItemDropPosition` state which are used to render
|
|
311
|
+
* visual drop indicators in the UI.
|
|
312
|
+
*
|
|
313
|
+
* @param e - The mouse event from dragging
|
|
314
|
+
*/
|
|
315
|
+
private updateNavItemDropTarget;
|
|
316
|
+
/**
|
|
317
|
+
* Cancels the pending auto-expand timeout for nav groups during drag.
|
|
318
|
+
* Called when the user moves away from a group's center or stops dragging.
|
|
319
|
+
*/
|
|
320
|
+
private clearNavItemDragExpandTimeout;
|
|
321
|
+
/**
|
|
322
|
+
* Auto-expands a collapsed nav group after a delay while dragging over it.
|
|
323
|
+
*
|
|
324
|
+
* Uses a 500ms timeout to prevent groups from expanding too eagerly when the
|
|
325
|
+
* user is just passing over them. Only expands if the user is still hovering
|
|
326
|
+
* over the group's center when the timeout fires.
|
|
327
|
+
*
|
|
328
|
+
* @param itemId - The ID of the group to expand
|
|
329
|
+
*/
|
|
330
|
+
private expandNavGroupOnDrag;
|
|
331
|
+
/**
|
|
332
|
+
* Executes the drop operation after a nav item drag completes.
|
|
333
|
+
*
|
|
334
|
+
* Calculates the new position and parent for the dragged item based on
|
|
335
|
+
* the drop target and position (above/below/center). Updates the navDelta
|
|
336
|
+
* with new order values for the dragged item and shifts siblings as needed.
|
|
337
|
+
*/
|
|
338
|
+
private executeNavItemDrop;
|
|
339
|
+
private toggleUserMenu;
|
|
340
|
+
private closeUserMenu;
|
|
341
|
+
private handleCustomize;
|
|
342
|
+
private renderNormalFooter;
|
|
343
|
+
private renderEditFooter;
|
|
344
|
+
/**
|
|
345
|
+
* Renders a navigation item as either a group or a link.
|
|
346
|
+
*
|
|
347
|
+
* Groups render as expandable `<button>` elements with a chevron indicator and
|
|
348
|
+
* nested children. Items render as `<a>` anchor links with href navigation.
|
|
349
|
+
*
|
|
350
|
+
* Both types support drag-and-drop reordering in edit mode, context menus for
|
|
351
|
+
* customization, and visual indicators for active/hidden/drop-target states.
|
|
352
|
+
*
|
|
353
|
+
* Icons use SVG strings and fall back to `defaultNavItemIcon` when not provided.
|
|
354
|
+
* Icons are only rendered for top-level items, not for children nested within groups.
|
|
355
|
+
*
|
|
356
|
+
* @param item - The flat nav item data to render
|
|
357
|
+
* @param isChild - Whether this item is nested within a group (affects icon rendering)
|
|
358
|
+
* @returns Lit HTML template for the nav item
|
|
359
|
+
*/
|
|
360
|
+
private renderNavItem;
|
|
361
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
362
|
+
}
|
|
363
|
+
declare global {
|
|
364
|
+
interface HTMLElementTagNameMap {
|
|
365
|
+
'kr-scaffold': KRScaffold;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=scaffold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
|