Skip to content

Commit

Permalink
Renaming hooks (#73)
Browse files Browse the repository at this point in the history
* Renaming

* Changeset
  • Loading branch information
keller-mark authored Feb 15, 2024
1 parent 1f5fd1f commit 6919e30
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 68 deletions.
5 changes: 5 additions & 0 deletions .changeset/thirty-bears-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@use-coordination/core": patch
---

Rename the hook functions to improve API.
4 changes: 2 additions & 2 deletions examples/basic/src/meta-multi-level-example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
ZodCoordinationProvider,
ZodErrorBoundary,
useCoordination,
useCoordinationScopesL1,
useCoordinationScopes,
useCoordinationL1,
} from '@use-coordination/all';
import { z } from 'zod';
Expand Down Expand Up @@ -92,7 +92,7 @@ const ColorfulSliderInputContainer = ({
}: any) => {

// Support meta-coordination.
const channelScopes = useCoordinationScopesL1(viewUid, "channel");
const channelScopes = useCoordinationScopes(viewUid, "channel");
const channelCoordination = useCoordinationL1(viewUid, "channel", [
"channelValue"
]);
Expand Down
4 changes: 2 additions & 2 deletions examples/basic/src/multi-level-example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
ZodCoordinationProvider,
ZodErrorBoundary,
useCoordination,
useCoordinationScopesL1,
useCoordinationScopes,
useCoordinationL1,
} from '@use-coordination/all';
import { z } from 'zod';
Expand Down Expand Up @@ -93,7 +93,7 @@ const ColorfulSliderInput = ({
const ColorfulSliderInputContainer = ({
viewUid,
}: any) => {
const channelScopes = useCoordinationScopesL1(viewUid, "channel");
const channelScopes = useCoordinationScopes(viewUid, "channel");
const channelCoordination = useCoordinationL1(viewUid, "channel", ["channelValue"]);
return (
<ColorfulSliderInput
Expand Down
6 changes: 3 additions & 3 deletions examples/plots/src/multilevel-colors.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { useCoordinationScopesL1, useCoordinationL1, useMultiCoordinationValues } from '@use-coordination/all';
import { useCoordinationScopes, useCoordinationL1, useCoordinationObject } from '@use-coordination/all';

function ColorPicker(props: any) {
const {
Expand All @@ -21,8 +21,8 @@ export function MultilevelColors(props: any) {
viewUid,
} = props;

const selectionScopes = useCoordinationScopesL1(viewUid, "barSelection");
const selectionValues = useMultiCoordinationValues(viewUid, "barSelection");
const selectionScopes = useCoordinationScopes(viewUid, "barSelection");
const selectionValues = useCoordinationObject(viewUid, "barSelection");
const selectionCoordination = useCoordinationL1(viewUid, "barSelection", ["barColor"]);

return (
Expand Down
6 changes: 3 additions & 3 deletions examples/plots/src/multilevel-d3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { scale as vega_scale } from 'vega-scale';
import { axisBottom, axisLeft } from 'd3-axis';
import { max } from 'd3-array';
import { select } from 'd3-selection';
import { useCoordinationScopesL1, useCoordinationL1, useMultiCoordinationValues } from '@use-coordination/all';
import { useCoordinationScopes, useCoordinationL1, useCoordinationObject } from '@use-coordination/all';
import { useSelectBar, useUnselectBar } from './multilevel-example.js';

const scaleBand = vega_scale('band');
Expand Down Expand Up @@ -143,9 +143,9 @@ export function MultiLevelD3BarPlotView(props: any) {
const selectBar = useSelectBar();
const unselectBar = useUnselectBar();

const selectionScopes = useCoordinationScopesL1(viewUid, "barSelection");
const selectionScopes = useCoordinationScopes(viewUid, "barSelection");
const selectionCoordination = useCoordinationL1(viewUid, "barSelection", ["barColor", "barValue"]);
const selectionValues = useMultiCoordinationValues(viewUid, "barSelection");
const selectionValues = useCoordinationObject(viewUid, "barSelection");

const barSelection = selectionScopes.map(scope => selectionValues[scope]);
const barColors = Object.fromEntries(selectionScopes.map(scope => ([
Expand Down
6 changes: 3 additions & 3 deletions examples/plots/src/multilevel-vega-lite.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo, Suspense, useCallback } from 'react';
import { clamp } from 'lodash-es';
import { useCoordinationScopesL1, useCoordinationL1, useMultiCoordinationValues } from '@use-coordination/all';
import { useCoordinationScopes, useCoordinationL1, useCoordinationObject } from '@use-coordination/all';
import { Vega, VisualizationSpec } from 'react-vega';
import { useSelectBar, useUnselectBar } from './multilevel-example.js';

Expand Down Expand Up @@ -143,9 +143,9 @@ export function MultiLevelVegaLitePlotView(props: any) {
const selectBar = useSelectBar();
const unselectBar = useUnselectBar();

const selectionScopes = useCoordinationScopesL1(viewUid, "barSelection");
const selectionScopes = useCoordinationScopes(viewUid, "barSelection");
const selectionCoordination = useCoordinationL1(viewUid, "barSelection", ["barColor", "barValue"]);
const selectionValues = useMultiCoordinationValues(viewUid, "barSelection");
const selectionValues = useCoordinationObject(viewUid, "barSelection");

const barSelection = selectionScopes.map(scope => selectionValues[scope]);
const barColors = Object.fromEntries(selectionScopes.map(scope => ([
Expand Down
30 changes: 15 additions & 15 deletions packages/core/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,19 +505,19 @@ export function useCoordination(viewUid: string, parameters: string[]) {
return _useCoordination(coordinationScopes, parameters);
}

export function _useCoordinationScopesL1All(coordinationScopes: Record<string, string | string[]>, parameter: string) {
export function _useCoordinationScopesAll(coordinationScopes: Record<string, string | string[]>, parameter: string) {
return useMemo(() => {
const scopes = coordinationScopes[parameter];
return Array.isArray(scopes) ? scopes : [scopes];
}, [parameter, coordinationScopes]);
}

export function useCoordinationScopesL1All(viewUid: string, parameter: string) {
export function useCoordinationScopesAll(viewUid: string, parameter: string) {
const [coordinationScopes] = useViewMapping(viewUid);
return _useCoordinationScopesL1All(coordinationScopes, parameter);
return _useCoordinationScopesAll(coordinationScopes, parameter);
}

export function _useCoordinationScopesL1(coordinationScopes: Record<string, string | string[]>, parameter: string) {
export function _useCoordinationScopes(coordinationScopes: Record<string, string | string[]>, parameter: string) {
const scopes = getParameterScope(coordinationScopes, parameter);

// Return array of coordination scopes,
Expand All @@ -540,12 +540,12 @@ export function _useCoordinationScopesL1(coordinationScopes: Record<string, stri
return nonNullScopes;
}

export function useCoordinationScopesL1(viewUid: string, parameter: string) {
export function useCoordinationScopes(viewUid: string, parameter: string) {
const [coordinationScopes] = useViewMapping(viewUid);
return _useCoordinationScopesL1(coordinationScopes, parameter);
return _useCoordinationScopes(coordinationScopes, parameter);
}

export function _useCoordinationScopesL2All(
export function _useCoordinationScopesL1All(
coordinationScopes: Record<string, string | string[]>, coordinationScopesBy: Record<string, any>,
byType: string, parameter: string,
) {
Expand Down Expand Up @@ -576,12 +576,12 @@ export function _useCoordinationScopesL2All(
}, [parameter, byType, coordinationScopes, coordinationScopesBy]);
}

export function useCoordinationScopesL2All(viewUid: string, byType: string, parameter: string) {
export function useCoordinationScopesL1All(viewUid: string, byType: string, parameter: string) {
const [coordinationScopes, coordinationScopesBy] = useViewMapping(viewUid);
return _useCoordinationScopesL2All(coordinationScopes, coordinationScopesBy, byType, parameter);
return _useCoordinationScopesL1All(coordinationScopes, coordinationScopesBy, byType, parameter);
}

export function _useCoordinationScopesL2(
export function _useCoordinationScopesL1(
coordinationScopes: Record<string, string | string[]>, coordinationScopesBy: Record<string, any>,
byType: string, parameter: string,
) {
Expand Down Expand Up @@ -650,12 +650,12 @@ export function _useCoordinationScopesL2(
}, [parameter, byType, scopes, coordinationScopes, coordinationScopesBy, parameterSpace, byTypeSpace]);
}

export function useCoordinationScopesL2(viewUid: string, byType: string, parameter: string) {
export function useCoordinationScopesL1(viewUid: string, byType: string, parameter: string) {
const [coordinationScopes, coordinationScopesBy] = useViewMapping(viewUid);
return _useCoordinationScopesL2(coordinationScopes, coordinationScopesBy, byType, parameter);
return _useCoordinationScopesL1(coordinationScopes, coordinationScopesBy, byType, parameter);
}

export function _useMultiCoordinationValues(coordinationScopes: Record<string, string | string[]>, parameter: string) {
export function _useCoordinationObject(coordinationScopes: Record<string, string | string[]>, parameter: string) {
const scopes = getParameterScope(coordinationScopes, parameter);

// Mapping from dataset coordination scope name to dataset uid
Expand All @@ -676,9 +676,9 @@ export function _useMultiCoordinationValues(coordinationScopes: Record<string, s
return vals;
}

export function useMultiCoordinationValues(viewUid: string, parameter: string) {
export function useCoordinationObject(viewUid: string, parameter: string) {
const [coordinationScopes] = useViewMapping(viewUid);
return _useMultiCoordinationValues(coordinationScopes, parameter);
return _useCoordinationObject(coordinationScopes, parameter);
}

/**
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ export {
useCoordinationL1,
_useCoordinationL2,
useCoordinationL2,
_useCoordinationScopesAll,
useCoordinationScopesAll,
_useCoordinationScopes,
useCoordinationScopes,
_useCoordinationScopesL1All,
useCoordinationScopesL1All,
_useCoordinationScopesL1,
useCoordinationScopesL1,
_useCoordinationScopesL2All,
useCoordinationScopesL2All,
_useCoordinationScopesL2,
useCoordinationScopesL2,
_useMultiCoordinationValues,
useMultiCoordinationValues,
_useCoordinationObject,
useCoordinationObject,
} from './hooks.js';
export { ZodCoordinationProvider } from './ZodCoordinationProvider.js';
export { ZodErrorBoundary } from './ZodErrorBoundary.js';
Expand Down
144 changes: 110 additions & 34 deletions sites/docs/docs/hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,47 @@ Returns `values` where the keys are the input `coordinationTypes`.
const { someValue } = useInitialCoordination(viewUid, ["someValue"]);
```

## Multi-coordination

### `useCoordinationScopes`

Get the ordered list of coordination scopes for a particular coordination type.
Scopes are filtered out if their value in the coordination space is null.

#### Parameters:

- `viewUid` (`string`) - The unique identifier for a view.
- `coordinationType` (`string`) - A single coordination type for a view.

#### Returns:

- Type: `string[]`

The coordination scopes mapped to the specified coordination type for a view.

```js
const channelScopes = useCoordinationScopes(viewUid, "channel");
```

### `useCoordinationObject`

Get a mapping from (multiple) coordination scopes to their values for a particular coordination type.

#### Parameters:

- `viewUid` (`string`) - The unique identifier for a view.
- `coordinationType` (`string`) - A single coordination type for a view.

#### Returns:

- Type: `Record<string, any>`

The mapping from coordination scopes (the keys of the returned object) to their values for the specified coordination type and view.

```js
const channelObject = useCoordinationObject(viewUid, "channel");
```

## Multi-level coordination (First level)

### `useCoordinationL1`
Expand Down Expand Up @@ -80,22 +121,27 @@ const channelCoordination = useCoordinationL1(viewUid, "channel", ["channelValue

### `useCoordinationScopesL1`

Get the ordered list of coordination scopes for a particular coordination type.
Scopes are filtered out if their value in the coordination space is null.
Filters out primary and secondary scopes from the results if their value in the coordination space is `null`.


#### Parameters:

- `viewUid` (`string`) - The unique identifier for a view.
- `coordinationType` (`string`) - A single coordination type for a view.
- `primaryType` (`string`)
- `secondaryType` (`string`)

#### Returns:

- Type: `string[]`
- Type: `[string[], Record<string, string[]>]`

The coordination scopes mapped to the specified coordination type for a view.
`[primaryScopesArr, primaryToSecondaryScopesArr]` where
`primaryScopesArr` is an array of coordination scopes for the primary coordination type, and
`primaryToSecondaryScopesArr` is a mapping from each of the primary scopes to a list of secondary scopes `{ [primaryScope]: secondaryScopesArr }`.

```js
const channelScopes = useCoordinationScopesL1(viewUid, "channel");
const [imageLayerScopes, imageChannelScopesByLayer] = useCoordinationScopesL1(
viewUid, "imageLayer", "imageChannel"
);
```

## Multi-level coordination (Second level)
Expand Down Expand Up @@ -147,31 +193,6 @@ const imageChannelCoordination = useCoordinationL2(
);
```

### `useCoordinationScopesL2`

Filters out primary and secondary scopes from the results if their value in the coordination space is `null`.


#### Parameters:

- `viewUid` (`string`) - The unique identifier for a view.
- `primaryType` (`string`)
- `secondaryType` (`string`)

#### Returns:

- Type: `[string[], Record<string, string[]>]`

`[primaryScopesArr, primaryToSecondaryScopesArr]` where
`primaryScopesArr` is an array of coordination scopes for the primary coordination type, and
`primaryToSecondaryScopesArr` is a mapping from each of the primary scopes to a list of secondary scopes `{ [primaryScope]: secondaryScopesArr }`.

```js
const [imageLayerScopes, imageChannelScopesByLayer] = useCoordinationScopesL2(
viewUid, "imageLayer", "imageChannel"
);
```

## Advanced usage

### `useRawViewMapping`
Expand All @@ -194,7 +215,7 @@ const [coordinationScopes, coordinationScopesBy] = useViewMapping(viewUid);
### Underscore-prefixed hooks

Many of the above hooks internally call `useViewMapping` to get the coordination scope mapping information based on the `viewUid`.
This is convenient, but using multiple hooks that call `useViewMapping` in the same view can be inefficient, as it results in redundant lookup (and meta-coordination resolution) operations.
This is convenient, but using multiple hooks that call `useViewMapping` in the same view will result in redundant lookup (and meta-coordination resolution) operations.
We provide a set of underscore-prefixed hooks that take the result of `useViewMapping` as input.

```js
Expand All @@ -209,7 +230,62 @@ The full list of underscore-prefixed hooks:

- `_useCoordination(coordinationScopes, coordinationTypes)`
- `_useInitialCoordination(coordinationScopes, coordinationTypes)`
- `_useCoordinationScopes(coordinationScopes, coordinationType)`
- `_useCoordinationL1(coordinationScopes, coordinationScopesBy, primaryType, secondaryTypes)`
- `_useCoordinationL2(coordinationScopes, coordinationScopesBy, primaryType, secondaryType, tertiaryTypes)`
- `_useCoordinationScopesL1(coordinationScopes, coordinationType)`
- `_useCoordinationScopesL2(coordinationScopes, coordinationScopesBy, primaryType, secondaryType)`
- `_useCoordinationScopesL1(coordinationScopes, coordinationScopesBy, primaryType, secondaryType)`

### Definition of custom hooks

Custom hooks can be defined to provide the lowest-level of control over the coordination implementation.
This can be useful to define custom multi-level coordination logic.

First, define custom action(s) in the Zustand store using the `onCreateStore` [prop](../provider-components/#oncreatestore) of the coordination provider.

```js
function onCreateStore(set) {
return {
selectBar: (viewUid, letter) => set((state) => {
const { coordinationSpace, viewCoordination } = state.viewConfig;
const newConfig = // ... custom logic
return { viewConfig: newConfig };
}),
unselectBar: (viewUid, letter) => set((state) => {
const { coordinationSpace, viewCoordination } = state.viewConfig;
const newConfig = // ... custom logic
return { viewConfig: newConfig };
}),
};
}
```

Then, wrap the custom actions in custom hook functions:

```js
import { useViewConfigStore } from '@use-coordination/all';

export function useSelectBar() {
return useViewConfigStore(state => state.selectBar);
}

export function useUnselectBar() {
return useViewConfigStore(state => state.unselectBar);
}
```

Finally, import these into your view components to use:

```js
import { useSelectBar, useUnselectBar } from './path/to/my-custom-hooks.js';

export function MyView(props) {
const { viewUid } = props;

const selectBar = useSelectBar();
const unselectBar = useUnselectBar();

return (
<button onClick={() => selectBar(viewUid, "A")}>Select the letter A</button>
);
}
```

0 comments on commit 6919e30

Please sign in to comment.