diff --git a/api-generator/components/speeddial.js b/api-generator/components/speeddial.js index 5ea2a60282..84fc6ad58a 100644 --- a/api-generator/components/speeddial.js +++ b/api-generator/components/speeddial.js @@ -106,6 +106,12 @@ const SpeedDialProps = [ type: 'object', default: 'null', description: "Whether to display the tooltip on items. The modifiers of tooltip can be used like an object in it. Valid keys are 'event' and 'position'." + }, + { + name: 'pt', + type: 'any', + default: 'null', + description: 'Uses to pass attributes to DOM elements inside the component.' } ]; diff --git a/components/lib/speeddial/SpeedDial.d.ts b/components/lib/speeddial/SpeedDial.d.ts index ca2250df62..0cb25a052e 100644 --- a/components/lib/speeddial/SpeedDial.d.ts +++ b/components/lib/speeddial/SpeedDial.d.ts @@ -11,6 +11,92 @@ import { VNode } from 'vue'; import { MenuItem } from '../menuitem'; import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers'; +export declare type SpeedDialPassThroughOptionType = SpeedDialPassThroughAttributes | ((options: SpeedDialPassThroughMethodOptions) => SpeedDialPassThroughAttributes) | null | undefined; + +/** + * Custom passthrough(pt) option method. + */ +export interface SpeedDialPassThroughMethodOptions { + props: SpeedDialProps; + state: SpeedDialState; +} + +/** + * Custom passthrough(pt) options. + * @see {@link SpeedDialProps.pt} + */ +export interface SpeedDialPassThroughOptions { + /** + * Uses to pass attributes to the root's DOM element. + */ + root?: SpeedDialPassThroughOptionType; + /** + * Uses to pass attributes to the button's DOM element. + */ + button?: SpeedDialPassThroughOptionType; + /** + * Uses to pass attributes to the icon's DOM element. + */ + icon?: SpeedDialPassThroughOptionType; + /** + * Uses to pass attributes to the list's DOM element. + */ + list?: SpeedDialPassThroughOptionType; + /** + * Uses to pass attributes to the item's DOM element. + */ + item?: SpeedDialPassThroughOptionType; + /** + * Uses to pass attributes to the action's DOM element. + */ + action?: SpeedDialPassThroughOptionType; + /** + * Uses to pass attributes to the action icon's DOM element. + */ + actionIcon?: SpeedDialPassThroughOptionType; + /** + * Uses to pass attributes to the mask's DOM element. + */ + mask?: SpeedDialPassThroughOptionType; +} + +/** + * Custom passthrough attributes for each DOM elements + */ +export interface SpeedDialPassThroughAttributes { + [key: string]: any; +} + +/** + * Defines current inline state in SpeedDial component. + */ +export interface SpeedDialState { + /** + * List of items' id. + */ + id: string; + /** + * Current visible state as a boolean. + * @defaultValue false + */ + visible: boolean; + /** + * Current click state of component as a boolean. + * @defaultValue false + */ + isItemClicked: boolean; + /** + * Current focus state as a boolean. + * @defaultValue false + */ + focused: boolean; + /** + * Current focused option index as a number. + * @defaultValue -1 + */ + focusedOptionIndex: number; +} + /** * Defines tooltip options. * @see {@link SpeedDialProps.tooltipOptions} @@ -127,6 +213,11 @@ export interface SpeedDialProps { * Identifier of the underlying list element. */ 'aria-labelledby'?: string | undefined; + /** + * Uses to pass attributes to DOM elements inside the component. + * @type {SpeedDialPassThroughOptions} + */ + pt?: SpeedDialPassThroughOptions; } /** diff --git a/components/lib/speeddial/SpeedDial.vue b/components/lib/speeddial/SpeedDial.vue index 3e65dfb930..4c0ae13c18 100644 --- a/components/lib/speeddial/SpeedDial.vue +++ b/components/lib/speeddial/SpeedDial.vue @@ -1,5 +1,5 @@ <template> - <div :ref="containerRef" :class="containerClass" :style="style"> + <div :ref="containerRef" :class="containerClass" :style="style" v-bind="ptm('root')"> <slot name="button" :toggle="onClick"> <SDButton type="button" @@ -12,18 +12,19 @@ :aria-controls="id + '_list'" :aria-label="ariaLabel" :aria-labelledby="ariaLabelledby" + v-bind="ptm('button')" > <template #icon> <slot name="icon" :visible="d_visible"> - <component v-if="d_visible && !!hideIcon" :is="hideIcon ? 'span' : 'PlusIcon'" :class="hideIcon" /> - <component v-else :is="showIcon ? 'span' : 'PlusIcon'" :class="showIcon" /> + <component v-if="d_visible && !!hideIcon" :is="hideIcon ? 'span' : 'PlusIcon'" :class="hideIcon" v-bind="ptm('icon')" /> + <component v-else :is="showIcon ? 'span' : 'PlusIcon'" :class="showIcon" v-bind="ptm('icon')" /> </slot> </template> </SDButton> </slot> - <ul :ref="listRef" :id="id + '_list'" class="p-speeddial-list" role="menu" @focus="onFocus" @blur="onBlur" @keydown="onKeyDown" :aria-activedescendant="focused ? focusedOptionId : undefined" tabindex="-1"> + <ul :ref="listRef" :id="id + '_list'" class="p-speeddial-list" role="menu" @focus="onFocus" @blur="onBlur" @keydown="onKeyDown" :aria-activedescendant="focused ? focusedOptionId : undefined" tabindex="-1" v-bind="ptm('list')"> <template v-for="(item, index) of model" :key="index"> - <li v-if="isItemVisible(item)" :id="`${id}_${index}`" :aria-controls="`${id}_item`" class="p-speeddial-item" :class="itemClass(`${id}_${index}`)" :style="getItemStyle(index)" role="menuitem"> + <li v-if="isItemVisible(item)" :id="`${id}_${index}`" :aria-controls="`${id}_item`" class="p-speeddial-item" :class="itemClass(`${id}_${index}`)" :style="getItemStyle(index)" role="menuitem" v-bind="ptm('item')"> <template v-if="!$slots.item"> <a v-tooltip:[tooltipOptions]="{ value: item.label, disabled: !tooltipOptions }" @@ -35,8 +36,9 @@ :target="item.target" @click="onItemClick($event, item)" :aria-label="item.label" + v-bind="ptm('action')" > - <span v-if="item.icon" :class="['p-speeddial-action-icon', item.icon]"></span> + <span v-if="item.icon" :class="['p-speeddial-action-icon', item.icon]" v-bind="ptm('actionIcon')"></span> </a> </template> <component v-else :is="$slots.item" :item="item"></component> @@ -45,11 +47,12 @@ </ul> </div> <template v-if="mask"> - <div :class="maskClassName" :style="maskStyle"></div> + <div :class="maskClassName" :style="maskStyle" v-bind="ptm('mask')"></div> </template> </template> <script> +import BaseComponent from 'primevue/basecomponent'; import Button from 'primevue/button'; import PlusIcon from 'primevue/icons/plus'; import Ripple from 'primevue/ripple'; @@ -58,6 +61,7 @@ import { DomHandler, UniqueComponentId } from 'primevue/utils'; export default { name: 'SpeedDial', + extends: BaseComponent, emits: ['click', 'show', 'hide', 'focus', 'blur'], props: { model: null,