Skip to content

Commit

Permalink
feat: introduce sidecar
Browse files Browse the repository at this point in the history
  • Loading branch information
theKashey committed Jun 29, 2019
1 parent 46c1631 commit 0588039
Show file tree
Hide file tree
Showing 19 changed files with 1,742 additions and 697 deletions.
16 changes: 13 additions & 3 deletions .size-limit
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
[
{
path: "dist/es2015/index.js",
limit: "7 KB",
ignore: ["prop-types", "react-dom", "tslib"]
ignore: ["react-dom", "tslib", "use-sidecar"],
limit: "6 KB"
},
{
path: "dist/es2015/sidecar.js",
ignore: ["react-dom", "tslib", "use-sidecar"],
limit: "5 KB"
},
{
path: "dist/es2015/UI.js",
ignore: ["react-dom", "tslib", "use-sidecar"],
limit: "2 KB"
}
]
]
1 change: 1 addition & 0 deletions UI/UI.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../dist/es2015/UI'
8 changes: 8 additions & 0 deletions UI/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"private": true,
"main": "../dist/cjs/UI.js",
"jsnext:main": "../dist/es2015/UI.js",
"module": "../dist/es2015/UI.js",
"types": "UI.d.ts",
"sideEffects": false
}
9 changes: 3 additions & 6 deletions example/app.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import * as React from 'react';
import {Component} from 'react';
import {GHCorner} from 'react-gh-corner';
import {Toggle} from 'react-powerplug';
import {AppWrapper} from './styled';
import {FocusOn, AutoFocusInside, MoveFocusInside, InFocusGuard, classNames} from "../src";
import {FocusOn, MoveFocusInside, InFocusGuard, classNames} from "../src";

export interface AppState {
enabled: boolean;
Expand Down Expand Up @@ -38,9 +36,8 @@ export default class App extends Component <{}, AppState> {
return (
<Toggle>
{({on, toggle}) => (
<AppWrapper>
<div>
<FocusPane>
<GHCorner openInNewTab href={repoUrl}/>
<button>outside</button>
outside
<button onClick={()=>alert('ok')}>test outside event</button>
Expand Down Expand Up @@ -89,7 +86,7 @@ export default class App extends Component <{}, AppState> {
)
}
</FocusPane>
</AppWrapper>
</div>
)}
</Toggle>
)
Expand Down
16 changes: 0 additions & 16 deletions example/styled.ts

This file was deleted.

33 changes: 26 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,48 @@
"static": "ts-react-toolbox publish",
"format": "ts-react-toolbox format",
"analyze": "ts-react-toolbox analyze",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"size": "npx size-limit",
"link:rfl": "rsync -av ../react-focus-lock node_modules/ --exclude node_modules --exclude .git",
"link:rf": "rsync -av ../react-remove-scroll node_modules/ --exclude node_modules --exclude .git",
"link:sb": "rsync -av ../react-remove-scroll-bar node_modules/ --exclude node_modules --exclude .git",
"link:fl": "rsync -av ../focus-lock node_modules/ --exclude node_modules --exclude .git",
"link:ss": "rsync -av ../react-remove-scroll-bar/node_modules/react-style-singleton node_modules/ --exclude node_modules --exclude .git",
"link:all": "yarn link:fl & yarn link:rfl & yarn link:ss & yarn link:rf & yarn link:sb"
},
"sideEffects": [
"**/sidecar.js"
],
"author": "Anton Korzunov <thekashey@gmail.com>",
"license": "MIT",
"devDependencies": {
"@types/react": "^16.8.19",
"conventional-changelog-cli": "^2.0.12",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-powerplug": "^1.0.0",
"size-limit": "^0.21.1",
"ts-react-toolbox": "^0.1.22"
"ts-react-toolbox": "^0.2.2"
},
"dependencies": {
"aria-hidden": "^1.1.1",
"react-focus-lock": "^1.18.2",
"react-remove-scroll": "^1.0.8"
"react-focus-lock": "^2.0.1",
"react-remove-scroll": "^2.0.1",
"react-style-singleton": "^2.0.0",
"use-sidecar": "^1.0.1"
},
"engines": {
"node": ">=8.5.0"
},
"peerDependencies": {
"react": "^16.3.0"
"react": "^16.8.0"
},
"jsnext:main": "dist/es2015/index.js",
"module": "dist/es2015/index.js",
"types": "dist/es5/index.d.ts",
"files": [
"dist"
"dist",
"UI",
"sidecar"
],
"keywords": [
"react",
Expand All @@ -49,5 +65,8 @@
"scroll",
"isolation"
],
"resolutions": {
"typescript": "^3.0.0"
},
"homepage": "https://github.com/theKashey/react-focus-on#readme"
}
7 changes: 7 additions & 0 deletions sidecar/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"private": true,
"main": "../dist/cjs/sidecar.js",
"jsnext:main": "../dist/es2015/sidecar.js",
"module": "../dist/es2015/sidecar.js",
"types": "sidecar.d.ts"
}
5 changes: 5 additions & 0 deletions sidecar/sidecar.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as React from 'react';

