Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yupiik/yupiik-preact
A simple preact libraries set targetting configured UI (from static files or even a backend).
https://github.com/yupiik/yupiik-preact
configuration javascript preact
Last synced: about 4 hours ago
JSON representation
A simple preact libraries set targetting configured UI (from static files or even a backend).
- Host: GitHub
- URL: https://github.com/yupiik/yupiik-preact
- Owner: yupiik
- Created: 2022-05-10T13:39:10.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2024-06-25T07:29:42.000Z (5 months ago)
- Last Synced: 2024-06-25T09:07:46.398Z (5 months ago)
- Topics: configuration, javascript, preact
- Language: JavaScript
- Homepage:
- Size: 1.53 MB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
Awesome Lists containing this project
README
= @yupiik/preact
[abstract]
Simple library enabling to render `preact` components from a registry + config and some utilities around JSON-RPC as a hook.
Overall goal is to configure its UI.IMPORTANT: this library is not yet deployed on npm so you will have to install it locally yourself for now.
== Dynamic component Usage (@yupiik/dynamic)
[source,js]
----
import { render } from 'preact';
import { Dynamic } from '@yupiik/dynamic';const registry = {
component1: Component1,
component2: Component2,
component3: Component3,
}render(
,
document.getElementById('app'));
----=== FromConfiguratonHoc
`FromConfiguratonHoc` is a companion for `Dynamic` (a HoC actually on top of `Dynamic`) which is purely configuration oriented.
It handles callbacks, children etc from plain JSON.==== Configuration
Configuration schema (properties of the component):
[source,js]
----
{
registry = undefined,
parentState = undefined,
parentDispatch = undefined,
options: {
name,
options: {
useReducerCallback: {
initialState = undefined,
reducerJsonLogic = false,
} = {},
useEffectCallback = [],
callbacks = {},
configuration = {},
} = {},
},
}
----[options="header"]
|===
|Property|Description
|registry|component registry (key matching the component name)
| name | the component name in the registry
| useEffectCallback | the useEffect callbacks properties definition in JSON-Logic format, it can be an array or an object (behaves as an array of 1 element). Each element is a JSON-Logic expression.
| useReducerCallback | the useReducer callbacks. initialState is the state initial value and reducerJsonLogic the JSON-Logic implementation which takes the current state and action as parameters. JSONLogic take the state and dispatch functions as parameters.
| callbacks | the callbacks properties definition in JSON-Logic format, key is the callback name and value its JSON-Logic chain. The JSON-Logic can use variables `state`, `dispatch` and `event` (the callback event).
| configuration | properties to passthrough the underlying component.
| parentState | if no initialState is passed it will be used to overwrite it, enables to forward through children the state when children are compatible.
| parentDispatch | parent dispatch callback (to be able to modify parent state).
|====== Registry context usage
In most applications, you will mix `Dynamic` with custom components.
For that case it is worth injecting the registry as a context at a high level of the application:[source,js]
----
import { render } from 'preact';
import { Dynamic, ComponentRegistryContext } from '@yupiik/preact';
import MyComponent from './my-component';const registry = {
component1: Component1,
component2: Component2,
component3: Component3,
}render(
,
document.getElementById('app'));
----This simple snippet enables any nested component like `MyComponent` to reuse `Dynamic` without specifying the registry which allows to write reusable component more easily:
[source,js]
----
export const MyComponent = () => (
);
----=== Note about the configuration
In a real application, you will often have a tree of `Dynamic`.
If your backend supports bulking (JSON-RPC is highly recommended but GraphQL or other protocols can support it), we recommend you to wrap `Dynamic` to enable to bulk the requests by stashing them and to issue a single HTTP request for the component tree.
It is mainly a matter of abstracting the communication with the backend for the components and having a toggle to know if all subcomponents got an initial render or not.
== ANT Design integration (@yupiik/antd-registry)
`@yupiik/antd-registry` provides a component registry which works with `Dynamic` or `FromConfiguratonHoc`.
== React component based libraries (Bootstrap, Feather, ...)
`react-bootstrap` can be integrated importing it (`import * as reactBootstrap`) and converting the import to a registry using `@yupiik/dynamic` `nestedRegistry` fonction.
Similarly `react-feather` which does not use nested components can be converted to a registry the same way but using `simpleRegistry` function is more efficient instead of `nestedRegistry`.
Using this method on `react-bootstrap`, you will get in in the registry, as of today, the following list of component:
* Accordion
* Accordion.Button
* Accordion.Collapse
* Accordion.Item
* Accordion.Header
* Accordion.Body
* AccordionButton
* AccordionCollapse
* AccordionContext
* AccordionContext.Consumer
* AccordionContext.Provider
* AccordionHeader
* AccordionItem
* Alert
* Alert.Link
* Alert.Heading
* AlertHeading
* AlertLink
* Anchor
* Badge
* Breadcrumb
* Breadcrumb.Item
* BreadcrumbItem
* Button
* ButtonGroup
* ButtonToolbar
* Card
* Card.Img
* Card.Title
* Card.Subtitle
* Card.Body
* Card.Link
* Card.Text
* Card.Header
* Card.Footer
* Card.ImgOverlay
* CardBody
* CardFooter
* CardGroup
* CardHeader
* CardImg
* CardImgOverlay
* CardLink
* CardSubtitle
* CardText
* CardTitle
* Carousel
* Carousel.Caption
* Carousel.Item
* CarouselCaption
* CarouselItem
* CloseButton
* Col
* Collapse
* Container
* Dropdown
* Dropdown.Toggle
* Dropdown.Menu
* Dropdown.Item
* Dropdown.ItemText
* Dropdown.Divider
* Dropdown.Header
* DropdownButton
* DropdownDivider
* DropdownHeader
* DropdownItem
* DropdownItemText
* DropdownMenu
* DropdownToggle
* Fade
* Figure
* Figure.Image
* Figure.Caption
* FigureCaption
* FigureImage
* FloatingLabel
* Form
* Form.Group
* Form.Control
* Form.Floating
* Form.Check
* Form.Switch
* Form.Label
* Form.Text
* Form.Range
* Form.Select
* Form.FloatingLabel
* FormCheck
* FormCheck.Input
* FormCheck.Label
* FormControl
* FormControl.Feedback
* FormFloating
* FormGroup
* FormLabel
* FormSelect
* FormText
* Image
* InputGroup
* InputGroup.Text
* InputGroup.Radio
* InputGroup.Checkbox
* ListGroup
* ListGroup.Item
* ListGroupItem
* Modal
* Modal.Body
* Modal.Header
* Modal.Title
* Modal.Footer
* Modal.Dialog
* ModalBody
* ModalDialog
* ModalFooter
* ModalHeader
* ModalTitle
* Nav
* Nav.Item
* Nav.Link
* NavDropdown
* NavDropdown.Item
* NavDropdown.ItemText
* NavDropdown.Divider
* NavDropdown.Header
* NavItem
* NavLink
* Navbar
* Navbar.Brand
* Navbar.Collapse
* Navbar.Offcanvas
* Navbar.Text
* Navbar.Toggle
* NavbarBrand
* NavbarCollapse
* NavbarOffcanvas
* NavbarText
* NavbarToggle
* Offcanvas
* Offcanvas.Body
* Offcanvas.Header
* Offcanvas.Title
* OffcanvasBody
* OffcanvasHeader
* OffcanvasTitle
* OffcanvasToggling
* Overlay
* OverlayTrigger
* PageItem
* Pagination
* Pagination.First
* Pagination.Prev
* Pagination.Ellipsis
* Pagination.Item
* Pagination.Next
* Pagination.Last
* Placeholder
* Placeholder.Button
* PlaceholderButton
* Popover
* Popover.Header
* Popover.Body
* PopoverBody
* PopoverHeader
* ProgressBar
* Ratio
* Row
* SSRProvider
* Spinner
* SplitButton
* Stack
* Tab
* Tab.Container
* Tab.Content
* Tab.Pane
* TabContainer
* TabContent
* TabPane
* Table
* Tabs
* ThemeProvider
* Toast
* Toast.Body
* Toast.Header
* ToastBody
* ToastContainer
* ToastHeader
* ToggleButton
* ToggleButtonGroup
* ToggleButtonGroup.Button
* Tooltip== useJsonRpc hook (@yupiik/use-json-rpc)
=== Usage
[source,js]
----
import { render } from 'preact';
import { useJsonRpc } from '@yupiik/use-json-rpc';export const MyComponent = ({}) => {
const [ loading, error, data ] = useJsonRpc({
payload: {
jsonrpc: '2.0',
method: 'my-server-method',
params: {},
},
// optional
endpoint: '/jsonrpc',
needsSecurity: true,
fetchOptions: {},
dependencies: [],
});if (loading) {
return ();
}if (error) {
return ();
}
if (!data) {
return (No data.);
}return (
{JSON.stringify(data, null, 2)});
};
----=== Configuration
`useJsonRpc` hook takes the following properties in its object parameter:
[options="header"]
|===
| Name | Default | Description
|payload| - | JSON-RPC request, can be an array or an object.
|endpoint|/jsonrpc|JSON-RPC endpoint to call
|needsSecurity|true|Should `Authorization` header be appended from `SecurityContext.access_token` value as a bearer token.
|fetchOptions|`{}`|Any `fetch` option merged with computed ones from other parameters.
|dependencies|`[endpoint,payload,providedData]`|`useEffect` dependencies, by default it uses the request but customizing it can enable to avoid rendering loops.
|fetch|`fetch`|The `fetch` function to use, default to global javascript one.
|providedData|-|The JSON-RPC data result (if provided, ie thruthy, it will be used and the server call will be bypassed).
|====== Use `SecurityContext` provider
When you keep `needsSecurity` to `true`, you must pass a `SecurityContext.Provider`:
[source,js]
----
import { SecurityContext } from '@yupiik/use-json-rpc';export const MyComponent = () => (
);
----TIP: it is often done at a high level of the application to be shared accross all components.
== Build
Project uses `lerna`.
To build all modules run:[source,bash]
----
npm i
npm run build# optionally to run tests
npm run test
----