@tailorkit/react 0.1.0-beta.3 → 0.1.0-beta.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.
Files changed (41) hide show
  1. package/dist/components/context.d.ts +0 -1
  2. package/dist/components/index.d.ts +0 -1
  3. package/dist/components/render.d.ts +0 -1
  4. package/dist/components/root.d.ts +0 -1
  5. package/dist/hooks/use-apps.d.ts +0 -1
  6. package/dist/hooks/use-current-screen.d.ts +0 -1
  7. package/dist/index.d.ts +0 -1
  8. package/dist/node-store.d.ts +0 -1
  9. package/dist/primitives.d.ts +0 -1
  10. package/dist/remote-context.d.ts +0 -1
  11. package/dist/remote-view.d.ts +0 -1
  12. package/dist/tailor-kit.d.ts +0 -1
  13. package/package.json +4 -15
  14. package/dist/components/context.d.ts.map +0 -1
  15. package/dist/components/index.d.ts.map +0 -1
  16. package/dist/components/render.d.ts.map +0 -1
  17. package/dist/components/root.d.ts.map +0 -1
  18. package/dist/hooks/use-apps.d.ts.map +0 -1
  19. package/dist/hooks/use-current-screen.d.ts.map +0 -1
  20. package/dist/index.d.ts.map +0 -1
  21. package/dist/node-store.d.ts.map +0 -1
  22. package/dist/primitives.d.ts.map +0 -1
  23. package/dist/remote-context.d.ts.map +0 -1
  24. package/dist/remote-view.d.ts.map +0 -1
  25. package/dist/tailor-kit.d.ts.map +0 -1
  26. package/src/__tests__/node-store.test.ts +0 -206
  27. package/src/__tests__/primitives.test.tsx +0 -85
  28. package/src/__tests__/tailor-kit.test.tsx +0 -424
  29. package/src/__tests__/tailor-kit.types.tsx +0 -151
  30. package/src/components/context.ts +0 -21
  31. package/src/components/index.ts +0 -1
  32. package/src/components/render.tsx +0 -116
  33. package/src/components/root.tsx +0 -37
  34. package/src/hooks/use-apps.ts +0 -47
  35. package/src/hooks/use-current-screen.ts +0 -81
  36. package/src/index.ts +0 -8
  37. package/src/node-store.ts +0 -131
  38. package/src/primitives.tsx +0 -261
  39. package/src/remote-context.ts +0 -11
  40. package/src/remote-view.tsx +0 -232
  41. package/src/tailor-kit.tsx +0 -501
