@goat-bravos/intern-hub-layout 3.0.4 → 3.0.7

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,8 +4,9 @@
4
4
  ![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?style=flat&logo=typescript&logoColor=white)
5
5
  ![License](https://img.shields.io/badge/License-MIT-green?style=flat)
6
6
  ![npm](https://img.shields.io/badge/npm-@goat--bravos/intern--hub--layout-CB3837?style=flat&logo=npm)
7
+ ![Version](https://img.shields.io/badge/version-3.0.15-blue?style=flat)
7
8
 
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.
9
+ A comprehensive Angular library providing reusable layout components and shared UI elements for Intern Hub applications. Built with Angular 21, TypeScript 5.9, and designed for seamless integration with modern Angular projects.
9
10
 
10
11
  ---
11
12
 
@@ -14,29 +15,38 @@ A comprehensive Angular library providing reusable layout components and shared
14
15
  - [Features](#-features)
15
16
  - [Installation](#-installation)
16
17
  - [Quick Start](#-quick-start)
18
+ - [Project Structure](#-project-structure)
17
19
  - [Components](#-components)
18
20
  - [Layout Components](#layout-components)
19
21
  - [Button Components](#button-components)
20
22
  - [Input Components](#input-components)
21
23
  - [Table Components](#table-components)
22
24
  - [Approval Components](#approval-components)
25
+ - [Modal Components](#modal-components)
23
26
  - [Pop-up Components](#pop-up-components)
27
+ - [Upload Components](#upload-components)
24
28
  - [Icon Components](#icon-components)
25
- - [Development](#-development)
29
+ - [Best Practices](#-best-practices)
30
+ - [Troubleshooting](#-troubleshooting)
31
+ - [Development](#️-development)
26
32
  - [Contributing](#-contributing)
33
+ - [Changelog](#-changelog)
27
34
  - [License](#-license)
28
35
 
29
36
  ---
30
37
 
31
38
  ## ✨ Features
32
39
 
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
40
+ - 🎨 **Pre-built Layouts** - Header and sidebar components with smooth hover effects and animations
41
+ - 🧩 **Reusable UI Components** - Buttons, inputs, tables, modals, file uploads, approval lists, and more
42
+ - 🔧 **Highly Configurable** - Extensive customization via input properties and CSS custom properties
43
+ - 📦 **Standalone Components** - Modern Angular standalone component architecture (no NgModules required)
44
+ - 🎯 **TypeScript Support** - Full type definitions and interfaces included
45
+ - ♿ **Accessible** - Built with accessibility best practices (ARIA attributes, keyboard navigation)
46
+ - 🚀 **Angular 21 Ready** - Built for the latest Angular version with Signal support
47
+ - 🎭 **Theme Support** - Customizable color schemes using CSS variables
48
+ - 📱 **Responsive** - Mobile-first design with responsive breakpoints
49
+ - 🔄 **Two-way Binding** - Support for Angular's two-way data binding with `[(value)]`
40
50
 
41
51
  ---
42
52
 
@@ -52,13 +62,13 @@ npm install @goat-bravos/intern-hub-layout
52
62
 
53
63
  This library requires the following peer dependencies:
54
64
 
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 |
65
+ | Package | Version | Required | Description |
66
+ | ----------------- | ------- | ----------- | --------------------------------- |
67
+ | `@angular/common` | ^21.0.0 | ✅ Yes | Angular common utilities |
68
+ | `@angular/core` | ^21.0.0 | ✅ Yes | Angular core framework |
69
+ | `@angular/forms` | ^21.0.0 | ✅ Yes | Angular reactive & template forms |
70
+ | `@angular/router` | ^21.0.0 | ✅ Yes | Angular routing |
71
+ | `dynamic-ds` | ^1.0.3 | ⚠️ Optional | Icon library (if using icons) |
62
72
 
63
73
  Install peer dependencies if not already present:
64
74
 
@@ -66,6 +76,12 @@ Install peer dependencies if not already present:
66
76
  npm install @angular/common @angular/core @angular/forms @angular/router
67
77
  ```
68
78
 
79
+ For icon support, install the optional dependency:
80
+
81
+ ```bash
82
+ npm install dynamic-ds
83
+ ```
84
+
69
85
  ---
70
86
 
71
87
  ## 🚀 Quick Start
@@ -83,8 +99,15 @@ import { HeaderComponent, SidebarComponent, ButtonContainerComponent, InputTextC
83
99
  standalone: true,
84
100
  imports: [HeaderComponent, SidebarComponent, ButtonContainerComponent, InputTextComponent],
85
101
  templateUrl: "./app.component.html",
102
+ styleUrls: ["./app.component.scss"],
86
103
  })
87
- export class AppComponent {}
104
+ export class AppComponent {
105
+ username = "";
106
+
107
+ onButtonClick() {
108
+ console.log("Button clicked!");
109
+ }
110
+ }
88
111
  ```
89
112
 
90
113
  ### Step 2: Use in Template
@@ -96,11 +119,76 @@ export class AppComponent {}
96
119
  <!-- Sidebar -->
97
120
  <app-sidebar [data]="sidebarData"></app-sidebar>
98
121
 
99
- <!-- Button -->
100
- <app-button-container content="Click Me" size="md" backgroundColor="var(--brand-500)" (buttonClick)="onButtonClick()"></app-button-container>
122
+ <!-- Main Content Area -->
123
+ <div class="content">
124
+ <!-- Button -->
125
+ <app-button-container content="Click Me" size="md" backgroundColor="var(--brand-500)" (buttonClick)="onButtonClick()"> </app-button-container>
126
+
127
+ <!-- Input -->
128
+ <app-input-text headerInput="Username" placeholder="Enter your username" [required]="true" [(value)]="username"> </app-input-text>
129
+ </div>
130
+ ```
131
+
132
+ ### Step 3: Configure Data Objects (Optional)
133
+
134
+ ```typescript
135
+ import { HeaderData, SidebarData } from "@goat-bravos/intern-hub-layout";
136
+
137
+ export class AppComponent {
138
+ headerData: HeaderData = {
139
+ headerItems: [
140
+ {
141
+ icon: "dsi-bell-line",
142
+ content: "Notifications",
143
+ badge: "5",
144
+ method: () => console.log("Notifications clicked"),
145
+ },
146
+ ],
147
+ userName: "John Doe",
148
+ logo: "assets/logo.png",
149
+ };
150
+
151
+ sidebarData: SidebarData = {
152
+ backgroundColor: "var(--brand-500)",
153
+ menuItems: [
154
+ {
155
+ iconLeft: "dsi-home-01-line",
156
+ content: "Dashboard",
157
+ url: "/dashboard",
158
+ },
159
+ ],
160
+ };
161
+ }
162
+ ```
163
+
164
+ ---
165
+
166
+ ## 📁 Project Structure
101
167
 
102
- <!-- Input -->
103
- <app-input-text headerInput="Username" placeholder="Enter your username" [required]="true" [(value)]="username"></app-input-text>
168
+ ```
169
+ intern-hub-layout/
170
+ ├── src/
171
+ │ ├── libs/
172
+ │ │ ├── layouts/ # Layout components
173
+ │ │ │ ├── header/ # Header component
174
+ │ │ │ └── sidebar/ # Sidebar component
175
+ │ │ └── shared/
176
+ │ │ └── components/ # Shared UI components
177
+ │ │ ├── approval/ # Approval list components
178
+ │ │ ├── button/ # Button components
179
+ │ │ ├── file-upload-dropzone/ # Drag & drop file upload
180
+ │ │ ├── functional-label/ # Label with icons
181
+ │ │ ├── icon/ # Icon component
182
+ │ │ ├── input/ # Input components
183
+ │ │ ├── modal/ # Modal dialog
184
+ │ │ ├── pop-up/ # Confirmation dialogs
185
+ │ │ ├── table/ # Table components
186
+ │ │ └── upload-button/ # File upload button
187
+ │ └── public-api.ts # Public API exports
188
+ ├── demo/ # Demo application
189
+ ├── dist/ # Build output
190
+ ├── README.md # This file
191
+ └── package.json # Package configuration
104
192
  ```
105
193
 
106
194
  ---
@@ -749,11 +837,87 @@ interface ApprovalListItemInterface {
749
837
 
750
838
  ---
751
839
 
840
+ ### Modal Components
841
+
842
+ #### ModalComponent
843
+
844
+ A flexible modal dialog with customizable themes and responsive design.
845
+
846
+ **Selector:** `app-modal`
847
+
848
+ ```typescript
849
+ import { ModalComponent } from "@goat-bravos/intern-hub-layout";
850
+ import { CommonModule } from "@angular/common";
851
+
852
+ @Component({
853
+ imports: [CommonModule, ModalComponent],
854
+ template: `
855
+ <!-- Trigger button -->
856
+ <button (click)="isModalOpen = true">Open Modal</button>
857
+
858
+ <!-- Modal component -->
859
+ @if (isModalOpen) {
860
+ <app-modal [title]="'User Details'" [isOpen]="isModalOpen" [width]="'600px'" [minHeight]="'400px'" [theme]="'default'" (close)="onModalClose()">
861
+ <!-- Modal content goes here -->
862
+ <div class="modal-content">
863
+ <p>This is the modal content area.</p>
864
+ <p>Add any custom content here.</p>
865
+ </div>
866
+ </app-modal>
867
+ }
868
+ `,
869
+ })
870
+ export class MyComponent {
871
+ isModalOpen = false;
872
+
873
+ onModalClose() {
874
+ console.log("Modal closed");
875
+ this.isModalOpen = false;
876
+ }
877
+ }
878
+ ```
879
+
880
+ **Inputs:**
881
+
882
+ | Input | Type | Default | Description |
883
+ | ----------- | ---------------------- | ----------- | ------------------------- |
884
+ | `title` | `string` | `''` | Modal title text |
885
+ | `width` | `string` | `'800px'` | Modal width |
886
+ | `minHeight` | `string` | `'300px'` | Minimum modal height |
887
+ | `isOpen` | `boolean` | `false` | Controls modal visibility |
888
+ | `theme` | `'default' \| 'white'` | `'default'` | Color theme |
889
+
890
+ **Outputs:**
891
+
892
+ | Output | Type | Description |
893
+ | ------- | -------------------- | --------------------------------- |
894
+ | `close` | `EventEmitter<void>` | Emits when modal should be closed |
895
+
896
+ **Content Projection:**
897
+
898
+ The modal supports content projection. Place any HTML content between the opening and closing tags:
899
+
900
+ ```html
901
+ <app-modal [title]="'Custom Modal'" [isOpen]="true" (close)="closeModal()">
902
+ <form>
903
+ <input type="text" placeholder="Name" />
904
+ <button type="submit">Submit</button>
905
+ </form>
906
+ </app-modal>
907
+ ```
908
+
909
+ **Themes:**
910
+
911
+ - `default` - Dark themed modal with contrasting colors
912
+ - `white` - Light themed modal with white background
913
+
914
+ ---
915
+
752
916
  ### Pop-up Components
753
917
 
754
918
  #### PopUpConfirmComponent
755
919
 
756
- An accessible confirmation modal dialog.
920
+ An accessible confirmation modal dialog for user confirmations.
757
921
 
758
922
  **Selector:** `app-pop-up-confirm`
759
923
 
@@ -805,6 +969,124 @@ export class MyComponent {
805
969
 
806
970
  ---
807
971
 
972
+ ### Upload Components
973
+
974
+ #### UploadButtonComponent
975
+
976
+ A file upload button with label, tooltip support, and helper text.
977
+
978
+ **Selector:** `app-upload-button`
979
+
980
+ ```typescript
981
+ import { UploadButtonComponent } from "@goat-bravos/intern-hub-layout";
982
+
983
+ @Component({
984
+ imports: [UploadButtonComponent],
985
+ template: `
986
+ <!-- Basic upload button -->
987
+ <app-upload-button [label]="'Profile Picture'" [required]="true" [buttonText]="'Upload Image'" [acceptFormats]="'.png,.jpg,.jpeg'" [helperText]="'Max size: 5MB (PNG, JPG, JPEG)'" (fileSelected)="onFileSelected($event)"></app-upload-button>
988
+
989
+ <!-- With tooltip -->
990
+ <app-upload-button [label]="'Document Upload'" [showTooltip]="true" [tooltipText]="'Upload your resume or portfolio'" [acceptFormats]="'.pdf,.doc,.docx'" (fileSelected)="onFileSelected($event)"></app-upload-button>
991
+ `,
992
+ })
993
+ export class MyComponent {
994
+ onFileSelected(file: File) {
995
+ console.log("File selected:", file.name, file.size, file.type);
996
+ // Handle file upload logic here
997
+ }
998
+ }
999
+ ```
1000
+
1001
+ **Inputs:**
1002
+
1003
+ | Input | Type | Default | Description |
1004
+ | --------------- | --------- | ------------------------------- | ----------------------------- |
1005
+ | `label` | `string` | `''` | Label text above button |
1006
+ | `required` | `boolean` | `false` | Shows required indicator (\*) |
1007
+ | `showTooltip` | `boolean` | `false` | Shows info tooltip |
1008
+ | `tooltipText` | `string` | `''` | Tooltip content |
1009
+ | `buttonText` | `string` | `'Tải ảnh lên'` | Button text |
1010
+ | `acceptFormats` | `string` | `'.png,.jpeg,.jpg'` | Accepted file formats |
1011
+ | `helperText` | `string` | `'Định dạng .png, .jpeg, .jpg'` | Helper text below button |
1012
+
1013
+ **Outputs:**
1014
+
1015
+ | Output | Type | Description |
1016
+ | -------------- | -------------------- | --------------------------- |
1017
+ | `fileSelected` | `EventEmitter<File>` | Emits when file is selected |
1018
+
1019
+ ---
1020
+
1021
+ #### FileUploadDropzoneComponent
1022
+
1023
+ A drag-and-drop file upload zone with multiple file support.
1024
+
1025
+ **Selector:** `app-file-upload-dropzone`
1026
+
1027
+ ```typescript
1028
+ import { FileUploadDropzoneComponent } from "@goat-bravos/intern-hub-layout";
1029
+
1030
+ @Component({
1031
+ imports: [FileUploadDropzoneComponent],
1032
+ template: `
1033
+ <!-- Single file upload -->
1034
+ <app-file-upload-dropzone [label]="'Upload Assignment'" [buttonText]="'Browse Files'" [maxSize]="'5MB'" [acceptFormats]="'.pdf,.doc,.docx'" (fileSelected)="onSingleFileSelected($event)"></app-file-upload-dropzone>
1035
+
1036
+ <!-- Multiple files upload -->
1037
+ <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>
1038
+ `,
1039
+ })
1040
+ export class MyComponent {
1041
+ onSingleFileSelected(file: File) {
1042
+ console.log("Single file selected:", file.name);
1043
+ // Handle single file upload
1044
+ }
1045
+
1046
+ onMultipleFilesSelected(files: File[]) {
1047
+ console.log(`${files.length} files selected`);
1048
+ files.forEach((file) => {
1049
+ console.log("File:", file.name, file.size);
1050
+ });
1051
+ // Handle multiple files upload
1052
+ }
1053
+ }
1054
+ ```
1055
+
1056
+ **Inputs:**
1057
+
1058
+ | Input | Type | Default | Description |
1059
+ | --------------- | -------- | --------------------------------------- | ---------------------------- |
1060
+ | `label` | `string` | `'Thêm file bài học'` | Label text above dropzone |
1061
+ | `buttonText` | `string` | `'Tải lên'` | Button text |
1062
+ | `maxSize` | `string` | `'10MB'` | Maximum file size |
1063
+ | `acceptFormats` | `string` | `'.docx,.xlsx,.png,.jpg,.jpeg,.pdf'` | Accepted file formats |
1064
+ | `helperText` | `string` | Auto-generated from maxSize and formats | Helper text (auto or custom) |
1065
+
1066
+ **Outputs:**
1067
+
1068
+ | Output | Type | Description |
1069
+ | --------------- | ---------------------- | -------------------------------------- |
1070
+ | `fileSelected` | `EventEmitter<File>` | Emits when single file is selected |
1071
+ | `filesSelected` | `EventEmitter<File[]>` | Emits when multiple files are selected |
1072
+
1073
+ **Features:**
1074
+
1075
+ - ✅ **Drag & Drop Support** - Users can drag files directly onto the dropzone
1076
+ - ✅ **Visual Feedback** - Highlighted border when dragging files over the zone
1077
+ - ✅ **Multiple Files** - Supports both single and multiple file selection
1078
+ - ✅ **Format Validation** - Restricts file types based on `acceptFormats`
1079
+ - ✅ **Size Display** - Shows maximum allowed file size
1080
+ - ✅ **Accessible** - Keyboard-accessible file input
1081
+
1082
+ **Usage Tips:**
1083
+
1084
+ - The component will emit `fileSelected` for single file uploads
1085
+ - The component will emit `filesSelected` for multiple file uploads
1086
+ - Helper text is automatically generated from `maxSize` and `acceptFormats`, but can be overridden
1087
+
1088
+ ---
1089
+
808
1090
  ### Icon Components
809
1091
 
810
1092
  #### IconComponent
@@ -903,34 +1185,566 @@ export class MyComponent {
903
1185
 
904
1186
  ---
905
1187
 
1188
+ ## 💡 Best Practices
1189
+
1190
+ ### Component Usage
1191
+
1192
+ #### 1. **Use Two-Way Binding for Forms**
1193
+
1194
+ ```typescript
1195
+ // ✅ Good - Two-way binding
1196
+ <app-input-text
1197
+ headerInput="Email"
1198
+ [(value)]="userEmail"
1199
+ ></app-input-text>
1200
+
1201
+ // ❌ Avoid - One-way binding without handling value changes
1202
+ <app-input-text
1203
+ headerInput="Email"
1204
+ [value]="userEmail"
1205
+ ></app-input-text>
1206
+ ```
1207
+
1208
+ #### 2. **Leverage CSS Custom Properties for Theming**
1209
+
1210
+ ```typescript
1211
+ // Define your theme colors in global CSS
1212
+ :root {
1213
+ --brand-500: #3b82f6;
1214
+ --brand-600: #2563eb;
1215
+ --neutral-100: #f5f5f5;
1216
+ }
1217
+
1218
+ // Use them in components
1219
+ <app-button-container
1220
+ content="Submit"
1221
+ backgroundColor="var(--brand-500)"
1222
+ color="var(--neutral-100)"
1223
+ ></app-button-container>
1224
+ ```
1225
+
1226
+ #### 3. **Import Only What You Need**
1227
+
1228
+ ```typescript
1229
+ // ✅ Good - Import only required components
1230
+ import { ButtonContainerComponent, InputTextComponent } from "@goat-bravos/intern-hub-layout";
1231
+
1232
+ // ❌ Avoid - Wildcard imports
1233
+ import * from "@goat-bravos/intern-hub-layout";
1234
+ ```
1235
+
1236
+ #### 4. **Use Interfaces for Type Safety**
1237
+
1238
+ ```typescript
1239
+ import { HeaderData, SidebarData } from "@goat-bravos/intern-hub-layout";
1240
+
1241
+ export class MyComponent {
1242
+ // ✅ Good - Typed data objects
1243
+ headerData: HeaderData = {
1244
+ headerItems: [],
1245
+ userName: "John Doe",
1246
+ };
1247
+
1248
+ // ❌ Avoid - Untyped objects
1249
+ headerData: any = {
1250
+ headerItems: [],
1251
+ userName: "John Doe",
1252
+ };
1253
+ }
1254
+ ```
1255
+
1256
+ #### 5. **Handle Events Properly**
1257
+
1258
+ ```typescript
1259
+ // ✅ Good - Proper event handling
1260
+ <app-button-container
1261
+ content="Delete"
1262
+ (buttonClick)="confirmDelete()"
1263
+ ></app-button-container>
1264
+
1265
+ confirmDelete() {
1266
+ if (confirm("Are you sure?")) {
1267
+ this.deleteItem();
1268
+ }
1269
+ }
1270
+
1271
+ // ❌ Avoid - Inline complex logic
1272
+ <app-button-container
1273
+ content="Delete"
1274
+ (buttonClick)="confirm('Are you sure?') && deleteItem()"
1275
+ ></app-button-container>
1276
+ ```
1277
+
1278
+ ### Performance
1279
+
1280
+ - **Use `OnPush` Change Detection**: All library components use `OnPush` for optimal performance
1281
+ - **Avoid Frequent Re-renders**: Pass stable object references to avoid unnecessary re-renders
1282
+ - **Lazy Load Large Components**: Use dynamic imports for modals and heavy components
1283
+
1284
+ ### Accessibility
1285
+
1286
+ - **Always Provide Labels**: Use `headerInput` or `label` properties for form elements
1287
+ - **Use Semantic Buttons**: The library components handle semantic HTML automatically
1288
+ - **Test Keyboard Navigation**: Ensure all interactive components are keyboard accessible
1289
+ - **Provide Alt Text**: When using images in headers or icons, provide descriptive text
1290
+
1291
+ ---
1292
+
1293
+ ## 🔧 Troubleshooting
1294
+
1295
+ ### Common Issues
1296
+
1297
+ #### Issue: Components not displaying correctly
1298
+
1299
+ **Possible Causes:**
1300
+
1301
+ - Missing peer dependencies
1302
+ - CSS conflicts with existing styles
1303
+ - Incorrect selector usage
1304
+
1305
+ **Solutions:**
1306
+
1307
+ ```bash
1308
+ # Verify all peer dependencies are installed
1309
+ npm list @angular/core @angular/common @angular/forms @angular/router
1310
+
1311
+ # Check package.json for correct versions
1312
+ npm install @angular/common@^21.0.0 @angular/core@^21.0.0
1313
+ ```
1314
+
1315
+ #### Issue: Icons not showing
1316
+
1317
+ **Possible Causes:**
1318
+
1319
+ - `dynamic-ds` library not installed
1320
+ - Icon class names incorrect
1321
+
1322
+ **Solutions:**
1323
+
1324
+ ```bash
1325
+ # Install the optional icon library
1326
+ npm install dynamic-ds
1327
+
1328
+ # Verify icon names (they should start with 'dsi-')
1329
+ <app-icon icon="dsi-home-01-line"></app-icon>
1330
+ ```
1331
+
1332
+ #### Issue: Two-way binding not working
1333
+
1334
+ **Possible Causes:**
1335
+
1336
+ - Missing `FormsModule` import
1337
+ - Incorrect syntax (`[(value)]` vs `[value]`)
1338
+
1339
+ **Solutions:**
1340
+
1341
+ ```typescript
1342
+ // Ensure FormsModule is imported
1343
+ import { FormsModule } from '@angular/forms';
1344
+
1345
+ @Component({
1346
+ imports: [FormsModule, InputTextComponent],
1347
+ // ...
1348
+ })
1349
+
1350
+ // Use correct two-way binding syntax
1351
+ <app-input-text [(value)]="myValue"></app-input-text>
1352
+ ```
1353
+
1354
+ #### Issue: TypeScript errors about missing interfaces
1355
+
1356
+ **Solutions:**
1357
+
1358
+ ```typescript
1359
+ // Import the required interfaces
1360
+ import { HeaderData, SidebarData, ButtonContainerData, IconData } from "@goat-bravos/intern-hub-layout";
1361
+ ```
1362
+
1363
+ #### Issue: Sidebar not collapsing/expanding
1364
+
1365
+ **Possible Causes:**
1366
+
1367
+ - Missing router outlet
1368
+ - Incorrect configuration
1369
+
1370
+ **Solutions:**
1371
+
1372
+ ```typescript
1373
+ // Ensure Angular Router is properly configured
1374
+ import { RouterOutlet } from '@angular/router';
1375
+
1376
+ @Component({
1377
+ imports: [RouterOutlet, SidebarComponent],
1378
+ template: `
1379
+ <app-sidebar [data]="sidebarData"></app-sidebar>
1380
+ <router-outlet></router-outlet>
1381
+ `
1382
+ })
1383
+ ```
1384
+
1385
+ ### Getting Help
1386
+
1387
+ If you encounter issues not covered here:
1388
+
1389
+ 1. **Check the Demo App**: Review the `/demo` directory for working examples
1390
+ 2. **GitHub Issues**: Search for [existing issues](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues)
1391
+ 3. **Create an Issue**: Provide a minimal reproduction example
1392
+ 4. **Stack Overflow**: Tag with `angular` and `intern-hub-layout`
1393
+
1394
+ ---
1395
+
1396
+ ## 📝 Changelog
1397
+
1398
+ ### Version 3.0.15 (Current)
1399
+
1400
+ **Added:**
1401
+
1402
+ - ✨ Modal component with theme support
1403
+ - ✨ File upload components (button and dropzone)
1404
+ - ✨ Drag-and-drop file upload functionality
1405
+ - ✨ Enhanced accessibility features
1406
+
1407
+ **Improved:**
1408
+
1409
+ - 🔧 Better TypeScript type definitions
1410
+ - 🔧 Optimized component performance with OnPush
1411
+ - 📚 Comprehensive README documentation
1412
+
1413
+ **Fixed:**
1414
+
1415
+ - 🐛 Icon color inheritance issues
1416
+ - 🐛 Sidebar collapse/expand animations
1417
+ - 🐛 Input validation edge cases
1418
+
1419
+ ### Version 3.0.x
1420
+
1421
+ **Added:**
1422
+
1423
+ - Support for Angular 21
1424
+ - Standalone component architecture
1425
+ - Input components (text, stepper, calendar)
1426
+ - Table components with custom templates
1427
+ - Approval list components
1428
+
1429
+ **Changed:**
1430
+
1431
+ - Migrated from NgModules to standalone components
1432
+ - Updated to TypeScript 5.9
1433
+ - Improved CSS architecture
1434
+
1435
+ ### Version 2.0.x
1436
+
1437
+ **Added:**
1438
+
1439
+ - Header and sidebar layout components
1440
+ - Button components
1441
+ - Icon support with dynamic-ds
1442
+
1443
+ ---
1444
+
906
1445
  ## 🛠️ Development
907
1446
 
1447
+ ### Prerequisites
1448
+
1449
+ - Node.js (v18 or higher)
1450
+ - npm (v9 or higher)
1451
+ - Angular CLI (v21 or higher)
1452
+
908
1453
  ### Building the library
909
1454
 
1455
+ Build the library for production:
1456
+
910
1457
  ```bash
911
1458
  npm run build
912
1459
  ```
913
1460
 
1461
+ This will compile the library to the `dist/intern-hub-layout` directory.
1462
+
914
1463
  ### Running the demo app
915
1464
 
1465
+ Start the demo application to see all components in action:
1466
+
916
1467
  ```bash
917
1468
  npm run demo
918
1469
  ```
919
1470
 
1471
+ Navigate to `http://localhost:4200/` to view the demo.
1472
+
1473
+ ### Development Workflow
1474
+
1475
+ 1. **Make changes** to components in `src/libs/`
1476
+ 2. **Build the library** with `npm run build`
1477
+ 3. **Test in demo** app with `npm run demo`
1478
+ 4. **Verify build** with `npm run build` after changes
1479
+
1480
+ ### Publishing to npm
1481
+
1482
+ #### Dry Run (Test Before Publishing)
1483
+
1484
+ ```bash
1485
+ npm run publish:lib:dry
1486
+ ```
1487
+
1488
+ This will show what will be published without actually publishing.
1489
+
1490
+ #### Publish to npm Registry
1491
+
1492
+ ```bash
1493
+ npm run publish:lib
1494
+ ```
1495
+
1496
+ This will:
1497
+
1498
+ 1. Build the library
1499
+ 2. Navigate to the dist directory
1500
+ 3. Publish to npm
1501
+
1502
+ #### Create a Package Tarball
1503
+
1504
+ ```bash
1505
+ npm run pack:lib
1506
+ ```
1507
+
1508
+ This will:
1509
+
1510
+ 1. Increment the patch version
1511
+ 2. Build the library
1512
+ 3. Create a `.tgz` file for local testing
1513
+
1514
+ ### Testing Locally
1515
+
1516
+ To test the library in another Angular project before publishing:
1517
+
1518
+ ```bash
1519
+ # In the library project
1520
+ npm run pack:lib
1521
+
1522
+ # In your test project
1523
+ npm install /path/to/intern-hub-layout/dist/intern-hub-layout/goat-bravos-intern-hub-layout-3.0.15.tgz
1524
+ ```
1525
+
1526
+ ### Project Scripts
1527
+
1528
+ | Script | Description |
1529
+ | ------------------------- | -------------------------------- |
1530
+ | `npm run build` | Build the library for production |
1531
+ | `npm run demo` | Start the demo application |
1532
+ | `npm run publish:lib` | Build and publish to npm |
1533
+ | `npm run publish:lib:dry` | Test publish without uploading |
1534
+ | `npm run pack:lib` | Create a local package tarball |
1535
+
920
1536
  ---
921
1537
 
922
1538
  ## 🤝 Contributing
923
1539
 
924
- Contributions are welcome! Please feel free to submit a Pull Request.
1540
+ We welcome contributions from the community! Here's how you can help:
1541
+
1542
+ ### Getting Started
1543
+
1544
+ 1. **Fork the repository**
1545
+
1546
+ ```bash
1547
+ git clone https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout.git
1548
+ ```
1549
+
1550
+ 2. **Create a feature branch**
1551
+
1552
+ ```bash
1553
+ git checkout -b feature/AmazingFeature
1554
+ ```
1555
+
1556
+ 3. **Make your changes**
1557
+ - Follow the existing code style
1558
+ - Add tests if applicable
1559
+ - Update documentation
1560
+
1561
+ 4. **Commit your changes**
1562
+
1563
+ ```bash
1564
+ git commit -m 'feat: Add some AmazingFeature'
1565
+ ```
1566
+
1567
+ We follow [Conventional Commits](https://www.conventionalcommits.org/):
1568
+ - `feat:` - New feature
1569
+ - `fix:` - Bug fix
1570
+ - `docs:` - Documentation changes
1571
+ - `style:` - Code style changes (formatting, etc.)
1572
+ - `refactor:` - Code refactoring
1573
+ - `test:` - Adding tests
1574
+ - `chore:` - Maintenance tasks
1575
+
1576
+ 5. **Push to your fork**
1577
+
1578
+ ```bash
1579
+ git push origin feature/AmazingFeature
1580
+ ```
1581
+
1582
+ 6. **Open a Pull Request**
1583
+
1584
+ Go to the [repository](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout) and create a pull request.
1585
+
1586
+ ### Contribution Guidelines
1587
+
1588
+ #### Code Style
1589
+
1590
+ - Use TypeScript strict mode
1591
+ - Follow Angular style guide
1592
+ - Use meaningful variable and function names
1593
+ - Add comments for complex logic
1594
+ - Keep components focused and single-purpose
1595
+
1596
+ #### Component Guidelines
1597
+
1598
+ When creating a new component:
1599
+
1600
+ 1. **Create in appropriate directory**
1601
+
1602
+ ```
1603
+ src/libs/shared/components/your-component/
1604
+ ├── your-component.component.ts
1605
+ ├── your-component.component.html
1606
+ ├── your-component.component.scss
1607
+ └── your-component.model.ts (if needed)
1608
+ ```
1609
+
1610
+ 2. **Use standalone components**
1611
+
1612
+ ```typescript
1613
+ @Component({
1614
+ selector: 'app-your-component',
1615
+ standalone: true,
1616
+ imports: [CommonModule],
1617
+ // ...
1618
+ })
1619
+ ```
1620
+
1621
+ 3. **Export in public-api.ts**
925
1622
 
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
1623
+ ```typescript
1624
+ export * from "./libs/shared/components/your-component/your-component.component";
1625
+ ```
1626
+
1627
+ 4. **Document in README.md**
1628
+ - Add usage examples
1629
+ - Document all inputs and outputs
1630
+ - Include practical examples
1631
+
1632
+ #### Testing
1633
+
1634
+ Before submitting a PR:
1635
+
1636
+ - [ ] Build the library successfully (`npm run build`)
1637
+ - [ ] Test in demo app (`npm run demo`)
1638
+ - [ ] Verify no console errors or warnings
1639
+ - [ ] Test in different browsers (Chrome, Firefox, Safari)
1640
+ - [ ] Check accessibility (keyboard navigation, screen readers)
1641
+
1642
+ #### Pull Request Process
1643
+
1644
+ 1. Update the README.md with details of changes
1645
+ 2. Update version numbers following [SemVer](https://semver.org/)
1646
+ 3. Ensure the PR description clearly describes the problem and solution
1647
+ 4. Link any related issues
1648
+
1649
+ ### Questions or Issues?
1650
+
1651
+ - Open an [issue](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues)
1652
+ - Reach out to the maintainers
1653
+ - Check existing issues and PRs first
931
1654
 
932
1655
  ---
933
1656
 
934
1657
  ## 📄 License
935
1658
 
936
- This project is licensed under the MIT License - see the LICENSE file for details.
1659
+ This project is licensed under the **MIT License**.
1660
+
1661
+ ### MIT License
1662
+
1663
+ ```
1664
+ Copyright (c) 2024 FPT IS Intern Team
1665
+
1666
+ Permission is hereby granted, free of charge, to any person obtaining a copy
1667
+ of this software and associated documentation files (the "Software"), to deal
1668
+ in the Software without restriction, including without limitation the rights
1669
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1670
+ copies of the Software, and to permit persons to whom the Software is
1671
+ furnished to do so, subject to the following conditions:
1672
+
1673
+ The above copyright notice and this permission notice shall be included in all
1674
+ copies or substantial portions of the Software.
1675
+
1676
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1677
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1678
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1679
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1680
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1681
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1682
+ SOFTWARE.
1683
+ ```
1684
+
1685
+ ---
1686
+
1687
+ ## 🔗 Links & Resources
1688
+
1689
+ ### Official Links
1690
+
1691
+ - **📦 npm Package**: [@goat-bravos/intern-hub-layout](https://www.npmjs.com/package/@goat-bravos/intern-hub-layout)
1692
+ - **💻 GitHub Repository**: [FPT-IS-Intern/Intern-Hub-FE-Layout](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout)
1693
+ - **📝 Changelog**: [GitHub Releases](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/releases)
1694
+ - **🐛 Bug Reports**: [GitHub Issues](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues)
1695
+
1696
+ ### Related Projects
1697
+
1698
+ - **Angular**: [https://angular.dev](https://angular.dev)
1699
+ - **TypeScript**: [https://www.typescriptlang.org](https://www.typescriptlang.org)
1700
+ - **Dynamic DS**: Icon library used by this project
1701
+
1702
+ ### External Resources
1703
+
1704
+ - [Angular Style Guide](https://angular.dev/style-guide)
1705
+ - [TypeScript Documentation](https://www.typescriptlang.org/docs/)
1706
+ - [Web Accessibility Guidelines (WCAG)](https://www.w3.org/WAI/WCAG21/quickref/)
1707
+ - [Conventional Commits](https://www.conventionalcommits.org/)
1708
+ - [Semantic Versioning](https://semver.org/)
1709
+
1710
+ ---
1711
+
1712
+ ## 💬 Support
1713
+
1714
+ ### Need Help?
1715
+
1716
+ - 💡 **General Questions**: Check the [Troubleshooting](#-troubleshooting) section
1717
+ - 📖 **Documentation**: Read through component examples above
1718
+ - 🐛 **Bug Reports**: [Create an issue](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues/new)
1719
+ - ✨ **Feature Requests**: [Suggest a feature](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/issues/new)
1720
+ - 💬 **Discussions**: [GitHub Discussions](https://github.com/FPT-IS-Intern/Intern-Hub-FE-Layout/discussions)
1721
+
1722
+ ### Stay Updated
1723
+
1724
+ - ⭐ Star the repository to stay updated
1725
+ - 👁️ Watch for new releases
1726
+ - 🍴 Fork to contribute
1727
+
1728
+ ---
1729
+
1730
+ ## 🙏 Acknowledgments
1731
+
1732
+ Built with ❤️ by the **FPT IS Intern Team**
1733
+
1734
+ Special thanks to:
1735
+
1736
+ - The Angular team for an amazing framework
1737
+ - All contributors who help improve this library
1738
+ - The open-source community
1739
+
1740
+ ---
1741
+
1742
+ <div align="center">
1743
+
1744
+ **[⬆ Back to Top](#-intern-hub-layout)**
1745
+
1746
+ Made with 💙 by [FPT IS Intern Team](https://github.com/FPT-IS-Intern)
1747
+
1748
+ **📦 @goat-bravos/intern-hub-layout** | **v3.0.15** | **MIT License**
1749
+
1750
+ </div>