juxscript 1.0.19 → 1.0.21

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.
Files changed (77) hide show
  1. package/bin/cli.js +121 -72
  2. package/lib/components/alert.ts +212 -165
  3. package/lib/components/badge.ts +93 -103
  4. package/lib/components/base/BaseComponent.ts +397 -0
  5. package/lib/components/base/FormInput.ts +322 -0
  6. package/lib/components/button.ts +63 -122
  7. package/lib/components/card.ts +109 -155
  8. package/lib/components/charts/areachart.ts +315 -0
  9. package/lib/components/charts/barchart.ts +421 -0
  10. package/lib/components/charts/doughnutchart.ts +263 -0
  11. package/lib/components/charts/lib/BaseChart.ts +402 -0
  12. package/lib/components/charts/lib/chart-types.ts +159 -0
  13. package/lib/components/charts/lib/chart-utils.ts +160 -0
  14. package/lib/components/charts/lib/chart.ts +707 -0
  15. package/lib/components/checkbox.ts +264 -127
  16. package/lib/components/code.ts +75 -108
  17. package/lib/components/container.ts +113 -130
  18. package/lib/components/data.ts +37 -5
  19. package/lib/components/datepicker.ts +195 -147
  20. package/lib/components/dialog.ts +187 -157
  21. package/lib/components/divider.ts +85 -191
  22. package/lib/components/docs-data.json +544 -2027
  23. package/lib/components/dropdown.ts +178 -136
  24. package/lib/components/element.ts +227 -171
  25. package/lib/components/fileupload.ts +285 -228
  26. package/lib/components/guard.ts +92 -0
  27. package/lib/components/heading.ts +46 -69
  28. package/lib/components/helpers.ts +13 -6
  29. package/lib/components/hero.ts +107 -95
  30. package/lib/components/icon.ts +160 -0
  31. package/lib/components/icons.ts +175 -0
  32. package/lib/components/include.ts +153 -5
  33. package/lib/components/input.ts +174 -374
  34. package/lib/components/kpicard.ts +16 -16
  35. package/lib/components/list.ts +378 -240
  36. package/lib/components/loading.ts +142 -211
  37. package/lib/components/menu.ts +103 -97
  38. package/lib/components/modal.ts +138 -144
  39. package/lib/components/nav.ts +169 -90
  40. package/lib/components/paragraph.ts +49 -150
  41. package/lib/components/progress.ts +118 -200
  42. package/lib/components/radio.ts +297 -149
  43. package/lib/components/script.ts +19 -87
  44. package/lib/components/select.ts +184 -186
  45. package/lib/components/sidebar.ts +152 -140
  46. package/lib/components/style.ts +19 -82
  47. package/lib/components/switch.ts +258 -188
  48. package/lib/components/table.ts +1117 -170
  49. package/lib/components/tabs.ts +162 -145
  50. package/lib/components/theme-toggle.ts +108 -169
  51. package/lib/components/tooltip.ts +86 -157
  52. package/lib/components/write.ts +108 -127
  53. package/lib/jux.ts +86 -41
  54. package/machinery/build.js +466 -0
  55. package/machinery/compiler.js +354 -105
  56. package/machinery/server.js +23 -100
  57. package/machinery/watcher.js +153 -130
  58. package/package.json +1 -2
  59. package/presets/base.css +1166 -0
  60. package/presets/notion.css +2 -1975
  61. package/lib/adapters/base-adapter.js +0 -35
  62. package/lib/adapters/index.js +0 -33
  63. package/lib/adapters/mysql-adapter.js +0 -65
  64. package/lib/adapters/postgres-adapter.js +0 -70
  65. package/lib/adapters/sqlite-adapter.js +0 -56
  66. package/lib/components/areachart.ts +0 -1246
  67. package/lib/components/areachartsmooth.ts +0 -1380
  68. package/lib/components/barchart.ts +0 -1250
  69. package/lib/components/chart.ts +0 -127
  70. package/lib/components/doughnutchart.ts +0 -1191
  71. package/lib/components/footer.ts +0 -165
  72. package/lib/components/header.ts +0 -187
  73. package/lib/components/layout.ts +0 -239
  74. package/lib/components/main.ts +0 -137
  75. package/lib/layouts/default.jux +0 -8
  76. package/lib/layouts/figma.jux +0 -0
  77. /package/lib/{themes → components/charts/lib}/charts.js +0 -0