@@ -1,116 +0,0 @@
1
- import { cloneElement, createElement, isValidElement, useMemo } from "react";
2
- import type {
3
- CSSProperties,
4
- ComponentPropsWithoutRef,
5
- DOMAttributes,
6
- ElementType,
7
- HTMLAttributes,
8
- ReactElement,
9
- ReactNode,
10
- Ref,
11
- } from "react";
12
-
13
- type ElementProps<TTagName extends ElementType> = ComponentPropsWithoutRef<TTagName> & {
14
- ref?: Ref<unknown>;
15
- };
16
-
17
- export interface RenderProps {
18
- render?: ReactElement<Record<string, unknown>>;
19
- }
20
-
21
- export type ComponentProps<TTagName extends ElementType> = ElementProps<TTagName> & RenderProps;
22
-
23
- export function useRender<TTagName extends ElementType>({
24
- defaultTagName,
25
- props,
26
- render,
27
- }: {
28
- defaultTagName: TTagName;
29
- props: ElementProps<TTagName>;
30
- render?: ReactElement<Record<string, unknown>>;
31
- }): ReactNode {
32
- return useMemo(() => {
33
- if (render) {
34
- if (!isValidElement(render)) {
35
- throw new Error("The render prop must be a valid React element.");
36
- }
37
-
38
- return cloneElement(render, mergeProps(render.props, props));
39
- }
40
-
41
- return createElement(defaultTagName, props);
42
- }, [defaultTagName, props, render]);
43
- }
44
-
45
- export function mergeProps<TProps extends Record<string, unknown>>(
46
- ...propSets: (TProps | Record<string, unknown> | undefined)[]
47
- ): TProps {
48
- const merged: Record<string, unknown> = {};
49
-
50
- for (const props of propSets) {
51
- if (!props) {
52
- continue;
53
- }
54
-
55
- for (const [key, value] of Object.entries(props)) {
56
- if (value === undefined) {
57
- continue;
58
- }
59
-
60
- const existing = merged[key];
61
-
62
- if (key === "className" && existing && value) {
63
- merged[key] = `${existing as string} ${value as string}`;
64
- continue;
65
- }
66
-
67
- if (key === "style" && existing && value) {
68
- merged[key] = {
69
- ...(existing as CSSProperties),
70
- ...(value as CSSProperties),
71
- };
72
- continue;
73
- }
74
-
75
- if (key === "ref" && existing && value) {
76
- merged[key] = composeRefs(existing as Ref<unknown>, value as Ref<unknown>);
77
- continue;
78
- }
79
-
80
- if (isEventHandler(key) && typeof existing === "function" && typeof value === "function") {
81
- merged[key] = (...args: unknown[]) => {
82
- (existing as (...eventArgs: unknown[]) => void)(...args);
83
- const event = args[0] as { defaultPrevented?: boolean } | undefined;
84
- if (!event?.defaultPrevented) {
85
- (value as (...eventArgs: unknown[]) => void)(...args);
86
- }
87
- };
88
- continue;
89
- }
90
-
91
- merged[key] = value;
92
- }
93
- }
94
-
95
- return merged as TProps;
96
- }
97
-
98
- export function composeRefs<T>(...refs: (Ref<T> | undefined)[]): Ref<T> {
99
- return (node: T) => {
100
- for (const ref of refs) {
101
- if (typeof ref === "function") {
102
- ref(node);
103
- } else if (ref) {
104
- (ref as { current: T | null }).current = node;
105
- }
106
- }
107
- };
108
- }
109
-
110
- function isEventHandler(key: string): key is keyof DOMAttributes<HTMLElement> {
111
- return /^on[A-Z]/u.test(key);
112
- }
113
-
114
- export type HtmlProps<TElement extends HTMLElement> = HTMLAttributes<TElement> & {
115
- ref?: Ref<TElement>;
116
- };
@@ -1,37 +0,0 @@
1
- import { useMemo } from "react";
2
- import type { ReactNode } from "react";
3
- import type { TailorKitApp } from "../tailor-kit";
4
- import type { ComponentProps } from "./render";
5
- import { mergeProps, useRender } from "./render";
6
- import { TailorRootContext } from "./context";
7
- import type { RootTailor, TailorRootContextValue } from "./context";
8
-
9
- const EMPTY_APPS: TailorKitApp[] = [];
10
-
11
- export interface RootProps extends ComponentProps<"div"> {
12
- apps?: TailorKitApp[];
13
- children?: ReactNode;
14
- tailor: RootTailor;
15
- }
16
-
17
- export function Root({ apps: appsProp, children, render, tailor, ...props }: RootProps): ReactNode {
18
- const appsResult = tailor.useApps();
19
- const apps = appsProp ?? appsResult.data ?? EMPTY_APPS;
20
-
21
- const context = useMemo<TailorRootContextValue>(
22
- () => ({
23
- apps,
24
- }),
25
- [apps],
26
- );
27
-
28
- const element = render
29
- ? useRender({
30
- defaultTagName: "div",
31
- props: mergeProps({ children }, props),
32
- render,
33
- })
34
- : children;
35
-
36
- return <TailorRootContext.Provider value={context}>{element}</TailorRootContext.Provider>;
37
- }
@@ -1,47 +0,0 @@
1
- import { useCallback, useEffect, useSyncExternalStore } from "react";
2
- import type { TailorKitApp, TailorKitAppsSnapshot, TailorKitStore } from "../tailor-kit";
3
-
4
- export interface UseAppsResult {
5
- data: TailorKitApp[] | undefined;
6
- error: Error | null;
7
- isError: boolean;
8
- isLoading: boolean;
9
- isPending: boolean;
10
- isSuccess: boolean;
11
- refetch: () => Promise<void>;
12
- status: "error" | "idle" | "loading" | "ready";
13
- }
14
-
15
- export function createUseApps(store: TailorKitStore): () => UseAppsResult {
16
- return function useApps(): UseAppsResult {
17
- const snapshot = useSyncExternalStore(
18
- store.subscribe,
19
- store.getAppsSnapshot,
20
- store.getAppsSnapshot,
21
- );
22
-
23
- useEffect(() => {
24
- void store.fetchApps();
25
- }, []);
26
-
27
- const refetch = useCallback(() => store.fetchApps({ force: true }), []);
28
-
29
- return toUseAppsResult(snapshot, refetch);
30
- };
31
- }
32
-
33
- function toUseAppsResult(
34
- snapshot: TailorKitAppsSnapshot,
35
- refetch: () => Promise<void>,
36
- ): UseAppsResult {
37
- return {
38
- data: snapshot.status === "ready" ? snapshot.apps : undefined,
39
- error: snapshot.error,
40
- isError: snapshot.status === "error",
41
- isLoading: snapshot.status === "loading",
42
- isPending: snapshot.status === "idle" || snapshot.status === "loading",
43
- isSuccess: snapshot.status === "ready",
44
- refetch,
45
- status: snapshot.status,
46
- };
47
- }
@@ -1,81 +0,0 @@
1
- import { useEffect, useMemo, useRef } from "react";
2
- import type { StandardJSONSchemaV1 } from "@standard-schema/spec";
3
- import type { ScreenDefinition } from "@tailorkit/core/schema";
4
- import type { TailorKitStore } from "../tailor-kit";
5
- import { useTailorRootContext } from "../components/context";
6
-
7
- export type ScreenName<TScreens extends Record<string, ScreenDefinition>> = keyof TScreens & string;
8
-
9
- export type ScreenContext<TScreen> =
10
- TScreen extends ScreenDefinition<infer TContext>
11
- ? TContext extends StandardJSONSchemaV1
12
- ? StandardJSONSchemaV1.InferOutput<TContext>
13
- : Record<string, never>
14
- : never;
15
-
16
- interface ReadyScreenOptions<
17
- TScreens extends Record<string, ScreenDefinition>,
18
- TScreen extends ScreenName<TScreens>,
19
- > {
20
- context: ScreenContext<TScreens[TScreen]>;
21
- screen: TScreen;
22
- status?: "ready";
23
- }
24
-
25
- interface LoadingScreenOptions<TScreen extends string> {
26
- context?: never;
27
- screen: TScreen;
28
- status: "loading";
29
- }
30
-
31
- interface ErrorScreenOptions<TScreen extends string> {
32
- context?: never;
33
- screen: TScreen;
34
- status: "error";
35
- }
36
-
37
- export type CurrentScreenOptions<
38
- TScreens extends Record<string, ScreenDefinition>,
39
- TScreen extends ScreenName<TScreens> = ScreenName<TScreens>,
40
- > =
41
- TScreen extends ScreenName<TScreens>
42
- ?
43
- | ReadyScreenOptions<TScreens, TScreen>
44
- | LoadingScreenOptions<TScreen>
45
- | ErrorScreenOptions<TScreen>
46
- : never;
47
-
48
- export function createUseCurrentScreen<TScreens extends Record<string, ScreenDefinition>>(
49
- store: TailorKitStore,
50
- ) {
51
- return function useCurrentScreen<TScreen extends ScreenName<TScreens>>(
52
- options: CurrentScreenOptions<TScreens, TScreen>,
53
- ): void {
54
- useTailorRootContext("tailor.useCurrentScreen");
55
- const id = useMemo(() => Symbol("tailorkit-current-screen"), []);
56
- const status = options.status ?? "ready";
57
- const context = "context" in options ? options.context : undefined;
58
- const contextKey = JSON.stringify(context);
59
- const contextRef = useRef({ key: contextKey, value: context });
60
- if (contextRef.current.key !== contextKey) {
61
- contextRef.current = { key: contextKey, value: context };
62
- }
63
- const contextSnapshot = contextRef.current.value;
64
-
65
- useEffect(
66
- () => () => {
67
- store.unregisterScreen(id);
68
- },
69
- [id],
70
- );
71
-
72
- useEffect(() => {
73
- store.registerScreen({
74
- context: contextSnapshot,
75
- id,
76
- screen: options.screen,
77
- status,
78
- });
79
- }, [contextSnapshot, id, options.screen, status]);
80
- };
81
- }
package/src/index.ts DELETED
@@ -1,8 +0,0 @@
1
- export { components, createTailorKitClient } from "./tailor-kit";
2
- export type {
3
- AppViewProps,
4
- CurrentScreenOptions,
5
- TailorKitApp,
6
- TailorKitInstance,
7
- } from "./tailor-kit";
8
- export { primitives } from "./primitives";
package/src/node-store.ts DELETED
@@ -1,131 +0,0 @@
1
- import type { RemoteNode } from "@tailorkit/sandbox/protocol";
2
-
3
- type Listener = () => void;
4
-
5
- const childIds = (children: RemoteNode[]): string => children.map((c) => c.id).join(",");
6
-
7
- const nodeSignature = (node: RemoteNode): string => {
8
- if (node.kind === "text") {
9
- return `text:${node.text}`;
10
- }
11
- if (node.kind === "fragment") {
12
- return `frag:${childIds(node.children)}`;
13
- }
14
- // For elements: type + child IDs + serialized props + callback bindings
15
- const propsStr = JSON.stringify(node.props);
16
- const callbacksStr = (node.callbacks ?? [])
17
- .map((binding) => `${binding.callback}:${binding.event}`)
18
- .join(",");
19
- return `elem:${node.type}|${childIds(node.children)}|${propsStr}|${callbacksStr}`;
20
- };
21
-
22
- const flattenTree = (node: RemoteNode, out: Map<string, RemoteNode>): void => {
23
- out.set(node.id, node);
24
- if (node.kind === "text") {
25
- return;
26
- }
27
- for (const child of node.children) {
28
- flattenTree(child, out);
29
- }
30
- };
31
-
32
- export class NodeStore {
33
- private nodes = new Map<string, RemoteNode>();
34
- private signatures = new Map<string, string>();
35
- private nodeListeners = new Map<string, Set<Listener>>();
36
- private rootListeners = new Set<Listener>();
37
- private rootId: string | null = null;
38
-
39
- clear(): void {
40
- const nodeIds = [...this.nodeListeners.keys()];
41
- const hadRoot = this.rootId !== null;
42
-
43
- this.nodes = new Map();
44
- this.signatures = new Map();
45
- this.rootId = null;
46
-
47
- for (const id of nodeIds) {
48
- const subs = this.nodeListeners.get(id);
49
- if (subs) {
50
- for (const l of subs) {
51
- l();
52
- }
53
- }
54
- }
55
-
56
- if (hadRoot) {
57
- for (const l of this.rootListeners) {
58
- l();
59
- }
60
- }
61
- }
62
-
63
- setSnapshot(tree: RemoteNode): void {
64
- const next = new Map<string, RemoteNode>();
65
- flattenTree(tree, next);
66
-
67
- const changed = new Set<string>();
68
-
69
- for (const [id, node] of next) {
70
- const sig = nodeSignature(node);
71
- if (this.signatures.get(id) !== sig) {
72
- changed.add(id);
73
- this.signatures.set(id, sig);
74
- }
75
- }
76
-
77
- for (const id of this.signatures.keys()) {
78
- if (!next.has(id)) {
79
- this.signatures.delete(id);
80
- }
81
- }
82
-
83
- this.nodes = next;
84
-
85
- const prevRootId = this.rootId;
86
- this.rootId = tree.id;
87
-
88
- for (const id of changed) {
89
- const subs = this.nodeListeners.get(id);
90
- if (subs) {
91
- for (const l of subs) {
92
- l();
93
- }
94
- }
95
- }
96
-
97
- if (prevRootId !== this.rootId) {
98
- for (const l of this.rootListeners) {
99
- l();
100
- }
101
- }
102
- }
103
-
104
- getRootId(): string | null {
105
- return this.rootId;
106
- }
107
-
108
- getNode(id: string): RemoteNode | null {
109
- return this.nodes.get(id) ?? null;
110
- }
111
-
112
- subscribe(id: string, listener: Listener): () => void {
113
- let subs = this.nodeListeners.get(id);
114
- if (!subs) {
115
- subs = new Set();
116
- this.nodeListeners.set(id, subs);
117
- }
118
- subs.add(listener);
119
- return () => {
120
- subs.delete(listener);
121
- if (subs.size === 0) {
122
- this.nodeListeners.delete(id);
123
- }
124
- };
125
- }
126
-
127
- subscribeRoot(listener: Listener): () => void {
128
- this.rootListeners.add(listener);
129
- return () => this.rootListeners.delete(listener);
130
- }
131
- }
@@ -1,261 +0,0 @@
1
- import { createContext, useContext, useId, useMemo } from "react";
2
- import type { CSSProperties, ReactNode } from "react";
3
- import type { TailorKitTheme } from "@tailorkit/core/schema";
4
- import { resolveTheme } from "@tailorkit/core/primitives/theme";
5
-
6
- type Responsive<T> = T | Record<string, T | undefined>;
7
- type PrimitiveValue = number | string;
8
- type PrimitiveProps = Record<string, unknown>;
9
-
10
- interface PrimitiveThemeContextValue {
11
- screenId: string;
12
- theme: TailorKitTheme;
13
- }
14
-
15
- export const PrimitiveThemeContext = createContext<PrimitiveThemeContextValue | null>(null);
16
-
17
- const tokenGroups = [
18
- "space",
19
- "radius",
20
- "background",
21
- "border",
22
- "borderColor",
23
- "textColor",
24
- ] as const;
25
-
26
- const cssEscape = (value: string): string => {
27
- const css = (globalThis as { CSS?: { escape?: (input: string) => string } }).CSS;
28
- if (typeof css?.escape === "function") {
29
- return css.escape(value);
30
- }
31
- return value.replaceAll(/[^A-Za-z0-9_-]/gu, "\\$&");
32
- };
33
-
34
- const toCssValue = (
35
- group: (typeof tokenGroups)[number] | "size" | "raw",
36
- value: PrimitiveValue,
37
- ): string => {
38
- if (typeof value === "number") {
39
- return `${value}px`;
40
- }
41
- if (group === "size" || group === "raw") {
42
- return value;
43
- }
44
- return `var(--tailorkit-${group}-${cssEscape(value)})`;
45
- };
46
-
47
- const toResponsiveEntries = <T,>(value: Responsive<T> | undefined): [string, T][] => {
48
- if (value === undefined) {
49
- return [];
50
- }
51
- if (!(value && typeof value === "object") || Array.isArray(value)) {
52
- return [["base", value as T]];
53
- }
54
- return Object.entries(value as Record<string, T | undefined>).filter(
55
- (entry): entry is [string, T] => entry[1] !== undefined,
56
- );
57
- };
58
-
59
- const declarationsForProp = (prop: string, value: PrimitiveValue): string[] => {
60
- if (prop === "columns") {
61
- return [`grid-template-columns: repeat(${String(value)}, minmax(0, 1fr));`];
62
- }
63
- const tokenDeclarations: Record<string, [(typeof tokenGroups)[number], string]> = {
64
- background: ["background", "background"],
65
- border: ["border", "border"],
66
- borderColor: ["borderColor", "border-color"],
67
- textColor: ["textColor", "color"],
68
- };
69
- const tokenDeclaration = tokenDeclarations[prop];
70
- if (tokenDeclaration) {
71
- const [group, property] = tokenDeclaration;
72
- if (prop === "border") {
73
- return [`border-style: ${toCssValue(group, value)};`, "border-width: 1px;"];
74
- }
75
- return [`${property}: ${toCssValue(group, value)};`];
76
- }
77
- if (prop === "gap" || prop === "margin" || prop === "padding") {
78
- return [`${prop}: ${toCssValue("space", value)};`];
79
- }
80
- if (prop === "height" || prop === "width") {
81
- return [`${prop}: ${toCssValue("size", value)};`];
82
- }
83
- if (prop === "radius") {
84
- return [`border-radius: ${toCssValue("radius", value)};`];
85
- }
86
- if (prop === "align") {
87
- return [`align-items: ${toFlexAlignment(value)};`];
88
- }
89
- if (prop === "justify") {
90
- return [`justify-content: ${toFlexJustification(value)};`];
91
- }
92
- if (prop === "direction") {
93
- return [`flex-direction: ${toCssValue("raw", value)};`];
94
- }
95
- if (prop === "overflow") {
96
- return [`overflow: ${toCssValue("raw", value)};`];
97
- }
98
- if (prop === "grow") {
99
- return [`flex-grow: ${String(value)};`];
100
- }
101
- if (prop === "shrink") {
102
- return [`flex-shrink: ${String(value)};`];
103
- }
104
- if (prop === "minHeight") {
105
- return [`min-height: ${toCssValue("size", value)};`];
106
- }
107
- if (prop === "minWidth") {
108
- return [`min-width: ${toCssValue("size", value)};`];
109
- }
110
- if (prop === "basis") {
111
- return [`flex-basis: ${toCssValue("size", value)};`];
112
- }
113
- if (prop === "wrap") {
114
- return [`flex-wrap: ${toCssValue("raw", value)};`];
115
- }
116
- return [];
117
- };
118
-
119
- const toFlexAlignment = (value: PrimitiveValue): string => {
120
- if (value === "start") {
121
- return "flex-start";
122
- }
123
- if (value === "end") {
124
- return "flex-end";
125
- }
126
- return String(value);
127
- };
128
-
129
- const toFlexJustification = (value: PrimitiveValue): string => {
130
- if (value === "start") {
131
- return "flex-start";
132
- }
133
- if (value === "end") {
134
- return "flex-end";
135
- }
136
- if (value === "between") {
137
- return "space-between";
138
- }
139
- return String(value);
140
- };
141
-
142
- const buildPrimitiveCss = ({
143
- display,
144
- nodeId,
145
- props,
146
- screenId,
147
- theme,
148
- }: {
149
- display: "block" | "flex" | "grid" | "inline";
150
- nodeId: string;
151
- props: PrimitiveProps;
152
- screenId: string;
153
- theme: TailorKitTheme;
154
- }): string => {
155
- const selector = `[data-tailorkit-screen="${cssEscape(screenId)}"] [data-tailorkit-node="${cssEscape(
156
- nodeId,
157
- )}"]`;
158
- const base = [`display: ${display};`];
159
- const byBreakpoint = new Map<string, string[]>();
160
-
161
- for (const [prop, rawValue] of Object.entries(props)) {
162
- for (const [breakpoint, value] of toResponsiveEntries(rawValue as Responsive<PrimitiveValue>)) {
163
- const declarations = declarationsForProp(prop, value);
164
- if (declarations.length === 0) {
165
- continue;
166
- }
167
- const target = breakpoint === "base" ? base : (byBreakpoint.get(breakpoint) ?? []);
168
- target.push(...declarations);
169
- if (breakpoint !== "base") {
170
- byBreakpoint.set(breakpoint, target);
171
- }
172
- }
173
- }
174
-
175
- const rules = [`${selector} { ${base.join(" ")} }`];
176
- for (const [breakpoint, declarations] of byBreakpoint) {
177
- const minWidth = theme.breakpoints?.[breakpoint];
178
- if (!minWidth) {
179
- continue;
180
- }
181
- rules.push(`@media (min-width: ${minWidth}) { ${selector} { ${declarations.join(" ")} } }`);
182
- }
183
-
184
- return rules.join("\n");
185
- };
186
-
187
- export const buildThemeCss = (screenId: string, theme: TailorKitTheme): string => {
188
- const selector = `[data-tailorkit-screen="${cssEscape(screenId)}"]`;
189
- const declarations: string[] = [];
190
- const resolvedTheme = resolveTheme(theme);
191
-
192
- for (const group of tokenGroups) {
193
- for (const [name, value] of Object.entries(resolvedTheme.tokens?.[group] ?? {})) {
194
- declarations.push(`--tailorkit-${group}-${cssEscape(name)}: ${value};`);
195
- }
196
- }
197
-
198
- return `${selector} { ${declarations.join(" ")} }`;
199
- };
200
-
201
- const usePrimitiveNodeId = (): string => {
202
- const id = useId();
203
- return useMemo(() => `tailorkit-${id.replaceAll(":", "")}`, [id]);
204
- };
205
-
206
- const Primitive = ({
207
- children,
208
- display,
209
- element,
210
- props,
211
- }: {
212
- children?: ReactNode;
213
- display: "block" | "flex" | "grid" | "inline";
214
- element: "div" | "span";
215
- props: PrimitiveProps;
216
- }): ReactNode => {
217
- const context = useContext(PrimitiveThemeContext);
218
- const nodeId = usePrimitiveNodeId();
219
- const Element = element;
220
- const css = context
221
- ? buildPrimitiveCss({
222
- display,
223
- nodeId,
224
- props,
225
- screenId: context.screenId,
226
- theme: context.theme,
227
- })
228
- : "";
229
-
230
- return (
231
- <Element data-tailorkit-node={nodeId}>
232
- {css === "" ? null : <style data-tailorkit-node-style={nodeId}>{css}</style>}
233
- {children}
234
- </Element>
235
- );
236
- };
237
-
238
- export const primitives = {
239
- Box: ({ props, slots }: { props: PrimitiveProps; slots: { default?: ReactNode } }) => (
240
- <Primitive display="block" element="div" props={props}>
241
- {slots.default}
242
- </Primitive>
243
- ),
244
- Flex: ({ props, slots }: { props: PrimitiveProps; slots: { default?: ReactNode } }) => (
245
- <Primitive display="flex" element="div" props={props}>
246
- {slots.default}
247
- </Primitive>
248
- ),
249
- Grid: ({ props, slots }: { props: PrimitiveProps; slots: { default?: ReactNode } }) => (
250
- <Primitive display="grid" element="div" props={props}>
251
- {slots.default}
252
- </Primitive>
253
- ),
254
- Inline: ({ props, slots }: { props: PrimitiveProps; slots: { default?: ReactNode } }) => (
255
- <Primitive display="inline" element="span" props={props}>
256
- {slots.default}
257
- </Primitive>
258
- ),
259
- } as const;
260
-
261
- export type PrimitiveStyle = CSSProperties;
@@ -1,11 +0,0 @@
1
- import { createContext } from "react";
2
- import type { HostToWorkerPayload } from "@tailorkit/sandbox/protocol";
3
- import type { NodeStore } from "./node-store";
4
-
5
- export interface RemoteViewContext {
6
- components: Record<string, unknown>;
7
- dispatch: (payload: HostToWorkerPayload) => void;
8
- store: NodeStore;
9
- }
10
-
11
- export const RemoteUIContext = createContext<RemoteViewContext | null>(null);