@riboseinc/paneron-extension-kit v2.2.27
= Paneron extension kit
== Extension development
Paneron extensions are written in TypeScript based on React, and can make use of Blueprint 3 UI components.
An extension is essentially a React component that is given as props some functions that simplify interaction with underlying data repository.
=== Setup
. Create a new repository using Paneron extension template repository (https://github.com/paneron/extension-template-basic).
. For testing purposes, obtain Paneron source code (clone https://github.com/paneron/paneron) and build the project locally.
. Create a directory named paneron-extension-dev
somewhere on your machine.
==== Iteration
After you make changes:
. Rebuild your extension from its repository root: +
source,sh
$ yarn build
. Copy the contents of dist/
into paneron-extension-dev/@riboseinc/paneron-extension-<your-extension-name>
.
. Launch your local build of Paneron using a command like this, from within Paneron repository root: +
source,sh
$ env PANERON_PLUGIN_DIR=/path/to/your/paneron-extension-dev/directory yarn dev
==== Release
An extension must be released as a separate NPM package, specifying entry as plugin.js
(see template extension for example packaging).
When ready & tested, release your extension on NPM:
source,sh
$ npm publish
NOTE: Currently, only extensions released under @riboseinc
NPM scope are supported.
Plugin name must be prefixed with paneron-extension-
(e.g., @riboseinc/paneron-extension-foo-registry
).
=== Rules of Paneron extensions
There are some extra constraints placed upon extension component code, mostly due to limitations of extension mechanism at this point in time.
. An extension must not have any dependencies specified in package.json. Anything you want to import should be provided by Paneron (see below what is). (You can use devDependencies, though.)
. An extension cannot call browser window’s native functions.
If you need setTimeout()
, use setTimeout
prop passed to your top-level extension component.
. An extension cannot import and use React’s tools (e.g., hooks like useState()
).
Instead, React instance passed via the React
prop must be used.
If these rules are not observed, you may end up getting a confusing blank screen after opening a repository using your extension and “DevTools was disconnected from the page” in console.
Here’s how using a useState()
hook might look like:
source,tsx
// This is only to enable JSX support. import React from 'react';
const MyRepositoryView: React.FC = function (props) { const value, setValue = props.React.useState(null); return <div style={{ padding: '1rem' }}>Welcome to repository {props.title}!;
};
As usual, for a more complete example check out the basic extension template repository.
==== Modules you can import
Here are the modules you can import:
- "@blueprintjs/core"
- "@blueprintjs/datetime"
- "@blueprintjs/icons"
- "@blueprintjs/select"
- "@emotion/core"
- "@riboseinc/paneron-extension-kit"
- "@riboseinc/paneron-registry-kit"
- "electron-log"
- "js-yaml"
- "react" (but note quirks above)
- "react-window"
- "throttle-debounce"
Again, you must not have anything in your dependencies, but you may want to add what you use from the above to your devDependencies for TypeScript development convenience.
=== Using Emotion for styling components
Taking the above example, here is how it could be written using Emotion:
source,tsx
/* @jsx jsx /
import { css, jsx } from '@emotion/core';
const MyRepositoryView: React.FC = function (props) {
const value, setValue = props.React.useState(null);
return <div css={csspadding: 1rem;
}>Welcome to repository {props.title}!;
};
NOTE
If using React fragment shorthand syntax (<>…</>
),
keep the React import and add @jsxFrag
pragma:
source,tsx
/ @jsx jsx */ / @jsxFrag React.Fragment */
import React from 'react';
import { css, jsx } from '@emotion/core';
const MyRepositoryView: React.FC = function (props) { const value, setValue = props.React.useState(null); return <>
<div css={css`padding: 1rem;`}>Welcome to repository {props.title}!</div>
</>;
};
====
9 days ago
9 days ago
9 days ago
11 days ago
12 days ago
14 days ago
21 days ago
2 months ago
2 months ago
5 months ago
5 months ago
9 months ago
9 months ago
6 months ago
8 months ago
9 months ago
6 months ago
8 months ago
6 months ago
8 months ago
6 months ago
7 months ago
6 months ago
8 months ago
6 months ago
10 months ago
7 months ago
7 months ago
11 months ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago