@draftably/solid 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,5 +8,10 @@ cleanup when it unmounts. Any number of diagrams can share a page.
8
8
  pnpm add @draftably/solid
9
9
  ```
10
10
 
11
- See [Frameworks](https://draftably.dev/docs/frameworks) for the component, server
12
- rendering with the `svg` prop, and a complete example.
11
+ Import `@draftably/runtime/host.css` once in your client entry: it reserves each element's height
12
+ and hides slot content until the element loads. With Vite, add
13
+ `optimizeDeps: { exclude: ['@draftably/runtime', '@draftably/editor'] }` to `vite.config`.
14
+
15
+ The [Solid recipe](https://draftably.dev/docs/frameworks#solid) is a complete, type-checked app: both
16
+ components, an event, your content on a node, a dark theme and server rendering with the `svg`
17
+ prop. CI compiles it from the packed packages.
package/dist/editor.d.ts CHANGED
@@ -1,23 +1,27 @@
1
1
  /** `<DraftEditor>` for Solid: drag boxes and lines, and get the `.draft` source back. */
2
- import type { DraftEditorElement } from '@draftably/editor/element';
2
+ import type { DraftEditorElement, EditorOptions } from '@draftably/editor/element';
3
3
  import { type JSX } from 'solid-js';
4
- export type { DraftEditorElement };
4
+ import { type HostEventProps } from './events.js';
5
+ export type { DraftEditorElement, EditorOptions };
5
6
  declare module 'solid-js' {
6
7
  namespace JSX {
7
8
  interface IntrinsicElements {
8
9
  'draft-editor': JSX.HTMLAttributes<DraftEditorElement> & {
9
10
  source?: string;
11
+ 'prop:options'?: EditorOptions;
10
12
  };
11
13
  }
12
14
  }
13
15
  }
14
- export interface DraftEditorProps {
15
- /** `.draft` source. Passing back the text from `onChange` does not redraw. */
16
+ export interface DraftEditorProps extends HostEventProps {
17
+ /** `.draft` source. Passing back the source from `onChange` does not redraw. */
16
18
  source: string;
17
- /** Receives the new source after every kept edit, undo and redo. */
18
- onChange?: (source: string) => void;
19
+ /** Every `mountEditor` option but `source` and `onChange`. Callbacks apply live. */
20
+ options?: EditorOptions;
19
21
  ref?: (element: DraftEditorElement) => void;
20
22
  class?: string;
21
23
  style?: JSX.CSSProperties | string;
24
+ /** Slot content: children marked `data-draft-slot="body:<id>"` or `"overlay:<id>"`. */
25
+ children?: JSX.Element;
22
26
  }
23
27
  export declare function DraftEditor(props: DraftEditorProps): JSX.Element;
package/dist/editor.jsx CHANGED
@@ -1,19 +1,21 @@
1
- import { createEffect, onCleanup, onMount } from 'solid-js';
1
+ import { onMount } from 'solid-js';
2
+ import { listenHostEvents } from './events.js';
2
3
  export function DraftEditor(props) {
3
4
  let el;
4
5
  // The editor loads in the browser only, so server rendering and viewer-only pages skip it.
5
- onMount(() => void import('@draftably/editor/element'));
6
- createEffect(() => {
7
- const node = el;
8
- const onChange = props.onChange;
9
- if (!node || !onChange)
10
- return;
11
- const listen = (event) => onChange(event.detail);
12
- node.addEventListener('draft-change', listen);
13
- onCleanup(() => node.removeEventListener('draft-change', listen));
14
- });
6
+ onMount(() => import('@draftably/editor/element').catch((error) => {
7
+ el?.setAttribute('status', 'error');
8
+ el?.setAttribute('data-error', String(error));
9
+ }));
15
10
  return (<draft-editor ref={(node) => {
16
11
  el = node;
12
+ listenHostEvents(node, props);
17
13
  props.ref?.(node);
18
- }} source={props.source} class={props.class} style={props.style}/>);
14
+ }} source={props.source} class={props.class}
15
+ // Only when set: Solid's server HTML writes `style=""` for undefined, which a strict CSP blocks.
16
+ {...(props.style === undefined ? {} : { style: props.style })}
17
+ // Only when set, so options a host set through the ref survive.
18
+ {...(props.options === undefined ? {} : { 'prop:options': props.options })}>
19
+ {props.children}
20
+ </draft-editor>);
19
21
  }
@@ -0,0 +1,9 @@
1
+ /** Event props from the runtime's one list of events: a new event adds no lines here. */
2
+ import { type HostEventName, type HostEvents } from '@draftably/runtime/host';
3
+ export type { HostEventName, HostEvents };
4
+ /** `onCamera`, `onSelect`, … : each receives the event's `detail`. */
5
+ export type HostEventProps = {
6
+ [K in HostEventName as `on${Capitalize<K>}`]?: (detail: HostEvents[K]) => void;
7
+ };
8
+ /** Listen for every host event on `node`; each call reads the latest prop. */
9
+ export declare function listenHostEvents(node: HTMLElement, props: HostEventProps): void;
package/dist/events.js ADDED
@@ -0,0 +1,9 @@
1
+ /** Event props from the runtime's one list of events: a new event adds no lines here. */
2
+ import { HOST_EVENTS } from '@draftably/runtime/host';
3
+ /** Listen for every host event on `node`; each call reads the latest prop. */
4
+ export function listenHostEvents(node, props) {
5
+ for (const name of HOST_EVENTS) {
6
+ const key = `on${name[0].toUpperCase()}${name.slice(1)}`;
7
+ node.addEventListener(`draft-${name}`, event => props[key]?.(event.detail));
8
+ }
9
+ }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,12 @@
1
- /** `<DraftDiagram>` for Solid: the `<draft-diagram>` element with Solid props, a ref and `onUpdate`. */
1
+ /** `<DraftDiagram>` for Solid: the `<draft-diagram>` element with Solid props, a ref and event props. */
2
2
  import '@draftably/runtime/element';
3
3
  import type { DraftDiagramElement } from '@draftably/runtime/element';
4
4
  import type { UpdateResult, ViewerOptions } from '@draftably/runtime/viewer';
5
5
  import { type JSX } from 'solid-js';
6
+ import { type HostEventProps } from './events.js';
7
+ export { renderSvg } from '@draftably/runtime';
8
+ export { HOST_EVENTS } from '@draftably/runtime/host';
9
+ export type { HostEventName, HostEventProps, HostEvents } from './events.js';
6
10
  export type { DraftDiagramElement, UpdateResult, ViewerOptions };
7
11
  declare module 'solid-js' {
8
12
  namespace JSX {
@@ -12,11 +16,12 @@ declare module 'solid-js' {
12
16
  state?: string;
13
17
  label?: string;
14
18
  outline?: 'visible' | 'hidden';
19
+ 'prop:options'?: ViewerOptions;
15
20
  };
16
21
  }
17
22
  }
18
23
  }
19
- export interface DraftDiagramProps {
24
+ export interface DraftDiagramProps extends HostEventProps {
20
25
  /** `.draft` source. A change redraws the diagram and keeps the camera. */
21
26
  source: string;
22
27
  /** A declared emphasis state to show. */
@@ -30,10 +35,12 @@ export interface DraftDiagramProps {
30
35
  * draws. Server rendering and readers without JavaScript see it.
31
36
  */
32
37
  svg?: string;
38
+ /** Every `mountViewer` option. A new object with the same values does nothing. */
33
39
  options?: ViewerOptions;
34
- onUpdate?: (result: UpdateResult) => void;
35
40
  ref?: (element: DraftDiagramElement) => void;
36
41
  class?: string;
37
42
  style?: JSX.CSSProperties | string;
43
+ /** Slot content: children marked `data-draft-slot="body:<id>"` or `"overlay:<id>"`. */
44
+ children?: JSX.Element;
38
45
  }
39
46
  export declare function DraftDiagram(props: DraftDiagramProps): JSX.Element;
package/dist/index.jsx CHANGED
@@ -1,25 +1,19 @@
1
- /** `<DraftDiagram>` for Solid: the `<draft-diagram>` element with Solid props, a ref and `onUpdate`. */
1
+ /** `<DraftDiagram>` for Solid: the `<draft-diagram>` element with Solid props, a ref and event props. */
2
2
  import '@draftably/runtime/element';
3
- import { createEffect, onCleanup, Show } from 'solid-js';
3
+ import { Show } from 'solid-js';
4
+ import { listenHostEvents } from './events.js';
5
+ export { renderSvg } from '@draftably/runtime';
6
+ export { HOST_EVENTS } from '@draftably/runtime/host';
4
7
  export function DraftDiagram(props) {
5
- let el;
6
- createEffect(() => {
7
- if (el && props.options)
8
- el.options = props.options;
9
- });
10
- createEffect(() => {
11
- const node = el;
12
- const onUpdate = props.onUpdate;
13
- if (!node || !onUpdate)
14
- return;
15
- const listen = (event) => onUpdate(event.detail);
16
- node.addEventListener('draft-update', listen);
17
- onCleanup(() => node.removeEventListener('draft-update', listen));
18
- });
19
8
  return (<draft-diagram ref={(node) => {
20
- el = node;
9
+ listenHostEvents(node, props);
21
10
  props.ref?.(node);
22
- }} source={props.source} state={props.state ?? undefined} label={props.label} outline={props.outline} class={props.class} style={props.style}>
11
+ }} source={props.source} state={props.state ?? undefined} label={props.label} outline={props.outline} class={props.class}
12
+ // Only when set: Solid's server HTML writes `style=""` for undefined, which a strict CSP blocks.
13
+ {...(props.style === undefined ? {} : { style: props.style })}
14
+ // Only when set, so options a host set through the ref survive.
15
+ {...(props.options === undefined ? {} : { 'prop:options': props.options })}>
23
16
  <Show when={props.svg}>{svg => <div innerHTML={svg()}/>}</Show>
17
+ {props.children}
24
18
  </draft-diagram>);
25
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@draftably/solid",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Solid components for Draftably diagrams.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -23,8 +23,8 @@
23
23
  },
24
24
  "sideEffects": false,
25
25
  "dependencies": {
26
- "@draftably/runtime": "0.2.0",
27
- "@draftably/editor": "0.2.0"
26
+ "@draftably/runtime": "0.4.0",
27
+ "@draftably/editor": "0.4.0"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "solid-js": "^1.8"