@arbidocs/blocks 0.3.110 → 0.3.112
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/dist/index.cjs +1534 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +371 -31
- package/dist/index.d.ts +371 -31
- package/dist/index.js +1515 -123
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/studio/studio.css +19 -18
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { UseBoundStore, StoreApi } from 'zustand';
|
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import react__default, { ReactNode } from 'react';
|
|
4
4
|
import * as _arbidocs_react from '@arbidocs/react';
|
|
5
|
-
import { AiRunOptions, useArbi } from '@arbidocs/react';
|
|
5
|
+
import { AiRunOptions, useArbi, AiTaskStatus } from '@arbidocs/react';
|
|
6
6
|
export { AiRunOptions, AiTaskStatus, ArtifactEvent, SearchChunk, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, redlineStats, textToArtifact, toRedlineMarkdown } from '@arbidocs/react';
|
|
7
7
|
import { ColDef, GridOptions, GridApi, CellValueChangedEvent, GridState } from 'ag-grid-community';
|
|
8
8
|
import { LucideIcon } from 'lucide-react';
|
|
9
|
-
import { Config, CustomField, Field, ComponentConfig } from '@measured/puck';
|
|
9
|
+
import { Data, Config, CustomField, Field, ComponentConfig } from '@measured/puck';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* The reusable AI-native law-firm prompt library.
|
|
@@ -37,7 +37,7 @@ declare function matterToContext(m: {
|
|
|
37
37
|
}): MatterContext;
|
|
38
38
|
/** Firm voice for the prompt library — everything firm-specific lives here. */
|
|
39
39
|
interface PromptConfig {
|
|
40
|
-
/** The firm's name, e.g. "
|
|
40
|
+
/** The firm's name, e.g. "Acme Legal". */
|
|
41
41
|
firmName: string;
|
|
42
42
|
/** The legal system adjective used throughout, e.g. "English". */
|
|
43
43
|
jurisdiction?: string;
|
|
@@ -127,20 +127,20 @@ declare function createPromptLibrary(config: PromptConfig): {
|
|
|
127
127
|
};
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
|
-
* The theme-token model
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
130
|
+
* The theme-token model. Firm-agnostic: the token *catalog*, default values and
|
|
131
|
+
* presets are supplied by the consuming app (via {@link createThemeStore}); this
|
|
132
|
+
* module owns the shared types and the logic for writing tokens onto the live
|
|
133
|
+
* document.
|
|
134
134
|
*
|
|
135
|
-
* There are two emit models, selected per-
|
|
135
|
+
* There are two emit models, selected per-app by {@link ThemeEmitMode}:
|
|
136
136
|
*
|
|
137
|
-
* - `'flat'` (default
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
137
|
+
* - `'flat'` (default): each colour key is written as an inline `--color-<key>`
|
|
138
|
+
* custom property on `<html>`, plus `--font-*` / `--radius`. Inline styles
|
|
139
|
+
* override the compiled `@theme` defaults, so an edit previews live across the
|
|
140
|
+
* whole app (and the @arbidocs AI kit) and reverts cleanly. Apps whose CSS sets
|
|
141
|
+
* `--color-*` HEX directly rely on this.
|
|
142
142
|
*
|
|
143
|
-
* - `'cssVars'
|
|
143
|
+
* - `'cssVars'`: each colour key is written as a raw
|
|
144
144
|
* HSL-triplet custom property (`--<key>: <h s l>`) into an injected
|
|
145
145
|
* `<style id="arbi-theme-vars">` appended to `<head>`. The monolith's source
|
|
146
146
|
* of truth is HSL triplets wrapped as `hsl(var(--x))`, with a real `.dark`
|
|
@@ -176,7 +176,7 @@ interface ThemePreset {
|
|
|
176
176
|
/** How a theme is written onto the document. See the module doc for the models. */
|
|
177
177
|
type ThemeEmitMode = 'flat' | 'cssVars';
|
|
178
178
|
interface ApplyThemeOptions {
|
|
179
|
-
/** Emit model. Defaults to `'flat'
|
|
179
|
+
/** Emit model. Defaults to `'flat'`. */
|
|
180
180
|
mode?: ThemeEmitMode;
|
|
181
181
|
/**
|
|
182
182
|
* `cssVars` mode only: dark-variant colour values keyed by token key. Emitted
|
|
@@ -250,9 +250,9 @@ interface ThemeStoreConfig {
|
|
|
250
250
|
storageKey: string;
|
|
251
251
|
/**
|
|
252
252
|
* How edits are written onto the document. Defaults to `'flat'` (inline
|
|
253
|
-
* `--color
|
|
254
|
-
* `<style>` so
|
|
255
|
-
* survive
|
|
253
|
+
* `--color-*`). `'cssVars'` emits raw HSL-triplet vars into an injected
|
|
254
|
+
* `<style>` so an app's own `hsl(var(--x))` indirection + `.dark` variant
|
|
255
|
+
* survive. See {@link applyThemeVars}.
|
|
256
256
|
*/
|
|
257
257
|
mode?: ThemeEmitMode;
|
|
258
258
|
/**
|
|
@@ -623,13 +623,15 @@ declare function PageHeader({ title, eyebrow, description, actions, className, t
|
|
|
623
623
|
}): react.JSX.Element;
|
|
624
624
|
|
|
625
625
|
/** Editorial heading block for marketing sections: eyebrow + title + lead. */
|
|
626
|
-
declare function SectionHeading({ eyebrow, title, lead, align, className, invert, }: {
|
|
626
|
+
declare function SectionHeading({ eyebrow, title, lead, align, className, invert, eyebrowClassName, }: {
|
|
627
627
|
eyebrow?: string;
|
|
628
628
|
title: string;
|
|
629
629
|
lead?: string;
|
|
630
630
|
align?: 'left' | 'center';
|
|
631
631
|
className?: string;
|
|
632
632
|
invert?: boolean;
|
|
633
|
+
/** Override the eyebrow styling (e.g. a firm brand accent). Default: token classes. */
|
|
634
|
+
eyebrowClassName?: string;
|
|
633
635
|
}): react.JSX.Element;
|
|
634
636
|
|
|
635
637
|
/** Search + filter bar used above every list view. */
|
|
@@ -653,8 +655,12 @@ interface MetricCardProps {
|
|
|
653
655
|
direction: 'up' | 'down';
|
|
654
656
|
good?: boolean;
|
|
655
657
|
};
|
|
656
|
-
/**
|
|
657
|
-
|
|
658
|
+
/**
|
|
659
|
+
* Icon accent as a theme colour-token key (e.g. `primary`, `success`, or a
|
|
660
|
+
* firm's own brand token). Resolved to `var(--color-<accent>)` at render, so
|
|
661
|
+
* it themes with whatever firm consumes it. `'default'` inherits `foreground`.
|
|
662
|
+
*/
|
|
663
|
+
accent?: string;
|
|
658
664
|
testId?: string;
|
|
659
665
|
}
|
|
660
666
|
/** The one true KPI tile. Used across every dashboard and module header. */
|
|
@@ -667,6 +673,8 @@ interface BlockImageProps {
|
|
|
667
673
|
alt?: string;
|
|
668
674
|
aspect?: BlockImageAspect;
|
|
669
675
|
rounded?: BlockImageRounded;
|
|
676
|
+
/** Editorial "photo frame" treatment: a matte border ring + soft shadow. */
|
|
677
|
+
framed?: boolean;
|
|
670
678
|
className?: string;
|
|
671
679
|
testId?: string;
|
|
672
680
|
}
|
|
@@ -675,7 +683,7 @@ interface BlockImageProps {
|
|
|
675
683
|
* token-clean gradient placeholder (no network needed) so the palette always looks
|
|
676
684
|
* good in the editor and in demos. Token-only classes so it themes per firm.
|
|
677
685
|
*/
|
|
678
|
-
declare function BlockImage({ src, alt, aspect, rounded, className, testId, }: BlockImageProps): react.JSX.Element;
|
|
686
|
+
declare function BlockImage({ src, alt, aspect, rounded, framed, className, testId, }: BlockImageProps): react.JSX.Element;
|
|
679
687
|
|
|
680
688
|
type HeroTone = 'default' | 'muted' | 'ink';
|
|
681
689
|
type HeroAlign = 'left' | 'center';
|
|
@@ -686,16 +694,25 @@ interface HeroCta {
|
|
|
686
694
|
interface HeroProps {
|
|
687
695
|
eyebrow?: string;
|
|
688
696
|
title: string;
|
|
697
|
+
/** A word/phrase within the title to accent (rendered in the primary colour). */
|
|
698
|
+
emphasis?: string;
|
|
689
699
|
subtitle?: string;
|
|
690
700
|
primaryCta?: HeroCta;
|
|
691
701
|
secondaryCta?: HeroCta;
|
|
692
702
|
align?: HeroAlign;
|
|
693
703
|
tone?: HeroTone;
|
|
704
|
+
/** Side visual (ignored when `backgroundImage` is set). */
|
|
694
705
|
imageUrl?: string;
|
|
706
|
+
/** Full-bleed background image URL/data-URI. Turns the hero into a cover band. */
|
|
707
|
+
backgroundImage?: string;
|
|
708
|
+
/** Darkening scrim over the background image, for legible copy. Default true. */
|
|
709
|
+
overlay?: boolean;
|
|
710
|
+
/** Override the eyebrow styling (e.g. a firm brand accent). Default: token classes. */
|
|
711
|
+
eyebrowClassName?: string;
|
|
695
712
|
testId?: string;
|
|
696
713
|
}
|
|
697
714
|
/** Editorial marketing hero: eyebrow, headline, subtitle, two CTAs and a visual. */
|
|
698
|
-
declare function Hero({ eyebrow, title, subtitle, primaryCta, secondaryCta, align, tone, imageUrl, testId, }: HeroProps): react.JSX.Element;
|
|
715
|
+
declare function Hero({ eyebrow, title, emphasis, subtitle, primaryCta, secondaryCta, align, tone, imageUrl, backgroundImage, overlay, eyebrowClassName, testId, }: HeroProps): react.JSX.Element;
|
|
699
716
|
|
|
700
717
|
interface FeatureItem {
|
|
701
718
|
icon?: LucideIcon;
|
|
@@ -740,10 +757,14 @@ interface CTABannerProps {
|
|
|
740
757
|
href?: string;
|
|
741
758
|
};
|
|
742
759
|
tone?: CTABannerTone;
|
|
760
|
+
/** Full-bleed background image URL/data-URI. Overrides the tone surface. */
|
|
761
|
+
backgroundImage?: string;
|
|
762
|
+
/** Darkening scrim over the background image. Default true. */
|
|
763
|
+
overlay?: boolean;
|
|
743
764
|
testId?: string;
|
|
744
765
|
}
|
|
745
766
|
/** Full-width call-to-action banner. */
|
|
746
|
-
declare function CTABanner({ title, subtitle, cta, tone, testId }: CTABannerProps): react.JSX.Element;
|
|
767
|
+
declare function CTABanner({ title, subtitle, cta, tone, backgroundImage, overlay, testId, }: CTABannerProps): react.JSX.Element;
|
|
747
768
|
|
|
748
769
|
interface LogoItem {
|
|
749
770
|
label: string;
|
|
@@ -877,6 +898,170 @@ interface ContainerProps {
|
|
|
877
898
|
/** Max-width wrapper that centres and pads a nested Puck slot. */
|
|
878
899
|
declare function Container({ width, padding, children, testId }: ContainerProps): react.JSX.Element;
|
|
879
900
|
|
|
901
|
+
interface PricingPlan {
|
|
902
|
+
name: string;
|
|
903
|
+
price: string;
|
|
904
|
+
period?: string;
|
|
905
|
+
description?: string;
|
|
906
|
+
features?: string[];
|
|
907
|
+
cta?: {
|
|
908
|
+
label?: string;
|
|
909
|
+
href?: string;
|
|
910
|
+
};
|
|
911
|
+
/** Highlight this plan as the recommended one. */
|
|
912
|
+
featured?: boolean;
|
|
913
|
+
}
|
|
914
|
+
interface PricingTableProps {
|
|
915
|
+
plans: PricingPlan[];
|
|
916
|
+
testId?: string;
|
|
917
|
+
}
|
|
918
|
+
/** A row of pricing plan cards with feature lists and a CTA per plan. */
|
|
919
|
+
declare function PricingTable({ plans, testId }: PricingTableProps): react.JSX.Element;
|
|
920
|
+
|
|
921
|
+
interface TabItem {
|
|
922
|
+
label: string;
|
|
923
|
+
content: string;
|
|
924
|
+
}
|
|
925
|
+
interface TabsProps {
|
|
926
|
+
items: TabItem[];
|
|
927
|
+
testId?: string;
|
|
928
|
+
}
|
|
929
|
+
/** A simple tabbed panel: a row of tab buttons over the active tab's content. */
|
|
930
|
+
declare function Tabs({ items, testId }: TabsProps): react.JSX.Element;
|
|
931
|
+
|
|
932
|
+
interface AccordionItem {
|
|
933
|
+
title: string;
|
|
934
|
+
content: string;
|
|
935
|
+
}
|
|
936
|
+
interface AccordionProps {
|
|
937
|
+
items: AccordionItem[];
|
|
938
|
+
/** Allow multiple panels open at once. Default false (single-open). */
|
|
939
|
+
allowMultiple?: boolean;
|
|
940
|
+
testId?: string;
|
|
941
|
+
}
|
|
942
|
+
/** A stack of collapsible title/content panels. */
|
|
943
|
+
declare function Accordion({ items, allowMultiple, testId }: AccordionProps): react.JSX.Element;
|
|
944
|
+
|
|
945
|
+
interface GalleryImage {
|
|
946
|
+
src?: string;
|
|
947
|
+
alt?: string;
|
|
948
|
+
caption?: string;
|
|
949
|
+
}
|
|
950
|
+
interface GalleryProps {
|
|
951
|
+
images: GalleryImage[];
|
|
952
|
+
columns?: '2' | '3' | '4';
|
|
953
|
+
aspect?: BlockImageProps['aspect'];
|
|
954
|
+
rounded?: BlockImageProps['rounded'];
|
|
955
|
+
testId?: string;
|
|
956
|
+
}
|
|
957
|
+
/** A responsive image grid. Each tile previews via BlockImage with a caption. */
|
|
958
|
+
declare function Gallery({ images, columns, aspect, rounded, testId, }: GalleryProps): react.JSX.Element;
|
|
959
|
+
|
|
960
|
+
type VideoAspect = '16:9' | '4:3' | '1:1';
|
|
961
|
+
interface VideoEmbedProps {
|
|
962
|
+
/** A YouTube / Vimeo / Loom page URL, or a direct video file URL. */
|
|
963
|
+
url: string;
|
|
964
|
+
title?: string;
|
|
965
|
+
aspect?: VideoAspect;
|
|
966
|
+
rounded?: boolean;
|
|
967
|
+
testId?: string;
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Resolve a shareable video URL to an embeddable iframe src. Supports YouTube,
|
|
971
|
+
* Vimeo and Loom; returns null for anything else (rendered as a `<video>`).
|
|
972
|
+
*/
|
|
973
|
+
declare function toEmbedUrl(url: string): string | null;
|
|
974
|
+
/** Embed a video from a YouTube/Vimeo/Loom link or a direct file, in a set aspect. */
|
|
975
|
+
declare function VideoEmbed({ url, title, aspect, rounded, testId, }: VideoEmbedProps): react.JSX.Element;
|
|
976
|
+
|
|
977
|
+
interface ContactField {
|
|
978
|
+
name: string;
|
|
979
|
+
label: string;
|
|
980
|
+
type?: 'text' | 'email' | 'tel' | 'textarea';
|
|
981
|
+
required?: boolean;
|
|
982
|
+
}
|
|
983
|
+
interface ContactFormProps {
|
|
984
|
+
fields: ContactField[];
|
|
985
|
+
submitLabel?: string;
|
|
986
|
+
/** Optional POST endpoint. When set, the form submits natively to it. */
|
|
987
|
+
action?: string;
|
|
988
|
+
/** Message shown after a client-side (no-action) submit. */
|
|
989
|
+
successMessage?: string;
|
|
990
|
+
testId?: string;
|
|
991
|
+
}
|
|
992
|
+
/** A configurable lead/contact form. Posts to `action`, or confirms client-side. */
|
|
993
|
+
declare function ContactForm({ fields, submitLabel, action, successMessage, testId, }: ContactFormProps): react.JSX.Element;
|
|
994
|
+
|
|
995
|
+
type BannerTone = 'primary' | 'muted' | 'ink';
|
|
996
|
+
interface BannerProps {
|
|
997
|
+
text: string;
|
|
998
|
+
cta?: {
|
|
999
|
+
label?: string;
|
|
1000
|
+
href?: string;
|
|
1001
|
+
};
|
|
1002
|
+
tone?: BannerTone;
|
|
1003
|
+
testId?: string;
|
|
1004
|
+
}
|
|
1005
|
+
/** A slim full-width announcement strip with optional inline CTA. */
|
|
1006
|
+
declare function Banner({ text, cta, tone, testId }: BannerProps): react.JSX.Element;
|
|
1007
|
+
|
|
1008
|
+
interface MediaTextProps {
|
|
1009
|
+
eyebrow?: string;
|
|
1010
|
+
title: string;
|
|
1011
|
+
body?: string;
|
|
1012
|
+
imageUrl?: string;
|
|
1013
|
+
/** Which side the media sits on (desktop). */
|
|
1014
|
+
mediaSide?: 'left' | 'right';
|
|
1015
|
+
cta?: {
|
|
1016
|
+
label?: string;
|
|
1017
|
+
href?: string;
|
|
1018
|
+
};
|
|
1019
|
+
testId?: string;
|
|
1020
|
+
}
|
|
1021
|
+
/** A split media-and-copy row: an image on one side, prose + CTA on the other. */
|
|
1022
|
+
declare function MediaText({ eyebrow, title, body, imageUrl, mediaSide, cta, testId, }: MediaTextProps): react.JSX.Element;
|
|
1023
|
+
|
|
1024
|
+
interface TeamMember {
|
|
1025
|
+
name: string;
|
|
1026
|
+
role?: string;
|
|
1027
|
+
bio?: string;
|
|
1028
|
+
avatarUrl?: string;
|
|
1029
|
+
}
|
|
1030
|
+
interface TeamGridProps {
|
|
1031
|
+
members: TeamMember[];
|
|
1032
|
+
columns?: '2' | '3' | '4';
|
|
1033
|
+
testId?: string;
|
|
1034
|
+
}
|
|
1035
|
+
/** A grid of people cards: avatar, name, role and an optional short bio. */
|
|
1036
|
+
declare function TeamGrid({ members, columns, testId }: TeamGridProps): react.JSX.Element;
|
|
1037
|
+
|
|
1038
|
+
interface StepItem {
|
|
1039
|
+
title: string;
|
|
1040
|
+
description?: string;
|
|
1041
|
+
}
|
|
1042
|
+
interface StepsProps {
|
|
1043
|
+
steps: StepItem[];
|
|
1044
|
+
/** `timeline` draws a connected vertical rail; `numbered` is a horizontal grid. */
|
|
1045
|
+
variant?: 'numbered' | 'timeline';
|
|
1046
|
+
testId?: string;
|
|
1047
|
+
}
|
|
1048
|
+
/** A process / how-it-works sequence, as numbered cards or a vertical timeline. */
|
|
1049
|
+
declare function Steps({ steps, variant, testId }: StepsProps): react.JSX.Element;
|
|
1050
|
+
|
|
1051
|
+
interface TestimonialItem {
|
|
1052
|
+
quote: string;
|
|
1053
|
+
author?: string;
|
|
1054
|
+
role?: string;
|
|
1055
|
+
avatarUrl?: string;
|
|
1056
|
+
}
|
|
1057
|
+
interface TestimonialGridProps {
|
|
1058
|
+
items: TestimonialItem[];
|
|
1059
|
+
columns?: '2' | '3';
|
|
1060
|
+
testId?: string;
|
|
1061
|
+
}
|
|
1062
|
+
/** A grid of multiple pull-quote testimonials. */
|
|
1063
|
+
declare function TestimonialGrid({ items, columns, testId }: TestimonialGridProps): react.JSX.Element;
|
|
1064
|
+
|
|
880
1065
|
/**
|
|
881
1066
|
* Navigation shapes shared by firm app shells. The concrete nav manifest (which
|
|
882
1067
|
* modules, in what order) is per-firm data the app supplies; these interfaces
|
|
@@ -918,8 +1103,16 @@ interface LoadResult<T> {
|
|
|
918
1103
|
}
|
|
919
1104
|
/** The save/load surface the studio + renderer consume. */
|
|
920
1105
|
interface StudioPersistence {
|
|
1106
|
+
/** Persist the authoring layout for a slug (image values stay `asset:` refs). */
|
|
921
1107
|
savePage: (arbi: Arbi | null, live: boolean, slug: string, data: unknown) => Promise<PersistVia>;
|
|
922
1108
|
loadPage: <T>(arbi: Arbi | null, live: boolean, slug: string) => Promise<LoadResult<T>>;
|
|
1109
|
+
/**
|
|
1110
|
+
* Persist the **published** layout for a slug — a self-contained copy whose
|
|
1111
|
+
* asset refs have been materialized to `data:` URIs, so the unauthenticated
|
|
1112
|
+
* public renderer can paint it. The public renderer reads this, not savePage's.
|
|
1113
|
+
*/
|
|
1114
|
+
savePublished: (arbi: Arbi | null, live: boolean, slug: string, data: unknown) => Promise<PersistVia>;
|
|
1115
|
+
loadPublished: <T>(arbi: Arbi | null, live: boolean, slug: string) => Promise<LoadResult<T>>;
|
|
923
1116
|
saveTheme: (arbi: Arbi | null, live: boolean, theme: unknown) => Promise<PersistVia>;
|
|
924
1117
|
loadTheme: <T>(arbi: Arbi | null, live: boolean) => Promise<LoadResult<T>>;
|
|
925
1118
|
}
|
|
@@ -930,6 +1123,45 @@ type BuildPrompt = (a: {
|
|
|
930
1123
|
current: string;
|
|
931
1124
|
}) => string;
|
|
932
1125
|
|
|
1126
|
+
/**
|
|
1127
|
+
* Publish-time asset materialization.
|
|
1128
|
+
*
|
|
1129
|
+
* While authoring, an image is stored as a workspace **asset ref**
|
|
1130
|
+
* (`asset:<docId>`) — resolvable only inside the authenticated Studio. The
|
|
1131
|
+
* public marketing renderer has no auth token, so a published page must be
|
|
1132
|
+
* **self-contained**: every asset ref is replaced with a directly-renderable
|
|
1133
|
+
* source before the page is saved for the public.
|
|
1134
|
+
*
|
|
1135
|
+
* The default {@link createArbiMaterializer} downloads each asset once and
|
|
1136
|
+
* inlines it as a `data:` URI — the bytes travel *inside* the published JSON,
|
|
1137
|
+
* so nothing is fetched, served or auth-gated at render time (no backend). A
|
|
1138
|
+
* consumer that prefers a CDN/static host can pass a `publishAsset` hook that
|
|
1139
|
+
* uploads the bytes and returns a URL instead; that is purely a payload-size
|
|
1140
|
+
* optimization and keeps this package firm- and backend-agnostic.
|
|
1141
|
+
*/
|
|
1142
|
+
|
|
1143
|
+
/** Resolve a workspace document ext_id to a public-renderable src, or null. */
|
|
1144
|
+
type AssetMaterializer = (docId: string) => Promise<string | null>;
|
|
1145
|
+
interface MaterializeOptions {
|
|
1146
|
+
/**
|
|
1147
|
+
* Optional sink: given a doc id + its bytes, store them somewhere public and
|
|
1148
|
+
* return the URL. When omitted, bytes are inlined as a `data:` URI (no backend).
|
|
1149
|
+
*/
|
|
1150
|
+
publishAsset?: (docId: string, blob: Blob) => Promise<string>;
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* A materializer backed by the authenticated Arbi client: download the asset,
|
|
1154
|
+
* then either hand it to `publishAsset` or inline it as a data URI. Any failure
|
|
1155
|
+
* resolves to `null` so a single broken asset never fails the whole publish.
|
|
1156
|
+
*/
|
|
1157
|
+
declare function createArbiMaterializer(arbi: Arbi, opts?: MaterializeOptions): AssetMaterializer;
|
|
1158
|
+
/**
|
|
1159
|
+
* Return a copy of `data` with every `asset:<docId>` ref replaced by its
|
|
1160
|
+
* materialized source. Each distinct ref is resolved exactly once; a ref that
|
|
1161
|
+
* fails to resolve is left untouched (it simply won't paint for the public).
|
|
1162
|
+
*/
|
|
1163
|
+
declare function materializePageData(data: Data, materialize: AssetMaterializer): Promise<Data>;
|
|
1164
|
+
|
|
933
1165
|
interface StudioEditorProps {
|
|
934
1166
|
config: Config;
|
|
935
1167
|
pages: readonly StudioPageMeta[];
|
|
@@ -942,8 +1174,14 @@ interface StudioEditorProps {
|
|
|
942
1174
|
live: boolean;
|
|
943
1175
|
initialSlug?: string;
|
|
944
1176
|
testIdPrefix?: string;
|
|
1177
|
+
/**
|
|
1178
|
+
* Optional sink for published image bytes. When omitted, publishing inlines
|
|
1179
|
+
* each asset as a `data:` URI (self-contained, no backend). Provide this to
|
|
1180
|
+
* upload bytes to a CDN/static host and return a URL instead.
|
|
1181
|
+
*/
|
|
1182
|
+
publishAsset?: MaterializeOptions['publishAsset'];
|
|
945
1183
|
}
|
|
946
|
-
declare function StudioEditor({ config, pages, persistence, themeBundle, defaultTheme, brandLabel, backHref, backLabel, live, initialSlug, testIdPrefix, }: StudioEditorProps): react.JSX.Element;
|
|
1184
|
+
declare function StudioEditor({ config, pages, persistence, themeBundle, defaultTheme, brandLabel, backHref, backLabel, live, initialSlug, testIdPrefix, publishAsset, }: StudioEditorProps): react.JSX.Element;
|
|
947
1185
|
|
|
948
1186
|
interface PageRendererProps {
|
|
949
1187
|
config: Config;
|
|
@@ -964,7 +1202,7 @@ interface StudioPersistenceConfig {
|
|
|
964
1202
|
workspaceId: string;
|
|
965
1203
|
/** Folder inside the workspace where studio artefacts live. */
|
|
966
1204
|
folder?: string;
|
|
967
|
-
/** Prefix for the localStorage mirror keys (e.g. "
|
|
1205
|
+
/** Prefix for the localStorage mirror keys (e.g. "studio-"). */
|
|
968
1206
|
storagePrefix: string;
|
|
969
1207
|
/** localStorage key for the theme mirror (default `${storagePrefix}theme`). */
|
|
970
1208
|
themeStorageKey?: string;
|
|
@@ -972,6 +1210,8 @@ interface StudioPersistenceConfig {
|
|
|
972
1210
|
themeFileName?: string;
|
|
973
1211
|
/** File name for a page's persisted document (default `${slug}.json`). */
|
|
974
1212
|
pageFileName?: (slug: string) => string;
|
|
1213
|
+
/** File name for a page's published document (default `${slug}.published.json`). */
|
|
1214
|
+
publishedFileName?: (slug: string) => string;
|
|
975
1215
|
}
|
|
976
1216
|
declare function createStudioPersistence(cfg: StudioPersistenceConfig): StudioPersistence;
|
|
977
1217
|
|
|
@@ -991,12 +1231,68 @@ interface AiFields {
|
|
|
991
1231
|
}
|
|
992
1232
|
declare function createAiFields(cfg: AiFieldsConfig): AiFields;
|
|
993
1233
|
|
|
1234
|
+
interface ImageFieldConfig {
|
|
1235
|
+
/** The workspace uploads/generations are saved to, and assets are picked from. */
|
|
1236
|
+
workspaceId: string;
|
|
1237
|
+
/** Folder for uploaded/authored assets. Default "assets". */
|
|
1238
|
+
folder?: string;
|
|
1239
|
+
/** Testid namespace. Default "studio". */
|
|
1240
|
+
testIdPrefix?: string;
|
|
1241
|
+
}
|
|
1242
|
+
interface ImageFieldFactory {
|
|
1243
|
+
imageField: (label: string) => CustomField<string>;
|
|
1244
|
+
}
|
|
1245
|
+
/** Build the image field, closing over the firm's workspace + testid prefix. */
|
|
1246
|
+
declare function createImageField(cfg: ImageFieldConfig): ImageFieldFactory;
|
|
1247
|
+
|
|
1248
|
+
interface UseImageGen {
|
|
1249
|
+
/** ext_id of the most recently generated image document (null until one exists). */
|
|
1250
|
+
docExtId: string | null;
|
|
1251
|
+
/** Underlying task status: 'idle' | 'running' | 'done' | 'error'. */
|
|
1252
|
+
status: AiTaskStatus;
|
|
1253
|
+
/** Human-readable failure message, or null. */
|
|
1254
|
+
error: string | null;
|
|
1255
|
+
/** True while a generation is in flight. */
|
|
1256
|
+
isGenerating: boolean;
|
|
1257
|
+
/**
|
|
1258
|
+
* Generate an image from a prompt. Resolves with the new image document's
|
|
1259
|
+
* ext_id, or null when the prompt is empty or no image was produced.
|
|
1260
|
+
*/
|
|
1261
|
+
generate: (prompt: string) => Promise<string | null>;
|
|
1262
|
+
/** Clear the current result and error. */
|
|
1263
|
+
reset: () => void;
|
|
1264
|
+
}
|
|
1265
|
+
declare function useImageGen(): UseImageGen;
|
|
1266
|
+
|
|
1267
|
+
/** Marks a stored image value as a workspace asset ref rather than a URL. */
|
|
1268
|
+
declare const ASSET_REF_PREFIX = "asset:";
|
|
1269
|
+
/** Wrap a workspace document ext_id as a storable asset ref. */
|
|
1270
|
+
declare function asAssetRef(docId: string): string;
|
|
1271
|
+
/** The workspace document ext_id behind an asset ref (`asset:doc-1` → `doc-1`). */
|
|
1272
|
+
declare function assetRefId(src: string): string;
|
|
1273
|
+
declare function AssetResolverProvider({ children }: {
|
|
1274
|
+
children: ReactNode;
|
|
1275
|
+
}): react.JSX.Element;
|
|
1276
|
+
declare function useAssetResolverActive(): boolean;
|
|
1277
|
+
/**
|
|
1278
|
+
* Is `src` a workspace asset ref (`asset:<docId>`) rather than an already-
|
|
1279
|
+
* renderable URL / `data:` URI? Only prefixed refs need resolution.
|
|
1280
|
+
*/
|
|
1281
|
+
declare function isAssetRef(src: string | undefined): src is string;
|
|
1282
|
+
|
|
1283
|
+
type SectionTone = 'default' | 'muted' | 'ink';
|
|
1284
|
+
type SectionPadding = 'none' | 'sm' | 'md' | 'lg';
|
|
1285
|
+
type SectionWidth = 'narrow' | 'default' | 'wide' | 'full';
|
|
994
1286
|
interface SectionProps {
|
|
995
1287
|
children: ReactNode;
|
|
996
|
-
tone?:
|
|
1288
|
+
tone?: SectionTone;
|
|
1289
|
+
padding?: SectionPadding;
|
|
1290
|
+
maxWidth?: SectionWidth;
|
|
1291
|
+
/** Subtle grain/texture overlay in the current text colour (editorial surfaces). */
|
|
1292
|
+
texture?: boolean;
|
|
997
1293
|
className?: string;
|
|
998
1294
|
}
|
|
999
|
-
declare function Section({ children, tone, className }: SectionProps): react.JSX.Element;
|
|
1295
|
+
declare function Section({ children, tone, padding, maxWidth, texture, className, }: SectionProps): react.JSX.Element;
|
|
1000
1296
|
|
|
1001
1297
|
/**
|
|
1002
1298
|
* Shared field helpers for the block registry. Every block config — the built-ins
|
|
@@ -1013,6 +1309,8 @@ interface BlockKit {
|
|
|
1013
1309
|
textField: (label: string, placeholder?: string) => Field;
|
|
1014
1310
|
/** Multi-line copy: AI-authorable when a firm supplies aiFields, else plain textarea. */
|
|
1015
1311
|
textareaField: (label: string, placeholder?: string, kind?: string) => Field;
|
|
1312
|
+
/** Image source: a workspace-asset picker when a firm supplies imageField, else a URL input. */
|
|
1313
|
+
imageField: (label: string) => Field;
|
|
1016
1314
|
/** A Yes/No radio. */
|
|
1017
1315
|
boolRadio: (label: string) => Field;
|
|
1018
1316
|
/** A `select` over {@link iconMap} names. */
|
|
@@ -1021,9 +1319,15 @@ interface BlockKit {
|
|
|
1021
1319
|
resolveIcon: (name?: string) => LucideIcon | undefined;
|
|
1022
1320
|
/** Stable, e2e-locatable testid derived from a block's Puck id. */
|
|
1023
1321
|
blockTestId: (id: string) => string;
|
|
1322
|
+
/**
|
|
1323
|
+
* Optional firm override for the eyebrow style on heading-bearing blocks
|
|
1324
|
+
* (Hero, Section heading). Lets a consumer render a brand accent (e.g. a brass
|
|
1325
|
+
* eyebrow) without forking the blocks. Undefined → the default token classes.
|
|
1326
|
+
*/
|
|
1327
|
+
eyebrowClassName?: string;
|
|
1024
1328
|
}
|
|
1025
|
-
/** Build the shared field helpers, closing over the firm's optional AI fields. */
|
|
1026
|
-
declare function createBlockKit(ai?: AiFields): BlockKit;
|
|
1329
|
+
/** Build the shared field helpers, closing over the firm's optional AI + image fields. */
|
|
1330
|
+
declare function createBlockKit(ai?: AiFields, image?: (label: string) => Field, eyebrowClassName?: string): BlockKit;
|
|
1027
1331
|
|
|
1028
1332
|
interface ArbiBlocksConfigOptions {
|
|
1029
1333
|
/**
|
|
@@ -1031,6 +1335,28 @@ interface ArbiBlocksConfigOptions {
|
|
|
1031
1335
|
* prop becomes an AI-authorable field; when absent, plain Puck text inputs.
|
|
1032
1336
|
*/
|
|
1033
1337
|
aiFields?: AiFields;
|
|
1338
|
+
/**
|
|
1339
|
+
* Firm image field from {@link createImageField}. When present, image props
|
|
1340
|
+
* become a workspace-asset picker (pick / upload / URL / generate); when absent,
|
|
1341
|
+
* a plain URL text input.
|
|
1342
|
+
*/
|
|
1343
|
+
imageField?: (label: string) => Field;
|
|
1344
|
+
/**
|
|
1345
|
+
* Page canvas overrides. The builder paints every page inside this root; a
|
|
1346
|
+
* consumer sets e.g. a dark editorial canvas without forking the package.
|
|
1347
|
+
* Defaults to `bg-background text-foreground font-sans` on a neutral wrapper.
|
|
1348
|
+
*/
|
|
1349
|
+
root?: {
|
|
1350
|
+
/** Extra classes appended to (and able to override) the default canvas classes. */
|
|
1351
|
+
className?: string;
|
|
1352
|
+
/** testid for the page root wrapper. Defaults to `arbi-blocks-page-root`. */
|
|
1353
|
+
testId?: string;
|
|
1354
|
+
};
|
|
1355
|
+
/**
|
|
1356
|
+
* Firm override for the eyebrow style on heading-bearing blocks (Hero, Section
|
|
1357
|
+
* heading) — e.g. a brand accent like a brass eyebrow. Undefined → token default.
|
|
1358
|
+
*/
|
|
1359
|
+
eyebrowClassName?: string;
|
|
1034
1360
|
}
|
|
1035
1361
|
|
|
1036
1362
|
declare function createArbiBlocksConfig(opts?: ArbiBlocksConfigOptions): Config;
|
|
@@ -1038,6 +1364,20 @@ declare function createArbiBlocksConfig(opts?: ArbiBlocksConfigOptions): Config;
|
|
|
1038
1364
|
/** Build every website block, closing over the shared field {@link BlockKit}. */
|
|
1039
1365
|
declare function createWebsiteBlocks(kit: BlockKit): Record<string, ComponentConfig>;
|
|
1040
1366
|
|
|
1367
|
+
/**
|
|
1368
|
+
* The extended site-building block set — the richer vocabulary a builder needs to
|
|
1369
|
+
* assemble arbitrary sites beyond the marketing basics: pricing, tabs, accordion,
|
|
1370
|
+
* gallery, video, contact form, banner, split media, team, steps and a
|
|
1371
|
+
* multi-testimonial grid.
|
|
1372
|
+
*
|
|
1373
|
+
* Same contract as {@link createWebsiteBlocks}: serializable-only props, semantic
|
|
1374
|
+
* tokens (themes with the firm), a stable render-time `data-testid`, and sensible
|
|
1375
|
+
* defaults so each block looks right the moment it is dropped. Copy props route
|
|
1376
|
+
* through the shared {@link BlockKit} AI-or-plain fields.
|
|
1377
|
+
*/
|
|
1378
|
+
|
|
1379
|
+
declare function createSiteBlocks(kit: BlockKit): Record<string, ComponentConfig>;
|
|
1380
|
+
|
|
1041
1381
|
/**
|
|
1042
1382
|
* Module registry types — a typed model of a firm's back-office modules,
|
|
1043
1383
|
* derived from its canonical nav. The builder toggles/reorders these; the
|
|
@@ -1210,4 +1550,4 @@ interface AgentsPanelProps {
|
|
|
1210
1550
|
}
|
|
1211
1551
|
declare function AgentsPanel({ store, testIdPrefix }: AgentsPanelProps): react.JSX.Element;
|
|
1212
1552
|
|
|
1213
|
-
export { type AgentSelectionStore, AgentsPanel, type AgentsPanelProps, type AiFields, type AiFieldsConfig, type AppNavItem, type AppNavSection, type ApplyThemeOptions, type ArbiBlocksConfigOptions, type ArbiMode, type ArbiUser, type AssistantCitation, type AssistantMessage, type AssistantStep, AvatarBlock, type AvatarBlockProps, BlockImage, type BlockImageProps, type BlockKit, type BuildPrompt, type BuilderModule, CTABanner, type CTABannerProps, Callout, type CalloutProps, type CalloutVariant, type ColorToken, type Column, Columns, type ColumnsProps, ConnectionProvider, type ConnectionStatus, Container, type ContainerProps, DataTable, DataTableBlock, type DataTableBlockColumn, type DataTableBlockProps, EmptyState, type ExportedModule, FAQ, type FAQProps, type FaqItem, FeatureGrid, type FeatureGridProps, type FeatureItem, type FirmArbiConfig, Footer, type FooterColumn, type FooterLink, type FooterProps, GridView, type GridViewEmptyState, type GridViewProps, type GridViewSelection, Hero, type HeroCta, type HeroProps, LegalArbiProvider, ListBlock, type ListBlockProps, type ListItem, type LoadResult, LogoCloud, type LogoCloudProps, type LogoItem, type MatterContext, MetricCard, type MetricCardProps, ModuleManager, type ModuleManagerProps, type ModuleRegistry, type ModuleStoreBundle, type NavLink, Navbar, type NavbarProps, PageHeader, PageRenderer, type PageRendererProps, type PersistVia, type PromptConfig, type PromptLibrary, type Prompts, type ResolvedModule, RichTextBlock, type RichTextBlockProps, Section, SectionHeading, type SectionProps, Spacer, type SpacerProps, StatGroup, type StatGroupProps, type StatItem, StudioEditor, type StudioEditorProps, type StudioPageMeta, type StudioPersistence, type StudioPersistenceConfig, THEME_STYLE_ID, Testimonial, type TestimonialProps, type ThemeBundle, ThemeEditor, type ThemeEditorProps, type ThemeEmitMode, type ThemeFonts, type ThemePreset, type ThemeState, type ThemeStoreConfig, type ThemeTokens, Toolbar, VerticalBuilder, type VerticalBuilderProps, type VerticalConfig, type VerticalExport, type VerticalExportConfig, applyStoredTheme, applyThemeVars, clearThemeVars, createAgentSelectionStore, createAiFields, createArbiBlocksConfig, createBlockKit, createModuleRegistry, createModuleStore, createPromptLibrary, createStudioPersistence, createThemeStore, createVerticalExport, createWebsiteBlocks, daysUntil, fmtDate, fmtDateTime, fromNow, gbp, hrs, iconMap, initials, isAuthenticated, matterToContext, pct, tid, toHslTriplet, useConnection, useFirmAiTask, useSemanticSearch, useWorkspaceDocs };
|
|
1553
|
+
export { ASSET_REF_PREFIX, Accordion, type AccordionItem, type AccordionProps, type AgentSelectionStore, AgentsPanel, type AgentsPanelProps, type AiFields, type AiFieldsConfig, type AppNavItem, type AppNavSection, type ApplyThemeOptions, type ArbiBlocksConfigOptions, type ArbiMode, type ArbiUser, type AssetMaterializer, AssetResolverProvider, type AssistantCitation, type AssistantMessage, type AssistantStep, AvatarBlock, type AvatarBlockProps, Banner, type BannerProps, type BannerTone, BlockImage, type BlockImageProps, type BlockKit, type BuildPrompt, type BuilderModule, CTABanner, type CTABannerProps, Callout, type CalloutProps, type CalloutVariant, type ColorToken, type Column, Columns, type ColumnsProps, ConnectionProvider, type ConnectionStatus, type ContactField, ContactForm, type ContactFormProps, Container, type ContainerProps, DataTable, DataTableBlock, type DataTableBlockColumn, type DataTableBlockProps, EmptyState, type ExportedModule, FAQ, type FAQProps, type FaqItem, FeatureGrid, type FeatureGridProps, type FeatureItem, type FirmArbiConfig, Footer, type FooterColumn, type FooterLink, type FooterProps, Gallery, type GalleryImage, type GalleryProps, GridView, type GridViewEmptyState, type GridViewProps, type GridViewSelection, Hero, type HeroCta, type HeroProps, type ImageFieldConfig, type ImageFieldFactory, LegalArbiProvider, ListBlock, type ListBlockProps, type ListItem, type LoadResult, LogoCloud, type LogoCloudProps, type LogoItem, type MaterializeOptions, type MatterContext, MediaText, type MediaTextProps, MetricCard, type MetricCardProps, ModuleManager, type ModuleManagerProps, type ModuleRegistry, type ModuleStoreBundle, type NavLink, Navbar, type NavbarProps, PageHeader, PageRenderer, type PageRendererProps, type PersistVia, type PricingPlan, PricingTable, type PricingTableProps, type PromptConfig, type PromptLibrary, type Prompts, type ResolvedModule, RichTextBlock, type RichTextBlockProps, Section, SectionHeading, type SectionProps, Spacer, type SpacerProps, StatGroup, type StatGroupProps, type StatItem, type StepItem, Steps, type StepsProps, StudioEditor, type StudioEditorProps, type StudioPageMeta, type StudioPersistence, type StudioPersistenceConfig, THEME_STYLE_ID, type TabItem, Tabs, type TabsProps, TeamGrid, type TeamGridProps, type TeamMember, Testimonial, TestimonialGrid, type TestimonialGridProps, type TestimonialItem, type TestimonialProps, type ThemeBundle, ThemeEditor, type ThemeEditorProps, type ThemeEmitMode, type ThemeFonts, type ThemePreset, type ThemeState, type ThemeStoreConfig, type ThemeTokens, Toolbar, type UseImageGen, VerticalBuilder, type VerticalBuilderProps, type VerticalConfig, type VerticalExport, type VerticalExportConfig, type VideoAspect, VideoEmbed, type VideoEmbedProps, applyStoredTheme, applyThemeVars, asAssetRef, assetRefId, clearThemeVars, createAgentSelectionStore, createAiFields, createArbiBlocksConfig, createArbiMaterializer, createBlockKit, createImageField, createModuleRegistry, createModuleStore, createPromptLibrary, createSiteBlocks, createStudioPersistence, createThemeStore, createVerticalExport, createWebsiteBlocks, daysUntil, fmtDate, fmtDateTime, fromNow, gbp, hrs, iconMap, initials, isAssetRef, isAuthenticated, materializePageData, matterToContext, pct, tid, toEmbedUrl, toHslTriplet, useAssetResolverActive, useConnection, useFirmAiTask, useImageGen, useSemanticSearch, useWorkspaceDocs };
|