@prosary/vue 0.0.0-stage → 0.0.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.
@@ -0,0 +1,51 @@
1
+ import { Component, PropType, VNodeChild } from "vue";
2
+ import { Root } from "hast";
3
+ /**
4
+ * The property of an element built from a directive that names the
5
+ * directive, as the kit's `content.marker` names it: `data-directive` in
6
+ * HTML.
7
+ */
8
+ export declare const MARKER = "dataDirective";
9
+ /**
10
+ * What renders in place of an element: by tag name (`h2`, `a`) or, for an
11
+ * element built from a directive, by the directive's name (`callout`). A
12
+ * directive's name wins over its tag. The component receives the element's
13
+ * attributes as props — a directive's own attributes by the names they were
14
+ * written with — and its children in the default slot.
15
+ */
16
+ export type Components = Record<string, Component>;
17
+ /**
18
+ * Renders a content document: the HTML tree the kit built, as vnodes in
19
+ * place. `components` names what renders instead of an element, by tag or
20
+ * by directive.
21
+ */
22
+ export declare const ProsaryDocument: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
23
+ tree: {
24
+ type: PropType<Root>;
25
+ required: true;
26
+ };
27
+ components: {
28
+ type: PropType<Components>;
29
+ default: () => {};
30
+ };
31
+ }>, () => import("vue").VNodeChild[], {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
32
+ tree: {
33
+ type: PropType<Root>;
34
+ required: true;
35
+ };
36
+ components: {
37
+ type: PropType<Components>;
38
+ default: () => {};
39
+ };
40
+ }>> & Readonly<{}>, {
41
+ components: Components;
42
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
43
+ /**
44
+ * Renders an HTML tree to vnodes: each element as its tag, or as the
45
+ * component that overrides it, each text node as text. Comments and
46
+ * doctypes render nothing.
47
+ *
48
+ * @param tree - The HTML tree, as the kit builds it.
49
+ * @param components - What renders in place of elements, by tag or directive.
50
+ */
51
+ export declare const render: (tree: Root, components?: Components) => VNodeChild[];
@@ -0,0 +1,69 @@
1
+ import { defineComponent, h } from "vue";
2
+ import { find, html } from "property-information";
3
+ const MARKER = "dataDirective";
4
+ const written = (property) => {
5
+ const name = property.replace(/^data(?=[A-Z])/, "");
6
+ return name === property ? property : name.charAt(0).toLowerCase() + name.slice(1);
7
+ };
8
+ const value = (property, given) => {
9
+ if (!Array.isArray(given)) return given;
10
+ return given.join(find(html, property).commaSeparated ? ", " : " ");
11
+ };
12
+ const props = (properties, directive) => {
13
+ const result = {};
14
+ for (const [property, given] of Object.entries(properties)) {
15
+ if (given === void 0 || given === null) continue;
16
+ if (property === "dataDirective" && directive !== void 0) continue;
17
+ const name = directive === void 0 ? find(html, property).attribute : written(property);
18
+ result[name] = value(property, given);
19
+ }
20
+ return result;
21
+ };
22
+ const resolve = (element, components) => {
23
+ const marker = element.properties[MARKER];
24
+ const directive = typeof marker === "string" ? marker : void 0;
25
+ if (directive !== void 0 && components[directive] !== void 0) return {
26
+ type: components[directive],
27
+ directive
28
+ };
29
+ return {
30
+ type: components[element.tagName] ?? element.tagName,
31
+ directive: void 0
32
+ };
33
+ };
34
+ const nodes = (contents, components) => {
35
+ return contents.flatMap((content) => {
36
+ const child = node(content, components);
37
+ return child === null ? [] : [child];
38
+ });
39
+ };
40
+ const node = (content, components) => {
41
+ switch (content.type) {
42
+ case "text": return content.value;
43
+ case "element": {
44
+ const { type, directive } = resolve(content, components);
45
+ const children = nodes(content.children, components);
46
+ if (typeof type === "string") return h(type, props(content.properties, void 0), children);
47
+ return h(type, props(content.properties, directive), { default: () => children });
48
+ }
49
+ default: return null;
50
+ }
51
+ };
52
+ const render = (tree, components = {}) => {
53
+ return nodes(tree.children, components);
54
+ };
55
+ const ProsaryDocument = defineComponent({
56
+ name: "ProsaryDocument",
57
+ props: {
58
+ tree: {
59
+ type: Object,
60
+ required: true
61
+ },
62
+ components: {
63
+ type: Object,
64
+ default: () => ({})
65
+ }
66
+ },
67
+ setup: (props) => () => render(props.tree, props.components)
68
+ });
69
+ export { MARKER, ProsaryDocument, render };
package/README.md CHANGED
@@ -1,3 +1,49 @@
1
- # Temporary Holding Version
1
+ # @prosary/vue
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Renders prosary content in Vue: the HTML tree `@prosary/kit` builds a
4
+ document to, as vnodes, with components in place of the elements you choose.
5
+
6
+ ## Install
7
+
8
+ ```sh
9
+ pnpm add @prosary/vue
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ ```vue
15
+ <script setup lang="ts">
16
+ import { ProsaryDocument } from "@prosary/vue";
17
+ import Callout from "./Callout.vue";
18
+ import Heading from "./Heading.vue";
19
+ </script>
20
+
21
+ <template>
22
+ <ProsaryDocument
23
+ :tree="tree"
24
+ :components="{ h2: Heading, callout: Callout }"
25
+ />
26
+ </template>
27
+ ```
28
+
29
+ Each element renders as its tag, with its attributes. Each text node renders
30
+ as text. Comments render nothing.
31
+
32
+ ## Components
33
+
34
+ `components` names what renders in place of an element, by tag name or, for
35
+ an element built from a directive, by the directive's name. A directive's
36
+ name wins over its tag.
37
+
38
+ - A component in place of a tag receives the element's attributes as props
39
+ by their HTML names (`id`, `class`, `href`) and the children in its
40
+ default slot.
41
+ - A component in place of a directive receives the directive's attributes by
42
+ the names they were written with — `:::callout{kind="warning"}` gives
43
+ `kind` — and the children in its default slot. The marker is left out.
44
+
45
+ ## Render function
46
+
47
+ `render(tree, components)` returns the vnode children for a tree, for a
48
+ render function of your own. `MARKER` is the property that names a directive
49
+ on its element.
package/package.json CHANGED
@@ -1,6 +1,40 @@
1
1
  {
2
2
  "name": "@prosary/vue",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.0.0",
4
+ "description": "Vue renderer for prosary content: an HTML tree to vnodes, with component overrides",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/zoobzio/prosary.git",
9
+ "directory": "integrations/vue"
10
+ },
11
+ "type": "module",
12
+ "main": "./.dist/index.mjs",
13
+ "types": "./.dist/index.d.mts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./.dist/index.d.mts",
17
+ "import": "./.dist/index.mjs"
18
+ }
19
+ },
20
+ "files": [
21
+ ".dist"
22
+ ],
23
+ "scripts": {
24
+ "build": "obuild",
25
+ "stub": "obuild --stub",
26
+ "lint": "oxlint",
27
+ "typecheck": "tsc --noEmit",
28
+ "test": "vitest run"
29
+ },
30
+ "dependencies": {
31
+ "@types/hast": "catalog:",
32
+ "property-information": "catalog:"
33
+ },
34
+ "peerDependencies": {
35
+ "vue": "catalog:"
36
+ },
37
+ "devDependencies": {
38
+ "vue": "catalog:"
39
+ }
40
+ }