@@ -1,65 +1,47 @@
1
- import { getOrCreateContainer } from './helpers.js';
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+
3
+ // Event definitions
4
+ const TRIGGER_EVENTS = [] as const;
5
+ const CALLBACK_EVENTS = [] as const;
2
6
 
3
- /**
4
- * Tooltip component options
5
- */
6
7
  export interface TooltipOptions {
7
8
  text?: string;
8
9
  position?: 'top' | 'bottom' | 'left' | 'right';
9
- trigger?: 'hover' | 'click' | 'focus';
10
10
  style?: string;
11
11
  class?: string;
12
12
  }
13
13
 
14
- /**
15
- * Tooltip component state
16
- */
17
14
  type TooltipState = {
18
15
  text: string;
19
16
  position: string;
20
- trigger: string;
21
17
  style: string;
22
18
  class: string;
23
19
  };
24
20
 
25
- /**
26
- * Tooltip component - Contextual help on hover
27
- *
28
- * Usage:
29
- * // Attach to existing element
30
- * jux.tooltip('help-tip', {
31
- * text: 'This is helpful information',
32
- * position: 'top'
33
- * }).attachTo('#help-icon');
34
- *
35
- * // Or render with content
36
- * jux.button('info').label('ℹ️').render('#app');
37
- * jux.tooltip('info-tip').text('More info').attachTo('#info');
38
- */
39
- export class Tooltip {
40
- state: TooltipState;
41
- container: HTMLElement | null = null;
42
- _id: string;
43
- id: string;
44
- private _targetElement: HTMLElement | null = null;
45
- private _tooltipElement: HTMLElement | null = null;
21
+ export class Tooltip extends BaseComponent<TooltipState> {
22
+ private _tooltip: HTMLElement | null = null;
23
+ private _target: HTMLElement | null = null;
46
24
 
47
25
  constructor(id: string, options: TooltipOptions = {}) {
48
- this._id = id;
49
- this.id = id;
50
-
51
- this.state = {
26
+ super(id, {
52
27
  text: options.text ?? '',
53
28
  position: options.position ?? 'top',
54
- trigger: options.trigger ?? 'hover',
55
29
  style: options.style ?? '',
56
30
  class: options.class ?? ''
57
- };
31
+ });
58
32
  }
59
33
 
60
- /* -------------------------
61
- * Fluent API
62
- * ------------------------- */
34
+ protected getTriggerEvents(): readonly string[] {
35
+ return TRIGGER_EVENTS;
36
+ }
37
+
38
+ protected getCallbackEvents(): readonly string[] {
39
+ return CALLBACK_EVENTS;
40
+ }
41
+
42
+ /* ═════════════════════════════════════════════════════════════════
43
+ * FLUENT API
44
+ * ═════════════════════════════════════════════════════════════════ */
63
45
 
64
46
  text(value: string): this {
65
47
  this.state.text = value;
@@ -71,133 +53,57 @@ export class Tooltip {
71
53
  return this;
72
54
  }
73
55
 
74
- trigger(value: 'hover' | 'click' | 'focus'): this {
75
- this.state.trigger = value;
76
- return this;
77
- }
56
+ attachTo(target: HTMLElement | null): this {
57
+ if (!target) return this;
78
58
 
79
- style(value: string): this {
80
- this.state.style = value;
59
+ this._target = target;
60
+ this._setupTooltip();
81
61
  return this;
82
62
  }
83
63
 
84
- class(value: string): this {
85
- this.state.class = value;
86
- return this;
87
- }
88
-
89
- /* -------------------------
90
- * Methods
91
- * ------------------------- */
92
-
93
- /**
94
- * Attach tooltip to an element
95
- */
96
- attachTo(target: string | HTMLElement | any): this {
97
- let targetElement: HTMLElement | null = null;
98
-
99
- if (typeof target === 'string') {
100
- // String selector
101
- const el = document.querySelector(target);
102
- if (!el || !(el instanceof HTMLElement)) {
103
- throw new Error(`Tooltip: Target element "${target}" not found`);
104
- }
105
- targetElement = el;
106
- } else if (target instanceof HTMLElement) {
107
- // Direct HTMLElement
108
- targetElement = target;
109
- } else if (target && target.container) {
110
- // Jux component with container
111
- targetElement = target.container;
112
- } else if (target && target._id) {
113
- // Jux component with _id
114
- const el = document.getElementById(target._id);
115
- if (!el) {
116
- throw new Error(`Tooltip: Target element with id "${target._id}" not found`);
117
- }
118
- targetElement = el;
119
- } else {
120
- throw new Error('Tooltip: Invalid target element');
121
- }
122
-
123
- this._targetElement = targetElement;
124
- this._createTooltip();
125
- this._attachEventListeners();
64
+ /* ═════════════════════════════════════════════════════════════════
65
+ * RENDER
66
+ * ═════════════════════════════════════════════════════════════════ */
126
67
 
127
- return this;
128
- }
68
+ private _setupTooltip(): void {
69
+ if (!this._target) return;
129
70
 
130
- show(): void {
131
- if (this._tooltipElement) {
132
- this._tooltipElement.classList.add('jux-tooltip-visible');
133
- this._positionTooltip();
134
- }
135
- }
136
-
137
- hide(): void {
138
- if (this._tooltipElement) {
139
- this._tooltipElement.classList.remove('jux-tooltip-visible');
140
- }
141
- }
142
-
143
- /* -------------------------
144
- * Helpers
145
- * ------------------------- */
146
-
147
- private _createTooltip(): void {
148
71
  const { text, position, style, class: className } = this.state;
149
72
 
73
+ // Create tooltip element
150
74
  const tooltip = document.createElement('div');
151
75
  tooltip.className = `jux-tooltip jux-tooltip-${position}`;
152
76
  tooltip.id = this._id;
153
- tooltip.setAttribute('role', 'tooltip');
77
+ if (className) tooltip.className += ` ${className}`;
78
+ if (style) tooltip.setAttribute('style', style);
154
79
  tooltip.textContent = text;
80
+ tooltip.style.display = 'none';
81
+ this._tooltip = tooltip;
155
82
 
156
- if (className) {
157
- tooltip.className += ` ${className}`;
158
- }
83
+ document.body.appendChild(tooltip);
159
84
 
160
- if (style) {
161
- tooltip.setAttribute('style', style);
162
- }
85
+ // Show on hover
86
+ this._target.addEventListener('mouseenter', () => {
87
+ this._show();
88
+ });
163
89
 
164
- document.body.appendChild(tooltip);
165
- this._tooltipElement = tooltip;
166
- }
90
+ this._target.addEventListener('mouseleave', () => {
91
+ this._hide();
92
+ });
167
93
 
168
- private _attachEventListeners(): void {
169
- if (!this._targetElement) return;
170
-
171
- const { trigger } = this.state;
172
-
173
- if (trigger === 'hover') {
174
- this._targetElement.addEventListener('mouseenter', () => this.show());
175
- this._targetElement.addEventListener('mouseleave', () => this.hide());
176
- } else if (trigger === 'click') {
177
- this._targetElement.addEventListener('click', () => {
178
- if (this._tooltipElement?.classList.contains('jux-tooltip-visible')) {
179
- this.hide();
180
- } else {
181
- this.show();
182
- }
183
- });
184
- } else if (trigger === 'focus') {
185
- this._targetElement.addEventListener('focus', () => this.show());
186
- this._targetElement.addEventListener('blur', () => this.hide());
187
- }
94
+ this._injectTooltipStyles();
188
95
  }
189
96
 
190
- private _positionTooltip(): void {
191
- if (!this._targetElement || !this._tooltipElement) return;
97
+ private _show(): void {
98
+ if (!this._tooltip || !this._target) return;
192
99
 
193
- const targetRect = this._targetElement.getBoundingClientRect();
194
- const tooltipRect = this._tooltipElement.getBoundingClientRect();
195
- const { position } = this.state;
100
+ const targetRect = this._target.getBoundingClientRect();
101
+ const tooltipRect = this._tooltip.getBoundingClientRect();
196
102
 
197
103
  let top = 0;
198
104
  let left = 0;
199
105
 
200
- switch (position) {
106
+ switch (this.state.position) {
201
107
  case 'top':
202
108
  top = targetRect.top - tooltipRect.height - 8;
203
109
  left = targetRect.left + (targetRect.width - tooltipRect.width) / 2;
@@ -216,26 +122,49 @@ export class Tooltip {
216
122
  break;
217
123
  }
218
124
 
219
- this._tooltipElement.style.top = `${top + window.scrollY}px`;
220
- this._tooltipElement.style.left = `${left + window.scrollX}px`;
125
+ this._tooltip.style.top = `${top}px`;
126
+ this._tooltip.style.left = `${left}px`;
127
+ this._tooltip.style.display = 'block';
221
128
  }
222
129
 
223
- /* -------------------------
224
- * Render (Alternative usage)
225
- * ------------------------- */
130
+ private _hide(): void {
131
+ if (this._tooltip) {
132
+ this._tooltip.style.display = 'none';
133
+ }
134
+ }
226
135
 
227
136
  render(targetId?: string): this {
228
- if (targetId) {
229
- return this.attachTo(targetId);
230
- }
231
- throw new Error('Tooltip requires a target element. Use attachTo(selector) instead.');
137
+ // Tooltips don't render to containers, they attach to targets
138
+ console.warn('Tooltip: Use .attachTo(element) instead of .render()');
139
+ return this;
232
140
  }
233
141
 
234
- renderTo(juxComponent: any): this {
235
- if (!juxComponent?._id) {
236
- throw new Error('Tooltip.renderTo: Invalid component');
237
- }
238
- return this.attachTo(`#${juxComponent._id}`);
142
+ private _injectTooltipStyles(): void {
143
+ const styleId = 'jux-tooltip-styles';
144
+ if (document.getElementById(styleId)) return;
145
+
146
+ const style = document.createElement('style');
147
+ style.id = styleId;
148
+ style.textContent = `
149
+ .jux-tooltip {
150
+ position: fixed;
151
+ background: #1f2937;
152
+ color: white;
153
+ padding: 6px 12px;
154
+ border-radius: 6px;
155
+ font-size: 12px;
156
+ white-space: nowrap;
157
+ z-index: 10000;
158
+ pointer-events: none;
159
+ animation: jux-tooltip-fade 0.2s;
160
+ }
161
+
162
+ @keyframes jux-tooltip-fade {
163
+ from { opacity: 0; }
164
+ to { opacity: 1; }
165
+ }
166
+ `;
167
+ document.head.appendChild(style);
239
168
  }
240
169
  }
241
170
 
@@ -22,18 +22,10 @@ export interface WriteOptions {
22
22
  * jux.write('Content').render('#container');
23
23
  *
24
24
  * // Write HTML
25
- * jux.write('<strong>Bold text</strong>', { html: true }).render('#container');
25
+ * jux.write('<strong>Bold text</strong>').html(true).render('#container');
26
26
  *
27
27
  * // Write with styling
28
- * jux.write('Styled text', {
29
- * tagType: 'p',
30
- * className: 'highlight',
31
- * style: 'color: red;'
32
- * }).render('#container');
33
- *
34
- * // Append multiple writes
35
- * jux.write('First').render('#container');
36
- * jux.write('Second').render('#container');
28
+ * jux.write('Styled text').style('color: red;').render('#container');
37
29
  */
38
30
  export class Write {
39
31
  private content: string;
@@ -50,54 +42,63 @@ export class Write {
50
42
  ...options
51
43
  };
52
44
  }
45
+
46
+ /* ═════════════════════════════════════════════════════════════════
47
+ * FLUENT API
48
+ * ═════════════════════════════════════════════════════════════════ */
49
+
53
50
  /**
54
- * Set HTML mode (chainable setter)
55
- */
51
+ * Set HTML mode (treat content as HTML)
52
+ */
56
53
  html(enabled: boolean = true): this {
57
54
  this.options.html = enabled;
58
55
  return this;
59
56
  }
57
+
60
58
  /**
61
- * Render content to target element
62
- * Falls back to body if no target specified
59
+ * Set tag type
63
60
  */
64
- render(targetSelector?: string): this {
65
- // Default to body if no target
66
- const selector = targetSelector || 'body';
67
- const target = document.querySelector(selector);
68
-
69
- if (!target || !(target instanceof HTMLElement)) {
70
- console.warn(`Write: Target element "${selector}" not found`);
71
- return this;
72
- }
61
+ tagType(value: string): this {
62
+ this.options.tagType = value;
63
+ return this;
64
+ }
73
65
 
74
- const element = document.createElement(this.options.tagType!);
66
+ /**
67
+ * Set CSS class
68
+ */
69
+ className(value: string): this {
70
+ this.options.className = value;
71
+ return this;
72
+ }
75
73
 
76
- // Set content (text or HTML)
77
- if (this.options.html) {
78
- element.innerHTML = this.content;
79
- } else {
80
- element.textContent = this.content;
81
- }
74
+ /**
75
+ * Set inline styles
76
+ */
77
+ style(value: string): this {
78
+ this.options.style = value;
79
+ return this;
80
+ }
82
81
 
83
- // Apply className
84
- if (this.options.className) {
85
- element.className = this.options.className;
86
- }
82
+ /**
83
+ * Set custom attributes
84
+ */
85
+ attrs(attributes: Record<string, string>): this {
86
+ this.options.attributes = attributes;
87
+ return this;
88
+ }
87
89
 
88
- // Apply inline styles
89
- if (this.options.style) {
90
- element.setAttribute('style', this.options.style);
91
- }
90
+ /* ═════════════════════════════════════════════════════════════════
91
+ * RENDER METHODS
92
+ * ═════════════════════════════════════════════════════════════════ */
92
93
 
93
- // Apply custom attributes
94
- if (this.options.attributes) {
95
- Object.entries(this.options.attributes).forEach(([key, value]) => {
96
- element.setAttribute(key, value);
97
- });
98
- }
94
+ /**
95
+ * Render content to target element
96
+ */
97
+ render(targetSelector?: string): this {
98
+ const target = this._getTarget(targetSelector);
99
+ if (!target) return this;
99
100
 
100
- // Append to target
101
+ const element = this._createElement();
101
102
  target.appendChild(element);
102
103
 
103
104
  return this;
@@ -107,19 +108,14 @@ export class Write {
107
108
  * Replace target content (clear first, then render)
108
109
  */
109
110
  replace(targetSelector?: string): this {
110
- const selector = targetSelector || 'body';
111
- const target = document.querySelector(selector);
111
+ const target = this._getTarget(targetSelector);
112
+ if (!target) return this;
112
113
 
113
- if (!target || !(target instanceof HTMLElement)) {
114
- console.warn(`Write: Target element "${selector}" not found`);
115
- return this;
116
- }
117
-
118
- // Clear existing content
119
114
  target.innerHTML = '';
115
+ const element = this._createElement();
116
+ target.appendChild(element);
120
117
 
121
- // Render new content
122
- return this.render(selector);
118
+ return this;
123
119
  }
124
120
 
125
121
  /**
@@ -127,35 +123,12 @@ export class Write {
127
123
  */
128
124
  before(targetSelector: string): this {
129
125
  const target = document.querySelector(targetSelector);
130
-
131
126
  if (!target || !(target instanceof HTMLElement)) {
132
127
  console.warn(`Write: Target element "${targetSelector}" not found`);
133
128
  return this;
134
129
  }
135
130
 
136
- const element = document.createElement(this.options.tagType!);
137
-
138
- if (this.options.html) {
139
- element.innerHTML = this.content;
140
- } else {
141
- element.textContent = this.content;
142
- }
143
-
144
- if (this.options.className) {
145
- element.className = this.options.className;
146
- }
147
-
148
- if (this.options.style) {
149
- element.setAttribute('style', this.options.style);
150
- }
151
-
152
- if (this.options.attributes) {
153
- Object.entries(this.options.attributes).forEach(([key, value]) => {
154
- element.setAttribute(key, value);
155
- });
156
- }
157
-
158
- // Insert before target
131
+ const element = this._createElement();
159
132
  target.parentNode?.insertBefore(element, target);
160
133
 
161
134
  return this;
@@ -166,35 +139,12 @@ export class Write {
166
139
  */
167
140
  after(targetSelector: string): this {
168
141
  const target = document.querySelector(targetSelector);
169
-
170
142
  if (!target || !(target instanceof HTMLElement)) {
171
143
  console.warn(`Write: Target element "${targetSelector}" not found`);
172
144
  return this;
173
145
  }
174
146
 
175
- const element = document.createElement(this.options.tagType!);
176
-
177
- if (this.options.html) {
178
- element.innerHTML = this.content;
179
- } else {
180
- element.textContent = this.content;
181
- }
182
-
183
- if (this.options.className) {
184
- element.className = this.options.className;
185
- }
186
-
187
- if (this.options.style) {
188
- element.setAttribute('style', this.options.style);
189
- }
190
-
191
- if (this.options.attributes) {
192
- Object.entries(this.options.attributes).forEach(([key, value]) => {
193
- element.setAttribute(key, value);
194
- });
195
- }
196
-
197
- // Insert after target
147
+ const element = this._createElement();
198
148
  target.parentNode?.insertBefore(element, target.nextSibling);
199
149
 
200
150
  return this;
@@ -204,87 +154,118 @@ export class Write {
204
154
  * Prepend to target (insert as first child)
205
155
  */
206
156
  prepend(targetSelector?: string): this {
207
- const selector = targetSelector || 'body';
208
- const target = document.querySelector(selector);
157
+ const target = this._getTarget(targetSelector);
158
+ if (!target) return this;
159
+
160
+ const element = this._createElement();
161
+ target.insertBefore(element, target.firstChild);
162
+
163
+ return this;
164
+ }
165
+
166
+ /**
167
+ * Append to target (alias for render)
168
+ */
169
+ append(targetSelector?: string): this {
170
+ return this.render(targetSelector);
171
+ }
172
+
173
+ /* ═════════════════════════════════════════════════════════════════
174
+ * PRIVATE HELPERS
175
+ * ═════════════════════════════════════════════════════════════════ */
176
+
177
+ private _getTarget(selector?: string): HTMLElement | null {
178
+ const targetSelector = selector || 'body';
179
+ const target = document.querySelector(targetSelector);
209
180
 
210
181
  if (!target || !(target instanceof HTMLElement)) {
211
- console.warn(`Write: Target element "${selector}" not found`);
212
- return this;
182
+ console.warn(`Write: Target element "${targetSelector}" not found`);
183
+ return null;
213
184
  }
214
185
 
186
+ return target;
187
+ }
188
+
189
+ private _createElement(): HTMLElement {
215
190
  const element = document.createElement(this.options.tagType!);
216
191
 
192
+ // Set content (text or HTML)
217
193
  if (this.options.html) {
218
194
  element.innerHTML = this.content;
219
195
  } else {
220
196
  element.textContent = this.content;
221
197
  }
222
198
 
199
+ // Apply className
223
200
  if (this.options.className) {
224
201
  element.className = this.options.className;
225
202
  }
226
203
 
204
+ // Apply inline styles
227
205
  if (this.options.style) {
228
206
  element.setAttribute('style', this.options.style);
229
207
  }
230
208
 
209
+ // Apply custom attributes
231
210
  if (this.options.attributes) {
232
211
  Object.entries(this.options.attributes).forEach(([key, value]) => {
233
212
  element.setAttribute(key, value);
234
213
  });
235
214
  }
236
215
 
237
- // Prepend to target
238
- target.insertBefore(element, target.firstChild);
239
-
240
- return this;
241
- }
242
-
243
- /**
244
- * Append to target (alias for render)
245
- */
246
- append(targetSelector?: string): this {
247
- return this.render(targetSelector);
216
+ return element;
248
217
  }
249
218
  }
250
219
 
251
220
  /**
252
- * Factory function for quick writing
221
+ * Factory function - simple, no overloads
253
222
  */
254
223
  export function write(content: string, options: WriteOptions = {}): Write {
255
224
  return new Write(content, options);
256
225
  }
257
226
 
227
+ /* ═════════════════════════════════════════════════════════════════
228
+ * SHORTHAND HELPERS
229
+ * ═════════════════════════════════════════════════════════════════ */
230
+
258
231
  /**
259
- * Shorthand helpers
232
+ * Write text (explicit)
260
233
  */
261
-
262
- // Write text (alias)
263
234
  export function writeText(content: string, options: Omit<WriteOptions, 'html'> = {}): Write {
264
235
  return new Write(content, { ...options, html: false });
265
236
  }
266
237
 
267
- // Write HTML (alias)
238
+ /**
239
+ * Write HTML (explicit)
240
+ */
268
241
  export function writeHtml(content: string, options: Omit<WriteOptions, 'html'> = {}): Write {
269
242
  return new Write(content, { ...options, html: true });
270
243
  }
271
244
 
272
- // Write paragraph
245
+ /**
246
+ * Write paragraph
247
+ */
273
248
  export function writeParagraph(content: string, options: Omit<WriteOptions, 'tagType'> = {}): Write {
274
249
  return new Write(content, { ...options, tagType: 'p' });
275
250
  }
276
251
 
277
- // Write heading
252
+ /**
253
+ * Write heading
254
+ */
278
255
  export function writeHeading(content: string, level: 1 | 2 | 3 | 4 | 5 | 6 = 2, options: Omit<WriteOptions, 'tagType'> = {}): Write {
279
256
  return new Write(content, { ...options, tagType: `h${level}` });
280
257
  }
281
258
 
282
- // Write span
259
+ /**
260
+ * Write span
261
+ */
283
262
  export function writeSpan(content: string, options: Omit<WriteOptions, 'tagType'> = {}): Write {
284
263
  return new Write(content, { ...options, tagType: 'span' });
285
264
  }
286
265
 
287
- // Write div (explicit)
266
+ /**
267
+ * Write div (explicit)
268
+ */
288
269
  export function writeDiv(content: string, options: Omit<WriteOptions, 'tagType'> = {}): Write {
289
270
  return new Write(content, { ...options, tagType: 'div' });
290
271
  }