Merge branch 'master' into v4

pull/5507/head
Cagatay Civici 2024-02-03 15:50:33 +03:00
commit 5ac44cfc6f
901 changed files with 196296 additions and 32520 deletions

View File

@ -1,98 +1,99 @@
name: Bug report
description: Create a report to help PrimeVue improve.
title: "Component Name: Issue Title"
labels: "Status: Needs Triage"
title: 'Component Name: Issue Title'
labels: 'Status: Needs Triage'
body:
- type: markdown
attributes:
# yamllint disable rule:line-length
value: >
### There is no guarantee in receiving an immediate response in GitHub Issue Tracker, If you'd like to secure our response, you may consider *PrimeVue PRO Support* where support is provided within 4 business hours
# yamllint enable rule:line-length
- type: textarea
id: description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is.
validations:
required: true
- type: input
id: reproducer
attributes:
label: Reproducer
placeholder: https://codesandbox.io/s/primevue-create-vue-issue-template-kw9g6i
description: |
Please fork one of the issue template
[PrimeVue 3 Issue Template](https://codesandbox.io/s/primevue-create-vue-issue-template-kw9g6i)
[PrimeVue TypeScript Issue Template](https://codesandbox.io/s/primevue-create-vue-typescript-issue-template-fb775d)
[PrimeVue 2 Issue Template](https://codesandbox.io/s/primevue-2-issue-template-dw7jd7)
and create a case demonstrating your bug report. Issues **without** a CodeSandbox have much less possibility to be reviewed.
validations:
required: true
- type: input
id: pr-version
attributes:
label: PrimeVue version
placeholder: x.x.x
validations:
required: true
- type: dropdown
id: vue-version
attributes:
label: Vue version
multiple: false
options:
- 3.x
- 2.x
validations:
required: true
- type: dropdown
id: language
attributes:
label: Language
multiple: false
options:
- TypeScript
- ES5
- ES6
- ALL
validations:
required: true
- type: dropdown
id: engine
attributes:
label: Build / Runtime
multiple: false
options:
- Vue CLI App
- TypeScript
- Nuxt
- Vite
validations:
required: true
- type: input
id: browsers
attributes:
label: Browser(s)
description: List specific browser(s) the problem occurs on or leave blank if ALL browsers
placeholder: >
e.g. Safari 15, iOS 15.4, Chrome 90
- type: textarea
id: reproduce-steps
attributes:
label: Steps to reproduce the behavior
description: A clear and concise description of how to make the issue happen.
placeholder: >
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: false
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: false
- type: markdown
attributes:
# yamllint disable rule:line-length
value: >
### There is no guarantee in receiving an immediate response in GitHub Issue Tracker, If you'd like to secure our response, you may consider *PrimeVue PRO Support* where support is provided within 4 business hours
# yamllint enable rule:line-length
- type: textarea
id: description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is.
validations:
required: true
- type: input
id: reproducer
attributes:
label: Reproducer
placeholder: https://stackblitz.com/edit/primevue-create-vue-issue-template
description: |
Please fork one of the issue template
[PrimeVue 3 Issue Template](https://stackblitz.com/edit/primevue-create-vue-issue-template)
[PrimeVue TypeScript Issue Template](https://stackblitz.com/edit/primevue-create-vue-typescript-issue-template)
[PrimeVue Nuxt Issue Template](https://stackblitz.com/edit/primevue-nuxt-issue-template)
[PrimeVue 2 Issue Template](https://codesandbox.io/s/primevue-2-issue-template-dw7jd7)
and create a case demonstrating your bug report. Issues **without** a Stackblitz have much less possibility to be reviewed.
validations:
required: true
- type: input
id: pr-version
attributes:
label: PrimeVue version
placeholder: x.x.x
validations:
required: true
- type: dropdown
id: vue-version
attributes:
label: Vue version
multiple: false
options:
- 3.x
- 2.x
validations:
required: true
- type: dropdown
id: language
attributes:
label: Language
multiple: false
options:
- TypeScript
- ES5
- ES6
- ALL
validations:
required: true
- type: dropdown
id: engine
attributes:
label: Build / Runtime
multiple: false
options:
- Vue CLI App
- TypeScript
- Nuxt
- Vite
validations:
required: true
- type: input
id: browsers
attributes:
label: Browser(s)
description: List specific browser(s) the problem occurs on or leave blank if ALL browsers
placeholder: >
e.g. Safari 15, iOS 15.4, Chrome 90
- type: textarea
id: reproduce-steps
attributes:
label: Steps to reproduce the behavior
description: A clear and concise description of how to make the issue happen.
placeholder: >
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: false
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: false

View File

@ -1,5 +1,99 @@
# Changelog
## [3.47.2](https://github.com/primefaces/primevue/tree/3.47.1) (2024-01-23)
[Full Changelog](https://github.com/primefaces/primevue/compare/3.47.1...3.47.2)
**Fixed bugs:**
- OverlayPanel: RangeError: Maximum call stack size exceeded inside link [\#5146](https://github.com/primefaces/primevue/issues/5146)
- Align hover colors for MultipleSelect, AutoComplete and CascadeSelect [\#5150](https://github.com/primefaces/primevue/issues/5150)
## [3.47.1](https://github.com/primefaces/primevue/tree/3.47.1) (2024-01-24)
[Full Changelog](https://github.com/primefaces/primevue/compare/3.47.0...3.47.1)
**Fixed bugs:**
- Keyboard accessibility is not working on OrderList and PickList [\#5144](https://github.com/primefaces/primevue/issues/5144)
## [3.47.0](https://github.com/primefaces/primevue/tree/3.47.0) (2024-01-24)
[Full Changelog](https://github.com/primefaces/primevue/compare/3.46.0...3.47.0)
**Breaking Changes:**
- Change visual focus behavior for UI/UX enhancement on some components [\#5106](https://github.com/primefaces/primevue/issues/5106)
- Highlight state changes on Checkbox selection mode [\#5105](https://github.com/primefaces/primevue/issues/5105)
- autoOptionFocus property added to Input-like components [\#5099](https://github.com/primefaces/primevue/issues/5099)
- Improve the structure of some components to comply with standards [\#5071](https://github.com/primefaces/primevue/issues/5071)
- autoOptionFocus default type is changed as false [\#5096](https://github.com/primefaces/primevue/issues/5096)
**Fixed bugs:**
- Search with null/undefined values breaks rendering [\#5140](https://github.com/primefaces/primevue/issues/5140)
- The hideIcon property is not working on SpeedDial [\#5135](https://github.com/primefaces/primevue/issues/5135)
- Textarea: modelValue should accept Nullable<string> as InputText does [\#5127](https://github.com/primefaces/primevue/issues/5127)
- Chips: Separator by new line doesn't work by pasting value [\#5103](https://github.com/primefaces/primevue/issues/5103)
- DataTable: Cannot read properties of null when editMode="cell" and selectionMode="single" [\#5100](https://github.com/primefaces/primevue/issues/5100)
- Unit tests in the master branch are failing [\#5095](https://github.com/primefaces/primevue/issues/5095)
- InputNumber: Home and End key defects [\#5094](https://github.com/primefaces/primevue/issues/5094)
- Float label demo is broken in mobile mode [\#5089](https://github.com/primefaces/primevue/issues/5089)
- [TabMenu] Router demo has the wrong code [\#5082](https://github.com/primefaces/primevue/issues/5082)
- Calendar: Incorrect interface "CalendarContext" for Calendar component [\#5077](https://github.com/primefaces/primevue/issues/5077)
- Tag: center icon when no label is present (icon-only mode) [\#5067](https://github.com/primefaces/primevue/issues/5067)
- DataTable: Uncaught TypeError: Cannot read properties of null (reading 'sortable') at Proxy.getColumnPT8 [\#5062](https://github.com/primefaces/primevue/issues/5062)
- Calendar: When use with Datatable filter, the calendar would show at the bottom of the page. [\#5055](https://github.com/primefaces/primevue/issues/5055)
- DataTable: persistent expandedRows with dataKey doesn't working properly [\#5057](https://github.com/primefaces/primevue/issues/5057)
- DataTable: Column with no props throws exception [\#5056](https://github.com/primefaces/primevue/issues/5056)
- DataTable: Empty column causes maximum recursive calls to be reached [\#5053](https://github.com/primefaces/primevue/issues/5053)
- ContextMenu: Cache duplication "focusedItemId" [\#5054](https://github.com/primefaces/primevue/issues/5054)
- Calendar: panel does not hide when pressing enter [\#5050](https://github.com/primefaces/primevue/issues/5050)
- Dialog: maximizable broken if dialog moved [\#5048](https://github.com/primefaces/primevue/issues/5048)
- DataTable: Hydration attribute mismatch with sortable columns [\#5046](https://github.com/primefaces/primevue/issues/5046)
- Can't paste a decimal value when there is a total value in the input. [\#5034](https://github.com/primefaces/primevue/issues/5034)
- Tooltip: Malfunction inside Links [\#5030](https://github.com/primefaces/primevue/issues/5030)
- SplitButton inherits CSS properties from DynamicDialog "footer" and disrupts the original design [\#5012](https://github.com/primefaces/primevue/issues/5012)
- Tooltip: missing nonce for inline styles [\#5010](https://github.com/primefaces/primevue/issues/5010)
- InputNumber: insert behavior defects [\#4539](https://github.com/primefaces/primevue/issues/4539)
**Implemented New Features and Enhancements:**
- New Aura Theme[\#5143](https://github.com/primefaces/primevue/issues/5143)
- Add itemGroupLabel, itemLabel, tickIcon and blankIcon options to pt in Dropdown [\#5142](https://github.com/primefaces/primevue/issues/5142)
- Add highlightOnSelect and checkmark props to Dropdown [\#5141](https://github.com/primefaces/primevue/issues/5141)
- Icon: BlankIcon [\#5139](https://github.com/primefaces/primevue/issues/5139)
- Add focusOnHover props to some components [\#5130](https://github.com/primefaces/primevue/issues/5130)
- DataTable: body template rowTogglerCallback callback option added [\#5123](https://github.com/primefaces/primevue/issues/5123)
- Dialog: no transition on open/close when dialog is maximized [\#5118](https://github.com/primefaces/primevue/issues/5118)
- Expose alignOverlay method in OverlayPanel [\#5075](https://github.com/primefaces/primevue/issues/5075)
- Message: 'life-end' emit [\#5070](https://github.com/primefaces/primevue/issues/5070)
- New MeterGroup component [\#5066](https://github.com/primefaces/primevue/issues/5066)
- Dropdown: After selecting an option, clearing the value using close icon should clear the filter input [\#5060](https://github.com/primefaces/primevue/issues/5060)
## [3.46.0](https://github.com/primefaces/primevue/tree/3.46.0) (2024-01-08)
[Full Changelog](https://github.com/primefaces/primevue/compare/3.45.0...3.46.0)
**Fixed bugs:**
- SVG clip path attribute should be clip-path and not clipPath [\#5036](https://github.com/primefaces/primevue/issues/5036)
- Tooltip arrow is broken [\#5033](https://github.com/primefaces/primevue/issues/5033)
- ConfirmDialog & ConfirmPopup: icon option class pt implementation defect [\#5028](https://github.com/primefaces/primevue/issues/5028)
- Sidebar: Escape key doesn't close the Slidebar [\#5016](https://github.com/primefaces/primevue/issues/5016)
- BodyRow: Cannot read propertie of null (reading 'forEach) [\#5005](https://github.com/primefaces/primevue/issues/5005)
- InputNumber: highlight on focus don't work on multiple inputs with the same value [\#5003](https://github.com/primefaces/primevue/issues/5003)
- TreeSelect: tab key control defect [\#4998](https://github.com/primefaces/primevue/issues/4998)
- bodyRow broken pt context options [\#4996](https://github.com/primefaces/primevue/issues/4996)
- VirtualScroller loading is not working on DataTable [\#4993](https://github.com/primefaces/primevue/issues/4993)
- added sortIcon property to type ColumnPassThroughOptionType [\#4992](https://github.com/primefaces/primevue/issues/4992)
- wrong type appendTo props [\#4905](https://github.com/primefaces/primevue/issues/4905)
**Implemented New Features and Enhancements:**
- Add caption option to passthrough options on Card [\#5020](https://github.com/primefaces/primevue/issues/5020)
- CascadeSelect: context options improvements for pt [\#4995](https://github.com/primefaces/primevue/issues/4995)
## [3.45.0](https://github.com/primefaces/primevue/tree/3.45.0) (2023-12-22)
[Full Changelog](https://github.com/primefaces/primevue/compare/3.44.0...3.45.0)

View File

@ -26,7 +26,7 @@ pnpm add primevue
## Plugin
PrimeVue plugin is required to be installed with the **use** function to set up the default [configuration](https://primevue.org/theming).
PrimeVue plugin is required to be installed with the **use** function to set up the default [configuration](https://primevue.org/configuration).
```javascript
import { createApp } from 'vue';
@ -46,7 +46,7 @@ Styled mode is based on pre-skinned components with opinionated themes like Mate
```javascript
// theme
import 'primevue/resources/themes/lara-light-green/theme.css';
import 'primevue/resources/themes/aura-light-green/theme.css';
```
**Unstyled Mode**
@ -138,7 +138,7 @@ In styled mode, the theme can be defined at Nuxt configuration with the css prop
```javascript
export default defineNuxtConfig({
css: ['primevue/resources/themes/lara-dark-green/theme.css']
css: ['primevue/resources/themes/aura-dark-green/theme.css']
});
```

View File

@ -89,6 +89,18 @@ const AutoCompleteProps = [
default: 'false',
description: 'When present, it specifies that the component should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'dataKey',
type: 'string',
@ -200,7 +212,7 @@ const AutoCompleteProps = [
{
name: 'autoOptionFocus',
type: 'boolean',
default: 'true',
default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.'
},
{

View File

@ -9,7 +9,7 @@ const BadgeProps = [
name: 'severity',
type: 'string',
default: 'null',
description: 'Severity type of the badge.'
description: 'Severity type of the badge. Valid severities are "secondary", "success", "info", "warning", "danger" and "contrast".'
},
{
name: 'size',

View File

@ -57,7 +57,7 @@ const ButtonProps = [
name: 'severity',
type: 'string',
default: 'null',
description: 'Defines the style of the button, valid values are "secondary", "success", "info", "warning", "help", "danger".'
description: 'Defines the style of the button, valid values are "secondary", "success", "info", "warning", "help", "danger", "contrast".'
},
{
name: 'raised',

View File

@ -257,6 +257,18 @@ const CalendarProps = [
default: 'false',
description: 'When present, it specifies that the element should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'readonly',
type: 'boolean',

View File

@ -53,6 +53,18 @@ const CascadeSelectProps = [
default: 'false',
description: 'When present, it specifies that the component should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'dataKey',
type: 'string',
@ -128,7 +140,7 @@ const CascadeSelectProps = [
{
name: 'autoOptionFocus',
type: 'boolean',
default: 'true',
default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.'
},
{

View File

@ -23,6 +23,18 @@ const CheckboxProps = [
default: 'false',
description: 'When present, it specifies that the element should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'readonly',
type: 'boolean',

View File

@ -35,6 +35,18 @@ const ChipsProps = [
default: 'false',
description: 'When present, it specifies that the element should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'placeholder',
type: 'string',

View File

@ -366,6 +366,12 @@ const DataTableProps = [
default: 'false',
description: 'Whether to displays rows with alternating colors.'
},
{
name: 'highlightOnSelect',
type: 'boolean',
default: 'false',
description: 'Highlights automatically the first item.'
},
{
name: 'size',
type: 'string',

View File

@ -95,6 +95,18 @@ const DropdownProps = [
default: 'false',
description: 'When present, it specifies that the component should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'dataKey',
type: 'string',
@ -185,6 +197,12 @@ const DropdownProps = [
default: 'false',
description: 'Clears the filter value when hiding the dropdown.'
},
{
name: 'resetFilterOnClear',
type: 'boolean',
default: 'false',
description: 'Clears the filter value when clicking on the clear icon.'
},
{
name: 'virtualScrollerOptions',
type: 'object',
@ -194,7 +212,7 @@ const DropdownProps = [
{
name: 'autoOptionFocus',
type: 'boolean',
default: 'true',
default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.'
},
{

View File

@ -3,7 +3,7 @@ const InlineMessageProps = [
name: 'severity',
type: 'string',
default: 'error',
description: 'Severity level of the message. Valid severities are "success", "info", "warn" and "error".'
description: 'Severity level of the message. Valid severities are "success", "info", "warn", "error", "secondary" and "contrast".'
},
{
name: 'icon',

View File

@ -29,6 +29,18 @@ const InputMaskProps = [
default: 'false',
description: 'Defines if model sets the raw unmasked value to bound value or the formatted mask value.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'pt',
type: 'any',

View File

@ -147,6 +147,18 @@ const InputNumberProps = [
default: 'null',
description: 'Placeholder text for the input.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'inputId',
type: 'string',

View File

@ -11,6 +11,18 @@ const InputTextProps = [
default: 'null',
description: 'Defines the size of the component, valid values are "small" and "large".'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'pt',
type: 'any',

View File

@ -53,6 +53,12 @@ const ListboxProps = [
default: 'false',
description: 'When specified, disables the component.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'dataKey',
type: 'string',
@ -117,7 +123,7 @@ const ListboxProps = [
{
name: 'autoOptionFocus',
type: 'boolean',
default: 'true',
default: 'false',
description: 'Whether to focus on the first visible or selected element.'
},
{

View File

@ -3,7 +3,7 @@ const MessageProps = [
name: 'severity',
type: 'string',
default: 'info',
description: 'Severity level of the message. Valid severities are "success", "info", "warn" and "error".'
description: 'Severity level of the message. Valid severities are "success", "info", "warn", "error", "secondary" and "contrast".'
},
{
name: 'closable',
@ -75,6 +75,10 @@ const MessageEvents = [
description: 'Browser event'
}
]
},
{
name: 'life-end',
description: "Callback to invoke when the message's timeout is over."
}
];

View File

@ -59,6 +59,18 @@ const MultiSelectProps = [
default: 'false',
description: 'When present, it specifies that the component should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'inputId',
type: 'string',
@ -236,7 +248,7 @@ const MultiSelectProps = [
{
name: 'autoOptionFocus',
type: 'boolean',
default: 'true',
default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.'
},
{
@ -245,6 +257,12 @@ const MultiSelectProps = [
default: 'false',
description: 'Whether to focus on the filter element when the overlay panel is shown.'
},
{
name: 'highlightOnSelect',
type: 'boolean',
default: 'false',
description: 'Highlights automatically the first item.'
},
{
name: 'filterMessage',
type: 'string',

View File

@ -18,6 +18,12 @@ const OrderListProps = [
description:
'Defines whether metaKey is requred or not for the selection. When true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically.'
},
{
name: 'autoOptionFocus',
type: 'boolean',
default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.'
},
{
name: 'dataKey',
type: 'string',

View File

@ -83,6 +83,18 @@ const PasswordProps = [
default: 'null',
description: 'Placeholder text for the input.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'required',
type: 'boolean',

View File

@ -18,6 +18,12 @@ const PickListProps = [
description:
'Defines whether metaKey is requred or not for the selection. When true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically.'
},
{
name: 'autoOptionFocus',
type: 'boolean',
default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.'
},
{
name: 'dataKey',
type: 'string',

View File

@ -23,6 +23,18 @@ const RadioButtonProps = [
default: 'false',
description: 'When present, it specifies that the element should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'inputId',
type: 'string',

View File

@ -41,6 +41,12 @@ const SelectButtonProps = [
default: 'false',
description: 'When present, it specifies that the element should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'dataKey',
type: 'string',

View File

@ -63,7 +63,7 @@ const SplitButtonProps = [
name: 'severity',
type: 'string',
default: 'null',
description: 'Defines the style of the button, valid values are "secondary", "success", "info", "warning", "help", "danger".'
description: 'Defines the style of the button, valid values are "secondary", "success", "info", "warning", "help", "danger", "contrast".'
},
{
name: 'raised',

View File

@ -9,7 +9,7 @@ const TagProps = [
name: 'severity',
type: 'string',
default: 'null',
description: 'Severity type of the tag. Valid severities are "success", "info", "warning" and "danger".'
description: 'Severity type of the tag. Valid severities are "secondary", "success", "info", "warning", "danger" and "contrast".'
},
{
name: 'rounded',

View File

@ -11,6 +11,18 @@ const TextareaProps = [
default: 'false',
description: 'When present, height of textarea changes as being typed.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'pt',
type: 'any',

View File

@ -47,6 +47,12 @@ const ToggleButtonProps = [
default: 'false',
description: 'When present, it specifies that the element should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'inputId',
type: 'string',

View File

@ -72,6 +72,12 @@ const TreeProps = [
default: 'undefined',
description: "Locale to use in filtering. The default locale is the host environment's current locale."
},
{
name: 'highlightOnSelect',
type: 'boolean',
default: 'false',
description: 'Highlights automatically the first item.'
},
{
name: 'scrollHeight',
type: 'string',

View File

@ -29,6 +29,18 @@ const TreeSelectProps = [
default: 'false',
description: 'When present, it specifies that the component should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'tabindex',
type: 'string',

View File

@ -11,6 +11,18 @@ const TriStateCheckboxProps = [
default: 'false',
description: 'When present, it specifies that the component should be disabled.'
},
{
name: 'invalid',
type: 'boolean',
default: 'false',
description: 'When present, it specifies that the component should have invalid state style.'
},
{
name: 'variant',
type: 'string',
default: 'null',
description: 'Specifies the input variant of the component.'
},
{
name: 'tabindex',
type: 'string',

View File

@ -12,7 +12,7 @@ export default {
$route: {
handler(to) {
if (to.name === 'index') {
this.themeChangeListener({ theme: this.$appState.darkTheme ? 'lara-dark-green' : 'lara-light-green', dark: this.$appState.darkTheme });
this.themeChangeListener({ theme: this.$appState.darkTheme ? 'aura-dark-green' : 'aura-light-green', dark: this.$appState.darkTheme });
}
}
}
@ -28,7 +28,7 @@ export default {
{
id: 'home-table-link',
rel: 'stylesheet',
href: '/styles/landing/themes/lara-light-green/theme.css'
href: '/styles/landing/themes/aura-light-green/theme.css'
}
]
});

View File

@ -1,8 +1,8 @@
{
"id": 51,
"content": "New Year Sale is Here! 🎉",
"linkText": "Visit Store",
"linkHref": "https://primefaces.org/store",
"id": 52,
"content": "Tailwind Presets for Unstyled PrimeVue",
"linkText": "Learn More",
"linkHref": "http://tailwind.primevue.org",
"backgroundStyle": "background-color:var(--primary-color)",
"textStyle": "color:var(--primary-color-text);font-weight:500",
"linkStyle": "color:var(--primary-color-text);font-weight:700;text-decoration: underline;"

View File

@ -9,16 +9,8 @@
"to": "/introduction"
},
{
"name": "Vite Setup",
"to": "/vite"
},
{
"name": "Nuxt Setup",
"to": "/nuxt"
},
{
"name": "Configuration",
"to": "/configuration"
"name": "Setup",
"to": "/setup"
},
{
"name": "Playground",
@ -26,6 +18,42 @@
}
]
},
{
"name": "Installation",
"icon": "pi pi-cloud-download",
"children": [
{
"name": "Vite",
"to": "/vite"
},
{
"name": "Nuxt",
"to": "/nuxt"
},
{
"name": "CDN",
"to": "/cdn"
}
]
},
{
"name": "Configuration",
"icon": "pi pi-cog",
"children": [
{
"name": "Options",
"to": "/configuration"
},
{
"name": "Auto Import",
"to": "/autoimport"
},
{
"name": "CSS Layer",
"to": "/csslayer"
}
]
},
{
"name": "Components",
"icon": "pi pi-compass",
@ -65,6 +93,16 @@
"name": "Editor",
"to": "/editor"
},
{
"name": "FloatLabel",
"to": "/floatlabel",
"badge": "NEW"
},
{
"name": "IconField",
"to": "/iconfield",
"badge": "NEW"
},
{
"name": "InputGroup",
"to": "/inputgroup"
@ -399,6 +437,11 @@
"name": "Inplace",
"to": "/inplace"
},
{
"name": "MeterGroup",
"to": "/metergroup",
"badge": "NEW"
},
{
"name": "ScrollTop",
"to": "/scrolltop"
@ -531,10 +574,6 @@
"name": "Accessibility",
"to": "/guides/accessibility"
},
{
"name": "CSS Layer",
"to": "/guides/csslayer"
},
{
"name": "PrimeTV",
"icon": "pi pi-youtube",

View File

@ -140,4 +140,12 @@ pre[class*="language-"] {
}
}
}
&[data-p-theme^="aura-light-noir"] {
pre[class*="language-"] {
code {
background: var(--surface-950);
}
}
}
}

View File

@ -5,16 +5,6 @@
.p-selectbutton {
.p-button {
padding: 0.5rem 1rem;
&:first-child {
border-top-left-radius: 30px;
border-bottom-left-radius: 30px;
}
&:last-child {
border-top-right-radius: 30px;
border-bottom-right-radius: 30px;
}
}
}

View File

@ -40,29 +40,29 @@ h1, h2, h3, h4, h5, h6 {
}
h1 {
font-size: 2rem;
font-size: 1.75rem;
}
h2 {
font-size: 1.5rem;
}
h3 {
font-size: 1.25rem;
}
h4 {
h3 {
font-size: 1.125rem;
}
h5 {
h4 {
font-size: 1rem;
}
h6 {
h5 {
font-size: .875rem;
}
h6 {
font-size: .75rem;
}
p {
line-height: 1.75;
margin: 0 0 1rem 0;

View File

@ -78,7 +78,7 @@
p {
font-size: 1.125rem;
color: var(--surface-900);
color: var(--text-color);
margin: 0;
a {
@ -119,13 +119,13 @@
.doc-section-description {
> p {
font-size: 1.125rem;
color: var(--surface-900);
font-size: 1rem;
color: var(--text-color);
i {
border-radius: 6px;
padding: 2px 6px;
font-size: 1rem;
font-size: .875rem;
font-weight: 500;
font-style: normal;
background-color: var(--doc-highlight-text-bg);

View File

@ -1,53 +1,53 @@
.landing.layout-dark {
--home-highlight-color:#34d399;
--home-highlight-darker-color:#6ee7b7;
--home-highlight-fore-color:#030712;
--home-bg:#111827;
--home-border-color:#424b57;
--home-highlight-fore-color:#020617;
--home-bg:#09090b;
--home-border-color:#27272a;
--home-primary-text-color:#ffffff;
--home-secondary-text-color:rgba(255,255,255,.6);
--home-secondary-text-color:#a1a1aa;
--home-card-shadow:0px 50px 100px rgba(0, 0, 0, 0.25);
--home-box-bg:#1f2937;
--home-box-bg:#18181b;
--home-linkbox-bg:rgba(255, 255, 255, .05);
--home-linkbox-border:1px solid rgba(255, 255, 255, .1);
--home-linkbox-text-color:#ffffff;
--home-linkbox-hover-bg:rgba(255, 255, 255, .1);
--home-blocks-bg:transparent;
--home-blocks-block-bg:#111827;
--home-blocks-block-bg:#09090b;
--home-blocks-block-shadow:0px 5px 10px 0px rgba(0, 0, 0, 0.25) , 0px 4px 25px rgba(0, 0, 0, 0.25);
--home-blocks-border-left:5px solid #1f2937;
--home-blocks-border-bottom:7px solid #1f2937;
--home-blocks-border:1px solid #424b57;
--home-blocks-sidebar-bg:#1f2937;
--home-blocks-list-bg:#28323f;
--home-blocks-main-bg:#111827;
--home-blocks-main-border:1px solid #424b57;
--home-blocks-item-bg:#1f2937;
--home-blocks-image-bg:#28323f;
--home-blocks-text-color:#4b5563;
--home-blocks-border-left:5px solid #27272a;
--home-blocks-border-bottom:7px solid #27272a;
--home-blocks-border:1px solid #27272a;
--home-blocks-sidebar-bg:#18181b;
--home-blocks-list-bg:#27272a;
--home-blocks-main-bg:#09090b;
--home-blocks-main-border:1px solid #27272a;
--home-blocks-item-bg:#18181b;
--home-blocks-image-bg:#27272a;
--home-blocks-text-color:#52525b;
--home-blocks-active-shadow:0px 30px 50px 0px rgba(0, 0, 0, 0.25);
--home-blocks-active-border-top:1px solid #424b57;
--home-blocks-active-border-right:1px solid #424b57;
--home-blocks-active-border-bottom:6px solid #424b57;
--home-blocks-active-border-left:4px solid #424b57;
--home-blocks-active-border-top:1px solid #27272a;
--home-blocks-active-border-right:1px solid #27272a;
--home-blocks-active-border-bottom:6px solid #27272a;
--home-blocks-active-border-left:4px solid #27272a;
--home-blocks-animation-shadow:0px 30px 50px 20px rgba(0, 0, 0, 0.25);
--home-blocks-tablebar-bg:#4b5563;
--home-blocks-bar-bg:#4b5563;
--home-blocks-bar-button-bg:#ffffff;
--home-blocks-circle-bg:#4b5563;
--home-blocks-tablebar-bg:#3f3f46;
--home-blocks-bar-bg:#3f3f46;
--home-blocks-bar-button-bg:#3f3f46;
--home-blocks-circle-bg:#27272a;
--home-templates-bg:transparent;
--home-templates-block-shadow:0px 5px 10px 0px rgba(0, 0, 0, 0.25);
--home-templates-block-border-left:5px solid #424b57;
--home-templates-block-border-bottom:7px solid #424b57;
--home-templates-block-border-left:5px solid #27272a;
--home-templates-block-border-bottom:7px solid #27272a;
--home-templates-line:rgba(255,255,255,.1);
--home-templates-block-hover-bg:rgba(255,255,255,.1);
--home-templates-btn-bg:#1f2937;
--home-templates-btn-bg:#18181b;
--home-templates-btn-text-color:#ffffff;
--home-templates-btn-shadow:0px 10px 15px 0px rgba(0, 0, 0, 0.25);
--home-templates-btn-border-top:1px solid #424b57;
--home-templates-btn-border-right:1px solid #424b57;
--home-templates-btn-border-bottom:4px solid #424b57;
--home-templates-btn-border-left:3px solid #424b57;
--home-templates-btn-border-top:1px solid #27272a;
--home-templates-btn-border-right:1px solid #27272a;
--home-templates-btn-border-bottom:4px solid #27272a;
--home-templates-btn-border-left:3px solid #27272a;
--home-features-card-shadow: none;
--home-box-ring-color: rgba(52, 211, 153, .3);
}

View File

@ -2,39 +2,39 @@
--home-highlight-color:#10b981;
--home-highlight-darker-color:#059669;
--home-highlight-fore-color:#ffffff;
--home-bg:#F9FAFB;
--home-border-color:rgba(0,0,0,.1);
--home-primary-text-color:#030712;
--home-secondary-text-color:#6b7280;
--home-bg:#f8fafc;
--home-border-color:#e2e8f0;
--home-primary-text-color:#334155;
--home-secondary-text-color:#64748b;
--home-card-shadow:0px 7px 15px 0px rgba(0, 0, 0, 0.02), 0px 28px 28px 0px rgba(0, 0, 0, 0.02), 0px 63px 38px 0px rgba(0, 0, 0, 0.01);
--home-box-bg:#ffffff;
--home-linkbox-bg:#ffffff;
--home-linkbox-border:1px solid rgba(0,0,0,.1);
--home-linkbox-text-color:#030712;
--home-linkbox-hover-bg:#e5e7eb;
--home-linkbox-border:1px solid #e2e8f0;
--home-linkbox-text-color:#334155;
--home-linkbox-hover-bg:#f1f5f9;
--home-blocks-bg:transparent;
--home-blocks-block-bg:#ffffff;
--home-blocks-block-shadow:-10px 4px 10px 0px rgba(0, 0, 0, .1), -10px 4px 25px rgba(0, 0, 0, .1);
--home-blocks-border-left:5px solid rgba(0,0,0,.1);
--home-blocks-border-bottom:7px solid rgba(0,0,0,.1);
--home-blocks-border:1px solid rgba(0,0,0,.1);
--home-blocks-sidebar-bg:#f3f4f6;
--home-blocks-list-bg:#f9fafb;
--home-blocks-border-left:5px solid #e2e8f0;
--home-blocks-border-bottom:7px solid #e2e8f0;
--home-blocks-border:1px solid #e2e8f0;
--home-blocks-sidebar-bg:#f1f5f9;
--home-blocks-list-bg:#f8fafc;
--home-blocks-main-bg:#ffffff;
--home-blocks-main-border:1px solid rgba(0,0,0,.1);
--home-blocks-item-bg:#f4f5f7;
--home-blocks-image-bg:#e5e7eb;
--home-blocks-text-color:#d1d5db;
--home-blocks-main-border:1px solid #e2e8f0;
--home-blocks-item-bg:#f1f5f9;
--home-blocks-image-bg:#e2e8f0;
--home-blocks-text-color:#cbd5e1;
--home-blocks-active-shadow:0px 30px 50px 0px rgba(0, 0, 0, .1);
--home-blocks-active-border-top:1px solid rgba(0,0,0,.07);
--home-blocks-active-border-right:1px solid rgba(0,0,0,.07);
--home-blocks-active-border-bottom:4px solid rgba(0,0,0,.07);
--home-blocks-active-border-left:4px solid rgba(0,0,0,.07);
--home-blocks-animation-shadow:0px 30px 50px 10px rgba(0, 0, 0, .2);
--home-blocks-tablebar-bg:#d1d5db;
--home-blocks-bar-bg:#d1d5db;
--home-blocks-tablebar-bg:#cbd5e1;
--home-blocks-bar-bg:#cbd5e1;
--home-blocks-bar-button-bg:#ffffff;
--home-blocks-circle-bg:#c7cad0;
--home-blocks-circle-bg:#cbd5e1;
--home-templates-bg:transparent;
--home-templates-block-shadow:0px 5px 10px 0px rgba(0,0,0,.1);
--home-templates-block-border-left:5px solid #d1d5db;
@ -49,5 +49,5 @@
--home-templates-btn-border-bottom:4px solid rgba(0,0,0,.1);
--home-templates-btn-border-left:3px solid rgba(0,0,0,.1);
--home-features-card-shadow: 0px 7px 15px 0px rgba(0, 0, 0, 0.02), 0px 28px 28px 0px rgba(0, 0, 0, 0.02), 0px 63px 38px 0px rgba(0, 0, 0, 0.01);
--home-box-ring-color: var(--primary-100);
--home-box-ring-color: var(--primary-200);
}

View File

@ -13,6 +13,6 @@
--demo-code-button-color: var(--surface-500);
--demo-code-button-hover-bg: rgba(255,255,255,.1);
--demo-code-button-hover-color: var(--surface-700);
--doc-highlight-text-bg: var(--highlight-bg);
--doc-highlight-text-color: var(--highlight-text-color);
--doc-highlight-text-bg: var(--surface-50);
--doc-highlight-text-color: var(--surface-500);
}

View File

@ -2,17 +2,16 @@
--primary-color-default:var(--primary-600);
--primary-color-inverse-default:var(--surface-0);
--topbar-sticky-bg:rgba(255,255,255,.7);
--body-bg: var(--p-surface-50);
--card-border: 1px solid var(--p-surface-200);
--card-bg: var(--p-surface-0);
--glow-image: url(https://www.primefaces.org/cdn/primevue/images/layout/pattern.png), radial-gradient(50% 50% at center top, var(--primary-100) 0%, #ffffff 100%);
--card-border: 1px solid var(--surface-border);
--card-bg: var(--surface-card);
--glow-image: url(https://www.primefaces.org/cdn/primevue/images/layout/pattern.png);
--glow-blend: hard-light, multiply;
--topbar-border: rgba(0,0,0,.05);
--mobile-menu-bg: var(--surface-overlay);
--demo-code-bg: var(--surface-700);
--demo-code-bg: var(--surface-800);
--demo-code-button-color: var(--surface-300);
--demo-code-button-hover-bg: rgba(255,255,255,.1);
--demo-code-button-hover-color: var(--surface-100);
--doc-highlight-text-bg: var(--primary-100);
--doc-highlight-text-color: var(--primary-900);
--doc-highlight-text-bg: var(--surface-200);
--doc-highlight-text-color: var(--surface-700);
}

View File

@ -1,5 +1,9 @@
<template>
<div v-if="!visible" class="demo-section-loading">Loading...</div>
<div v-if="!visible">
<div class="card">
<div class="deferred-demo-loading"></div>
</div>
</div>
<slot v-else></slot>
</template>
@ -42,14 +46,33 @@ export default {
};
</script>
<style>
.demo-section-loading {
display: grid;
place-items: center;
padding: 2rem;
.deferred-demo-loading {
border-radius: 10px;
margin-bottom: 1rem;
font-size: 2rem;
height: 350px;
background: var(--maskbg);
position: relative;
overflow: hidden;
}
.deferred-demo-loading::after {
content: '';
animation: deferred-demo-loading 1.2s infinite;
left: 0;
position: absolute;
right: 0;
top: 0;
height: 100%;
transform: translateX(-100%);
z-index: 1;
border-radius: 10px;
background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--surface-100), rgba(255, 255, 255, 0));
}
@keyframes deferred-demo-loading {
from {
transform: translateX(-100%);
}
to {
transform: translateX(100%);
}
}
</style>

View File

@ -18,16 +18,6 @@
</button>
</template>
<template v-if="!hideCodeSandbox">
<button v-tooltip.bottom="{ value: 'Edit in CodeSandbox', class: 'doc-section-code-tooltip' }" type="button" class="h-2rem w-2rem p-0 inline-flex align-items-center justify-content-center" @click="showCodesandbox">
<svg role="img" viewBox="0 0 24 24" width="16" height="16" fill="currentColor" style="display: 'block'">
<path
d="M2 6l10.455-6L22.91 6 23 17.95 12.455 24 2 18V6zm2.088 2.481v4.757l3.345 1.86v3.516l3.972 2.296v-8.272L4.088 8.481zm16.739 0l-7.317 4.157v8.272l3.972-2.296V15.1l3.345-1.861V8.48zM5.134 6.601l7.303 4.144 7.32-4.18-3.871-2.197-3.41 1.945-3.43-1.968L5.133 6.6z"
/>
</svg>
</button>
</template>
<template v-if="!hideStackBlitz">
<button v-tooltip.bottom="{ value: 'Edit in StackBlitz', class: 'doc-section-code-tooltip' }" type="button" class="h-2rem w-2rem p-0 inline-flex align-items-center justify-content-center" @click="showStackblitz">
<svg role="img" width="13" height="18" viewBox="0 0 13 19" fill="currentColor" xmlns="http://www.w3.org/2000/svg" style="display: 'block'">
@ -72,7 +62,7 @@
</template>
<script>
import { useCodeSandbox, useStackBlitz } from './codeeditor';
import { useStackBlitz } from './codeeditor';
export default {
inheritAttrs: false,
@ -91,7 +81,7 @@ export default {
},
hideCodeSandbox: {
type: Boolean,
default: false
default: true
},
hideStackBlitz: {
type: Boolean,
@ -142,9 +132,6 @@ export default {
async copyCode() {
await navigator.clipboard.writeText(this.code[this.codeLang]);
},
showCodesandbox() {
useCodeSandbox(this.codeLang, this.code[this.codeLang === 'data' ? 'options' : this.codeLang], this.service, this.code.pages, this.dependencies, this.component, this.extFiles);
},
showStackblitz() {
useStackBlitz(this.codeLang, this.code[this.codeLang === 'data' ? 'options' : this.codeLang], this.service, this.code.pages, this.dependencies, this.component, this.extFiles);
}

View File

@ -2,7 +2,7 @@ import pkg from '../../../package.json';
import { services } from './services';
const PrimeVue = {
version: '^3.45.0',
version: '^3.47.0',
description:
'PrimeVue is an open source UI library for Vue featuring a rich set of 80+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock, which has 400+ ready to use UI blocks to build spectacular applications in no time.'
};
@ -182,8 +182,11 @@ import Dropdown from 'primevue/dropdown';
import DynamicDialog from 'primevue/dynamicdialog';
import Fieldset from 'primevue/fieldset';
import FileUpload from 'primevue/fileupload';
import FloatLabel from 'primevue/floatlabel';
import FocusTrap from 'primevue/focustrap';
import Galleria from 'primevue/galleria';
import IconField from 'primevue/iconfield';
import InputIcon from 'primevue/inputicon';
import Image from 'primevue/image';
import InlineMessage from 'primevue/inlinemessage';
import Inplace from 'primevue/inplace';

View File

@ -6,7 +6,7 @@
<ul class="list-none p-0 m-0">
<li class="font-bold mb-5">General</li>
<li class="mb-4">
<PrimeVueNuxtLink to="/introduction" class="text-secondary font-medium hover:text-primary border-round transition-all transition-duration-300">Get Started</PrimeVueNuxtLink>
<PrimeVueNuxtLink to="/setup" class="text-secondary font-medium hover:text-primary border-round transition-all transition-duration-300">Get Started</PrimeVueNuxtLink>
</li>
<li class="mb-4">
<a href="https://github.com/primefaces/primevue-examples" class="text-secondary font-medium hover:text-primary border-round transition-all transition-duration-300" target="_blank" rel="noopener noreferrer">Examples</a>

View File

@ -7,15 +7,15 @@
target="_blank"
rel="noopener noreferrer"
style="border-radius: 50px"
class="bg-yellow-300 border-1 border-yellow-400 text-yellow-900 py-1 px-3 xl:align-self-start font-semibold text-lg transition-colors transition-duration-300 hover:border-yellow-600"
>🎉 Introducing the Tailwind CSS Presets <i class="pi pi-arrow-right text-sm"></i
class="bg-yellow-300 border-1 border-yellow-400 text-yellow-900 py-1 px-3 xl:align-self-start font-semibold transition-colors transition-duration-300 hover:border-yellow-600 text-base sm:text-lg"
>🎉 Introducing the Tailwind Presets <i class="pi pi-arrow-right text-sm"></i
></a>
<h1 class="text-6xl font-bold text-center xl:text-left">The Next-Gen UI Suite for <span class="font-bold text-primary">Vue.js</span></h1>
<p class="section-detail xl:text-left text-center px-0 mt-0 mb-5">
Elevate your web applications with PrimeVue's comprehensive suite of customizable, feature-rich UI components. With PrimeVue, turning your development vision into reality has never been easier.
</p>
<div class="flex align-items-center gap-3">
<PrimeVueNuxtLink to="/introduction" class="linkbox active font-semibold py-3 px-4">
<PrimeVueNuxtLink to="/setup" class="linkbox active font-semibold py-3 px-4">
<span>Get Started</span>
<i class="pi pi-arrow-right ml-3"></i>
</PrimeVueNuxtLink>
@ -141,6 +141,12 @@
menuButton: {
width: 'auto',
root: 'p-2'
},
menu: {
root: {
style: 'width: 10rem; min-width: auto'
},
action: 'p-2'
}
}"
/>

View File

@ -3,14 +3,11 @@
<div class="section-header">Themes</div>
<p class="section-detail">Crafted on a design-agnostic infrastructure, choose from a vast amount of themes such as Material, Bootstrap, Tailwind, PrimeOne or develop your own.</p>
<div class="flex flex-wrap justify-content-center px-5">
<button type="button" :class="['font-medium linkbox mr-3 mt-4', { active: theme && theme.startsWith('lara') }]" @click="changeTheme('lara', 'green')">PrimeOne</button>
<button type="button" :class="['font-medium linkbox mr-3 mt-4', { active: theme && theme.startsWith('aura') }]" @click="changeTheme('aura', 'green')">PrimeOne</button>
<button type="button" :class="['font-medium linkbox mr-3 mt-4', { active: theme && theme.startsWith('md') }]" @click="changeTheme('md', 'indigo')">Material</button>
<button type="button" :class="['font-medium linkbox mr-3 mt-4', { active: theme && theme.startsWith('bootstrap4') }]" @click="changeTheme('bootstrap4', 'blue')">Bootstrap</button>
</div>
<div
class="themes-main flex mt-7 justify-content-center px-5 lg:px-8"
:style="{ backgroundImage: `url('https://primefaces.org/cdn/primevue/images/landing/wave-${$appState.darkTheme ? 'dark-alt-gray' : 'light-alt-gray'}.svg')`, backgroundSize: 'cover' }"
>
<div class="themes-main flex mt-7 justify-content-center px-5 lg:px-8">
<div class="box overflow-hidden z-1 p-5 table-container">
<DataTable
v-model:selection="selectedCustomers"
@ -29,10 +26,12 @@
<template #header>
<div class="flex flex-column sm:flex-row sm:justify-content-between sm:align-items-center">
<h5 class="m-0">Customers</h5>
<span class="p-input-icon-left mt-3 sm:mt-0 w-full sm:w-auto">
<i class="pi pi-search" />
<IconField iconPosition="left" class="mt-3 sm:mt-0 w-full sm:w-auto">
<InputIcon>
<i class="pi pi-search" />
</InputIcon>
<InputText v-model="filters['global'].value" placeholder="Search" class="w-full" />
</span>
</IconField>
</div>
</template>
<template #empty> No customers found. </template>

View File

@ -30,7 +30,7 @@ const FilterService = {
},
filters: {
startsWith(value, filter, filterLocale) {
if (filter === undefined || filter === null || filter.trim() === '') {
if (filter === undefined || filter === null || filter === '') {
return true;
}
@ -44,7 +44,7 @@ const FilterService = {
return stringValue.slice(0, filterValue.length) === filterValue;
},
contains(value, filter, filterLocale) {
if (filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) {
if (filter === undefined || filter === null || filter === '') {
return true;
}
@ -58,7 +58,7 @@ const FilterService = {
return stringValue.indexOf(filterValue) !== -1;
},
notContains(value, filter, filterLocale) {
if (filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) {
if (filter === undefined || filter === null || filter === '') {
return true;
}
@ -72,7 +72,7 @@ const FilterService = {
return stringValue.indexOf(filterValue) === -1;
},
endsWith(value, filter, filterLocale) {
if (filter === undefined || filter === null || filter.trim() === '') {
if (filter === undefined || filter === null || filter === '') {
return true;
}
@ -86,7 +86,7 @@ const FilterService = {
return stringValue.indexOf(filterValue, stringValue.length - filterValue.length) !== -1;
},
equals(value, filter, filterLocale) {
if (filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) {
if (filter === undefined || filter === null || filter === '') {
return true;
}
@ -98,7 +98,7 @@ const FilterService = {
else return ObjectUtils.removeAccents(value.toString()).toLocaleLowerCase(filterLocale) == ObjectUtils.removeAccents(filter.toString()).toLocaleLowerCase(filterLocale);
},
notEquals(value, filter, filterLocale) {
if (filter === undefined || filter === null || (typeof filter === 'string' && filter.trim() === '')) {
if (filter === undefined || filter === null || filter === '') {
return false;
}

View File

@ -350,11 +350,21 @@ export interface AutoCompleteProps {
* @defaultValue false
*/
loading?: boolean | undefined;
/**
* When present, it specifies that the component should have invalid state style.
* @defaultValue false
*/
invalid?: boolean | undefined;
/**
* When present, it specifies that the component should be disabled.
* @defaultValue false
*/
disabled?: boolean | undefined;
/**
* Specifies the input variant of the component.
* @defaultValue outlined
*/
variant?: 'outlined' | 'filled' | undefined;
/**
* A property to uniquely identify an option.
*/
@ -439,7 +449,7 @@ export interface AutoCompleteProps {
virtualScrollerOptions?: VirtualScrollerProps;
/**
* Whether to focus on the first visible or selected element when the overlay panel is shown.
* @defaultValue true
* @defaultValue false
*/
autoOptionFocus?: boolean | undefined;
/**
@ -447,6 +457,11 @@ export interface AutoCompleteProps {
* @defaultValue false
*/
selectOnFocus?: boolean | undefined;
/**
* When enabled, the focus is placed on the hovered option.
* @defaultValue true
*/
focusOnHover?: boolean | undefined;
/**
* Locale to use in searching. The default locale is the host environment's current locale.
*/

View File

@ -1,5 +1,5 @@
<template>
<div ref="container" :class="cx('root')" :style="sx('root')" @click="onContainerClick" v-bind="ptm('root')" data-pc-name="autocomplete">
<div ref="container" :class="cx('root')" :style="sx('root')" @click="onContainerClick" v-bind="ptm('root')">
<input
v-if="!multiple"
ref="focusInput"
@ -91,19 +91,7 @@
<i v-if="loadingIcon" :class="['pi-spin', cx('loadingIcon'), loadingIcon]" aria-hidden="true" v-bind="ptm('loadingIcon')" />
<SpinnerIcon v-else :class="[cx('loadingIcon'), loadingIcon]" spin aria-hidden="true" v-bind="ptm('loadingIcon')" />
</slot>
<Button
v-if="dropdown"
ref="dropdownButton"
type="button"
tabindex="-1"
:class="[cx('dropdownButton'), dropdownClass]"
:disabled="disabled"
aria-hidden="true"
@click="onDropdownClick"
:unstyled="unstyled"
:pt="ptm('dropdownButton')"
data-pc-section="dropdownbutton"
>
<Button v-if="dropdown" ref="dropdownButton" type="button" tabindex="-1" :class="[cx('dropdownButton'), dropdownClass]" :disabled="disabled" aria-hidden="true" @click="onDropdownClick" :unstyled="unstyled" :pt="ptm('dropdownButton')">
<template #icon>
<slot name="dropdownicon" :class="dropdownIcon">
<component :is="dropdownIcon ? 'span' : 'ChevronDownIcon'" :class="dropdownIcon" v-bind="ptm('dropdownButton')['icon']" data-pc-section="dropdownicon" />
@ -197,11 +185,11 @@ export default {
overlay: null,
virtualScroller: null,
searchTimeout: null,
focusOnHover: false,
dirty: false,
data() {
return {
id: this.$attrs.id,
clicked: false,
focused: false,
focusedOptionIndex: -1,
focusedMultipleOptionIndex: -1,
@ -225,7 +213,6 @@ export default {
},
mounted() {
this.id = this.id || UniqueComponentId();
this.autoUpdateModel();
},
updated() {
@ -297,6 +284,7 @@ export default {
this.$emit('before-hide');
this.dirty = isFocus;
this.overlayVisible = false;
this.clicked = false;
this.focusedOptionIndex = -1;
isFocus && DomHandler.focus(this.$refs.focusInput);
@ -318,8 +306,12 @@ export default {
this.dirty = true;
this.focused = true;
this.focusedOptionIndex = this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : this.overlayVisible && this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
this.overlayVisible && this.scrollInView(this.focusedOptionIndex);
if (this.overlayVisible) {
this.focusedOptionIndex = this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : this.overlayVisible && this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
this.scrollInView(this.focusedOptionIndex);
}
this.$emit('focus', event);
},
onBlur(event) {
@ -393,6 +385,8 @@ export default {
default:
break;
}
this.clicked = false;
},
onInput(event) {
if (this.searchTimeout) {
@ -478,6 +472,8 @@ export default {
}
},
onContainerClick(event) {
this.clicked = true;
if (this.disabled || this.searching || this.loading || this.isInputClicked(event) || this.isDropdownClicked(event)) {
return;
}
@ -544,7 +540,7 @@ export default {
return;
}
const optionIndex = this.focusedOptionIndex !== -1 ? this.findNextOptionIndex(this.focusedOptionIndex) : this.findFirstFocusedOptionIndex();
const optionIndex = this.focusedOptionIndex !== -1 ? this.findNextOptionIndex(this.focusedOptionIndex) : this.clicked ? this.findFirstOptionIndex() : this.findFirstFocusedOptionIndex();
this.changeFocusedOptionIndex(event, optionIndex);
@ -563,7 +559,7 @@ export default {
this.overlayVisible && this.hide();
event.preventDefault();
} else {
const optionIndex = this.focusedOptionIndex !== -1 ? this.findPrevOptionIndex(this.focusedOptionIndex) : this.findLastFocusedOptionIndex();
const optionIndex = this.focusedOptionIndex !== -1 ? this.findPrevOptionIndex(this.focusedOptionIndex) : this.clicked ? this.findLastOptionIndex() : this.findLastFocusedOptionIndex();
this.changeFocusedOptionIndex(event, optionIndex);
@ -617,6 +613,7 @@ export default {
},
onEnterKey(event) {
if (!this.overlayVisible) {
this.focusedOptionIndex = -1; // reset
this.onArrowDownKey(event);
} else {
if (this.focusedOptionIndex !== -1) {
@ -763,7 +760,7 @@ export default {
return this.$refs.dropdownButton ? event.target === this.$refs.dropdownButton || this.$refs.dropdownButton.$el.contains(event.target) : false;
},
isOptionMatched(option, value) {
return this.isValidOption(option) && this.getOptionLabel(option).toLocaleLowerCase(this.searchLocale) === value.toLocaleLowerCase(this.searchLocale);
return this.isValidOption(option) && this.getOptionLabel(option)?.toLocaleLowerCase(this.searchLocale) === value.toLocaleLowerCase(this.searchLocale);
},
isValidOption(option) {
return ObjectUtils.isNotEmpty(option) && !(this.isOptionDisabled(option) || this.isOptionGroup(option));
@ -837,16 +834,16 @@ export default {
}
},
scrollInView(index = -1) {
const id = index !== -1 ? `${this.id}_${index}` : this.focusedOptionId;
const element = DomHandler.findSingle(this.list, `li[id="${id}"]`);
this.$nextTick(() => {
const id = index !== -1 ? `${this.id}_${index}` : this.focusedOptionId;
const element = DomHandler.findSingle(this.list, `li[id="${id}"]`);
if (element) {
element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' });
} else if (!this.virtualScrollerDisabled) {
setTimeout(() => {
if (element) {
element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' });
} else if (!this.virtualScrollerDisabled) {
this.virtualScroller && this.virtualScroller.scrollToIndex(index !== -1 ? index : this.focusedOptionIndex);
}, 0);
}
}
});
},
autoUpdateModel() {
if ((this.selectOnFocus || this.autoHighlight) && this.autoOptionFocus && !this.hasSelectedOption) {

View File

@ -45,6 +45,14 @@ export default {
type: Boolean,
default: false
},
variant: {
type: String,
default: null
},
invalid: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
@ -66,7 +74,7 @@ export default {
default: 300
},
appendTo: {
type: String,
type: [String, Object],
default: 'body'
},
forceSelection: {
@ -127,12 +135,16 @@ export default {
},
autoOptionFocus: {
type: Boolean,
default: true
default: false
},
selectOnFocus: {
type: Boolean,
default: false
},
focusOnHover: {
type: Boolean,
default: true
},
searchLocale: {
type: String,
default: undefined

View File

@ -110,6 +110,7 @@ const classes = {
'p-autocomplete p-component p-inputwrapper',
{
'p-disabled': props.disabled,
'p-invalid': props.invalid,
'p-focus': instance.focused,
'p-autocomplete-dd': props.dropdown,
'p-autocomplete-multiple': props.multiple,
@ -118,18 +119,28 @@ const classes = {
'p-overlay-open': instance.overlayVisible
}
],
input: ({ props }) => ['p-autocomplete-input p-inputtext p-component', { 'p-autocomplete-dd-input': props.dropdown }],
container: 'p-autocomplete-multiple-container p-component p-inputtext',
input: ({ props, instance }) => [
'p-autocomplete-input p-inputtext p-component',
{
'p-autocomplete-dd-input': props.dropdown,
'p-variant-filled': props.variant ? props.variant === 'filled' : instance.$primevue.config.inputStyle === 'filled'
}
],
container: ({ props, instance }) => [
'p-autocomplete-multiple-container p-component p-inputtext',
{
'p-variant-filled': props.variant ? props.variant === 'filled' : instance.$primevue.config.inputStyle === 'filled'
}
],
token: ({ instance, i }) => ['p-autocomplete-token', { 'p-focus': instance.focusedMultipleOptionIndex === i }],
tokenLabel: 'p-autocomplete-token-label',
removeTokenIcon: 'p-autocomplete-token-icon',
inputToken: 'p-autocomplete-input-token',
loadingIcon: 'p-autocomplete-loader',
dropdownButton: 'p-autocomplete-dropdown',
panel: ({ instance }) => [
panel: ({ props, instance }) => [
'p-autocomplete-panel p-component',
{
'p-input-filled': instance.$primevue.config.inputStyle === 'filled',
'p-ripple-disabled': instance.$primevue.config.ripple === false
}
],

View File

@ -1,5 +1,5 @@
<template>
<div :class="cx('root')" :aria-labelledby="ariaLabelledby" :aria-label="ariaLabel" v-bind="ptm('root')" data-pc-name="avatar">
<div :class="cx('root')" :aria-labelledby="ariaLabelledby" :aria-label="ariaLabel" v-bind="ptm('root')">
<slot>
<span v-if="label" :class="cx('label')" v-bind="ptm('label')">{{ label }}</span>
<component v-else-if="$slots.icon" :is="$slots.icon" :class="cx('icon')" />

View File

@ -1,5 +1,5 @@
<template>
<div :class="cx('root')" v-bind="ptm('root')" data-pc-name="avatargroup">
<div :class="cx('root')" v-bind="ptm('root')">
<slot></slot>
</div>
</template>

View File

@ -70,7 +70,7 @@ export interface BadgeProps {
/**
* Severity type of the badge.
*/
severity?: 'info' | 'success' | 'warning' | 'danger' | string | null | undefined;
severity?: 'secondary' | 'info' | 'success' | 'warning' | 'danger' | 'contrast' | string | null | undefined;
/**
* Size of the badge, valid options are 'large' and 'xlarge'.
*/

View File

@ -1,5 +1,5 @@
<template>
<span :class="cx('root')" v-bind="ptm('root')" data-pc-name="badge">
<span :class="cx('root')" v-bind="ptm('root')">
<slot>{{ value }}</slot>
</span>
</template>

View File

@ -49,7 +49,9 @@ const classes = {
'p-badge-info': props.severity === 'info',
'p-badge-success': props.severity === 'success',
'p-badge-warning': props.severity === 'warning',
'p-badge-danger': props.severity === 'danger'
'p-badge-danger': props.severity === 'danger',
'p-badge-secondary': props.severity === 'secondary',
'p-badge-contrast': props.severity === 'contrast'
}
]
};

View File

@ -101,6 +101,9 @@ export default {
defaultHook?.();
}
},
_mergeProps(fn, ...args) {
return ObjectUtils.isFunction(fn) ? fn(...args) : mergeProps(...args);
},
_loadGlobalStyles() {
/*
* @todo Add self custom css support;
@ -146,17 +149,27 @@ export default {
: ObjectUtils.getItemValue(options, params);
},
_getPTValue(obj = {}, key = '', params = {}, searchInDefaultPT = true) {
const datasetPrefix = 'data-pc-';
const searchOut = /./g.test(key) && !!params[key.split('.')[0]];
const { mergeSections = true, mergeProps: useMergeProps = false } = this._getPropValue('ptOptions') || this.$config?.ptOptions || {};
const global = searchInDefaultPT ? (searchOut ? this._useGlobalPT(this._getPTClassValue, key, params) : this._useDefaultPT(this._getPTClassValue, key, params)) : undefined;
const self = searchOut ? undefined : this._usePT(this._getPT(obj, this.$name), this._getPTClassValue, key, { ...params, global: global || {} });
const datasets = key !== 'transition' && {
...(key === 'root' && { [`${datasetPrefix}name`]: ObjectUtils.toFlatCase(this.$.type.name) }),
[`${datasetPrefix}section`]: ObjectUtils.toFlatCase(key)
};
const datasets = this._getPTDatasets(key);
return mergeSections || (!mergeSections && self) ? (useMergeProps ? mergeProps(global, self, datasets) : { ...global, ...self, ...datasets }) : { ...self, ...datasets };
return mergeSections || (!mergeSections && self) ? (useMergeProps ? this._mergeProps(useMergeProps, global, self, datasets) : { ...global, ...self, ...datasets }) : { ...self, ...datasets };
},
_getPTDatasets(key = '') {
const datasetPrefix = 'data-pc-';
const isExtended = key === 'root' && ObjectUtils.isNotEmpty(this.pt?.['data-pc-section']);
return (
key !== 'transition' && {
...(key === 'root' && {
[`${datasetPrefix}name`]: ObjectUtils.toFlatCase(isExtended ? this.pt?.['data-pc-section'] : this.$.type.name),
...(isExtended && { [`${datasetPrefix}extend`]: ObjectUtils.toFlatCase(this.$.type.name) })
}),
[`${datasetPrefix}section`]: ObjectUtils.toFlatCase(key)
}
);
},
_getPTClassValue(...args) {
const value = this._getOptionValue(...args);
@ -192,7 +205,7 @@ export default {
else if (ObjectUtils.isString(value)) return value;
else if (ObjectUtils.isString(originalValue)) return originalValue;
return mergeSections || (!mergeSections && value) ? (useMergeProps ? mergeProps(originalValue, value) : { ...originalValue, ...value }) : value;
return mergeSections || (!mergeSections && value) ? (useMergeProps ? this._mergeProps(useMergeProps, originalValue, value) : { ...originalValue, ...value }) : value;
}
return fn(pt);

View File

@ -71,161 +71,17 @@ const buttonCSS = `
}
`;
const checkboxCSS = `
.p-checkbox {
display: inline-flex;
cursor: pointer;
user-select: none;
vertical-align: bottom;
position: relative;
}
.p-checkbox.p-checkbox-disabled {
cursor: default;
}
.p-checkbox-box {
display: flex;
justify-content: center;
align-items: center;
}
`;
const inputTextCSS = `
.p-fluid .p-inputtext {
width: 100%;
}
/* InputGroup */
.p-inputgroup {
display: flex;
align-items: stretch;
width: 100%;
}
.p-inputgroup-addon {
display: flex;
align-items: center;
justify-content: center;
}
.p-inputgroup .p-float-label {
display: flex;
align-items: stretch;
width: 100%;
}
.p-inputgroup .p-inputtext,
.p-fluid .p-inputgroup .p-inputtext,
.p-inputgroup .p-inputwrapper,
.p-fluid .p-inputgroup .p-input {
flex: 1 1 auto;
width: 1%;
}
/* Floating Label */
.p-float-label {
display: block;
position: relative;
}
.p-float-label label {
position: absolute;
pointer-events: none;
top: 50%;
margin-top: -.5rem;
transition-property: all;
transition-timing-function: ease;
line-height: 1;
}
.p-float-label textarea ~ label {
top: 1rem;
}
.p-float-label input:focus ~ label,
.p-float-label input.p-filled ~ label,
.p-float-label input:-webkit-autofill ~ label,
.p-float-label textarea:focus ~ label,
.p-float-label textarea.p-filled ~ label,
.p-float-label .p-inputwrapper-focus ~ label,
.p-float-label .p-inputwrapper-filled ~ label {
top: -.75rem;
font-size: 12px;
}
.p-float-label .p-placeholder,
.p-float-label input::placeholder,
.p-float-label .p-inputtext::placeholder {
opacity: 0;
transition-property: all;
transition-timing-function: ease;
}
.p-float-label .p-focus .p-placeholder,
.p-float-label input:focus::placeholder,
.p-float-label .p-inputtext:focus::placeholder {
opacity: 1;
transition-property: all;
transition-timing-function: ease;
}
.p-input-icon-left,
.p-input-icon-right {
position: relative;
display: inline-block;
}
.p-input-icon-left > i,
.p-input-icon-left > svg,
.p-input-icon-right > i,
.p-input-icon-right > svg {
position: absolute;
top: 50%;
margin-top: -.5rem;
}
.p-fluid .p-input-icon-left,
.p-fluid .p-input-icon-right {
display: block;
width: 100%;
}
`;
const radioButtonCSS = `
.p-radiobutton {
position: relative;
display: inline-flex;
cursor: pointer;
user-select: none;
vertical-align: bottom;
}
.p-radiobutton.p-radiobutton-disabled {
cursor: default;
}
.p-radiobutton-box {
display: flex;
justify-content: center;
align-items: center;
}
.p-radiobutton-icon {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
transform: translateZ(0) scale(.1);
border-radius: 50%;
visibility: hidden;
}
.p-radiobutton-box.p-highlight .p-radiobutton-icon {
transform: translateZ(0) scale(1.0, 1.0);
visibility: visible;
}
`;
const css = `
@layer primevue {
.p-component, .p-component * {
@ -348,9 +204,7 @@ const css = `
transition: max-height 1s ease-in-out;
}
${buttonCSS}
${checkboxCSS}
${inputTextCSS}
${radioButtonCSS}
}
`;

View File

@ -22,16 +22,20 @@ const BaseDirective = {
return ObjectUtils.isString(value) || ObjectUtils.isArray(value) ? { class: value } : value;
};
const datasetPrefix = 'data-pc-';
const { mergeSections = true, mergeProps: useMergeProps = false } = instance.binding?.value?.ptOptions || instance.$config?.ptOptions || {};
const global = searchInDefaultPT ? BaseDirective._useDefaultPT(instance, instance.defaultPT(), getValue, key, params) : undefined;
const self = BaseDirective._usePT(instance, BaseDirective._getPT(obj, instance.$name), getValue, key, { ...params, global: global || {} });
const datasets = {
const datasets = BaseDirective._getPTDatasets(instance, key);
return mergeSections || (!mergeSections && self) ? (useMergeProps ? BaseDirective._mergeProps(instance, useMergeProps, global, self, datasets) : { ...global, ...self, ...datasets }) : { ...self, ...datasets };
},
_getPTDatasets(instance = {}, key = '') {
const datasetPrefix = 'data-pc-';
return {
...(key === 'root' && { [`${datasetPrefix}name`]: ObjectUtils.toFlatCase(instance.$name) }),
[`${datasetPrefix}section`]: ObjectUtils.toFlatCase(key)
};
return mergeSections || (!mergeSections && self) ? (useMergeProps ? mergeProps(global, self, datasets) : { ...global, ...self, ...datasets }) : { ...self, ...datasets };
},
_getPT: (pt, key = '', callback) => {
const getValue = (value) => {
@ -61,7 +65,7 @@ const BaseDirective = {
else if (ObjectUtils.isString(value)) return value;
else if (ObjectUtils.isString(originalValue)) return originalValue;
return mergeSections || (!mergeSections && value) ? (useMergeProps ? mergeProps(originalValue, value) : { ...originalValue, ...value }) : value;
return mergeSections || (!mergeSections && value) ? (useMergeProps ? BaseDirective._mergeProps(instance, useMergeProps, originalValue, value) : { ...originalValue, ...value }) : value;
}
return fn(pt);
@ -80,6 +84,9 @@ const BaseDirective = {
selfHook?.(instance, options);
defaultHook?.(instance, options);
},
_mergeProps(instance = {}, fn, ...args) {
return ObjectUtils.isFunction(fn) ? fn(...args) : mergeProps(...args);
},
_extend: (name, options = {}) => {
const handleHook = (hook, el, binding, vnode, prevVnode) => {
el._$instances = el._$instances || {};
@ -112,6 +119,7 @@ const BaseDirective = {
el.$instance = el._$instances[name]; // pass instance data to hooks
el.$instance[hook]?.(el, binding, vnode, prevVnode); // handle hook in directive implementation
el[`$${name}`] = el.$instance; // expose all options with $<directive_name>
BaseDirective._hook(name, hook, el, binding, vnode, prevVnode); // handle hooks during directive uses (global and self-definition)
};
@ -122,11 +130,15 @@ const BaseDirective = {
beforeMount: (el, binding, vnode, prevVnode) => {
const config = BaseDirective._getConfig(binding, vnode);
BaseStyle.loadStyle(undefined, { nonce: config?.csp?.nonce });
!el.$instance?.isUnstyled() && el.$instance?.$style?.loadStyle(undefined, { nonce: config?.csp?.nonce });
BaseStyle.loadStyle({ nonce: config?.csp?.nonce });
!el.$instance?.isUnstyled() && el.$instance?.$style?.loadStyle({ nonce: config?.csp?.nonce });
handleHook('beforeMount', el, binding, vnode, prevVnode);
},
mounted: (el, binding, vnode, prevVnode) => {
const config = BaseDirective._getConfig(binding, vnode);
BaseStyle.loadStyle({ nonce: config?.csp?.nonce });
!el.$instance?.isUnstyled() && el.$instance?.$style?.loadStyle({ nonce: config?.csp?.nonce });
handleHook('mounted', el, binding, vnode, prevVnode);
},
beforeUpdate: (el, binding, vnode, prevVnode) => {

View File

@ -37,7 +37,6 @@ export default {
styleClass += ' p-blockui-document';
this.mask = DomHandler.createElement('div', {
'data-pc-section': 'mask',
style: {
position: 'fixed',
top: '0',
@ -54,7 +53,6 @@ export default {
document.activeElement.blur();
} else {
this.mask = DomHandler.createElement('div', {
'data-pc-section': 'mask',
style: {
position: 'absolute',
top: '0',

View File

@ -1,5 +1,5 @@
<template>
<nav :class="cx('root')" v-bind="ptm('root')" data-pc-name="breadcrumb">
<nav :class="cx('root')" v-bind="ptm('root')">
<ol :class="cx('menu')" v-bind="ptm('menu')">
<BreadcrumbItem v-if="home" :item="home" :class="cx('home')" :templates="$slots" :pt="pt" :unstyled="unstyled" v-bind="ptm('home')" />
<template v-for="(item, i) of model" :key="item.label + '_' + i">

View File

@ -119,7 +119,7 @@ export interface ButtonProps extends ButtonHTMLAttributes {
/**
* Severity type of the badge.
*/
badgeSeverity?: 'info' | 'success' | 'warning' | 'danger' | string | null | undefined;
badgeSeverity?: 'secondary' | 'info' | 'success' | 'warning' | 'danger' | 'contrast' | string | null | undefined;
/**
* Whether the button is in loading state.
* @defaultValue false
@ -137,7 +137,7 @@ export interface ButtonProps extends ButtonHTMLAttributes {
/**
* Defines the style of the button.
*/
severity?: 'secondary' | 'success' | 'info' | 'warning' | 'help' | 'danger' | string | undefined;
severity?: 'secondary' | 'success' | 'info' | 'warning' | 'help' | 'danger' | 'contrast' | string | undefined;
/**
* Add a shadow to indicate elevation.
* @defaultValue false

View File

@ -1,5 +1,5 @@
<template>
<button v-ripple :class="cx('root')" type="button" :aria-label="defaultAriaLabel" :disabled="disabled" v-bind="getPTOptions('root')" data-pc-name="button" :data-pc-severity="severity">
<button v-ripple :class="cx('root')" type="button" :aria-label="defaultAriaLabel" :disabled="disabled" v-bind="getPTOptions('root')" :data-pc-severity="severity">
<slot>
<slot v-if="loading" name="loadingicon" :class="[cx('loadingIcon'), cx('icon')]">
<span v-if="loadingIcon" :class="[cx('loadingIcon'), cx('icon'), loadingIcon]" v-bind="ptm('loadingIcon')" />

View File

@ -173,9 +173,17 @@ export default {
default: true
},
appendTo: {
type: String,
type: [String, Object],
default: 'body'
},
variant: {
type: String,
default: null
},
invalid: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false

View File

@ -398,6 +398,32 @@ export interface CalendarState {
currentView: string;
}
/**
* Defines current date options in Calendar component.
*/
export interface CalendarDateContext {
/**
* Current date.
*/
day: number;
/**
* Current month state.
*/
month: number;
/**
* Current year state.
*/
year: number;
/**
* Current today state of the calendar's day.
*/
today: boolean;
/**
* Selectable state of the day.
*/
selectable: boolean;
}
/**
* Defines current options in Calendar component.
*/
@ -405,7 +431,7 @@ export interface CalendarContext {
/**
* Current date.
*/
date: string | Date | string[] | Date[] | undefined | null;
date: CalendarDateContext;
/**
* Current today state of the calendar's day.
* @defaultValue false
@ -685,11 +711,21 @@ export interface CalendarProps {
* @defaultValue true
*/
manualInput?: boolean | undefined;
/**
* When present, it specifies that the component should have invalid state style.
* @defaultValue false
*/
invalid?: boolean | undefined;
/**
* When present, it specifies that the component should be disabled.
* @defaultValue false
*/
disabled?: boolean | undefined;
/**
* Specifies the input variant of the component.
* @defaultValue outlined
*/
variant?: 'outlined' | 'filled' | undefined;
/**
* When present, it specifies that an input field is read-only.
* @defaultValue false
@ -760,6 +796,31 @@ export interface CalendarProps {
*/
unstyled?: boolean;
}
/**
* Defines valid options of the date slot in Calendar component.
*/
export interface CalendarDateSlotOptions {
/**
* Current date.
*/
day: number;
/**
* Current month state.
*/
month: number;
/**
* Current year state.
*/
year: number;
/**
* Current today state of the calendar's day.
*/
today: boolean;
/**
* Selectable state of the day.
*/
selectable: boolean;
}
/**
* Defines valid slots in Calendar component.
@ -780,7 +841,7 @@ export interface CalendarSlots {
/**
* Value of the component.
*/
date: { day: number; month: number; year: number; today: boolean; selectable: boolean };
date: CalendarDateSlotOptions;
}): VNode[];
/**
* Custom decade template.

View File

@ -1,5 +1,5 @@
<template>
<span ref="container" :id="id" :class="cx('root')" :style="sx('root')" v-bind="ptm('root')" data-pc-name="calendar">
<span ref="container" :id="d_id" :class="cx('root')" :style="sx('root')" v-bind="ptm('root')">
<input
v-if="!inline"
:ref="inputRef"
@ -39,7 +39,6 @@
:aria-controls="panelId"
:unstyled="unstyled"
:pt="ptm('dropdownButton')"
data-pc-section="dropdownbutton"
>
<template #icon>
<slot name="dropdownicon" :class="icon">
@ -486,7 +485,6 @@
@keydown="onContainerButtonKeydown"
:unstyled="unstyled"
:pt="ptm('todayButton')"
data-pc-section="todaybutton"
data-pc-group-section="button"
/>
<CalendarButton
@ -497,7 +495,6 @@
@keydown="onContainerButtonKeydown"
:unstyled="unstyled"
:pt="ptm('clearButton')"
data-pc-section="clearbutton"
data-pc-group-section="button"
/>
</div>
@ -542,6 +539,7 @@ export default {
typeUpdate: false,
data() {
return {
d_id: this.id,
currentMonth: null,
currentYear: null,
currentHour: null,
@ -556,6 +554,9 @@ export default {
};
},
watch: {
id: function (newValue) {
this.d_id = newValue || UniqueComponentId();
},
modelValue(newValue) {
this.updateCurrentMetaData();
@ -595,12 +596,16 @@ export default {
},
currentView() {
Promise.resolve(null).then(() => this.alignOverlay());
},
view(newValue) {
this.currentView = newValue;
}
},
created() {
this.updateCurrentMetaData();
},
mounted() {
this.d_id = this.d_id || UniqueComponentId();
this.createResponsiveStyle();
this.bindMatchMediaListener();
@ -1155,8 +1160,9 @@ export default {
let date = new Date(dateMeta.year, dateMeta.month, dateMeta.day);
if (this.showTime) {
if (this.hourFormat === '12' && this.pm && this.currentHour != 12) date.setHours(this.currentHour + 12);
else date.setHours(this.currentHour);
if (this.hourFormat === '12' && this.currentHour !== 12) {
this.pm ? date.setHours(this.currentHour + 12) : date.setHours(this.currentHour);
}
date.setMinutes(this.currentMinute);
date.setSeconds(this.currentSecond);
@ -1690,7 +1696,6 @@ export default {
let styleClass = 'p-datepicker-mask p-datepicker-mask-scrollblocker p-component-overlay p-component-overlay-enter';
this.mask = DomHandler.createElement('div', {
'data-pc-section': 'datepickermask',
class: !this.isUnstyled && styleClass,
'p-bind': this.ptm('datepickermask')
});
@ -2665,6 +2670,18 @@ export default {
if (this.overlayVisible) {
this.overlayVisible = false;
}
} else if (event.code === 'Enter') {
if (this.manualInput && event.target.value !== null && event.target.value?.trim() !== '') {
try {
let value = this.parseValue(event.target.value);
if (this.isValidSelection(value)) {
this.overlayVisible = false;
}
} catch (err) {
/* NoOp */
}
}
}
},
overlayRef(el) {
@ -2989,7 +3006,7 @@ export default {
return this.numberOfMonths > 1 || this.disabled;
},
panelId() {
return UniqueComponentId() + '_panel';
return this.d_id + '_panel';
}
},
components: {

View File

@ -166,12 +166,18 @@ const classes = {
'p-input-icon-right': props.showIcon && props.iconDisplay === 'input',
'p-calendar-timeonly': props.timeOnly,
'p-calendar-disabled': props.disabled,
'p-invalid': props.invalid,
'p-inputwrapper-filled': props.modelValue,
'p-inputwrapper-focus': state.focused,
'p-focus': state.focused || state.overlayVisible
}
],
input: 'p-inputtext p-component',
input: ({ props, instance }) => [
'p-inputtext p-component',
{
'p-variant-filled': props.variant ? props.variant === 'filled' : instance.$primevue.config.inputStyle === 'filled'
}
],
dropdownButton: 'p-datepicker-trigger',
inputIcon: 'p-datepicker-trigger-icon',
panel: ({ instance, props, state }) => [
@ -185,7 +191,6 @@ const classes = {
'p-datepicker-monthpicker': state.currentView === 'month',
'p-datepicker-yearpicker': state.currentView === 'year',
'p-datepicker-touch-ui': props.touchUI,
'p-input-filled': instance.$primevue.config.inputStyle === 'filled',
'p-ripple-disabled': instance.$primevue.config.ripple === false
}
],

View File

@ -1,5 +1,5 @@
<template>
<div :class="cx('root')" v-bind="ptm('root')" data-pc-name="card">
<div :class="cx('root')" v-bind="ptm('root')">
<div v-if="$slots.header" :class="cx('header')" v-bind="ptm('header')">
<slot name="header"></slot>
</div>

View File

@ -14,6 +14,14 @@ export default {
optionGroupLabel: null,
optionGroupChildren: null,
placeholder: String,
variant: {
type: String,
default: null
},
invalid: {
type: Boolean,
default: false
},
disabled: Boolean,
dataKey: null,
inputId: {
@ -45,7 +53,7 @@ export default {
default: null
},
appendTo: {
type: String,
type: [String, Object],
default: 'body'
},
loading: {
@ -66,12 +74,16 @@ export default {
},
autoOptionFocus: {
type: Boolean,
default: true
default: false
},
selectOnFocus: {
type: Boolean,
default: false
},
focusOnHover: {
type: Boolean,
default: true
},
searchLocale: {
type: String,
default: undefined

View File

@ -271,11 +271,21 @@ export interface CascadeSelectProps {
* Default text to display when no option is selected.
*/
placeholder?: string | undefined;
/**
* When present, it specifies that the component should have invalid state style.
* @defaultValue false
*/
invalid?: boolean | undefined;
/**
* When present, it specifies that the component should be disabled.
* @defaultValue false
*/
disabled?: boolean | undefined;
/**
* Specifies the input variant of the component.
* @defaultValue outlined
*/
variant?: 'outlined' | 'filled' | undefined;
/**
* A property to uniquely identify an option.
*/
@ -335,7 +345,7 @@ export interface CascadeSelectProps {
optionGroupIcon?: string | undefined;
/**
* Whether to focus on the first visible or selected element when the overlay panel is shown.
* @defaultValue true
* @defaultValue false
*/
autoOptionFocus?: boolean | undefined;
/**
@ -343,6 +353,11 @@ export interface CascadeSelectProps {
* @defaultValue false
*/
selectOnFocus?: boolean | undefined;
/**
* When enabled, the focus is placed on the hovered option.
* @defaultValue true
*/
focusOnHover?: boolean | undefined;
/**
* Locale to use in searching. The default locale is the host environment's current locale.
*/

View File

@ -1,5 +1,5 @@
<template>
<div ref="container" :class="cx('root')" :style="sx('root')" @click="onContainerClick($event)" v-bind="ptm('root')" data-pc-name="cascadeselect">
<div ref="container" :class="cx('root')" :style="sx('root')" @click="onContainerClick($event)" v-bind="ptm('root')">
<div class="p-hidden-accessible" v-bind="ptm('hiddenInputWrapper')" :data-p-hidden-accessible="true">
<input
ref="focusInput"
@ -62,6 +62,7 @@
:optionGroupLabel="optionGroupLabel"
:optionGroupChildren="optionGroupChildren"
@option-change="onOptionChange"
@option-focus-change="onOptionFocusChange"
:pt="pt"
:unstyled="unstyled"
/>
@ -95,10 +96,10 @@ export default {
overlay: null,
searchTimeout: null,
searchValue: null,
focusOnHover: false,
data() {
return {
id: this.$attrs.id,
clicked: false,
focused: false,
focusedOptionInfo: { index: -1, level: 0, parentKey: '' },
activeOptionPath: [],
@ -116,7 +117,6 @@ export default {
},
mounted() {
this.id = this.id || UniqueComponentId();
this.autoUpdateModel();
},
beforeUnmount() {
@ -152,13 +152,13 @@ export default {
isOptionGroup(option, level) {
return Object.prototype.hasOwnProperty.call(option, this.optionGroupChildren[level]);
},
getProccessedOptionLabel(processedOption) {
getProccessedOptionLabel(processedOption = {}) {
const grouped = this.isProccessedOptionGroup(processedOption);
return grouped ? this.getOptionGroupLabel(processedOption.option, processedOption.level) : this.getOptionLabel(processedOption.option);
},
isProccessedOptionGroup(processedOption) {
return ObjectUtils.isNotEmpty(processedOption.children);
return ObjectUtils.isNotEmpty(processedOption?.children);
},
show(isFocus) {
this.$emit('before-show');
@ -168,9 +168,9 @@ export default {
if (this.hasSelectedOption && ObjectUtils.isNotEmpty(this.activeOptionPath)) {
const processedOption = this.activeOptionPath[this.activeOptionPath.length - 1];
this.focusedOptionInfo = { index: this.autoOptionFocus ? processedOption.index : -1, level: processedOption.level, parentKey: processedOption.parentKey };
this.focusedOptionInfo = { index: processedOption.index, level: processedOption.level, parentKey: processedOption.parentKey };
} else {
this.focusedOptionInfo = { index: this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1, level: 0, parentKey: '' };
this.focusedOptionInfo = { index: this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : this.findSelectedOptionIndex(), level: 0, parentKey: '' };
}
isFocus && DomHandler.focus(this.$refs.focusInput);
@ -179,6 +179,7 @@ export default {
const _hide = () => {
this.$emit('before-hide');
this.overlayVisible = false;
this.clicked = false;
this.activeOptionPath = [];
this.focusedOptionInfo = { index: -1, level: 0, parentKey: '' };
@ -271,6 +272,8 @@ export default {
break;
}
this.clicked = false;
},
onOptionChange(event) {
const { originalEvent, processedOption, isFocus, isHide } = event;
@ -290,8 +293,17 @@ export default {
grouped ? this.onOptionGroupSelect(originalEvent, processedOption) : this.onOptionSelect(originalEvent, processedOption, isHide);
isFocus && DomHandler.focus(this.$refs.focusInput);
},
onOptionFocusChange(event) {
if (this.focusOnHover) {
const { originalEvent, processedOption } = event;
const { index, level, parentKey } = processedOption;
this.focusedOptionInfo = { index, level, parentKey };
this.changeFocusedOptionIndex(originalEvent, index);
}
},
onOptionSelect(event, processedOption, isHide = true) {
const value = this.getOptionValue(processedOption.option);
const value = this.getOptionValue(processedOption?.option);
this.activeOptionPath.forEach((p) => (p.selected = true));
this.updateModel(event, value);
@ -311,6 +323,7 @@ export default {
DomHandler.focus(this.$refs.focusInput);
}
this.clicked = true;
this.$emit('click', event);
},
onOverlayClick(event) {
@ -330,11 +343,14 @@ export default {
}
},
onArrowDownKey(event) {
const optionIndex = this.focusedOptionInfo.index !== -1 ? this.findNextOptionIndex(this.focusedOptionInfo.index) : this.findFirstFocusedOptionIndex();
if (!this.overlayVisible) {
this.show();
} else {
const optionIndex = this.focusedOptionInfo.index !== -1 ? this.findNextOptionIndex(this.focusedOptionInfo.index) : this.clicked ? this.findFirstOptionIndex() : this.findFirstFocusedOptionIndex();
this.changeFocusedOptionIndex(event, optionIndex);
this.changeFocusedOptionIndex(event, optionIndex);
}
!this.overlayVisible && this.show();
event.preventDefault();
},
onArrowUpKey(event) {
@ -349,7 +365,7 @@ export default {
this.overlayVisible && this.hide();
event.preventDefault();
} else {
const optionIndex = this.focusedOptionInfo.index !== -1 ? this.findPrevOptionIndex(this.focusedOptionInfo.index) : this.findLastFocusedOptionIndex();
const optionIndex = this.focusedOptionInfo.index !== -1 ? this.findPrevOptionIndex(this.focusedOptionInfo.index) : this.clicked ? this.findLastOptionIndex() : this.findLastFocusedOptionIndex();
this.changeFocusedOptionIndex(event, optionIndex);
@ -360,9 +376,9 @@ export default {
onArrowLeftKey(event) {
if (this.overlayVisible) {
const processedOption = this.visibleOptions[this.focusedOptionInfo.index];
const parentOption = this.activeOptionPath.find((p) => p.key === processedOption.parentKey);
const parentOption = this.activeOptionPath.find((p) => p.key === processedOption?.parentKey);
const matched = this.focusedOptionInfo.parentKey === '' || (parentOption && parentOption.key === this.focusedOptionInfo.parentKey);
const root = ObjectUtils.isEmpty(processedOption.parent);
const root = ObjectUtils.isEmpty(processedOption?.parent);
if (matched) {
this.activeOptionPath = this.activeOptionPath.filter((p) => p.parentKey !== this.focusedOptionInfo.parentKey);
@ -383,10 +399,10 @@ export default {
const grouped = this.isProccessedOptionGroup(processedOption);
if (grouped) {
const matched = this.activeOptionPath.some((p) => processedOption.key === p.key);
const matched = this.activeOptionPath.some((p) => processedOption?.key === p.key);
if (matched) {
this.focusedOptionInfo = { index: -1, parentKey: processedOption.key };
this.focusedOptionInfo = { index: -1, parentKey: processedOption?.key };
this.searchValue = '';
this.onArrowDownKey(event);
} else {
@ -411,6 +427,7 @@ export default {
},
onEnterKey(event) {
if (!this.overlayVisible) {
this.focusedOptionInfo.index !== -1; // reset
this.onArrowDownKey(event);
} else {
if (this.focusedOptionInfo.index !== -1) {
@ -526,7 +543,7 @@ export default {
}
},
isOptionMatched(processedOption) {
return this.isValidOption(processedOption) && this.getProccessedOptionLabel(processedOption).toLocaleLowerCase(this.searchLocale).startsWith(this.searchValue.toLocaleLowerCase(this.searchLocale));
return this.isValidOption(processedOption) && this.getProccessedOptionLabel(processedOption)?.toLocaleLowerCase(this.searchLocale).startsWith(this.searchValue.toLocaleLowerCase(this.searchLocale));
},
isValidOption(processedOption) {
return ObjectUtils.isNotEmpty(processedOption) && !this.isOptionDisabled(processedOption.option);
@ -594,23 +611,25 @@ export default {
let optionIndex = -1;
let matched = false;
if (this.focusedOptionInfo.index !== -1) {
optionIndex = this.visibleOptions.slice(this.focusedOptionInfo.index).findIndex((processedOption) => this.isOptionMatched(processedOption));
optionIndex = optionIndex === -1 ? this.visibleOptions.slice(0, this.focusedOptionInfo.index).findIndex((processedOption) => this.isOptionMatched(processedOption)) : optionIndex + this.focusedOptionInfo.index;
} else {
optionIndex = this.visibleOptions.findIndex((processedOption) => this.isOptionMatched(processedOption));
}
if (ObjectUtils.isNotEmpty(this.searchValue)) {
if (this.focusedOptionInfo.index !== -1) {
optionIndex = this.visibleOptions.slice(this.focusedOptionInfo.index).findIndex((processedOption) => this.isOptionMatched(processedOption));
optionIndex = optionIndex === -1 ? this.visibleOptions.slice(0, this.focusedOptionInfo.index).findIndex((processedOption) => this.isOptionMatched(processedOption)) : optionIndex + this.focusedOptionInfo.index;
} else {
optionIndex = this.visibleOptions.findIndex((processedOption) => this.isOptionMatched(processedOption));
}
if (optionIndex !== -1) {
matched = true;
}
if (optionIndex !== -1) {
matched = true;
}
if (optionIndex === -1 && this.focusedOptionInfo.index === -1) {
optionIndex = this.findFirstFocusedOptionIndex();
}
if (optionIndex === -1 && this.focusedOptionInfo.index === -1) {
optionIndex = this.findFirstFocusedOptionIndex();
}
if (optionIndex !== -1) {
this.changeFocusedOptionIndex(event, optionIndex);
if (optionIndex !== -1) {
this.changeFocusedOptionIndex(event, optionIndex);
}
}
if (this.searchTimeout) {
@ -635,12 +654,14 @@ export default {
}
},
scrollInView(index = -1) {
const id = index !== -1 ? `${this.id}_${index}` : this.focusedOptionId;
const element = DomHandler.findSingle(this.list, `li[id="${id}"]`);
this.$nextTick(() => {
const id = index !== -1 ? `${this.id}_${index}` : this.focusedOptionId;
const element = DomHandler.findSingle(this.list, `li[id="${id}"]`);
if (element) {
element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' });
}
if (element) {
element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' });
}
});
},
autoUpdateModel() {
if (this.selectOnFocus && this.autoOptionFocus && !this.hasSelectedOption) {

View File

@ -17,7 +17,7 @@
:data-p-focus="isOptionFocused(processedOption)"
:data-p-disabled="isOptionDisabled(processedOption)"
>
<div v-ripple :class="cx('content')" @click="onOptionClick($event, processedOption)" v-bind="getPTOptions(processedOption, index, 'content')">
<div v-ripple :class="cx('content')" @click="onOptionClick($event, processedOption)" @mousemove="onOptionMouseMove($event, processedOption)" v-bind="getPTOptions(processedOption, index, 'content')">
<component v-if="templates['option']" :is="templates['option']" :option="processedOption.option" />
<span v-else :class="cx('text')" v-bind="getPTOptions(processedOption, index, 'text')">{{ getOptionLabelToRender(processedOption) }}</span>
<template v-if="isOptionGroup(processedOption)">
@ -43,6 +43,7 @@
:optionGroupLabel="optionGroupLabel"
:optionGroupChildren="optionGroupChildren"
@option-change="onOptionChange"
@option-focus-change="onOptionFocusChange"
:pt="pt"
:unstyled="unstyled"
:isParentMount="mounted"
@ -62,7 +63,7 @@ export default {
name: 'CascadeSelectSub',
hostName: 'CascadeSelect',
extends: BaseComponent,
emits: ['option-change'],
emits: ['option-change', 'option-focus-change'],
container: null,
props: {
selectId: String,
@ -149,9 +150,15 @@ export default {
onOptionClick(event, processedOption) {
this.$emit('option-change', { originalEvent: event, processedOption, isFocus: true });
},
onOptionMouseMove(event, processedOption) {
this.$emit('option-focus-change', { originalEvent: event, processedOption });
},
onOptionChange(event) {
this.$emit('option-change', event);
},
onOptionFocusChange(event) {
this.$emit('option-focus-change', event);
},
containerRef(el) {
this.container = el;
}

View File

@ -103,6 +103,8 @@ const classes = {
'p-cascadeselect p-component p-inputwrapper',
{
'p-disabled': props.disabled,
'p-invalid': props.invalid,
'p-variant-filled': props.variant ? props.variant === 'filled' : instance.$primevue.config.inputStyle === 'filled',
'p-focus': instance.focused,
'p-inputwrapper-filled': props.modelValue,
'p-inputwrapper-focus': instance.focused || instance.overlayVisible,
@ -119,10 +121,9 @@ const classes = {
dropdownButton: 'p-cascadeselect-trigger',
loadingIcon: 'p-cascadeselect-trigger-icon',
dropdownIcon: 'p-cascadeselect-trigger-icon',
panel: ({ instance }) => [
panel: ({ props, instance }) => [
'p-cascadeselect-panel p-component',
{
'p-input-filled': instance.$primevue.config.inputStyle === 'filled',
'p-ripple-disabled': instance.$primevue.config.ripple === false
}
],

View File

@ -1,5 +1,5 @@
<template>
<div :class="cx('root')" :style="sx('root')" v-bind="ptm('root')" data-pc-name="chart">
<div :class="cx('root')" :style="sx('root')" v-bind="ptm('root')">
<canvas ref="canvas" :width="width" :height="height" @click="onCanvasClick($event)" v-bind="{ ...canvasProps, ...ptm('canvas') }"></canvas>
</div>
</template>

View File

@ -21,6 +21,14 @@ export default {
type: null,
default: false
},
variant: {
type: String,
default: null
},
invalid: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
@ -49,10 +57,6 @@ export default {
type: Object,
default: null
},
inputProps: {
type: null,
default: null
},
ariaLabelledby: {
type: String,
default: null

View File

@ -7,7 +7,7 @@
* @module checkbox
*
*/
import { InputHTMLAttributes, VNode } from 'vue';
import { VNode } from 'vue';
import { ComponentHooks } from '../basecomponent';
import { PassThroughOptions } from '../passthrough';
import { ClassComponent, GlobalComponentConstructor, PassThrough } from '../ts-helpers';
@ -61,18 +61,14 @@ export interface CheckboxPassThroughOptions {
* Used to pass attributes to the input's DOM element.
*/
input?: CheckboxPassThroughOptionType;
/**
* Used to pass attributes to the box's DOM element.
*/
box?: CheckboxPassThroughOptionType;
/**
* Used to pass attributes to the icon's DOM element.
*/
icon?: CheckboxPassThroughOptionType;
/**
* Used to pass attributes to the hidden input wrapper's DOM element.
*/
hiddenInputWrapper?: CheckboxPassThroughOptionType;
/**
* Used to pass attributes to the hidden input's DOM element.
*/
hiddenInput?: CheckboxPassThroughOptionType;
/**
* Used to manage all lifecycle hooks.
* @see {@link BaseComponent.ComponentHooks}
@ -91,11 +87,7 @@ export interface CheckboxPassThroughAttributes {
* Defines current inline state in Checkbox component.
*/
export interface CheckboxState {
/**
* Current focus state as a boolean.
* @defaultValue false
*/
focused: boolean;
[key: string]: any;
}
/**
@ -119,11 +111,21 @@ export interface CheckboxProps {
* @default false
*/
binary?: boolean;
/**
* When present, it specifies that the component should have invalid state style.
* @defaultValue false
*/
invalid?: boolean | undefined;
/**
* When present, it specifies that the element should be disabled.
* @default false
*/
disabled?: boolean | undefined;
/**
* Specifies the input variant of the component.
* @defaultValue outlined
*/
variant?: 'outlined' | 'filled' | undefined;
/**
* When present, it specifies that an input field is read-only.
* @default false
@ -160,10 +162,6 @@ export interface CheckboxProps {
* Inline style of the input field.
*/
inputStyle?: string | object | undefined;
/**
* Used to pass all properties of the HTMLInputElement to the focusable input element inside the component.
*/
inputProps?: InputHTMLAttributes | undefined;
/**
* Establishes relationships between the component and label(s) where its value should be one or more element IDs.
*/
@ -198,11 +196,6 @@ export interface CheckboxContext {
* @defaultValue false
*/
checked: boolean;
/**
* Current focus state of the item as a boolean.
* @defaultValue false
*/
focused: boolean;
/**
* Current disabled state of the item as a boolean.
* @defaultValue false
@ -235,25 +228,25 @@ export interface CheckboxSlots {
*/
export interface CheckboxEmits {
/**
* Emitted when the page changes.
* @param {*} value - New page value.
* Emitted when the value changes.
* @param {*} value - New value.
*/
'update:page'(value: any): void;
/**
* Callback to invoke on value click.
* @param {MouseEvent} event - Browser event.
*/
click(event: MouseEvent): void;
'update:modelValue'(value: any): void;
/**
* Callback to invoke on value change.
* @param {Event} event - Browser event.
*/
change(event: Event): void;
/**
* Callback to invoke on value change.
* @param {boolean} value - New value.
* Callback to invoke when the component receives focus.
* @param {Event} event - Browser event.
*/
input(value: boolean): void;
focus(event: Event): void;
/**
* Callback to invoke when the component loses focus.
* @param {Event} event - Browser event.
*/
blur(event: Event): void;
}
/**

View File

@ -21,7 +21,6 @@ describe('Checkbox.vue', () => {
it('should exist', async () => {
await wrapper.setProps({ modelValue: true });
expect(wrapper.find('.p-checkbox-checked').exists()).toBe(true);
expect(wrapper.find('.p-checkbox-box.p-highlight').exists()).toBe(true);
expect(wrapper.find('.p-checkbox.p-highlight').exists()).toBe(true);
});
});

View File

@ -1,25 +1,25 @@
<template>
<div :class="cx('root')" @click="onClick($event)" v-bind="getPTOptions('root')" data-pc-name="checkbox">
<div class="p-hidden-accessible" v-bind="ptm('hiddenInputWrapper')" :data-p-hidden-accessible="true">
<input
ref="input"
:id="inputId"
type="checkbox"
:value="value"
:name="name"
:checked="checked"
:tabindex="tabindex"
:disabled="disabled"
:readonly="readonly"
:required="required"
:aria-labelledby="ariaLabelledby"
:aria-label="ariaLabel"
@focus="onFocus($event)"
@blur="onBlur($event)"
v-bind="ptm('hiddenInput')"
/>
</div>
<div ref="box" :class="[cx('input'), inputClass]" :style="inputStyle" v-bind="{ ...inputProps, ...getPTOptions('input') }" :data-p-highlight="checked" :data-p-disabled="disabled" :data-p-focused="focused">
<div :class="cx('root')" v-bind="getPTOptions('root')" :data-p-highlight="checked" :data-p-disabled="disabled">
<input
:id="inputId"
type="checkbox"
:class="[cx('input'), inputClass]"
:style="inputStyle"
:value="value"
:name="name"
:checked="checked"
:tabindex="tabindex"
:disabled="disabled"
:readonly="readonly"
:required="required"
:aria-labelledby="ariaLabelledby"
:aria-label="ariaLabel"
@focus="onFocus"
@blur="onBlur"
@change="onChange"
v-bind="getPTOptions('input')"
/>
<div :class="cx('box')" v-bind="getPTOptions('box')">
<slot name="icon" :checked="checked" :class="cx('icon')">
<CheckIcon v-if="checked" :class="cx('icon')" v-bind="getPTOptions('icon')" />
</slot>
@ -35,23 +35,17 @@ import BaseCheckbox from './BaseCheckbox.vue';
export default {
name: 'Checkbox',
extends: BaseCheckbox,
emits: ['click', 'update:modelValue', 'change', 'input', 'focus', 'blur'],
data() {
return {
focused: false
};
},
emits: ['update:modelValue', 'change', 'focus', 'blur'],
methods: {
getPTOptions(key) {
return this.ptm(key, {
context: {
checked: this.checked,
focused: this.focused,
disabled: this.disabled
}
});
},
onClick(event) {
onChange(event) {
if (!this.disabled && !this.readonly) {
let newModelValue;
@ -62,19 +56,14 @@ export default {
else newModelValue = this.modelValue ? [...this.modelValue, this.value] : [this.value];
}
this.$emit('click', event);
this.$emit('update:modelValue', newModelValue);
this.$emit('change', event);
this.$emit('input', newModelValue);
this.$refs.input.focus();
}
},
onFocus(event) {
this.focused = true;
this.$emit('focus', event);
},
onBlur(event) {
this.focused = false;
this.$emit('blur', event);
}
},
@ -84,7 +73,7 @@ export default {
}
},
components: {
CheckIcon: CheckIcon
CheckIcon
}
};
</script>

View File

@ -1,26 +1,43 @@
import BaseStyle from 'primevue/base/style';
const css = `
@layer primevue {
.p-checkbox {
position: relative;
display: inline-flex;
user-select: none;
vertical-align: bottom;
}
.p-checkbox-input {
cursor: pointer;
}
.p-checkbox-box {
display: flex;
justify-content: center;
align-items: center;
}
}
`;
const classes = {
root: ({ instance, props }) => [
'p-checkbox p-component',
{
'p-checkbox-checked': instance.checked,
'p-checkbox-disabled': props.disabled,
'p-checkbox-focused': instance.focused
}
],
input: ({ instance, props }) => [
'p-checkbox-box',
{
'p-highlight': instance.checked,
'p-disabled': props.disabled,
'p-focus': instance.focused
'p-invalid': props.invalid,
'p-variant-filled': props.variant ? props.variant === 'filled' : instance.$primevue.config.inputStyle === 'filled'
}
],
box: 'p-checkbox-box',
input: 'p-checkbox-input',
icon: 'p-checkbox-icon'
};
export default BaseStyle.extend({
name: 'checkbox',
css,
classes
});

View File

@ -1,5 +1,5 @@
<template>
<div v-if="visible" :class="cx('root')" :aria-label="label" v-bind="ptm('root')" data-pc-name="chip">
<div v-if="visible" :class="cx('root')" :aria-label="label" v-bind="ptm('root')">
<slot>
<img v-if="image" :src="image" v-bind="ptm('image')" />
<component v-else-if="$slots.icon" :is="$slots.icon" :class="cx('icon')" v-bind="ptm('icon')" />

View File

@ -30,6 +30,14 @@ export default {
type: String,
default: null
},
variant: {
type: String,
default: null
},
invalid: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false

View File

@ -184,10 +184,21 @@ export interface ChipsProps {
* @deprecated since v3.27.0. Use 'removetokenicon' slot.
*/
removeTokenIcon?: string | undefined;
/**
* When present, it specifies that the component should have invalid state style.
* @defaultValue false
*/
invalid?: boolean | undefined;
/**
* When present, it specifies that the element should be disabled.
* @defaultValue false
*/
disabled?: boolean | undefined;
/**
* Specifies the input variant of the component.
* @defaultValue outlined
*/
variant?: 'outlined' | 'filled' | undefined;
/**
* Placeholder text for the input.
*/

View File

@ -1,5 +1,5 @@
<template>
<div :class="cx('root')" v-bind="ptm('root')" data-pc-name="chips">
<div :class="cx('root')" v-bind="ptm('root')">
<ul
ref="container"
:class="cx('container')"
@ -67,12 +67,20 @@ export default {
emits: ['update:modelValue', 'add', 'remove', 'focus', 'blur'],
data() {
return {
id: UniqueComponentId(),
id: this.$attrs.id,
inputValue: null,
focused: false,
focusedIndex: null
};
},
watch: {
'$attrs.id': function (newValue) {
this.id = newValue || UniqueComponentId();
}
},
mounted() {
this.id = this.id || UniqueComponentId();
},
methods: {
onWrapperClick() {
this.$refs.input.focus();
@ -140,11 +148,12 @@ export default {
},
onPaste(event) {
if (this.separator) {
let separator = this.separator.replace('\\n', '\n').replace('\\r', '\r').replace('\\t', '\t');
let pastedData = (event.clipboardData || window['clipboardData']).getData('Text');
if (pastedData) {
let value = this.modelValue || [];
let pastedValues = pastedData.split(this.separator);
let pastedValues = pastedData.split(separator);
pastedValues = pastedValues.filter((val) => this.allowDuplicate || value.indexOf(val) === -1);
value = [...value, ...pastedValues];

View File

@ -55,12 +55,18 @@ const classes = {
'p-chips p-component p-inputwrapper',
{
'p-disabled': props.disabled,
'p-invalid': props.invalid,
'p-focus': instance.focused,
'p-inputwrapper-filled': (props.modelValue && props.modelValue.length) || (instance.inputValue && instance.inputValue.length),
'p-inputwrapper-focus': instance.focused
}
],
container: 'p-inputtext p-chips-multiple-container',
container: ({ props, instance }) => [
'p-inputtext p-chips-multiple-container',
{
'p-variant-filled': props.variant ? props.variant === 'filled' : instance.$primevue.config.inputStyle === 'filled'
}
],
token: ({ state, index }) => ['p-chips-token', { 'p-focus': state.focusedIndex === index }],
label: 'p-chips-token-label',
removeTokenIcon: 'p-chips-token-icon',

View File

@ -39,7 +39,7 @@ export default {
default: 0
},
appendTo: {
type: String,
type: [String, Object],
default: 'body'
},
panelClass: null

View File

@ -54,7 +54,7 @@ export interface ColorPickerChangeEvent {
/**
* Browser event
*/
originalEvent: Event;
event: Event;
/**
* Selected color value.
*/
@ -211,7 +211,7 @@ export interface ColorPickerEmits {
*/
'update:modelValue'(value: any): void;
/**
* Callback to invoke when a chip is added.
* Callback to invoke when a color is selected.
* @param {ColorPickerChangeEvent} event - Custom add event.
*/
change(event: ColorPickerChangeEvent): void;

View File

@ -96,8 +96,7 @@ export default {
this.selfUpdate = true;
this.updateColorHandle();
this.updateInput();
this.updateModel();
this.$emit('change', { event: event, value: this.modelValue });
this.updateModel(event);
},
pickHue(event) {
let top = this.hueView.getBoundingClientRect().top + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
@ -111,28 +110,32 @@ export default {
this.selfUpdate = true;
this.updateColorSelector();
this.updateHue();
this.updateModel();
this.updateModel(event);
this.updateInput();
this.$emit('change', { event: event, value: this.modelValue });
},
updateModel() {
updateModel(event) {
let value = this.modelValue;
switch (this.format) {
case 'hex':
this.$emit('update:modelValue', this.HSBtoHEX(this.hsbValue));
value = this.HSBtoHEX(this.hsbValue);
break;
case 'rgb':
this.$emit('update:modelValue', this.HSBtoRGB(this.hsbValue));
value = this.HSBtoRGB(this.hsbValue);
break;
case 'hsb':
this.$emit('update:modelValue', this.hsbValue);
value = this.hsbValue;
break;
default:
//NoOp
break;
}
this.$emit('update:modelValue', value);
this.$emit('change', { event, value });
},
updateColorSelector() {
if (this.colorSelector) {

View File

@ -20,7 +20,6 @@ const classes = {
{
'p-colorpicker-overlay-panel': !props.inline,
'p-disabled': props.disabled,
'p-input-filled': instance.$primevue.config.inputStyle === 'filled',
'p-ripple-disabled': instance.$primevue.config.ripple === false
}
],

View File

@ -12,9 +12,11 @@
import { VNode } from 'vue';
import { ComponentHooks } from '../basecomponent';
import { ButtonPassThroughOptions } from '../button';
import { CheckboxPassThroughOptionType } from '../checkbox';
import { DataTablePassThroughOptions } from '../datatable';
import { DropdownPassThroughOptionType } from '../dropdown';
import { PassThroughOptions } from '../passthrough';
import { RadioButtonPassThroughOptionType } from '../radiobutton';
import { ClassComponent, GlobalComponentConstructor, PassThrough } from '../ts-helpers';
import { VirtualScrollerLoaderOptions } from '../virtualscroller';
@ -156,18 +158,10 @@ export interface ColumnPassThroughOptions {
* Used to pass attributes to the sort badge's DOM element.
*/
sortBadge?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the checkbox wrapper's DOM element.
*/
headerCheckboxWrapper?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the header checkbox's DOM element.
*/
headerCheckbox?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the header checkbox icon's DOM element.
*/
headerCheckboxIcon?: ColumnPassThroughOptionType;
headerCheckbox?: CheckboxPassThroughOptionType;
/**
* Used to pass attributes to the column filter's DOM element.
*/
@ -278,30 +272,14 @@ export interface ColumnPassThroughOptions {
* Used to pass attributes to the column title's DOM element.
*/
columnTitle?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the radiobutton wrapper's DOM element.
*/
radiobuttonWrapper?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the radiobutton's DOM element.
*/
radiobutton?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the radiobutton icon's DOM element.
*/
radiobuttonIcon?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the checkbox wrapper's DOM element.
*/
checkboxWrapper?: ColumnPassThroughOptionType;
rowRadioButton?: RadioButtonPassThroughOptionType;
/**
* Used to pass attributes to the checkbox's DOM element.
*/
checkbox?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the checkbox icon's DOM element.
*/
checkboxIcon?: ColumnPassThroughOptionType;
rowCheckbox?: CheckboxPassThroughOptionType;
/**
* Used to pass attributes to the rowtoggler's DOM element.
*/
@ -342,22 +320,6 @@ export interface ColumnPassThroughOptions {
* Used to pass attributes to the body cell content's DOM element.
*/
bodyCellContent?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the hidden input wrapper's DOM element.
*/
hiddenHeaderInputWrapper?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the hidden input's DOM element.
*/
hiddenHeaderInput?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the hidden input wrapper's DOM element.
*/
hiddenInputWrapper?: ColumnPassThroughOptionType;
/**
* Used to pass attributes to the hidden input's DOM element.
*/
hiddenInput?: ColumnPassThroughOptionType;
/**
* Used to manage all lifecycle hooks.
* @see {@link BaseComponent.ComponentHooks}
@ -722,10 +684,15 @@ export interface ColumnSlots {
*/
frozenRow: boolean;
/**
* Callback function
* Editor init callback function
* @param {Event} event - Browser event
*/
editorInitCallback: (event: Event) => void;
/**
* Row toggler callback unction
* @param {Event} event - Browser event
*/
rowTogglerCallback: (event: Event) => void;
}): VNode[];
/**
* Custom header template.

View File

@ -99,7 +99,7 @@ import { VirtualScrollerPassThroughOptions } from '../virtualscroller';
export interface PrimeVueConfiguration {
ripple?: boolean;
inputStyle?: string;
inputStyle?: 'filled' | 'outlined' | undefined;
locale?: PrimeVueLocaleOptions;
filterMatchModeOptions?: any;
zIndex?: PrimeVueZIndexOptions;

View File

@ -4,7 +4,7 @@ import { inject, reactive } from 'vue';
export const defaultOptions = {
ripple: false,
inputStyle: 'outlined',
inputStyle: null,
locale: {
startsWith: 'Starts with',
contains: 'Contains',

View File

@ -28,17 +28,17 @@
<component v-else :is="$slots.message" :message="confirmation"></component>
</template>
<template v-if="!$slots.container" #footer>
<CDButton :label="rejectLabel" :class="[cx('rejectButton'), confirmation.rejectClass]" @click="reject()" :autofocus="autoFocusReject" :unstyled="unstyled" :pt="ptm('rejectButton')" data-pc-name="rejectbutton">
<CDButton :label="rejectLabel" :class="[cx('rejectButton'), confirmation.rejectClass]" @click="reject()" :autofocus="autoFocusReject" :unstyled="unstyled" :pt="ptm('rejectButton')">
<template v-if="rejectIcon || $slots.rejecticon" #icon="iconProps">
<slot name="rejecticon">
<span :class="[rejectIcon, iconProps.class]" v-bind="ptm('rejectButton')['icon']" data-pc-name="rejectbuttonicon" />
<span :class="[rejectIcon, iconProps.class]" v-bind="ptm('rejectButton')['icon']" data-pc-section="rejectbuttonicon" />
</slot>
</template>
</CDButton>
<CDButton :label="acceptLabel" :class="[cx('acceptButton'), confirmation.acceptClass]" @click="accept()" :autofocus="autoFocusAccept" :unstyled="unstyled" :pt="ptm('acceptButton')" data-pc-name="acceptbutton">
<CDButton :label="acceptLabel" :class="[cx('acceptButton'), confirmation.acceptClass]" @click="accept()" :autofocus="autoFocusAccept" :unstyled="unstyled" :pt="ptm('acceptButton')">
<template v-if="acceptIcon || $slots.accepticon" #icon="iconProps">
<slot name="accepticon">
<span :class="[acceptIcon, iconProps.class]" v-bind="ptm('acceptButton')['icon']" data-pc-name="acceptbuttonicon" />
<span :class="[acceptIcon, iconProps.class]" v-bind="ptm('acceptButton')['icon']" data-pc-section="acceptbuttonicon" />
</slot>
</template>
</CDButton>

View File

@ -15,35 +15,17 @@
</template>
<component v-else :is="$slots.message" :message="confirmation"></component>
<div :class="cx('footer')" v-bind="ptm('footer')">
<CPButton
:label="rejectLabel"
@click="reject()"
@keydown="onRejectKeydown"
:autofocus="autoFocusReject"
:class="[cx('rejectButton'), confirmation.rejectClass]"
:unstyled="unstyled"
:pt="ptm('rejectButton')"
data-pc-name="rejectbutton"
>
<CPButton :label="rejectLabel" @click="reject()" @keydown="onRejectKeydown" :autofocus="autoFocusReject" :class="[cx('rejectButton'), confirmation.rejectClass]" :unstyled="unstyled" :pt="ptm('rejectButton')">
<template v-if="rejectIcon || $slots.rejecticon" #icon="iconProps">
<slot name="rejecticon">
<span :class="[rejectIcon, iconProps.class]" v-bind="ptm('rejectButton')['icon']" data-pc-name="rejectbuttonicon" />
<span :class="[rejectIcon, iconProps.class]" v-bind="ptm('rejectButton')['icon']" data-pc-section="rejectbuttonicon" />
</slot>
</template>
</CPButton>
<CPButton
:label="acceptLabel"
@click="accept()"
@keydown="onAcceptKeydown"
:autofocus="autoFocusAccept"
:class="[cx('acceptButton'), confirmation.acceptClass]"
:unstyled="unstyled"
:pt="ptm('acceptButton')"
data-pc-name="acceptbutton"
>
<CPButton :label="acceptLabel" @click="accept()" @keydown="onAcceptKeydown" :autofocus="autoFocusAccept" :class="[cx('acceptButton'), confirmation.acceptClass]" :unstyled="unstyled" :pt="ptm('acceptButton')">
<template v-if="acceptIcon || $slots.accepticon" #icon="iconProps">
<slot name="accepticon">
<span :class="[acceptIcon, iconProps.class]" v-bind="ptm('acceptButton')['icon']" data-pc-name="acceptbuttonicon" />
<span :class="[acceptIcon, iconProps.class]" v-bind="ptm('acceptButton')['icon']" data-pc-section="acceptbuttonicon" />
</slot>
</template>
</CPButton>
@ -190,7 +172,7 @@ export default {
ZIndexUtils.clear(el);
},
alignOverlay() {
DomHandler.absolutePosition(this.container, this.target);
DomHandler.absolutePosition(this.container, this.target, false);
const containerOffset = DomHandler.getOffset(this.container);
const targetOffset = DomHandler.getOffset(this.target);

View File

@ -78,7 +78,6 @@ const classes = {
root: ({ instance }) => [
'p-confirm-popup p-component',
{
'p-input-filled': instance.$primevue.config.inputStyle === 'filled',
'p-ripple-disabled': instance.$primevue.config.ripple === false
}
],

View File

@ -11,7 +11,7 @@ export default {
default: null
},
appendTo: {
type: String,
type: [String, Object],
default: 'body'
},
autoZIndex: {

View File

@ -1,7 +1,7 @@
<template>
<Portal :appendTo="appendTo">
<transition name="p-contextmenu" @enter="onEnter" @after-enter="onAfterEnter" @leave="onLeave" @after-leave="onAfterLeave" v-bind="ptm('transition')">
<div v-if="visible" :ref="containerRef" :class="cx('root')" v-bind="{ ...$attrs, ...ptm('root') }" data-pc-name="contextmenu">
<div v-if="visible" :ref="containerRef" :class="cx('root')" v-bind="{ ...$attrs, ...ptm('root') }">
<ContextMenuSub
:ref="listRef"
:id="id + '_list'"
@ -10,9 +10,9 @@
:root="true"
:tabindex="tabindex"
aria-orientation="vertical"
:aria-activedescendant="focused ? focusedItemId : undefined"
:aria-activedescendant="focused ? focusedItemIdx : undefined"
:menuId="id"
:focusedItemId="focused ? focusedItemId : undefined"
:focusedItemId="focused ? focusedItemIdx : undefined"
:items="processedItems"
:templates="$slots"
:activeItemPath="activeItemPath"
@ -309,7 +309,7 @@ export default {
},
onEnterKey(event) {
if (this.focusedItemInfo.index !== -1) {
const element = DomHandler.findSingle(this.list, `li[id="${`${this.focusedItemId}`}"]`);
const element = DomHandler.findSingle(this.list, `li[id="${`${this.focusedItemIdx}`}"]`);
const anchorElement = element && DomHandler.findSingle(element, 'a[data-pc-section="action"]');
anchorElement ? anchorElement.click() : element && element.click();
@ -450,7 +450,7 @@ export default {
}
},
isItemMatched(processedItem) {
return this.isValidItem(processedItem) && this.getProccessedItemLabel(processedItem).toLocaleLowerCase().startsWith(this.searchValue.toLocaleLowerCase());
return this.isValidItem(processedItem) && this.getProccessedItemLabel(processedItem)?.toLocaleLowerCase().startsWith(this.searchValue.toLocaleLowerCase());
},
isValidItem(processedItem) {
return !!processedItem && !this.isItemDisabled(processedItem.item) && !this.isItemSeparator(processedItem.item);
@ -533,7 +533,7 @@ export default {
}
},
scrollInView(index = -1) {
const id = index !== -1 ? `${this.id}_${index}` : this.focusedItemId;
const id = index !== -1 ? `${this.id}_${index}` : this.focusedItemIdx;
const element = DomHandler.findSingle(this.list, `li[id="${id}"]`);
if (element) {
@ -577,13 +577,13 @@ export default {
return processedItem ? processedItem.items : this.processedItems;
},
focusedItemId() {
focusedItemIdx() {
return this.focusedItemInfo.index !== -1 ? `${this.id}${ObjectUtils.isNotEmpty(this.focusedItemInfo.parentKey) ? '_' + this.focusedItemInfo.parentKey : ''}_${this.focusedItemInfo.index}` : null;
}
},
components: {
ContextMenuSub: ContextMenuSub,
Portal: Portal
ContextMenuSub,
Portal
}
};
</script>

View File

@ -50,7 +50,6 @@ const classes = {
root: ({ instance }) => [
'p-contextmenu p-component',
{
'p-input-filled': instance.$primevue.config.inputStyle === 'filled',
'p-ripple-disabled': instance.$primevue.config.ripple === false
}
],

View File

@ -250,6 +250,10 @@ export default {
type: Boolean,
default: false
},
highlightOnSelect: {
type: Boolean,
default: false
},
size: {
type: String,
default: null

Some files were not shown because too many files have changed in this diff Show More