Skip to content

Commit

Permalink
refactor: rollback groupActivatorActivatable & move activate group ac…
Browse files Browse the repository at this point in the history
…tivator as treeview dedicated logic
  • Loading branch information
yuwu9145 committed May 11, 2024
1 parent b49a70b commit d13e68f
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 20 deletions.
2 changes: 1 addition & 1 deletion packages/vuetify/src/components/VList/VListGroup.tsx
Expand Up @@ -78,7 +78,7 @@ export const VListGroup = genericComponent<VListGroupSlots>()({
const toggleIcon = computed(() => isOpen.value ? props.collapseIcon : props.expandIcon)
const activatorDefaults = computed(() => ({
VListItem: {
// active: isOpen.value,
active: isOpen.value,
activeColor: props.activeColor,
baseColor: props.baseColor,
color: props.color,
Expand Down
9 changes: 9 additions & 0 deletions packages/vuetify/src/components/VList/VListItem.sass
Expand Up @@ -318,3 +318,12 @@

.v-list-group__items .v-list-item
padding-inline-start: calc(#{$base-padding} + var(--indent-padding)) !important

// .v-list-group__header.v-list-item--active
// &:not(:focus-visible)
// .v-list-item__overlay
// opacity: 0
// &:hover
// .v-list-item__overlay
// opacity: calc(#{map.get(settings.$states, 'hover')} * var(--v-theme-overlay-multiplier))
14 changes: 4 additions & 10 deletions packages/vuetify/src/components/VList/VListItem.tsx
Expand Up @@ -28,7 +28,7 @@ import { Ripple } from '@/directives/ripple'

// Utilities
import { computed, watch } from 'vue'
import { deprecate, EventProp, genericComponent, noop, propsFactory, useRender } from '@/util'
import { deprecate, EventProp, genericComponent, propsFactory, useRender } from '@/util'

// Types
import type { PropType } from 'vue'
Expand Down Expand Up @@ -173,13 +173,12 @@ export const VListItem = genericComponent<VListItemSlots>()({

function onClick (e: MouseEvent) {
emit('click', e)
}
function onSelect (e: MouseEvent) {

if (!isClickable.value) return

link.navigate?.(e)

if (!root.groupActivatorActivatable && isGroupActivator) return
if (isGroupActivator) return

if (root.activatable.value) {
activate(!isActivated.value, e)
Expand Down Expand Up @@ -242,10 +241,7 @@ export const VListItem = genericComponent<VListItemSlots>()({
]}
href={ link.href.value }
tabindex={ isClickable.value ? (list ? -2 : 0) : undefined }
onClick={[
onSelect,
root.groupActivatorActivatable ? () => noop : onClick,
]}
onClick={ onClick }
onKeydown={ isClickable.value && !isLink.value && onKeyDown }
v-ripple={ isClickable.value && props.ripple }
>
Expand All @@ -268,7 +264,6 @@ export const VListItem = genericComponent<VListItemSlots>()({
key="prepend-icon"
density={ props.density }
icon={ props.prependIcon }
onClick={ root.groupActivatorActivatable ? onClick : () => noop }
/>
)}
</>
Expand Down Expand Up @@ -323,7 +318,6 @@ export const VListItem = genericComponent<VListItemSlots>()({
key="append-icon"
density={ props.density }
icon={ props.appendIcon }
onClick={ root.groupActivatorActivatable ? onClick : () => noop }
/>
)}

Expand Down
5 changes: 1 addition & 4 deletions packages/vuetify/src/composables/nested/nested.ts
Expand Up @@ -45,7 +45,6 @@ export type OpenStrategyProp = 'single' | 'multiple' | 'list' | OpenStrategy

export interface NestedProps {
activatable: boolean
groupActivatorActivatable: boolean
selectable: boolean
activeStrategy: ActiveStrategyProp | undefined
selectStrategy: SelectStrategyProp | undefined
Expand All @@ -67,7 +66,6 @@ type NestedProvide = {
parents: Ref<Map<unknown, unknown>>
activatable: Ref<boolean>
selectable: Ref<boolean>
groupActivatorActivatable: Ref<boolean>
opened: Ref<Set<unknown>>
activated: Ref<Set<unknown>>
selected: Ref<Map<unknown, 'on' | 'off' | 'indeterminate'>>
Expand Down Expand Up @@ -95,7 +93,6 @@ export const emptyNested: NestedProvide = {
activate: () => null,
select: () => null,
activatable: ref(false),
groupActivatorActivatable: ref(false),
selectable: ref(false),
opened: ref(new Set()),
activated: ref(new Set()),
Expand Down Expand Up @@ -199,7 +196,6 @@ export const useNested = (props: NestedProps) => {
root: {
opened,
activatable: toRef(props, 'activatable'),
groupActivatorActivatable: toRef(props, 'groupActivatorActivatable'),
selectable: toRef(props, 'selectable'),
activated,
selected,
Expand Down Expand Up @@ -340,3 +336,4 @@ export const useNestedGroupActivator = () => {

provide(VNestedSymbol, { ...parent, isGroupActivator: true })
}

14 changes: 14 additions & 0 deletions packages/vuetify/src/labs/VTreeview/VTreeviewItem.sass
@@ -1,4 +1,6 @@
@use 'sass:map'
@use '../../styles/tools'
@use '../../styles/settings'
@use './variables' as *

@include tools.layer('components')
Expand All @@ -19,3 +21,15 @@

.v-list-group__items .v-list-item--prepend
// padding-inline-start: calc(#{$treeview-item-prepend-padding-inline-start} + var(--indent-padding)) !important
.v-list-item
&--active
.v-list-item__prepend,
.v-list-item__append
> .v-badge .v-icon,
> .v-icon
opacity: #{$list-item-icon-active-opacity}

&:not(.v-list-item--link)
.v-list-item__overlay
opacity: calc(#{map.get(settings.$states, 'activated')} * var(--v-theme-overlay-multiplier))
93 changes: 88 additions & 5 deletions packages/vuetify/src/labs/VTreeview/VTreeviewItem.tsx
Expand Up @@ -3,12 +3,14 @@ import './VTreeviewItem.sass'

// Components
import { VBtn } from '@/components/VBtn'
import { VListItemAction } from '@/components/VList'
import { VListItemAction, VListItemSubtitle, VListItemTitle } from '@/components/VList'
import { makeVListItemProps, VListItem } from '@/components/VList/VListItem'

// Composables
import { IconValue } from '@/composables/icons'
import { useNestedItem } from '@/composables/nested/nested'
import { useLink } from '@/composables/router'
import { genOverlays } from '@/composables/variant'

// Utilities
import { computed, inject, ref } from 'vue'
Expand Down Expand Up @@ -36,15 +38,37 @@ export const VTreeviewItem = genericComponent<VListItemSlots>()({
const id = computed(() => props.value === undefined ? link.href.value : props.value)
const vListItemRef = ref<VListItem>()

const {
activate,
isActivated,
select,
isSelected,
isIndeterminate,
isGroupActivator,
root,
} = useNestedItem(id, false)

const slotProps = computed(() => ({
isActive: isActivated.value,
select,
isSelected: isSelected.value,
isIndeterminate: isIndeterminate.value,
} satisfies any))

const isClickable = computed(() =>
!props.disabled &&
props.link !== false &&
(props.link || link.isClickable.value || (props.value != null && !!vListItemRef.value?.list))
)

function onClick (e: MouseEvent | KeyboardEvent) {
if (!vListItemRef.value?.isGroupActivator || !isClickable.value) return
props.value != null && vListItemRef.value?.select(!vListItemRef.value?.isSelected, e)
if (root.activatable.value) {
activate(!isActivated.value, e)
} else if (root.selectable.value) {
select(!isSelected.value, e)
} else if (props.value != null) {
select(!isSelected.value, e)
}
}

function onKeyDown (e: KeyboardEvent) {
Expand All @@ -57,10 +81,69 @@ export const VTreeviewItem = genericComponent<VListItemSlots>()({
const visibleIds = inject(VTreeviewSymbol, { visibleIds: ref() }).visibleIds

useRender(() => {
const hasTitle = (slots.title || props.title != null)
const hasSubtitle = (slots.subtitle || props.subtitle != null)
const listItemProps = VListItem.filterProps(props)
const hasPrepend = slots.prepend || props.toggleIcon

return (
return isGroupActivator
? (
<div
class={[
'v-list-item',
'v-treeview-item',
{
'v-list-item--active': isActivated.value,
},
props.class,
]}
onClick={ onClick }
>
<>
{ genOverlays(isActivated.value, 'v-list-item') }
{ props.toggleIcon && (
<VListItemAction start={ false }>
<VBtn
density="compact"
icon={ props.toggleIcon }
loading={ props.loading }
variant="text"
onClick={ props.onClick }
>
{{
loader () {
return (
<VProgressCircular
indeterminate="disable-shrink"
size="20"
width="2"
/>
)
},
}}
</VBtn>
</VListItemAction>
)}

</>

<div class="v-list-item__content" data-no-activator="">
{ hasTitle && (
<VListItemTitle key="title">
{ slots.title?.({ title: props.title }) ?? props.title }
</VListItemTitle>
)}

{ hasSubtitle && (
<VListItemSubtitle key="subtitle">
{ slots.subtitle?.({ subtitle: props.subtitle }) ?? props.subtitle }
</VListItemSubtitle>
)}

{ slots.default?.(slotProps.value) }
</div>
</div>
) : (
<VListItem
ref={ vListItemRef }
{ ...listItemProps }
Expand Down Expand Up @@ -108,7 +191,7 @@ export const VTreeviewItem = genericComponent<VListItemSlots>()({
} : undefined,
}}
</VListItem>
)
)
})

return {}
Expand Down
1 change: 1 addition & 0 deletions packages/vuetify/src/labs/VTreeview/_variables.scss
@@ -1,4 +1,5 @@
@use 'sass:map';
@forward '../../components/VList/variables';

$treeview-group-list-indent-size: 16px !default;
$treeview-group-list-prepend-width: 16px !default;
Expand Down

0 comments on commit d13e68f

Please sign in to comment.