diff --git a/package-lock.json b/package-lock.json index fe3c268c..24ec1d11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "@hug/ngx-components", + "name": "ngx-components", "lockfileVersion": 3, "requires": true, "packages": { @@ -34,6 +34,9 @@ "@angular/platform-browser": "~14.3.0", "@angular/platform-browser-dynamic": "~14.3.0", "@angular/router": "~14.3.0", + "@fontsource-variable/material-symbols-outlined": "~5.0.19", + "@fontsource/material-icons": "4.5.4", + "@fontsource/roboto": "4.5.8", "date-fns": "~2.30.0", "lodash-es": "~4.17.21", "rxjs": "~7.8.1", @@ -4386,6 +4389,21 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fontsource-variable/material-symbols-outlined": { + "version": "5.0.34", + "resolved": "https://nxrm.hisaas.hcuge.ch/repository/npm-all/@fontsource-variable/material-symbols-outlined/-/material-symbols-outlined-5.0.34.tgz", + "integrity": "sha512-dC6BoXU93VMjNlfbn4YRdqsSOFp6Smue2KZgZJ8wy2x0OeyA73hgJyb5i6mV6JZnuaiJHMwqTfwJQ3FtSPKFnw==" + }, + "node_modules/@fontsource/material-icons": { + "version": "4.5.4", + "resolved": "https://nxrm.hisaas.hcuge.ch/repository/npm-all/@fontsource/material-icons/-/material-icons-4.5.4.tgz", + "integrity": "sha512-YGmXkkEdu6EIgpFKNmB/nIXzZocwSmbI01Ninpmml8x8BT0M6RR++V1KqOfpzZ6Cw/FQ2/KYonQ3x4IY/4VRRA==" + }, + "node_modules/@fontsource/roboto": { + "version": "4.5.8", + "resolved": "https://nxrm.hisaas.hcuge.ch/repository/npm-all/@fontsource/roboto/-/roboto-4.5.8.tgz", + "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA==" + }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", diff --git a/package.json b/package.json index a9fce168..ff91df6a 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,9 @@ "@angular/platform-browser": "~14.3.0", "@angular/platform-browser-dynamic": "~14.3.0", "@angular/router": "~14.3.0", + "@fontsource-variable/material-symbols-outlined": "~5.0.19", + "@fontsource/material-icons": "4.5.4", + "@fontsource/roboto": "4.5.8", "date-fns": "~2.30.0", "lodash-es": "~4.17.21", "rxjs": "~7.8.1", diff --git a/projects/core/package.json b/projects/core/package.json index 25e56a58..54a2dfc6 100644 --- a/projects/core/package.json +++ b/projects/core/package.json @@ -27,6 +27,9 @@ "./themeVariables": { "sass": "./styles/_themeVariables.scss" }, + "./dialog": { + "sass": "./styles/mixins/_dialog.scss" + }, "./menu": { "sass": "./styles/mixins/_menu.scss" }, diff --git a/projects/core/src/styles/mixins/_dialog.scss b/projects/core/src/styles/mixins/_dialog.scss new file mode 100644 index 00000000..e5511d7e --- /dev/null +++ b/projects/core/src/styles/mixins/_dialog.scss @@ -0,0 +1,53 @@ +@mixin dialog() { + .no-padding-dialog .mat-dialog-container { + padding: 0; + + .mat-dialog-content { + margin: 0; + } + } + + .mat-dialog-container { + padding: 0; + + .mat-dialog-content { + margin: 0; + } + + .dialog-toolbar { + display: flex; + justify-content: space-between; + + .dialog-title { + padding: 0 1rem 0 0; + } + + .dialog-action { + display: flex; + justify-content: baseline; + align-items: center; + cursor: pointer; + font-size: 85%; + opacity: 0.9; + } + } + + .dialog-container { + padding: 1rem; + max-height: 65vh; + max-width: 90vw; + overflow: auto; + } + + .dialog-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + padding: 0.7rem; + + .mat-button { + margin: 0 0.5rem; + } + } + } +} diff --git a/projects/demo-app/src/app/app.component.html b/projects/demo-app/src/app/app.component.html index e94e5770..b8856da5 100644 --- a/projects/demo-app/src/app/app.component.html +++ b/projects/demo-app/src/app/app.component.html @@ -7,7 +7,13 @@

hug/ngx-components Demo

- + + + + message + Message Box + + menu diff --git a/projects/demo-app/src/app/app.component.ts b/projects/demo-app/src/app/app.component.ts index 6b247cbb..8db4dd02 100644 --- a/projects/demo-app/src/app/app.component.ts +++ b/projects/demo-app/src/app/app.component.ts @@ -1,11 +1,11 @@ import { MediaMatcher } from '@angular/cdk/layout'; import { NgFor, NgIf } from '@angular/common'; -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnDestroy } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, inject } from '@angular/core'; import { MatIconModule } from '@angular/material/icon'; import { MatListModule } from '@angular/material/list'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatToolbarModule } from '@angular/material/toolbar'; -import { RouterOutlet } from '@angular/router'; +import { RouterModule } from '@angular/router'; @Component({ @@ -21,7 +21,7 @@ import { RouterOutlet } from '@angular/router'; MatToolbarModule, NgIf, NgFor, - RouterOutlet + RouterModule ] }) export class AppComponent implements OnDestroy { diff --git a/projects/demo-app/src/app/app.routes.ts b/projects/demo-app/src/app/app.routes.ts index 7ce24d14..128e2a55 100644 --- a/projects/demo-app/src/app/app.routes.ts +++ b/projects/demo-app/src/app/app.routes.ts @@ -1,7 +1,8 @@ import { Routes } from '@angular/router'; export const appRoutes: Routes = [ - { path: '', redirectTo: 'overlay', pathMatch: 'full' }, + { path: '', redirectTo: 'message-box', pathMatch: 'full' }, { path: 'overlay', loadComponent: () => import('./overlay/overlay-demo.component').then(m => m.OverlayDemoComponent), data: { title: 'Overlay' } }, - { path: '**', redirectTo: 'overlay', pathMatch: 'prefix' } + { path: 'message-box', loadComponent: () => import('./message-box/message-box-demo.component').then(m => m.MessageBoxDemoComponent), data: { title: 'Message Box' } }, + { path: '**', redirectTo: 'message-box', pathMatch: 'prefix' } ]; diff --git a/projects/demo-app/src/app/message-box/message-box-demo.component.html b/projects/demo-app/src/app/message-box/message-box-demo.component.html new file mode 100644 index 00000000..3a9f8792 --- /dev/null +++ b/projects/demo-app/src/app/message-box/message-box-demo.component.html @@ -0,0 +1,56 @@ + + + + + + + + + +
+ + Du texte dans la + message box + + + + Du texte dans la + message box + + + + Un message "warn" + horizontal + avec titre + + + + Un message "info" + horizontal + + + + Un message "warn" + horizontal + + + + Un message "danger" + horizontal + avec une action au format template + + + + + + Un message horizontal sans type ni titre + + Un message horizontal sans type ni titre + Un message horizontal sans type ni titre + Un message horizontal sans type ni titre + Un message horizontal sans type ni titre + + +
diff --git a/projects/demo-app/src/app/message-box/message-box-demo.component.scss b/projects/demo-app/src/app/message-box/message-box-demo.component.scss new file mode 100644 index 00000000..274c0c79 --- /dev/null +++ b/projects/demo-app/src/app/message-box/message-box-demo.component.scss @@ -0,0 +1,9 @@ +:host { + .example { + margin-top: 2rem; + } + + message-box { + margin-bottom: 1rem; + } +} diff --git a/projects/demo-app/src/app/message-box/message-box-demo.component.ts b/projects/demo-app/src/app/message-box/message-box-demo.component.ts new file mode 100644 index 00000000..fcce4341 --- /dev/null +++ b/projects/demo-app/src/app/message-box/message-box-demo.component.ts @@ -0,0 +1,59 @@ +import { NgIf } from '@angular/common'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatIconModule } from '@angular/material/icon'; +import { MatTabsModule } from '@angular/material/tabs'; +import { Destroy } from '@hug/ngx-core'; +import { MessageBoxAction, MessageBoxComponent } from '@hug/ngx-message-box'; +import { MessageBoxDialogButtons, MessageBoxDialogService } from '@hug/ngx-message-box-dialog'; +import { Subject, switchMap, takeUntil } from 'rxjs'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + selector: 'app-message-box-demo', + styleUrls: ['./message-box-demo.component.scss'], + templateUrl: './message-box-demo.component.html', + standalone: true, + imports: [ + MatButtonModule, + MatCardModule, + MatIconModule, + MatTabsModule, + MessageBoxComponent, + NgIf + ], +}) +export class MessageBoxDemoComponent extends Destroy { + public tabIndex = 1; + + public closeAction = [ + { + action: (): void => alert('test action'), + icon: 'clear' + } + ] as ReadonlyArray; + + protected openDialog$ = new Subject(); + + private messageBoxService = inject(MessageBoxDialogService); + + public constructor() { + super(); + + this.openDialog$.pipe( + switchMap(() => { + const dialogData = { + title: 'MessageBox Dialog', + text: 'This is a message box dialog. Click OK or Cancel to close.', + buttons: MessageBoxDialogButtons.OK + MessageBoxDialogButtons.CANCEL, + }; + + return this.messageBoxService.openDialog$(dialogData); + }), + takeUntil(this.destroyed$) + ).subscribe(response => { + alert(`${response} was clicked`); + }); + } +} diff --git a/projects/demo-app/src/app/overlay/overlay-demo.component.scss b/projects/demo-app/src/app/overlay/overlay-demo.component.scss index b5ef54fe..147e2d54 100644 --- a/projects/demo-app/src/app/overlay/overlay-demo.component.scss +++ b/projects/demo-app/src/app/overlay/overlay-demo.component.scss @@ -19,7 +19,8 @@ app-overlay-demo { .ngx-menu { .menu-content { - background-color: #fff; + display: flex; + flex-direction: column; &.anchor-menu, &.button-menu { diff --git a/projects/demo-app/src/main.ts b/projects/demo-app/src/main.ts index c68b56b6..5275a773 100644 --- a/projects/demo-app/src/main.ts +++ b/projects/demo-app/src/main.ts @@ -3,6 +3,9 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { provideAnimations } from '@angular/platform-browser/animations'; import { PreloadAllModules, provideRouter, withPreloading } from '@angular/router'; +import { DIALOG_SCROLL_STRATEGY_PROVIDER, Dialog } from '@angular/cdk/dialog'; +import { Overlay } from '@angular/cdk/overlay'; +import { MAT_DIALOG_SCROLL_STRATEGY_PROVIDER, MatDialog } from '@angular/material/dialog'; import { AppComponent } from './app/app.component'; import { appRoutes } from './app/app.routes'; import { environment } from './environments/environment'; @@ -14,6 +17,11 @@ if (environment.production) { bootstrapApplication(AppComponent, { providers: [ provideAnimations(), - provideRouter(appRoutes, withPreloading(PreloadAllModules)) + provideRouter(appRoutes, withPreloading(PreloadAllModules)), + MatDialog, + Overlay, + MAT_DIALOG_SCROLL_STRATEGY_PROVIDER, + Dialog, + DIALOG_SCROLL_STRATEGY_PROVIDER ] }).catch(err => console.error(err)); diff --git a/projects/demo-app/src/styles.scss b/projects/demo-app/src/styles.scss index 107e678c..d44b79c4 100644 --- a/projects/demo-app/src/styles.scss +++ b/projects/demo-app/src/styles.scss @@ -1,44 +1,34 @@ -// Custom Theming for Angular Material -// For more information: https://material.angular.io/guide/theming @use '@angular/material' as mat; -// Plus imports for other components in your app. -//@use "@hug/ngx-list-loader" as list-loader; -// @use "../../list-loader/src/list-loader-theme" as list-loader; - -// Include the common styles for Angular Material. We include this here so that you only -// have to load a single css file for Angular Material in your app. -// Be sure that you only ever include this mixin once! -@include mat.core(); - -// Define the palettes for your theme using the Material Design palettes available in palette.scss -// (imported above). For each palette, you can optionally specify a default, lighter, and darker -// hue. Available color palettes: https://material.io/design/color/ -$demo-app-primary: mat.define-palette(mat.$indigo-palette); -$demo-app-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); - -// The warn palette is optional (defaults to red). -$demo-app-warn: mat.define-palette(mat.$red-palette); - -// Create the theme object. A theme consists of configurations for individual -// theming systems such as "color" or "typography". -$demo-app-theme: mat.define-light-theme( - ( - color: ( - primary: $demo-app-primary, - accent: $demo-app-accent, - warn: $demo-app-warn, - ), - ) -); - -// Include theme styles for core and each component used in your app. -// Alternatively, you can import and @include the theme mixins for each component -// that you are using. -// ex: @include mat.button-theme($demo-app-theme) -@include mat.all-component-themes($demo-app-theme); -// @include list-loader.theme($demo-app-theme); - -/* You can add global styles to this file, and also import other style files */ +@use '../../core/src/styles/themeVariables' as themeVariables; +@use '../../core/src/styles/theme'; +@use '../../core/src/styles/mixins/dialog' as dialog; +@use '../../core/src/styles/mixins/menu' as menu; +@use '../../core/src/styles/mixins/icon-theme' as iconTheme; +@use '../../core/src/styles/mixins/menu-theme' as menuTheme; +@use '../../layout/src/layout-theme' as layoutTheme; +@use '../../search-container/src/search-container-theme' as searchContainerTheme; +@use '../../message-box/src/message-box-theme' as messageBoxTheme; +@use '../../message-box-dialog/src/message-box-dialog-theme' as messageBoxDialogTheme; +@use '../../splitter/src/splitter-theme' as splitterTheme; +@use '../../numeric-stepper/src/numeric-stepper-theme' as numericStepperTheme; +@use '../../user-card/src/user-card-theme' as userCardTheme; +@use '../../status/src/status-theme' as statusTheme; +@use '../../list-loader/src/list-loader-theme' as listLoaderTheme; + +@include layoutTheme.theme(themeVariables.$theme); +@include searchContainerTheme.theme(themeVariables.$theme); +@include messageBoxTheme.theme(themeVariables.$theme); +@include messageBoxDialogTheme.theme(themeVariables.$theme); +@include splitterTheme.theme(themeVariables.$theme); +@include numericStepperTheme.theme(themeVariables.$theme); +@include userCardTheme.theme(themeVariables.$theme); +@include iconTheme.theme(themeVariables.$theme); +@include menuTheme.theme(themeVariables.$theme); +@include statusTheme.theme(themeVariables.$theme); +@include listLoaderTheme.theme(themeVariables.$theme); + +@include menu.menu(); +@include dialog.dialog(); html, body { @@ -49,55 +39,3 @@ body { margin: 0; font-family: Roboto, 'Helvetica Neue', sans-serif; } - -@mixin menu() { - .ngx-menu, - [ngx-menu] { - .cdk-overlay-pane { - display: flex; - flex-direction: column; - - .menu-content { - overflow-x: hidden; - overflow-y: auto; - display: block; - border-style: solid; - border-width: 1px; - box-shadow: - 0 3px 1px -2px rgba(0, 0, 0, 0.2), - 0px 2px 2px 0px rgba(0, 0, 0, 0.14), - 0 1px 5px 0 rgba(0, 0, 0, 0.12); - height: 100%; - - .menu-header, - .menu-footer { - flex: 0 0 auto; - padding: 0.5rem; - } - - > * { - padding: 0; - margin: 0; - display: flex; - flex-direction: column; - flex: 1 1 auto; - - li { - cursor: pointer; - align-items: center; - display: flex; - justify-content: flex-start; - list-style-type: none; - padding: 0.5rem; - - md-icon { - margin: 0 0.5rem; - } - } - } - } - } - } -} - -@include menu(); diff --git a/projects/layout/package.json b/projects/layout/package.json index 855673cd..ac5efbe2 100644 --- a/projects/layout/package.json +++ b/projects/layout/package.json @@ -1,6 +1,6 @@ { "name": "@hug/ngx-layout", - "version": "1.1.2", + "version": "1.1.3", "description": "HUG Angular - layout component", "homepage": "https://github.com/dsi-hug/ngx-components", "license": "GPL-3.0-only", diff --git a/projects/overlay/src/connection-position-pair.ts b/projects/overlay/src/connection-position-pair.ts index ee78043c..0c5c3964 100644 --- a/projects/overlay/src/connection-position-pair.ts +++ b/projects/overlay/src/connection-position-pair.ts @@ -7,7 +7,7 @@ export class OverlayConnectionPositionPair extends ConnectionPositionPair { values.forEach(pos => { const poss = pos.trim().split(' '); if (poss.length !== 4) { - throw new Error('Invalid positions property for DejaMenuComponent. String entry must be of type \'positions="start top end bottom"\''); + throw new Error('Invalid positions property for MenuComponent. String entry must be of type \'positions="start top end bottom"\''); } const originPosition = {