@01.software/sdk 0.2.9-dev.260305.4f1735b → 0.2.9-dev.260306.1a05ae3

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
@@ -419,18 +419,38 @@ formatOrderName([
419
419
 
420
420
  ### RichTextContent
421
421
 
422
- React component for rendering Payload CMS Lexical rich text.
422
+ React component for rendering Payload CMS Lexical rich text. Two variants:
423
+
424
+ - **`RichTextContent`** — Base component with maximum flexibility (`converters`, `blocks`, `disableDefaultConverters`)
425
+ - **`StyledRichTextContent`** — Headless component with slot-based customization (`components` prop)
423
426
 
424
427
  ```tsx
425
- import { RichTextContent } from '@01.software/sdk'
428
+ import { RichTextContent, StyledRichTextContent } from '@01.software/sdk/components'
426
429
 
427
- ;<RichTextContent
430
+ // Base: full converter control
431
+ <RichTextContent
428
432
  data={content}
429
433
  className="prose"
430
- internalDocToHref={(args) => `/posts/${args.doc.slug}`}
434
+ internalDocToHref={({ linkNode }) => `/posts/${linkNode.fields.doc?.value?.slug}`}
431
435
  blocks={{
432
- Iframe: ({ url }) => <iframe src={url} />,
433
- Player: ({ videoId }) => <VideoPlayer id={videoId} />,
436
+ Iframe: ({ node }) => <iframe src={node.fields.url} />,
437
+ Player: ({ node }) => <VideoPlayer url={node.fields.url} />,
438
+ }}
439
+ />
440
+
441
+ // Headless: component slots (Radix-style)
442
+ <StyledRichTextContent
443
+ data={content}
444
+ components={{
445
+ Heading: ({ tag: Tag, children }) => (
446
+ <Tag className={Tag === 'h1' ? 'text-4xl font-bold' : 'text-2xl'}>{children}</Tag>
447
+ ),
448
+ Link: ({ href, children, target, rel }) => (
449
+ <a href={href} target={target} rel={rel} className="text-blue-600 underline">{children}</a>
450
+ ),
451
+ Upload: ({ src, alt, width, height }) => (
452
+ <img src={src} alt={alt} width={width} height={height} className="rounded-lg" />
453
+ ),
434
454
  }}
435
455
  />
436
456
  ```
@@ -1,5 +1,5 @@
1
1
  import { Sort, Where } from 'payload';
2
- import './payload-types-Bpi16SHO.cjs';
2
+ import './payload-types-CoLxaq7L.cjs';
3
3
 
4
4
  declare class SDKError extends Error {
5
5
  readonly code: string;
@@ -1,5 +1,5 @@
1
1
  import { Sort, Where } from 'payload';
2
- import './payload-types-Bpi16SHO.js';
2
+ import './payload-types-CoLxaq7L.js';
3
3
 
4
4
  declare class SDKError extends Error {
5
5
  readonly code: string;
package/dist/auth.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- export { J as JwtPayload, q as createApiKey, o as createServerToken, p as decodeServerToken, r as parseApiKey, v as verifyServerToken } from './auth-3qWmYUln.cjs';
1
+ export { J as JwtPayload, q as createApiKey, o as createServerToken, p as decodeServerToken, r as parseApiKey, v as verifyServerToken } from './auth-CveDznSJ.cjs';
2
2
  import 'payload';
3
- import './payload-types-Bpi16SHO.cjs';
3
+ import './payload-types-CoLxaq7L.cjs';
package/dist/auth.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { J as JwtPayload, q as createApiKey, o as createServerToken, p as decodeServerToken, r as parseApiKey, v as verifyServerToken } from './auth-BfGmV75P.js';
1
+ export { J as JwtPayload, q as createApiKey, o as createServerToken, p as decodeServerToken, r as parseApiKey, v as verifyServerToken } from './auth-DmZlBU74.js';
2
2
  import 'payload';
3
- import './payload-types-Bpi16SHO.js';
3
+ import './payload-types-CoLxaq7L.js';
@@ -22,6 +22,18 @@ var __spreadValues = (a, b) => {
22
22
  return a;
23
23
  };
24
24
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __objRest = (source, exclude) => {
26
+ var target = {};
27
+ for (var prop in source)
28
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
29
+ target[prop] = source[prop];
30
+ if (source != null && __getOwnPropSymbols)
31
+ for (var prop of __getOwnPropSymbols(source)) {
32
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
33
+ target[prop] = source[prop];
34
+ }
35
+ return target;
36
+ };
25
37
  var __export = (target, all) => {
26
38
  for (var name in all)
27
39
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -67,38 +79,211 @@ var __async = (__this, __arguments, generator) => {
67
79
  // src/components/index.ts
68
80
  var components_exports = {};
69
81
  __export(components_exports, {
82
+ CodeBlock: () => CodeBlock,
70
83
  FormRenderer: () => FormRenderer,
71
84
  Image: () => Image,
72
85
  RichTextContent: () => RichTextContent,
86
+ StyledRichTextContent: () => StyledRichTextContent,
87
+ highlight: () => highlight,
73
88
  toSubmissionData: () => toSubmissionData
74
89
  });
75
90
  module.exports = __toCommonJS(components_exports);
76
91
 
77
92
  // src/components/RichTextContent/index.tsx
93
+ var import_react2 = __toESM(require("react"), 1);
94
+ var import_react3 = require("@payloadcms/richtext-lexical/react");
95
+
96
+ // src/components/RichTextContent/styled.tsx
78
97
  var import_react = __toESM(require("react"), 1);
79
- var import_react2 = require("@payloadcms/richtext-lexical/react");
98
+ function createComponentConverters(components, internalDocToHref) {
99
+ const converters = {};
100
+ if (components.Heading) {
101
+ const Heading = components.Heading;
102
+ converters.heading = ({ node, nodesToJSX }) => /* @__PURE__ */ import_react.default.createElement(Heading, { tag: node.tag, node }, nodesToJSX({ nodes: node.children }));
103
+ }
104
+ if (components.Paragraph) {
105
+ const Paragraph = components.Paragraph;
106
+ converters.paragraph = ({ node, nodesToJSX }) => {
107
+ const children = nodesToJSX({ nodes: node.children });
108
+ return /* @__PURE__ */ import_react.default.createElement(Paragraph, { isEmpty: !(children == null ? void 0 : children.length), node }, (children == null ? void 0 : children.length) ? children : /* @__PURE__ */ import_react.default.createElement("br", null));
109
+ };
110
+ }
111
+ if (components.Blockquote) {
112
+ const Blockquote = components.Blockquote;
113
+ converters.quote = ({ node, nodesToJSX }) => /* @__PURE__ */ import_react.default.createElement(Blockquote, { node }, nodesToJSX({ nodes: node.children }));
114
+ }
115
+ if (components.List) {
116
+ const List = components.List;
117
+ converters.list = ({ node, nodesToJSX }) => /* @__PURE__ */ import_react.default.createElement(List, { tag: node.tag, listType: node.listType, node }, nodesToJSX({ nodes: node.children }));
118
+ }
119
+ if (components.ListItem) {
120
+ const ListItem = components.ListItem;
121
+ converters.listitem = ({ node, nodesToJSX }) => {
122
+ const hasSubLists = node.children.some(
123
+ (child) => child.type === "list"
124
+ );
125
+ return /* @__PURE__ */ import_react.default.createElement(
126
+ ListItem,
127
+ {
128
+ hasSubLists,
129
+ checked: node.checked,
130
+ value: node.value,
131
+ node
132
+ },
133
+ nodesToJSX({ nodes: node.children })
134
+ );
135
+ };
136
+ }
137
+ if (components.Link) {
138
+ const Link = components.Link;
139
+ const resolveHref = (node) => {
140
+ var _a;
141
+ if (node.fields.linkType === "internal") {
142
+ return internalDocToHref ? internalDocToHref({ linkNode: node }) : "#";
143
+ }
144
+ return (_a = node.fields.url) != null ? _a : "";
145
+ };
146
+ converters.link = ({ node, nodesToJSX }) => /* @__PURE__ */ import_react.default.createElement(
147
+ Link,
148
+ {
149
+ href: resolveHref(node),
150
+ rel: node.fields.newTab ? "noopener noreferrer" : void 0,
151
+ target: node.fields.newTab ? "_blank" : void 0,
152
+ node
153
+ },
154
+ nodesToJSX({ nodes: node.children })
155
+ );
156
+ converters.autolink = ({ node, nodesToJSX }) => {
157
+ var _a;
158
+ return /* @__PURE__ */ import_react.default.createElement(
159
+ Link,
160
+ {
161
+ href: (_a = node.fields.url) != null ? _a : "",
162
+ rel: node.fields.newTab ? "noopener noreferrer" : void 0,
163
+ target: node.fields.newTab ? "_blank" : void 0,
164
+ node
165
+ },
166
+ nodesToJSX({ nodes: node.children })
167
+ );
168
+ };
169
+ }
170
+ if (components.HorizontalRule) {
171
+ const HorizontalRule = components.HorizontalRule;
172
+ converters.horizontalrule = /* @__PURE__ */ import_react.default.createElement(HorizontalRule, null);
173
+ }
174
+ if (components.Upload) {
175
+ const Upload = components.Upload;
176
+ converters.upload = ({ node }) => {
177
+ var _a;
178
+ const uploadNode = node;
179
+ if (typeof uploadNode.value !== "object") return null;
180
+ const doc = uploadNode.value;
181
+ return /* @__PURE__ */ import_react.default.createElement(
182
+ Upload,
183
+ {
184
+ src: doc.url,
185
+ alt: ((_a = uploadNode.fields) == null ? void 0 : _a.alt) || (doc == null ? void 0 : doc.alt) || "",
186
+ width: doc.width,
187
+ height: doc.height,
188
+ mimeType: doc.mimeType,
189
+ filename: doc.filename,
190
+ sizes: doc.sizes,
191
+ node
192
+ }
193
+ );
194
+ };
195
+ }
196
+ if (components.Table) {
197
+ const Table = components.Table;
198
+ converters.table = ({ node, nodesToJSX }) => /* @__PURE__ */ import_react.default.createElement(Table, { node }, nodesToJSX({ nodes: node.children }));
199
+ }
200
+ if (components.TableRow) {
201
+ const TableRow = components.TableRow;
202
+ converters.tablerow = ({ node, nodesToJSX }) => /* @__PURE__ */ import_react.default.createElement(TableRow, { node }, nodesToJSX({ nodes: node.children }));
203
+ }
204
+ if (components.TableCell) {
205
+ const TableCell = components.TableCell;
206
+ converters.tablecell = ({ node, nodesToJSX }) => /* @__PURE__ */ import_react.default.createElement(
207
+ TableCell,
208
+ {
209
+ tag: node.headerState > 0 ? "th" : "td",
210
+ colSpan: node.colSpan > 1 ? node.colSpan : void 0,
211
+ rowSpan: node.rowSpan > 1 ? node.rowSpan : void 0,
212
+ backgroundColor: node.backgroundColor || void 0,
213
+ node
214
+ },
215
+ nodesToJSX({ nodes: node.children })
216
+ );
217
+ }
218
+ return converters;
219
+ }
220
+ function StyledRichTextContent(_a) {
221
+ var _b = _a, {
222
+ components = {},
223
+ internalDocToHref,
224
+ blocks,
225
+ textState
226
+ } = _b, props = __objRest(_b, [
227
+ "components",
228
+ "internalDocToHref",
229
+ "blocks",
230
+ "textState"
231
+ ]);
232
+ const converters = createComponentConverters(components, internalDocToHref);
233
+ return /* @__PURE__ */ import_react.default.createElement(
234
+ RichTextContent,
235
+ __spreadProps(__spreadValues({}, props), {
236
+ internalDocToHref,
237
+ converters,
238
+ blocks,
239
+ textState
240
+ })
241
+ );
242
+ }
243
+
244
+ // src/components/RichTextContent/index.tsx
245
+ function hyphenToCamel(str) {
246
+ return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
247
+ }
248
+ function createTextStateConverter(state) {
249
+ const defaultTextConverter = import_react3.TextJSXConverter.text;
250
+ return (_a) => {
251
+ var _b = _a, { node } = _b, rest = __objRest(_b, ["node"]);
252
+ var _a2, _b2;
253
+ const base = defaultTextConverter(__spreadValues({ node }, rest));
254
+ const nodeState = node.$;
255
+ if (!nodeState || typeof nodeState !== "object") return base;
256
+ const style = {};
257
+ for (const stateKey in nodeState) {
258
+ const stateValue = nodeState[stateKey];
259
+ if (!stateValue) continue;
260
+ const css = (_b2 = (_a2 = state[stateKey]) == null ? void 0 : _a2[stateValue]) == null ? void 0 : _b2.css;
261
+ if (css) {
262
+ for (const prop in css) {
263
+ const val = css[prop];
264
+ if (val) style[hyphenToCamel(prop)] = val;
265
+ }
266
+ }
267
+ }
268
+ if (Object.keys(style).length === 0) return base;
269
+ return /* @__PURE__ */ import_react2.default.createElement("span", { style }, base);
270
+ };
271
+ }
80
272
  function RichTextContent({
81
273
  data,
82
274
  className,
83
275
  internalDocToHref,
84
- blocks
276
+ converters,
277
+ blocks,
278
+ disableDefaultConverters,
279
+ textState
85
280
  }) {
86
- return /* @__PURE__ */ import_react.default.createElement(
87
- import_react2.RichText,
88
- {
89
- data,
90
- className,
91
- converters: __spreadProps(__spreadValues(__spreadValues({}, import_react2.defaultJSXConverters), (0, import_react2.LinkJSXConverter)({
92
- internalDocToHref
93
- })), {
94
- blocks: blocks ? blocks : void 0
95
- })
96
- }
97
- );
281
+ const baseConverters = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, disableDefaultConverters ? {} : import_react3.defaultJSXConverters), (0, import_react3.LinkJSXConverter)({ internalDocToHref })), textState ? { text: createTextStateConverter(textState) } : {}), converters), blocks ? { blocks } : {});
282
+ return /* @__PURE__ */ import_react2.default.createElement(import_react3.RichText, { data, className, converters: baseConverters });
98
283
  }
99
284
 
100
285
  // src/components/FormRenderer/index.tsx
101
- var import_react3 = __toESM(require("react"), 1);
286
+ var import_react4 = __toESM(require("react"), 1);
102
287
 
103
288
  // src/components/FormRenderer/countries.ts
104
289
  var COUNTRIES = [
@@ -437,15 +622,15 @@ function FormRenderer({
437
622
  renderButton
438
623
  }) {
439
624
  var _a;
440
- const [values, setValues] = (0, import_react3.useState)(
625
+ const [values, setValues] = (0, import_react4.useState)(
441
626
  () => getInitialValues(form.fields)
442
627
  );
443
- const [isSubmitting, setIsSubmitting] = (0, import_react3.useState)(false);
444
- const submittingRef = (0, import_react3.useRef)(false);
445
- (0, import_react3.useEffect)(() => {
628
+ const [isSubmitting, setIsSubmitting] = (0, import_react4.useState)(false);
629
+ const submittingRef = (0, import_react4.useRef)(false);
630
+ (0, import_react4.useEffect)(() => {
446
631
  setValues(getInitialValues(form.fields));
447
632
  }, [form.id]);
448
- const handleChange = (0, import_react3.useCallback)(
633
+ const handleChange = (0, import_react4.useCallback)(
449
634
  (name, value) => {
450
635
  setValues((prev) => __spreadProps(__spreadValues({}, prev), { [name]: value }));
451
636
  },
@@ -469,14 +654,14 @@ function FormRenderer({
469
654
  value: (_a2 = values[field.name]) != null ? _a2 : "",
470
655
  onChange: (v) => handleChange(field.name, v)
471
656
  };
472
- const el = /* @__PURE__ */ import_react3.default.createElement(
657
+ const el = /* @__PURE__ */ import_react4.default.createElement(
473
658
  "div",
474
659
  {
475
660
  key: (_b = field.id) != null ? _b : field.name,
476
661
  className: fieldClassName,
477
662
  style
478
663
  },
479
- field.label && /* @__PURE__ */ import_react3.default.createElement("label", { htmlFor: field.name }, field.label),
664
+ field.label && /* @__PURE__ */ import_react4.default.createElement("label", { htmlFor: field.name }, field.label),
480
665
  input
481
666
  );
482
667
  return renderField ? renderField(field, context, el) : el;
@@ -486,7 +671,7 @@ function FormRenderer({
486
671
  return wrapField(
487
672
  field,
488
673
  style,
489
- /* @__PURE__ */ import_react3.default.createElement(
674
+ /* @__PURE__ */ import_react4.default.createElement(
490
675
  "select",
491
676
  {
492
677
  id: field.name,
@@ -495,8 +680,8 @@ function FormRenderer({
495
680
  required: (_b = field.required) != null ? _b : false,
496
681
  onChange: (e) => handleChange(field.name, e.target.value)
497
682
  },
498
- /* @__PURE__ */ import_react3.default.createElement("option", { value: "" }, placeholder || "Select\u2026"),
499
- options.map((opt) => /* @__PURE__ */ import_react3.default.createElement("option", { key: opt.value, value: opt.value }, opt.label))
683
+ /* @__PURE__ */ import_react4.default.createElement("option", { value: "" }, placeholder || "Select\u2026"),
684
+ options.map((opt) => /* @__PURE__ */ import_react4.default.createElement("option", { key: opt.value, value: opt.value }, opt.label))
500
685
  )
501
686
  );
502
687
  };
@@ -508,7 +693,7 @@ function FormRenderer({
508
693
  return wrapField(
509
694
  field,
510
695
  style,
511
- /* @__PURE__ */ import_react3.default.createElement(
696
+ /* @__PURE__ */ import_react4.default.createElement(
512
697
  "input",
513
698
  {
514
699
  type: "text",
@@ -525,7 +710,7 @@ function FormRenderer({
525
710
  return wrapField(
526
711
  field,
527
712
  style,
528
- /* @__PURE__ */ import_react3.default.createElement(
713
+ /* @__PURE__ */ import_react4.default.createElement(
529
714
  "input",
530
715
  {
531
716
  type: "email",
@@ -541,7 +726,7 @@ function FormRenderer({
541
726
  return wrapField(
542
727
  field,
543
728
  style,
544
- /* @__PURE__ */ import_react3.default.createElement(
729
+ /* @__PURE__ */ import_react4.default.createElement(
545
730
  "input",
546
731
  {
547
732
  type: "number",
@@ -562,7 +747,7 @@ function FormRenderer({
562
747
  return wrapField(
563
748
  field,
564
749
  style,
565
- /* @__PURE__ */ import_react3.default.createElement(
750
+ /* @__PURE__ */ import_react4.default.createElement(
566
751
  "textarea",
567
752
  {
568
753
  id: field.name,
@@ -578,14 +763,14 @@ function FormRenderer({
578
763
  value: (_j = values[field.name]) != null ? _j : false,
579
764
  onChange: (v) => handleChange(field.name, v)
580
765
  };
581
- const el = /* @__PURE__ */ import_react3.default.createElement(
766
+ const el = /* @__PURE__ */ import_react4.default.createElement(
582
767
  "div",
583
768
  {
584
769
  key: (_k = field.id) != null ? _k : field.name,
585
770
  className: fieldClassName,
586
771
  style
587
772
  },
588
- /* @__PURE__ */ import_react3.default.createElement("label", { htmlFor: field.name }, /* @__PURE__ */ import_react3.default.createElement(
773
+ /* @__PURE__ */ import_react4.default.createElement("label", { htmlFor: field.name }, /* @__PURE__ */ import_react4.default.createElement(
589
774
  "input",
590
775
  {
591
776
  type: "checkbox",
@@ -595,7 +780,7 @@ function FormRenderer({
595
780
  required: (_l = field.required) != null ? _l : false,
596
781
  onChange: (e) => handleChange(field.name, e.target.checked)
597
782
  }
598
- ), field.label && /* @__PURE__ */ import_react3.default.createElement("span", null, field.label))
783
+ ), field.label && /* @__PURE__ */ import_react4.default.createElement("span", null, field.label))
599
784
  );
600
785
  return renderField ? renderField(field, context, el) : el;
601
786
  }
@@ -612,7 +797,7 @@ function FormRenderer({
612
797
  return renderSelectField(field, style, US_STATES);
613
798
  case "message":
614
799
  if (renderMessage && field.message) {
615
- return /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, { key: (_p = (_o = field.id) != null ? _o : field.blockName) != null ? _p : "message" }, renderMessage(field.message));
800
+ return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, { key: (_p = (_o = field.id) != null ? _o : field.blockName) != null ? _p : "message" }, renderMessage(field.message));
616
801
  }
617
802
  return null;
618
803
  default:
@@ -620,7 +805,7 @@ function FormRenderer({
620
805
  }
621
806
  };
622
807
  const buttonLabel = form.submitButtonLabel || "Submit";
623
- return /* @__PURE__ */ import_react3.default.createElement("form", { onSubmit: handleSubmit, className }, (_a = form.fields) == null ? void 0 : _a.map((field) => renderFieldElement(field)), renderButton ? renderButton({ isSubmitting, label: buttonLabel }) : /* @__PURE__ */ import_react3.default.createElement(
808
+ return /* @__PURE__ */ import_react4.default.createElement("form", { onSubmit: handleSubmit, className }, (_a = form.fields) == null ? void 0 : _a.map((field) => renderFieldElement(field)), renderButton ? renderButton({ isSubmitting, label: buttonLabel }) : /* @__PURE__ */ import_react4.default.createElement(
624
809
  "button",
625
810
  {
626
811
  type: "submit",
@@ -632,7 +817,7 @@ function FormRenderer({
632
817
  }
633
818
 
634
819
  // src/components/Image/index.tsx
635
- var import_react4 = __toESM(require("react"), 1);
820
+ var import_react5 = __toESM(require("react"), 1);
636
821
 
637
822
  // src/utils/image.ts
638
823
  var IMAGE_SIZES = [384, 768, 1536];
@@ -697,8 +882,8 @@ function Image({
697
882
  imageRendering
698
883
  }) {
699
884
  var _a, _b;
700
- const [loaded, setLoaded] = (0, import_react4.useState)(false);
701
- const firedRef = (0, import_react4.useRef)(false);
885
+ const [loaded, setLoaded] = (0, import_react5.useState)(false);
886
+ const firedRef = (0, import_react5.useRef)(false);
702
887
  const isPixelRendering = imageRendering === "pixelated" || imageRendering === "crisp-edges";
703
888
  const placeholder = placeholderProp != null ? placeholderProp : isPixelRendering ? "none" : "blur";
704
889
  const loading = priority ? "eager" : loadingProp != null ? loadingProp : "lazy";
@@ -710,13 +895,13 @@ function Image({
710
895
  type: placeholder
711
896
  });
712
897
  const placeholderColor = !hasLqip && "backgroundColor" in placeholderStyle ? placeholderStyle.backgroundColor : void 0;
713
- const fireLoad = (0, import_react4.useCallback)(() => {
898
+ const fireLoad = (0, import_react5.useCallback)(() => {
714
899
  if (firedRef.current) return;
715
900
  firedRef.current = true;
716
901
  setLoaded(true);
717
902
  onLoad == null ? void 0 : onLoad();
718
903
  }, [onLoad]);
719
- const imgRef = (0, import_react4.useCallback)(
904
+ const imgRef = (0, import_react5.useCallback)(
720
905
  (node) => {
721
906
  if (node && node.complete && node.naturalWidth > 0) {
722
907
  fireLoad();
@@ -747,7 +932,7 @@ function Image({
747
932
  opacity: loaded ? 1 : 0,
748
933
  transition: "opacity 0.3s ease"
749
934
  }), imgStyle);
750
- return /* @__PURE__ */ import_react4.default.createElement("div", { className, style: containerStyle }, hasLqip && /* @__PURE__ */ import_react4.default.createElement(
935
+ return /* @__PURE__ */ import_react5.default.createElement("div", { className, style: containerStyle }, hasLqip && /* @__PURE__ */ import_react5.default.createElement(
751
936
  "img",
752
937
  {
753
938
  "aria-hidden": true,
@@ -760,7 +945,7 @@ function Image({
760
945
  transform: "scale(1.1)"
761
946
  })
762
947
  }
763
- ), placeholderColor && /* @__PURE__ */ import_react4.default.createElement(
948
+ ), placeholderColor && /* @__PURE__ */ import_react5.default.createElement(
764
949
  "div",
765
950
  {
766
951
  "aria-hidden": true,
@@ -768,7 +953,7 @@ function Image({
768
953
  backgroundColor: placeholderColor
769
954
  })
770
955
  }
771
- ), /* @__PURE__ */ import_react4.default.createElement(
956
+ ), /* @__PURE__ */ import_react5.default.createElement(
772
957
  "img",
773
958
  {
774
959
  ref: imgRef,
@@ -786,4 +971,130 @@ function Image({
786
971
  }
787
972
  ));
788
973
  }
974
+
975
+ // src/components/CodeBlock/index.tsx
976
+ var import_react7 = __toESM(require("react"), 1);
977
+
978
+ // src/components/CodeBlock/highlight.ts
979
+ var import_react6 = require("react");
980
+ var import_jsx_runtime = require("react/jsx-runtime");
981
+ var import_hast_util_to_jsx_runtime = require("hast-util-to-jsx-runtime");
982
+ var import_shiki = require("shiki");
983
+ var LANGUAGE_ALIASES = {
984
+ js: "javascript",
985
+ ts: "typescript",
986
+ sh: "bash",
987
+ shell: "bash",
988
+ yml: "yaml",
989
+ py: "python",
990
+ rb: "ruby",
991
+ plaintext: "text"
992
+ };
993
+ function normalizeLanguage(lang) {
994
+ return LANGUAGE_ALIASES[lang] || lang;
995
+ }
996
+ function highlight(code, lang, theme = "github-dark") {
997
+ return __async(this, null, function* () {
998
+ const normalized = normalizeLanguage(lang);
999
+ try {
1000
+ const hast = yield (0, import_shiki.codeToHast)(code, {
1001
+ lang: normalized,
1002
+ theme
1003
+ });
1004
+ return (0, import_hast_util_to_jsx_runtime.toJsxRuntime)(hast, { Fragment: import_react6.Fragment, jsx: import_jsx_runtime.jsx, jsxs: import_jsx_runtime.jsxs });
1005
+ } catch (e) {
1006
+ const hast = yield (0, import_shiki.codeToHast)(code, { lang: "text", theme });
1007
+ return (0, import_hast_util_to_jsx_runtime.toJsxRuntime)(hast, { Fragment: import_react6.Fragment, jsx: import_jsx_runtime.jsx, jsxs: import_jsx_runtime.jsxs });
1008
+ }
1009
+ });
1010
+ }
1011
+
1012
+ // src/components/CodeBlock/index.tsx
1013
+ function CodeBlock({
1014
+ code,
1015
+ language = "typescript",
1016
+ theme = "github-dark",
1017
+ className,
1018
+ initial,
1019
+ showLineNumbers = false,
1020
+ showCopyButton = true
1021
+ }) {
1022
+ const [nodes, setNodes] = (0, import_react7.useState)(initial);
1023
+ const [copied, setCopied] = (0, import_react7.useState)(false);
1024
+ (0, import_react7.useEffect)(() => {
1025
+ let cancelled = false;
1026
+ void highlight(code, language, theme).then((el) => {
1027
+ if (!cancelled) setNodes(el);
1028
+ });
1029
+ return () => {
1030
+ cancelled = true;
1031
+ };
1032
+ }, [code, language, theme]);
1033
+ const handleCopy = () => {
1034
+ void navigator.clipboard.writeText(code).then(() => {
1035
+ setCopied(true);
1036
+ setTimeout(() => setCopied(false), 2e3);
1037
+ }, () => {
1038
+ });
1039
+ };
1040
+ return /* @__PURE__ */ import_react7.default.createElement("div", { className, style: { position: "relative" } }, showCopyButton && /* @__PURE__ */ import_react7.default.createElement(
1041
+ "button",
1042
+ {
1043
+ type: "button",
1044
+ onClick: handleCopy,
1045
+ "aria-label": "Copy code",
1046
+ style: {
1047
+ position: "absolute",
1048
+ top: 8,
1049
+ right: 8,
1050
+ zIndex: 1,
1051
+ padding: "4px 8px",
1052
+ fontSize: 12,
1053
+ lineHeight: 1,
1054
+ border: "1px solid rgba(255,255,255,0.2)",
1055
+ borderRadius: 4,
1056
+ background: "rgba(0,0,0,0.3)",
1057
+ color: "#ccc",
1058
+ cursor: "pointer",
1059
+ opacity: 0.7,
1060
+ transition: "opacity 0.15s"
1061
+ },
1062
+ onMouseEnter: (e) => {
1063
+ e.currentTarget.style.opacity = "1";
1064
+ },
1065
+ onMouseLeave: (e) => {
1066
+ e.currentTarget.style.opacity = "0.7";
1067
+ }
1068
+ },
1069
+ copied ? "Copied!" : "Copy"
1070
+ ), showLineNumbers && nodes ? /* @__PURE__ */ import_react7.default.createElement("div", { style: { display: "flex" } }, /* @__PURE__ */ import_react7.default.createElement(
1071
+ "div",
1072
+ {
1073
+ "aria-hidden": true,
1074
+ style: {
1075
+ padding: "1em 0.5em 1em 1em",
1076
+ textAlign: "right",
1077
+ userSelect: "none",
1078
+ color: "rgba(255,255,255,0.3)",
1079
+ fontFamily: "monospace",
1080
+ fontSize: 13,
1081
+ lineHeight: 1.5
1082
+ }
1083
+ },
1084
+ code.split("\n").map((_, i) => /* @__PURE__ */ import_react7.default.createElement("div", { key: i }, i + 1))
1085
+ ), /* @__PURE__ */ import_react7.default.createElement("div", { style: { flex: 1, overflow: "auto" } }, nodes)) : nodes != null ? nodes : /* @__PURE__ */ import_react7.default.createElement(
1086
+ "pre",
1087
+ {
1088
+ style: {
1089
+ margin: 0,
1090
+ padding: "1em",
1091
+ overflow: "auto",
1092
+ fontFamily: "monospace",
1093
+ fontSize: 13,
1094
+ lineHeight: 1.5
1095
+ }
1096
+ },
1097
+ /* @__PURE__ */ import_react7.default.createElement("code", null, code)
1098
+ ));
1099
+ }
789
1100
  //# sourceMappingURL=components.cjs.map