Skip to content

Commit

Permalink
feat(ui): new composable - useSplitAttrs()
Browse files Browse the repository at this point in the history
  • Loading branch information
rstoenescu committed Mar 11, 2024
1 parent 18cfba5 commit 0299efa
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 40 deletions.
6 changes: 2 additions & 4 deletions docs/src/pages/vue-composables/use-render-cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ setup () {
```

```js
interface useRenderCacheObject {
function useRenderCache(): {
getCache: <T = any>(key: string, defaultValue?: T | (() => T)) => T | undefined;
setCache: <T = any>(key: string, value: T) => void;
hasCache: (key: string) => boolean;
clearCache: (key?: string) => void;
}

function useRenderCache(): useRenderCacheObject;
};
```

## Example
Expand Down
51 changes: 51 additions & 0 deletions docs/src/pages/vue-composables/use-split-attrs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
title: useSplitAttrs composable
desc: What is useSplitAttrs() composable and how you can use it
keys: useSplitAttrs
badge: Quasar v2.15+
---

Vue's `attrs` in a component can contain both listeners and real HTML attributes. The `useSplitAttrs()` composable breaks down this Vue attr object into the two categories and keeps them updated.

## Syntax

```js
import { useSplitAttrs } from 'quasar'

setup () {
const {
attributes,
listeners
} = useSplitAttrs()

// ...
}
```

```js
function useSplitAttrs(): {
attributes: Ref<Record<string, any>>;
listeners: Ref<Record<string, any>>;
};
```

## Example

```js
import { useSplitAttrs } from 'quasar'

setup () {
const {
attributes, // is a Vue ref()
listeners // is a Vue ref()
} = useSplitAttrs()

console.log(attributes.value)
// prints out a key-value object

console.log(listeners.value)
// prints out a key-value object

// ...
}
```
20 changes: 16 additions & 4 deletions docs/src/pages/vue-composables/use-tick.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ setup () {
```

```js
interface useTickObject {
function useTick(): {
registerTick(fn: () => void): void;
removeTick(): void;
}

export function useTick(): useTickObject;
};
```

## Example
Expand All @@ -57,3 +55,17 @@ setup () {
// is time for it
}
```

Should you need more than one useTick() per component, simply rename the functions of the returned object:

```js
const {
registerTick: registerFirstTick,
removeTick: removeFirstTick
} = useTick()

const {
registerTick: registerSecondTick,
removeTick: removeSecondTick
} = useTick()
```
20 changes: 16 additions & 4 deletions docs/src/pages/vue-composables/use-timeout.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ setup () {
```

```js
interface useTimeoutObject {
function useTimeout(): {
registerTimeout(fn: () => void, delay?: string | number): void;
removeTimeout(): void;
}

export function useTimeout(): useTimeoutObject;
};
```

## Example
Expand Down Expand Up @@ -60,3 +58,17 @@ setup () {
// time you register/override the timeout
}
```

Should you need more than one useTimeout() per component, simply rename the functions of the returned object:

```js
const {
registerTimeout: registerFirstTimeout,
removeTimeout: removeFirstTimeout
} = useTimeout()

const {
registerTimeout: registerSecondTimeout,
removeTimeout: removeSecondTimeout
} = useTimeout()
```
8 changes: 4 additions & 4 deletions ui/src/components/editor/QEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getToolbar, getFonts, getLinkEditor } from './editor-utils.js'

import useDark, { useDarkProps } from '../../composables/private/use-dark.js'
import useFullscreen, { useFullscreenProps, useFullscreenEmits } from '../../composables/private/use-fullscreen.js'
import useSplitAttrs from '../../composables/private/use-split-attrs.js'
import useSplitAttrs from '../../composables/use-split-attrs.js'

import { createComponent } from '../../utils/private/create.js'
import { stopAndPrevent } from '../../utils/event.js'
Expand Down Expand Up @@ -85,13 +85,13 @@ export default createComponent({
'linkHide'
],

setup (props, { slots, emit, attrs }) {
const { proxy, vnode } = getCurrentInstance()
setup (props, { slots, emit }) {
const { proxy } = getCurrentInstance()
const { $q } = proxy

const isDark = useDark(props, $q)
const { inFullscreen, toggleFullscreen } = useFullscreen()
const splitAttrs = useSplitAttrs(attrs, vnode)
const splitAttrs = useSplitAttrs()

const rootRef = ref(null)
const contentRef = ref(null)
Expand Down
6 changes: 4 additions & 2 deletions ui/src/composables.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import useRenderCache from './composables/use-render-cache.js'
import useDialogPluginComponent from './composables/use-dialog-plugin-component.js'
import useFormChild from './composables/use-form-child.js'
import useMeta from './composables/use-meta.js'
import useQuasar from './composables/use-quasar.js'
import useRenderCache from './composables/use-render-cache.js'
import useSplitAttrs from './composables/use-split-attrs.js'
import useTick from './composables/use-tick.js'
import useTimeout from './composables/use-timeout.js'

export {
useRenderCache,
useDialogPluginComponent,
useFormChild,
useMeta,
useQuasar,
useRenderCache,
useSplitAttrs,
useTick,
useTimeout
}
6 changes: 3 additions & 3 deletions ui/src/composables/private/use-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import QSpinner from '../../components/spinner/QSpinner.js'
import useDark, { useDarkProps } from '../../composables/private/use-dark.js'
import useId, { getId } from './use-id.js'
import useValidate, { useValidateProps } from './use-validate.js'
import useSplitAttrs from './use-split-attrs.js'
import useSplitAttrs from '../use-split-attrs.js'

import { hSlot } from '../../utils/private/render.js'
import { prevent, stopAndPrevent } from '../../utils/event.js'
Expand Down Expand Up @@ -69,7 +69,7 @@ export const useFieldProps = {
export const useFieldEmits = [ 'update:modelValue', 'clear', 'focus', 'blur', 'popupShow', 'popupHide' ]

export function useFieldState ({ requiredForAttr = true, tagProp } = {}) {
const { props, attrs, proxy, vnode } = getCurrentInstance()
const { props, proxy } = getCurrentInstance()

const isDark = useDark(props, proxy.$q)
const targetUid = useId(props.for, requiredForAttr)
Expand All @@ -90,7 +90,7 @@ export function useFieldState ({ requiredForAttr = true, tagProp } = {}) {
focused: ref(false),
hasPopupOpen: false,

splitAttrs: useSplitAttrs(attrs, vnode),
splitAttrs: useSplitAttrs(),
targetUid,

rootRef: ref(null),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ref, onBeforeUpdate } from 'vue'
import { ref, onBeforeUpdate, getCurrentInstance } from 'vue'

const listenerRE = /^on[A-Z]/

export default function (attrs, vnode) {
export default function () {
const { attrs, vnode } = getCurrentInstance()

const acc = {
listeners: ref({}),
attributes: ref({})
Expand Down
33 changes: 16 additions & 17 deletions ui/types/composables.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@ import { MetaOptions } from "./meta";
import { Ref } from "vue";
import { QVueGlobals } from "./globals";

interface useRenderCacheObject {
getCache: <T = any>(key: string, defaultValue?: T | (() => T)) => T | undefined;
setCache: <T = any>(key: string, value: T) => void;
hasCache: (key: string) => boolean;
clearCache: (key?: string) => void;
}

export function useRenderCache(): useRenderCacheObject;

interface useDialogPluginComponent {
<T = any>(): {
dialogRef: Ref<QDialog | undefined>;
Expand Down Expand Up @@ -40,16 +31,24 @@ export function useMeta(options: MetaOptions | (() => MetaOptions)): void;

export function useQuasar(): QVueGlobals;

interface useTickObject {
export function useRenderCache(): {
getCache: <T = any>(key: string, defaultValue?: T | (() => T)) => T | undefined;
setCache: <T = any>(key: string, value: T) => void;
hasCache: (key: string) => boolean;
clearCache: (key?: string) => void;
};

export function useSplitAttrs(): {
attributes: Ref<Record<string, any>>;
listeners: Ref<Record<string, any>>;
};

export function useTick(): {
registerTick(fn: () => void): void;
removeTick(): void;
}

export function useTick(): useTickObject;
};

interface useTimeoutObject {
export function useTimeout(): {
registerTimeout(fn: () => void, delay?: string | number): void;
removeTimeout(): void;
}

export function useTimeout(): useTimeoutObject;
};

0 comments on commit 0299efa

Please sign in to comment.