@particle-academy/fancy-docs 0.0.0-stage → 0.1.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,184 @@
1
+ import * as react from 'react';
2
+ import { FauxClientProps } from '@particle-academy/react-fancy';
3
+
4
+ /**
5
+ * The last-word document model, as its readers (PHP and JS, one schema) return
6
+ * it. Structural on purpose -- no dependency on last-word -- and loose, because
7
+ * a read document is data from a file, not something this package wrote.
8
+ */
9
+ type Align = "left" | "center" | "right" | "justify";
10
+ type VAlign = "top" | "center" | "bottom";
11
+ type BorderStyle = "single" | "double" | "dashed" | "dotted" | "none";
12
+ interface Border {
13
+ style?: BorderStyle;
14
+ /** Points. Default 0.5. */
15
+ width?: number;
16
+ /** #RRGGBB */
17
+ color?: string;
18
+ }
19
+ interface BoxBorders {
20
+ top?: Border;
21
+ right?: Border;
22
+ bottom?: Border;
23
+ left?: Border;
24
+ }
25
+ interface TableBorders extends BoxBorders {
26
+ insideH?: Border;
27
+ insideV?: Border;
28
+ }
29
+ interface BoxSides {
30
+ top?: number;
31
+ right?: number;
32
+ bottom?: number;
33
+ left?: number;
34
+ }
35
+ interface Run {
36
+ text: string;
37
+ bold?: boolean;
38
+ italic?: boolean;
39
+ underline?: boolean;
40
+ strike?: boolean;
41
+ code?: boolean;
42
+ smallCaps?: boolean;
43
+ link?: string;
44
+ color?: string;
45
+ highlight?: string;
46
+ size?: number;
47
+ font?: string;
48
+ letterSpacing?: number;
49
+ }
50
+ interface ParagraphProps {
51
+ align?: Align;
52
+ spaceBefore?: number;
53
+ spaceAfter?: number;
54
+ lineHeight?: number;
55
+ indentLeft?: number;
56
+ indentRight?: number;
57
+ shading?: string;
58
+ borders?: BoxBorders;
59
+ }
60
+ interface ListItem extends ParagraphProps {
61
+ runs: Run[];
62
+ children?: ListItem[];
63
+ }
64
+ interface TableCell {
65
+ blocks: Block[];
66
+ shading?: string;
67
+ borders?: BoxBorders;
68
+ padding?: BoxSides;
69
+ valign?: VAlign;
70
+ colSpan?: number;
71
+ rowSpan?: number;
72
+ }
73
+ interface TableRow {
74
+ header?: boolean;
75
+ cells: TableCell[];
76
+ }
77
+ type Block = ({
78
+ type: "heading";
79
+ level: number;
80
+ runs: Run[];
81
+ } & ParagraphProps) | ({
82
+ type: "paragraph";
83
+ runs: Run[];
84
+ } & ParagraphProps) | {
85
+ type: "list";
86
+ ordered?: boolean;
87
+ items: ListItem[];
88
+ } | {
89
+ type: "table";
90
+ rows: TableRow[];
91
+ widths?: number[];
92
+ width?: number;
93
+ align?: "left" | "center" | "right";
94
+ borders?: TableBorders;
95
+ cellPadding?: BoxSides;
96
+ } | {
97
+ type: "code";
98
+ language?: string;
99
+ text: string;
100
+ } | {
101
+ type: "quote";
102
+ blocks: Block[];
103
+ } | {
104
+ type: "image";
105
+ src: string;
106
+ widthPx?: number;
107
+ heightPx?: number;
108
+ alt?: string;
109
+ } | {
110
+ type: "pageBreak";
111
+ } | {
112
+ type: "hr";
113
+ };
114
+ /** A running header or footer: three slots; `{page}` and `{pages}` are filled in. */
115
+ interface Band {
116
+ left?: string;
117
+ center?: string;
118
+ right?: string;
119
+ /** Points. Default 9. */
120
+ size?: number;
121
+ color?: string;
122
+ }
123
+ interface Page {
124
+ size?: "letter" | "legal" | "a4";
125
+ orientation?: "portrait" | "landscape";
126
+ margins?: BoxSides;
127
+ header?: Band;
128
+ footer?: Band;
129
+ }
130
+ interface Doc {
131
+ title?: string;
132
+ blocks: Block[];
133
+ page?: Page;
134
+ defaultFont?: string;
135
+ defaultSize?: number;
136
+ }
137
+
138
+ interface DocViewerProps {
139
+ /** A last-word document, as its readers return it. */
140
+ doc: Doc;
141
+ /**
142
+ * Show the document in react-fancy's `FauxClient` frame: zoom and full screen,
143
+ * revealed on hover, like every file viewer. Default `true`.
144
+ */
145
+ frame?: boolean;
146
+ /** Passed to the frame: `variant`, a controlled `zoom`, `onFullscreenChange`, … */
147
+ frameProps?: Partial<FauxClientProps>;
148
+ className?: string;
149
+ }
150
+ /**
151
+ * A last-word document rendered the way Word renders it: page size, margins and
152
+ * running header / footer per page; runs, paragraphs, lists, tables (fills,
153
+ * borders, spans, alignment), code, quotes and images.
154
+ *
155
+ * Measurements stay in points, the model's own unit, so a 0.5pt rule is a 0.5pt
156
+ * rule and the page is the page's size; the frame scales the whole sheet to fit
157
+ * and zooms it.
158
+ *
159
+ * Everything shown came out of a file, so links go through react-fancy's
160
+ * `sanitizeHref`, images are `data:` rasters only (a remote URL in a document
161
+ * is a tracking pixel waiting to fire), and colours must be `#RRGGBB`.
162
+ */
163
+ declare function DocViewer({ doc, frame, frameProps, className }: DocViewerProps): react.JSX.Element;
164
+
165
+ interface DocFileViewProps {
166
+ /** A document as last-word's reader returns it. */
167
+ document: unknown;
168
+ filename?: string;
169
+ /** Passed to the FauxClient frame. */
170
+ frameProps?: Partial<FauxClientProps>;
171
+ }
172
+ /**
173
+ * A .docx in fancy-code's `FileViewer`: register it once at app start.
174
+ *
175
+ * ```ts
176
+ * registerOfficeViewer("docx", DocFileView, { read: (b) => new DocxReader().read(b) });
177
+ * ```
178
+ *
179
+ * The props match fancy-code's `OfficeViewerProps` without importing them, so
180
+ * this package does not depend on fancy-code.
181
+ */
182
+ declare function DocFileView({ document, filename, frameProps }: DocFileViewProps): react.JSX.Element;
183
+
184
+ export { type Align, type Band, type Block, type Border, type BorderStyle, type BoxBorders, type BoxSides, type Doc, DocFileView, type DocFileViewProps, DocViewer, type DocViewerProps, type ListItem, type Page, type ParagraphProps, type Run, type TableBorders, type TableCell, type TableRow, type VAlign };
@@ -0,0 +1,184 @@
1
+ import * as react from 'react';
2
+ import { FauxClientProps } from '@particle-academy/react-fancy';
3
+
4
+ /**
5
+ * The last-word document model, as its readers (PHP and JS, one schema) return
6
+ * it. Structural on purpose -- no dependency on last-word -- and loose, because
7
+ * a read document is data from a file, not something this package wrote.
8
+ */
9
+ type Align = "left" | "center" | "right" | "justify";
10
+ type VAlign = "top" | "center" | "bottom";
11
+ type BorderStyle = "single" | "double" | "dashed" | "dotted" | "none";
12
+ interface Border {
13
+ style?: BorderStyle;
14
+ /** Points. Default 0.5. */
15
+ width?: number;
16
+ /** #RRGGBB */
17
+ color?: string;
18
+ }
19
+ interface BoxBorders {
20
+ top?: Border;
21
+ right?: Border;
22
+ bottom?: Border;
23
+ left?: Border;
24
+ }
25
+ interface TableBorders extends BoxBorders {
26
+ insideH?: Border;
27
+ insideV?: Border;
28
+ }
29
+ interface BoxSides {
30
+ top?: number;
31
+ right?: number;
32
+ bottom?: number;
33
+ left?: number;
34
+ }
35
+ interface Run {
36
+ text: string;
37
+ bold?: boolean;
38
+ italic?: boolean;
39
+ underline?: boolean;
40
+ strike?: boolean;
41
+ code?: boolean;
42
+ smallCaps?: boolean;
43
+ link?: string;
44
+ color?: string;
45
+ highlight?: string;
46
+ size?: number;
47
+ font?: string;
48
+ letterSpacing?: number;
49
+ }
50
+ interface ParagraphProps {
51
+ align?: Align;
52
+ spaceBefore?: number;
53
+ spaceAfter?: number;
54
+ lineHeight?: number;
55
+ indentLeft?: number;
56
+ indentRight?: number;
57
+ shading?: string;
58
+ borders?: BoxBorders;
59
+ }
60
+ interface ListItem extends ParagraphProps {
61
+ runs: Run[];
62
+ children?: ListItem[];
63
+ }
64
+ interface TableCell {
65
+ blocks: Block[];
66
+ shading?: string;
67
+ borders?: BoxBorders;
68
+ padding?: BoxSides;
69
+ valign?: VAlign;
70
+ colSpan?: number;
71
+ rowSpan?: number;
72
+ }
73
+ interface TableRow {
74
+ header?: boolean;
75
+ cells: TableCell[];
76
+ }
77
+ type Block = ({
78
+ type: "heading";
79
+ level: number;
80
+ runs: Run[];
81
+ } & ParagraphProps) | ({
82
+ type: "paragraph";
83
+ runs: Run[];
84
+ } & ParagraphProps) | {
85
+ type: "list";
86
+ ordered?: boolean;
87
+ items: ListItem[];
88
+ } | {
89
+ type: "table";
90
+ rows: TableRow[];
91
+ widths?: number[];
92
+ width?: number;
93
+ align?: "left" | "center" | "right";
94
+ borders?: TableBorders;
95
+ cellPadding?: BoxSides;
96
+ } | {
97
+ type: "code";
98
+ language?: string;
99
+ text: string;
100
+ } | {
101
+ type: "quote";
102
+ blocks: Block[];
103
+ } | {
104
+ type: "image";
105
+ src: string;
106
+ widthPx?: number;
107
+ heightPx?: number;
108
+ alt?: string;
109
+ } | {
110
+ type: "pageBreak";
111
+ } | {
112
+ type: "hr";
113
+ };
114
+ /** A running header or footer: three slots; `{page}` and `{pages}` are filled in. */
115
+ interface Band {
116
+ left?: string;
117
+ center?: string;
118
+ right?: string;
119
+ /** Points. Default 9. */
120
+ size?: number;
121
+ color?: string;
122
+ }
123
+ interface Page {
124
+ size?: "letter" | "legal" | "a4";
125
+ orientation?: "portrait" | "landscape";
126
+ margins?: BoxSides;
127
+ header?: Band;
128
+ footer?: Band;
129
+ }
130
+ interface Doc {
131
+ title?: string;
132
+ blocks: Block[];
133
+ page?: Page;
134
+ defaultFont?: string;
135
+ defaultSize?: number;
136
+ }
137
+
138
+ interface DocViewerProps {
139
+ /** A last-word document, as its readers return it. */
140
+ doc: Doc;
141
+ /**
142
+ * Show the document in react-fancy's `FauxClient` frame: zoom and full screen,
143
+ * revealed on hover, like every file viewer. Default `true`.
144
+ */
145
+ frame?: boolean;
146
+ /** Passed to the frame: `variant`, a controlled `zoom`, `onFullscreenChange`, … */
147
+ frameProps?: Partial<FauxClientProps>;
148
+ className?: string;
149
+ }
150
+ /**
151
+ * A last-word document rendered the way Word renders it: page size, margins and
152
+ * running header / footer per page; runs, paragraphs, lists, tables (fills,
153
+ * borders, spans, alignment), code, quotes and images.
154
+ *
155
+ * Measurements stay in points, the model's own unit, so a 0.5pt rule is a 0.5pt
156
+ * rule and the page is the page's size; the frame scales the whole sheet to fit
157
+ * and zooms it.
158
+ *
159
+ * Everything shown came out of a file, so links go through react-fancy's
160
+ * `sanitizeHref`, images are `data:` rasters only (a remote URL in a document
161
+ * is a tracking pixel waiting to fire), and colours must be `#RRGGBB`.
162
+ */
163
+ declare function DocViewer({ doc, frame, frameProps, className }: DocViewerProps): react.JSX.Element;
164
+
165
+ interface DocFileViewProps {
166
+ /** A document as last-word's reader returns it. */
167
+ document: unknown;
168
+ filename?: string;
169
+ /** Passed to the FauxClient frame. */
170
+ frameProps?: Partial<FauxClientProps>;
171
+ }
172
+ /**
173
+ * A .docx in fancy-code's `FileViewer`: register it once at app start.
174
+ *
175
+ * ```ts
176
+ * registerOfficeViewer("docx", DocFileView, { read: (b) => new DocxReader().read(b) });
177
+ * ```
178
+ *
179
+ * The props match fancy-code's `OfficeViewerProps` without importing them, so
180
+ * this package does not depend on fancy-code.
181
+ */
182
+ declare function DocFileView({ document, filename, frameProps }: DocFileViewProps): react.JSX.Element;
183
+
184
+ export { type Align, type Band, type Block, type Border, type BorderStyle, type BoxBorders, type BoxSides, type Doc, DocFileView, type DocFileViewProps, DocViewer, type DocViewerProps, type ListItem, type Page, type ParagraphProps, type Run, type TableBorders, type TableCell, type TableRow, type VAlign };