Skip to content

Commit

Permalink
Fixed #5823 #5824 - New Stepper implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
tugcekucukoglu committed Jun 4, 2024
1 parent ff0df14 commit 033a50f
Show file tree
Hide file tree
Showing 51 changed files with 1,571 additions and 693 deletions.
34 changes: 34 additions & 0 deletions components/lib/step/BaseStep.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<script>
import BaseComponent from 'primevue/basecomponent';
import StepStyle from 'primevue/step/style';
export default {
name: 'BaseStep',
extends: BaseComponent,
props: {
value: {
type: [String, Number],
default: undefined
},
disabled: {
type: Boolean,
default: false
},
asChild: {
type: Boolean,
default: false
},
as: {
type: String,
default: 'DIV'
}
},
style: StepStyle,
provide() {
return {
$pcStep: this,
$parentInstance: this
};
}
};
</script>
187 changes: 187 additions & 0 deletions components/lib/step/Step.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/**
*
* Step is a helper component for Stepper component.
*
* [Live Demo](https://www.primevue.org/stepper/)
*
* @module step
*
*/
import { VNode } from 'vue';
import { ComponentHooks } from '../basecomponent';
import { PassThroughOptions } from '../passthrough';
import { DefineComponent, DesignToken, EmitFn, GlobalComponentConstructor, PassThrough } from '../ts-helpers';

export declare type StepPassThroughOptionType = StepPassThroughAttributes | ((options: StepPassThroughMethodOptions) => StepPassThroughAttributes | string) | string | null | undefined;

/**
* Custom passthrough(pt) option method.
*/
export interface StepPassThroughMethodOptions {
/**
* Defines instance.
*/
instance: any;
/**
* Defines valid properties.
*/
props: StepProps;
/**
* Defines current options.
*/
context: StepContext;
/**
* Defines valid attributes.
*/
attrs: any;
/**
* Defines parent options.
*/
parent: any;
/**
* Defines passthrough(pt) options in global config.
*/
global: object | undefined;
}

/**
* Custom passthrough(pt) options.
* @see {@link StepProps.pt}
*/
export interface StepPassThroughOptions {
/**
* Used to pass attributes to the root's DOM element.
*/
root?: StepPassThroughOptionType;
/**
* Used to pass attributes to the header's DOM element.
*/
header?: StepPassThroughOptionType;
/**
* Used to pass attributes to the number's DOM element.
*/
number?: StepPassThroughOptionType;
/**
* Used to pass attributes to the title's DOM element.
*/
title?: StepPassThroughOptionType;
/**
* Used to manage all lifecycle hooks.
* @see {@link BaseComponent.ComponentHooks}
*/
hooks?: ComponentHooks;
}

export interface StepPassThroughAttributes {
[key: string]: any;
}

/**
* Defines valid properties in Step component.
*/
export interface StepProps {
/**
* Value of step.
*/
value?: string | number | undefined;
/**
* Whether the step is disabled.
* @defaultValue false
*/
disabled?: boolean | undefined;
/**
* Use to change the HTML tag of root element.
* @defaultValue BUTTON
*/
as?: string | undefined;
/**
* When enabled, it changes the default rendered element for the one passed as a child element.
* @defaultValue false
*/
asChild?: boolean | undefined;
/**
* It generates scoped CSS variables using design tokens for the component.
*/
dt?: DesignToken<any>;
/**
* Used to pass attributes to DOM elements inside the component.
* @type {StepPassThroughOptions}
*/
pt?: PassThrough<StepPassThroughOptions>;
/**
* Used to configure passthrough(pt) options of the component.
* @type {PassThroughOptions}
*/
ptOptions?: PassThroughOptions;
}

/**
* Defines current options in Step component.
*/
export interface StepContext {
/**
* Whether the step is active.
*/
active: boolean;
/**
* Whether the step is disabled.
*/
disabled: boolean;
}

/**
* Defines valid slots in Step slots.
*/
export interface StepSlots {
/**
* Custom content template. Slot attributes can be used when asChild prop is true.
*/
default(scope: {
/**
* Style class of the loader.
*/
class: string;
/**
* Whether the step is active.
*/
active: boolean;
/**
* Value of step.
*/
value: string | number;
/**
* A11t attributes
*/
a11yAttrs: any;
/**
* Click function.
*/
activateCallback: () => void;
}): VNode[];
}

export interface StepEmitsOptions {}

export declare type StepEmits = EmitFn<StepEmitsOptions>;

/**
* **PrimeVue - Step**
*
* _Step is a helper component for Stepper component._
*
* [Live Demo](https://www.primevue.org/stepper/)
* --- ---
* ![PrimeVue](https://primefaces.org/cdn/primevue/images/logo-100.png)
*
* @group Component
*
*/
declare const Step: DefineComponent<StepProps, StepSlots, StepEmits>;

