114 lines
3.9 KiB
JavaScript
114 lines
3.9 KiB
JavaScript
|
import { withDirectives as _withDirectives, resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
|
||
|
// Styles
|
||
|
import "./VStepperItem.css";
|
||
|
|
||
|
// Components
|
||
|
import { VAvatar } from "../VAvatar/VAvatar.mjs";
|
||
|
import { VIcon } from "../VIcon/VIcon.mjs"; // Composables
|
||
|
import { makeGroupItemProps, useGroupItem } from "../../composables/group.mjs"; // Directives
|
||
|
import { Ripple } from "../../directives/ripple/index.mjs"; // Utilities
|
||
|
import { computed } from 'vue';
|
||
|
import { VStepperSymbol } from "./VStepper.mjs";
|
||
|
import { genericComponent, propsFactory, useRender } from "../../util/index.mjs"; // Types
|
||
|
export const makeVStepperItemProps = propsFactory({
|
||
|
color: String,
|
||
|
title: String,
|
||
|
subtitle: String,
|
||
|
complete: Boolean,
|
||
|
completeIcon: {
|
||
|
type: String,
|
||
|
default: '$complete'
|
||
|
},
|
||
|
editable: Boolean,
|
||
|
editIcon: {
|
||
|
type: String,
|
||
|
default: '$edit'
|
||
|
},
|
||
|
error: Boolean,
|
||
|
errorIcon: {
|
||
|
type: String,
|
||
|
default: '$error'
|
||
|
},
|
||
|
icon: String,
|
||
|
ripple: {
|
||
|
type: [Boolean, Object],
|
||
|
default: true
|
||
|
},
|
||
|
rules: {
|
||
|
type: Array,
|
||
|
default: () => []
|
||
|
},
|
||
|
...makeGroupItemProps()
|
||
|
}, 'VStepperItem');
|
||
|
export const VStepperItem = genericComponent()({
|
||
|
name: 'VStepperItem',
|
||
|
directives: {
|
||
|
Ripple
|
||
|
},
|
||
|
props: makeVStepperItemProps(),
|
||
|
emits: {
|
||
|
'group:selected': val => true
|
||
|
},
|
||
|
setup(props, _ref) {
|
||
|
let {
|
||
|
slots
|
||
|
} = _ref;
|
||
|
const group = useGroupItem(props, VStepperSymbol, true);
|
||
|
const step = computed(() => group?.value.value ?? props.value);
|
||
|
const isValid = computed(() => props.rules.every(handler => handler() === true));
|
||
|
const canEdit = computed(() => !props.disabled && props.editable);
|
||
|
const hasError = computed(() => props.error || !isValid.value);
|
||
|
const hasCompleted = computed(() => props.complete || props.rules.length > 0 && isValid.value);
|
||
|
const icon = computed(() => {
|
||
|
if (hasError.value) return props.errorIcon;
|
||
|
if (hasCompleted.value) return props.completeIcon;
|
||
|
if (props.editable) return props.editIcon;
|
||
|
return props.icon;
|
||
|
});
|
||
|
const slotProps = computed(() => ({
|
||
|
canEdit: canEdit.value,
|
||
|
hasError: hasError.value,
|
||
|
hasCompleted: hasCompleted.value,
|
||
|
title: props.title,
|
||
|
subtitle: props.subtitle,
|
||
|
step: step.value,
|
||
|
value: props.value
|
||
|
}));
|
||
|
useRender(() => {
|
||
|
const hasColor = (!group || group.isSelected.value || hasCompleted.value || canEdit.value) && !hasError.value && !props.disabled;
|
||
|
const hasTitle = !!(props.title != null || slots.title);
|
||
|
const hasSubtitle = !!(props.subtitle != null || slots.subtitle);
|
||
|
function onClick() {
|
||
|
group?.toggle();
|
||
|
}
|
||
|
return _withDirectives(_createVNode("button", {
|
||
|
"class": ['v-stepper-item', {
|
||
|
'v-stepper-item--complete': hasCompleted.value,
|
||
|
'v-stepper-item--disabled': props.disabled,
|
||
|
'v-stepper-item--error': hasError.value
|
||
|
}, group?.selectedClass.value],
|
||
|
"disabled": !props.editable,
|
||
|
"onClick": onClick
|
||
|
}, [_createVNode(VAvatar, {
|
||
|
"key": "stepper-avatar",
|
||
|
"class": "v-stepper-item__avatar",
|
||
|
"color": hasColor ? props.color : undefined,
|
||
|
"size": 24
|
||
|
}, {
|
||
|
default: () => [slots.icon?.(slotProps.value) ?? (icon.value ? _createVNode(VIcon, {
|
||
|
"icon": icon.value
|
||
|
}, null) : step.value)]
|
||
|
}), _createVNode("div", {
|
||
|
"class": "v-stepper-item__content"
|
||
|
}, [hasTitle && _createVNode("div", {
|
||
|
"key": "title",
|
||
|
"class": "v-stepper-item__title"
|
||
|
}, [slots.title?.(slotProps.value) ?? props.title]), hasSubtitle && _createVNode("div", {
|
||
|
"key": "subtitle",
|
||
|
"class": "v-stepper-item__subtitle"
|
||
|
}, [slots.subtitle?.(slotProps.value) ?? props.subtitle]), slots.default?.(slotProps.value)])]), [[_resolveDirective("ripple"), props.ripple && props.editable, null]]);
|
||
|
});
|
||
|
return {};
|
||
|
}
|
||
|
});
|
||
|
//# sourceMappingURL=VStepperItem.mjs.map
|