@foldkit/markdown 0.1.2 → 0.2.1

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
@@ -41,7 +41,7 @@ If you run tests with Vitest, add `markdown()` with the same options to the `plu
41
41
  ## Render a document
42
42
 
43
43
  ```typescript
44
- import { Html, html } from 'foldkit/html'
44
+ import { Html, type HtmlBuilder } from 'foldkit/html'
45
45
 
46
46
  import * as Markdown from '@foldkit/markdown'
47
47
 
@@ -50,11 +50,8 @@ import { type Message } from './message'
50
50
 
51
51
  const about = Markdown.decodeDocument(aboutRaw)
52
52
 
53
- const view = (): Html => {
54
- const h = html<Message>()
55
-
56
- return h.div([], [Markdown.view(about)])
57
- }
53
+ const view = (h: HtmlBuilder<Message>): Html =>
54
+ h.div([], [Markdown.view(about)])
58
55
  ```
59
56
 
60
57
  `Markdown.view` renders every node through unstyled semantic defaults. Restyle any node by overriding its view:
@@ -111,7 +108,7 @@ markdown({ islands: islandAttributes })
111
108
  `islandsFor` pairs the same definitions with typed views: attributes arrive decoded through each island's schema, and the record must cover every declared name. State stays in your Model; the markdown only decides placement. The third argument is the zero-based occurrence of that island name in the document, for identifiers that must be unique per instance, like an `h.submodel` slotId:
112
109
 
113
110
  ```typescript
114
- import { Html, html } from 'foldkit/html'
111
+ import { Html, type HtmlBuilder } from 'foldkit/html'
115
112
 
116
113
  import * as Markdown from '@foldkit/markdown'
117
114
 
@@ -119,10 +116,12 @@ import { Counter } from './counter'
119
116
  import { islandAttributes } from './islands'
120
117
  import { GotCounterMessage, type Message, type Model } from './message'
121
118
 
