Skip to content

Commit

Permalink
Merge pull request #8 from bryanmylee/opts-fix
Browse files Browse the repository at this point in the history
feat: merge initial options with action options
  • Loading branch information
bryanmylee committed Feb 24, 2021
2 parents f732e7b + f7fc6dd commit 836ca67
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 157 deletions.
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ Since Svelte automatically bundles all required dependencies, you only need to i

## Usage

`createPopperActions` returns a pair of actions to be used on the [reference and popper elements](https://popper.js.org/docs/v2/constructors/#usage).
`createPopperActions` takes an optional [options object](https://popper.js.org/docs/v2/constructors/#options) for configuring the popper instance, and returns a pair of actions to be used on the [reference and popper elements](https://popper.js.org/docs/v2/constructors/#usage).

The content action takes an [options object](https://popper.js.org/docs/v2/constructors/#options) for configuring the popper instance.
The content action also takes an [options object](https://popper.js.org/docs/v2/constructors/#options) for updating the options of the popper instance.

### Example

Expand Down Expand Up @@ -62,6 +62,22 @@ A Svelte version of the standard [tutorial](https://popper.js.org/docs/v2/tutori

## API

### Setting popper options

Popper options can be set statically when creating the popper actions, or dynamically on the content action.

If both are set, then the dynamic options will be merged with the initial options.

```svelte
<script>
// set once and no longer updated
const [popperRef, popperContent] = createPopperActions(initOptions);
</script>
<!-- will be merged with initOptions -->
<div use:popperContent={dynamicOptions}/>
```

### Accessing the Popper instance

If access is needed to the raw [Popper instance](https://popper.js.org/docs/v2/constructors/#instance) created by the actions, you can reference the third element returned by `createPopperActions`. The third element is a function that will return the current Popper instance used by the actions.
Expand All @@ -78,3 +94,4 @@ Using the raw Popper instance to [manually recompute the popper's position](http
}
</script>
```

6 changes: 5 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
roots: [
'./src',
'.',
],
testMatch: [
'**/__tests__/**/*.+(ts|js)',
Expand All @@ -9,5 +9,9 @@ module.exports = {
transform: {
'^.+\\.(ts)$': 'ts-jest',
},
coveragePathIgnorePatterns: [
'./node_modules/',
'./tests/helpers.ts',
],
};

150 changes: 0 additions & 150 deletions src/index.test.ts

This file was deleted.

8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ export function createPopperActions<
};
};

const contentAction: ContentAction<TModifier> = (node, initOptions?) => {
const contentAction: ContentAction<TModifier> = (node, contentOptions?) => {
contentNode = node;
options = initOptions;
options = { ...initOptions, ...contentOptions };
initPopper();
return {
update(newOptions: PopperOptions<TModifier>) {
options = newOptions;
update(newContentOptions: PopperOptions<TModifier>) {
options = { ...initOptions, ...newContentOptions };
if (popperInstance && options) {
popperInstance.setOptions(options);
}
Expand Down
24 changes: 24 additions & 0 deletions tests/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Action = (node: HTMLElement, params?: any) => ActionLifecycleHandlers;
export type ActionLifecycleHandlers = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
update?: (params: any) => void,
destroy? : () => void,
}

export const getElements = () => [
global.document.createElement('div'),
global.document.createElement('div'),
];

export const mountWithAction
// eslint-disable-next-line @typescript-eslint/no-explicit-any
= (node: HTMLElement, action: Action, params?: any) => action(node, params);

export const unmount = (_: HTMLElement, lifecycle: ActionLifecycleHandlers) => {
if (lifecycle.destroy) {
lifecycle.destroy();
}
};

61 changes: 61 additions & 0 deletions tests/init.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { createPopperActions } from '../src/index';
import { getElements, mountWithAction, unmount } from './helpers';

test('instance should init if and only if ref and content is mounted', () => {
// Arrange
const [refDiv, contentDiv] = getElements();
const [refAction, contentAction, getInstance] = createPopperActions();

// Act and Assert
expect(getInstance()).toBeNull();
mountWithAction(refDiv, refAction);

expect(getInstance()).toBeNull();
mountWithAction(contentDiv, contentAction);

expect(getInstance()).not.toBeNull();
});

test('instance should deinit if ref is unmounted', () => {
// Arrange
const [refDiv, contentDiv] = getElements();
const [refAction, contentAction, getInstance] = createPopperActions();
mountWithAction(contentDiv, contentAction);
const refLifecycle = mountWithAction(refDiv, refAction);

// Act
unmount(refDiv, refLifecycle);

// Assert
expect(getInstance()).toBeNull();
});

test('instance should deinit if content is unmounted', () => {
// Arrange
const [refDiv, contentDiv] = getElements();
const [refAction, contentAction, getInstance] = createPopperActions();
mountWithAction(refDiv, refAction);
const contentLifecycle = mountWithAction(contentDiv, contentAction);

// Act
unmount(contentDiv, contentLifecycle);

// Assert
expect(getInstance()).toBeNull();
});

test('instance should deinit if ref and content is unmounted', () => {
// Arrange
const [refDiv, contentDiv] = getElements();
const [refAction, contentAction, getInstance] = createPopperActions();
const refLifecycle = mountWithAction(refDiv, refAction);
const contentLifecycle = mountWithAction(contentDiv, contentAction);

// Act
unmount(refDiv, refLifecycle);
unmount(contentDiv, contentLifecycle);

// Assert
expect(getInstance()).toBeNull();
});

0 comments on commit 836ca67

Please sign in to comment.