Fixed #6511 - ToggleButton: handle element added

pull/6537/head
tugcekucukoglu 2024-10-02 10:03:15 +03:00
parent 28053d5ee8
commit b008b7901d
5 changed files with 64 additions and 15 deletions

View File

@ -10,6 +10,7 @@
import type { DefineComponent, DesignToken, EmitFn, GlobalComponentConstructor, PassThrough } from '@primevue/core'; import type { DefineComponent, DesignToken, EmitFn, GlobalComponentConstructor, PassThrough } from '@primevue/core';
import type { ComponentHooks } from '@primevue/core/basecomponent'; import type { ComponentHooks } from '@primevue/core/basecomponent';
import type { PassThroughOptions } from 'primevue/passthrough'; import type { PassThroughOptions } from 'primevue/passthrough';
import { VNode } from 'vue';
export declare type ToggleSwitchPassThroughOptionType = ToggleSwitchPassThroughAttributes | ((options: ToggleSwitchPassThroughMethodOptions) => ToggleSwitchPassThroughAttributes | string) | string | null | undefined; export declare type ToggleSwitchPassThroughOptionType = ToggleSwitchPassThroughAttributes | ((options: ToggleSwitchPassThroughMethodOptions) => ToggleSwitchPassThroughAttributes | string) | string | null | undefined;
@ -60,6 +61,14 @@ export interface ToggleSwitchPassThroughOptions {
* Used to pass attributes to the slider's DOM element. * Used to pass attributes to the slider's DOM element.
*/ */
slider?: ToggleSwitchPassThroughOptionType; slider?: ToggleSwitchPassThroughOptionType;
/**
* Used to pass attributes to the handle's DOM element.
*/
handle?: ToggleSwitchPassThroughOptionType;
/**
* Used to pass attributes to the icon's DOM element.
*/
icon?: ToggleSwitchPassThroughOptionType;
/** /**
* Used to manage all lifecycle hooks. * Used to manage all lifecycle hooks.
* @see {@link BaseComponent.ComponentHooks} * @see {@link BaseComponent.ComponentHooks}
@ -169,7 +178,18 @@ export interface ToggleSwitchContext {
disabled: boolean; disabled: boolean;
} }
export interface ToggleSwitchSlots {} export interface ToggleSwitchSlots {
/**
* Custom icon template.
* @param {Object} scope - icon slot's params.
*/
icon(scope: {
/**
* Current checked state of the item as a boolean.
*/
checked: boolean;
}): VNode[];
}
/** /**
* Defines valid emits in ToggleSwitch component. * Defines valid emits in ToggleSwitch component.

View File

@ -19,12 +19,21 @@
@change="onChange" @change="onChange"
v-bind="getPTOptions('input')" v-bind="getPTOptions('input')"
/> />
<span :class="cx('slider')" v-bind="getPTOptions('slider')"></span> <span :class="cx('slider')" v-bind="getPTOptions('slider')">
<span :class="cx('handle')" v-bind="getPTOptions('handle')">
<slot name="icon" :checked="checked">
<CheckIcon v-if="checked" :class="cx('icon')" v-bind="getPTOptions('icon')" />
<TimesIcon v-else :class="cx('icon')" v-bind="getPTOptions('icon')" />
</slot>
</span>
</span>
</div> </div>
</template> </template>
<script> <script>
import BaseToggleSwitch from './BaseToggleSwitch.vue'; import BaseToggleSwitch from './BaseToggleSwitch.vue';
import TimesIcon from '@primevue/icons/times';
import CheckIcon from '@primevue/icons/check';
export default { export default {
name: 'ToggleSwitch', name: 'ToggleSwitch',
@ -61,6 +70,10 @@ export default {
checked() { checked() {
return this.modelValue === this.trueValue; return this.modelValue === this.trueValue;
} }
},
components: {
CheckIcon,
TimesIcon
} }
}; };
</script> </script>

View File

@ -21,7 +21,15 @@ export enum ToggleSwitchClasses {
/** /**
* Class name of the slider element * Class name of the slider element
*/ */
slider = 'p-toggleswitch-slider' slider = 'p-toggleswitch-slider',
/**
* Class name of the handle element
*/
handle = 'p-toggleswitch-handle',
/**
* Class name of the icon element
*/
icon = 'p-toggleswitch-handle'
} }
export interface ToggleSwitchStyle extends BaseStyle {} export interface ToggleSwitchStyle extends BaseStyle {}

View File

