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

View File

@ -1,5 +1,99 @@
# Changelog # 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) ## [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) [Full Changelog](https://github.com/primefaces/primevue/compare/3.44.0...3.45.0)

View File

@ -26,7 +26,7 @@ pnpm add primevue
## Plugin ## 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 ```javascript
import { createApp } from 'vue'; import { createApp } from 'vue';
@ -46,7 +46,7 @@ Styled mode is based on pre-skinned components with opinionated themes like Mate
```javascript ```javascript
// theme // theme
import 'primevue/resources/themes/lara-light-green/theme.css'; import 'primevue/resources/themes/aura-light-green/theme.css';
``` ```
**Unstyled Mode** **Unstyled Mode**
@ -138,7 +138,7 @@ In styled mode, the theme can be defined at Nuxt configuration with the css prop
```javascript ```javascript
export default defineNuxtConfig({ 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', default: 'false',
description: 'When present, it specifies that the component should be disabled.' 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', name: 'dataKey',
type: 'string', type: 'string',
@ -200,7 +212,7 @@ const AutoCompleteProps = [
{ {
name: 'autoOptionFocus', name: 'autoOptionFocus',
type: 'boolean', type: 'boolean',
default: 'true', default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.' 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', name: 'severity',
type: 'string', type: 'string',
default: 'null', 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', name: 'size',

View File

@ -57,7 +57,7 @@ const ButtonProps = [
name: 'severity', name: 'severity',
type: 'string', type: 'string',
default: 'null', 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', name: 'raised',

View File

@ -257,6 +257,18 @@ const CalendarProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the element should be disabled.' 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', name: 'readonly',
type: 'boolean', type: 'boolean',

View File

@ -53,6 +53,18 @@ const CascadeSelectProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the component should be disabled.' 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', name: 'dataKey',
type: 'string', type: 'string',
@ -128,7 +140,7 @@ const CascadeSelectProps = [
{ {
name: 'autoOptionFocus', name: 'autoOptionFocus',
type: 'boolean', type: 'boolean',
default: 'true', default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.' 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', default: 'false',
description: 'When present, it specifies that the element should be disabled.' 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', name: 'readonly',
type: 'boolean', type: 'boolean',

View File

@ -35,6 +35,18 @@ const ChipsProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the element should be disabled.' 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', name: 'placeholder',
type: 'string', type: 'string',

View File

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

View File

@ -95,6 +95,18 @@ const DropdownProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the component should be disabled.' 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', name: 'dataKey',
type: 'string', type: 'string',
@ -185,6 +197,12 @@ const DropdownProps = [
default: 'false', default: 'false',
description: 'Clears the filter value when hiding the dropdown.' 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', name: 'virtualScrollerOptions',
type: 'object', type: 'object',
@ -194,7 +212,7 @@ const DropdownProps = [
{ {
name: 'autoOptionFocus', name: 'autoOptionFocus',
type: 'boolean', type: 'boolean',
default: 'true', default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.' 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', name: 'severity',
type: 'string', type: 'string',
default: 'error', 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', name: 'icon',

View File

@ -29,6 +29,18 @@ const InputMaskProps = [
default: 'false', default: 'false',
description: 'Defines if model sets the raw unmasked value to bound value or the formatted mask value.' 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', name: 'pt',
type: 'any', type: 'any',

View File

@ -147,6 +147,18 @@ const InputNumberProps = [
default: 'null', default: 'null',
description: 'Placeholder text for the input.' 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', name: 'inputId',
type: 'string', type: 'string',

View File

@ -11,6 +11,18 @@ const InputTextProps = [
default: 'null', default: 'null',
description: 'Defines the size of the component, valid values are "small" and "large".' 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', name: 'pt',
type: 'any', type: 'any',

View File

@ -53,6 +53,12 @@ const ListboxProps = [
default: 'false', default: 'false',
description: 'When specified, disables the component.' 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', name: 'dataKey',
type: 'string', type: 'string',
@ -117,7 +123,7 @@ const ListboxProps = [
{ {
name: 'autoOptionFocus', name: 'autoOptionFocus',
type: 'boolean', type: 'boolean',
default: 'true', default: 'false',
description: 'Whether to focus on the first visible or selected element.' description: 'Whether to focus on the first visible or selected element.'
}, },
{ {

View File

@ -3,7 +3,7 @@ const MessageProps = [
name: 'severity', name: 'severity',
type: 'string', type: 'string',
default: 'info', 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', name: 'closable',
@ -75,6 +75,10 @@ const MessageEvents = [
description: 'Browser event' 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', default: 'false',
description: 'When present, it specifies that the component should be disabled.' 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', name: 'inputId',
type: 'string', type: 'string',
@ -236,7 +248,7 @@ const MultiSelectProps = [
{ {
name: 'autoOptionFocus', name: 'autoOptionFocus',
type: 'boolean', type: 'boolean',
default: 'true', default: 'false',
description: 'Whether to focus on the first visible or selected element when the overlay panel is shown.' 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', default: 'false',
description: 'Whether to focus on the filter element when the overlay panel is shown.' 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', name: 'filterMessage',
type: 'string', type: 'string',

View File

@ -18,6 +18,12 @@ const OrderListProps = [
description: 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.' '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', name: 'dataKey',
type: 'string', type: 'string',

View File

@ -83,6 +83,18 @@ const PasswordProps = [
default: 'null', default: 'null',
description: 'Placeholder text for the input.' 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', name: 'required',
type: 'boolean', type: 'boolean',

View File

@ -18,6 +18,12 @@ const PickListProps = [
description: 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.' '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', name: 'dataKey',
type: 'string', type: 'string',

View File

@ -23,6 +23,18 @@ const RadioButtonProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the element should be disabled.' 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', name: 'inputId',
type: 'string', type: 'string',

View File

@ -41,6 +41,12 @@ const SelectButtonProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the element should be disabled.' 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', name: 'dataKey',
type: 'string', type: 'string',

View File

@ -63,7 +63,7 @@ const SplitButtonProps = [
name: 'severity', name: 'severity',
type: 'string', type: 'string',
default: 'null', 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', name: 'raised',

View File

@ -9,7 +9,7 @@ const TagProps = [
name: 'severity', name: 'severity',
type: 'string', type: 'string',
default: 'null', 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', name: 'rounded',

View File

@ -11,6 +11,18 @@ const TextareaProps = [
default: 'false', default: 'false',
description: 'When present, height of textarea changes as being typed.' 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', name: 'pt',
type: 'any', type: 'any',

View File

@ -47,6 +47,12 @@ const ToggleButtonProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the element should be disabled.' 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', name: 'inputId',
type: 'string', type: 'string',

View File

@ -72,6 +72,12 @@ const TreeProps = [
default: 'undefined', default: 'undefined',
description: "Locale to use in filtering. The default locale is the host environment's current locale." 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', name: 'scrollHeight',
type: 'string', type: 'string',

View File

@ -29,6 +29,18 @@ const TreeSelectProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the component should be disabled.' 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', name: 'tabindex',
type: 'string', type: 'string',

View File

@ -11,6 +11,18 @@ const TriStateCheckboxProps = [
default: 'false', default: 'false',
description: 'When present, it specifies that the component should be disabled.' 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', name: 'tabindex',
type: 'string', type: 'string',

View File

@ -12,7 +12,7 @@ export default {
$route: { $route: {
handler(to) { handler(to) {
if (to.name === 'index') { 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', id: 'home-table-link',
rel: 'stylesheet', 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, "id": 52,
"content": "New Year Sale is Here! 🎉", "content": "Tailwind Presets for Unstyled PrimeVue",
"linkText": "Visit Store", "linkText": "Learn More",
"linkHref": "https://primefaces.org/store", "linkHref": "http://tailwind.primevue.org",
"backgroundStyle": "background-color:var(--primary-color)", "backgroundStyle": "background-color:var(--primary-color)",
"textStyle": "color:var(--primary-color-text);font-weight:500", "textStyle": "color:var(--primary-color-text);font-weight:500",
"linkStyle": "color:var(--primary-color-text);font-weight:700;text-decoration: underline;" "linkStyle": "color:var(--primary-color-text);font-weight:700;text-decoration: underline;"

View File

@ -9,16 +9,8 @@
"to": "/introduction" "to": "/introduction"
}, },
{ {
"name": "Vite Setup", "name": "Setup",
"to": "/vite" "to": "/setup"
},
{
"name": "Nuxt Setup",
"to": "/nuxt"
},
{
"name": "Configuration",
"to": "/configuration"
}, },
{ {
"name": "Playground", "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", "name": "Components",
"icon": "pi pi-compass", "icon": "pi pi-compass",
@ -65,6 +93,16 @@
"name": "Editor", "name": "Editor",
"to": "/editor" "to": "/editor"
}, },
{
"name": "FloatLabel",
"to": "/floatlabel",
"badge": "NEW"
},
{
"name": "IconField",
"to": "/iconfield",
"badge": "NEW"
},
{ {
"name": "InputGroup", "name": "InputGroup",
"to": "/inputgroup" "to": "/inputgroup"
@ -399,6 +437,11 @@
"name": "Inplace", "name": "Inplace",
"to": "/inplace" "to": "/inplace"
}, },
{
"name": "MeterGroup",
"to": "/metergroup",
"badge": "NEW"
},
{ {
"name": "ScrollTop", "name": "ScrollTop",
"to": "/scrolltop" "to": "/scrolltop"
@ -531,10 +574,6 @@
"name": "Accessibility", "name": "Accessibility",
"to": "/guides/accessibility" "to": "/guides/accessibility"
}, },
{
"name": "CSS Layer",
"to": "/guides/csslayer"
},
{ {
"name": "PrimeTV", "name": "PrimeTV",
"icon": "pi pi-youtube", "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-selectbutton {
.p-button { .p-button {
padding: 0.5rem 1rem; 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 { h1 {
font-size: 2rem; font-size: 1.75rem;
} }
h2 { h2 {
font-size: 1.5rem;
}
h3 {
font-size: 1.25rem; font-size: 1.25rem;
} }
h4 { h3 {
font-size: 1.125rem; font-size: 1.125rem;
} }
h5 { h4 {
font-size: 1rem; font-size: 1rem;
} }
h6 { h5 {
font-size: .875rem; font-size: .875rem;
} }
h6 {
font-size: .75rem;
}
p { p {
line-height: 1.75; line-height: 1.75;
margin: 0 0 1rem 0; margin: 0 0 1rem 0;

View File

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

View File

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

View File

@ -2,39 +2,39 @@
--home-highlight-color:#10b981; --home-highlight-color:#10b981;
--home-highlight-darker-color:#059669; --home-highlight-darker-color:#059669;
--home-highlight-fore-color:#ffffff; --home-highlight-fore-color:#ffffff;
--home-bg:#F9FAFB; --home-bg:#f8fafc;
--home-border-color:rgba(0,0,0,.1); --home-border-color:#e2e8f0;
--home-primary-text-color:#030712; --home-primary-text-color:#334155;
--home-secondary-text-color:#6b7280; --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-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-box-bg:#ffffff;
--home-linkbox-bg:#ffffff; --home-linkbox-bg:#ffffff;
--home-linkbox-border:1px solid rgba(0,0,0,.1); --home-linkbox-border:1px solid #e2e8f0;
--home-linkbox-text-color:#030712; --home-linkbox-text-color:#334155;
--home-linkbox-hover-bg:#e5e7eb; --home-linkbox-hover-bg:#f1f5f9;
--home-blocks-bg:transparent; --home-blocks-bg:transparent;
--home-blocks-block-bg:#ffffff; --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-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-left:5px solid #e2e8f0;
--home-blocks-border-bottom:7px solid rgba(0,0,0,.1); --home-blocks-border-bottom:7px solid #e2e8f0;
--home-blocks-border:1px solid rgba(0,0,0,.1); --home-blocks-border:1px solid #e2e8f0;
--home-blocks-sidebar-bg:#f3f4f6; --home-blocks-sidebar-bg:#f1f5f9;
--home-blocks-list-bg:#f9fafb; --home-blocks-list-bg:#f8fafc;
--home-blocks-main-bg:#ffffff; --home-blocks-main-bg:#ffffff;
--home-blocks-main-border:1px solid rgba(0,0,0,.1); --home-blocks-main-border:1px solid #e2e8f0;
--home-blocks-item-bg:#f4f5f7; --home-blocks-item-bg:#f1f5f9;
--home-blocks-image-bg:#e5e7eb; --home-blocks-image-bg:#e2e8f0;
--home-blocks-text-color:#d1d5db; --home-blocks-text-color:#cbd5e1;
--home-blocks-active-shadow:0px 30px 50px 0px rgba(0, 0, 0, .1); --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-top:1px solid rgba(0,0,0,.07);
--home-blocks-active-border-right: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-bottom:4px solid rgba(0,0,0,.07);
--home-blocks-active-border-left: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-animation-shadow:0px 30px 50px 10px rgba(0, 0, 0, .2);
--home-blocks-tablebar-bg:#d1d5db; --home-blocks-tablebar-bg:#cbd5e1;
--home-blocks-bar-bg:#d1d5db; --home-blocks-bar-bg:#cbd5e1;
--home-blocks-bar-button-bg:#ffffff; --home-blocks-bar-button-bg:#ffffff;
--home-blocks-circle-bg:#c7cad0; --home-blocks-circle-bg:#cbd5e1;
--home-templates-bg:transparent; --home-templates-bg:transparent;
--home-templates-block-shadow:0px 5px 10px 0px rgba(0,0,0,.1); --home-templates-block-shadow:0px 5px 10px 0px rgba(0,0,0,.1);
--home-templates-block-border-left:5px solid #d1d5db; --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-bottom:4px solid rgba(0,0,0,.1);
--home-templates-btn-border-left:3px 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-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-color: var(--surface-500);
--demo-code-button-hover-bg: rgba(255,255,255,.1); --demo-code-button-hover-bg: rgba(255,255,255,.1);
--demo-code-button-hover-color: var(--surface-700); --demo-code-button-hover-color: var(--surface-700);
--doc-highlight-text-bg: var(--highlight-bg); --doc-highlight-text-bg: var(--surface-50);
--doc-highlight-text-color: var(--highlight-text-color); --doc-highlight-text-color: var(--surface-500);
} }

View File

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

View File

@ -1,5 +1,9 @@
<template> <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> <slot v-else></slot>
</template> </template>
@ -42,14 +46,33 @@ export default {
}; };
</script> </script>
<style> <style>
.demo-section-loading { .deferred-demo-loading {
display: grid;
place-items: center;
padding: 2rem;
border-radius: 10px; border-radius: 10px;
margin-bottom: 1rem;
font-size: 2rem;
height: 350px; 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> </style>

View File

@ -18,16 +18,6 @@
</button> </button>
</template> </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"> <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"> <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'"> <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> </template>
<script> <script>
import { useCodeSandbox, useStackBlitz } from './codeeditor'; import { useStackBlitz } from './codeeditor';
export default { export default {
inheritAttrs: false, inheritAttrs: false,
@ -91,7 +81,7 @@ export default {
}, },
hideCodeSandbox: { hideCodeSandbox: {
type: Boolean, type: Boolean,
default: false default: true
}, },
hideStackBlitz: { hideStackBlitz: {
type: Boolean, type: Boolean,
@ -142,9 +132,6 @@ export default {
async copyCode() { async copyCode() {
await navigator.clipboard.writeText(this.code[this.codeLang]); 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() { showStackblitz() {
useStackBlitz(this.codeLang, this.code[this.codeLang === 'data' ? 'options' : this.codeLang], this.service, this.code.pages, this.dependencies, this.component, this.extFiles); 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'; import { services } from './services';
const PrimeVue = { const PrimeVue = {
version: '^3.45.0', version: '^3.47.0',
description: 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.' '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 DynamicDialog from 'primevue/dynamicdialog';
import Fieldset from 'primevue/fieldset'; import Fieldset from 'primevue/fieldset';
import FileUpload from 'primevue/fileupload'; import FileUpload from 'primevue/fileupload';
import FloatLabel from 'primevue/floatlabel';
import FocusTrap from 'primevue/focustrap'; import FocusTrap from 'primevue/focustrap';
import Galleria from 'primevue/galleria'; import Galleria from 'primevue/galleria';
import IconField from 'primevue/iconfield';
import InputIcon from 'primevue/inputicon';
import Image from 'primevue/image'; import Image from 'primevue/image';
import InlineMessage from 'primevue/inlinemessage'; import InlineMessage from 'primevue/inlinemessage';
import Inplace from 'primevue/inplace'; import Inplace from 'primevue/inplace';

View File

@ -6,7 +6,7 @@
<ul class="list-none p-0 m-0"> <ul class="list-none p-0 m-0">
<li class="font-bold mb-5">General</li> <li class="font-bold mb-5">General</li>
<li class="mb-4"> <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>
<li class="mb-4"> <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> <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" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
style="border-radius: 50px" 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" 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 CSS Presets <i class="pi pi-arrow-right text-sm"></i >🎉 Introducing the Tailwind Presets <i class="pi pi-arrow-right text-sm"></i
></a> ></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> <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"> <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. 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> </p>
<div class="flex align-items-center gap-3"> <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> <span>Get Started</span>
<i class="pi pi-arrow-right ml-3"></i> <i class="pi pi-arrow-right ml-3"></i>
</PrimeVueNuxtLink> </PrimeVueNuxtLink>
@ -141,6 +141,12 @@
menuButton: { menuButton: {
width: 'auto', width: 'auto',
root: 'p-2' 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> <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> <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"> <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('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> <button type="button" :class="['font-medium linkbox mr-3 mt-4', { active: theme && theme.startsWith('bootstrap4') }]" @click="changeTheme('bootstrap4', 'blue')">Bootstrap</button>
</div> </div>
<div <div class="themes-main flex mt-7 justify-content-center px-5 lg:px-8">
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="box overflow-hidden z-1 p-5 table-container"> <div class="box overflow-hidden z-1 p-5 table-container">
<DataTable <DataTable
v-model:selection="selectedCustomers" v-model:selection="selectedCustomers"
@ -29,10 +26,12 @@
<template #header> <template #header>
<div class="flex flex-column sm:flex-row sm:justify-content-between sm:align-items-center"> <div class="flex flex-column sm:flex-row sm:justify-content-between sm:align-items-center">
<h5 class="m-0">Customers</h5> <h5 class="m-0">Customers</h5>
<span class="p-input-icon-left mt-3 sm:mt-0 w-full sm:w-auto"> <IconField iconPosition="left" class="mt-3 sm:mt-0 w-full sm:w-auto">
<i class="pi pi-search" /> <InputIcon>
<i class="pi pi-search" />
</InputIcon>
<InputText v-model="filters['global'].value" placeholder="Search" class="w-full" /> <InputText v-model="filters['global'].value" placeholder="Search" class="w-full" />
</span> </IconField>
</div> </div>
</template> </template>
<template #empty> No customers found. </template> <template #empty> No customers found. </template>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
<template> <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> <slot>
<span v-if="label" :class="cx('label')" v-bind="ptm('label')">{{ label }}</span> <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')" /> <component v-else-if="$slots.icon" :is="$slots.icon" :class="cx('icon')" />

View File

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

View File

@ -70,7 +70,7 @@ export interface BadgeProps {
/** /**
* Severity type of the badge. * 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'. * Size of the badge, valid options are 'large' and 'xlarge'.
*/ */

View File

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

View File

@ -49,7 +49,9 @@ const classes = {
'p-badge-info': props.severity === 'info', 'p-badge-info': props.severity === 'info',
'p-badge-success': props.severity === 'success', 'p-badge-success': props.severity === 'success',
'p-badge-warning': props.severity === 'warning', '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?.(); defaultHook?.();
} }
}, },
_mergeProps(fn, ...args) {
return ObjectUtils.isFunction(fn) ? fn(...args) : mergeProps(...args);
},
_loadGlobalStyles() { _loadGlobalStyles() {
/* /*
* @todo Add self custom css support; * @todo Add self custom css support;
@ -146,17 +149,27 @@ export default {
: ObjectUtils.getItemValue(options, params); : ObjectUtils.getItemValue(options, params);
}, },
_getPTValue(obj = {}, key = '', params = {}, searchInDefaultPT = true) { _getPTValue(obj = {}, key = '', params = {}, searchInDefaultPT = true) {
const datasetPrefix = 'data-pc-';
const searchOut = /./g.test(key) && !!params[key.split('.')[0]]; const searchOut = /./g.test(key) && !!params[key.split('.')[0]];
const { mergeSections = true, mergeProps: useMergeProps = false } = this._getPropValue('ptOptions') || this.$config?.ptOptions || {}; 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 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 self = searchOut ? undefined : this._usePT(this._getPT(obj, this.$name), this._getPTClassValue, key, { ...params, global: global || {} });
const datasets = key !== 'transition' && { const datasets = this._getPTDatasets(key);
...(key === 'root' && { [`${datasetPrefix}name`]: ObjectUtils.toFlatCase(this.$.type.name) }),
[`${datasetPrefix}section`]: ObjectUtils.toFlatCase(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) { _getPTClassValue(...args) {
const value = this._getOptionValue(...args); const value = this._getOptionValue(...args);
@ -192,7 +205,7 @@ export default {
else if (ObjectUtils.isString(value)) return value; else if (ObjectUtils.isString(value)) return value;
else if (ObjectUtils.isString(originalValue)) return originalValue; 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); 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 = ` const inputTextCSS = `
.p-fluid .p-inputtext { .p-fluid .p-inputtext {
width: 100%; 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-left,
.p-fluid .p-input-icon-right { .p-fluid .p-input-icon-right {
display: block;
width: 100%; 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 = ` const css = `
@layer primevue { @layer primevue {
.p-component, .p-component * { .p-component, .p-component * {
@ -348,9 +204,7 @@ const css = `
transition: max-height 1s ease-in-out; transition: max-height 1s ease-in-out;
} }
${buttonCSS} ${buttonCSS}
${checkboxCSS}
${inputTextCSS} ${inputTextCSS}
${radioButtonCSS}
} }
`; `;

View File

@ -22,16 +22,20 @@ const BaseDirective = {
return ObjectUtils.isString(value) || ObjectUtils.isArray(value) ? { class: value } : value; 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 { 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 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 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) }), ...(key === 'root' && { [`${datasetPrefix}name`]: ObjectUtils.toFlatCase(instance.$name) }),
[`${datasetPrefix}section`]: ObjectUtils.toFlatCase(key) [`${datasetPrefix}section`]: ObjectUtils.toFlatCase(key)
}; };
return mergeSections || (!mergeSections && self) ? (useMergeProps ? mergeProps(global, self, datasets) : { ...global, ...self, ...datasets }) : { ...self, ...datasets };
}, },
_getPT: (pt, key = '', callback) => { _getPT: (pt, key = '', callback) => {
const getValue = (value) => { const getValue = (value) => {
@ -61,7 +65,7 @@ const BaseDirective = {
else if (ObjectUtils.isString(value)) return value; else if (ObjectUtils.isString(value)) return value;
else if (ObjectUtils.isString(originalValue)) return originalValue; 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); return fn(pt);
@ -80,6 +84,9 @@ const BaseDirective = {
selfHook?.(instance, options); selfHook?.(instance, options);
defaultHook?.(instance, options); defaultHook?.(instance, options);
}, },
_mergeProps(instance = {}, fn, ...args) {
return ObjectUtils.isFunction(fn) ? fn(...args) : mergeProps(...args);
},
_extend: (name, options = {}) => { _extend: (name, options = {}) => {
const handleHook = (hook, el, binding, vnode, prevVnode) => { const handleHook = (hook, el, binding, vnode, prevVnode) => {
el._$instances = el._$instances || {}; el._$instances = el._$instances || {};
@ -112,6 +119,7 @@ const BaseDirective = {
el.$instance = el._$instances[name]; // pass instance data to hooks el.$instance = el._$instances[name]; // pass instance data to hooks
el.$instance[hook]?.(el, binding, vnode, prevVnode); // handle hook in directive implementation 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) 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) => { beforeMount: (el, binding, vnode, prevVnode) => {
const config = BaseDirective._getConfig(binding, vnode); const config = BaseDirective._getConfig(binding, vnode);
BaseStyle.loadStyle(undefined, { nonce: config?.csp?.nonce }); BaseStyle.loadStyle({ nonce: config?.csp?.nonce });
!el.$instance?.isUnstyled() && el.$instance?.$style?.loadStyle(undefined, { nonce: config?.csp?.nonce }); !el.$instance?.isUnstyled() && el.$instance?.$style?.loadStyle({ nonce: config?.csp?.nonce });
handleHook('beforeMount', el, binding, vnode, prevVnode); handleHook('beforeMount', el, binding, vnode, prevVnode);
}, },
mounted: (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); handleHook('mounted', el, binding, vnode, prevVnode);
}, },
beforeUpdate: (el, binding, vnode, prevVnode) => { beforeUpdate: (el, binding, vnode, prevVnode) => {

View File

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

View File

@ -1,5 +1,5 @@
<template> <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')"> <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')" /> <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"> <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. * 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. * Whether the button is in loading state.
* @defaultValue false * @defaultValue false
@ -137,7 +137,7 @@ export interface ButtonProps extends ButtonHTMLAttributes {
/** /**
* Defines the style of the button. * 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. * Add a shadow to indicate elevation.
* @defaultValue false * @defaultValue false

View File

@ -1,5 +1,5 @@
<template> <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>
<slot v-if="loading" name="loadingicon" :class="[cx('loadingIcon'), cx('icon')]"> <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')" /> <span v-if="loadingIcon" :class="[cx('loadingIcon'), cx('icon'), loadingIcon]" v-bind="ptm('loadingIcon')" />

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
<template> <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')"> <div v-if="$slots.header" :class="cx('header')" v-bind="ptm('header')">
<slot name="header"></slot> <slot name="header"></slot>
</div> </div>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
<template> <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> <canvas ref="canvas" :width="width" :height="height" @click="onCanvasClick($event)" v-bind="{ ...canvasProps, ...ptm('canvas') }"></canvas>
</div> </div>
</template> </template>

View File

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

View File

@ -7,7 +7,7 @@
* @module checkbox * @module checkbox
* *
*/ */
import { InputHTMLAttributes, VNode } from 'vue'; import { VNode } from 'vue';
import { ComponentHooks } from '../basecomponent'; import { ComponentHooks } from '../basecomponent';
import { PassThroughOptions } from '../passthrough'; import { PassThroughOptions } from '../passthrough';
import { ClassComponent, GlobalComponentConstructor, PassThrough } from '../ts-helpers'; import { ClassComponent, GlobalComponentConstructor, PassThrough } from '../ts-helpers';
@ -61,18 +61,14 @@ export interface CheckboxPassThroughOptions {
* Used to pass attributes to the input's DOM element. * Used to pass attributes to the input's DOM element.
*/ */
input?: CheckboxPassThroughOptionType; input?: CheckboxPassThroughOptionType;
/**
* Used to pass attributes to the box's DOM element.
*/
box?: CheckboxPassThroughOptionType;
/** /**
* Used to pass attributes to the icon's DOM element. * Used to pass attributes to the icon's DOM element.
*/ */
icon?: CheckboxPassThroughOptionType; 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. * Used to manage all lifecycle hooks.
* @see {@link BaseComponent.ComponentHooks} * @see {@link BaseComponent.ComponentHooks}
@ -91,11 +87,7 @@ export interface CheckboxPassThroughAttributes {
* Defines current inline state in Checkbox component. * Defines current inline state in Checkbox component.
*/ */
export interface CheckboxState { export interface CheckboxState {
/** [key: string]: any;
* Current focus state as a boolean.
* @defaultValue false
*/
focused: boolean;
} }
/** /**
@ -119,11 +111,21 @@ export interface CheckboxProps {
* @default false * @default false
*/ */
binary?: boolean; 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. * When present, it specifies that the element should be disabled.
* @default false * @default false
*/ */
disabled?: boolean | undefined; 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. * When present, it specifies that an input field is read-only.
* @default false * @default false
@ -160,10 +162,6 @@ export interface CheckboxProps {
* Inline style of the input field. * Inline style of the input field.
*/ */
inputStyle?: string | object | undefined; 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. * 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 * @defaultValue false
*/ */
checked: boolean; checked: boolean;
/**
* Current focus state of the item as a boolean.
* @defaultValue false
*/
focused: boolean;
/** /**
* Current disabled state of the item as a boolean. * Current disabled state of the item as a boolean.
* @defaultValue false * @defaultValue false
@ -235,25 +228,25 @@ export interface CheckboxSlots {
*/ */
export interface CheckboxEmits { export interface CheckboxEmits {
/** /**
* Emitted when the page changes. * Emitted when the value changes.
* @param {*} value - New page value. * @param {*} value - New value.
*/ */
'update:page'(value: any): void; 'update:modelValue'(value: any): void;
/**
* Callback to invoke on value click.
* @param {MouseEvent} event - Browser event.
*/
click(event: MouseEvent): void;
/** /**
* Callback to invoke on value change. * Callback to invoke on value change.
* @param {Event} event - Browser event. * @param {Event} event - Browser event.
*/ */
change(event: Event): void; change(event: Event): void;
/** /**
* Callback to invoke on value change. * Callback to invoke when the component receives focus.
* @param {boolean} value - New value. * @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 () => { it('should exist', async () => {
await wrapper.setProps({ modelValue: true }); await wrapper.setProps({ modelValue: true });
expect(wrapper.find('.p-checkbox-checked').exists()).toBe(true); expect(wrapper.find('.p-checkbox.p-highlight').exists()).toBe(true);
expect(wrapper.find('.p-checkbox-box.p-highlight').exists()).toBe(true);
}); });
}); });

View File

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

View File

@ -1,26 +1,43 @@
import BaseStyle from 'primevue/base/style'; 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 = { const classes = {
root: ({ instance, props }) => [ root: ({ instance, props }) => [
'p-checkbox p-component', '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-highlight': instance.checked,
'p-disabled': props.disabled, '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' icon: 'p-checkbox-icon'
}; };
export default BaseStyle.extend({ export default BaseStyle.extend({
name: 'checkbox', name: 'checkbox',
css,
classes classes
}); });

View File

@ -1,5 +1,5 @@
<template> <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> <slot>
<img v-if="image" :src="image" v-bind="ptm('image')" /> <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')" /> <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, type: String,
default: null default: null
}, },
variant: {
type: String,
default: null
},
invalid: {
type: Boolean,
default: false
},
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false

View File

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

View File

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

View File

@ -55,12 +55,18 @@ const classes = {
'p-chips p-component p-inputwrapper', 'p-chips p-component p-inputwrapper',
{ {
'p-disabled': props.disabled, 'p-disabled': props.disabled,
'p-invalid': props.invalid,
'p-focus': instance.focused, 'p-focus': instance.focused,
'p-inputwrapper-filled': (props.modelValue && props.modelValue.length) || (instance.inputValue && instance.inputValue.length), 'p-inputwrapper-filled': (props.modelValue && props.modelValue.length) || (instance.inputValue && instance.inputValue.length),
'p-inputwrapper-focus': instance.focused '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 }], token: ({ state, index }) => ['p-chips-token', { 'p-focus': state.focusedIndex === index }],
label: 'p-chips-token-label', label: 'p-chips-token-label',
removeTokenIcon: 'p-chips-token-icon', removeTokenIcon: 'p-chips-token-icon',

View File

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

View File

@ -54,7 +54,7 @@ export interface ColorPickerChangeEvent {
/** /**
* Browser event * Browser event
*/ */
originalEvent: Event; event: Event;
/** /**
* Selected color value. * Selected color value.
*/ */
@ -211,7 +211,7 @@ export interface ColorPickerEmits {
*/ */
'update:modelValue'(value: any): void; '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. * @param {ColorPickerChangeEvent} event - Custom add event.
*/ */
change(event: ColorPickerChangeEvent): void; change(event: ColorPickerChangeEvent): void;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,17 +28,17 @@
<component v-else :is="$slots.message" :message="confirmation"></component> <component v-else :is="$slots.message" :message="confirmation"></component>
</template> </template>
<template v-if="!$slots.container" #footer> <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"> <template v-if="rejectIcon || $slots.rejecticon" #icon="iconProps">
<slot name="rejecticon"> <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> </slot>
</template> </template>
</CDButton> </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"> <template v-if="acceptIcon || $slots.accepticon" #icon="iconProps">
<slot name="accepticon"> <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> </slot>
</template> </template>
</CDButton> </CDButton>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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