create-appsemble 0.20.15 → 0.20.17

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
@@ -1,10 +1,10 @@
1
- # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.20.15/config/assets/logo.svg) Appsemble Create
1
+ # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.20.17/config/assets/logo.svg) Appsemble Create
2
2
 
3
3
  > Bootstrap an Appsemble block
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/create-appsemble)](https://www.npmjs.com/package/create-appsemble)
6
- [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.20.15/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.20.15)
7
- [![Code coverage](https://codecov.io/gl/appsemble/appsemble/branch/0.20.15/graph/badge.svg)](https://codecov.io/gl/appsemble/appsemble)
6
+ [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.20.17/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.20.17)
7
+ [![Code coverage](https://codecov.io/gl/appsemble/appsemble/branch/0.20.17/graph/badge.svg)](https://codecov.io/gl/appsemble/appsemble)
8
8
  [![Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://prettier.io)
9
9
 
10
10
  ## Usage
@@ -31,5 +31,5 @@ npm init appsemble block
31
31
 
32
32
  ## License
33
33
 
34
- [LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.20.15/LICENSE.md) ©
34
+ [LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.20.17/LICENSE.md) ©
35
35
  [Appsemble](https://appsemble.com)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-appsemble",
3
- "version": "0.20.15",
3
+ "version": "0.20.17",
4
4
  "description": "Bootstrap an Appsemble project",
5
5
  "keywords": [
6
6
  "app",
@@ -33,7 +33,7 @@
33
33
  "test": "NODE_OPTIONS=--experimental-vm-modules jest"
34
34
  },
35
35
  "dependencies": {
36
- "@appsemble/node-utils": "0.20.15",
36
+ "@appsemble/node-utils": "0.20.17",
37
37
  "inquirer": "^9.0.0",
38
38
  "type-fest": "^2.0.0",
39
39
  "yargs": "^17.0.0"
@@ -0,0 +1,11 @@
1
+ This block was bootstrapped using the following command:
2
+
3
+ ```sh
4
+ npm init appsemble block
5
+ ```
6
+
7
+ This block renders a single data entity that is emitted through an Appsemble block event. It uses
8
+ [`mini-jsx`](https://gitlab.com/appsemble/mini-jsx) to define raw DOM nodes using JSX syntax.
9
+
10
+ This readme will be rendered on <https://appsemble.app> when the block is published. Replace the
11
+ contents of this document with a useful block description.
@@ -1,5 +1,12 @@
1
+ // Blocks can actions, parameters, messages, and event listeners and emitters. These can be defined
2
+ // by augmenting the @appsemble/sdk module. Typically this happens in a file named block.ts. When a
3
+ // block is published, the CLI will process the augmented interfaces and validate the app definition
4
+ // complies with them. The JSDoc will be used to render documentation.
1
5
  import { IconName, Remapper } from '@appsemble/sdk';
2
6
 
7
+ /**
8
+ * A field to display.
9
+ */
3
10
  export interface Field {
4
11
  /**
5
12
  * The value of the property to render.
@@ -19,10 +26,23 @@ export interface Field {
19
26
 
20
27
  declare module '@appsemble/sdk' {
21
28
  interface EventListeners {
22
- data: {};
29
+ /**
30
+ * The event to listen on for data to display.
31
+ */
32
+ data: never;
33
+ }
34
+
35
+ interface Messages {
36
+ /**
37
+ * This message is displayed when there was an error loading data.
38
+ */
39
+ error: never;
23
40
  }
24
41
 
25
42
  interface Parameters {
43
+ /**
44
+ * The fields to display.
45
+ */
26
46
  fields: Field[];
27
47
  }
28
48
  }
@@ -0,0 +1,3 @@
1
+ {
2
+ "error": "There was a problem loading the data."
3
+ }
@@ -2,7 +2,7 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@appsemble/sdk": "0.20.15",
5
+ "@appsemble/sdk": "0.20.17",
6
6
  "mini-jsx": "^3.0.0"
7
7
  }
8
8
  }
@@ -1,29 +1,50 @@
1
+ // `src/index.tsx` is the initial entry poinf of the block source code run. For small blocks this
2
+ // often contains the entire logic of the block. Bigger blocks are often split into smaller modules.
1
3
  import { bootstrap } from '@appsemble/sdk';
2
4
 
3
5
  import styles from './index.module.css';
4
6
 
5
- bootstrap(({ events, parameters: { fields }, utils: { fa, remap } }) => {
7
+ // The bootstrap function injects various properties that can be destructured. You can use your
8
+ // editor’s autocomplete to see which variables are available.
9
+ bootstrap(({ events, parameters: { fields }, utils: { fa, formatMessage, remap } }) => {
10
+ /**
11
+ * The wrapper element is used to assign data to when it has loaded asyncronously.
12
+ */
6
13
  const wrapper = (
14
+ // In this template the JSX is handled by mini-jsx (https://gitlab.com/appsemble/mini-jsx).
15
+ // This is a small library that turns JSX into plain DOM nodes. Unlike React or Preact, no
16
+ // virtual DOM or state management is involved.
7
17
  <div className={styles.wrapper}>
8
18
  <div className={styles.loader} />
9
19
  </div>
10
20
  );
11
21
 
22
+ // The preferred way to listen for handling data is using event listeners. At first it may seem
23
+ // simpler to use actions, but event handlers give users the ability to do additional processing
24
+ // in another block, or to render the same data in different blocks. Typically user data is loaded
25
+ // using the data-loader block.
12
26
  events.on.data((data, error) => {
13
- while (wrapper.lastElementChild) {
14
- wrapper.lastElementChild.remove();
27
+ while (wrapper.lastChild) {
28
+ wrapper.lastChild.remove();
15
29
  }
16
30
 
17
31
  if (error) {
18
- wrapper.append('error');
32
+ // It’s always important to handle errors. Events may emit errors for various reasons that are
33
+ // out of control for this block.
34
+ wrapper.append(formatMessage('error'));
19
35
  } else {
20
36
  wrapper.append(
21
37
  ...fields.map(({ icon, label, value }) => {
38
+ // The remap utility is a powerful tool to transform user data. A full reference is found
39
+ // on https://appsemble.app/docs/reference/remapper. However, for the block all that
40
+ // matters is we can pass in a user defined remapper and a value, and get the value the
41
+ // user wants to use.
22
42
  const remappedLabel = remap(label, data) as string;
23
43
 
24
44
  return (
25
45
  <div className={styles.field}>
26
46
  <i className={`${fa(icon)} ${styles.icon}`} />
47
+ {/* Bulma classes are supported. See https://bulma.io/documentation */}
27
48
  <div className={`has-text-weight-bold ${styles.value}`}>
28
49
  {remap(value, data) as string}
29
50
  </div>
@@ -35,5 +56,6 @@ bootstrap(({ events, parameters: { fields }, utils: { fa, remap } }) => {
35
56
  }
36
57
  });
37
58
 
59
+ // If a DOM node is returned by the bootstrap function, it will be rendered in the shadow root.
38
60
  return <div>{wrapper}</div>;
39
61
  });
@@ -0,0 +1,11 @@
1
+ This block was bootstrapped using the following command:
2
+
3
+ ```sh
4
+ npm init appsemble block
5
+ ```
6
+
7
+ This block renders a list of data entities that is emitted through an Appsemble block event. It uses
8
+ [`preact`](https://preactjs.com) to define a block.
9
+
10
+ This readme will be rendered on <https://appsemble.app> when the block is published. Replace the
11
+ contents of this document with a useful block description.
@@ -1,3 +1,8 @@
1
+ // Blocks can actions, parameters, messages, and event listeners and emitters. These can be defined
2
+ // by augmenting the @appsemble/sdk module. Typically this happens in a file named block.ts. When a
3
+ // block is published, the CLI will process the augmented interfaces and validate the app definition
4
+ // complies with them. The JSDoc will be used to render documentation.
5
+
1
6
  declare module '@appsemble/sdk' {
2
7
  interface EventListeners {
3
8
  /**
@@ -6,6 +11,23 @@ declare module '@appsemble/sdk' {
6
11
  data: never;
7
12
  }
8
13
 
14
+ interface Messages {
15
+ /**
16
+ * This message is displayed if the data is empty.
17
+ */
18
+ empty: never;
19
+
20
+ /**
21
+ * This message is displayed if there was a problem loading the data.
22
+ */
23
+ error: never;
24
+
25
+ /**
26
+ * This message is displayed if no data has been loaded yet.
27
+ */
28
+ loading: never;
29
+ }
30
+
9
31
  interface Parameters {
10
32
  /**
11
33
  * A list of fields to render out in a table.
@@ -13,5 +35,3 @@ declare module '@appsemble/sdk' {
13
35
  fields: string[];
14
36
  }
15
37
  }
16
-
17
- export {};
@@ -0,0 +1,5 @@
1
+ {
2
+ "empty": "There is no data to display",
3
+ "error": "There was a problem loading the data.",
4
+ "loading": "Loading…"
5
+ }
@@ -2,8 +2,8 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@appsemble/preact": "0.20.15",
6
- "@appsemble/sdk": "0.20.15",
5
+ "@appsemble/preact": "0.20.17",
6
+ "@appsemble/sdk": "0.20.17",
7
7
  "preact": "^10.0.0"
8
8
  }
9
9
  }
@@ -1,18 +1,39 @@
1
- import { bootstrap } from '@appsemble/preact';
1
+ // `src/index.tsx` is the initial entry poinf of the block source code run. For small blocks this
2
+ // often contains the entire logic of the block. Bigger blocks are often split into smaller modules.
3
+
4
+ // Normally bootstrap is imported from @appsemble/sdk. When using preact, it must be imported from
5
+ // @appsemble/preact instead.
6
+ import { bootstrap, FormattedMessage } from '@appsemble/preact';
2
7
  import { useEffect, useState } from 'preact/hooks';
3
8
 
4
- bootstrap(({ events, parameters: { fields } }) => {
5
- const [data, setData] = useState<any[]>(null);
9
+ // The bootstrap function injects various properties that can be destructured. You can use your
10
+ // editor’s autocomplete to see which variables are available. These properties can also be accessed
11
+ // from anywhere in a preact component using the useBlock() hook.
12
+ bootstrap(({ events, parameters: { fields }, ready }) => {
13
+ // The @appsemble/preact bootstrap function renders a component. This means preact hooks such as
14
+ // useState and useEffect can be used.
15
+ const [data, setData] = useState<any[]>();
6
16
  const [error, setError] = useState(false);
7
17
 
18
+ // The block needs to call ready() once when it’s ready. Appsemble waits for all blocks to be
19
+ // ready before it dispatches any actions or events.
20
+ useEffect(() => {
21
+ ready();
22
+ }, [ready]);
23
+
24
+ // The preferred way to listen for handling data is using event listeners. At first it may seem
25
+ // simpler to use actions, but event handlers give users the ability to do additional processing
26
+ // in another block, or to render the same data in different blocks. Typically user data is loaded
27
+ // using the data-loader block.
8
28
  useEffect(() => {
9
29
  const onData = (newData: unknown[], newError: unknown): void => {
10
30
  if (newError) {
11
31
  setError(true);
12
- setData(null);
32
+ // @ts-expect-error this is valid.
33
+ setData();
13
34
  } else {
14
- setError(false);
15
35
  setData(newData);
36
+ setError(false);
16
37
  }
17
38
  };
18
39
 
@@ -23,19 +44,36 @@ bootstrap(({ events, parameters: { fields } }) => {
23
44
  };
24
45
  }, [events]);
25
46
 
47
+ // It’s always important to handle errors. Events may emit errors for various reasons that are
48
+ // out of control for this block.
26
49
  if (error) {
27
- return <p>Error loading data.</p>;
50
+ return (
51
+ <p>
52
+ <FormattedMessage id="error" />
53
+ </p>
54
+ );
28
55
  }
29
56
 
57
+ // It’s always important to handle the loading state.
30
58
  if (!data) {
31
- return <p>Loading…</p>;
59
+ return (
60
+ <p>
61
+ <FormattedMessage id="loading" />
62
+ </p>
63
+ );
32
64
  }
33
65
 
66
+ // It’s always important to handle an empty state
34
67
  if (!data.length) {
35
- return <p>No data to display.</p>;
68
+ return (
69
+ <p>
70
+ <FormattedMessage id="empty" />
71
+ </p>
72
+ );
36
73
  }
37
74
 
38
75
  return (
76
+ // Bulma classes are supported in Appsemble blocks. See https://bulma.io/documentation
39
77
  <table className="table">
40
78
  <thead>
41
79
  <tr>
@@ -46,6 +84,9 @@ bootstrap(({ events, parameters: { fields } }) => {
46
84
  </thead>
47
85
  <tbody>
48
86
  {data.map((item, dataIndex) => (
87
+ // Because any data may be emitted, it’s often hard to determine the correct key to use.
88
+ // Often an id property is known, at least this handles the use case of Appsemble
89
+ // resources.
49
90
  <tr key={item.id || dataIndex}>
50
91
  {fields.map((field) => (
51
92
  <td key={field}>{item[field]}</td>
@@ -2,8 +2,8 @@
2
2
  "extends": "../../tsconfig",
3
3
  "compilerOptions": {
4
4
  "jsx": "react-jsx",
5
- "jsxImportSource": "preact"
6
- },
7
- "lib": ["dom", "dom.iterable", "esnext"],
8
- "types": ["@appsemble/webpack-config/types"]
5
+ "jsxImportSource": "preact",
6
+ "lib": ["dom", "dom.iterable", "esnext"],
7
+ "types": ["@appsemble/webpack-config/types"]
8
+ }
9
9
  }
@@ -0,0 +1,10 @@
1
+ This block was bootstrapped using the following command:
2
+
3
+ ```sh
4
+ npm init appsemble block
5
+ ```
6
+
7
+ This block displays a button that dispatches an action when clicked.
8
+
9
+ This readme will be rendered on <https://appsemble.app> when the block is published. Replace the
10
+ contents of this document with a useful block description.
@@ -1,3 +1,8 @@
1
+ // Blocks can actions, parameters, messages, and event listeners and emitters. These can be defined
2
+ // by augmenting the @appsemble/sdk module. Typically this happens in a file named block.ts. When a
3
+ // block is published, the CLI will process the augmented interfaces and validate the app definition
4
+ // complies with them. The JSDoc will be used to render documentation.
5
+
1
6
  declare module '@appsemble/sdk' {
2
7
  interface Actions {
3
8
  /**
@@ -5,6 +10,11 @@ declare module '@appsemble/sdk' {
5
10
  */
6
11
  onClick: never;
7
12
  }
8
- }
9
13
 
10
- export {};
14
+ interface Messages {
15
+ /**
16
+ * The button label.
17
+ */
18
+ label: never;
19
+ }
20
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "label": "Click me"
3
+ }
@@ -2,6 +2,6 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@appsemble/sdk": "0.20.15"
5
+ "@appsemble/sdk": "0.20.17"
6
6
  }
7
7
  }
@@ -1,25 +1,25 @@
1
+ // `src/index.ts` is the initial entry poinf of the block source code run. For small blocks this
2
+ // often contains the entire logic of the block. Bigger blocks are often split into smaller modules.
1
3
  import { bootstrap } from '@appsemble/sdk';
2
4
 
3
- /**
4
- * @param {Object} actions Prepared actions the block can dispatch.
5
- * @param {Object} data The data that was somehow passed into the block. I.e. data passed in from
6
- * another block.
7
- * @param {Object} events Event related functions and constants.
8
- * @param {Object} pageParameters Parameters that the app creator defined in the app definition.
9
- * @param {Object} utils Some utility functions provided by the Appsemble framework.
10
- */
11
- bootstrap(({ actions, data, events, pageParameters, shadowRoot, utils }) => {
5
+ // The bootstrap function injects various properties that can be destructured. You can use your
6
+ // editor’s autocomplete to see which variables are available.
7
+ bootstrap(({ actions, utils }) => {
12
8
  const button = document.createElement('button');
13
9
  button.type = 'button';
14
- button.textContent = 'Click me!';
10
+
11
+ // Using utils.formatMessage we can provide internationalized messages.
12
+ button.textContent = utils.formatMessage('label');
13
+
14
+ // Bulma classes are supported. See https://bulma.io/documentation
15
15
  button.classList.add('button');
16
- button.addEventListener(
17
- 'click',
18
- (event) => {
19
- event.preventDefault();
20
- actions.onClick();
21
- },
22
- true,
23
- );
16
+
17
+ button.addEventListener('click', (event) => {
18
+ event.preventDefault();
19
+ // This dispatches a user defined action.
20
+ actions.onClick();
21
+ });
22
+
23
+ // If a DOM node is returned by the bootstrap function, it will be rendered in the shadow root.
24
24
  return button;
25
25
  });