@demokit-ai/react 0.2.0 → 0.4.0

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.js CHANGED
@@ -1,44 +1,125 @@
1
- import { createContext, useState, useRef, useEffect, useCallback, useMemo, useContext } from 'react';
2
- import { createDemoInterceptor } from '@demokit-ai/core';
3
- import { jsx, jsxs } from 'react/jsx-runtime';
4
-
5
1
  // src/provider.tsx
2
+ import { useState, useEffect, useCallback, useMemo, useRef } from "react";
3
+ import {
4
+ createDemoInterceptor,
5
+ fetchCloudFixtures,
6
+ createRemoteFixtures
7
+ } from "@demokit-ai/core";
8
+
9
+ // src/context.ts
10
+ import { createContext } from "react";
6
11
  var DemoModeContext = createContext(void 0);
7
12
  DemoModeContext.displayName = "DemoModeContext";
13
+
14
+ // src/provider.tsx
15
+ import { jsx } from "react/jsx-runtime";
8
16
  function DemoKitProvider({
9
17
  children,
10
18
  fixtures,
19
+ // Remote config
20
+ source,
21
+ onRemoteLoad,
22
+ onRemoteError,
23
+ loadingFallback = null,
24
+ errorFallback,
25
+ // Standard props
11
26
  storageKey = "demokit-mode",
12
27
  initialEnabled = false,
13
28
  onDemoModeChange,
14
- baseUrl
29
+ baseUrl,
30
+ // Detection & guards
31
+ detection,
32
+ canDisable,
33
+ onMutationIntercepted
15
34
  }) {
16
35
  const [isDemoMode, setIsDemoMode] = useState(initialEnabled);
17
36
  const [isHydrated, setIsHydrated] = useState(false);
37
+ const [isPublicDemo, setIsPublicDemo] = useState(false);
38
+ const [isLoading, setIsLoading] = useState(!!source?.apiKey);
39
+ const [remoteError, setRemoteError] = useState(null);
40
+ const [remoteVersion, setRemoteVersion] = useState(null);
18
41
  const interceptorRef = useRef(null);
19
42
  const initializedRef = useRef(false);
43
+ const remoteFixturesRef = useRef(null);
44
+ const refetchFnRef = useRef(null);
45
+ const setupInterceptor = useCallback(
46
+ (mergedFixtures) => {
47
+ interceptorRef.current?.destroy();
48
+ interceptorRef.current = createDemoInterceptor({
49
+ fixtures: mergedFixtures,
50
+ storageKey,
51
+ initialEnabled,
52
+ baseUrl,
53
+ detection,
54
+ canDisable,
55
+ onMutationIntercepted,
56
+ onEnable: () => {
57
+ setIsDemoMode(true);
58
+ onDemoModeChange?.(true);
59
+ },
60
+ onDisable: () => {
61
+ setIsDemoMode(false);
62
+ onDemoModeChange?.(false);
63
+ }
64
+ });
65
+ const storedState = interceptorRef.current.isEnabled();
66
+ setIsDemoMode(storedState);
67
+ setIsPublicDemo(interceptorRef.current.isPublicDemo());
68
+ setIsHydrated(true);
69
+ },
70
+ [storageKey, initialEnabled, baseUrl, onDemoModeChange, detection, canDisable, onMutationIntercepted]
71
+ );
72
+ const fetchAndSetup = useCallback(async () => {
73
+ if (!source?.apiKey) return;
74
+ setIsLoading(true);
75
+ setRemoteError(null);
76
+ try {
77
+ const response = await fetchCloudFixtures({
78
+ apiKey: source.apiKey,
79
+ apiUrl: source.apiUrl,
80
+ timeout: source.timeout,
81
+ retry: source.retry,
82
+ maxRetries: source.maxRetries,
83
+ onLoad: onRemoteLoad,
84
+ onError: onRemoteError
85
+ });
86
+ const remoteFixtures = createRemoteFixtures(response, fixtures);
87
+ remoteFixturesRef.current = remoteFixtures;
88
+ setRemoteVersion(response.version);
89
+ setupInterceptor(remoteFixtures);
90
+ } catch (error) {
91
+ const err = error instanceof Error ? error : new Error(String(error));
92
+ setRemoteError(err);
93
+ onRemoteError?.(err);
94
+ if (fixtures && Object.keys(fixtures).length > 0) {
95
+ setupInterceptor(fixtures);
96
+ } else {
97
+ setIsHydrated(true);
98
+ }
99
+ } finally {
100
+ setIsLoading(false);
101
+ }
102
+ }, [
103
+ source,
104
+ fixtures,
105
+ onRemoteLoad,
106
+ onRemoteError,
107
+ setupInterceptor
108
+ ]);
109
+ refetchFnRef.current = fetchAndSetup;
20
110
  useEffect(() => {
21
111
  if (initializedRef.current) {
22
112
  return;
23
113
  }
24
114
  initializedRef.current = true;
25
- interceptorRef.current = createDemoInterceptor({
26
- fixtures,
27
- storageKey,
28
- initialEnabled,
29
- baseUrl,
30
- onEnable: () => {
31
- setIsDemoMode(true);
32
- onDemoModeChange?.(true);
33
- },
34
- onDisable: () => {
35
- setIsDemoMode(false);
36
- onDemoModeChange?.(false);
37
- }
38
- });
39
- const storedState = interceptorRef.current.isEnabled();
40
- setIsDemoMode(storedState);
41
- setIsHydrated(true);
115
+ if (source?.apiKey) {
116
+ fetchAndSetup();
117
+ } else if (fixtures) {
118
+ setupInterceptor(fixtures);
119
+ } else {
120
+ setIsHydrated(true);
121
+ setIsLoading(false);
122
+ }
42
123
  return () => {
43
124
  interceptorRef.current?.destroy();
44
125
  interceptorRef.current = null;
@@ -46,15 +127,19 @@ function DemoKitProvider({
46
127
  };
47
128
  }, []);
48
129
  useEffect(() => {
49
- if (interceptorRef.current && isHydrated) {
50
- interceptorRef.current.setFixtures(fixtures);
130
+ if (!isHydrated || isLoading) return;
131
+ if (source?.apiKey && remoteFixturesRef.current) {
132
+ const merged = { ...remoteFixturesRef.current, ...fixtures };
133
+ interceptorRef.current?.setFixtures(merged);
134
+ } else if (fixtures) {
135
+ interceptorRef.current?.setFixtures(fixtures);
51
136
  }
52
- }, [fixtures, isHydrated]);
137
+ }, [fixtures, isHydrated, isLoading, source]);
53
138
  const enable = useCallback(() => {
54
139
  interceptorRef.current?.enable();
55
140
  }, []);
56
141
  const disable = useCallback(() => {
57
- interceptorRef.current?.disable();
142
+ return interceptorRef.current?.disable() ?? true;
58
143
  }, []);
59
144
  const toggle = useCallback(() => {
60
145
  interceptorRef.current?.toggle();
@@ -72,21 +157,67 @@ function DemoKitProvider({
72
157
  const getSession = useCallback(() => {
73
158
  return interceptorRef.current?.getSession() ?? null;
74
159
  }, []);
160
+ const refetch = useCallback(async () => {
161
+ if (!source?.apiKey) {
162
+ console.warn("[DemoKit] refetch() called but no source provided");
163
+ return;
164
+ }
165
+ await refetchFnRef.current?.();
166
+ }, [source]);
75
167
  const value = useMemo(
76
168
  () => ({
77
169
  isDemoMode,
78
170
  isHydrated,
171
+ isPublicDemo,
172
+ isLoading,
173
+ remoteError,
174
+ remoteVersion,
79
175
  enable,
80
176
  disable,
81
177
  toggle,
82
178
  setDemoMode,
83
179
  resetSession,
84
- getSession
180
+ getSession,
181
+ refetch
85
182
  }),
86
- [isDemoMode, isHydrated, enable, disable, toggle, setDemoMode, resetSession, getSession]
183
+ [
184
+ isDemoMode,
185
+ isHydrated,
186
+ isPublicDemo,
187
+ isLoading,
188
+ remoteError,
189
+ remoteVersion,
190
+ enable,
191
+ disable,
192
+ toggle,
193
+ setDemoMode,
194
+ resetSession,
195
+ getSession,
196
+ refetch
197
+ ]
87
198
  );
199
+ if (isLoading && source?.apiKey) {
200
+ return /* @__PURE__ */ jsx(DemoModeContext.Provider, { value, children: loadingFallback });
201
+ }
202
+ if (remoteError && errorFallback) {
203
+ const errorContent = typeof errorFallback === "function" ? errorFallback(remoteError) : errorFallback;
204
+ return /* @__PURE__ */ jsx(DemoModeContext.Provider, { value, children: errorContent });
205
+ }
88
206
  return /* @__PURE__ */ jsx(DemoModeContext.Provider, { value, children });
89
207
  }
208
+
209
+ // src/config.ts
210
+ function createRemoteSource(config) {
211
+ return {
212
+ timeout: 1e4,
213
+ retry: true,
214
+ maxRetries: 3,
215
+ ...config
216
+ };
217
+ }
218
+
219
+ // src/hooks.ts
220
+ import { useContext } from "react";
90
221
  function useDemoMode() {
91
222
  const context = useContext(DemoModeContext);
92
223
  if (context === void 0) {
@@ -105,8 +236,139 @@ function useIsHydrated() {
105
236
  function useDemoSession() {
106
237
  return useDemoMode().getSession();
107
238
  }
108
- function EyeIcon() {
239
+
240
+ // src/guard.ts
241
+ import { useCallback as useCallback2 } from "react";
242
+ function useDemoGuard(options = {}) {
243
+ const { isDemoMode } = useDemoMode();
244
+ const { onBlocked } = options;
245
+ const guardMutation = useCallback2(
246
+ (action, actionName) => {
247
+ if (isDemoMode) {
248
+ const message = actionName ? `${actionName} (simulated in demo mode)` : "Action simulated in demo mode";
249
+ onBlocked?.(message);
250
+ return false;
251
+ }
252
+ action();
253
+ return true;
254
+ },
255
+ [isDemoMode, onBlocked]
256
+ );
257
+ return {
258
+ guardMutation,
259
+ isDemoMode
260
+ };
261
+ }
262
+
263
+ // src/powered-by.tsx
264
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
265
+ function ExternalLinkIcon({ size }) {
109
266
  return /* @__PURE__ */ jsxs(
267
+ "svg",
268
+ {
269
+ width: size,
270
+ height: size,
271
+ viewBox: "0 0 24 24",
272
+ fill: "none",
273
+ stroke: "currentColor",
274
+ strokeWidth: "2",
275
+ strokeLinecap: "round",
276
+ strokeLinejoin: "round",
277
+ "aria-hidden": "true",
278
+ children: [
279
+ /* @__PURE__ */ jsx2("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
280
+ /* @__PURE__ */ jsx2("polyline", { points: "15 3 21 3 21 9" }),
281
+ /* @__PURE__ */ jsx2("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
282
+ ]
283
+ }
284
+ );
285
+ }
286
+ var sizeConfig = {
287
+ xs: {
288
+ fontSize: "10px",
289
+ padding: "2px 6px",
290
+ gap: "3px",
291
+ iconSize: 8
292
+ },
293
+ sm: {
294
+ fontSize: "11px",
295
+ padding: "3px 8px",
296
+ gap: "4px",
297
+ iconSize: 10
298
+ },
299
+ md: {
300
+ fontSize: "12px",
301
+ padding: "4px 10px",
302
+ gap: "5px",
303
+ iconSize: 12
304
+ }
305
+ };
306
+ var variantStyles = {
307
+ light: {
308
+ color: "rgba(120, 53, 15, 0.7)",
309
+ hoverColor: "rgba(120, 53, 15, 0.9)",
310
+ backgroundColor: "transparent",
311
+ hoverBackgroundColor: "rgba(217, 119, 6, 0.08)"
312
+ },
313
+ dark: {
314
+ color: "rgba(255, 255, 255, 0.6)",
315
+ hoverColor: "rgba(255, 255, 255, 0.9)",
316
+ backgroundColor: "transparent",
317
+ hoverBackgroundColor: "rgba(255, 255, 255, 0.1)"
318
+ }
319
+ };
320
+ function PoweredByBadge({
321
+ url = "https://demokit.ai",
322
+ variant = "light",
323
+ size = "sm",
324
+ className = "",
325
+ style
326
+ }) {
327
+ const config = sizeConfig[size];
328
+ const colors = variantStyles[variant === "auto" ? "light" : variant];
329
+ const baseStyles = {
330
+ display: "inline-flex",
331
+ alignItems: "center",
332
+ gap: config.gap,
333
+ fontSize: config.fontSize,
334
+ padding: config.padding,
335
+ color: colors.color,
336
+ textDecoration: "none",
337
+ borderRadius: "4px",
338
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
339
+ fontWeight: 500,
340
+ transition: "color 0.15s ease, background-color 0.15s ease",
341
+ whiteSpace: "nowrap",
342
+ ...style
343
+ };
344
+ return /* @__PURE__ */ jsxs(
345
+ "a",
346
+ {
347
+ href: url,
348
+ target: "_blank",
349
+ rel: "noopener noreferrer",
350
+ className: `demokit-powered-by ${className}`.trim(),
351
+ style: baseStyles,
352
+ onMouseOver: (e) => {
353
+ e.currentTarget.style.color = colors.hoverColor;
354
+ e.currentTarget.style.backgroundColor = colors.hoverBackgroundColor;
355
+ },
356
+ onMouseOut: (e) => {
357
+ e.currentTarget.style.color = colors.color;
358
+ e.currentTarget.style.backgroundColor = "transparent";
359
+ },
360
+ children: [
361
+ /* @__PURE__ */ jsx2("span", { children: "Powered by DemoKit" }),
362
+ /* @__PURE__ */ jsx2(ExternalLinkIcon, { size: config.iconSize })
363
+ ]
364
+ }
365
+ );
366
+ }
367
+
368
+ // src/banner.tsx
369
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
370
+ function EyeIcon() {
371
+ return /* @__PURE__ */ jsxs2(
110
372
  "svg",
111
373
  {
112
374
  width: "20",
@@ -119,8 +381,8 @@ function EyeIcon() {
119
381
  strokeLinejoin: "round",
120
382
  "aria-hidden": "true",
121
383
  children: [
122
- /* @__PURE__ */ jsx("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }),
123
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" })
384
+ /* @__PURE__ */ jsx3("path", { d: "M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" }),
385
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "3" })
124
386
  ]
125
387
  }
126
388
  );
@@ -171,6 +433,8 @@ function DemoModeBanner({
171
433
  demoLabel = "Demo Mode Active",
172
434
  description = "Changes are simulated and not saved",
173
435
  showIcon = true,
436
+ showPoweredBy = true,
437
+ poweredByUrl = "https://demokit.ai",
174
438
  style,
175
439
  onExit
176
440
  }) {
@@ -185,39 +449,223 @@ function DemoModeBanner({
185
449
  disable();
186
450
  }
187
451
  };
188
- return /* @__PURE__ */ jsxs(
452
+ const effectiveShowPoweredBy = showPoweredBy;
453
+ return /* @__PURE__ */ jsxs2(
189
454
  "div",
190
455
  {
191
456
  className: `demokit-banner ${className}`.trim(),
192
- style: { ...defaultStyles.container, ...style },
457
+ style: { ...defaultStyles.container, flexDirection: "column", gap: "4px", ...style },
193
458
  role: "status",
194
459
  "aria-live": "polite",
195
460
  children: [
196
- /* @__PURE__ */ jsxs("div", { style: defaultStyles.content, children: [
197
- showIcon && /* @__PURE__ */ jsx("span", { style: defaultStyles.icon, children: /* @__PURE__ */ jsx(EyeIcon, {}) }),
198
- /* @__PURE__ */ jsx("span", { style: defaultStyles.label, children: demoLabel }),
199
- description && /* @__PURE__ */ jsx("span", { style: defaultStyles.description, children: description })
461
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%" }, children: [
462
+ /* @__PURE__ */ jsxs2("div", { style: defaultStyles.content, children: [
463
+ showIcon && /* @__PURE__ */ jsx3("span", { style: defaultStyles.icon, children: /* @__PURE__ */ jsx3(EyeIcon, {}) }),
464
+ /* @__PURE__ */ jsx3("span", { style: defaultStyles.label, children: demoLabel }),
465
+ description && /* @__PURE__ */ jsx3("span", { style: defaultStyles.description, children: description })
466
+ ] }),
467
+ /* @__PURE__ */ jsx3(
468
+ "button",
469
+ {
470
+ onClick: handleExit,
471
+ style: defaultStyles.button,
472
+ onMouseOver: (e) => {
473
+ e.currentTarget.style.backgroundColor = "rgba(217, 119, 6, 0.1)";
474
+ },
475
+ onMouseOut: (e) => {
476
+ e.currentTarget.style.backgroundColor = "transparent";
477
+ },
478
+ type: "button",
479
+ children: exitLabel
480
+ }
481
+ )
200
482
  ] }),
201
- /* @__PURE__ */ jsx(
202
- "button",
203
- {
204
- onClick: handleExit,
205
- style: defaultStyles.button,
206
- onMouseOver: (e) => {
207
- e.currentTarget.style.backgroundColor = "rgba(217, 119, 6, 0.1)";
208
- },
209
- onMouseOut: (e) => {
210
- e.currentTarget.style.backgroundColor = "transparent";
211
- },
212
- type: "button",
213
- children: exitLabel
214
- }
215
- )
483
+ effectiveShowPoweredBy && /* @__PURE__ */ jsx3("div", { style: { display: "flex", justifyContent: "flex-end", width: "100%" }, children: /* @__PURE__ */ jsx3(PoweredByBadge, { url: poweredByUrl, size: "xs" }) })
216
484
  ]
217
485
  }
218
486
  );
219
487
  }
220
488
 
221
- export { DemoKitProvider, DemoModeBanner, DemoModeContext, useDemoMode, useDemoSession, useIsDemoMode, useIsHydrated };
222
- //# sourceMappingURL=index.js.map
489
+ // src/toggle.tsx
490
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
491
+ var sizeConfig2 = {
492
+ sm: {
493
+ trackWidth: 36,
494
+ trackHeight: 20,
495
+ thumbSize: 16,
496
+ thumbOffset: 2,
497
+ fontSize: "12px",
498
+ padding: "8px 12px",
499
+ gap: "8px"
500
+ },
501
+ md: {
502
+ trackWidth: 44,
503
+ trackHeight: 24,
504
+ thumbSize: 20,
505
+ thumbOffset: 2,
506
+ fontSize: "14px",
507
+ padding: "12px 16px",
508
+ gap: "10px"
509
+ },
510
+ lg: {
511
+ trackWidth: 52,
512
+ trackHeight: 28,
513
+ thumbSize: 24,
514
+ thumbOffset: 2,
515
+ fontSize: "16px",
516
+ padding: "16px 20px",
517
+ gap: "12px"
518
+ }
519
+ };
520
+ var positionStyles = {
521
+ inline: {},
522
+ floating: {
523
+ position: "fixed",
524
+ zIndex: 9999,
525
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
526
+ borderRadius: "8px"
527
+ },
528
+ corner: {
529
+ position: "fixed",
530
+ bottom: "20px",
531
+ right: "20px",
532
+ zIndex: 9999,
533
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
534
+ borderRadius: "8px"
535
+ }
536
+ };
537
+ var defaultStyles2 = {
538
+ container: {
539
+ display: "inline-flex",
540
+ flexDirection: "column",
541
+ alignItems: "flex-start",
542
+ gap: "4px",
543
+ backgroundColor: "#ffffff",
544
+ border: "1px solid rgba(0, 0, 0, 0.1)",
545
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
546
+ },
547
+ row: {
548
+ display: "flex",
549
+ alignItems: "center",
550
+ width: "100%"
551
+ },
552
+ label: {
553
+ fontWeight: 500,
554
+ color: "#1f2937",
555
+ userSelect: "none"
556
+ },
557
+ track: {
558
+ position: "relative",
559
+ borderRadius: "9999px",
560
+ cursor: "pointer",
561
+ transition: "background-color 0.2s ease",
562
+ flexShrink: 0
563
+ },
564
+ trackOff: {
565
+ backgroundColor: "#d1d5db"
566
+ },
567
+ trackOn: {
568
+ backgroundColor: "#d97706"
569
+ },
570
+ thumb: {
571
+ position: "absolute",
572
+ top: "50%",
573
+ transform: "translateY(-50%)",
574
+ backgroundColor: "#ffffff",
575
+ borderRadius: "50%",
576
+ boxShadow: "0 1px 3px rgba(0, 0, 0, 0.2)",
577
+ transition: "left 0.2s ease"
578
+ },
579
+ poweredByContainer: {
580
+ display: "flex",
581
+ justifyContent: "flex-end",
582
+ width: "100%"
583
+ }
584
+ };
585
+ function DemoModeToggle({
586
+ showLabel = true,
587
+ label = "Demo Mode",
588
+ showPoweredBy = true,
589
+ poweredByUrl = "https://demokit.ai",
590
+ position = "inline",
591
+ size = "md",
592
+ className = "",
593
+ style,
594
+ onChange
595
+ }) {
596
+ const { isDemoMode, isHydrated, toggle } = useDemoMode();
597
+ if (!isHydrated) {
598
+ return null;
599
+ }
600
+ const config = sizeConfig2[size];
601
+ const posStyle = positionStyles[position];
602
+ const handleToggle = () => {
603
+ toggle();
604
+ onChange?.(!isDemoMode);
605
+ };
606
+ const thumbLeft = isDemoMode ? config.trackWidth - config.thumbSize - config.thumbOffset : config.thumbOffset;
607
+ const effectiveShowPoweredBy = showPoweredBy;
608
+ return /* @__PURE__ */ jsxs3(
609
+ "div",
610
+ {
611
+ className: `demokit-toggle ${className}`.trim(),
612
+ style: {
613
+ ...defaultStyles2.container,
614
+ padding: config.padding,
615
+ ...posStyle,
616
+ ...style
617
+ },
618
+ role: "group",
619
+ "aria-label": "Demo mode toggle",
620
+ children: [
621
+ /* @__PURE__ */ jsxs3("div", { style: { ...defaultStyles2.row, gap: config.gap }, children: [
622
+ showLabel && /* @__PURE__ */ jsx4("span", { style: { ...defaultStyles2.label, fontSize: config.fontSize }, children: label }),
623
+ /* @__PURE__ */ jsx4(
624
+ "button",
625
+ {
626
+ type: "button",
627
+ role: "switch",
628
+ "aria-checked": isDemoMode,
629
+ "aria-label": `${label}: ${isDemoMode ? "On" : "Off"}`,
630
+ onClick: handleToggle,
631
+ style: {
632
+ ...defaultStyles2.track,
633
+ ...isDemoMode ? defaultStyles2.trackOn : defaultStyles2.trackOff,
634
+ width: config.trackWidth,
635
+ height: config.trackHeight,
636
+ border: "none",
637
+ padding: 0
638
+ },
639
+ children: /* @__PURE__ */ jsx4(
640
+ "span",
641
+ {
642
+ style: {
643
+ ...defaultStyles2.thumb,
644
+ width: config.thumbSize,
645
+ height: config.thumbSize,
646
+ left: thumbLeft
647
+ }
648
+ }
649
+ )
650
+ }
651
+ )
652
+ ] }),
653
+ effectiveShowPoweredBy && /* @__PURE__ */ jsx4("div", { style: defaultStyles2.poweredByContainer, children: /* @__PURE__ */ jsx4(PoweredByBadge, { url: poweredByUrl, size: "xs" }) })
654
+ ]
655
+ }
656
+ );
657
+ }
658
+ export {
659
+ DemoKitProvider,
660
+ DemoModeBanner,
661
+ DemoModeContext,
662
+ DemoModeToggle,
663
+ PoweredByBadge,
664
+ createRemoteSource,
665
+ useDemoGuard,
666
+ useDemoMode,
667
+ useDemoSession,
668
+ useIsDemoMode,
669
+ useIsHydrated
670
+ };
223
671
  //# sourceMappingURL=index.js.map