@ -40,10 +40,12 @@ const theme = ({ dt }) => `
box-shadow: ${dt('toggleswitch.shadow')}; box-shadow: ${dt('toggleswitch.shadow')};
} }
.p-toggleswitch-slider:before { .p-toggleswitch-handle {
position: absolute; position: absolute;
content: "";
top: 50%; top: 50%;
display: flex;
justify-content: center;
align-items: center;
background: ${dt('toggleswitch.handle.background')}; background: ${dt('toggleswitch.handle.background')};
width: ${dt('toggleswitch.handle.size')}; width: ${dt('toggleswitch.handle.size')};
height: ${dt('toggleswitch.handle.size')}; height: ${dt('toggleswitch.handle.size')};
@ -58,7 +60,7 @@ const theme = ({ dt }) => `
border-color: ${dt('toggleswitch.checked.border.color')}; border-color: ${dt('toggleswitch.checked.border.color')};
} }
.p-toggleswitch.p-toggleswitch-checked .p-toggleswitch-slider:before { .p-toggleswitch.p-toggleswitch-checked .p-toggleswitch-handle {
background: ${dt('toggleswitch.handle.checked.background')}; background: ${dt('toggleswitch.handle.checked.background')};
left: calc(${dt('toggleswitch.width')} - calc(${dt('toggleswitch.handle.size')} + ${dt('toggleswitch.gap')})); left: calc(${dt('toggleswitch.width')} - calc(${dt('toggleswitch.handle.size')} + ${dt('toggleswitch.gap')}));
} }
@ -68,7 +70,7 @@ const theme = ({ dt }) => `
border-color: ${dt('toggleswitch.hover.border.color')}; border-color: ${dt('toggleswitch.hover.border.color')};
} }
.p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:hover) .p-toggleswitch-slider:before { .p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:hover) .p-toggleswitch-handle {
background: ${dt('toggleswitch.handle.hover.background')}; background: ${dt('toggleswitch.handle.hover.background')};
} }
@ -77,7 +79,7 @@ const theme = ({ dt }) => `
border-color: ${dt('toggleswitch.checked.hover.border.color')}; border-color: ${dt('toggleswitch.checked.hover.border.color')};
} }
.p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:hover).p-toggleswitch-checked .p-toggleswitch-slider:before { .p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:hover).p-toggleswitch-checked .p-toggleswitch-handle {
background: ${dt('toggleswitch.handle.checked.hover.background')}; background: ${dt('toggleswitch.handle.checked.hover.background')};
} }
@ -99,7 +101,7 @@ const theme = ({ dt }) => `
background: ${dt('toggleswitch.disabled.background')}; background: ${dt('toggleswitch.disabled.background')};
} }
.p-toggleswitch.p-disabled .p-toggleswitch-slider:before { .p-toggleswitch.p-disabled .p-toggleswitch-handle {
background: ${dt('toggleswitch.handle.disabled.background')}; background: ${dt('toggleswitch.handle.disabled.background')};
} }
`; `;
@ -118,7 +120,9 @@ const classes = {
} }
], ],
input: 'p-toggleswitch-input', input: 'p-toggleswitch-input',
slider: 'p-toggleswitch-slider' slider: 'p-toggleswitch-slider',
handle: 'p-toggleswitch-handle',
icon: 'p-toggleswitch-icon'
}; };
export default BaseStyle.extend({ export default BaseStyle.extend({

View File

@ -58,24 +58,28 @@ export default {
} }
}, },
style: ({ dt }) => ` style: ({ dt }) => `
.p-toggleswitch-slider:before { .p-toggleswitch-handle {
box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
} }
.p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:hover) .p-toggleswitch-slider:before { .p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:hover) .p-toggleswitch-handle {
box-shadow: 0 0 1px 10px color-mix(in srgb, ${dt('text.color')}, transparent 96%), 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); box-shadow: 0 0 1px 10px color-mix(in srgb, ${dt('text.color')}, transparent 96%), 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
} }
.p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:focus-visible) .p-toggleswitch-slider:before { .p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:focus-visible) .p-toggleswitch-handle {
box-shadow: 0 0 1px 10px color-mix(in srgb, ${dt('text.color')}, transparent 88%), 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); box-shadow: 0 0 1px 10px color-mix(in srgb, ${dt('text.color')}, transparent 88%), 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
} }
.p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:hover).p-toggleswitch-checked .p-toggleswitch-slider:before { .p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:hover).p-toggleswitch-checked .p-toggleswitch-handle {
box-shadow: 0 0 1px 10px color-mix(in srgb, ${dt('toggleswitch.handle.checked.background')}, transparent 92%), 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); box-shadow: 0 0 1px 10px color-mix(in srgb, ${dt('toggleswitch.handle.checked.background')}, transparent 92%), 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
} }
.p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:focus-visible).p-toggleswitch-checked .p-toggleswitch-slider:before { .p-toggleswitch:not(.p-disabled):has(.p-toggleswitch-input:focus-visible).p-toggleswitch-checked .p-toggleswitch-handle {
box-shadow: 0 0 1px 10px color-mix(in srgb, ${dt('toggleswitch.handle.checked.background')}, transparent 84%), 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); box-shadow: 0 0 1px 10px color-mix(in srgb, ${dt('toggleswitch.handle.checked.background')}, transparent 84%), 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);
} }
.p-toggleswitch-icon {
display: none !important;
}
` `
}; };