diff --git a/CHANGELOG.md b/CHANGELOG.md index 9487932..98d61b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.15] - 2025-07-30 +### Added +- Menu bar compoenent + ## [1.0.14] - 2025-07-29 ### fixed - Package publication error fixed diff --git a/README.md b/README.md index 9ba20ca..d8e7297 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # visua-vue -**Current version: v1.0.14** \ No newline at end of file +**Current version: v1.0.15** \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3f85de8..a793179 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cellule-financiere-pmo/visua-vue", - "version": "1.0.14", + "version": "1.0.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cellule-financiere-pmo/visua-vue", - "version": "1.0.14", + "version": "1.0.15", "license": "ISC", "dependencies": { "@cellule-financiere-pmo/visua": "1.1.3", diff --git a/package.json b/package.json index 8fe7545..a44bfb1 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,25 @@ { "name": "@cellule-financiere-pmo/visua-vue", - "version": "1.0.14", + "version": "1.0.15", "type": "module", "description": "Composants Vue.js du Design System Visua.", "main": "dist/visua-vue.umd.js", "module": "dist/visua-vue.es.js", "types": "dist/index.d.ts", + "exports": { + ".": { + "require": "./dist/visua-vue.umd.js", + "import": "./dist/visua-vue.es.js", + "types": "./dist/index.d.ts" + } + }, + "sideEffects": false, "files": [ - "dist" + "dist", + "src/components/*.vue", + "src/components/**/*.ts", + "src/components/**/*.type.ts", + "src/composables/*" ], "scripts": { "dev": "vite", diff --git a/src/App.vue b/src/App.vue index 6abd524..94c5e86 100644 --- a/src/App.vue +++ b/src/App.vue @@ -13,7 +13,8 @@ // import VAlertView from '../template/VAlertView.vue'; // import VModalView from '../template/VModalView.vue'; // import VConfirmModalView from '../template/VConfirmModalView.vue'; -import VDataTableView from '../template/VDataTableView.vue'; +// import VDataTableView from '../template/VDataTableView.vue'; +import VMenuBarView from '../template/VMenuBarView.vue' @@ -32,5 +33,14 @@ import VDataTableView from '../template/VDataTableView.vue'; - + + + + diff --git a/src/assets/base.css b/src/assets/base.css index 5df8f7f..6800f62 100644 --- a/src/assets/base.css +++ b/src/assets/base.css @@ -8,4 +8,6 @@ html { font-size: 16px; font-family: var(--font-family-primary); font-style: normal; + padding: 0px; + margin: 0px; } diff --git a/src/assets/style/global.css b/src/assets/style/global.css index b326de8..fd714b6 100644 --- a/src/assets/style/global.css +++ b/src/assets/style/global.css @@ -31,7 +31,7 @@ /* menu */ --menu-container-border-color: var(--border-default-grey); --menu-border-width: 0px 0px 0px var(--large-border-width); - --menu-default-background: var(--background-transparent); + --menu-default-background: var(--background-default-grey); --menu-default-color: var(--text-default-grey); --menu-active-color: var(--text-active-blue-france); --menu-hover-background: var(--background-transparent-active); @@ -41,4 +41,5 @@ --menu-indent: 1rem; --menu-border-color: transparent; --menu-border-color-active: var(--border-active-blue-france); + --menu-border-radius: 0px; } diff --git a/src/assets/style/primevue-configuration.css b/src/assets/style/primevue-configuration.css index 1a1ca2e..f07817d 100644 --- a/src/assets/style/primevue-configuration.css +++ b/src/assets/style/primevue-configuration.css @@ -21,3 +21,5 @@ @import './primevue-style/datatable.css'; @import './primevue-style/paginator.css'; @import './primevue-style/list.css'; +@import './primevue-style/menubar.css'; +@import './primevue-style/navigation.css'; diff --git a/src/assets/style/primevue-style/menubar.css b/src/assets/style/primevue-style/menubar.css new file mode 100644 index 0000000..ec3e09c --- /dev/null +++ b/src/assets/style/primevue-style/menubar.css @@ -0,0 +1,44 @@ +:root { + --p-menubar-mobile-button-border-radius: var(--menu-border-radius); + --p-menubar-mobile-button-size: 1.75rem; + --p-menubar-mobile-button-color: var(--text-active-blue-france); + --p-menubar-mobile-button-hover-color: var(--text-active-blue-france); + --p-menubar-mobile-button-hover-background: var(--background-transparent-active); + --p-menubar-mobile-button-focus-ring-width: var(--focus-width); + --p-menubar-mobile-button-focus-ring-style: var(--focus-style); + --p-menubar-mobile-button-focus-ring-color: var(--focus-color); + --p-menubar-mobile-button-focus-ring-offset: var(--focus-offset); + /* --p-menubar-mobile-button-focus-ring-shadow: */ + --p-menubar-separator-border-color: var(--border-default-grey); + --p-menubar-submenu-padding: var(--p-navigation-list-padding); + --p-menubar-submenu-gap: var(--p-navigation-list-gap); + --p-menubar-submenu-background: var(--background-transparent); + --p-menubar-submenu-border-color: var(--border-default-grey); + --p-menubar-submenu-border-radius: var(--menu-border-radius); + --p-menubar-submenu-shadow: var(--shadow); + --p-menubar-submenu-mobile-indent: 1rem; + --p-menubar-submenu-icon-size: var(--p-navigation-submenu-icon-size); + --p-menubar-submenu-icon-color: var(--p-navigation-submenu-icon-color); + --p-menubar-submenu-icon-focus-color: var(--p-navigation-submenu-icon-focus-color); + --p-menubar-submenu-icon-active-color: var(--p-navigation-submenu-icon-active-color); + --p-menubar-item-focus-background: var(--p-navigation-item-focus-background); + --p-menubar-item-active-background: var(--p-navigation-item-active-background); + --p-menubar-item-color: var(--p-navigation-item-color); + --p-menubar-item-focus-color: var(--p-navigation-item-focus-color); + --p-menubar-item-active-color: var(--p-navigation-item-active-color); + --p-menubar-item-padding: var(--p-navigation-item-padding); + --p-menubar-item-border-radius: var(--p-navigation-item-border-radius); + --p-menubar-item-gap: var(--p-navigation-item-gap); + --p-menubar-item-icon-color: var(--p-navigation-item-icon-color); + --p-menubar-item-icon-focus-color: var(--p-navigation-item-icon-focus-color); + --p-menubar-item-icon-active-color: var(--p-navigation-item-icon-active-color); + --p-menubar-base-item-border-radius: var(--menu-border-radius); + --p-menubar-base-item-padding: var(--p-navigation-item-padding); + --p-menubar-background: var(--background-transparent); + --p-menubar-border-color: var(--border-default-grey); + --p-menubar-border-radius: var(--menu-border-radius); + --p-menubar-color: var(--menu-default-color); + --p-menubar-gap: 0.5rem; + --p-menubar-padding: var(--menu-padding); + --p-menubar-transition-duration: var(--transition-duration); +} diff --git a/src/assets/style/primevue-style/navigation.css b/src/assets/style/primevue-style/navigation.css new file mode 100644 index 0000000..732ec93 --- /dev/null +++ b/src/assets/style/primevue-style/navigation.css @@ -0,0 +1,23 @@ +:root{ + --p-navigation-submenu-icon-size: 0.875rem; + --p-navigation-submenu-label-padding: var(--menu-padding); + --p-navigation-submenu-label-font-weight: var( --titles-H4-SM-weight); + --p-navigation-item-padding: calc(var(--menu-padding) * 3); + --p-navigation-item-border-radius: var(--p-border-radius-sm); + --p-navigation-item-gap: var(--menu-item-gap); + --p-navigation-list-padding: var(--menu-padding); + --p-navigation-list-gap: var(--menu-gap); + --p-navigation-submenu-icon-color: var(--menu-default-color); + --p-navigation-submenu-icon-focus-color: var(--menu-active-color); + --p-navigation-submenu-icon-active-color: var(--menu-active-color); + --p-navigation-submenu-label-background: var(--menu-default-background); + --p-navigation-submenu-label-color: var(--menu-default-color); + --p-navigation-item-focus-background: var(--menu-default-background); + --p-navigation-item-active-background: var(--menu-default-background); + --p-navigation-item-color: var(--menu-default-color); + --p-navigation-item-focus-color: var(--menu-active-color); + --p-navigation-item-active-color: var(--menu-active-color); + --p-navigation-item-icon-color: var(--menu-default-color); + --p-navigation-item-icon-focus-color: var(--menu-active-color); + --p-navigation-item-icon-active-color: var(--menu-active-color); +} diff --git a/src/components/interface/index.ts b/src/components/interface/index.ts index 2054a82..4c1f4a6 100644 --- a/src/components/interface/index.ts +++ b/src/components/interface/index.ts @@ -14,3 +14,5 @@ export type { default as IVMessage } from '../message/IVMessage.type'; export type { default as IVModal } from '../modal/IVModal.type'; export type { default as IVProgressBar } from '../progressbar/IVProgressBar.type'; export type { default as IVSelect } from '../select/IVSelect.type'; +export type { default as IVMenuBar } from '../menu/IVMenuBar.type'; +export type { default as IVMenuBarItem } from '../menu/IVMenuBar.type'; diff --git a/src/components/menu/IVMenuBar.type.ts b/src/components/menu/IVMenuBar.type.ts new file mode 100644 index 0000000..3ab604e --- /dev/null +++ b/src/components/menu/IVMenuBar.type.ts @@ -0,0 +1,91 @@ +import type { HTMLAttributes } from "vue" +import type { RouteLocationRaw } from "vue-router" +import type { MenuItem } from "primevue/menuitem" +/** + * Describes a link or button item in a menu bar. + */ +export interface IVMenuBarLinks { + /** Whether the item should be rendered as a button */ + button?: boolean; + + /** Name of the icon to display on the left */ + icon?: string; + + /** Whether the icon appears on the right side */ + iconRight?: boolean; + + /** Text label for the item */ + label?: string; + + /** Target URL if rendered as an anchor () */ + target?: string; + + /** Callback executed when the item is clicked */ + onClick?: ($event: MouseEvent) => void; + + /** Navigation route */ + to?: RouteLocationRaw; +} + +/** + * Extends PrimeVue's MenuItem with optional routing capabilities. + * Excludes 'style' and 'class' to avoid conflicts with Vue attributes. + */ +export interface IVMenuBarItem + extends Partial>, + Partial> {} + +/** + * Interface for configuring a customizable menu bar component. + */ +export default interface IVMenuBar { + /** HTML id for the searchbar input */ + searchbarId?: string; + + /** Title of the service or application */ + serviceTitle?: string; + + /** Description of the service */ + serviceDescription?: string; + + /** Text displayed beside the logo (can be multiline) */ + logoText?: string | string[]; + + /** Whether to show the logo */ + logo?: boolean; + + /** Bound model value for the search input */ + modelValue?: string; + + /** Placeholder text for the search input */ + placeholder?: string; + + /** List of quick link items with additional HTML attributes */ + quickLinks?: (IVMenuBarItem & HTMLAttributes)[]; + + /** Label for the search input (accessibility) */ + searchLabel?: string; + + /** ARIA label for the quick links section */ + quickLinksAriaLabel?: string; + + /** Whether to display the search bar */ + showSearch?: boolean; + + /** Label describing the search bar visibility */ + showSearchLabel?: string; + + /** Label for the main menu toggle button */ + menuLabel?: string; + + /** Label used in modal menus */ + menuModalLabel?: string; + + /** Label for closing the modal menu */ + closeMenuModalLabel?: string; + + /** Responsive breakpoints (e.g. Tailwind-style classes) */ + breakpoints?: string; +} + + diff --git a/src/components/menu/VMenuBar.vue b/src/components/menu/VMenuBar.vue new file mode 100644 index 0000000..96a7c39 --- /dev/null +++ b/src/components/menu/VMenuBar.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/src/components/scrollpanel/VScrollpanel.vue b/src/components/scrollpanel/VScrollPanel.vue similarity index 100% rename from src/components/scrollpanel/VScrollpanel.vue rename to src/components/scrollpanel/VScrollPanel.vue diff --git a/src/index.ts b/src/index.ts index ce643a7..a2fa461 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ export { default as VGroup } from './components/group/VGroup.vue'; export { default as VHint } from './components/hint/VHint.vue'; export { default as VInput } from './components/input/VInput.vue'; export { default as VLabel } from './components/label/VLabel.vue'; +export { default as VMenuBar } from './components/menu/VMenuBar.vue'; export { default as VMessage } from './components/message/VMessage.vue'; export { default as VModal } from './components/modal/VModal.vue'; export { default as VConfirmModal } from './components/modal/VConfirmModal.vue'; diff --git a/src/main.ts b/src/main.ts index 590d577..7a6c56e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,11 +4,13 @@ import App from './App.vue' import primeVue from 'primevue/config' import ToastService from 'primevue/toastservice' import ConfirmationService from 'primevue/confirmationservice' +import router from '../template/router' const app = createApp(App) app.use(primeVue) app.use(ToastService) app.use(ConfirmationService) +app.use(router) app.mount('#app') diff --git a/tsconfig.app.json b/tsconfig.app.json index 3bb66f6..88049a0 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -1,6 +1,6 @@ { "extends": "@vue/tsconfig/tsconfig.dom.json", - "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "test/VButton.spec.ts"], + "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "test/VButton.spec.ts", "template/router.ts"], "exclude": ["src/**/__tests__/*"], "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", diff --git a/vitest.config.ts b/vitest.config.ts index a2705ef..a13a13a 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,8 +2,10 @@ import { fileURLToPath, URL } from 'node:url'; import { defineConfig } from 'vitest/config'; import path from 'path'; +import vue from '@vitejs/plugin-vue'; export default defineConfig({ + plugins: [vue()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)),