declare var sidecar: React.SFC;

export default sidecar;
14 changes: 14 additions & 0 deletions src/Combination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from 'react';
import {FocusOn as ReactFocusOn} from "./UI";
import {ReactFocusOnProps} from './types';

import sideCar from './sidecar';

export function FocusOn(props: ReactFocusOnProps) {
return (
<ReactFocusOn
{...props}
sideCar={sideCar}
/>
);
}
92 changes: 92 additions & 0 deletions src/Effect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as React from 'react';

import {hideOthers} from 'aria-hidden';

import {InteractivityDisabler} from "./InteractivityDisabler";
import {EffectProps} from "./types";
import {focusHiddenMarker} from "./medium";

const extractRef = (ref: React.RefObject<any> | HTMLElement): HTMLElement => (
('current' in ref) ? ref.current : ref
);

export function Effect(
{
setLockProps,

onEscapeKey,
onClickOutside,
shards,

onActivation,
onDeactivation,
noIsolation
}: EffectProps) {
React.useEffect(() => {
let _undo = () => {
return
};
let lastEventTarget: EventTarget;

const onKeyPress = (event: KeyboardEvent) => {
if (event.defaultPrevented) {
return;
}
const code = event.key || event.keyCode;
if ((event.code === 'Escape' || code === 'Escape' || code === 27) && onEscapeKey) {
onEscapeKey(event);
}
};

const onClick = (event: MouseEvent) => {
if (event.defaultPrevented || event.target === lastEventTarget) {
return;
}
if (
shards
.map(extractRef)
.some(node => node && node.contains(event.target as any) || node === event.target)
) {
return;
}
if (onClickOutside) {
onClickOutside();
}
};

const onNodeActivation = (node: HTMLElement) => {
_undo = hideOthers(
[node, ...(shards || []).map(extractRef)],
document.body,
noIsolation ? undefined : focusHiddenMarker
);
if (onActivation) {
onActivation(node);
}
document.addEventListener('keyup', onKeyPress);
document.addEventListener('click', onClick);
};

const onNodeDeactivation = () => {
_undo();
if (onDeactivation) {
onDeactivation();
}
document.removeEventListener('keyup', onKeyPress);
document.removeEventListener('click', onClick);
};

setLockProps({
onClick: (e: React.MouseEvent) => {
lastEventTarget = e.target
},
onActivation: onNodeActivation,
onDeactivation: onNodeDeactivation,
});

}, []);

return (
<InteractivityDisabler/>
);
}
9 changes: 4 additions & 5 deletions src/InteractivityDisabler.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as React from 'react';
import {styleSinglentone} from 'react-style-singleton';
import {styleSingleton} from 'react-style-singleton';
import {focusHiddenMarker} from "./medium";

const Style = styleSinglentone();

export const focusHiddenMarker = 'data-focus-on-hidden';
const Style = styleSingleton();

const styles = `
[${focusHiddenMarker}] {
Expand All @@ -13,4 +12,4 @@ const styles = `

export const InteractivityDisabler: React.SFC = () => (
<Style styles={styles}/>
)
);
47 changes: 47 additions & 0 deletions src/UI.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as React from 'react';
import {SideCarComponent} from "use-sidecar";

import {RemoveScroll} from 'react-remove-scroll/UI';
import ReactFocusLock from 'react-focus-lock/UI'

import {EffectProps, ReactFocusOnSideProps} from "./types";
import {effectCar} from "./medium";

export function FocusOn(props: ReactFocusOnSideProps) {
const [lockProps, setLockProps] = React.useState(null);

const {children, autoFocus, shards, enabled = true, scrollLock = true, focusLock = true, sideCar, ...rest} = props;

const SideCar: SideCarComponent<EffectProps> = sideCar;
return (
<>
<RemoveScroll
sideCar={enabled && sideCar}
enabled={enabled && scrollLock}
shards={shards}
>
{enabled && <SideCar
{...rest}
sideCar={effectCar}
setLockProps={setLockProps}
shards={shards}
/>}
<ReactFocusLock
sideCar={enabled && sideCar}
disabled={!(lockProps && enabled && focusLock)}

returnFocus
autoFocus={autoFocus}

shards={shards}

lockProps={lockProps}
>
{children}
</ReactFocusLock>
</RemoveScroll>
</>
);
}

export * from './reExports';
Loading

0 comments on commit 0588039

Please sign in to comment.