nextcloud-libraries/nextcloud-vue

[NcActions] doesn't support non-direct NcAction* usage

Opened this issue · 4 comments

This works:

<NcActions>
  <NcAction* />
  <NcAction* />
</NcActions>

This doesn't:

<NcActions>
  <MyActionWrapper* /> -- Renders <NcAction* />
  <MyActionWrapper* />
</NcActions>

The problem is that in NcActions we manually take actions from slot in render function.
And some parts check, what exactly action do we have.

For example, here (1)

isValidSingleAction(action) {
return ['NcActionButton', 'NcActionLink', 'NcActionRouter'].includes(this.getActionName(action))
},

and here (2)

const menuItemsActions = ['NcActionButton', 'NcActionButtonGroup', 'NcActionCheckbox', 'NcActionRadio']
const textInputActions = ['NcActionInput', 'NcActionTextEditable']
const linkActions = ['NcActionLink', 'NcActionRouter']
const hasTextInputAction = menuActions.some(action => textInputActions.includes(this.getActionName(action)))
const hasMenuItemAction = menuActions.some(action => menuItemsActions.includes(this.getActionName(action)))
const hasLinkAction = menuActions.some(action => linkActions.includes(this.getActionName(action)))

Because as an action name we take vnode's component instance's name:

getActionName(action) {
return action?.componentOptions?.Ctor?.extendOptions?.name ?? action?.componentOptions?.tag
},

For MyActionWrapper it will be MyActionWrapper even if it renders <NcActionButton>.

While (1) only results in broken inline feature, (2) now breaks a whole <NcActions> when we use custom wrappers.

The complex part here is that in Vue when a parent is being rendered, it has no child yet. So we cannot just make recursive getActionName. So during NcActions rendering we have no idea what child MyActionWrapper way actually be.

The current idea:

  1. Check for the action name recursively
  2. If no NcAction* was found - mark instance as not-ready and schedule a $forceUpdate

@ShGKme thanks a lot for this fix! Could this issue be closed?

@ShGKme thanks a lot for this fix! Could this issue be closed?

Unfortunately, no, until Vue 3 migration.

My hotfix only brings back an old behavior when it "works in general", but has a number of limitations, including in a11y.

I only fixed a new "completely broken" state.

For a full-working solution, we need to either search for NcAction* components recursively or find some other solution.

UPDATE: Vue 3 has the same limitation