122
- const postView = (model: Model, post: Markdown.MarkdownDocument): Html => {
123
- const h = html<Message>()
124
-
125
- return Markdown.view(post, {
119
+ const postView = (
120
+ model: Model,
121
+ post: Markdown.MarkdownDocument,
122
+ h: HtmlBuilder<Message>,
123
+ ): Html =>
124
+ Markdown.view(post, {
126
125
  islands: Markdown.islandsFor(islandAttributes, {
127
126
  Counter: ({ label }, _content, occurrenceIndex) =>
128
127
  h.div(
@@ -141,7 +140,6 @@ const postView = (model: Model, post: Markdown.MarkdownDocument): Html => {
141
140
  h.aside([h.Class('rounded border p-4')], content),
142
141
  }),
143
142
  })
144
- }
145
143
  ```
146
144
 
147
145
  Attribute values are strings on the wire, so transforming field schemas decode past them: `S.NumberFromString` turns `::Chart{height="240"}` into `height: number`. A plain `islands` record of untyped views (`Readonly<Record<string, IslandView>>`) also works when you want to skip the schemas.
@@ -59,7 +59,7 @@ export type ViewConfig = Readonly<{
59
59
  * const blogViews: Markdown.Views = {
60
60
  * ...Markdown.defaultViews,
61
61
  * Paragraph: (paragraph, content) =>
62
- * h.p([h.Class('leading-relaxed text-stone-700')], content),
62
+ * ih.p([ih.Class('leading-relaxed text-stone-700')], content),
63
63
  * }
64
64
  * ```
65
65
  */
@@ -1 +1 @@
1
- {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/view/view.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/view/view.ts"],"names":[],"mappings":"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"}
package/dist/view/view.js CHANGED
@@ -1,15 +1,14 @@
1
1
  import { Array, Match as M, Option, Record as Record_, Schema as S, } from 'effect';
2
- import { html } from 'foldkit/html';
3
- const h = html();
2
+ import { inertHtml as ih } from 'foldkit/html';
4
3
  const titleAttribute = (maybeTitle) => Option.match(maybeTitle, {
5
4
  onNone: () => [],
6
- onSome: title => [h.Title(title)],
5
+ onSome: title => [ih.Title(title)],
7
6
  });
8
7
  const startAttribute = (maybeStartNumber) => Option.match(maybeStartNumber, {
9
8
  onNone: () => [],
10
- onSome: startNumber => [h.Start(startNumber)],
9
+ onSome: startNumber => [ih.Start(startNumber)],
11
10
  });
12
- const alignmentAttribute = (alignment) => M.value(alignment).pipe(M.when('None', () => []), M.when('Left', () => [h.Style({ 'text-align': 'left' })]), M.when('Center', () => [h.Style({ 'text-align': 'center' })]), M.when('Right', () => [h.Style({ 'text-align': 'right' })]), M.exhaustive);
11
+ const alignmentAttribute = (alignment) => M.value(alignment).pipe(M.when('None', () => []), M.when('Left', () => [ih.Style({ 'text-align': 'left' })]), M.when('Center', () => [ih.Style({ 'text-align': 'center' })]), M.when('Right', () => [ih.Style({ 'text-align': 'right' })]), M.exhaustive);
13
12
  /**
14
13
  * Unstyled semantic defaults for every markdown node. Spread these into your
15
14
  * own record and replace the nodes you want to restyle:
@@ -19,7 +18,7 @@ const alignmentAttribute = (alignment) => M.value(alignment).pipe(M.when('None',
19
18
  * const blogViews: Markdown.Views = {
20
19
  * ...Markdown.defaultViews,
21
20
  * Paragraph: (paragraph, content) =>
22
- * h.p([h.Class('leading-relaxed text-stone-700')], content),
21
+ * ih.p([ih.Class('leading-relaxed text-stone-700')], content),
23
22
  * }
24
23
  * ```
25
24
  */
@@ -30,35 +29,35 @@ const alignmentAttribute = (alignment) => M.value(alignment).pipe(M.when('None',
30
29
  // whole document belongs on the consumer's key around the rendered output.
31
30
  export const defaultViews = {
32
31
  Text: ({ value }) => value,
33
- InlineCode: ({ value }) => h.code([], [value]),
34
- HardBreak: () => h.br([]),
35
- Emphasis: (_emphasis, content) => h.em([], content),
36
- Strong: (_strong, content) => h.strong([], content),
37
- Strikethrough: (_strikethrough, content) => h.del([], content),
38
- Link: ({ url, maybeTitle }, content) => h.a([h.Href(url), ...titleAttribute(maybeTitle)], content),
39
- Image: ({ url, alt, maybeTitle }) => h.img([h.Src(url), h.Alt(alt), ...titleAttribute(maybeTitle)]),
40
- Heading: ({ level }, content) => M.value(level).pipe(M.withReturnType(), M.when(1, () => h.h1([], content)), M.when(2, () => h.h2([], content)), M.when(3, () => h.h3([], content)), M.when(4, () => h.h4([], content)), M.when(5, () => h.h5([], content)), M.when(6, () => h.h6([], content)), M.exhaustive),
41
- Paragraph: (_paragraph, content) => h.p([], content),
42
- CodeBlock: ({ value }) => h.pre([], [h.code([], [value])]),
32
+ InlineCode: ({ value }) => ih.code([], [value]),
33
+ HardBreak: () => ih.br([]),
34
+ Emphasis: (_emphasis, content) => ih.em([], content),
35
+ Strong: (_strong, content) => ih.strong([], content),
36
+ Strikethrough: (_strikethrough, content) => ih.del([], content),
37
+ Link: ({ url, maybeTitle }, content) => ih.a([ih.Href(url), ...titleAttribute(maybeTitle)], content),
38
+ Image: ({ url, alt, maybeTitle }) => ih.img([ih.Src(url), ih.Alt(alt), ...titleAttribute(maybeTitle)]),
39
+ Heading: ({ level }, content) => M.value(level).pipe(M.withReturnType(), M.when(1, () => ih.h1([], content)), M.when(2, () => ih.h2([], content)), M.when(3, () => ih.h3([], content)), M.when(4, () => ih.h4([], content)), M.when(5, () => ih.h5([], content)), M.when(6, () => ih.h6([], content)), M.exhaustive),
40
+ Paragraph: (_paragraph, content) => ih.p([], content),
41
+ CodeBlock: ({ value }) => ih.pre([], [ih.code([], [value])]),
43
42
  List: ({ isOrdered, maybeStartNumber }, items) => {
44
43
  if (isOrdered) {
45
- return h.ol(startAttribute(maybeStartNumber), items);
44
+ return ih.ol(startAttribute(maybeStartNumber), items);
46
45
  }
47
46
  else {
48
- return h.ul([], items);
47
+ return ih.ul([], items);
49
48
  }
50
49
  },
51
- ListItem: (_listItem, blocks) => h.li([], blocks),
52
- Blockquote: (_blockquote, blocks) => h.blockquote([], blocks),
53
- ThematicBreak: () => h.hr([]),
54
- Table: (_table, headerRow, bodyRows) => h.table([], [h.thead([], [headerRow]), h.tbody([], bodyRows)]),
55
- TableRow: (_tableRow, cells) => h.tr([], cells),
50
+ ListItem: (_listItem, blocks) => ih.li([], blocks),
51
+ Blockquote: (_blockquote, blocks) => ih.blockquote([], blocks),
52
+ ThematicBreak: () => ih.hr([]),
53
+ Table: (_table, headerRow, bodyRows) => ih.table([], [ih.thead([], [headerRow]), ih.tbody([], bodyRows)]),
54
+ TableRow: (_tableRow, cells) => ih.tr([], cells),
56
55
  TableCell: (_tableCell, content, alignment, isHeader) => {
57
56
  if (isHeader) {
58
- return h.th(alignmentAttribute(alignment), content);
57
+ return ih.th(alignmentAttribute(alignment), content);
59
58
  }
60
59
  else {
61
- return h.td(alignmentAttribute(alignment), content);
60
+ return ih.td(alignmentAttribute(alignment), content);
62
61
  }
63
62
  },
64
63
  };
@@ -161,4 +160,4 @@ export const viewBlocks = (document, config = {}) => {
161
160
  * {@link defaultViews} unless overridden in `config.views`, and every Island
162
161
  * directive renders through the matching entry in `config.islands`.
163
162
  */
164
- export const view = (document, config = {}) => h.div([], viewBlocks(document, config));
163
+ export const view = (document, config = {}) => ih.div([], viewBlocks(document, config));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foldkit/markdown",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "Write markdown files, get Foldkit views with live islands.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -46,7 +46,7 @@
46
46
  "typescript": "^6.0.3",
47
47
  "vite": "^8.0.16",
48
48
  "vitest": "^4.1.9",
49
- "foldkit": "0.133.0"
49
+ "foldkit": "0.135.0"
50
50
  },
51
51
  "keywords": [
52
52
  "foldkit",