declare module 'vue' {
export interface GlobalComponents {
Step: GlobalComponentConstructor<StepProps, StepSlots, StepEmits>;
}
}

export default Step;
98 changes: 98 additions & 0 deletions components/lib/step/Step.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<template>
<component v-if="!asChild" :is="as" :class="cx('root')" :aria-current="active ? 'step' : undefined" role="presentation" :data-p-active="active" :data-p-disabled="disabled" v-bind="getPTOptions('root')">
<button :id="id" :class="cx('header')" role="tab" type="button" :tabindex="disabled ? -1 : undefined" :aria-controls="ariaControls" :disabled="disabled" @click="onStepClick" v-bind="getPTOptions('header')">
<span :class="cx('number')" v-bind="getPTOptions('number')">{{ activeValue }}</span>
<span :class="cx('title')" v-bind="getPTOptions('title')">
<slot />
</span>
</button>
<StepperSeparator v-if="isSeparatorVisible" />
</component>
<slot v-else :class="cx('root')" :active="active" :value="value" :a11yAttrs="a11yAttrs" :activateCallback="onStepClick" />
</template>

<script>
import { DomHandler, ObjectUtils } from 'primevue/utils';
import StepperSeparator from '../stepper/StepperSeparator.vue';
import BaseStep from './BaseStep.vue';
export default {
name: 'Step',
extends: BaseStep,
inheritAttrs: false,
inject: {
$pcStepper: { default: null },
$pcStepList: { default: null },
$pcStepItem: { default: null }
},
data() {
return {
isSeparatorVisible: false
};
},
mounted() {
if (this.$el && this.$pcStepList) {
let index = ObjectUtils.findIndexInList(this.$el, DomHandler.find(this.$pcStepper.$el, '[data-pc-name="step"]'));
let stepLen = DomHandler.find(this.$pcStepper.$el, '[data-pc-name="step"]').length;
this.isSeparatorVisible = index !== stepLen - 1;
}
},
methods: {
getPTOptions(key) {
const _ptm = key === 'root' ? this.ptmi : this.ptm;
return _ptm(key, {
context: {
active: this.active,
disabled: this.disabled
}
});
},
isStepDisabled() {
return this.$pcStepper.isStepDisabled();
},
onStepClick() {
this.$pcStepper.updateValue(this.activeValue);
}
},
computed: {
active() {
return this.$pcStepper.isStepActive(this.activeValue);
},
activeValue() {
return !!this.$pcStepItem ? this.$pcStepItem?.value : this.value;
},
id() {
return `${this.$pcStepper?.id}_step_${this.activeValue}`;
},
ariaControls() {
return `${this.$pcStepper?.id}_steppanel_${this.activeValue}`;
},
a11yAttrs() {
return {
root: {
role: 'presentation',
'aria-current': this.active ? 'step' : undefined,
'data-pc-name': 'step',
'data-pc-section': 'root',
'data-p-disabled': this.disabled,
'data-p-active': this.active
},
header: {
id: this.id,
role: 'tab',
taindex: this.disabled ? -1 : undefined,
'aria-controls': this.ariaControls,
'data-pc-section': 'header',
disabled: this.disabled,
onClick: this.onStepClick
}
};
}
},
components: {
StepperSeparator
}
};
</script>
11 changes: 11 additions & 0 deletions components/lib/step/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"main": "./step.mjs",
"module": "./step.mjs",
"types": "./Step.d.ts",
"browser": {
"./sfc": "./Step.vue"
},
"sideEffects": [
"*.vue"
]
}
31 changes: 31 additions & 0 deletions components/lib/step/style/StepStyle.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
*
* Step is a helper component for Stepper component.
*
* [Live Demo](https://www.primevue.org/stepper/)
*
* @module stepstyle
*
*/
import { BaseStyle } from '../../base/style';

export enum StepClasses {
/**
* Class name of the root element
*/
root = 'p-step',
/**
* Class name of the header element
*/
header = 'p-step-header',
/**
* Class name of the number element
*/
number = 'p-step-number',
/**
* Class name of the title element
*/
title = 'p-step-title'
}

export interface StepStyle extends BaseStyle {}
19 changes: 19 additions & 0 deletions components/lib/step/style/StepStyle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import BaseStyle from 'primevue/base/style';

const classes = {
root: ({ instance, props }) => [
'p-step',
{
'p-step-active': instance.active,
'p-disabled': instance.isStepDisabled() || props.disabled
}
],
header: 'p-step-header',
number: 'p-step-number',
title: 'p-step-title'
};

export default BaseStyle.extend({
name: 'step',
classes
});
6 changes: 6 additions & 0 deletions components/lib/step/style/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"main": "./stepstyle.mjs",
"module": "./stepstyle.mjs",
"types": "./StepStyle.d.ts",
"sideEffects": false
}
Loading

0 comments on commit 033a50f

Please sign in to comment.