@egose/shadcn-theme-ng 0.0.17 → 0.0.19
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/alert/fesm2022/alert.mjs +1 -1
- package/alert/fesm2022/alert.mjs.map +1 -1
- package/autocomplete/fesm2022/autocomplete.mjs +1 -1
- package/autocomplete/fesm2022/autocomplete.mjs.map +1 -1
- package/autocomplete/index.d.ts +3 -3
- package/checkbox/fesm2022/checkbox.mjs +1 -1
- package/checkbox/fesm2022/checkbox.mjs.map +1 -1
- package/exports.json +1 -1
- package/form-checkbox/fesm2022/form-checkbox.mjs +2 -2
- package/form-checkbox/fesm2022/form-checkbox.mjs.map +1 -1
- package/form-date-picker/fesm2022/form-date-picker.mjs +10 -9
- package/form-date-picker/fesm2022/form-date-picker.mjs.map +1 -1
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +28 -26
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +1 -1
- package/form-select/fesm2022/form-select.mjs +26 -25
- package/form-select/fesm2022/form-select.mjs.map +1 -1
- package/form-text-input/fesm2022/form-text-input.mjs +10 -9
- package/form-text-input/fesm2022/form-text-input.mjs.map +1 -1
- package/form-textarea/fesm2022/form-textarea.mjs +10 -9
- package/form-textarea/fesm2022/form-textarea.mjs.map +1 -1
- package/layout-simple/README.md +64 -0
- package/layout-simple/fesm2022/layout-simple.mjs +315 -0
- package/layout-simple/fesm2022/layout-simple.mjs.map +1 -0
- package/layout-simple/index.d.ts +98 -0
- package/menu/README.md +64 -0
- package/menu/fesm2022/menu.mjs +449 -0
- package/menu/fesm2022/menu.mjs.map +1 -0
- package/menu/index.d.ts +137 -0
- package/package.json +13 -1
- package/sheet/README.md +64 -0
- package/sheet/fesm2022/sheet.mjs +271 -0
- package/sheet/fesm2022/sheet.mjs.map +1 -0
- package/sheet/index.d.ts +79 -0
- package/switch/fesm2022/switch.mjs +8 -4
- package/switch/fesm2022/switch.mjs.map +1 -1
- package/switch/index.d.ts +1 -1
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, Component, viewChild, output, inject, signal, resource, ChangeDetectionStrategy, computed } from '@angular/core';
|
|
3
|
+
import { RouterLink, RouterOutlet } from '@angular/router';
|
|
4
|
+
import * as i1$1 from '@angular/cdk/layout';
|
|
5
|
+
import { Breakpoints } from '@angular/cdk/layout';
|
|
6
|
+
import { hlm } from '@egose/shadcn-theme-ng/utils';
|
|
7
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
8
|
+
import { lucideUser } from '@ng-icons/lucide';
|
|
9
|
+
import { BrnMenuTrigger } from '@spartan-ng/brain/menu';
|
|
10
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
11
|
+
import { HlmMenu, HlmMenuItem, HlmMenuLabel, HlmMenuSeparator, HlmMenuGroup } from '@egose/shadcn-theme-ng/menu';
|
|
12
|
+
import * as i2 from '@angular/forms';
|
|
13
|
+
import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
14
|
+
import * as i1 from '@egose/shadcn-theme-ng/autocomplete';
|
|
15
|
+
import { provideHlmAutocompleteConfig, HlmAutocompleteImports } from '@egose/shadcn-theme-ng/autocomplete';
|
|
16
|
+
import { HlmSpinner } from '@egose/shadcn-theme-ng/spinner';
|
|
17
|
+
|
|
18
|
+
class EgLayoutSimpleUserMenu {
|
|
19
|
+
menus = input([], ...(ngDevMode ? [{ debugName: "menus" }] : []));
|
|
20
|
+
lucideUser = lucideUser;
|
|
21
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: EgLayoutSimpleUserMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
22
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.1", type: EgLayoutSimpleUserMenu, isStandalone: true, selector: "eg-layout-simple-user-menu", inputs: { menus: { classPropertyName: "menus", publicName: "menus", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
23
|
+
provideIcons({
|
|
24
|
+
lucideUser,
|
|
25
|
+
}),
|
|
26
|
+
], ngImport: i0, template: `
|
|
27
|
+
<ng-template #iconTemplate>
|
|
28
|
+
<ng-icon [svg]="lucideUser" size="1.5em" />
|
|
29
|
+
</ng-template>
|
|
30
|
+
|
|
31
|
+
<div class="flex w-full items-center justify-center pt-[20%]">
|
|
32
|
+
<button
|
|
33
|
+
hlmButton
|
|
34
|
+
variant="primary"
|
|
35
|
+
size="icon"
|
|
36
|
+
align="end"
|
|
37
|
+
[brnMenuTriggerFor]="menu"
|
|
38
|
+
[icon]="iconTemplate"
|
|
39
|
+
class="rounded-full! border! border-gray-400!"
|
|
40
|
+
></button>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<ng-template #menu>
|
|
44
|
+
<hlm-menu class="w-56">
|
|
45
|
+
@for (section of menus(); track section) {
|
|
46
|
+
@if (section.label) {
|
|
47
|
+
<hlm-menu-label>{{ section.label }}</hlm-menu-label>
|
|
48
|
+
}
|
|
49
|
+
@if (section.items?.length) {
|
|
50
|
+
<hlm-menu-group>
|
|
51
|
+
@for (item of section.items; track item) {
|
|
52
|
+
@if (item.link) {
|
|
53
|
+
<a hlmMenuItem [routerLink]="item.link" [class]="item.class || ''">
|
|
54
|
+
@if (item.icon) {
|
|
55
|
+
<ng-icon [svg]="item.icon" size="1em" class="mr-2" />
|
|
56
|
+
}
|
|
57
|
+
<span>{{ item.label }}</span>
|
|
58
|
+
</a>
|
|
59
|
+
} @else {
|
|
60
|
+
<button hlmMenuItem (click)="item.action?.()" [class]="item.class || ''">
|
|
61
|
+
@if (item.icon) {
|
|
62
|
+
<ng-icon [svg]="item.icon" size="1em" class="mr-2" />
|
|
63
|
+
}
|
|
64
|
+
<span>{{ item.label }}</span>
|
|
65
|
+
</button>
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
</hlm-menu-group>
|
|
69
|
+
}
|
|
70
|
+
@if (section.separator) {
|
|
71
|
+
<hlm-menu-separator />
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
</hlm-menu>
|
|
75
|
+
</ng-template>
|
|
76
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: BrnMenuTrigger, selector: "[brnMenuTriggerFor]", inputs: ["align"] }, { kind: "component", type: HlmMenu, selector: "hlm-menu", inputs: ["class", "variant"] }, { kind: "directive", type: HlmMenuItem, selector: "[hlmMenuItem]", inputs: ["variant", "inset", "class"] }, { kind: "component", type: HlmMenuLabel, selector: "hlm-menu-label", inputs: ["inset", "class"] }, { kind: "component", type: HlmMenuSeparator, selector: "hlm-menu-separator", inputs: ["class"] }, { kind: "component", type: HlmMenuGroup, selector: "hlm-menu-group" }, { kind: "component", type: HlmButton, selector: "button[hlmButton], a[hlmButton]", inputs: ["variant", "size", "appearance", "loading", "icon", "iconPosition", "userClass", "spinnerUserClass", "disabled", "type"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
|
|
77
|
+
}
|
|
78
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: EgLayoutSimpleUserMenu, decorators: [{
|
|
79
|
+
type: Component,
|
|
80
|
+
args: [{
|
|
81
|
+
selector: 'eg-layout-simple-user-menu',
|
|
82
|
+
imports: [
|
|
83
|
+
BrnMenuTrigger,
|
|
84
|
+
HlmMenu,
|
|
85
|
+
HlmMenuItem,
|
|
86
|
+
HlmMenuLabel,
|
|
87
|
+
HlmMenuSeparator,
|
|
88
|
+
HlmMenuGroup,
|
|
89
|
+
HlmButton,
|
|
90
|
+
NgIcon,
|
|
91
|
+
RouterLink,
|
|
92
|
+
],
|
|
93
|
+
providers: [
|
|
94
|
+
provideIcons({
|
|
95
|
+
lucideUser,
|
|
96
|
+
}),
|
|
97
|
+
],
|
|
98
|
+
template: `
|
|
99
|
+
<ng-template #iconTemplate>
|
|
100
|
+
<ng-icon [svg]="lucideUser" size="1.5em" />
|
|
101
|
+
</ng-template>
|
|
102
|
+
|
|
103
|
+
<div class="flex w-full items-center justify-center pt-[20%]">
|
|
104
|
+
<button
|
|
105
|
+
hlmButton
|
|
106
|
+
variant="primary"
|
|
107
|
+
size="icon"
|
|
108
|
+
align="end"
|
|
109
|
+
[brnMenuTriggerFor]="menu"
|
|
110
|
+
[icon]="iconTemplate"
|
|
111
|
+
class="rounded-full! border! border-gray-400!"
|
|
112
|
+
></button>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<ng-template #menu>
|
|
116
|
+
<hlm-menu class="w-56">
|
|
117
|
+
@for (section of menus(); track section) {
|
|
118
|
+
@if (section.label) {
|
|
119
|
+
<hlm-menu-label>{{ section.label }}</hlm-menu-label>
|
|
120
|
+
}
|
|
121
|
+
@if (section.items?.length) {
|
|
122
|
+
<hlm-menu-group>
|
|
123
|
+
@for (item of section.items; track item) {
|
|
124
|
+
@if (item.link) {
|
|
125
|
+
<a hlmMenuItem [routerLink]="item.link" [class]="item.class || ''">
|
|
126
|
+
@if (item.icon) {
|
|
127
|
+
<ng-icon [svg]="item.icon" size="1em" class="mr-2" />
|
|
128
|
+
}
|
|
129
|
+
<span>{{ item.label }}</span>
|
|
130
|
+
</a>
|
|
131
|
+
} @else {
|
|
132
|
+
<button hlmMenuItem (click)="item.action?.()" [class]="item.class || ''">
|
|
133
|
+
@if (item.icon) {
|
|
134
|
+
<ng-icon [svg]="item.icon" size="1em" class="mr-2" />
|
|
135
|
+
}
|
|
136
|
+
<span>{{ item.label }}</span>
|
|
137
|
+
</button>
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
</hlm-menu-group>
|
|
141
|
+
}
|
|
142
|
+
@if (section.separator) {
|
|
143
|
+
<hlm-menu-separator />
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
</hlm-menu>
|
|
147
|
+
</ng-template>
|
|
148
|
+
`,
|
|
149
|
+
}]
|
|
150
|
+
}] });
|
|
151
|
+
|
|
152
|
+
const transformValueToSearchMap = {};
|
|
153
|
+
class EgGenericAutocomplete {
|
|
154
|
+
defaultOptionTemplate = viewChild('defaultOption', ...(ngDevMode ? [{ debugName: "defaultOptionTemplate" }] : []));
|
|
155
|
+
controlId = input(crypto.randomUUID(), ...(ngDevMode ? [{ debugName: "controlId" }] : []));
|
|
156
|
+
placeholderText = input('Select an option', ...(ngDevMode ? [{ debugName: "placeholderText" }] : []));
|
|
157
|
+
emptyText = input('No options found', ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
158
|
+
optionTemplate = input(this.defaultOptionTemplate, ...(ngDevMode ? [{ debugName: "optionTemplate" }] : []));
|
|
159
|
+
loaderFn = input(async () => [], ...(ngDevMode ? [{ debugName: "loaderFn" }] : []));
|
|
160
|
+
transformValueToSearch = input((value) => String(value), ...(ngDevMode ? [{ debugName: "transformValueToSearch" }] : []));
|
|
161
|
+
optionChange = output();
|
|
162
|
+
_formBuilder = inject(FormBuilder);
|
|
163
|
+
form = this._formBuilder.group({
|
|
164
|
+
option: [null, Validators.required],
|
|
165
|
+
});
|
|
166
|
+
search = signal('', ...(ngDevMode ? [{ debugName: "search" }] : []));
|
|
167
|
+
options = resource({
|
|
168
|
+
defaultValue: [],
|
|
169
|
+
params: () => ({ search: this.search(), negajjang: '1111' }),
|
|
170
|
+
loader: async ({ params }) => {
|
|
171
|
+
const fn = this.loaderFn();
|
|
172
|
+
if (!fn) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
return fn(params);
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
ngOnInit() {
|
|
179
|
+
transformValueToSearchMap[this.controlId()] = this.transformValueToSearch();
|
|
180
|
+
this.form.controls['option'].valueChanges.subscribe((value) => {
|
|
181
|
+
if (value !== null) {
|
|
182
|
+
this.optionChange.emit(value);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
ngOnDestroy() {
|
|
187
|
+
delete transformValueToSearchMap[this.controlId()];
|
|
188
|
+
}
|
|
189
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: EgGenericAutocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
190
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.1", type: EgGenericAutocomplete, isStandalone: true, selector: "eg-generic-autocomplete", inputs: { controlId: { classPropertyName: "controlId", publicName: "controlId", isSignal: true, isRequired: false, transformFunction: null }, placeholderText: { classPropertyName: "placeholderText", publicName: "placeholderText", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, loaderFn: { classPropertyName: "loaderFn", publicName: "loaderFn", isSignal: true, isRequired: false, transformFunction: null }, transformValueToSearch: { classPropertyName: "transformValueToSearch", publicName: "transformValueToSearch", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { optionChange: "optionChange" }, viewQueries: [{ propertyName: "defaultOptionTemplate", first: true, predicate: ["defaultOption"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
191
|
+
<form [formGroup]="form" class="space-y-8">
|
|
192
|
+
<hlm-autocomplete
|
|
193
|
+
[inputId]="controlId()"
|
|
194
|
+
[filteredOptions]="options.value()"
|
|
195
|
+
[optionTemplate]="optionTemplate()"
|
|
196
|
+
[loading]="options.isLoading()"
|
|
197
|
+
[(search)]="search"
|
|
198
|
+
[searchPlaceholderText]="placeholderText()"
|
|
199
|
+
[emptyText]="emptyText()"
|
|
200
|
+
formControlName="option"
|
|
201
|
+
class="bg-white"
|
|
202
|
+
>
|
|
203
|
+
<hlm-spinner loading class="size-6" />
|
|
204
|
+
</hlm-autocomplete>
|
|
205
|
+
</form>
|
|
206
|
+
<ng-template #defaultOption let-option>
|
|
207
|
+
{{ option }}
|
|
208
|
+
</ng-template>
|
|
209
|
+
`, isInline: true, dependencies: [{ kind: "component", type: HlmSpinner, selector: "hlm-spinner", inputs: ["size", "show", "class", "spinnerClass"] }, { kind: "component", type: i1.HlmAutocomplete, selector: "hlm-autocomplete", inputs: ["onSelect", "class", "autocompleteListClass", "autocompleteEmptyClass", "filteredOptions", "value", "search", "transformValueToSearch", "optionTemplate", "loading", "searchPlaceholderText", "loadingText", "emptyText", "ariaLabelToggleButton", "inputId", "disabled"], outputs: ["valueChange", "searchChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
|
|
210
|
+
provideHlmAutocompleteConfig({
|
|
211
|
+
transformValueToSearch: (params, inputId) => {
|
|
212
|
+
const fn = transformValueToSearchMap[inputId];
|
|
213
|
+
return fn(params);
|
|
214
|
+
},
|
|
215
|
+
}),
|
|
216
|
+
], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
217
|
+
}
|
|
218
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: EgGenericAutocomplete, decorators: [{
|
|
219
|
+
type: Component,
|
|
220
|
+
args: [{
|
|
221
|
+
selector: 'eg-generic-autocomplete',
|
|
222
|
+
imports: [HlmSpinner, HlmAutocompleteImports, ReactiveFormsModule],
|
|
223
|
+
template: `
|
|
224
|
+
<form [formGroup]="form" class="space-y-8">
|
|
225
|
+
<hlm-autocomplete
|
|
226
|
+
[inputId]="controlId()"
|
|
227
|
+
[filteredOptions]="options.value()"
|
|
228
|
+
[optionTemplate]="optionTemplate()"
|
|
229
|
+
[loading]="options.isLoading()"
|
|
230
|
+
[(search)]="search"
|
|
231
|
+
[searchPlaceholderText]="placeholderText()"
|
|
232
|
+
[emptyText]="emptyText()"
|
|
233
|
+
formControlName="option"
|
|
234
|
+
class="bg-white"
|
|
235
|
+
>
|
|
236
|
+
<hlm-spinner loading class="size-6" />
|
|
237
|
+
</hlm-autocomplete>
|
|
238
|
+
</form>
|
|
239
|
+
<ng-template #defaultOption let-option>
|
|
240
|
+
{{ option }}
|
|
241
|
+
</ng-template>
|
|
242
|
+
`,
|
|
243
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
244
|
+
viewProviders: [
|
|
245
|
+
provideHlmAutocompleteConfig({
|
|
246
|
+
transformValueToSearch: (params, inputId) => {
|
|
247
|
+
const fn = transformValueToSearchMap[inputId];
|
|
248
|
+
return fn(params);
|
|
249
|
+
},
|
|
250
|
+
}),
|
|
251
|
+
],
|
|
252
|
+
}]
|
|
253
|
+
}] });
|
|
254
|
+
|
|
255
|
+
class EgLayoutSimple {
|
|
256
|
+
breakpointObserver;
|
|
257
|
+
/** Menu data inputs */
|
|
258
|
+
leftMenus = input([], ...(ngDevMode ? [{ debugName: "leftMenus" }] : []));
|
|
259
|
+
rightMenus = input([], ...(ngDevMode ? [{ debugName: "rightMenus" }] : []));
|
|
260
|
+
userMenus = input([], ...(ngDevMode ? [{ debugName: "userMenus" }] : []));
|
|
261
|
+
logo = input('assets/logo.png', ...(ngDevMode ? [{ debugName: "logo" }] : []));
|
|
262
|
+
logoLink = input('/', ...(ngDevMode ? [{ debugName: "logoLink" }] : []));
|
|
263
|
+
hlm = hlm;
|
|
264
|
+
/** Container class inputs */
|
|
265
|
+
leftMenuClass = input('', ...(ngDevMode ? [{ debugName: "leftMenuClass", alias: 'leftClass' }] : [{ alias: 'leftClass' }]));
|
|
266
|
+
rightMenuClass = input('', ...(ngDevMode ? [{ debugName: "rightMenuClass", alias: 'rightClass' }] : [{ alias: 'rightClass' }]));
|
|
267
|
+
/** Link/button base class inputs */
|
|
268
|
+
leftLinkClass = input('', ...(ngDevMode ? [{ debugName: "leftLinkClass", alias: 'leftLinkClass' }] : [{ alias: 'leftLinkClass' }]));
|
|
269
|
+
rightLinkClass = input('', ...(ngDevMode ? [{ debugName: "rightLinkClass", alias: 'rightLinkClass' }] : [{ alias: 'rightLinkClass' }]));
|
|
270
|
+
searchEnabled = input(false, ...(ngDevMode ? [{ debugName: "searchEnabled" }] : []));
|
|
271
|
+
searchPlaceholderText = input('Select an page', ...(ngDevMode ? [{ debugName: "searchPlaceholderText" }] : []));
|
|
272
|
+
searchEmptyText = input('No pages found', ...(ngDevMode ? [{ debugName: "searchEmptyText" }] : []));
|
|
273
|
+
searchOptionTemplate = input(...(ngDevMode ? [undefined, { debugName: "searchOptionTemplate" }] : []));
|
|
274
|
+
searchLoaderFn = input(...(ngDevMode ? [undefined, { debugName: "searchLoaderFn" }] : []));
|
|
275
|
+
searchTransformValueToSearch = input(...(ngDevMode ? [undefined, { debugName: "searchTransformValueToSearch" }] : []));
|
|
276
|
+
searchOptionChange = output();
|
|
277
|
+
/** Computed merged classes for containers */
|
|
278
|
+
_computedLeftClass = computed(() => hlm('hidden md:flex space-x-4 items-center', this.leftMenuClass()), ...(ngDevMode ? [{ debugName: "_computedLeftClass" }] : []));
|
|
279
|
+
_computedRightClass = computed(() => hlm('hidden md:flex space-x-4 items-center', this.rightMenuClass()), ...(ngDevMode ? [{ debugName: "_computedRightClass" }] : []));
|
|
280
|
+
/** Computed merged classes for link/button elements */
|
|
281
|
+
_computedLeftLinkClass = computed(() => hlm('text-gray-700 hover:text-blue-500', this.leftLinkClass()), ...(ngDevMode ? [{ debugName: "_computedLeftLinkClass" }] : []));
|
|
282
|
+
_computedRightLinkClass = computed(() => hlm('text-gray-700 hover:text-blue-500', this.rightLinkClass()), ...(ngDevMode ? [{ debugName: "_computedRightLinkClass" }] : []));
|
|
283
|
+
/** Mobile menu state */
|
|
284
|
+
mobileMenuOpen = false;
|
|
285
|
+
isMobile = signal(false, ...(ngDevMode ? [{ debugName: "isMobile" }] : []));
|
|
286
|
+
constructor(breakpointObserver) {
|
|
287
|
+
this.breakpointObserver = breakpointObserver;
|
|
288
|
+
this.breakpointObserver.observe([Breakpoints.Handset]).subscribe((result) => {
|
|
289
|
+
this.isMobile.set(result.matches);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
toggleMobileMenu() {
|
|
293
|
+
this.mobileMenuOpen = !this.mobileMenuOpen;
|
|
294
|
+
}
|
|
295
|
+
onSearchOptionChange(value) {
|
|
296
|
+
this.searchOptionChange.emit(value);
|
|
297
|
+
}
|
|
298
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: EgLayoutSimple, deps: [{ token: i1$1.BreakpointObserver }], target: i0.ɵɵFactoryTarget.Component });
|
|
299
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.1", type: EgLayoutSimple, isStandalone: true, selector: "eg-layout-simple", inputs: { leftMenus: { classPropertyName: "leftMenus", publicName: "leftMenus", isSignal: true, isRequired: false, transformFunction: null }, rightMenus: { classPropertyName: "rightMenus", publicName: "rightMenus", isSignal: true, isRequired: false, transformFunction: null }, userMenus: { classPropertyName: "userMenus", publicName: "userMenus", isSignal: true, isRequired: false, transformFunction: null }, logo: { classPropertyName: "logo", publicName: "logo", isSignal: true, isRequired: false, transformFunction: null }, logoLink: { classPropertyName: "logoLink", publicName: "logoLink", isSignal: true, isRequired: false, transformFunction: null }, leftMenuClass: { classPropertyName: "leftMenuClass", publicName: "leftClass", isSignal: true, isRequired: false, transformFunction: null }, rightMenuClass: { classPropertyName: "rightMenuClass", publicName: "rightClass", isSignal: true, isRequired: false, transformFunction: null }, leftLinkClass: { classPropertyName: "leftLinkClass", publicName: "leftLinkClass", isSignal: true, isRequired: false, transformFunction: null }, rightLinkClass: { classPropertyName: "rightLinkClass", publicName: "rightLinkClass", isSignal: true, isRequired: false, transformFunction: null }, searchEnabled: { classPropertyName: "searchEnabled", publicName: "searchEnabled", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholderText: { classPropertyName: "searchPlaceholderText", publicName: "searchPlaceholderText", isSignal: true, isRequired: false, transformFunction: null }, searchEmptyText: { classPropertyName: "searchEmptyText", publicName: "searchEmptyText", isSignal: true, isRequired: false, transformFunction: null }, searchOptionTemplate: { classPropertyName: "searchOptionTemplate", publicName: "searchOptionTemplate", isSignal: true, isRequired: false, transformFunction: null }, searchLoaderFn: { classPropertyName: "searchLoaderFn", publicName: "searchLoaderFn", isSignal: true, isRequired: false, transformFunction: null }, searchTransformValueToSearch: { classPropertyName: "searchTransformValueToSearch", publicName: "searchTransformValueToSearch", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchOptionChange: "searchOptionChange" }, ngImport: i0, template: "<div class=\"flex flex-col min-h-screen\">\n <!-- Header -->\n <header\n class=\"flex items-center justify-between bg-gray-100 px-4 py-2 border-b border-gray-300\"\n >\n <!-- Left side: Logo + Left menus -->\n <div class=\"flex items-center space-x-6\">\n <div class=\"logo\">\n <a [routerLink]=\"logoLink()\">\n <img [src]=\"logo()\" alt=\"Logo\" class=\"h-10\" />\n </a>\n </div>\n <!-- Left menus (desktop) -->\n <nav [class]=\"_computedLeftClass()\">\n @for (item of leftMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" [class]=\"hlm(_computedLeftLinkClass(), item.class || '')\"> {{ item.label }} </a>\n } @else {\n <button type=\"button\" (click)=\"item.action?.()\" [class]=\"hlm(_computedLeftLinkClass(), item.class || '')\">\n {{ item.label }}\n </button>\n }\n }\n </nav>\n </div>\n\n <!-- Right menus (desktop) -->\n <nav [class]=\"_computedRightClass()\">\n @if (searchEnabled()) {\n <eg-generic-autocomplete\n [optionTemplate]=\"searchOptionTemplate()\"\n [loaderFn]=\"searchLoaderFn()\"\n [transformValueToSearch]=\"searchTransformValueToSearch()\"\n [placeholderText]=\"searchPlaceholderText()\"\n [emptyText]=\"searchEmptyText()\"\n (optionChange)=\"onSearchOptionChange($event)\"\n ></eg-generic-autocomplete>\n }\n\n @for (item of rightMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" [class]=\"hlm(_computedRightLinkClass(), item.class || '')\"> {{ item.label }} </a>\n } @else {\n <button type=\"button\" (click)=\"item.action?.()\" [class]=\"hlm(_computedRightLinkClass(), item.class || '')\">\n {{ item.label }}\n </button>\n }\n }\n\n @let uMenus = userMenus();\n @if (uMenus && uMenus.length > 0) {\n <eg-layout-simple-user-menu [menus]=\"uMenus\"></eg-layout-simple-user-menu>\n }\n </nav>\n\n <!-- Mobile menu button -->\n <button\n (click)=\"toggleMobileMenu()\"\n class=\"md:hidden p-2 text-gray-700 hover:text-blue-500 focus:outline-none\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-6 w-6\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n </button>\n </header>\n\n <!-- Mobile menu -->\n @if (isMobile() && mobileMenuOpen) {\n <div class=\"bg-gray-100 border-b border-gray-300 px-4 py-2\">\n <nav class=\"flex flex-col space-y-2\">\n <!-- Left menus -->\n @for (item of leftMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\">\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n\n <!-- Right menus -->\n @for (item of rightMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\">\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n\n <!-- User menus (flattened for mobile) -->\n @for (section of userMenus(); track section.label) {\n @if (section.label) {\n <div class=\"font-bold mt-2\">{{ section.label }}</div>\n }\n @if (section.items?.length) {\n @for (item of section.items; track item.label) {\n @if (item.link) {\n <a\n [routerLink]=\"item.link\"\n class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\"\n >\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n }\n @if (section.separator) {\n <hr class=\"border-gray-300 my-2\" />\n }\n }\n </nav>\n </div>\n }\n\n <!-- Main content -->\n <main class=\"flex-1 p-4\">\n <router-outlet></router-outlet>\n </main>\n</div>\n", dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: EgLayoutSimpleUserMenu, selector: "eg-layout-simple-user-menu", inputs: ["menus"] }, { kind: "component", type: EgGenericAutocomplete, selector: "eg-generic-autocomplete", inputs: ["controlId", "placeholderText", "emptyText", "optionTemplate", "loaderFn", "transformValueToSearch"], outputs: ["optionChange"] }] });
|
|
300
|
+
}
|
|
301
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: EgLayoutSimple, decorators: [{
|
|
302
|
+
type: Component,
|
|
303
|
+
args: [{ selector: 'eg-layout-simple', standalone: true, imports: [RouterOutlet, RouterLink, EgLayoutSimpleUserMenu, EgGenericAutocomplete], template: "<div class=\"flex flex-col min-h-screen\">\n <!-- Header -->\n <header\n class=\"flex items-center justify-between bg-gray-100 px-4 py-2 border-b border-gray-300\"\n >\n <!-- Left side: Logo + Left menus -->\n <div class=\"flex items-center space-x-6\">\n <div class=\"logo\">\n <a [routerLink]=\"logoLink()\">\n <img [src]=\"logo()\" alt=\"Logo\" class=\"h-10\" />\n </a>\n </div>\n <!-- Left menus (desktop) -->\n <nav [class]=\"_computedLeftClass()\">\n @for (item of leftMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" [class]=\"hlm(_computedLeftLinkClass(), item.class || '')\"> {{ item.label }} </a>\n } @else {\n <button type=\"button\" (click)=\"item.action?.()\" [class]=\"hlm(_computedLeftLinkClass(), item.class || '')\">\n {{ item.label }}\n </button>\n }\n }\n </nav>\n </div>\n\n <!-- Right menus (desktop) -->\n <nav [class]=\"_computedRightClass()\">\n @if (searchEnabled()) {\n <eg-generic-autocomplete\n [optionTemplate]=\"searchOptionTemplate()\"\n [loaderFn]=\"searchLoaderFn()\"\n [transformValueToSearch]=\"searchTransformValueToSearch()\"\n [placeholderText]=\"searchPlaceholderText()\"\n [emptyText]=\"searchEmptyText()\"\n (optionChange)=\"onSearchOptionChange($event)\"\n ></eg-generic-autocomplete>\n }\n\n @for (item of rightMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" [class]=\"hlm(_computedRightLinkClass(), item.class || '')\"> {{ item.label }} </a>\n } @else {\n <button type=\"button\" (click)=\"item.action?.()\" [class]=\"hlm(_computedRightLinkClass(), item.class || '')\">\n {{ item.label }}\n </button>\n }\n }\n\n @let uMenus = userMenus();\n @if (uMenus && uMenus.length > 0) {\n <eg-layout-simple-user-menu [menus]=\"uMenus\"></eg-layout-simple-user-menu>\n }\n </nav>\n\n <!-- Mobile menu button -->\n <button\n (click)=\"toggleMobileMenu()\"\n class=\"md:hidden p-2 text-gray-700 hover:text-blue-500 focus:outline-none\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-6 w-6\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n </button>\n </header>\n\n <!-- Mobile menu -->\n @if (isMobile() && mobileMenuOpen) {\n <div class=\"bg-gray-100 border-b border-gray-300 px-4 py-2\">\n <nav class=\"flex flex-col space-y-2\">\n <!-- Left menus -->\n @for (item of leftMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\">\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n\n <!-- Right menus -->\n @for (item of rightMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\">\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n\n <!-- User menus (flattened for mobile) -->\n @for (section of userMenus(); track section.label) {\n @if (section.label) {\n <div class=\"font-bold mt-2\">{{ section.label }}</div>\n }\n @if (section.items?.length) {\n @for (item of section.items; track item.label) {\n @if (item.link) {\n <a\n [routerLink]=\"item.link\"\n class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\"\n >\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"text-left cursor-pointer text-gray-700 hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n }\n @if (section.separator) {\n <hr class=\"border-gray-300 my-2\" />\n }\n }\n </nav>\n </div>\n }\n\n <!-- Main content -->\n <main class=\"flex-1 p-4\">\n <router-outlet></router-outlet>\n </main>\n</div>\n" }]
|
|
304
|
+
}], ctorParameters: () => [{ type: i1$1.BreakpointObserver }] });
|
|
305
|
+
|
|
306
|
+
/*
|
|
307
|
+
* Public API Surface of layout-simple
|
|
308
|
+
*/
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Generated bundle index. Do not edit.
|
|
312
|
+
*/
|
|
313
|
+
|
|
314
|
+
export { EgGenericAutocomplete, EgLayoutSimple, EgLayoutSimpleUserMenu };
|
|
315
|
+
//# sourceMappingURL=layout-simple.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout-simple.mjs","sources":["../../../projects/layout-simple/src/lib/user-menu.ts","../../../projects/layout-simple/src/lib/search.ts","../../../projects/layout-simple/src/lib/layout.ts","../../../projects/layout-simple/src/lib/layout.html","../../../projects/layout-simple/src/public-api.ts","../../../projects/layout-simple/src/layout-simple.ts"],"sourcesContent":["import { Component, input } from '@angular/core';\nimport { provideIcons } from '@ng-icons/core';\nimport { lucideUser } from '@ng-icons/lucide';\nimport { RouterLink } from '@angular/router';\nimport { BrnMenuTrigger } from '@spartan-ng/brain/menu';\nimport { HlmButton } from '@egose/shadcn-theme-ng/button';\nimport { HlmMenu, HlmMenuGroup, HlmMenuItem, HlmMenuLabel, HlmMenuSeparator } from '@egose/shadcn-theme-ng/menu';\nimport { NgIcon } from '@ng-icons/core';\n\n// Interface for menu items\nexport interface UserMenuItem {\n label: string;\n icon?: any;\n action?: () => void;\n link?: string;\n class?: string;\n}\n\n// Interface for menu sections\nexport interface UserMenuSection {\n label?: string;\n separator?: boolean;\n items?: UserMenuItem[];\n}\n\n@Component({\n selector: 'eg-layout-simple-user-menu',\n imports: [\n BrnMenuTrigger,\n HlmMenu,\n HlmMenuItem,\n HlmMenuLabel,\n HlmMenuSeparator,\n HlmMenuGroup,\n HlmButton,\n NgIcon,\n RouterLink,\n ],\n providers: [\n provideIcons({\n lucideUser,\n }),\n ],\n template: `\n <ng-template #iconTemplate>\n <ng-icon [svg]=\"lucideUser\" size=\"1.5em\" />\n </ng-template>\n\n <div class=\"tw:flex tw:w-full tw:items-center tw:justify-center tw:pt-[20%]\">\n <button\n hlmButton\n variant=\"primary\"\n size=\"icon\"\n align=\"end\"\n [brnMenuTriggerFor]=\"menu\"\n [icon]=\"iconTemplate\"\n class=\"tw:rounded-full! tw:border! tw:border-gray-400!\"\n ></button>\n </div>\n\n <ng-template #menu>\n <hlm-menu class=\"tw:w-56\">\n @for (section of menus(); track section) {\n @if (section.label) {\n <hlm-menu-label>{{ section.label }}</hlm-menu-label>\n }\n @if (section.items?.length) {\n <hlm-menu-group>\n @for (item of section.items; track item) {\n @if (item.link) {\n <a hlmMenuItem [routerLink]=\"item.link\" [class]=\"item.class || ''\">\n @if (item.icon) {\n <ng-icon [svg]=\"item.icon\" size=\"1em\" class=\"tw:mr-2\" />\n }\n <span>{{ item.label }}</span>\n </a>\n } @else {\n <button hlmMenuItem (click)=\"item.action?.()\" [class]=\"item.class || ''\">\n @if (item.icon) {\n <ng-icon [svg]=\"item.icon\" size=\"1em\" class=\"tw:mr-2\" />\n }\n <span>{{ item.label }}</span>\n </button>\n }\n }\n </hlm-menu-group>\n }\n @if (section.separator) {\n <hlm-menu-separator />\n }\n }\n </hlm-menu>\n </ng-template>\n `,\n})\nexport class EgLayoutSimpleUserMenu {\n menus = input<UserMenuSection[]>([]);\n\n lucideUser = lucideUser;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n TemplateRef,\n signal,\n input,\n output,\n viewChild,\n inject,\n resource,\n} from '@angular/core';\nimport { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';\nimport {\n HlmAutocompleteImports,\n provideHlmAutocompleteConfig,\n HlmAutocompleteOption,\n} from '@egose/shadcn-theme-ng/autocomplete';\nimport { HlmSpinner } from '@egose/shadcn-theme-ng/spinner';\n\nconst transformValueToSearchMap: Record<string, any> = {};\n\n@Component({\n selector: 'eg-generic-autocomplete',\n imports: [HlmSpinner, HlmAutocompleteImports, ReactiveFormsModule],\n template: `\n <form [formGroup]=\"form\" class=\"space-y-8\">\n <hlm-autocomplete\n [inputId]=\"controlId()\"\n [filteredOptions]=\"options.value()\"\n [optionTemplate]=\"optionTemplate()\"\n [loading]=\"options.isLoading()\"\n [(search)]=\"search\"\n [searchPlaceholderText]=\"placeholderText()\"\n [emptyText]=\"emptyText()\"\n formControlName=\"option\"\n class=\"tw:bg-white\"\n >\n <hlm-spinner loading class=\"size-6\" />\n </hlm-autocomplete>\n </form>\n <ng-template #defaultOption let-option>\n {{ option }}\n </ng-template>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n viewProviders: [\n provideHlmAutocompleteConfig({\n transformValueToSearch: (params, inputId) => {\n const fn = transformValueToSearchMap[inputId];\n return fn(params);\n },\n }),\n ],\n})\nexport class EgGenericAutocomplete<TItem, TParams extends object = { search: string }> {\n defaultOptionTemplate = viewChild<TemplateRef<HlmAutocompleteOption<TItem>>>('defaultOption');\n controlId = input<string>(crypto.randomUUID());\n placeholderText = input<string>('Select an option');\n emptyText = input<string>('No options found');\n\n optionTemplate = input<TemplateRef<HlmAutocompleteOption<TItem>> | undefined>(this.defaultOptionTemplate as any);\n loaderFn = input<((params: TParams) => Promise<TItem[]>) | undefined>(async () => []);\n transformValueToSearch = input<((value: TItem) => string) | undefined>((value: TItem) => String(value));\n\n public readonly optionChange = output<TItem>();\n private readonly _formBuilder = inject(FormBuilder);\n public form = this._formBuilder.group({\n option: [null, Validators.required],\n });\n\n public readonly search = signal<string>('');\n\n public options = resource<TItem[], TParams>({\n defaultValue: [] as TItem[],\n params: () => ({ search: this.search(), negajjang: '1111' }) as TParams,\n loader: async ({ params }) => {\n const fn = this.loaderFn();\n if (!fn) {\n return [];\n }\n\n return fn(params);\n },\n });\n\n ngOnInit() {\n transformValueToSearchMap[this.controlId()] = this.transformValueToSearch();\n\n this.form.controls['option'].valueChanges.subscribe((value) => {\n if (value !== null) {\n this.optionChange.emit(value);\n }\n });\n }\n\n ngOnDestroy() {\n delete transformValueToSearchMap[this.controlId()];\n }\n}\n","import { Component, input, output, computed, signal, viewChild, TemplateRef } from '@angular/core';\nimport { RouterOutlet, RouterLink } from '@angular/router';\nimport { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';\nimport { ClassValue } from 'clsx';\nimport { hlm } from '@egose/shadcn-theme-ng/utils';\nimport { HlmAutocompleteOption } from '@egose/shadcn-theme-ng/autocomplete';\nimport { EgLayoutSimpleUserMenu, type UserMenuSection } from './user-menu';\nimport { EgGenericAutocomplete } from './search';\n\n// Updated interface for left/right menu items\nexport interface MenuItem {\n label: string;\n link?: string; // optional router link\n action?: () => void; // optional click handler\n class?: string; // optional per-item CSS/Tailwind classes\n}\n\n@Component({\n selector: 'eg-layout-simple',\n standalone: true,\n imports: [RouterOutlet, RouterLink, EgLayoutSimpleUserMenu, EgGenericAutocomplete],\n templateUrl: './layout.html',\n})\nexport class EgLayoutSimple<TItem, TParams extends object = { search: string }> {\n /** Menu data inputs */\n leftMenus = input<MenuItem[]>([]);\n rightMenus = input<MenuItem[]>([]);\n userMenus = input<UserMenuSection[]>([]);\n logo = input<string>('assets/logo.png');\n logoLink = input<string>('/');\n hlm = hlm;\n\n /** Container class inputs */\n leftMenuClass = input<ClassValue>('', { alias: 'leftClass' });\n rightMenuClass = input<ClassValue>('', { alias: 'rightClass' });\n\n /** Link/button base class inputs */\n leftLinkClass = input<ClassValue>('', { alias: 'leftLinkClass' });\n rightLinkClass = input<ClassValue>('', { alias: 'rightLinkClass' });\n\n searchEnabled = input<boolean>(false);\n searchPlaceholderText = input<string>('Select an page');\n searchEmptyText = input<string>('No pages found');\n searchOptionTemplate = input<TemplateRef<HlmAutocompleteOption<TItem>>>();\n searchLoaderFn = input<(params: TParams) => Promise<TItem[]>>();\n searchTransformValueToSearch = input<(value: TItem) => string>();\n\n public readonly searchOptionChange = output<TItem>();\n\n /** Computed merged classes for containers */\n protected readonly _computedLeftClass = computed(() =>\n hlm('tw:hidden tw:md:flex tw:space-x-4 tw:items-center', this.leftMenuClass()),\n );\n protected readonly _computedRightClass = computed(() =>\n hlm('tw:hidden tw:md:flex tw:space-x-4 tw:items-center', this.rightMenuClass()),\n );\n\n /** Computed merged classes for link/button elements */\n protected readonly _computedLeftLinkClass = computed(() =>\n hlm('tw:text-gray-700 tw:hover:text-blue-500', this.leftLinkClass()),\n );\n protected readonly _computedRightLinkClass = computed(() =>\n hlm('tw:text-gray-700 tw:hover:text-blue-500', this.rightLinkClass()),\n );\n\n /** Mobile menu state */\n mobileMenuOpen = false;\n isMobile = signal(false);\n\n constructor(private breakpointObserver: BreakpointObserver) {\n this.breakpointObserver.observe([Breakpoints.Handset]).subscribe((result) => {\n this.isMobile.set(result.matches);\n });\n }\n\n toggleMobileMenu() {\n this.mobileMenuOpen = !this.mobileMenuOpen;\n }\n\n onSearchOptionChange(value: TItem) {\n this.searchOptionChange.emit(value);\n }\n}\n","<div class=\"tw:flex tw:flex-col tw:min-h-screen\">\n <!-- Header -->\n <header\n class=\"tw:flex tw:items-center tw:justify-between tw:bg-gray-100 tw:px-4 tw:py-2 tw:border-b tw:border-gray-300\"\n >\n <!-- Left side: Logo + Left menus -->\n <div class=\"tw:flex tw:items-center tw:space-x-6\">\n <div class=\"logo\">\n <a [routerLink]=\"logoLink()\">\n <img [src]=\"logo()\" alt=\"Logo\" class=\"tw:h-10\" />\n </a>\n </div>\n <!-- Left menus (desktop) -->\n <nav [class]=\"_computedLeftClass()\">\n @for (item of leftMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" [class]=\"hlm(_computedLeftLinkClass(), item.class || '')\"> {{ item.label }} </a>\n } @else {\n <button type=\"button\" (click)=\"item.action?.()\" [class]=\"hlm(_computedLeftLinkClass(), item.class || '')\">\n {{ item.label }}\n </button>\n }\n }\n </nav>\n </div>\n\n <!-- Right menus (desktop) -->\n <nav [class]=\"_computedRightClass()\">\n @if (searchEnabled()) {\n <eg-generic-autocomplete\n [optionTemplate]=\"searchOptionTemplate()\"\n [loaderFn]=\"searchLoaderFn()\"\n [transformValueToSearch]=\"searchTransformValueToSearch()\"\n [placeholderText]=\"searchPlaceholderText()\"\n [emptyText]=\"searchEmptyText()\"\n (optionChange)=\"onSearchOptionChange($event)\"\n ></eg-generic-autocomplete>\n }\n\n @for (item of rightMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" [class]=\"hlm(_computedRightLinkClass(), item.class || '')\"> {{ item.label }} </a>\n } @else {\n <button type=\"button\" (click)=\"item.action?.()\" [class]=\"hlm(_computedRightLinkClass(), item.class || '')\">\n {{ item.label }}\n </button>\n }\n }\n\n @let uMenus = userMenus();\n @if (uMenus && uMenus.length > 0) {\n <eg-layout-simple-user-menu [menus]=\"uMenus\"></eg-layout-simple-user-menu>\n }\n </nav>\n\n <!-- Mobile menu button -->\n <button\n (click)=\"toggleMobileMenu()\"\n class=\"tw:md:hidden tw:p-2 tw:text-gray-700 tw:hover:text-blue-500 tw:focus:outline-none\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"tw:h-6 tw:w-6\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n </button>\n </header>\n\n <!-- Mobile menu -->\n @if (isMobile() && mobileMenuOpen) {\n <div class=\"tw:bg-gray-100 tw:border-b tw:border-gray-300 tw:px-4 tw:py-2\">\n <nav class=\"tw:flex tw:flex-col tw:space-y-2\">\n <!-- Left menus -->\n @for (item of leftMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" class=\"tw:text-left tw:cursor-pointer tw:text-gray-700 tw:hover:text-blue-500\">\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"tw:text-left tw:cursor-pointer tw:text-gray-700 tw:hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n\n <!-- Right menus -->\n @for (item of rightMenus(); track item.label) {\n @if (item.link) {\n <a [routerLink]=\"item.link\" class=\"tw:text-left tw:cursor-pointer tw:text-gray-700 tw:hover:text-blue-500\">\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"tw:text-left tw:cursor-pointer tw:text-gray-700 tw:hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n\n <!-- User menus (flattened for mobile) -->\n @for (section of userMenus(); track section.label) {\n @if (section.label) {\n <div class=\"tw:font-bold tw:mt-2\">{{ section.label }}</div>\n }\n @if (section.items?.length) {\n @for (item of section.items; track item.label) {\n @if (item.link) {\n <a\n [routerLink]=\"item.link\"\n class=\"tw:text-left tw:cursor-pointer tw:text-gray-700 tw:hover:text-blue-500\"\n >\n {{ item.label }}\n </a>\n } @else {\n <button\n type=\"button\"\n (click)=\"item.action?.()\"\n class=\"tw:text-left tw:cursor-pointer tw:text-gray-700 tw:hover:text-blue-500\"\n >\n {{ item.label }}\n </button>\n }\n }\n }\n @if (section.separator) {\n <hr class=\"tw:border-gray-300 tw:my-2\" />\n }\n }\n </nav>\n </div>\n }\n\n <!-- Main content -->\n <main class=\"tw:flex-1 tw:p-4\">\n <router-outlet></router-outlet>\n </main>\n</div>\n","/*\n * Public API Surface of layout-simple\n */\n\nexport * from './lib/layout';\nexport * from './lib/user-menu';\nexport * from './lib/search';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1"],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
3
|
+
import { BreakpointObserver } from '@angular/cdk/layout';
|
|
4
|
+
import { ClassValue } from 'clsx';
|
|
5
|
+
import { hlm } from '@egose/shadcn-theme-ng/utils';
|
|
6
|
+
import { HlmAutocompleteOption } from '@egose/shadcn-theme-ng/autocomplete';
|
|
7
|
+
import * as _angular_forms from '@angular/forms';
|
|
8
|
+
|
|
9
|
+
interface UserMenuItem {
|
|
10
|
+
label: string;
|
|
11
|
+
icon?: any;
|
|
12
|
+
action?: () => void;
|
|
13
|
+
link?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
}
|
|
16
|
+
interface UserMenuSection {
|
|
17
|
+
label?: string;
|
|
18
|
+
separator?: boolean;
|
|
19
|
+
items?: UserMenuItem[];
|
|
20
|
+
}
|
|
21
|
+
declare class EgLayoutSimpleUserMenu {
|
|
22
|
+
menus: _angular_core.InputSignal<UserMenuSection[]>;
|
|
23
|
+
lucideUser: string;
|
|
24
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EgLayoutSimpleUserMenu, never>;
|
|
25
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgLayoutSimpleUserMenu, "eg-layout-simple-user-menu", never, { "menus": { "alias": "menus"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface MenuItem {
|
|
29
|
+
label: string;
|
|
30
|
+
link?: string;
|
|
31
|
+
action?: () => void;
|
|
32
|
+
class?: string;
|
|
33
|
+
}
|
|
34
|
+
declare class EgLayoutSimple<TItem, TParams extends object = {
|
|
35
|
+
search: string;
|
|
36
|
+
}> {
|
|
37
|
+
private breakpointObserver;
|
|
38
|
+
/** Menu data inputs */
|
|
39
|
+
leftMenus: _angular_core.InputSignal<MenuItem[]>;
|
|
40
|
+
rightMenus: _angular_core.InputSignal<MenuItem[]>;
|
|
41
|
+
userMenus: _angular_core.InputSignal<UserMenuSection[]>;
|
|
42
|
+
logo: _angular_core.InputSignal<string>;
|
|
43
|
+
logoLink: _angular_core.InputSignal<string>;
|
|
44
|
+
hlm: typeof hlm;
|
|
45
|
+
/** Container class inputs */
|
|
46
|
+
leftMenuClass: _angular_core.InputSignal<ClassValue>;
|
|
47
|
+
rightMenuClass: _angular_core.InputSignal<ClassValue>;
|
|
48
|
+
/** Link/button base class inputs */
|
|
49
|
+
leftLinkClass: _angular_core.InputSignal<ClassValue>;
|
|
50
|
+
rightLinkClass: _angular_core.InputSignal<ClassValue>;
|
|
51
|
+
searchEnabled: _angular_core.InputSignal<boolean>;
|
|
52
|
+
searchPlaceholderText: _angular_core.InputSignal<string>;
|
|
53
|
+
searchEmptyText: _angular_core.InputSignal<string>;
|
|
54
|
+
searchOptionTemplate: _angular_core.InputSignal<TemplateRef<HlmAutocompleteOption<TItem>> | undefined>;
|
|
55
|
+
searchLoaderFn: _angular_core.InputSignal<((params: TParams) => Promise<TItem[]>) | undefined>;
|
|
56
|
+
searchTransformValueToSearch: _angular_core.InputSignal<((value: TItem) => string) | undefined>;
|
|
57
|
+
readonly searchOptionChange: _angular_core.OutputEmitterRef<TItem>;
|
|
58
|
+
/** Computed merged classes for containers */
|
|
59
|
+
protected readonly _computedLeftClass: _angular_core.Signal<string>;
|
|
60
|
+
protected readonly _computedRightClass: _angular_core.Signal<string>;
|
|
61
|
+
/** Computed merged classes for link/button elements */
|
|
62
|
+
protected readonly _computedLeftLinkClass: _angular_core.Signal<string>;
|
|
63
|
+
protected readonly _computedRightLinkClass: _angular_core.Signal<string>;
|
|
64
|
+
/** Mobile menu state */
|
|
65
|
+
mobileMenuOpen: boolean;
|
|
66
|
+
isMobile: _angular_core.WritableSignal<boolean>;
|
|
67
|
+
constructor(breakpointObserver: BreakpointObserver);
|
|
68
|
+
toggleMobileMenu(): void;
|
|
69
|
+
onSearchOptionChange(value: TItem): void;
|
|
70
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EgLayoutSimple<any, any>, never>;
|
|
71
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgLayoutSimple<any, any>, "eg-layout-simple", never, { "leftMenus": { "alias": "leftMenus"; "required": false; "isSignal": true; }; "rightMenus": { "alias": "rightMenus"; "required": false; "isSignal": true; }; "userMenus": { "alias": "userMenus"; "required": false; "isSignal": true; }; "logo": { "alias": "logo"; "required": false; "isSignal": true; }; "logoLink": { "alias": "logoLink"; "required": false; "isSignal": true; }; "leftMenuClass": { "alias": "leftClass"; "required": false; "isSignal": true; }; "rightMenuClass": { "alias": "rightClass"; "required": false; "isSignal": true; }; "leftLinkClass": { "alias": "leftLinkClass"; "required": false; "isSignal": true; }; "rightLinkClass": { "alias": "rightLinkClass"; "required": false; "isSignal": true; }; "searchEnabled": { "alias": "searchEnabled"; "required": false; "isSignal": true; }; "searchPlaceholderText": { "alias": "searchPlaceholderText"; "required": false; "isSignal": true; }; "searchEmptyText": { "alias": "searchEmptyText"; "required": false; "isSignal": true; }; "searchOptionTemplate": { "alias": "searchOptionTemplate"; "required": false; "isSignal": true; }; "searchLoaderFn": { "alias": "searchLoaderFn"; "required": false; "isSignal": true; }; "searchTransformValueToSearch": { "alias": "searchTransformValueToSearch"; "required": false; "isSignal": true; }; }, { "searchOptionChange": "searchOptionChange"; }, never, never, true, never>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
declare class EgGenericAutocomplete<TItem, TParams extends object = {
|
|
75
|
+
search: string;
|
|
76
|
+
}> {
|
|
77
|
+
defaultOptionTemplate: _angular_core.Signal<TemplateRef<HlmAutocompleteOption<TItem>> | undefined>;
|
|
78
|
+
controlId: _angular_core.InputSignal<string>;
|
|
79
|
+
placeholderText: _angular_core.InputSignal<string>;
|
|
80
|
+
emptyText: _angular_core.InputSignal<string>;
|
|
81
|
+
optionTemplate: _angular_core.InputSignal<TemplateRef<HlmAutocompleteOption<TItem>> | undefined>;
|
|
82
|
+
loaderFn: _angular_core.InputSignal<((params: TParams) => Promise<TItem[]>) | undefined>;
|
|
83
|
+
transformValueToSearch: _angular_core.InputSignal<((value: TItem) => string) | undefined>;
|
|
84
|
+
readonly optionChange: _angular_core.OutputEmitterRef<TItem>;
|
|
85
|
+
private readonly _formBuilder;
|
|
86
|
+
form: _angular_forms.FormGroup<{
|
|
87
|
+
option: _angular_forms.FormControl<null>;
|
|
88
|
+
}>;
|
|
89
|
+
readonly search: _angular_core.WritableSignal<string>;
|
|
90
|
+
options: _angular_core.ResourceRef<TItem[]>;
|
|
91
|
+
ngOnInit(): void;
|
|
92
|
+
ngOnDestroy(): void;
|
|
93
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EgGenericAutocomplete<any, any>, never>;
|
|
94
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgGenericAutocomplete<any, any>, "eg-generic-autocomplete", never, { "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "placeholderText": { "alias": "placeholderText"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "optionTemplate": { "alias": "optionTemplate"; "required": false; "isSignal": true; }; "loaderFn": { "alias": "loaderFn"; "required": false; "isSignal": true; }; "transformValueToSearch": { "alias": "transformValueToSearch"; "required": false; "isSignal": true; }; }, { "optionChange": "optionChange"; }, never, never, true, never>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { EgGenericAutocomplete, EgLayoutSimple, EgLayoutSimpleUserMenu };
|
|
98
|
+
export type { MenuItem, UserMenuItem, UserMenuSection };
|
package/menu/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Menu
|
|
2
|
+
|
|
3
|
+
This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
ng generate component component-name
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
ng generate --help
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Building
|
|
20
|
+
|
|
21
|
+
To build the library, run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
ng build menu
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
|
|
28
|
+
|
|
29
|
+
### Publishing the Library
|
|
30
|
+
|
|
31
|
+
Once the project is built, you can publish your library by following these steps:
|
|
32
|
+
|
|
33
|
+
1. Navigate to the `dist` directory:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd dist/menu
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
2. Run the `npm publish` command to publish your library to the npm registry:
|
|
40
|
+
```bash
|
|
41
|
+
npm publish
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Running unit tests
|
|
45
|
+
|
|
46
|
+
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
ng test
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Running end-to-end tests
|
|
53
|
+
|
|
54
|
+
For end-to-end (e2e) testing, run:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ng e2e
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
|
61
|
+
|
|
62
|
+
## Additional Resources
|
|
63
|
+
|
|
64
|
+
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|