@asteroidcms/core-utils 0.1.3 → 0.1.5
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 +64 -4
- package/dist/client.cjs +383 -17
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +116 -11
- package/dist/client.d.ts +116 -11
- package/dist/client.js +382 -20
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +115 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -2
- package/dist/index.d.ts +45 -2
- package/dist/index.js +113 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/client.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
3
|
-
import { PropsWithChildren } from 'react';
|
|
2
|
+
import { PropsWithChildren, ReactNode, RefObject } from 'react';
|
|
4
3
|
import * as _apollo_client from '@apollo/client';
|
|
5
4
|
import { InMemoryCacheConfig, ApolloClientOptions, ApolloClient } from '@apollo/client';
|
|
6
5
|
import { useMutation } from '@apollo/client/react';
|
|
@@ -205,7 +204,7 @@ declare function useCmsImage(): (id?: string) => string;
|
|
|
205
204
|
*
|
|
206
205
|
* Idempotent: parseRichText(parseRichText(x, opts), opts) === parseRichText(x, opts).
|
|
207
206
|
*/
|
|
208
|
-
type RichTextClassKey = "p" | "br" | "hr" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "ul" | "ol" | "li" | "blockquote" | "pre" | "code" | "inlineCode" | "a" | "strong" | "em" | "u" | "s" | "kbd" | "table" | "tableWrapper" | "thead" | "tbody" | "tr" | "th" | "td" | "figure" | "figcaption" | "img" | "span" | "callout" | "calloutTitle";
|
|
207
|
+
type RichTextClassKey = "p" | "br" | "hr" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "ul" | "ol" | "li" | "blockquote" | "pre" | "code" | "inlineCode" | "a" | "strong" | "em" | "u" | "s" | "kbd" | "table" | "tableWrapper" | "thead" | "tbody" | "tr" | "th" | "td" | "figure" | "figcaption" | "img" | "span" | "callout" | "calloutTitle" | "collapsible" | "collapsibleTitle";
|
|
209
208
|
type RichTextClassMap = Partial<Record<RichTextClassKey, string>> & {
|
|
210
209
|
/** Variant overrides keyed as `${matchKey}:${variant}`, e.g. "callout:warning". */
|
|
211
210
|
variants?: Record<string, string>;
|
|
@@ -217,13 +216,119 @@ interface RichTextContentProps {
|
|
|
217
216
|
/** Wrapper element. Defaults to `div`. Use `article` for blog content. */
|
|
218
217
|
as?: keyof React.JSX.IntrinsicElements;
|
|
219
218
|
className?: string;
|
|
219
|
+
/**
|
|
220
|
+
* Fires after the parsed HTML is in the DOM and post-render enhancements
|
|
221
|
+
* (syntax highlighting, copy buttons, blockquote decorations) have run.
|
|
222
|
+
* The wrapper element is passed back so callers can read headings, attach
|
|
223
|
+
* a ToC observer, or do other DOM work without re-querying.
|
|
224
|
+
*/
|
|
225
|
+
onReady?: (root: HTMLElement) => void;
|
|
226
|
+
/**
|
|
227
|
+
* Optional ref to the wrapper element. Useful for hooks like
|
|
228
|
+
* `useTableOfContents` that need a stable reference to the rendered tree.
|
|
229
|
+
*/
|
|
230
|
+
contentRef?: React.MutableRefObject<HTMLElement | null>;
|
|
231
|
+
/**
|
|
232
|
+
* Per-variant icon override for callouts that opt into icons via
|
|
233
|
+
* `data-icon`. Provide a React element for any variant key — these
|
|
234
|
+
* elements are rendered into the chip via a portal, so they live in
|
|
235
|
+
* React land (refs, event handlers, theme context all work). Variants
|
|
236
|
+
* you don't provide fall back to the built-in SVG glyph.
|
|
237
|
+
*
|
|
238
|
+
* Common variants: `"info" | "warning" | "success" | "danger" | "default"`.
|
|
239
|
+
* Custom variant names work too — anything you set via
|
|
240
|
+
* `data-variant` on an `<aside data-callout>`.
|
|
241
|
+
*
|
|
242
|
+
* Example:
|
|
243
|
+
* ```tsx
|
|
244
|
+
* import { Info, AlertTriangle } from "lucide-react";
|
|
245
|
+
*
|
|
246
|
+
* <RichTextContent
|
|
247
|
+
* html={article.doc}
|
|
248
|
+
* calloutIcons={{
|
|
249
|
+
* info: <Info size={14} strokeWidth={2.4} />,
|
|
250
|
+
* warning: <AlertTriangle size={14} strokeWidth={2.4} />,
|
|
251
|
+
* }}
|
|
252
|
+
* />
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
calloutIcons?: Partial<Record<string, ReactNode>>;
|
|
220
256
|
}
|
|
221
|
-
declare function RichTextContent({ html, classMap, as, className, }: RichTextContentProps):
|
|
222
|
-
ref: react.MutableRefObject<HTMLElement | null>;
|
|
223
|
-
className: string | undefined;
|
|
224
|
-
dangerouslySetInnerHTML: {
|
|
225
|
-
__html: string;
|
|
226
|
-
};
|
|
227
|
-
}, HTMLElement>;
|
|
257
|
+
declare function RichTextContent({ html, classMap, as, className, onReady, contentRef, calloutIcons, }: RichTextContentProps): react_jsx_runtime.JSX.Element;
|
|
228
258
|
|
|
229
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Heading extraction helpers used to build tables of contents (ToC) from
|
|
261
|
+
* rich-text HTML. Server-safe — no React, no DOM dependency in the HTML
|
|
262
|
+
* variant. The DOM variant assigns missing `id`s in-place so anchor links
|
|
263
|
+
* resolve immediately.
|
|
264
|
+
*/
|
|
265
|
+
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
266
|
+
interface ExtractedHeading {
|
|
267
|
+
id: string;
|
|
268
|
+
text: string;
|
|
269
|
+
level: HeadingLevel;
|
|
270
|
+
}
|
|
271
|
+
interface ExtractHeadingsOptions {
|
|
272
|
+
/** Levels to include. Defaults to `[2, 3]` — typical doc page outline. */
|
|
273
|
+
levels?: ReadonlyArray<HeadingLevel>;
|
|
274
|
+
/** Custom slug function. Defaults to a lowercase/kebab/diacritic-safe slug. */
|
|
275
|
+
slugify?: (text: string, index: number) => string;
|
|
276
|
+
}
|
|
277
|
+
declare function slugify(text: string): string;
|
|
278
|
+
/**
|
|
279
|
+
* Parse headings out of a raw HTML string. Returns headings in document
|
|
280
|
+
* order with stable, de-duplicated IDs.
|
|
281
|
+
*
|
|
282
|
+
* If a heading already has an `id` attribute, it's preserved verbatim
|
|
283
|
+
* (and reserved so later slugs don't collide with it).
|
|
284
|
+
*/
|
|
285
|
+
declare function extractHeadingsFromHtml(html: string, options?: ExtractHeadingsOptions): ExtractedHeading[];
|
|
286
|
+
/**
|
|
287
|
+
* Walk a rendered DOM subtree, collect headings, and assign missing `id`s
|
|
288
|
+
* in-place so anchor links resolve immediately. Also sets `scrollMarginTop`
|
|
289
|
+
* on each heading when `scrollMarginTop` is provided so navigation lands
|
|
290
|
+
* cleanly below a sticky header.
|
|
291
|
+
*/
|
|
292
|
+
declare function extractHeadingsFromElement(root: HTMLElement, options?: ExtractHeadingsOptions & {
|
|
293
|
+
scrollMarginTop?: number;
|
|
294
|
+
}): ExtractedHeading[];
|
|
295
|
+
|
|
296
|
+
interface UseTableOfContentsOptions {
|
|
297
|
+
/** Heading levels to include. Defaults to `[2, 3]`. */
|
|
298
|
+
levels?: ReadonlyArray<HeadingLevel>;
|
|
299
|
+
/**
|
|
300
|
+
* Re-collect headings whenever this value changes. Pass the article slug
|
|
301
|
+
* (or any stable identifier) so swapping content rebuilds the ToC.
|
|
302
|
+
*/
|
|
303
|
+
contentKey?: string | number | null;
|
|
304
|
+
/** Pixels to subtract from heading scroll-into-view target. Default 24. */
|
|
305
|
+
scrollMarginTop?: number;
|
|
306
|
+
/**
|
|
307
|
+
* Distance from the top of the viewport (in px) at which a heading becomes
|
|
308
|
+
* "active". A heading is considered active once its top edge has scrolled
|
|
309
|
+
* past this line. Default `96` — works well with a sticky header that
|
|
310
|
+
* stands ~60–80px tall.
|
|
311
|
+
*/
|
|
312
|
+
activationOffset?: number;
|
|
313
|
+
}
|
|
314
|
+
interface UseTableOfContentsResult {
|
|
315
|
+
items: ExtractedHeading[];
|
|
316
|
+
activeId: string;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Build a table of contents from a rendered element and track which
|
|
320
|
+
* heading is currently in view via IntersectionObserver. Resilient to
|
|
321
|
+
* content swaps when `contentKey` is provided.
|
|
322
|
+
*
|
|
323
|
+
* Usage:
|
|
324
|
+
* ```tsx
|
|
325
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
326
|
+
* const { items, activeId } = useTableOfContents(ref, {
|
|
327
|
+
* contentKey: article.slug,
|
|
328
|
+
* levels: [2, 3],
|
|
329
|
+
* });
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
declare function useTableOfContents(ref: RefObject<HTMLElement | null>, options?: UseTableOfContentsOptions): UseTableOfContentsResult;
|
|
333
|
+
|
|
334
|
+
export { AsteroidCMSProvider, type AsteroidCMSProviderProps, type ExtractHeadingsOptions, type ExtractedHeading, type HeadingLevel, RichTextContent, type UseCmsContentOptions, type UseCmsMutateOptions, type UseTableOfContentsOptions, type UseTableOfContentsResult, extractHeadingsFromElement, extractHeadingsFromHtml, slugify, useAsteroidCMSConfig, useCmsContent, useCmsImage, useCmsMutate, useTableOfContents };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
3
|
-
import { PropsWithChildren } from 'react';
|
|
2
|
+
import { PropsWithChildren, ReactNode, RefObject } from 'react';
|
|
4
3
|
import * as _apollo_client from '@apollo/client';
|
|
5
4
|
import { InMemoryCacheConfig, ApolloClientOptions, ApolloClient } from '@apollo/client';
|
|
6
5
|
import { useMutation } from '@apollo/client/react';
|
|
@@ -205,7 +204,7 @@ declare function useCmsImage(): (id?: string) => string;
|
|
|
205
204
|
*
|
|
206
205
|
* Idempotent: parseRichText(parseRichText(x, opts), opts) === parseRichText(x, opts).
|
|
207
206
|
*/
|
|
208
|
-
type RichTextClassKey = "p" | "br" | "hr" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "ul" | "ol" | "li" | "blockquote" | "pre" | "code" | "inlineCode" | "a" | "strong" | "em" | "u" | "s" | "kbd" | "table" | "tableWrapper" | "thead" | "tbody" | "tr" | "th" | "td" | "figure" | "figcaption" | "img" | "span" | "callout" | "calloutTitle";
|
|
207
|
+
type RichTextClassKey = "p" | "br" | "hr" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "ul" | "ol" | "li" | "blockquote" | "pre" | "code" | "inlineCode" | "a" | "strong" | "em" | "u" | "s" | "kbd" | "table" | "tableWrapper" | "thead" | "tbody" | "tr" | "th" | "td" | "figure" | "figcaption" | "img" | "span" | "callout" | "calloutTitle" | "collapsible" | "collapsibleTitle";
|
|
209
208
|
type RichTextClassMap = Partial<Record<RichTextClassKey, string>> & {
|
|
210
209
|
/** Variant overrides keyed as `${matchKey}:${variant}`, e.g. "callout:warning". */
|
|
211
210
|
variants?: Record<string, string>;
|
|
@@ -217,13 +216,119 @@ interface RichTextContentProps {
|
|
|
217
216
|
/** Wrapper element. Defaults to `div`. Use `article` for blog content. */
|
|
218
217
|
as?: keyof React.JSX.IntrinsicElements;
|
|
219
218
|
className?: string;
|
|
219
|
+
/**
|
|
220
|
+
* Fires after the parsed HTML is in the DOM and post-render enhancements
|
|
221
|
+
* (syntax highlighting, copy buttons, blockquote decorations) have run.
|
|
222
|
+
* The wrapper element is passed back so callers can read headings, attach
|
|
223
|
+
* a ToC observer, or do other DOM work without re-querying.
|
|
224
|
+
*/
|
|
225
|
+
onReady?: (root: HTMLElement) => void;
|
|
226
|
+
/**
|
|
227
|
+
* Optional ref to the wrapper element. Useful for hooks like
|
|
228
|
+
* `useTableOfContents` that need a stable reference to the rendered tree.
|
|
229
|
+
*/
|
|
230
|
+
contentRef?: React.MutableRefObject<HTMLElement | null>;
|
|
231
|
+
/**
|
|
232
|
+
* Per-variant icon override for callouts that opt into icons via
|
|
233
|
+
* `data-icon`. Provide a React element for any variant key — these
|
|
234
|
+
* elements are rendered into the chip via a portal, so they live in
|
|
235
|
+
* React land (refs, event handlers, theme context all work). Variants
|
|
236
|
+
* you don't provide fall back to the built-in SVG glyph.
|
|
237
|
+
*
|
|
238
|
+
* Common variants: `"info" | "warning" | "success" | "danger" | "default"`.
|
|
239
|
+
* Custom variant names work too — anything you set via
|
|
240
|
+
* `data-variant` on an `<aside data-callout>`.
|
|
241
|
+
*
|
|
242
|
+
* Example:
|
|
243
|
+
* ```tsx
|
|
244
|
+
* import { Info, AlertTriangle } from "lucide-react";
|
|
245
|
+
*
|
|
246
|
+
* <RichTextContent
|
|
247
|
+
* html={article.doc}
|
|
248
|
+
* calloutIcons={{
|
|
249
|
+
* info: <Info size={14} strokeWidth={2.4} />,
|
|
250
|
+
* warning: <AlertTriangle size={14} strokeWidth={2.4} />,
|
|
251
|
+
* }}
|
|
252
|
+
* />
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
calloutIcons?: Partial<Record<string, ReactNode>>;
|
|
220
256
|
}
|
|
221
|
-
declare function RichTextContent({ html, classMap, as, className, }: RichTextContentProps):
|
|
222
|
-
ref: react.MutableRefObject<HTMLElement | null>;
|
|
223
|
-
className: string | undefined;
|
|
224
|
-
dangerouslySetInnerHTML: {
|
|
225
|
-
__html: string;
|
|
226
|
-
};
|
|
227
|
-
}, HTMLElement>;
|
|
257
|
+
declare function RichTextContent({ html, classMap, as, className, onReady, contentRef, calloutIcons, }: RichTextContentProps): react_jsx_runtime.JSX.Element;
|
|
228
258
|
|
|
229
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Heading extraction helpers used to build tables of contents (ToC) from
|
|
261
|
+
* rich-text HTML. Server-safe — no React, no DOM dependency in the HTML
|
|
262
|
+
* variant. The DOM variant assigns missing `id`s in-place so anchor links
|
|
263
|
+
* resolve immediately.
|
|
264
|
+
*/
|
|
265
|
+
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
266
|
+
interface ExtractedHeading {
|
|
267
|
+
id: string;
|
|
268
|
+
text: string;
|
|
269
|
+
level: HeadingLevel;
|
|
270
|
+
}
|
|
271
|
+
interface ExtractHeadingsOptions {
|
|
272
|
+
/** Levels to include. Defaults to `[2, 3]` — typical doc page outline. */
|
|
273
|
+
levels?: ReadonlyArray<HeadingLevel>;
|
|
274
|
+
/** Custom slug function. Defaults to a lowercase/kebab/diacritic-safe slug. */
|
|
275
|
+
slugify?: (text: string, index: number) => string;
|
|
276
|
+
}
|
|
277
|
+
declare function slugify(text: string): string;
|
|
278
|
+
/**
|
|
279
|
+
* Parse headings out of a raw HTML string. Returns headings in document
|
|
280
|
+
* order with stable, de-duplicated IDs.
|
|
281
|
+
*
|
|
282
|
+
* If a heading already has an `id` attribute, it's preserved verbatim
|
|
283
|
+
* (and reserved so later slugs don't collide with it).
|
|
284
|
+
*/
|
|
285
|
+
declare function extractHeadingsFromHtml(html: string, options?: ExtractHeadingsOptions): ExtractedHeading[];
|
|
286
|
+
/**
|
|
287
|
+
* Walk a rendered DOM subtree, collect headings, and assign missing `id`s
|
|
288
|
+
* in-place so anchor links resolve immediately. Also sets `scrollMarginTop`
|
|
289
|
+
* on each heading when `scrollMarginTop` is provided so navigation lands
|
|
290
|
+
* cleanly below a sticky header.
|
|
291
|
+
*/
|
|
292
|
+
declare function extractHeadingsFromElement(root: HTMLElement, options?: ExtractHeadingsOptions & {
|
|
293
|
+
scrollMarginTop?: number;
|
|
294
|
+
}): ExtractedHeading[];
|
|
295
|
+
|
|
296
|
+
interface UseTableOfContentsOptions {
|
|
297
|
+
/** Heading levels to include. Defaults to `[2, 3]`. */
|
|
298
|
+
levels?: ReadonlyArray<HeadingLevel>;
|
|
299
|
+
/**
|
|
300
|
+
* Re-collect headings whenever this value changes. Pass the article slug
|
|
301
|
+
* (or any stable identifier) so swapping content rebuilds the ToC.
|
|
302
|
+
*/
|
|
303
|
+
contentKey?: string | number | null;
|
|
304
|
+
/** Pixels to subtract from heading scroll-into-view target. Default 24. */
|
|
305
|
+
scrollMarginTop?: number;
|
|
306
|
+
/**
|
|
307
|
+
* Distance from the top of the viewport (in px) at which a heading becomes
|
|
308
|
+
* "active". A heading is considered active once its top edge has scrolled
|
|
309
|
+
* past this line. Default `96` — works well with a sticky header that
|
|
310
|
+
* stands ~60–80px tall.
|
|
311
|
+
*/
|
|
312
|
+
activationOffset?: number;
|
|
313
|
+
}
|
|
314
|
+
interface UseTableOfContentsResult {
|
|
315
|
+
items: ExtractedHeading[];
|
|
316
|
+
activeId: string;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Build a table of contents from a rendered element and track which
|
|
320
|
+
* heading is currently in view via IntersectionObserver. Resilient to
|
|
321
|
+
* content swaps when `contentKey` is provided.
|
|
322
|
+
*
|
|
323
|
+
* Usage:
|
|
324
|
+
* ```tsx
|
|
325
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
326
|
+
* const { items, activeId } = useTableOfContents(ref, {
|
|
327
|
+
* contentKey: article.slug,
|
|
328
|
+
* levels: [2, 3],
|
|
329
|
+
* });
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
declare function useTableOfContents(ref: RefObject<HTMLElement | null>, options?: UseTableOfContentsOptions): UseTableOfContentsResult;
|
|
333
|
+
|
|
334
|
+
export { AsteroidCMSProvider, type AsteroidCMSProviderProps, type ExtractHeadingsOptions, type ExtractedHeading, type HeadingLevel, RichTextContent, type UseCmsContentOptions, type UseCmsMutateOptions, type UseTableOfContentsOptions, type UseTableOfContentsResult, extractHeadingsFromElement, extractHeadingsFromHtml, slugify, useAsteroidCMSConfig, useCmsContent, useCmsImage, useCmsMutate, useTableOfContents };
|