diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000000..209e3ef4b6
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+20
diff --git a/components/doc/bottomnavigation/accessibilitydoc.js b/components/doc/bottomnavigation/accessibilitydoc.js
new file mode 100644
index 0000000000..df65a6eca6
--- /dev/null
+++ b/components/doc/bottomnavigation/accessibilitydoc.js
@@ -0,0 +1,69 @@
+import { DocSectionText } from '@/components/doc/common/docsectiontext';
+
+export function AccessibilityDoc() {
+ return (
+
+ Screen Reader
+
+ BottomNavigation component uses the menubar role and the value to describe the menu can either be provided with aria-labelledby or aria-label props. Each list item has a presentation role whereas anchor
+ elements have a menuitem role with aria-label referring to the label of the item and aria-disabled defined if the item is disabled. The active item also includes aria-current .
+
+
+ Keyboard Support
+
+
+
+
+ Key
+ Function
+
+
+
+
+
+ tab
+
+ Adds focus to the active menuitem when focus moves in to the component, if there is already a focused menuitem moves the focus out of the component based on the page tab sequence.
+
+
+
+ enter
+
+ Activates the focused menuitem.
+
+
+
+ space
+
+ Activates the focused menuitem.
+
+
+
+ right arrow
+
+ Moves focus to the next menuitem.
+
+
+
+ left arrow
+
+ Moves focus to the previous menuitem.
+
+
+
+ home
+
+ Moves focus to the first menuitem.
+
+
+
+ end
+
+ Moves focus to the last menuitem.
+
+
+
+
+
+ );
+}
diff --git a/components/doc/bottomnavigation/basicdoc.js b/components/doc/bottomnavigation/basicdoc.js
new file mode 100644
index 0000000000..8219e5fee8
--- /dev/null
+++ b/components/doc/bottomnavigation/basicdoc.js
@@ -0,0 +1,74 @@
+import { DocSectionCode } from '@/components/doc/common/docsectioncode';
+import { DocSectionText } from '@/components/doc/common/docsectiontext';
+import { BottomNavigation } from '@/components/lib/bottomnavigation/BottomNavigation';
+
+export function BasicDoc(props) {
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ const code = {
+ basic: `
+
+ `,
+ javascript: `
+import React from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+
+export default function BasicDemo() {
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+
+
+ )
+}
+ `,
+ typescript: `
+import React from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+import { MenuItem } from 'primereact/menuitem';
+
+export default function BasicDemo() {
+ const items: MenuItem[] = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+
+
+ )
+}
+ `
+ };
+
+ return (
+ <>
+
+
+ BottomNavigation uses the common MenuItem model to define the available destinations.
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/components/doc/bottomnavigation/controlleddoc.js b/components/doc/bottomnavigation/controlleddoc.js
new file mode 100644
index 0000000000..530bcda81d
--- /dev/null
+++ b/components/doc/bottomnavigation/controlleddoc.js
@@ -0,0 +1,78 @@
+import { DocSectionCode } from '@/components/doc/common/docsectioncode';
+import { DocSectionText } from '@/components/doc/common/docsectiontext';
+import { BottomNavigation } from '@/components/lib/bottomnavigation/BottomNavigation';
+import { useState } from 'react';
+
+export function ControlledDoc(props) {
+ const [activeIndex, setActiveIndex] = useState(2);
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ const code = {
+ basic: `
+ setActiveIndex(e.index)} />
+ `,
+ javascript: `
+import { useState } from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+
+export default function ControlledDemo() {
+ const [activeIndex, setActiveIndex] = useState(2);
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+ setActiveIndex(e.index)} style={{ maxWidth: '30rem' }} />
+
+ )
+}
+ `,
+ typescript: `
+import { useState } from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+import { MenuItem } from 'primereact/menuitem';
+
+export default function ControlledDemo() {
+ const [activeIndex, setActiveIndex] = useState(2);
+ const items: MenuItem[] = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+ setActiveIndex(e.index)} style={{ maxWidth: '30rem' }} />
+
+ )
+}
+ `
+ };
+
+ return (
+ <>
+
+
+ Active item can be controlled with activeIndex and onChange .
+
+
+
+ setActiveIndex(e.index)} style={{ maxWidth: '30rem' }} />
+
+
+ >
+ );
+}
diff --git a/components/doc/bottomnavigation/displaydoc.js b/components/doc/bottomnavigation/displaydoc.js
new file mode 100644
index 0000000000..6063d47360
--- /dev/null
+++ b/components/doc/bottomnavigation/displaydoc.js
@@ -0,0 +1,84 @@
+import { DocSectionCode } from '@/components/doc/common/docsectioncode';
+import { DocSectionText } from '@/components/doc/common/docsectiontext';
+import { BottomNavigation } from '@/components/lib/bottomnavigation/BottomNavigation';
+
+export function DisplayDoc(props) {
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ const code = {
+ basic: `
+
+
+
+
+ `,
+ javascript: `
+import React from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+
+export default function DisplayDemo() {
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+
+
+
+
+
+ )
+}
+ `,
+ typescript: `
+import React from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+import { MenuItem } from 'primereact/menuitem';
+
+export default function DisplayDemo() {
+ const items: MenuItem[] = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+
+
+
+
+
+ )
+}
+ `
+ };
+
+ return (
+ <>
+
+ Active item display, indicator and labels are independent options, allowing multiple visual combinations.
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/components/doc/bottomnavigation/importdoc.js b/components/doc/bottomnavigation/importdoc.js
new file mode 100644
index 0000000000..f6685f9aa9
--- /dev/null
+++ b/components/doc/bottomnavigation/importdoc.js
@@ -0,0 +1,17 @@
+import { DocSectionCode } from '@/components/doc/common/docsectioncode';
+import { DocSectionText } from '@/components/doc/common/docsectiontext';
+
+export function ImportDoc(props) {
+ const code = {
+ basic: `
+import { BottomNavigation } from 'primereact/bottomnavigation';
+ `
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/components/doc/bottomnavigation/pt/wireframe.js b/components/doc/bottomnavigation/pt/wireframe.js
new file mode 100644
index 0000000000..ce9e8fd041
--- /dev/null
+++ b/components/doc/bottomnavigation/pt/wireframe.js
@@ -0,0 +1,9 @@
+export function Wireframe() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/components/doc/bottomnavigation/templatedoc.js b/components/doc/bottomnavigation/templatedoc.js
new file mode 100644
index 0000000000..5317dfe692
--- /dev/null
+++ b/components/doc/bottomnavigation/templatedoc.js
@@ -0,0 +1,109 @@
+import { DocSectionCode } from '@/components/doc/common/docsectioncode';
+import { DocSectionText } from '@/components/doc/common/docsectiontext';
+import { BottomNavigation } from '@/components/lib/bottomnavigation/BottomNavigation';
+import { Badge } from '@/components/lib/badge/Badge';
+
+export function TemplateDoc(props) {
+ const itemTemplate = (item, options) => {
+ return (
+
+
+
+ {item.badge && }
+
+ {item.label}
+
+ );
+ };
+
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send', badge: '2', template: itemTemplate },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ const code = {
+ basic: `
+
+ `,
+ javascript: `
+import React from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+import { Badge } from 'primereact/badge';
+
+export default function TemplateDemo() {
+ const itemTemplate = (item, options) => {
+ return (
+
+
+
+ {item.badge && }
+
+ {item.label}
+
+ );
+ };
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send', badge: '2', template: itemTemplate },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+
+
+ )
+}
+ `,
+ typescript: `
+import React from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+import { Badge } from 'primereact/badge';
+import { MenuItem } from 'primereact/menuitem';
+
+export default function TemplateDemo() {
+ const itemTemplate = (item: MenuItem, options: any) => {
+ return (
+
+
+
+ {item.badge && }
+
+ {item.label}
+
+ );
+ };
+ const items: MenuItem[] = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send', badge: '2', template: itemTemplate },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+
+
+ )
+}
+ `
+ };
+
+ return (
+ <>
+
+ Custom content can be placed inside menuitems using the template property of the menu model.
+
+
+
+
+
+ >
+ );
+}
diff --git a/components/doc/bottomnavigation/theming/styleddoc.js b/components/doc/bottomnavigation/theming/styleddoc.js
new file mode 100644
index 0000000000..8c4a6c8743
--- /dev/null
+++ b/components/doc/bottomnavigation/theming/styleddoc.js
@@ -0,0 +1,51 @@
+import { DocSectionText } from '@/components/doc/common/docsectiontext';
+
+export function StyledDoc(props) {
+ return (
+ <>
+
+ List of class names used in the styled mode.
+
+
+
+
+
+ Name
+ Element
+
+
+
+
+ p-bottomnavigation
+ Container element.
+
+
+ p-bottomnavigation-list
+ List element.
+
+
+ p-bottomnavigation-item
+ Menuitem element.
+
+
+ p-menuitem-link
+ Link inside a menuitem.
+
+
+ p-menuitem-text
+ Label of a menuitem.
+
+
+ p-menuitem-icon
+ Icon of a menuitem.
+
+
+ p-bottomnavigation-indicator
+ Active item indicator.
+
+
+
+
+ >
+ );
+}
diff --git a/components/doc/bottomnavigation/theming/tailwinddoc.js b/components/doc/bottomnavigation/theming/tailwinddoc.js
new file mode 100644
index 0000000000..cec12af188
--- /dev/null
+++ b/components/doc/bottomnavigation/theming/tailwinddoc.js
@@ -0,0 +1,76 @@
+import { DocSectionCode } from '@/components/doc/common/docsectioncode';
+import { DocSectionText } from '@/components/doc/common/docsectiontext';
+import Link from 'next/link';
+
+export function TailwindDoc(props) {
+ const code = {
+ basic: `
+const Tailwind = {
+ bottomnavigation: {
+ root: 'relative flex overflow-visible bg-white border border-gray-300 rounded-2xl shadow-sm',
+ menu: 'flex items-center justify-around flex-nowrap w-full m-0 p-2 list-none outline-none',
+ menuitem: 'relative flex flex-1 justify-center min-w-0',
+ action: ({ context, props }) => ({
+ className: classNames(
+ 'cursor-pointer select-none inline-flex flex-col items-center justify-center relative no-underline overflow-visible min-w-0 transition-all duration-200',
+ 'w-14 h-12 rounded-xl text-gray-500',
+ {
+ 'text-blue-500': context.active,
+ '-translate-y-3 bg-blue-500 text-white shadow-md': context.active && props.activeItemDisplay === 'raised',
+ 'bg-blue-50 text-blue-600': context.active && props.activeItemDisplay === 'highlight'
+ }
+ )
+ }),
+ icon: ({ props }) => ({
+ className: classNames({ 'mb-1': props.showLabels })
+ }),
+ label: 'text-xs leading-none truncate max-w-full',
+ indicator: ({ context, props }) => ({
+ className: classNames('absolute hidden bg-blue-500', {
+ 'block': context.active && props.indicator !== 'none',
+ 'w-1 h-1 rounded-full -bottom-1': props.indicator === 'dot',
+ 'h-0.5 rounded-full left-2 right-2 top-0': props.indicator === 'bar'
+ })
+ })
+ }
+}
+ `
+ };
+
+ const code2 = {
+ javascript: `
+import React from 'react';
+import { BottomNavigation } from 'primereact/bottomnavigation';
+
+export default function UnstyledDemo() {
+ const items = [
+ { label: 'Home', icon: 'pi pi-home' },
+ { label: 'Wallet', icon: 'pi pi-credit-card' },
+ { label: 'Send', icon: 'pi pi-send' },
+ { label: 'Card', icon: 'pi pi-id-card' },
+ { label: 'Profile', icon: 'pi pi-user' }
+ ];
+
+ return (
+
+
+
+ )
+}
+ `
+ };
+
+ return (
+ <>
+
+
+ PrimeReact offers a built-in Tailwind theme to get you started quickly. The default values related to the component are displayed below. The component can easily be styled with your own design based on Tailwind utilities, see the{' '}
+ Tailwind Customization section for an example.
+
+
+ A playground sample with the pre-built Tailwind theme.
+
+
+ >
+ );
+}
diff --git a/components/doc/common/apidoc/index.json b/components/doc/common/apidoc/index.json
index d78cf592aa..64ee84b6a5 100644
--- a/components/doc/common/apidoc/index.json
+++ b/components/doc/common/apidoc/index.json
@@ -1046,6 +1046,13 @@
"type": "BlockUIPassThroughOptions",
"description": "Custom passthrough(pt) options for BlockUI."
},
+ {
+ "name": "bottomnavigation",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughOptions",
+ "description": "Custom passthrough(pt) options for BottomNavigation."
+ },
{
"name": "breadcrumb",
"optional": true,
@@ -5353,6 +5360,318 @@
}
}
},
+ "bottomnavigation": {
+ "description": "BottomNavigation is a compact navigation component designed for switching between primary application destinations.\n\n[Live Demo](https://www.primereact.org/bottomnavigationmenu/)",
+ "components": {
+ "BottomNavigation": {
+ "description": "BottomNavigation is a compact navigation component designed for switching between primary application destinations.",
+ "methods": {
+ "description": "Defines methods that can be accessed by the component's reference.",
+ "values": [
+ {
+ "name": "getElement",
+ "parameters": [],
+ "returnType": "null | HTMLDivElement",
+ "description": "Used to get container element."
+ }
+ ]
+ },
+ "props": {
+ "description": "Defines valid properties in BottomNavigation component. In addition to these, all properties of HTMLDivElement can be used in this component.",
+ "values": [
+ {
+ "name": "activeIndex",
+ "optional": true,
+ "readonly": false,
+ "type": "number",
+ "default": "0",
+ "description": "Active index of menuitem."
+ },
+ {
+ "name": "activeItemDisplay",
+ "optional": true,
+ "readonly": false,
+ "type": "\"plain\" | \"highlight\" | \"raised\"",
+ "default": "raised",
+ "description": "Display style of the active item."
+ },
+ {
+ "name": "ariaLabel",
+ "optional": true,
+ "readonly": false,
+ "type": "string",
+ "default": "",
+ "description": "Used to define a string that labels the component."
+ },
+ {
+ "name": "ariaLabelledBy",
+ "optional": true,
+ "readonly": false,
+ "type": "string",
+ "default": "",
+ "description": "Establishes relationships between the component and label(s) where its value should be one or more element IDs."
+ },
+ {
+ "name": "children",
+ "optional": true,
+ "readonly": true,
+ "type": "ReactNode",
+ "default": "",
+ "description": "Used to get the child elements of the component."
+ },
+ {
+ "name": "indicator",
+ "optional": true,
+ "readonly": false,
+ "type": "\"none\" | \"bar\" | \"dot\"",
+ "default": "none",
+ "description": "Type of active item indicator."
+ },
+ {
+ "name": "model",
+ "optional": true,
+ "readonly": false,
+ "type": "MenuItem[]",
+ "default": "",
+ "description": "An array of menuitems."
+ },
+ {
+ "name": "pt",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughOptions",
+ "default": "",
+ "description": "Uses to pass attributes to DOM elements inside the component."
+ },
+ {
+ "name": "ptOptions",
+ "optional": true,
+ "readonly": false,
+ "type": "PassThroughOptions",
+ "default": "",
+ "description": "Used to configure passthrough(pt) options of the component."
+ },
+ {
+ "name": "showLabels",
+ "optional": true,
+ "readonly": false,
+ "type": "boolean",
+ "default": "true",
+ "description": "Whether to display item labels."
+ },
+ {
+ "name": "unstyled",
+ "optional": true,
+ "readonly": false,
+ "type": "boolean",
+ "default": "false",
+ "description": "When enabled, it removes component related styles in the core."
+ }
+ ]
+ },
+ "callbacks": {
+ "description": "Defines callbacks that determine the behavior of the component based on a given condition or report the actions that the component takes.",
+ "values": [
+ {
+ "name": "onChange",
+ "parameters": [
+ {
+ "name": "event",
+ "optional": false,
+ "type": "BottomNavigationChangeEvent",
+ "description": "Custom change event."
+ }
+ ],
+ "returnType": "void",
+ "description": "Callback to invoke when active item changes."
+ }
+ ]
+ }
+ }
+ },
+ "events": {
+ "description": "Defines the custom events used by the component's callbacks.",
+ "values": {
+ "BottomNavigationChangeEvent": {
+ "description": "Custom change event.",
+ "relatedProp": "onChange",
+ "props": [
+ {
+ "name": "originalEvent",
+ "optional": false,
+ "readonly": false,
+ "type": "SyntheticEvent",
+ "description": "Browser event."
+ },
+ {
+ "name": "value",
+ "optional": false,
+ "readonly": false,
+ "type": "MenuItem",
+ "description": "Selected menuitem."
+ },
+ {
+ "name": "index",
+ "optional": false,
+ "readonly": false,
+ "type": "number",
+ "description": "Index of the selected item."
+ }
+ ]
+ }
+ }
+ },
+ "interfaces": {
+ "description": "Defines the custom interfaces used by the module.",
+ "values": {
+ "BottomNavigationPassThroughMethodOptions": {
+ "description": "Custom passthrough(pt) option method.",
+ "relatedProp": "",
+ "props": [
+ {
+ "name": "props",
+ "optional": false,
+ "readonly": false,
+ "type": "BottomNavigationProps"
+ },
+ {
+ "name": "state",
+ "optional": false,
+ "readonly": false,
+ "type": "BottomNavigationState"
+ },
+ {
+ "name": "context",
+ "optional": false,
+ "readonly": false,
+ "type": "BottomNavigationContext"
+ }
+ ],
+ "callbacks": []
+ },
+ "BottomNavigationContext": {
+ "description": "Defines current options in BottomNavigation component.",
+ "relatedProp": "",
+ "props": [
+ {
+ "name": "item",
+ "optional": false,
+ "readonly": false,
+ "type": "any",
+ "description": "Current menuitem."
+ },
+ {
+ "name": "index",
+ "optional": false,
+ "readonly": false,
+ "type": "number",
+ "description": "Index of the menuitem."
+ },
+ {
+ "name": "active",
+ "optional": false,
+ "readonly": false,
+ "type": "boolean",
+ "description": "Whether the item is active."
+ },
+ {
+ "name": "disabled",
+ "optional": false,
+ "readonly": false,
+ "type": "boolean",
+ "description": "Whether the item is disabled."
+ }
+ ],
+ "callbacks": []
+ },
+ "BottomNavigationPassThroughOptions": {
+ "description": "Custom passthrough(pt) options.",
+ "relatedProp": "pt",
+ "props": [
+ {
+ "name": "root",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughType>",
+ "description": "Uses to pass attributes to the root's DOM element."
+ },
+ {
+ "name": "menu",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughType>",
+ "description": "Uses to pass attributes to the list's DOM element."
+ },
+ {
+ "name": "menuitem",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughType>",
+ "description": "Uses to pass attributes to the list item's DOM element."
+ },
+ {
+ "name": "action",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughType>",
+ "description": "Uses to pass attributes to the action's DOM element."
+ },
+ {
+ "name": "icon",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughType | SVGProps>",
+ "description": "Uses to pass attributes to the icon's DOM element."
+ },
+ {
+ "name": "label",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughType>",
+ "description": "Uses to pass attributes to the label's DOM element."
+ },
+ {
+ "name": "indicator",
+ "optional": true,
+ "readonly": false,
+ "type": "BottomNavigationPassThroughType>",
+ "description": "Uses to pass attributes to the active indicator's DOM element."
+ },
+ {
+ "name": "hooks",
+ "optional": true,
+ "readonly": false,
+ "type": "ComponentHooks",
+ "description": "Used to manage all lifecycle hooks."
+ }
+ ],
+ "callbacks": []
+ },
+ "BottomNavigationState": {
+ "description": "Defines current inline state in BottomNavigation component.",
+ "relatedProp": "",
+ "props": [
+ {
+ "name": "activeIndex",
+ "optional": false,
+ "readonly": false,
+ "type": "number",
+ "description": "Current active index state as a number."
+ }
+ ],
+ "callbacks": []
+ }
+ }
+ },
+ "types": {
+ "description": "Defines the custom types used by the module.",
+ "values": {
+ "BottomNavigationPassThroughType": {
+ "values": "PassThroughType"
+ }
+ }
+ }
+ },
"breadcrumb": {
"description": "Breadcrumb provides contextual information about page hierarchy.\n\n[Live Demo](https://www.primereact.org/breadcrumb/)",
"components": {
diff --git a/components/layout/menu.json b/components/layout/menu.json
index 7ad028c80d..a4f9cab199 100644
--- a/components/layout/menu.json
+++ b/components/layout/menu.json
@@ -307,6 +307,10 @@
{
"name": "Menu",
"children": [
+ {
+ "name": "Bottom Navigation Menu",
+ "to": "/bottomnavigationmenu"
+ },
{
"name": "Breadcrumb",
"to": "/breadcrumb"
diff --git a/components/lib/api/api.d.ts b/components/lib/api/api.d.ts
index 16b37feed3..961c2a29ca 100644
--- a/components/lib/api/api.d.ts
+++ b/components/lib/api/api.d.ts
@@ -12,6 +12,7 @@ import { AvatarPassThroughOptions } from '../avatar/avatar';
import { AvatarGroupPassThroughOptions } from '../avatargroup/avatargroup';
import { BadgePassThroughOptions } from '../badge/badge';
import { BlockUIPassThroughOptions } from '../blockui/blockui';
+import { BottomNavigationPassThroughOptions } from '../bottomnavigation/bottomnavigation';
import { BreadCrumbPassThroughOptions } from '../breadcrumb/breadcrumb';
import { ButtonPassThroughOptions } from '../button/button';
import { CalendarPassThroughOptions } from '../calendar/calendar';
@@ -321,6 +322,10 @@ export interface PrimeReactPTOptions {
* Custom passthrough(pt) options for BlockUI.
*/
blockui?: BlockUIPassThroughOptions;
+ /**
+ * Custom passthrough(pt) options for BottomNavigation.
+ */
+ bottomnavigation?: BottomNavigationPassThroughOptions;
/**
* Custom passthrough(pt) options for Breadcrumb.
*/
diff --git a/components/lib/bottomnavigation/BottomNavigation.js b/components/lib/bottomnavigation/BottomNavigation.js
new file mode 100644
index 0000000000..4df2536fca
--- /dev/null
+++ b/components/lib/bottomnavigation/BottomNavigation.js
@@ -0,0 +1,318 @@
+import * as React from 'react';
+import { PrimeReactContext } from '../api/Api';
+import { useHandleStyle } from '../componentbase/ComponentBase';
+import { useMergeProps, useMountEffect } from '../hooks/Hooks';
+import { Ripple } from '../ripple/Ripple';
+import { DomHandler, IconUtils, ObjectUtils, UniqueComponentId, classNames } from '../utils/Utils';
+import { BottomNavigationBase } from './BottomNavigationBase';
+
+export const BottomNavigation = React.memo(
+ React.forwardRef((inProps, ref) => {
+ const mergeProps = useMergeProps();
+ const context = React.useContext(PrimeReactContext);
+ const props = BottomNavigationBase.getProps(inProps, context);
+
+ const [idState, setIdState] = React.useState(props.id);
+ const [activeIndexState, setActiveIndexState] = React.useState(props.activeIndex);
+ const elementRef = React.useRef(null);
+ const navRef = React.useRef(null);
+ const activeIndex = props.onChange ? props.activeIndex : activeIndexState;
+ const metaData = {
+ props,
+ state: {
+ id: idState,
+ activeIndex
+ }
+ };
+
+ const { ptm, cx, isUnstyled } = BottomNavigationBase.setMetaData({
+ ...metaData
+ });
+
+ const getPTOptions = (key, item, index) => {
+ return ptm(key, {
+ parent: metaData,
+ context: {
+ item,
+ index,
+ active: isSelected(index),
+ disabled: item.disabled
+ }
+ });
+ };
+
+ useHandleStyle(BottomNavigationBase.css.styles, isUnstyled, { name: 'bottomnavigation' });
+
+ useMountEffect(() => {
+ if (!idState) {
+ setIdState(UniqueComponentId());
+ }
+ });
+
+ React.useImperativeHandle(ref, () => ({
+ props,
+ getElement: () => elementRef.current
+ }));
+
+ const itemClick = (event, item, index) => {
+ if (item.disabled) {
+ event.preventDefault();
+
+ return;
+ }
+
+ if (item.command) {
+ item.command({
+ originalEvent: event,
+ item
+ });
+ }
+
+ if (props.onChange) {
+ props.onChange({
+ originalEvent: event,
+ value: item,
+ index
+ });
+ } else {
+ setActiveIndexState(index);
+ }
+
+ if (!item.url) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ };
+
+ const isSelected = (index) => {
+ return index === (activeIndex || 0);
+ };
+
+ const onKeyDownItem = (event, item, index) => {
+ switch (event.code) {
+ case 'ArrowRight':
+ navigateToNextItem(event.target);
+ event.preventDefault();
+ break;
+
+ case 'ArrowLeft':
+ navigateToPrevItem(event.target);
+ event.preventDefault();
+ break;
+
+ case 'Home':
+ navigateToFirstItem(event.target);
+ event.preventDefault();
+ break;
+
+ case 'End':
+ navigateToLastItem(event.target);
+ event.preventDefault();
+ break;
+
+ case 'Space':
+ case 'Enter':
+ case 'NumpadEnter':
+ itemClick(event, item, index);
+ event.preventDefault();
+ break;
+
+ case 'Tab':
+ onTabKey();
+ break;
+
+ default:
+ break;
+ }
+ };
+
+ const navigateToNextItem = (target) => {
+ const nextItem = findNextItem(target);
+
+ nextItem && setFocusToMenuitem(target, nextItem);
+ };
+
+ const navigateToPrevItem = (target) => {
+ const prevItem = findPrevItem(target);
+
+ prevItem && setFocusToMenuitem(target, prevItem);
+ };
+
+ const navigateToFirstItem = (target) => {
+ const firstItem = findFirstItem();
+
+ firstItem && setFocusToMenuitem(target, firstItem);
+ };
+
+ const navigateToLastItem = (target) => {
+ const lastItem = findLastItem();
+
+ lastItem && setFocusToMenuitem(target, lastItem);
+ };
+
+ const findNextItem = (item) => {
+ const nextItem = item.parentElement.nextElementSibling;
+
+ return nextItem ? (DomHandler.getAttribute(nextItem, 'data-p-disabled') === true ? findNextItem(nextItem.children[0]) : nextItem.children[0]) : null;
+ };
+
+ const findPrevItem = (item) => {
+ const prevItem = item.parentElement.previousElementSibling;
+
+ return prevItem ? (DomHandler.getAttribute(prevItem, 'data-p-disabled') === true ? findPrevItem(prevItem.children[0]) : prevItem.children[0]) : null;
+ };
+
+ const findFirstItem = () => {
+ const firstSibling = DomHandler.findSingle(navRef.current, '[data-pc-section="menuitem"][data-p-disabled="false"]');
+
+ return firstSibling ? firstSibling.children[0] : null;
+ };
+
+ const findLastItem = () => {
+ const siblings = DomHandler.find(navRef.current, '[data-pc-section="menuitem"][data-p-disabled="false"]');
+
+ return siblings ? siblings[siblings.length - 1].children[0] : null;
+ };
+
+ const setFocusToMenuitem = (target, focusableItem) => {
+ target.tabIndex = '-1';
+ focusableItem.tabIndex = '0';
+ focusableItem.focus();
+ };
+
+ const onTabKey = () => {
+ const activeItem = DomHandler.findSingle(navRef.current, '[data-pc-section="menuitem"][data-p-disabled="false"][data-p-highlight="true"]');
+ const focusedItem = DomHandler.findSingle(navRef.current, '[data-pc-section="action"][tabindex="0"]');
+
+ if (activeItem && focusedItem && focusedItem !== activeItem.children[0]) {
+ activeItem.children[0].tabIndex = '0';
+ focusedItem.tabIndex = '-1';
+ }
+ };
+
+ const createMenuItem = (item, index) => {
+ if (item.visible === false) {
+ return null;
+ }
+
+ const { className: _className, style, disabled, icon: _icon, label: _label, template, url, target } = item;
+ const key = item.id || idState + '_' + index;
+ const active = isSelected(index);
+ const iconClassName = classNames('p-menuitem-icon', _icon);
+ const iconProps = mergeProps(
+ {
+ className: cx('icon', { _icon })
+ },
+ getPTOptions('icon', item, index)
+ );
+ const icon = IconUtils.getJSXIcon(_icon, { ...iconProps }, { props });
+ const labelProps = mergeProps(
+ {
+ className: cx('label')
+ },
+ getPTOptions('label', item, index)
+ );
+ const label = props.showLabels && _label && {_label} ;
+ const indicatorProps = mergeProps(
+ {
+ className: cx('indicator')
+ },
+ getPTOptions('indicator', item, index)
+ );
+ const indicator = props.indicator !== 'none' && ;
+ const actionProps = mergeProps(
+ {
+ href: url || '#',
+ role: 'menuitem',
+ 'aria-label': _label,
+ 'aria-current': active ? 'page' : undefined,
+ tabIndex: active ? '0' : '-1',
+ className: cx('action'),
+ target,
+ onClick: (event) => itemClick(event, item, index)
+ },
+ getPTOptions('action', item, index)
+ );
+
+ let content = (
+
+ {icon}
+ {label}
+ {indicator}
+
+
+ );
+
+ if (template) {
+ const defaultContentOptions = {
+ onClick: (event) => itemClick(event, item, index),
+ className: 'p-menuitem-link',
+ labelClassName: 'p-menuitem-text',
+ iconClassName,
+ indicatorClassName: 'p-bottomnavigation-indicator',
+ element: content,
+ props,
+ active,
+ index,
+ disabled
+ };
+
+ content = ObjectUtils.getJSXElement(template, item, defaultContentOptions);
+ }
+
+ const menuItemProps = mergeProps(
+ {
+ id: key,
+ onKeyDown: (event) => onKeyDownItem(event, item, index),
+ className: cx('menuitem', { _className, active, disabled }),
+ style,
+ role: 'presentation',
+ 'data-p-highlight': active,
+ 'data-p-disabled': disabled || false,
+ 'aria-disabled': disabled
+ },
+ getPTOptions('menuitem', item, index)
+ );
+
+ return (
+
+ {content}
+
+ );
+ };
+
+ if (props.model) {
+ const items = props.model.map(createMenuItem);
+ const menuProps = mergeProps(
+ {
+ ref: navRef,
+ 'aria-label': props.ariaLabel,
+ 'aria-labelledby': props.ariaLabelledBy,
+ className: cx('menu'),
+ role: 'menubar'
+ },
+ ptm('menu')
+ );
+ const rootProps = mergeProps(
+ {
+ id: props.id,
+ ref: elementRef,
+ className: classNames(props.className, cx('root')),
+ style: props.style
+ },
+ BottomNavigationBase.getOtherProps(props),
+ ptm('root')
+ );
+
+ return (
+
+ );
+ }
+
+ return null;
+ })
+);
+
+BottomNavigation.displayName = 'BottomNavigation';
diff --git a/components/lib/bottomnavigation/BottomNavigationBase.js b/components/lib/bottomnavigation/BottomNavigationBase.js
new file mode 100644
index 0000000000..89b5f41d5d
--- /dev/null
+++ b/components/lib/bottomnavigation/BottomNavigationBase.js
@@ -0,0 +1,105 @@
+import { ComponentBase } from '../componentbase/ComponentBase';
+import { classNames } from '../utils/Utils';
+
+const classes = {
+ icon: ({ _icon }) => classNames('p-menuitem-icon', _icon),
+ label: 'p-menuitem-text',
+ indicator: 'p-bottomnavigation-indicator',
+ action: 'p-menuitem-link',
+ menuitem: ({ _className, active, disabled }) =>
+ classNames(
+ 'p-bottomnavigation-item',
+ {
+ 'p-highlight': active,
+ 'p-disabled': disabled
+ },
+ _className
+ ),
+ menu: 'p-bottomnavigation-list p-reset',
+ root: ({ props }) =>
+ classNames('p-bottomnavigation p-component', `p-bottomnavigation-active-${props.activeItemDisplay}`, `p-bottomnavigation-indicator-${props.indicator}`, {
+ 'p-bottomnavigation-labels': props.showLabels
+ })
+};
+
+const styles = `
+@layer primereact {
+ .p-bottomnavigation {
+ position: relative;
+ display: flex;
+ overflow: visible;
+ }
+
+ .p-bottomnavigation-list {
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+ flex-wrap: nowrap;
+ }
+
+ .p-bottomnavigation-item {
+ position: relative;
+ flex: 1 1 0;
+ display: flex;
+ justify-content: center;
+ min-width: 0;
+ }
+
+ .p-bottomnavigation .p-menuitem-link {
+ cursor: pointer;
+ user-select: none;
+ display: inline-flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ text-decoration: none;
+ overflow: visible;
+ min-width: 0;
+ }
+
+ .p-bottomnavigation .p-menuitem-link:focus {
+ z-index: 1;
+ }
+
+ .p-bottomnavigation .p-menuitem-icon,
+ .p-bottomnavigation .p-menuitem-text {
+ line-height: 1;
+ }
+
+ .p-bottomnavigation .p-menuitem-text {
+ white-space: nowrap;
+ }
+
+ .p-bottomnavigation-indicator {
+ display: none;
+ pointer-events: none;
+ }
+}
+`;
+
+export const BottomNavigationBase = ComponentBase.extend({
+ defaultProps: {
+ __TYPE: 'BottomNavigation',
+ id: null,
+ model: null,
+ activeIndex: 0,
+ activeItemDisplay: 'raised',
+ indicator: 'none',
+ showLabels: true,
+ ariaLabel: null,
+ ariaLabelledBy: null,
+ style: null,
+ className: null,
+ onChange: null,
+ children: undefined
+ },
+ css: {
+ classes,
+ styles
+ }
+});
diff --git a/components/lib/bottomnavigation/bottomnavigation.d.ts b/components/lib/bottomnavigation/bottomnavigation.d.ts
new file mode 100644
index 0000000000..715ecd2e31
--- /dev/null
+++ b/components/lib/bottomnavigation/bottomnavigation.d.ts
@@ -0,0 +1,201 @@
+/**
+ *
+ * BottomNavigation is a compact navigation component designed for switching between primary application destinations.
+ *
+ * [Live Demo](https://www.primereact.org/bottomnavigationmenu/)
+ *
+ * @module bottomnavigation
+ *
+ */
+import * as React from 'react';
+import { ComponentHooks } from '../componentbase/componentbase';
+import { MenuItem } from '../menuitem';
+import { PassThroughOptions } from '../passthrough';
+import { PassThroughType } from '../utils/utils';
+
+export declare type BottomNavigationPassThroughType = PassThroughType;
+
+/**
+ * Custom passthrough(pt) option method.
+ */
+export interface BottomNavigationPassThroughMethodOptions {
+ props: BottomNavigationProps;
+ state: BottomNavigationState;
+ context: BottomNavigationContext;
+}
+
+/**
+ * Defines current options in BottomNavigation component.
+ */
+export interface BottomNavigationContext {
+ /**
+ * Current menuitem.
+ */
+ item: any;
+ /**
+ * Index of the menuitem.
+ */
+ index: number;
+ /**
+ * Whether the item is active.
+ */
+ active: boolean;
+ /**
+ * Whether the item is disabled.
+ */
+ disabled: boolean;
+}
+
+/**
+ * Custom passthrough(pt) options.
+ * @see {@link BottomNavigationProps.pt}
+ */
+export interface BottomNavigationPassThroughOptions {
+ /**
+ * Uses to pass attributes to the root's DOM element.
+ */
+ root?: BottomNavigationPassThroughType>;
+ /**
+ * Uses to pass attributes to the list's DOM element.
+ */
+ menu?: BottomNavigationPassThroughType>;
+ /**
+ * Uses to pass attributes to the list item's DOM element.
+ */
+ menuitem?: BottomNavigationPassThroughType>;
+ /**
+ * Uses to pass attributes to the action's DOM element.
+ */
+ action?: BottomNavigationPassThroughType>;
+ /**
+ * Uses to pass attributes to the icon's DOM element.
+ */
+ icon?: BottomNavigationPassThroughType | React.HTMLAttributes>;
+ /**
+ * Uses to pass attributes to the label's DOM element.
+ */
+ label?: BottomNavigationPassThroughType>;
+ /**
+ * Uses to pass attributes to the active indicator's DOM element.
+ */
+ indicator?: BottomNavigationPassThroughType>;
+ /**
+ * Used to manage all lifecycle hooks.
+ * @see {@link ComponentHooks}
+ */
+ hooks?: ComponentHooks;
+}
+
+/**
+ * Defines current inline state in BottomNavigation component.
+ */
+export interface BottomNavigationState {
+ /**
+ * Current active index state as a number.
+ * @defaultValue 0
+ */
+ activeIndex: number;
+}
+
+/**
+ * Custom change event.
+ * @see {@link BottomNavigationProps.onChange}
+ * @event
+ */
+interface BottomNavigationChangeEvent {
+ /**
+ * Browser event.
+ */
+ originalEvent: React.SyntheticEvent;
+ /**
+ * Selected menuitem.
+ */
+ value: MenuItem;
+ /**
+ * Index of the selected item.
+ */
+ index: number;
+}
+
+/**
+ * Defines valid properties in BottomNavigation component. In addition to these, all properties of HTMLDivElement can be used in this component.
+ * @group Properties
+ */
+export interface BottomNavigationProps extends Omit, HTMLDivElement>, 'ref' | 'onChange'> {
+ /**
+ * An array of menuitems.
+ */
+ model?: MenuItem[] | undefined;
+ /**
+ * Active index of menuitem.
+ * @defaultValue 0
+ */
+ activeIndex?: number | undefined;
+ /**
+ * Display style of the active item.
+ * @defaultValue raised
+ */
+ activeItemDisplay?: 'plain' | 'highlight' | 'raised' | undefined;
+ /**
+ * Type of active item indicator.
+ * @defaultValue none
+ */
+ indicator?: 'none' | 'dot' | 'bar' | undefined;
+ /**
+ * Whether to display item labels.
+ * @defaultValue true
+ */
+ showLabels?: boolean | undefined;
+ /**
+ * Used to define a string that labels the component.
+ */
+ ariaLabel?: string | undefined;
+ /**
+ * Establishes relationships between the component and label(s) where its value should be one or more element IDs.
+ */
+ ariaLabelledBy?: string | undefined;
+ /**
+ * Callback to invoke when active item changes.
+ * @param {BottomNavigationChangeEvent} event - Custom change event.
+ */
+ onChange?(event: BottomNavigationChangeEvent): void;
+ /**
+ * Used to get the child elements of the component.
+ * @readonly
+ */
+ children?: React.ReactNode | undefined;
+ /**
+ * Uses to pass attributes to DOM elements inside the component.
+ * @type {BottomNavigationPassThroughOptions}
+ */
+ pt?: BottomNavigationPassThroughOptions;
+ /**
+ * Used to configure passthrough(pt) options of the component.
+ * @type {PassThroughOptions}
+ */
+ ptOptions?: PassThroughOptions;
+ /**
+ * When enabled, it removes component related styles in the core.
+ * @defaultValue false
+ */
+ unstyled?: boolean;
+}
+
+/**
+ * **PrimeReact - BottomNavigation**
+ *
+ * _BottomNavigation is a compact navigation component designed for switching between primary application destinations._
+ *
+ * [Live Demo](https://www.primereact.org/bottomnavigationmenu/)
+ * --- ---
+ * 
+ *
+ * @group Component
+ */
+export declare class BottomNavigation extends React.Component {
+ /**
+ * Used to get container element.
+ * @return {HTMLDivElement | null} Container element
+ */
+ public getElement(): HTMLDivElement | null;
+}
diff --git a/components/lib/bottomnavigation/package.json b/components/lib/bottomnavigation/package.json
new file mode 100644
index 0000000000..35da6ada69
--- /dev/null
+++ b/components/lib/bottomnavigation/package.json
@@ -0,0 +1,7 @@
+{
+ "main": "./bottomnavigation.cjs.js",
+ "module": "./bottomnavigation.esm.js",
+ "unpkg": "./bottomnavigation.min.js",
+ "types": "./bottomnavigation.d.ts",
+ "sideEffects": false
+}
diff --git a/components/lib/passthrough/tailwind/index.js b/components/lib/passthrough/tailwind/index.js
index 9aa7a098d0..3303612932 100644
--- a/components/lib/passthrough/tailwind/index.js
+++ b/components/lib/passthrough/tailwind/index.js
@@ -1926,6 +1926,52 @@ const Tailwind = {
className: classNames('flex flex-col items-center justify-center relative overflow-hidden cursor-default', 'w-16 h-16')
}
},
+ bottomnavigation: {
+ root: ({ props }) => ({
+ className: classNames('relative flex overflow-visible', 'bg-white dark:bg-gray-900 border border-gray-300 dark:border-blue-900/40 rounded-2xl shadow-sm', {
+ 'p-bottomnavigation-active-raised': props.activeItemDisplay === 'raised',
+ 'p-bottomnavigation-active-highlight': props.activeItemDisplay === 'highlight'
+ })
+ }),
+ menu: {
+ className: classNames('flex items-center justify-around flex-nowrap w-full m-0 p-2 list-none outline-none')
+ },
+ menuitem: {
+ className: classNames('relative flex flex-1 justify-center min-w-0')
+ },
+ action: ({ context, props }) => ({
+ className: classNames(
+ 'cursor-pointer select-none inline-flex flex-col items-center justify-center relative no-underline overflow-visible min-w-0 transition-all duration-200',
+ 'w-14 h-12 rounded-xl text-gray-500 dark:text-white/70',
+ 'focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)]',
+ {
+ 'text-blue-500 dark:text-blue-300': context.active,
+ 'hover:text-gray-700 dark:hover:text-white/90': !context.active,
+ '-translate-y-3 bg-blue-500 text-white shadow-md hover:text-white dark:bg-blue-400 dark:text-gray-900': context.active && props.activeItemDisplay === 'raised',
+ 'bg-blue-50 text-blue-600 dark:bg-blue-300/20 dark:text-blue-300': context.active && props.activeItemDisplay === 'highlight'
+ }
+ )
+ }),
+ icon: ({ context, props }) => ({
+ className: classNames({
+ 'mb-1': props.showLabels,
+ 'text-white dark:text-gray-900': context.active && props.activeItemDisplay === 'raised'
+ })
+ }),
+ label: ({ context, props }) => ({
+ className: classNames('text-xs leading-none truncate max-w-full', {
+ 'font-semibold': context.active,
+ 'text-white dark:text-gray-900': context.active && props.activeItemDisplay === 'raised'
+ })
+ }),
+ indicator: ({ context, props }) => ({
+ className: classNames('absolute hidden bg-blue-500 dark:bg-blue-300', {
+ block: context.active && props.indicator !== 'none',
+ 'w-1 h-1 rounded-full -bottom-1': props.indicator === 'dot',
+ 'h-0.5 rounded-full left-2 right-2 top-0': props.indicator === 'bar'
+ })
+ })
+ },
menu: {
root: 'py-1 bg-white dark:bg-gray-900 text-gray-700 dark:text-white/80 border border-gray-300 dark:border-blue-900/40 rounded-md w-48',
menu: {
diff --git a/components/lib/primereact.all.js b/components/lib/primereact.all.js
index 9a15ed90eb..c0e9af1e1e 100644
--- a/components/lib/primereact.all.js
+++ b/components/lib/primereact.all.js
@@ -6,6 +6,7 @@ export * from './avatar/Avatar';
export * from './avatargroup/AvatarGroup';
export * from './badge/Badge';
export * from './blockui/BlockUI';
+export * from './bottomnavigation/BottomNavigation';
export * from './breadcrumb/BreadCrumb';
export * from './button/Button';
export * from './calendar/Calendar';
diff --git a/next.config.js b/next.config.js
index f587b05b6a..64aeb5a301 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,3 +1,9 @@
+// Polyfill Buffer.SlowBuffer for Node v24+ compatibility with Next.js 12 compiled jsonwebtoken
+const bufferModule = require('buffer');
+if (typeof bufferModule.SlowBuffer === 'undefined') {
+ bufferModule.SlowBuffer = class SlowBuffer extends bufferModule.Buffer {};
+}
+
module.exports = {
reactStrictMode: process.env.NODE_ENV === 'production' ? false : true,
trailingSlash: true,
diff --git a/package-lock.json b/package-lock.json
index 7d7387d536..b92a821c17 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,19 +1,19 @@
{
"name": "primereact",
- "version": "10.9.7",
+ "version": "10.9.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "primereact",
- "version": "10.9.7",
+ "version": "10.9.8",
"dependencies": {
"@docsearch/react": "3.9.0",
"chart.js": "4.5.0",
"file-saver": "2.0.5",
"fs-extra": "^11.3.2",
"jspdf": "4.0.0",
- "jspdf-autotable": "5.0.2",
+ "jspdf-autotable": "5.0.8",
"next": "12.3.7",
"path": "^0.12.7",
"primeflex": "3.3.1",
@@ -3475,7 +3475,6 @@
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
"integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -3515,7 +3514,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3536,7 +3534,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3557,7 +3554,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3578,7 +3574,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3599,7 +3594,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3620,7 +3614,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3641,7 +3634,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3662,7 +3654,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3683,7 +3674,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3704,7 +3694,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3725,7 +3714,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3746,7 +3734,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -3767,7 +3754,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6035,7 +6021,7 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
@@ -7077,7 +7063,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
- "dev": true,
"license": "Apache-2.0",
"optional": true,
"bin": {
@@ -8418,7 +8403,7 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
@@ -9893,7 +9878,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -9958,7 +9943,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@@ -10014,7 +9999,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
@@ -11654,12 +11639,12 @@
}
},
"node_modules/jspdf-autotable": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/jspdf-autotable/-/jspdf-autotable-5.0.2.tgz",
- "integrity": "sha512-YNKeB7qmx3pxOLcNeoqAv3qTS7KuvVwkFe5AduCawpop3NOkBUtqDToxNc225MlNecxT4kP2Zy3z/y/yvGdXUQ==",
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/jspdf-autotable/-/jspdf-autotable-5.0.8.tgz",
+ "integrity": "sha512-Hy05N86yBO7CXBrnSLOge7i1ZYpKH2DjQ94iybaP7vBhSInjvRBgDc99ngKzSbSO8Jc98ZCally8I6n0tj2RJQ==",
"license": "MIT",
"peerDependencies": {
- "jspdf": "^2 || ^3"
+ "jspdf": "^2 || ^3 || ^4"
}
},
"node_modules/jsx-ast-utils": {
@@ -12064,7 +12049,7 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
@@ -12078,7 +12063,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -12316,7 +12301,6 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "dev": true,
"license": "MIT",
"optional": true
},
@@ -15793,7 +15777,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
diff --git a/package.json b/package.json
index 601fc8005e..8bd681755f 100644
--- a/package.json
+++ b/package.json
@@ -3,9 +3,9 @@
"private": false,
"version": "10.9.8",
"scripts": {
- "dev": "next dev",
- "start": "next start",
- "build": "next build",
+ "dev": "NODE_OPTIONS='-r ./register-polyfill.js' next dev",
+ "start": "NODE_OPTIONS='-r ./register-polyfill.js' next start",
+ "build": "NODE_OPTIONS='-r ./register-polyfill.js' next build",
"build:lib": "NODE_ENV=production INPUT_DIR=components/lib/ OUTPUT_DIR=dist/ npm run build:package",
"build:lib:windows": "set \"NODE_ENV=production\" && set \"INPUT_DIR=components/lib/\" && set \"OUTPUT_DIR=dist/\" && npm run build:package",
"build:package": "npm run build:check && rollup -c && gulp build-resources && npm run build:api",
@@ -32,7 +32,7 @@
"file-saver": "2.0.5",
"fs-extra": "^11.3.2",
"jspdf": "4.0.0",
- "jspdf-autotable": "5.0.2",
+ "jspdf-autotable": "5.0.8",
"next": "12.3.7",
"path": "^0.12.7",
"primeflex": "3.3.1",
diff --git a/pages/bottomnavigationmenu/index.js b/pages/bottomnavigationmenu/index.js
new file mode 100644
index 0000000000..55ac573554
--- /dev/null
+++ b/pages/bottomnavigationmenu/index.js
@@ -0,0 +1,93 @@
+import DocApiTable from '@/components/doc/common/docapitable';
+import { DocComponent } from '@/components/doc/common/doccomponent';
+import { AccessibilityDoc } from '@/components/doc/bottomnavigation/accessibilitydoc';
+import { BasicDoc } from '@/components/doc/bottomnavigation/basicdoc';
+import { ControlledDoc } from '@/components/doc/bottomnavigation/controlleddoc';
+import { DisplayDoc } from '@/components/doc/bottomnavigation/displaydoc';
+import { ImportDoc } from '@/components/doc/bottomnavigation/importdoc';
+import { Wireframe } from '@/components/doc/bottomnavigation/pt/wireframe';
+import { TemplateDoc } from '@/components/doc/bottomnavigation/templatedoc';
+import { StyledDoc } from '@/components/doc/bottomnavigation/theming/styleddoc';
+import { TailwindDoc } from '@/components/doc/bottomnavigation/theming/tailwinddoc';
+
+const BottomNavigationDemo = () => {
+ const docs = [
+ {
+ id: 'import',
+ label: 'Import',
+ component: ImportDoc
+ },
+ {
+ id: 'basic',
+ label: 'Basic',
+ component: BasicDoc
+ },
+ {
+ id: 'display',
+ label: 'Display',
+ component: DisplayDoc
+ },
+ {
+ id: 'controlled',
+ label: 'Controlled',
+ component: ControlledDoc
+ },
+ {
+ id: 'template',
+ label: 'Template',
+ component: TemplateDoc
+ },
+ {
+ id: 'accessibility',
+ label: 'Accessibility',
+ component: AccessibilityDoc
+ }
+ ];
+
+ const ptDocs = [
+ {
+ id: 'pt.wireframe',
+ label: 'Wireframe',
+ component: Wireframe
+ },
+ {
+ id: 'pt.bottomnavigation.options',
+ label: 'BottomNavigation PT Options',
+ component: DocApiTable
+ }
+ ];
+
+ const themingDocs = [
+ {
+ id: 'styled',
+ label: 'Styled',
+ component: StyledDoc
+ },
+ {
+ id: 'unstyled',
+ label: 'Unstyled',
+ description: 'Theming is implemented with the pass through properties in unstyled mode.',
+ children: [
+ {
+ id: 'tailwind',
+ label: 'Tailwind',
+ component: TailwindDoc
+ }
+ ]
+ }
+ ];
+
+ return (
+
+ );
+};
+
+export default BottomNavigationDemo;
diff --git a/public/themes/lara-light-cyan/theme.css b/public/themes/lara-light-cyan/theme.css
index 0133f6b6a3..4a1baf2e00 100644
--- a/public/themes/lara-light-cyan/theme.css
+++ b/public/themes/lara-light-cyan/theme.css
@@ -68,126 +68,126 @@
src: url("./fonts/InterVariable-Italic.woff2") format("woff2");
}
:root {
- --blue-50:#f5f9ff;
- --blue-100:#d0e1fd;
- --blue-200:#abc9fb;
- --blue-300:#85b2f9;
- --blue-400:#609af8;
+ --blue-50:rgb(245.2, 248.75, 254.55);
+ --blue-100:rgb(207.96, 225, 252.84);
+ --blue-200:rgb(170.72, 201.25, 251.13);
+ --blue-300:rgb(133.48, 177.5, 249.42);
+ --blue-400:rgb(96.24, 153.75, 247.71);
--blue-500:#3b82f6;
- --blue-600:#326fd1;
- --blue-700:#295bac;
- --blue-800:#204887;
- --blue-900:#183462;
- --green-50:#f4fcf7;
- --green-100:#caf1d8;
- --green-200:#a0e6ba;
- --green-300:#76db9b;
- --green-400:#4cd07d;
+ --blue-600:rgb(50.15, 110.5, 209.1);
+ --blue-700:rgb(41.3, 91, 172.2);
+ --blue-800:rgb(32.45, 71.5, 135.3);
+ --blue-900:rgb(23.6, 52, 98.4);
+ --green-50:rgb(243.95, 252.1, 246.95);
+ --green-100:rgb(201.96, 241.08, 216.36);
+ --green-200:rgb(159.97, 230.06, 185.77);
+ --green-300:rgb(117.98, 219.04, 155.18);
+ --green-400:rgb(75.99, 208.02, 124.59);
--green-500:#22c55e;
- --green-600:#1da750;
- --green-700:#188a42;
- --green-800:#136c34;
- --green-900:#0e4f26;
- --yellow-50:#fefbf3;
- --yellow-100:#faedc4;
- --yellow-200:#f6de95;
- --yellow-300:#f2d066;
- --yellow-400:#eec137;
+ --green-600:rgb(28.9, 167.45, 79.9);
+ --green-700:rgb(23.8, 137.9, 65.8);
+ --green-800:rgb(18.7, 108.35, 51.7);
+ --green-900:rgb(13.6, 78.8, 37.6);
+ --yellow-50:rgb(253.95, 251.2, 242.65);
+ --yellow-100:rgb(249.96, 236.76, 195.72);
+ --yellow-200:rgb(245.97, 222.32, 148.79);
+ --yellow-300:rgb(241.98, 207.88, 101.86);
+ --yellow-400:rgb(237.99, 193.44, 54.93);
--yellow-500:#eab308;
- --yellow-600:#c79807;
- --yellow-700:#a47d06;
- --yellow-800:#816204;
- --yellow-900:#5e4803;
- --cyan-50:#f3fbfd;
- --cyan-100:#c3edf5;
- --cyan-200:#94e0ed;
- --cyan-300:#65d2e4;
- --cyan-400:#35c4dc;
+ --yellow-600:rgb(198.9, 152.15, 6.8);
+ --yellow-700:rgb(163.8, 125.3, 5.6);
+ --yellow-800:rgb(128.7, 98.45, 4.4);
+ --yellow-900:rgb(93.6, 71.6, 3.2);
+ --cyan-50:rgb(242.55, 251.35, 252.85);
+ --cyan-100:rgb(195.24, 237.48, 244.68);
+ --cyan-200:rgb(147.93, 223.61, 236.51);
+ --cyan-300:rgb(100.62, 209.74, 228.34);
+ --cyan-400:rgb(53.31, 195.87, 220.17);
--cyan-500:#06b6d4;
- --cyan-600:#059bb4;
- --cyan-700:#047f94;
- --cyan-800:#036475;
- --cyan-900:#024955;
- --pink-50:#fef6fa;
- --pink-100:#fad3e7;
- --pink-200:#f7b0d3;
- --pink-300:#f38ec0;
- --pink-400:#f06bac;
+ --cyan-600:rgb(5.1, 154.7, 180.2);
+ --cyan-700:rgb(4.2, 127.4, 148.4);
+ --cyan-800:rgb(3.3, 100.1, 116.6);
+ --cyan-900:rgb(2.4, 72.8, 84.8);
+ --pink-50:rgb(254.05, 245.85, 249.9);
+ --pink-100:rgb(250.44, 211.08, 230.52);
+ --pink-200:rgb(246.83, 176.31, 211.14);
+ --pink-300:rgb(243.22, 141.54, 191.76);
+ --pink-400:rgb(239.61, 106.77, 172.38);
--pink-500:#ec4899;
- --pink-600:#c93d82;
- --pink-700:#a5326b;
- --pink-800:#822854;
- --pink-900:#5e1d3d;
- --indigo-50:#f7f7fe;
- --indigo-100:#dadafc;
- --indigo-200:#bcbdf9;
- --indigo-300:#9ea0f6;
- --indigo-400:#8183f4;
+ --pink-600:rgb(200.6, 61.2, 130.05);
+ --pink-700:rgb(165.2, 50.4, 107.1);
+ --pink-800:rgb(129.8, 39.6, 84.15);
+ --pink-900:rgb(94.4, 28.8, 61.2);
+ --indigo-50:rgb(247.2, 247.35, 254.3);
+ --indigo-100:rgb(217.56, 218.28, 251.64);
+ --indigo-200:rgb(187.92, 189.21, 248.98);
+ --indigo-300:rgb(158.28, 160.14, 246.32);
+ --indigo-400:rgb(128.64, 131.07, 243.66);
--indigo-500:#6366f1;
- --indigo-600:#5457cd;
- --indigo-700:#4547a9;
- --indigo-800:#363885;
- --indigo-900:#282960;
- --teal-50:#f3fbfb;
- --teal-100:#c7eeea;
- --teal-200:#9ae0d9;
- --teal-300:#6dd3c8;
- --teal-400:#41c5b7;
+ --indigo-600:rgb(84.15, 86.7, 204.85);
+ --indigo-700:rgb(69.3, 71.4, 168.7);
+ --indigo-800:rgb(54.45, 56.1, 132.55);
+ --indigo-900:rgb(39.6, 40.8, 96.4);
+ --teal-50:rgb(243.25, 251.45, 250.55);
+ --teal-100:rgb(198.6, 237.96, 233.64);
+ --teal-200:rgb(153.95, 224.47, 216.73);
+ --teal-300:rgb(109.3, 210.98, 199.82);
+ --teal-400:rgb(64.65, 197.49, 182.91);
--teal-500:#14b8a6;
- --teal-600:#119c8d;
- --teal-700:#0e8174;
- --teal-800:#0b655b;
- --teal-900:#084a42;
- --orange-50:#fff8f3;
- --orange-100:#feddc7;
- --orange-200:#fcc39b;
- --orange-300:#fba86f;
- --orange-400:#fa8e42;
+ --teal-600:rgb(17, 156.4, 141.1);
+ --teal-700:rgb(14, 128.8, 116.2);
+ --teal-800:rgb(11, 101.2, 91.3);
+ --teal-900:rgb(8, 73.6, 66.4);
+ --orange-50:rgb(254.7, 248, 243.35);
+ --orange-100:rgb(253.56, 221.4, 199.08);
+ --orange-200:rgb(252.42, 194.8, 154.81);
+ --orange-300:rgb(251.28, 168.2, 110.54);
+ --orange-400:rgb(250.14, 141.6, 66.27);
--orange-500:#f97316;
- --orange-600:#d46213;
- --orange-700:#ae510f;
- --orange-800:#893f0c;
- --orange-900:#642e09;
- --bluegray-50:#f7f8f9;
- --bluegray-100:#dadee3;
- --bluegray-200:#bcc3cd;
- --bluegray-300:#9fa9b7;
- --bluegray-400:#818ea1;
+ --orange-600:rgb(211.65, 97.75, 18.7);
+ --orange-700:rgb(174.3, 80.5, 15.4);
+ --orange-800:rgb(136.95, 63.25, 12.1);
+ --orange-900:rgb(99.6, 46, 8.8);
+ --bluegray-50:rgb(247.25, 248.05, 249.2);
+ --bluegray-100:rgb(217.8, 221.64, 227.16);
+ --bluegray-200:rgb(188.35, 195.23, 205.12);
+ --bluegray-300:rgb(158.9, 168.82, 183.08);
+ --bluegray-400:rgb(129.45, 142.41, 161.04);
--bluegray-500:#64748b;
- --bluegray-600:#556376;
- --bluegray-700:#465161;
- --bluegray-800:#37404c;
- --bluegray-900:#282e38;
- --purple-50:#fbf7ff;
- --purple-100:#ead6fd;
- --purple-200:#dab6fc;
- --purple-300:#c996fa;
- --purple-400:#b975f9;
+ --bluegray-600:rgb(85, 98.6, 118.15);
+ --bluegray-700:rgb(70, 81.2, 97.3);
+ --bluegray-800:rgb(55, 63.8, 76.45);
+ --bluegray-900:rgb(40, 46.4, 55.6);
+ --purple-50:rgb(250.65, 246.5, 254.6);
+ --purple-100:rgb(234.12, 214.2, 253.08);
+ --purple-200:rgb(217.59, 181.9, 251.56);
+ --purple-300:rgb(201.06, 149.6, 250.04);
+ --purple-400:rgb(184.53, 117.3, 248.52);
--purple-500:#a855f7;
- --purple-600:#8f48d2;
- --purple-700:#763cad;
- --purple-800:#5c2f88;
- --purple-900:#432263;
- --red-50:#fff5f5;
- --red-100:#ffd0ce;
- --red-200:#ffaca7;
- --red-300:#ff8780;
- --red-400:#ff6259;
+ --purple-600:rgb(142.8, 72.25, 209.95);
+ --purple-700:rgb(117.6, 59.5, 172.9);
+ --purple-800:rgb(92.4, 46.75, 135.85);
+ --purple-900:rgb(67.2, 34, 98.8);
+ --red-50:rgb(255, 245.3, 244.75);
+ --red-100:rgb(255, 208.44, 205.8);
+ --red-200:rgb(255, 171.58, 166.85);
+ --red-300:rgb(255, 134.72, 127.9);
+ --red-400:rgb(255, 97.86, 88.95);
--red-500:#ff3d32;
- --red-600:#d9342b;
- --red-700:#b32b23;
- --red-800:#8c221c;
- --red-900:#661814;
- --primary-50:#f3fbfd;
- --primary-100:#c3edf5;
- --primary-200:#94e0ed;
- --primary-300:#65d2e4;
- --primary-400:#35c4dc;
+ --red-600:rgb(216.75, 51.85, 42.5);
+ --red-700:rgb(178.5, 42.7, 35);
+ --red-800:rgb(140.25, 33.55, 27.5);
+ --red-900:rgb(102, 24.4, 20);
+ --primary-50:rgb(242.55, 251.35, 252.85);
+ --primary-100:rgb(195.24, 237.48, 244.68);
+ --primary-200:rgb(147.93, 223.61, 236.51);
+ --primary-300:rgb(100.62, 209.74, 228.34);
+ --primary-400:rgb(53.31, 195.87, 220.17);
--primary-500:#06b6d4;
- --primary-600:#059bb4;
- --primary-700:#047f94;
- --primary-800:#036475;
- --primary-900:#024955;
+ --primary-600:rgb(5.1, 154.7, 180.2);
+ --primary-700:rgb(4.2, 127.4, 148.4);
+ --primary-800:rgb(3.3, 100.1, 116.6);
+ --primary-900:rgb(2.4, 72.8, 84.8);
}
.p-editor-container .p-editor-toolbar {
@@ -3698,7 +3698,7 @@
color: #0e7490;
}
.p-organizationchart .p-organizationchart-node-content.p-highlight .p-node-toggler i {
- color: #6df7ff;
+ color: rgb(108.5, 247.2894736842, 255);
}
.p-organizationchart .p-organizationchart-line-down {
background: #e5e7eb;
@@ -4020,7 +4020,7 @@
height: 0.5rem;
}
.p-tree .p-treenode-droppoint.p-treenode-droppoint-active {
- background: #8af9ff;
+ background: rgb(137.8, 248.8315789474, 255);
}
.p-treetable {
position: relative;
@@ -4869,7 +4869,7 @@
.p-confirm-popup:before {
border: solid transparent;
border-color: rgba(255, 255, 255, 0);
- border-bottom-color: #f2f2f2;
+ border-bottom-color: rgb(242.25, 242.25, 242.25);
}
.p-confirm-popup.p-confirm-popup-flipped:after {
border-top-color: #ffffff;
@@ -4997,7 +4997,7 @@
.p-overlaypanel:before {
border: solid transparent;
border-color: rgba(255, 255, 255, 0);
- border-bottom-color: #f2f2f2;
+ border-bottom-color: rgb(242.25, 242.25, 242.25);
}
.p-overlaypanel.p-overlaypanel-flipped:after {
border-top-color: #ffffff;
@@ -5294,6 +5294,73 @@
transform: none;
margin: 0;
}
+ .p-bottomnavigation {
+ background: #ffffff;
+ border: 1px solid #e5e7eb;
+ border-radius: 1rem;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+ padding: 0.5rem;
+ }
+ .p-bottomnavigation .p-bottomnavigation-list {
+ gap: 0.25rem;
+ outline: 0 none;
+ }
+ .p-bottomnavigation .p-bottomnavigation-item .p-menuitem-link {
+ width: 3.5rem;
+ height: 3rem;
+ padding: 0.5rem;
+ border-radius: 6px;
+ color: #6b7280;
+ transition: box-shadow 0.2s;
+ }
+ .p-bottomnavigation .p-bottomnavigation-item .p-menuitem-link .p-menuitem-text {
+ font-size: 0.75rem;
+ }
+ .p-bottomnavigation .p-bottomnavigation-item .p-menuitem-link:not(.p-disabled):focus-visible {
+ outline: 0 none;
+ outline-offset: 0;
+ box-shadow: inset 0 0 0 0.2rem #a5f3fc;
+ }
+ .p-bottomnavigation .p-bottomnavigation-item:not(.p-highlight):not(.p-disabled):hover .p-menuitem-link {
+ color: #4b5563;
+ }
+ .p-bottomnavigation .p-bottomnavigation-item.p-highlight .p-menuitem-link {
+ color: #0e7490;
+ }
+ .p-bottomnavigation.p-bottomnavigation-labels .p-menuitem-icon {
+ margin-bottom: 0.375rem;
+ }
+ .p-bottomnavigation.p-bottomnavigation-active-highlight .p-bottomnavigation-item.p-highlight .p-menuitem-link {
+ background: #ecfeff;
+ }
+ .p-bottomnavigation.p-bottomnavigation-active-raised .p-bottomnavigation-item.p-highlight .p-menuitem-link {
+ width: 3.5rem;
+ height: 3.5rem;
+ transform: translateY(calc(-1 * 0.75rem));
+ background: #ecfeff;
+ color: #0e7490;
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.18);
+ }
+ .p-bottomnavigation.p-bottomnavigation-indicator-dot .p-bottomnavigation-item.p-highlight .p-bottomnavigation-indicator, .p-bottomnavigation.p-bottomnavigation-indicator-bar .p-bottomnavigation-item.p-highlight .p-bottomnavigation-indicator {
+ display: block;
+ position: absolute;
+ background: #0e7490;
+ }
+ .p-bottomnavigation.p-bottomnavigation-indicator-dot .p-bottomnavigation-indicator {
+ width: 0.25rem;
+ height: 0.25rem;
+ border-radius: 50%;
+ bottom: calc(-1 * 0.25rem);
+ left: 50%;
+ transform: translateX(-50%);
+ }
+ .p-bottomnavigation.p-bottomnavigation-indicator-bar .p-bottomnavigation-indicator {
+ height: 0.125rem;
+ border-radius: 0.125rem;
+ top: 0;
+ left: 0.5rem;
+ right: 0.5rem;
+ }
.p-megamenu {
padding: 0.5rem;
background: #f9fafb;
@@ -7018,25 +7085,25 @@
background-color: #06b6d4;
}
.p-button:focus {
- box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #71e7fb, 0 1px 2px 0 rgb(0, 0, 0);
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgb(113.0183486239, 230.8899082569, 250.9816513761), 0 1px 2px 0 rgb(0, 0, 0);
}
.p-button.p-button-secondary:enabled:focus {
- box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #b0b9c6, 0 1px 2px 0 rgb(0, 0, 0);
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgb(176.1945606695, 185.2656903766, 198.3054393305), 0 1px 2px 0 rgb(0, 0, 0);
}
.p-button.p-button-success:enabled:focus {
- box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #88eaac, 0 1px 2px 0 rgb(0, 0, 0);
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgb(136.0324675325, 234.4675324675, 172.2662337662), 0 1px 2px 0 rgb(0, 0, 0);
}
.p-button.p-button-info:enabled:focus {
- box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #83d3f8, 0 1px 2px 0 rgb(0, 0, 0);
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgb(130.9534412955, 211.3441295547, 247.5465587045), 0 1px 2px 0 rgb(0, 0, 0);
}
.p-button.p-button-warning:enabled:focus {
- box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #fcb98b, 0 1px 2px 0 rgb(0, 0, 0);
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgb(252, 185, 138.5), 0 1px 2px 0 rgb(0, 0, 0);
}
.p-button.p-button-help:enabled:focus {
- box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #d4aafb, 0 1px 2px 0 rgb(0, 0, 0);
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgb(211.5, 170, 251), 0 1px 2px 0 rgb(0, 0, 0);
}
.p-button.p-button-danger:enabled:focus {
- box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #f7a2a2, 0 1px 2px 0 rgb(0, 0, 0);
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgb(247, 161.5, 161.5), 0 1px 2px 0 rgb(0, 0, 0);
}
.p-datatable .p-datatable-tbody > tr.p-datatable-dragpoint-top > td {
box-shadow: inset 0 2px 0 0 #06b6d4;
@@ -7045,7 +7112,7 @@
box-shadow: inset 0 -2px 0 0 #06b6d4;
}
.p-speeddial-item.p-focus > .p-speeddial-action {
- box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #71e7fb, 0 1px 2px 0 rgb(0, 0, 0);
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px rgb(113.0183486239, 230.8899082569, 250.9816513761), 0 1px 2px 0 rgb(0, 0, 0);
}
.p-toast-message {
backdrop-filter: blur(10px);
diff --git a/register-polyfill.js b/register-polyfill.js
new file mode 100644
index 0000000000..1f676ccb09
--- /dev/null
+++ b/register-polyfill.js
@@ -0,0 +1,4 @@
+const bufferModule = require('buffer');
+if (typeof bufferModule.SlowBuffer === 'undefined') {
+ bufferModule.SlowBuffer = class SlowBuffer extends bufferModule.Buffer {};
+}