@goat-bravos/intern-hub-layout 4.0.0 → 4.0.2
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
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|

|
|
5
5
|

|
|
6
6
|

|
|
7
|
-

|
|
8
7
|
|
|
9
|
-
A comprehensive Angular library providing reusable layout components and shared UI elements for Intern Hub applications. Built with Angular 21
|
|
8
|
+
A comprehensive Angular library providing reusable layout components and shared UI elements for Intern Hub applications. Built with Angular 21 and designed for seamless integration.
|
|
10
9
|
|
|
11
10
|
---
|
|
12
11
|
|
|
@@ -15,42 +14,29 @@ A comprehensive Angular library providing reusable layout components and shared
|
|
|
15
14
|
- [Features](#-features)
|
|
16
15
|
- [Installation](#-installation)
|
|
17
16
|
- [Quick Start](#-quick-start)
|
|
18
|
-
- [Project Structure](#-project-structure)
|
|
19
17
|
- [Components](#-components)
|
|
20
18
|
- [Layout Components](#layout-components)
|
|
21
19
|
- [Button Components](#button-components)
|
|
22
20
|
- [Input Components](#input-components)
|
|
23
|
-
- [Date Picker Components](#date-picker-components)
|
|
24
21
|
- [Table Components](#table-components)
|
|
25
22
|
- [Approval Components](#approval-components)
|
|
26
|
-
- [Modal Components](#modal-components)
|
|
27
23
|
- [Pop-up Components](#pop-up-components)
|
|
28
|
-
- [Upload Components](#upload-components)
|
|
29
24
|
- [Icon Components](#icon-components)
|
|
30
|
-
- [
|
|
31
|
-
- [Troubleshooting](#-troubleshooting)
|
|
32
|
-
- [Development](#️-development)
|
|
25
|
+
- [Development](#-development)
|
|
33
26
|
- [Contributing](#-contributing)
|
|
34
|
-
- [Changelog](#-changelog)
|
|
35
27
|
- [License](#-license)
|
|
36
|
-
- [Links & Resources](#-links--resources)
|
|
37
|
-
- [Support](#-support)
|
|
38
|
-
- [Acknowledgments](#-acknowledgments)
|
|
39
28
|
|
|
40
29
|
---
|
|
41
30
|
|
|
42
31
|
## ✨ Features
|
|
43
32
|
|
|
44
|
-
- 🎨 **Pre-built Layouts** - Header and sidebar components with
|
|
45
|
-
- 🧩 **Reusable UI Components** - Buttons, inputs, tables,
|
|
46
|
-
- 🔧 **Highly Configurable** - Extensive customization via
|
|
47
|
-
- 📦 **Standalone Components** - Modern Angular standalone component architecture
|
|
48
|
-
- 🎯 **TypeScript Support** - Full type definitions
|
|
49
|
-
- ♿ **Accessible** - Built with accessibility best practices
|
|
50
|
-
- 🚀 **Angular 21 Ready** - Built for the latest Angular version
|
|
51
|
-
- 🎭 **Theme Support** - Customizable color schemes using CSS variables
|
|
52
|
-
- 📱 **Responsive** - Mobile-first design with responsive breakpoints
|
|
53
|
-
- 🔄 **Two-way Binding** - Support for Angular's two-way data binding with `[(value)]`
|
|
33
|
+
- 🎨 **Pre-built Layouts** - Header and sidebar components with hover effects
|
|
34
|
+
- 🧩 **Reusable UI Components** - Buttons, inputs, tables, approval lists, and more
|
|
35
|
+
- 🔧 **Highly Configurable** - Extensive customization via inputs
|
|
36
|
+
- 📦 **Standalone Components** - Modern Angular standalone component architecture
|
|
37
|
+
- 🎯 **TypeScript Support** - Full type definitions included
|
|
38
|
+
- ♿ **Accessible** - Built with accessibility best practices
|
|
39
|
+
- 🚀 **Angular 21 Ready** - Built for the latest Angular version
|
|
54
40
|
|
|
55
41
|
---
|
|
56
42
|
|
|
@@ -66,13 +52,13 @@ npm install @goat-bravos/intern-hub-layout
|
|
|
66
52
|
|
|
67
53
|
This library requires the following peer dependencies:
|
|
68
54
|
|
|
69
|
-
| Package | Version | Required |
|
|
70
|
-
| ----------------- | ------- | ----------- |
|
|
71
|
-
| `@angular/common` | ^21.0.0 | ✅ Yes |
|
|
72
|
-
| `@angular/core` | ^21.0.0 | ✅ Yes |
|
|
73
|
-
| `@angular/forms` | ^21.0.0 | ✅ Yes |
|
|
74
|
-
| `@angular/router` | ^21.0.0 | ✅ Yes |
|
|
75
|
-
| `dynamic-ds` | ^1.0.
|
|
55
|
+
| Package | Version | Required |
|
|
56
|
+
| ----------------- | ------- | ----------- |
|
|
57
|
+
| `@angular/common` | ^21.0.0 | ✅ Yes |
|
|
58
|
+
| `@angular/core` | ^21.0.0 | ✅ Yes |
|
|
59
|
+
| `@angular/forms` | ^21.0.0 | ✅ Yes |
|
|
60
|
+
| `@angular/router` | ^21.0.0 | ✅ Yes |
|
|
61
|
+
| `dynamic-ds` | ^1.0.2 | ⚠️ Optional |
|
|
76
62
|
|
|
77
63
|
Install peer dependencies if not already present:
|
|
78
64
|
|
|
@@ -80,12 +66,6 @@ Install peer dependencies if not already present:
|
|
|
80
66
|
npm install @angular/common @angular/core @angular/forms @angular/router
|
|
81
67
|
```
|
|
82
68
|
|
|
83
|
-
For icon support, install the optional dependency:
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
npm install dynamic-ds
|
|
87
|
-
```
|
|
88
|
-
|
|
89
69
|
---
|
|
90
70
|
|
|
91
71
|
## 🚀 Quick Start
|
|
@@ -103,15 +83,8 @@ import { HeaderComponent, SidebarComponent, ButtonContainerComponent, InputTextC
|
|
|
103
83
|
standalone: true,
|
|
104
84
|
imports: [HeaderComponent, SidebarComponent, ButtonContainerComponent, InputTextComponent],
|
|
105
85
|
templateUrl: "./app.component.html",
|
|
106
|
-
styleUrls: ["./app.component.scss"],
|
|
107
86
|
})
|
|
108
|
-
export class AppComponent {
|
|
109
|
-
username = "";
|
|
110
|
-
|
|
111
|
-
onButtonClick() {
|
|
112
|
-
console.log("Button clicked!");
|
|
113
|
-
}
|
|
114
|
-
}
|
|
87
|
+
export class AppComponent {}
|
|
115
88
|
```
|
|
116
89
|
|
|
117
90
|
### Step 2: Use in Template
|
|
@@ -123,77 +96,11 @@ export class AppComponent {
|
|
|
123
96
|
<!-- Sidebar -->
|
|
124
97
|
<app-sidebar [data]="sidebarData"></app-sidebar>
|
|
125
98
|
|
|
126
|
-
<!--
|
|
127
|
-
<
|
|
128
|
-
<!-- Button -->
|
|
129
|
-
<app-button-container content="Click Me" size="md" bgDefault="var(--brand-500)" (buttonClick)="onButtonClick()"> </app-button-container>
|
|
130
|
-
|
|
131
|
-
<!-- Input -->
|
|
132
|
-
<app-input-text headerInput="Username" placeholder="Enter your username" [required]="true" [(value)]="username"> </app-input-text>
|
|
133
|
-
</div>
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### Step 3: Configure Data Objects (Optional)
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
import { HeaderData, SidebarData } from "@goat-bravos/intern-hub-layout";
|
|
140
|
-
|
|
141
|
-
export class AppComponent {
|
|
142
|
-
headerData: HeaderData = {
|
|
143
|
-
headerItems: [
|
|
144
|
-
{
|
|
145
|
-
icon: "dsi-bell-line",
|
|
146
|
-
content: "Notifications",
|
|
147
|
-
badge: "5",
|
|
148
|
-
method: () => console.log("Notifications clicked"),
|
|
149
|
-
},
|
|
150
|
-
],
|
|
151
|
-
userName: "John Doe",
|
|
152
|
-
logo: "assets/logo.png",
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
sidebarData: SidebarData = {
|
|
156
|
-
backgroundColor: "var(--brand-500)",
|
|
157
|
-
menuItems: [
|
|
158
|
-
{
|
|
159
|
-
iconLeft: "dsi-home-01-line",
|
|
160
|
-
content: "Dashboard",
|
|
161
|
-
url: "/dashboard",
|
|
162
|
-
},
|
|
163
|
-
],
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
---
|
|
99
|
+
<!-- Button -->
|
|
100
|
+
<app-button-container content="Click Me" size="md" backgroundColor="var(--brand-500)" (buttonClick)="onButtonClick()"></app-button-container>
|
|
169
101
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
```
|
|
173
|
-
intern-hub-layout/
|
|
174
|
-
├── src/
|
|
175
|
-
│ ├── libs/
|
|
176
|
-
│ │ ├── layouts/ # Layout components
|
|
177
|
-
│ │ │ ├── header/ # Header component
|
|
178
|
-
│ │ │ └── sidebar/ # Sidebar component
|
|
179
|
-
│ │ └── shared/
|
|
180
|
-
│ │ └── components/ # Shared UI components
|
|
181
|
-
│ │ ├── approval/ # Approval list components
|
|
182
|
-
│ │ ├── button/ # Button components
|
|
183
|
-
│ │ ├── date-picker/ # Date picker component
|
|
184
|
-
│ │ ├── avatar-upload-button/ # Avatar upload button
|
|
185
|
-
│ │ ├── file-upload-dropzone/ # Drag & drop file upload
|
|
186
|
-
│ │ ├── functional-label/ # Label with icons
|
|
187
|
-
│ │ ├── icon/ # Icon component
|
|
188
|
-
│ │ ├── input/ # Input components
|
|
189
|
-
│ │ ├── modal/ # Modal dialog
|
|
190
|
-
│ │ ├── pop-up/ # Confirmation dialogs
|
|
191
|
-
│ │ └── table/ # Table components
|
|
192
|
-
│ └── public-api.ts # Public API exports
|
|
193
|
-
├── demo/ # Demo application
|
|
194
|
-
├── dist/ # Build output
|
|
195
|
-
├── README.md # This file
|
|
196
|
-
└── package.json # Package configuration
|
|
102
|
+
<!-- Input -->
|
|
103
|
+
<app-input-text headerInput="Username" placeholder="Enter your username" [required]="true" [(value)]="username"></app-input-text>
|
|
197
104
|
```
|
|
198
105
|
|
|
199
106
|
---
|
|
@@ -234,7 +141,6 @@ export class MyComponent {
|
|
|
234
141
|
userIcon: "dsi-user-01-line",
|
|
235
142
|
dropdownIcon: "dsi-arrow-down-solid",
|
|
236
143
|
logo: "assets/logo.png",
|
|
237
|
-
minWidth: "1200px",
|
|
238
144
|
};
|
|
239
145
|
}
|
|
240
146
|
```
|
|
@@ -252,7 +158,6 @@ interface HeaderData {
|
|
|
252
158
|
logo?: string;
|
|
253
159
|
logoWidth?: string;
|
|
254
160
|
logoHeight?: string;
|
|
255
|
-
minWidth?: string;
|
|
256
161
|
}
|
|
257
162
|
|
|
258
163
|
interface HeaderAction {
|
|
@@ -422,7 +327,7 @@ interface SidebarData {
|
|
|
422
327
|
|
|
423
328
|
#### ButtonContainerComponent
|
|
424
329
|
|
|
425
|
-
A
|
|
330
|
+
A customizable button with icon support and multiple size variants.
|
|
426
331
|
|
|
427
332
|
**Selector:** `app-button-container`
|
|
428
333
|
|
|
@@ -433,13 +338,13 @@ import { ButtonContainerComponent, ButtonSize } from "@goat-bravos/intern-hub-la
|
|
|
433
338
|
imports: [ButtonContainerComponent],
|
|
434
339
|
template: `
|
|
435
340
|
<!-- Basic button -->
|
|
436
|
-
<app-button-container content="Submit" size="md" (buttonClick)="onSubmit()"
|
|
341
|
+
<app-button-container content="Submit" size="md" (buttonClick)="onSubmit()"></app-button-container>
|
|
437
342
|
|
|
438
|
-
<!--
|
|
439
|
-
<app-button-container content="Download" size="lg" leftIcon="
|
|
343
|
+
<!-- Button with icons -->
|
|
344
|
+
<app-button-container content="Download" size="lg" leftIcon="⬇" backgroundColor="#10b981" color="#ffffff" (buttonClick)="onDownload()"></app-button-container>
|
|
440
345
|
|
|
441
|
-
<!--
|
|
442
|
-
<app-button-container content="
|
|
346
|
+
<!-- Small button -->
|
|
347
|
+
<app-button-container content="Edit" size="xs" backgroundColor="#f59e0b" (buttonClick)="onEdit()"></app-button-container>
|
|
443
348
|
`,
|
|
444
349
|
})
|
|
445
350
|
export class MyComponent {
|
|
@@ -449,38 +354,33 @@ export class MyComponent {
|
|
|
449
354
|
onDownload() {
|
|
450
355
|
console.log("Download initiated");
|
|
451
356
|
}
|
|
357
|
+
onEdit() {
|
|
358
|
+
console.log("Edit clicked");
|
|
359
|
+
}
|
|
452
360
|
}
|
|
453
361
|
```
|
|
454
362
|
|
|
455
363
|
**Inputs:**
|
|
456
364
|
|
|
457
|
-
| Input
|
|
458
|
-
|
|
|
459
|
-
| `size`
|
|
460
|
-
| `content`
|
|
461
|
-
| `
|
|
462
|
-
| `
|
|
463
|
-
| `
|
|
464
|
-
| `
|
|
465
|
-
| `
|
|
466
|
-
| `
|
|
467
|
-
| `
|
|
468
|
-
| `
|
|
469
|
-
| `
|
|
470
|
-
| `colorHover` | `string` | `'var(--neutral-color-900)'` | Text/icon color on hover |
|
|
471
|
-
| `colorDisabled` | `string` | `'var(--neutral-color-500)'` | Text/icon color when disabled |
|
|
472
|
-
| `border` | `string` | - | CSS border property (e.g., '1px solid #ccc') |
|
|
473
|
-
| `borderRadius` | `string` | `'8px'` | CSS border-radius property |
|
|
474
|
-
| `width` | `string` | - | Custom button width |
|
|
475
|
-
| `height` | `string` | `'36px'` | Custom button height |
|
|
476
|
-
| `padding` | `string` | - | Custom button padding |
|
|
477
|
-
| `disabled` | `boolean` | `false` | Whether the button is interactive |
|
|
365
|
+
| Input | Type | Default | Description |
|
|
366
|
+
| ----------------- | ------------------------------ | ---------------------- | --------------------- |
|
|
367
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg'` | `'md'` (Optional) | Button size variant |
|
|
368
|
+
| `content` | `string` | `''` | Button text |
|
|
369
|
+
| `leftIcon` | `string` | - | Left icon text/class |
|
|
370
|
+
| `rightIcon` | `string` | - | Right icon text/class |
|
|
371
|
+
| `color` | `string` | `'var(--brand-100)'` | Text color |
|
|
372
|
+
| `backgroundColor` | `string` | `'var(--utility-900)'` | Background color |
|
|
373
|
+
| `border` | `string` | - | Border style |
|
|
374
|
+
| `borderRadius` | `string` | - | Button border radius |
|
|
375
|
+
| `width` | `string` | - | Button width |
|
|
376
|
+
| `fontSize` | `string` | - | Custom font size |
|
|
377
|
+
| `buttonData` | `ButtonContainerData` | - | Config object |
|
|
478
378
|
|
|
479
379
|
**Outputs:**
|
|
480
380
|
|
|
481
|
-
| Output | Type
|
|
482
|
-
|
|
|
483
|
-
| `buttonClick` | `EventEmitter<
|
|
381
|
+
| Output | Type | Description |
|
|
382
|
+
| ------------- | ------------------- | ------------------------- |
|
|
383
|
+
| `buttonClick` | `EventEmitter<any>` | Emits when button clicked |
|
|
484
384
|
|
|
485
385
|
---
|
|
486
386
|
|
|
@@ -648,95 +548,6 @@ export class MyComponent {
|
|
|
648
548
|
|
|
649
549
|
---
|
|
650
550
|
|
|
651
|
-
### Date Picker Components
|
|
652
|
-
|
|
653
|
-
#### DatePickerComponent
|
|
654
|
-
|
|
655
|
-
A comprehensive date/range picker with ng-zorro-antd integration supporting single selection, range selection, and multiple modes.
|
|
656
|
-
|
|
657
|
-
**Selector:** `app-date-picker`
|
|
658
|
-
|
|
659
|
-
```typescript
|
|
660
|
-
import { DatePickerComponent } from "@goat-bravos/intern-hub-layout";
|
|
661
|
-
|
|
662
|
-
@Component({
|
|
663
|
-
imports: [DatePickerComponent],
|
|
664
|
-
template: `
|
|
665
|
-
<!-- Single date picker -->
|
|
666
|
-
<app-date-picker headerInput="Start Date" mode="date" [(value)]="selectedDate" (dateChange)="onDateChange($event)"></app-date-picker>
|
|
667
|
-
|
|
668
|
-
<!-- Date range picker -->
|
|
669
|
-
<app-date-picker headerInput="Date Range" mode="default" isRange="true" [(value)]="dateRange" (rangeChange)="onRangeChange($event)"></app-date-picker>
|
|
670
|
-
|
|
671
|
-
<!-- Week picker -->
|
|
672
|
-
<app-date-picker headerInput="Select Week" mode="week" [(value)]="weekDate"></app-date-picker>
|
|
673
|
-
|
|
674
|
-
<!-- Month picker -->
|
|
675
|
-
<app-date-picker headerInput="Select Month" mode="month" [(value)]="monthDate"></app-date-picker>
|
|
676
|
-
|
|
677
|
-
<!-- Date and Time picker -->
|
|
678
|
-
<app-date-picker headerInput="Date & Time" mode="date" showTime="true" [(value)]="dateTime"></app-date-picker>
|
|
679
|
-
`,
|
|
680
|
-
})
|
|
681
|
-
export class MyComponent {
|
|
682
|
-
selectedDate: Date | null = null;
|
|
683
|
-
dateRange: [Date, Date] | null = null;
|
|
684
|
-
weekDate: Date | null = null;
|
|
685
|
-
monthDate: Date | null = null;
|
|
686
|
-
dateTime: Date | null = null;
|
|
687
|
-
|
|
688
|
-
onDateChange(date: Date) {
|
|
689
|
-
console.log("Date selected:", date);
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
onRangeChange(range: [Date, Date]) {
|
|
693
|
-
console.log("Date range selected:", range);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
```
|
|
697
|
-
|
|
698
|
-
**Inputs:**
|
|
699
|
-
|
|
700
|
-
| Input | Type | Default | Description |
|
|
701
|
-
| ------------------- | ---------------------------------------------------------- | --------------- | ---------------------------------- |
|
|
702
|
-
| `headerInput` | `string` | `''` | Label text above picker |
|
|
703
|
-
| `value` | `Date \| [Date, Date] \| null` | `null` | Selected date(s) value |
|
|
704
|
-
| `mode` | `'date' \| 'week' \| 'month' \| 'quarter' \| 'year'` | `'date'` | Picker mode |
|
|
705
|
-
| `isRange` | `boolean` | `false` | Enable range selection |
|
|
706
|
-
| `showTime` | `boolean` | `false` | Show time selection |
|
|
707
|
-
| `placeholder` | `string` | `'Select date'` | Placeholder text |
|
|
708
|
-
| `format` | `string` | `'dd/MM/yyyy'` | Date format string |
|
|
709
|
-
| `required` | `boolean` | `false` | Show required indicator |
|
|
710
|
-
| `readonly` | `boolean` | `false` | Read-only state |
|
|
711
|
-
| `disabled` | `boolean` | `false` | Disabled state |
|
|
712
|
-
| `disabledDate` | `(date: Date) => boolean` | - | Function to disable specific dates |
|
|
713
|
-
| `dropdownPlacement` | `'topLeft' \| 'topRight' \| 'bottomLeft' \| 'bottomRight'` | `'bottomLeft'` | Dropdown position |
|
|
714
|
-
| `width` | `string` | `'100%'` | Component width |
|
|
715
|
-
|
|
716
|
-
**Outputs:**
|
|
717
|
-
|
|
718
|
-
| Output | Type | Description |
|
|
719
|
-
| ------------- | ------------------------------------ | ---------------------------------- |
|
|
720
|
-
| `dateChange` | `EventEmitter<Date \| null>` | Emits when single date is selected |
|
|
721
|
-
| `rangeChange` | `EventEmitter<[Date, Date] \| null>` | Emits when date range is selected |
|
|
722
|
-
| `openChange` | `EventEmitter<boolean>` | Emits when picker opens/closes |
|
|
723
|
-
| `ok` | `EventEmitter<Date \| [Date, Date]>` | Emits when OK button is clicked |
|
|
724
|
-
| `panelChange` | `EventEmitter<any>` | Emits on panel change events |
|
|
725
|
-
|
|
726
|
-
**Features:**
|
|
727
|
-
|
|
728
|
-
- ✅ **Multiple Modes** - Date, week, month, quarter, year selection
|
|
729
|
-
- ✅ **Range Selection** - Pick date ranges for date range inputs
|
|
730
|
-
- ✅ **Time Support** - Include time selection with dates
|
|
731
|
-
- ✅ **Date Disabling** - Disable specific dates via custom function
|
|
732
|
-
- ✅ **Customizable Format** - Change date format string
|
|
733
|
-
- ✅ **Dropdown Control** - Position popup relative to input
|
|
734
|
-
- ✅ **Form Integration** - ControlValueAccessor for form support
|
|
735
|
-
|
|
736
|
-
---
|
|
737
|
-
|
|
738
|
-
### Table Components
|
|
739
|
-
|
|
740
551
|
#### InputCalendarComponent
|
|
741
552
|
|
|
742
553
|
A date picker with auto-formatting (dd/mm/yyyy) and validation.
|
|
@@ -791,6 +602,8 @@ export class MyComponent {
|
|
|
791
602
|
|
|
792
603
|
---
|
|
793
604
|
|
|
605
|
+
### Table Components
|
|
606
|
+
|
|
794
607
|
#### TableHeaderComponent & TableBodyComponent
|
|
795
608
|
|
|
796
609
|
Table components with customizable columns and template support.
|
|
@@ -936,128 +749,11 @@ interface ApprovalListItemInterface {
|
|
|
936
749
|
|
|
937
750
|
---
|
|
938
751
|
|
|
939
|
-
---
|
|
940
|
-
|
|
941
|
-
#### ApprovalListItemComponent
|
|
942
|
-
|
|
943
|
-
A single item component for the approval list, can be used independently.
|
|
944
|
-
|
|
945
|
-
**Selector:** `app-approval-list-item`
|
|
946
|
-
|
|
947
|
-
```typescript
|
|
948
|
-
import { ApprovalListItemComponent } from "@goat-bravos/intern-hub-layout";
|
|
949
|
-
|
|
950
|
-
@Component({
|
|
951
|
-
imports: [ApprovalListItemComponent],
|
|
952
|
-
template: ` <app-approval-list-item name="John Doe - Request #123" [date]="requestDate"></app-approval-list-item> `,
|
|
953
|
-
})
|
|
954
|
-
export class MyComponent {
|
|
955
|
-
requestDate = new Date();
|
|
956
|
-
}
|
|
957
|
-
```
|
|
958
|
-
|
|
959
|
-
**Inputs:**
|
|
960
|
-
|
|
961
|
-
| Input | Type | Description |
|
|
962
|
-
| --------------- | ------------------ | ------------------------------ |
|
|
963
|
-
| `name` | `string` | Main text/name to display |
|
|
964
|
-
| `date` | `Date` | Date object to display |
|
|
965
|
-
| `rightTemplate` | `TemplateRef<any>` | Custom template for right side |
|
|
966
|
-
| `rightContext` | `any` | Context for the right template |
|
|
967
|
-
|
|
968
|
-
---
|
|
969
|
-
|
|
970
|
-
### Modal Components
|
|
971
|
-
|
|
972
|
-
#### ModalComponent
|
|
973
|
-
|
|
974
|
-
A flexible modal dialog with customizable themes and responsive design, supporting named content slots for body and footer.
|
|
975
|
-
|
|
976
|
-
**Selector:** `app-modal`
|
|
977
|
-
|
|
978
|
-
```typescript
|
|
979
|
-
import { ModalComponent } from "@goat-bravos/intern-hub-layout";
|
|
980
|
-
import { CommonModule } from "@angular/common";
|
|
981
|
-
|
|
982
|
-
@Component({
|
|
983
|
-
imports: [CommonModule, ModalComponent],
|
|
984
|
-
template: `
|
|
985
|
-
<!-- Trigger button -->
|
|
986
|
-
<button (click)="isModalOpen = true">Open Modal</button>
|
|
987
|
-
|
|
988
|
-
<!-- Modal component -->
|
|
989
|
-
<app-modal [title]="'User Settings'" [isOpen]="isModalOpen" [width]="'600px'" [minHeight]="'400px'" [theme]="'default'" (closeModal)="isModalOpen = false">
|
|
990
|
-
<!-- Modal Body Content -->
|
|
991
|
-
<div modal-body>
|
|
992
|
-
<h3>Account Information</h3>
|
|
993
|
-
<p>Update your account details and preferences below.</p>
|
|
994
|
-
<!-- Your form or other components -->
|
|
995
|
-
</div>
|
|
996
|
-
|
|
997
|
-
<!-- Modal Footer Content -->
|
|
998
|
-
<div modal-footer>
|
|
999
|
-
<button (click)="isModalOpen = false">Cancel</button>
|
|
1000
|
-
<button class="primary" (click)="saveSettings()">Save Changes</button>
|
|
1001
|
-
</div>
|
|
1002
|
-
</app-modal>
|
|
1003
|
-
`,
|
|
1004
|
-
})
|
|
1005
|
-
export class MyComponent {
|
|
1006
|
-
isModalOpen = false;
|
|
1007
|
-
|
|
1008
|
-
saveSettings() {
|
|
1009
|
-
console.log("Settings saved");
|
|
1010
|
-
this.isModalOpen = false;
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
```
|
|
1014
|
-
|
|
1015
|
-
**Inputs:**
|
|
1016
|
-
|
|
1017
|
-
| Input | Type | Default | Description |
|
|
1018
|
-
| ----------- | ---------------------- | ----------- | ------------------------- |
|
|
1019
|
-
| `title` | `string` | `''` | Modal title text |
|
|
1020
|
-
| `width` | `string` | `'800px'` | Modal width (CSS value) |
|
|
1021
|
-
| `minHeight` | `string` | `'300px'` | Minimum modal height |
|
|
1022
|
-
| `isOpen` | `boolean` | `false` | Controls modal visibility |
|
|
1023
|
-
| `theme` | `'default' \| 'white'` | `'default'` | Visual color theme |
|
|
1024
|
-
|
|
1025
|
-
**Outputs:**
|
|
1026
|
-
|
|
1027
|
-
| Output | Type | Description |
|
|
1028
|
-
| ------------ | -------------------- | --------------------------------- |
|
|
1029
|
-
| `closeModal` | `EventEmitter<void>` | Emits when modal should be closed |
|
|
1030
|
-
|
|
1031
|
-
**Content Projection (Slots):**
|
|
1032
|
-
|
|
1033
|
-
The modal uses named content projection to organize your content:
|
|
1034
|
-
|
|
1035
|
-
- `[modal-body]`: The main content area of the modal.
|
|
1036
|
-
- `[modal-footer]`: The bottom action area (typically for buttons).
|
|
1037
|
-
|
|
1038
|
-
```html
|
|
1039
|
-
<app-modal [title]="'Custom Modal'" [isOpen]="true">
|
|
1040
|
-
<div modal-body>
|
|
1041
|
-
<!-- Main content goes here -->
|
|
1042
|
-
</div>
|
|
1043
|
-
<div modal-footer>
|
|
1044
|
-
<!-- Footer actions go here -->
|
|
1045
|
-
</div>
|
|
1046
|
-
</app-modal>
|
|
1047
|
-
```
|
|
1048
|
-
|
|
1049
|
-
**Themes:**
|
|
1050
|
-
|
|
1051
|
-
- `default` - Uses `var(--brand-100)` background with `var(--brand-600)` title.
|
|
1052
|
-
- `white` - Uses `var(--neutral-color-10)` background with `var(--neutral-color-50)` title.
|
|
1053
|
-
|
|
1054
|
-
---
|
|
1055
|
-
|
|
1056
752
|
### Pop-up Components
|
|
1057
753
|
|
|
1058
754
|
#### PopUpConfirmComponent
|
|
1059
755
|
|
|
1060
|
-
An accessible confirmation modal dialog
|
|
756
|
+
An accessible confirmation modal dialog.
|
|
1061
757
|
|
|
1062
758
|
**Selector:** `app-pop-up-confirm`
|
|
1063
759
|
|
|
@@ -1109,134 +805,6 @@ export class MyComponent {
|
|
|
1109
805
|
|
|
1110
806
|
---
|
|
1111
807
|
|
|
1112
|
-
### Upload Components
|
|
1113
|
-
|
|
1114
|
-
---
|
|
1115
|
-
|
|
1116
|
-
#### AvatarUploadButtonComponent
|
|
1117
|
-
|
|
1118
|
-
A dedicated button for uploading avatar images with preview functionality.
|
|
1119
|
-
|
|
1120
|
-
**Selector:** `app-avatar-upload-button`
|
|
1121
|
-
|
|
1122
|
-
```typescript
|
|
1123
|
-
import { AvatarUploadButtonComponent, AvatarUploadedFile } from "@goat-bravos/intern-hub-layout";
|
|
1124
|
-
|
|
1125
|
-
@Component({
|
|
1126
|
-
imports: [AvatarUploadButtonComponent],
|
|
1127
|
-
template: ` <app-avatar-upload-button [label]="'Avatar'" [required]="true" [buttonText]="'Upload Avatar'" (fileChange)="onAvatarChange($event)"></app-avatar-upload-button> `,
|
|
1128
|
-
})
|
|
1129
|
-
export class MyComponent {
|
|
1130
|
-
onAvatarChange(file: AvatarUploadedFile | null) {
|
|
1131
|
-
if (file) {
|
|
1132
|
-
console.log("Avatar uploaded:", file.fileName, file.previewUrl);
|
|
1133
|
-
} else {
|
|
1134
|
-
console.log("Avatar removed");
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
```
|
|
1139
|
-
|
|
1140
|
-
**Inputs:**
|
|
1141
|
-
|
|
1142
|
-
| Input | Type | Default | Description |
|
|
1143
|
-
| --------------- | --------- | ------------------------------- | ------------------ |
|
|
1144
|
-
| `label` | `string` | `''` | Label text |
|
|
1145
|
-
| `required` | `boolean` | `false` | Required indicator |
|
|
1146
|
-
| `showTooltip` | `boolean` | `false` | Show info tooltip |
|
|
1147
|
-
| `tooltipText` | `string` | `''` | Tooltip content |
|
|
1148
|
-
| `buttonText` | `string` | `'Tải file lên'` | Button text |
|
|
1149
|
-
| `acceptFormats` | `string` | `'.png,.jpeg,.jpg'` | Accepted formats |
|
|
1150
|
-
| `helperText` | `string` | `'Định dạng .png, .jpeg, .jpg'` | Helper text below |
|
|
1151
|
-
|
|
1152
|
-
**Outputs:**
|
|
1153
|
-
|
|
1154
|
-
| Output | Type | Description |
|
|
1155
|
-
| ------------ | -------------------------------- | ----------- | -------------------------------- |
|
|
1156
|
-
| `fileChange` | `EventEmitter<AvatarUploadedFile | null>` | Emits uploaded file data or null |
|
|
1157
|
-
|
|
1158
|
-
**Interfaces:**
|
|
1159
|
-
|
|
1160
|
-
```typescript
|
|
1161
|
-
interface AvatarUploadedFile {
|
|
1162
|
-
id: string;
|
|
1163
|
-
file: File;
|
|
1164
|
-
fileName: string;
|
|
1165
|
-
previewUrl: string | null;
|
|
1166
|
-
}
|
|
1167
|
-
```
|
|
1168
|
-
|
|
1169
|
-
---
|
|
1170
|
-
|
|
1171
|
-
#### FileUploadDropzoneComponent
|
|
1172
|
-
|
|
1173
|
-
A drag-and-drop file upload zone with multiple file support.
|
|
1174
|
-
|
|
1175
|
-
**Selector:** `app-file-upload-dropzone`
|
|
1176
|
-
|
|
1177
|
-
```typescript
|
|
1178
|
-
import { FileUploadDropzoneComponent } from "@goat-bravos/intern-hub-layout";
|
|
1179
|
-
|
|
1180
|
-
@Component({
|
|
1181
|
-
imports: [FileUploadDropzoneComponent],
|
|
1182
|
-
template: `
|
|
1183
|
-
<!-- Single file upload -->
|
|
1184
|
-
<app-file-upload-dropzone [label]="'Upload Assignment'" [buttonText]="'Browse Files'" [maxSize]="'5MB'" [acceptFormats]="'.pdf,.doc,.docx'" (fileSelected)="onSingleFileSelected($event)"></app-file-upload-dropzone>
|
|
1185
|
-
|
|
1186
|
-
<!-- Multiple files upload -->
|
|
1187
|
-
<app-file-upload-dropzone [label]="'Upload Documents'" [buttonText]="'Select Multiple Files'" [maxSize]="'10MB'" [acceptFormats]="'.docx,.xlsx,.png,.jpg,.jpeg,.pdf'" [helperText]="'You can drag and drop multiple files here'" (filesSelected)="onMultipleFilesSelected($event)"></app-file-upload-dropzone>
|
|
1188
|
-
`,
|
|
1189
|
-
})
|
|
1190
|
-
export class MyComponent {
|
|
1191
|
-
onSingleFileSelected(file: File) {
|
|
1192
|
-
console.log("Single file selected:", file.name);
|
|
1193
|
-
// Handle single file upload
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
onMultipleFilesSelected(files: File[]) {
|
|
1197
|
-
console.log(`${files.length} files selected`);
|
|
1198
|
-
files.forEach((file) => {
|
|
1199
|
-
console.log("File:", file.name, file.size);
|
|
1200
|
-
});
|
|
1201
|
-
// Handle multiple files upload
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
```
|
|
1205
|
-
|
|
1206
|
-
**Inputs:**
|
|
1207
|
-
|
|
1208
|
-
| Input | Type | Default | Description |
|
|
1209
|
-
| --------------- | -------- | --------------------------------------- | ---------------------------- |
|
|
1210
|
-
| `label` | `string` | `'Thêm file bài học'` | Label text above dropzone |
|
|
1211
|
-
| `buttonText` | `string` | `'Tải lên'` | Button text |
|
|
1212
|
-
| `maxSize` | `string` | `'10MB'` | Maximum file size |
|
|
1213
|
-
| `acceptFormats` | `string` | `'.docx,.xlsx,.png,.jpg,.jpeg,.pdf'` | Accepted file formats |
|
|
1214
|
-
| `helperText` | `string` | Auto-generated from maxSize and formats | Helper text (auto or custom) |
|
|
1215
|
-
|
|
1216
|
-
**Outputs:**
|
|
1217
|
-
|
|
1218
|
-
| Output | Type | Description |
|
|
1219
|
-
| --------------- | ---------------------- | -------------------------------------- |
|
|
1220
|
-
| `fileSelected` | `EventEmitter<File>` | Emits when single file is selected |
|
|
1221
|
-
| `filesSelected` | `EventEmitter<File[]>` | Emits when multiple files are selected |
|
|
1222
|
-
|
|
1223
|
-
**Features:**
|
|
1224
|
-
|
|
1225
|
-
- ✅ **Drag & Drop Support** - Users can drag files directly onto the dropzone
|
|
1226
|
-
- ✅ **Visual Feedback** - Highlighted border when dragging files over the zone
|
|
1227
|
-
- ✅ **Multiple Files** - Supports both single and multiple file selection
|
|
1228
|
-
- ✅ **Format Validation** - Restricts file types based on `acceptFormats`
|
|
1229
|
-
- ✅ **Size Display** - Shows maximum allowed file size
|
|
1230
|
-
- ✅ **Accessible** - Keyboard-accessible file input
|
|
1231
|
-
|
|
1232
|
-
**Usage Tips:**
|
|
1233
|
-
|
|
1234
|
-
- The component will emit `fileSelected` for single file uploads
|
|
1235
|
-
- The component will emit `filesSelected` for multiple file uploads
|
|
1236
|
-
- Helper text is automatically generated from `maxSize` and `acceptFormats`, but can be overridden
|
|
1237
|
-
|
|
1238
|
-
---
|
|
1239
|
-
|
|
1240
808
|
### Icon Components
|
|
1241
809
|
|
|
1242
810
|
#### IconComponent
|
|
@@ -1335,572 +903,34 @@ export class MyComponent {
|
|
|
1335
903
|
|
|
1336
904
|
---
|
|
1337
905
|
|
|
1338
|
-
## 💡 Best Practices
|
|
1339
|
-
|
|
1340
|
-
### Component Usage
|
|
1341
|
-
|
|
1342
|
-
#### 1. **Use Two-Way Binding for Forms**
|
|
1343
|
-
|
|
1344
|
-
```typescript
|
|
1345
|
-
// ✅ Good - Two-way binding
|
|
1346
|
-
<app-input-text
|
|
1347
|
-
headerInput="Email"
|
|
1348
|
-
[(value)]="userEmail"
|
|
1349
|
-
></app-input-text>
|
|
1350
|
-
|
|
1351
|
-
// ❌ Avoid - One-way binding without handling value changes
|
|
1352
|
-
<app-input-text
|
|
1353
|
-
headerInput="Email"
|
|
1354
|
-
[value]="userEmail"
|
|
1355
|
-
></app-input-text>
|
|
1356
|
-
```
|
|
1357
|
-
|
|
1358
|
-
#### 2. **Leverage CSS Custom Properties for Theming**
|
|
1359
|
-
|
|
1360
|
-
```typescript
|
|
1361
|
-
// Define your theme colors in global CSS
|
|
1362
|
-
:root {
|
|
1363
|
-
--brand-500: #3b82f6;
|
|
1364
|
-
--brand-600: #2563eb;
|
|
1365
|
-
--neutral-100: #f5f5f5;
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
// Use them in components
|
|
1369
|
-
<app-button-container
|
|
1370
|
-
content="Submit"
|
|
1371
|
-
bgDefault="var(--brand-500)"
|
|
1372
|
-
colorDefault="var(--neutral-100)"
|
|
1373
|
-
></app-button-container>
|
|
1374
|
-
```
|
|
1375
|
-
|
|
1376
|
-
#### 3. **Import Only What You Need**
|
|
1377
|
-
|
|
1378
|
-
```typescript
|
|
1379
|
-
// ✅ Good - Import only required components
|
|
1380
|
-
import { ButtonContainerComponent, InputTextComponent } from "@goat-bravos/intern-hub-layout";
|
|
1381
|
-
|
|
1382
|
-
// ❌ Avoid - Wildcard imports
|
|
1383
|
-
import * from "@goat-bravos/intern-hub-layout";
|
|
1384
|
-
```
|
|
1385
|
-
|
|
1386
|
-
#### 4. **Use Interfaces for Type Safety**
|
|
1387
|
-
|
|
1388
|
-
```typescript
|
|
1389
|
-
import { HeaderData, SidebarData } from "@goat-bravos/intern-hub-layout";
|
|
1390
|
-
|
|
1391
|
-
export class MyComponent {
|
|
1392
|
-
// ✅ Good - Typed data objects
|
|
1393
|
-
headerData: HeaderData = {
|
|
1394
|
-
headerItems: [],
|
|
1395
|
-
userName: "John Doe",
|
|
1396
|
-
};
|
|
1397
|
-
|
|
1398
|
-
// ❌ Avoid - Untyped objects
|
|
1399
|
-
headerData: any = {
|
|
1400
|
-
headerItems: [],
|
|
1401
|
-
userName: "John Doe",
|
|
1402
|
-
};
|
|
1403
|
-
}
|
|
1404
|
-
```
|
|
1405
|
-
|
|
1406
|
-
#### 5. **Handle Events Properly**
|
|
1407
|
-
|
|
1408
|
-
```typescript
|
|
1409
|
-
// ✅ Good - Proper event handling
|
|
1410
|
-
<app-button-container
|
|
1411
|
-
content="Delete"
|
|
1412
|
-
(buttonClick)="confirmDelete()"
|
|
1413
|
-
></app-button-container>
|
|
1414
|
-
|
|
1415
|
-
confirmDelete() {
|
|
1416
|
-
if (confirm("Are you sure?")) {
|
|
1417
|
-
this.deleteItem();
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
// ❌ Avoid - Inline complex logic
|
|
1422
|
-
<app-button-container
|
|
1423
|
-
content="Delete"
|
|
1424
|
-
(buttonClick)="confirm('Are you sure?') && deleteItem()"
|
|
1425
|
-
></app-button-container>
|
|
1426
|
-
```
|
|
1427
|
-
|
|
1428
|
-
### Performance
|
|
1429
|
-
|
|
1430
|
-
- **Use `OnPush` Change Detection**: All library components use `OnPush` for optimal performance
|
|
1431
|
-
- **Avoid Frequent Re-renders**: Pass stable object references to avoid unnecessary re-renders
|
|
1432
|
-
- **Lazy Load Large Components**: Use dynamic imports for modals and heavy components
|
|
1433
|
-
|
|
1434
|
-
### Accessibility
|
|
1435
|
-
|
|
1436
|
-
- **Always Provide Labels**: Use `headerInput` or `label` properties for form elements
|
|
1437
|
-
- **Use Semantic Buttons**: The library components handle semantic HTML automatically
|
|
1438
|
-
- **Test Keyboard Navigation**: Ensure all interactive components are keyboard accessible
|
|
1439
|
-
- **Provide Alt Text**: When using images in headers or icons, provide descriptive text
|
|
1440
|
-
|
|
1441
|
-
---
|
|
1442
|
-
|
|
1443
|
-
## 🔧 Troubleshooting
|
|
1444
|
-
|
|
1445
|
-
### Common Issues
|
|
1446
|
-
|
|
1447
|
-
#### Issue: Components not displaying correctly
|
|
1448
|
-
|
|
1449
|
-
**Possible Causes:**
|
|
1450
|
-
|
|
1451
|
-
- Missing peer dependencies
|
|
1452
|
-
- CSS conflicts with existing styles
|
|
1453
|
-
- Incorrect selector usage
|
|
1454
|
-
|
|
1455
|
-
**Solutions:**
|
|
1456
|
-
|
|
1457
|
-
```bash
|
|
1458
|
-
# Verify all peer dependencies are installed
|
|
1459
|
-
npm list @angular/core @angular/common @angular/forms @angular/router
|
|
1460
|
-
|
|
1461
|
-
# Check package.json for correct versions
|
|
1462
|
-
npm install @angular/common@^21.0.0 @angular/core@^21.0.0
|
|
1463
|
-
```
|
|
1464
|
-
|
|
1465
|
-
#### Issue: Icons not showing
|
|
1466
|
-
|
|
1467
|
-
**Possible Causes:**
|
|
1468
|
-
|
|
1469
|
-
- `dynamic-ds` library not installed
|
|
1470
|
-
- Icon class names incorrect
|
|
1471
|
-
|
|
1472
|
-
**Solutions:**
|
|
1473
|
-
|
|
1474
|
-
```bash
|
|
1475
|
-
# Install the optional icon library
|
|
1476
|
-
npm install dynamic-ds
|
|
1477
|
-
|
|
1478
|
-
# Verify icon names (they should start with 'dsi-')
|
|
1479
|
-
<app-icon icon="dsi-home-01-line"></app-icon>
|
|
1480
|
-
```
|
|
1481
|
-
|
|
1482
|
-
#### Issue: Two-way binding not working
|
|
1483
|
-
|
|
1484
|
-
**Possible Causes:**
|
|
1485
|
-
|
|
1486
|
-
- Missing `FormsModule` import
|
|
1487
|
-
- Incorrect syntax (`[(value)]` vs `[value]`)
|
|
1488
|
-
|
|
1489
|
-
**Solutions:**
|
|
1490
|
-
|
|
1491
|
-
```typescript
|
|
1492
|
-
// Ensure FormsModule is imported
|
|
1493
|
-
import { FormsModule } from '@angular/forms';
|
|
1494
|
-
|
|
1495
|
-
@Component({
|
|
1496
|
-
imports: [FormsModule, InputTextComponent],
|
|
1497
|
-
// ...
|
|
1498
|
-
})
|
|
1499
|
-
|
|
1500
|
-
// Use correct two-way binding syntax
|
|
1501
|
-
<app-input-text [(value)]="myValue"></app-input-text>
|
|
1502
|
-
```
|
|
1503
|
-
|
|
1504
|
-
#### Issue: TypeScript errors about missing interfaces
|
|
1505
|
-
|
|
1506
|
-
**Solutions:**
|
|
1507
|
-
|
|
1508
|
-
```typescript
|
|
1509
|
-
// Import the required interfaces
|
|
1510
|
-
import { HeaderData, SidebarData, ButtonContainerData, IconData } from "@goat-bravos/intern-hub-layout";
|
|
1511
|
-
```
|
|
1512
|
-
|
|
1513
|
-
#### Issue: Sidebar not collapsing/expanding
|
|
1514
|
-
|
|
1515
|
-
**Possible Causes:**
|
|
1516
|
-
|
|
1517
|
-
- Missing router outlet
|
|
1518
|
-
- Incorrect configuration
|
|
1519
|
-
|
|
1520
|
-
**Solutions:**
|
|
1521
|
-
|
|
1522
|
-
```typescript
|
|
1523
|
-
// Ensure Angular Router is properly configured
|
|
1524
|
-
import { RouterOutlet } from '@angular/router';
|
|
1525
|
-
|
|
1526
|
-
@Component({
|
|
1527
|
-
imports: [RouterOutlet, SidebarComponent],
|
|
1528
|
-
template: `
|
|
1529
|
-
<app-sidebar [data]="sidebarData"></app-sidebar>
|
|
1530
|
-
<router-outlet></router-outlet>
|
|
1531
|
-
`
|
|
1532
|
-
})
|
|
1533
|
-
```
|
|
1534
|
-
|
|
1535
|
-
### Getting Help
|
|
1536
|
-
|
|
1537
|
-
If you encounter issues not covered here:
|
|
1538
|
-
|
|
1539
|
-
1. **Check the Demo App**: Review the `/demo` directory for working examples
|
|
1540
|
-
2. **GitHub Issues**: Search for [existing issues](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues)
|
|
1541
|
-
3. **Create an Issue**: Provide a minimal reproduction example
|
|
1542
|
-
4. **Stack Overflow**: Tag with `angular` and `intern-hub-layout`
|
|
1543
|
-
|
|
1544
|
-
---
|
|
1545
|
-
|
|
1546
|
-
## 📝 Changelog
|
|
1547
|
-
|
|
1548
|
-
### Version 3.0.15 (Current)
|
|
1549
|
-
|
|
1550
|
-
**Added:**
|
|
1551
|
-
|
|
1552
|
-
- ✨ DatePickerComponent with ng-zorro-antd integration
|
|
1553
|
-
- Support for single date, range, and multiple modes (date, week, month, quarter, year)
|
|
1554
|
-
- Time selection support
|
|
1555
|
-
- Date disabling functionality
|
|
1556
|
-
- Customizable date formatting
|
|
1557
|
-
- ✨ Modal component with theme support
|
|
1558
|
-
- ✨ File upload components (AvatarUploadButtonComponent and FileUploadDropzoneComponent)
|
|
1559
|
-
- ✨ Drag-and-drop file upload functionality
|
|
1560
|
-
- ✨ Enhanced accessibility features
|
|
1561
|
-
|
|
1562
|
-
**Improved:**
|
|
1563
|
-
|
|
1564
|
-
- 🔧 Better TypeScript type definitions
|
|
1565
|
-
- 🔧 Optimized component performance with OnPush
|
|
1566
|
-
- 📚 Comprehensive README documentation with DatePicker examples
|
|
1567
|
-
- 🔧 Updated project structure documentation
|
|
1568
|
-
|
|
1569
|
-
**Fixed:**
|
|
1570
|
-
|
|
1571
|
-
- 🐛 Icon color inheritance issues
|
|
1572
|
-
- 🐛 Sidebar collapse/expand animations
|
|
1573
|
-
- 🐛 Input validation edge cases
|
|
1574
|
-
|
|
1575
|
-
### Version 3.0.x
|
|
1576
|
-
|
|
1577
|
-
**Added:**
|
|
1578
|
-
|
|
1579
|
-
- Support for Angular 21
|
|
1580
|
-
- Standalone component architecture
|
|
1581
|
-
- Input components (text, stepper, calendar)
|
|
1582
|
-
- Table components with custom templates
|
|
1583
|
-
- Approval list components
|
|
1584
|
-
|
|
1585
|
-
**Changed:**
|
|
1586
|
-
|
|
1587
|
-
- Migrated from NgModules to standalone components
|
|
1588
|
-
- Updated to TypeScript 5.9
|
|
1589
|
-
- Improved CSS architecture
|
|
1590
|
-
|
|
1591
|
-
### Version 2.0.x
|
|
1592
|
-
|
|
1593
|
-
**Added:**
|
|
1594
|
-
|
|
1595
|
-
- Header and sidebar layout components
|
|
1596
|
-
- Button components
|
|
1597
|
-
- Icon support with dynamic-ds
|
|
1598
|
-
|
|
1599
|
-
---
|
|
1600
|
-
|
|
1601
906
|
## 🛠️ Development
|
|
1602
907
|
|
|
1603
|
-
### Prerequisites
|
|
1604
|
-
|
|
1605
|
-
- Node.js (v18 or higher)
|
|
1606
|
-
- npm (v9 or higher)
|
|
1607
|
-
- Angular CLI (v21 or higher)
|
|
1608
|
-
|
|
1609
908
|
### Building the library
|
|
1610
909
|
|
|
1611
|
-
Build the library for production:
|
|
1612
|
-
|
|
1613
910
|
```bash
|
|
1614
911
|
npm run build
|
|
1615
912
|
```
|
|
1616
913
|
|
|
1617
|
-
This will compile the library to the `dist/intern-hub-layout` directory.
|
|
1618
|
-
|
|
1619
914
|
### Running the demo app
|
|
1620
915
|
|
|
1621
|
-
Start the demo application to see all components in action:
|
|
1622
|
-
|
|
1623
916
|
```bash
|
|
1624
917
|
npm run demo
|
|
1625
918
|
```
|
|
1626
919
|
|
|
1627
|
-
Navigate to `http://localhost:4200/` to view the demo.
|
|
1628
|
-
|
|
1629
|
-
### Development Workflow
|
|
1630
|
-
|
|
1631
|
-
1. **Make changes** to components in `src/libs/`
|
|
1632
|
-
2. **Build the library** with `npm run build`
|
|
1633
|
-
3. **Test in demo** app with `npm run demo`
|
|
1634
|
-
4. **Verify build** with `npm run build` after changes
|
|
1635
|
-
|
|
1636
|
-
### Publishing to npm
|
|
1637
|
-
|
|
1638
|
-
#### Dry Run (Test Before Publishing)
|
|
1639
|
-
|
|
1640
|
-
```bash
|
|
1641
|
-
npm run publish:lib:dry
|
|
1642
|
-
```
|
|
1643
|
-
|
|
1644
|
-
This will show what will be published without actually publishing.
|
|
1645
|
-
|
|
1646
|
-
#### Publish to npm Registry
|
|
1647
|
-
|
|
1648
|
-
```bash
|
|
1649
|
-
npm run publish:lib
|
|
1650
|
-
```
|
|
1651
|
-
|
|
1652
|
-
This will:
|
|
1653
|
-
|
|
1654
|
-
1. Build the library
|
|
1655
|
-
2. Navigate to the dist directory
|
|
1656
|
-
3. Publish to npm
|
|
1657
|
-
|
|
1658
|
-
#### Create a Package Tarball
|
|
1659
|
-
|
|
1660
|
-
```bash
|
|
1661
|
-
npm run pack:lib
|
|
1662
|
-
```
|
|
1663
|
-
|
|
1664
|
-
This will:
|
|
1665
|
-
|
|
1666
|
-
1. Increment the patch version
|
|
1667
|
-
2. Build the library
|
|
1668
|
-
3. Create a `.tgz` file for local testing
|
|
1669
|
-
|
|
1670
|
-
### Testing Locally
|
|
1671
|
-
|
|
1672
|
-
To test the library in another Angular project before publishing:
|
|
1673
|
-
|
|
1674
|
-
```bash
|
|
1675
|
-
# In the library project
|
|
1676
|
-
npm run pack:lib
|
|
1677
|
-
|
|
1678
|
-
# In your test project
|
|
1679
|
-
npm install /path/to/intern-hub-layout/dist/intern-hub-layout/goat-bravos-intern-hub-layout-3.0.15.tgz
|
|
1680
|
-
```
|
|
1681
|
-
|
|
1682
|
-
### Project Scripts
|
|
1683
|
-
|
|
1684
|
-
| Script | Description |
|
|
1685
|
-
| ------------------------- | -------------------------------- |
|
|
1686
|
-
| `npm run build` | Build the library for production |
|
|
1687
|
-
| `npm run demo` | Start the demo application |
|
|
1688
|
-
| `npm run publish:lib` | Build and publish to npm |
|
|
1689
|
-
| `npm run publish:lib:dry` | Test publish without uploading |
|
|
1690
|
-
| `npm run pack:lib` | Create a local package tarball |
|
|
1691
|
-
|
|
1692
920
|
---
|
|
1693
921
|
|
|
1694
922
|
## 🤝 Contributing
|
|
1695
923
|
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
### Getting Started
|
|
1699
|
-
|
|
1700
|
-
1. **Fork the repository**
|
|
1701
|
-
|
|
1702
|
-
```bash
|
|
1703
|
-
git clone https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout.git
|
|
1704
|
-
```
|
|
1705
|
-
|
|
1706
|
-
2. **Create a feature branch**
|
|
1707
|
-
|
|
1708
|
-
```bash
|
|
1709
|
-
git checkout -b feature/AmazingFeature
|
|
1710
|
-
```
|
|
1711
|
-
|
|
1712
|
-
3. **Make your changes**
|
|
1713
|
-
- Follow the existing code style
|
|
1714
|
-
- Add tests if applicable
|
|
1715
|
-
- Update documentation
|
|
1716
|
-
|
|
1717
|
-
4. **Commit your changes**
|
|
1718
|
-
|
|
1719
|
-
```bash
|
|
1720
|
-
git commit -m 'feat: Add some AmazingFeature'
|
|
1721
|
-
```
|
|
1722
|
-
|
|
1723
|
-
We follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
1724
|
-
- `feat:` - New feature
|
|
1725
|
-
- `fix:` - Bug fix
|
|
1726
|
-
- `docs:` - Documentation changes
|
|
1727
|
-
- `style:` - Code style changes (formatting, etc.)
|
|
1728
|
-
- `refactor:` - Code refactoring
|
|
1729
|
-
- `test:` - Adding tests
|
|
1730
|
-
- `chore:` - Maintenance tasks
|
|
1731
|
-
|
|
1732
|
-
5. **Push to your fork**
|
|
1733
|
-
|
|
1734
|
-
```bash
|
|
1735
|
-
git push origin feature/AmazingFeature
|
|
1736
|
-
```
|
|
1737
|
-
|
|
1738
|
-
6. **Open a Pull Request**
|
|
1739
|
-
|
|
1740
|
-
Go to the [repository](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout) and create a pull request.
|
|
1741
|
-
|
|
1742
|
-
### Contribution Guidelines
|
|
1743
|
-
|
|
1744
|
-
#### Code Style
|
|
924
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
1745
925
|
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
#### Component Guidelines
|
|
1753
|
-
|
|
1754
|
-
When creating a new component:
|
|
1755
|
-
|
|
1756
|
-
1. **Create in appropriate directory**
|
|
1757
|
-
|
|
1758
|
-
```
|
|
1759
|
-
src/libs/shared/components/your-component/
|
|
1760
|
-
├── your-component.component.ts
|
|
1761
|
-
├── your-component.component.html
|
|
1762
|
-
├── your-component.component.scss
|
|
1763
|
-
└── your-component.model.ts (if needed)
|
|
1764
|
-
```
|
|
1765
|
-
|
|
1766
|
-
2. **Use standalone components**
|
|
1767
|
-
|
|
1768
|
-
```typescript
|
|
1769
|
-
@Component({
|
|
1770
|
-
selector: 'app-your-component',
|
|
1771
|
-
standalone: true,
|
|
1772
|
-
imports: [CommonModule],
|
|
1773
|
-
// ...
|
|
1774
|
-
})
|
|
1775
|
-
```
|
|
1776
|
-
|
|
1777
|
-
3. **Export in public-api.ts**
|
|
1778
|
-
|
|
1779
|
-
```typescript
|
|
1780
|
-
export * from "./libs/shared/components/your-component/your-component.component";
|
|
1781
|
-
```
|
|
1782
|
-
|
|
1783
|
-
4. **Document in README.md**
|
|
1784
|
-
- Add usage examples
|
|
1785
|
-
- Document all inputs and outputs
|
|
1786
|
-
- Include practical examples
|
|
1787
|
-
|
|
1788
|
-
#### Testing
|
|
1789
|
-
|
|
1790
|
-
Before submitting a PR:
|
|
1791
|
-
|
|
1792
|
-
- [ ] Build the library successfully (`npm run build`)
|
|
1793
|
-
- [ ] Test in demo app (`npm run demo`)
|
|
1794
|
-
- [ ] Verify no console errors or warnings
|
|
1795
|
-
- [ ] Test in different browsers (Chrome, Firefox, Safari)
|
|
1796
|
-
- [ ] Check accessibility (keyboard navigation, screen readers)
|
|
1797
|
-
|
|
1798
|
-
#### Pull Request Process
|
|
1799
|
-
|
|
1800
|
-
1. Update the README.md with details of changes
|
|
1801
|
-
2. Update version numbers following [SemVer](https://semver.org/)
|
|
1802
|
-
3. Ensure the PR description clearly describes the problem and solution
|
|
1803
|
-
4. Link any related issues
|
|
1804
|
-
|
|
1805
|
-
### Questions or Issues?
|
|
1806
|
-
|
|
1807
|
-
- Open an [issue](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues)
|
|
1808
|
-
- Reach out to the maintainers
|
|
1809
|
-
- Check existing issues and PRs first
|
|
926
|
+
1. Fork the project
|
|
927
|
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
928
|
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
929
|
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
930
|
+
5. Open a Pull Request
|
|
1810
931
|
|
|
1811
932
|
---
|
|
1812
933
|
|
|
1813
934
|
## 📄 License
|
|
1814
935
|
|
|
1815
|
-
This project is licensed under the
|
|
1816
|
-
|
|
1817
|
-
### MIT License
|
|
1818
|
-
|
|
1819
|
-
```
|
|
1820
|
-
Copyright (c) 2024 FPT IS Intern Team
|
|
1821
|
-
|
|
1822
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1823
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
1824
|
-
in the Software without restriction, including without limitation the rights
|
|
1825
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1826
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
1827
|
-
furnished to do so, subject to the following conditions:
|
|
1828
|
-
|
|
1829
|
-
The above copyright notice and this permission notice shall be included in all
|
|
1830
|
-
copies or substantial portions of the Software.
|
|
1831
|
-
|
|
1832
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1833
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1834
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1835
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1836
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1837
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1838
|
-
SOFTWARE.
|
|
1839
|
-
```
|
|
1840
|
-
|
|
1841
|
-
---
|
|
1842
|
-
|
|
1843
|
-
## 🔗 Links & Resources
|
|
1844
|
-
|
|
1845
|
-
### Official Links
|
|
1846
|
-
|
|
1847
|
-
- **📦 npm Package**: [@goat-bravos/intern-hub-layout](https://www.npmjs.com/package/@goat-bravos/intern-hub-layout)
|
|
1848
|
-
- **💻 GitHub Repository**: [FPT-IS-Intern/Intern-Hub-FE-Layout](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout)
|
|
1849
|
-
- **📝 Changelog**: [GitHub Releases](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/releases)
|
|
1850
|
-
- **🐛 Bug Reports**: [GitHub Issues](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues)
|
|
1851
|
-
|
|
1852
|
-
### Related Projects
|
|
1853
|
-
|
|
1854
|
-
- **Angular**: [https://angular.dev](https://angular.dev)
|
|
1855
|
-
- **TypeScript**: [https://www.typescriptlang.org](https://www.typescriptlang.org)
|
|
1856
|
-
- **Dynamic DS**: Icon library used by this project
|
|
1857
|
-
|
|
1858
|
-
### External Resources
|
|
1859
|
-
|
|
1860
|
-
- [Angular Style Guide](https://angular.dev/style-guide)
|
|
1861
|
-
- [TypeScript Documentation](https://www.typescriptlang.org/docs/)
|
|
1862
|
-
- [Web Accessibility Guidelines (WCAG)](https://www.w3.org/WAI/WCAG21/quickref/)
|
|
1863
|
-
- [Conventional Commits](https://www.conventionalcommits.org/)
|
|
1864
|
-
- [Semantic Versioning](https://semver.org/)
|
|
1865
|
-
|
|
1866
|
-
---
|
|
1867
|
-
|
|
1868
|
-
## 💬 Support
|
|
1869
|
-
|
|
1870
|
-
### Need Help?
|
|
1871
|
-
|
|
1872
|
-
- 💡 **General Questions**: Check the [Troubleshooting](#-troubleshooting) section
|
|
1873
|
-
- 📖 **Documentation**: Read through component examples above
|
|
1874
|
-
- 🐛 **Bug Reports**: [Create an issue](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues/new)
|
|
1875
|
-
- ✨ **Feature Requests**: [Suggest a feature](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues/new)
|
|
1876
|
-
- 💬 **Discussions**: [GitHub Discussions](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/discussions)
|
|
1877
|
-
|
|
1878
|
-
### Stay Updated
|
|
1879
|
-
|
|
1880
|
-
- ⭐ Star the repository to stay updated
|
|
1881
|
-
- 👁️ Watch for new releases
|
|
1882
|
-
- 🍴 Fork to contribute
|
|
1883
|
-
|
|
1884
|
-
---
|
|
1885
|
-
|
|
1886
|
-
## 🙏 Acknowledgments
|
|
1887
|
-
|
|
1888
|
-
Built with ❤️ by the **FPT IS Intern Team**
|
|
1889
|
-
|
|
1890
|
-
Special thanks to:
|
|
1891
|
-
|
|
1892
|
-
- The Angular team for an amazing framework
|
|
1893
|
-
- All contributors who help improve this library
|
|
1894
|
-
- The open-source community
|
|
1895
|
-
|
|
1896
|
-
---
|
|
1897
|
-
|
|
1898
|
-
<div align="center">
|
|
1899
|
-
|
|
1900
|
-
**[⬆ Back to Top](#-intern-hub-layout)**
|
|
1901
|
-
|
|
1902
|
-
Made with 💙 by [FPT IS Intern Team](https://github.com/FPT-IS-Intern)
|
|
1903
|
-
|
|
1904
|
-
**📦 @goat-bravos/intern-hub-layout** | **v3.0.15** | **MIT License**
|
|
1905
|
-
|
|
1906
|
-
</div>
|
|
936
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|