@particle-academy/react-fancy 5.49.0 → 5.50.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/CHANGELOG.md +36 -0
- package/dist/button.cjs +4 -4
- package/dist/button.js +2 -2
- package/dist/{chunk-WBJRFWZE.cjs → chunk-2KZINS6D.cjs} +4 -4
- package/dist/{chunk-WBJRFWZE.cjs.map → chunk-2KZINS6D.cjs.map} +1 -1
- package/dist/chunk-6TBRBN7H.js +212 -0
- package/dist/chunk-6TBRBN7H.js.map +1 -0
- package/dist/{chunk-VM5BNL4L.js → chunk-7MJ7VEKE.js} +3 -3
- package/dist/{chunk-VM5BNL4L.js.map → chunk-7MJ7VEKE.js.map} +1 -1
- package/dist/{chunk-XOWWNG7D.js → chunk-ASS6EWNI.js} +3 -3
- package/dist/{chunk-XOWWNG7D.js.map → chunk-ASS6EWNI.js.map} +1 -1
- package/dist/{chunk-JHDO6CRT.js → chunk-FU6R6BZ4.js} +3 -3
- package/dist/{chunk-JHDO6CRT.js.map → chunk-FU6R6BZ4.js.map} +1 -1
- package/dist/{chunk-3XJKJQSY.cjs → chunk-FWA4PCW7.cjs} +4 -4
- package/dist/{chunk-3XJKJQSY.cjs.map → chunk-FWA4PCW7.cjs.map} +1 -1
- package/dist/{chunk-EEKXWXYO.cjs → chunk-GCWIZNN2.cjs} +4 -4
- package/dist/{chunk-EEKXWXYO.cjs.map → chunk-GCWIZNN2.cjs.map} +1 -1
- package/dist/{chunk-TKDUT7ZA.cjs → chunk-IPBEVSSC.cjs} +6 -6
- package/dist/{chunk-TKDUT7ZA.cjs.map → chunk-IPBEVSSC.cjs.map} +1 -1
- package/dist/{chunk-LP3HMRQT.cjs → chunk-IYVV4RD3.cjs} +4 -4
- package/dist/{chunk-LP3HMRQT.cjs.map → chunk-IYVV4RD3.cjs.map} +1 -1
- package/dist/{chunk-GMNMJLZO.js → chunk-K6EJLBBQ.js} +12 -6
- package/dist/chunk-K6EJLBBQ.js.map +1 -0
- package/dist/{chunk-ZLYOMQ2J.js → chunk-KODD54GT.js} +3 -3
- package/dist/{chunk-ZLYOMQ2J.js.map → chunk-KODD54GT.js.map} +1 -1
- package/dist/{chunk-ODAPI4QJ.cjs → chunk-M52IS5SO.cjs} +11 -11
- package/dist/{chunk-ODAPI4QJ.cjs.map → chunk-M52IS5SO.cjs.map} +1 -1
- package/dist/{chunk-FNYUUVOK.cjs → chunk-MFQ5NBSV.cjs} +14 -7
- package/dist/chunk-MFQ5NBSV.cjs.map +1 -0
- package/dist/{chunk-I6XHZ3S2.cjs → chunk-NAQJF3G6.cjs} +4 -4
- package/dist/{chunk-I6XHZ3S2.cjs.map → chunk-NAQJF3G6.cjs.map} +1 -1
- package/dist/{chunk-KST6GW2B.cjs → chunk-NCXH5O4I.cjs} +6 -6
- package/dist/{chunk-KST6GW2B.cjs.map → chunk-NCXH5O4I.cjs.map} +1 -1
- package/dist/{chunk-K74R6IEB.js → chunk-PCTZNK2Z.js} +4 -4
- package/dist/{chunk-K74R6IEB.js.map → chunk-PCTZNK2Z.js.map} +1 -1
- package/dist/{chunk-DUOZSOSB.cjs → chunk-RU6ZTA4M.cjs} +3 -3
- package/dist/chunk-RU6ZTA4M.cjs.map +1 -0
- package/dist/{chunk-62WPAKFS.js → chunk-UDEEPMQ4.js} +3 -3
- package/dist/{chunk-62WPAKFS.js.map → chunk-UDEEPMQ4.js.map} +1 -1
- package/dist/{chunk-VKRQHLM5.js → chunk-VB3QJ6QE.js} +3 -3
- package/dist/{chunk-VKRQHLM5.js.map → chunk-VB3QJ6QE.js.map} +1 -1
- package/dist/{chunk-RLC2BE3D.cjs → chunk-VWBKFQQN.cjs} +15 -15
- package/dist/{chunk-RLC2BE3D.cjs.map → chunk-VWBKFQQN.cjs.map} +1 -1
- package/dist/chunk-X2FC7ODX.cjs +215 -0
- package/dist/chunk-X2FC7ODX.cjs.map +1 -0
- package/dist/{chunk-SK4AEUO4.js → chunk-XBC3M4BL.js} +3 -3
- package/dist/{chunk-SK4AEUO4.js.map → chunk-XBC3M4BL.js.map} +1 -1
- package/dist/{chunk-XWXV6HSK.js → chunk-XZUGREDI.js} +3 -3
- package/dist/chunk-XZUGREDI.js.map +1 -0
- package/dist/{chunk-MQEV7XEG.js → chunk-YOTCZUNW.js} +4 -4
- package/dist/{chunk-MQEV7XEG.js.map → chunk-YOTCZUNW.js.map} +1 -1
- package/dist/content-renderer.cjs +5 -5
- package/dist/content-renderer.js +2 -2
- package/dist/editor.cjs +5 -5
- package/dist/editor.js +3 -3
- package/dist/faux-client.cjs +2 -2
- package/dist/faux-client.js +1 -1
- package/dist/image-viewer.cjs +3 -3
- package/dist/image-viewer.js +2 -2
- package/dist/index.cjs +48 -44
- package/dist/index.d.cts +74 -7
- package/dist/index.d.ts +74 -7
- package/dist/index.js +12 -12
- package/dist/json-editor.cjs +14 -14
- package/dist/json-editor.js +3 -3
- package/dist/magic-wand.cjs +4 -4
- package/dist/magic-wand.js +3 -3
- package/dist/media-viewer.cjs +5 -5
- package/dist/media-viewer.js +4 -4
- package/dist/pdf-viewer.cjs +3 -3
- package/dist/pdf-viewer.js +2 -2
- package/dist/prompt-input.cjs +4 -4
- package/dist/prompt-input.js +3 -3
- package/dist/reason-tag.cjs +4 -4
- package/dist/reason-tag.js +3 -3
- package/docs/ContentRenderer.md +36 -0
- package/package.json +1 -1
- package/dist/chunk-DUOZSOSB.cjs.map +0 -1
- package/dist/chunk-FNYUUVOK.cjs.map +0 -1
- package/dist/chunk-GMNMJLZO.js.map +0 -1
- package/dist/chunk-LRNWD26Z.cjs +0 -82
- package/dist/chunk-LRNWD26Z.cjs.map +0 -1
- package/dist/chunk-QXYO76NZ.js +0 -79
- package/dist/chunk-QXYO76NZ.js.map +0 -1
- package/dist/chunk-XWXV6HSK.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -131,14 +131,81 @@ declare function cn(...inputs: ClassValue[]): string;
|
|
|
131
131
|
*/
|
|
132
132
|
declare function sanitizeHref(href: string | undefined | null): string | undefined;
|
|
133
133
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
134
|
+
* Allowlist options for {@link sanitizeHtml}. Passing ANY options object
|
|
135
|
+
* (even `{}`) switches from the default blocklist to allowlist mode, where
|
|
136
|
+
* everything not listed is removed.
|
|
137
|
+
*/
|
|
138
|
+
interface SanitizeHtmlOptions {
|
|
139
|
+
/**
|
|
140
|
+
* Tags to keep, e.g. `["p", "a", "strong"]`. A tag that is not listed is
|
|
141
|
+
* removed but its text and (cleaned) children are kept. Default: none, so
|
|
142
|
+
* only text survives.
|
|
143
|
+
*
|
|
144
|
+
* Some tags are removed WITH their content even when listed, because no
|
|
145
|
+
* attribute filtering makes them safe: `script`, `style`, `iframe`, `frame`,
|
|
146
|
+
* `frameset`, `object`, `embed`, `applet`, `link`, `meta`, `base`, `form`,
|
|
147
|
+
* `title`, `template`, `noscript`, `noembed`, `noframes`, `xmp`,
|
|
148
|
+
* `plaintext`, `svg` and `math`.
|
|
149
|
+
*/
|
|
150
|
+
allowedTags?: readonly string[];
|
|
151
|
+
/**
|
|
152
|
+
* Attributes to keep. Either one list for every allowed tag, or a map from
|
|
153
|
+
* tag name to its list, where the key `"*"` applies to every tag. A trailing
|
|
154
|
+
* `*` matches a prefix (`"data-*"`, `"aria-*"`). Default: none.
|
|
155
|
+
*
|
|
156
|
+
* Never kept, even when listed: event handlers (`on*`), `srcdoc` and
|
|
157
|
+
* `srcset`.
|
|
158
|
+
*/
|
|
159
|
+
allowedAttributes?: readonly string[] | Readonly<Record<string, readonly string[]>>;
|
|
160
|
+
/**
|
|
161
|
+
* URL schemes allowed in URL attributes (`href`, `src`, `action`,
|
|
162
|
+
* `formaction`, `cite`, `poster`, `background`, `ping`, `xlink:href`), with
|
|
163
|
+
* the colon: `["https:", "mailto:"]`. A URL attribute whose scheme is not
|
|
164
|
+
* listed is removed. Default: `["http:", "https:", "mailto:"]`.
|
|
165
|
+
*
|
|
166
|
+
* `javascript:` and `vbscript:` are never kept, even when listed.
|
|
167
|
+
*/
|
|
168
|
+
allowedSchemes?: readonly string[];
|
|
169
|
+
/**
|
|
170
|
+
* Keep URLs with no scheme that stay on this site: `/x`, `x/y`, `../x`,
|
|
171
|
+
* `?q`, `#frag`. Protocol-relative URLs (`//host/x`, and the backslash
|
|
172
|
+
* spellings a browser treats the same way) leave the site and are always
|
|
173
|
+
* removed. Default: `false`.
|
|
174
|
+
*/
|
|
175
|
+
allowRelative?: boolean;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Sanitize an HTML string.
|
|
179
|
+
*
|
|
180
|
+
* **With no options** (the default blocklist): removes dangerous tags (script,
|
|
181
|
+
* iframe, etc.), event-handler attributes (`onclick`, `onerror`, ...), and
|
|
182
|
+
* dangerous URI schemes in `href`/`src` attributes. Everything else is kept.
|
|
183
|
+
* In non-browser environments returns the input unchanged — sanitize on the
|
|
184
|
+
* server in those cases.
|
|
185
|
+
*
|
|
186
|
+
* **With options** (allowlist mode): keeps ONLY the listed tags, attributes and
|
|
187
|
+
* URL schemes; see {@link SanitizeHtmlOptions}. The allowlist can only narrow:
|
|
188
|
+
* event handlers, `javascript:` URLs and script-capable tags never survive,
|
|
189
|
+
* even when listed. In non-browser environments the input is returned as
|
|
190
|
+
* escaped text (fail closed).
|
|
191
|
+
*
|
|
192
|
+
* Uses the browser's `DOMParser`.
|
|
193
|
+
*/
|
|
194
|
+
declare function sanitizeHtml(html: string, options?: SanitizeHtmlOptions): string;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Render markdown (GitHub-flavoured) to sanitised HTML — the same parser and
|
|
198
|
+
* output `ContentRenderer` uses, so a host never has to import the parser
|
|
199
|
+
* itself.
|
|
200
|
+
*
|
|
201
|
+
* With no `sanitize` options the default blocklist of {@link sanitizeHtml} is
|
|
202
|
+
* applied; pass allowlist options to keep only what you list:
|
|
137
203
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
204
|
+
* ```ts
|
|
205
|
+
* renderMarkdown(md, { allowedTags: ["p", "strong", "a"], allowedAttributes: ["href"] })
|
|
206
|
+
* ```
|
|
140
207
|
*/
|
|
141
|
-
declare function
|
|
208
|
+
declare function renderMarkdown(markdown: string, sanitize?: SanitizeHtmlOptions): string;
|
|
142
209
|
|
|
143
210
|
/**
|
|
144
211
|
* One state slot that works controlled or uncontrolled.
|
|
@@ -316,4 +383,4 @@ type UseThemeResult = {
|
|
|
316
383
|
*/
|
|
317
384
|
declare function useTheme(): UseThemeResult;
|
|
318
385
|
|
|
319
|
-
export { type NodeRect, Placement, type ResolvedTheme, THEME_STORAGE_KEY, type ThemePreference, type UseThemeResult, cn, getThemePreference, initTheme, resolveTheme, sanitizeHref, sanitizeHtml, setThemePreference, subscribeTheme, useAnimation, useControllableState, useEscapeKey, useFloatingPosition, useFocusTrap, useId, useNodeRegistry, useOutsideClick, usePanZoom, useTheme };
|
|
386
|
+
export { type NodeRect, Placement, type ResolvedTheme, type SanitizeHtmlOptions, THEME_STORAGE_KEY, type ThemePreference, type UseThemeResult, cn, getThemePreference, initTheme, renderMarkdown, resolveTheme, sanitizeHref, sanitizeHtml, setThemePreference, subscribeTheme, useAnimation, useControllableState, useEscapeKey, useFloatingPosition, useFocusTrap, useId, useNodeRegistry, useOutsideClick, usePanZoom, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ export { TimeGrid } from './chunk-7CN7IHES.js';
|
|
|
19
19
|
export { TimePicker } from './chunk-OTCLBINT.js';
|
|
20
20
|
export { Timeline } from './chunk-7JDVCQXD.js';
|
|
21
21
|
export { Toast, useToast } from './chunk-3AQLEMH7.js';
|
|
22
|
-
export { ReasonTag } from './chunk-
|
|
22
|
+
export { ReasonTag } from './chunk-UDEEPMQ4.js';
|
|
23
23
|
export { Section } from './chunk-SLJD25VV.js';
|
|
24
24
|
export { Separator } from './chunk-ZLWCZV7R.js';
|
|
25
25
|
export { Sidebar, useSidebar } from './chunk-YD4SXA6K.js';
|
|
@@ -31,7 +31,7 @@ export { Pillbox } from './chunk-FSRPZYZZ.js';
|
|
|
31
31
|
export { Popover, usePopover } from './chunk-6KXAFP2T.js';
|
|
32
32
|
export { Profile } from './chunk-KQQA7JBC.js';
|
|
33
33
|
export { Progress } from './chunk-P7PKK5BO.js';
|
|
34
|
-
export { PromptInput, browserPlatformHints, detectPlatform, modifierKeyLabel } from './chunk-
|
|
34
|
+
export { PromptInput, browserPlatformHints, detectPlatform, modifierKeyLabel } from './chunk-XBC3M4BL.js';
|
|
35
35
|
export { PullQuote } from './chunk-NDUEPDNS.js';
|
|
36
36
|
export { QrCode, encodeQr, selectMode } from './chunk-RLE5WYY6.js';
|
|
37
37
|
export { MobileMenu, useMobileMenu } from './chunk-P7F32HIH.js';
|
|
@@ -41,39 +41,39 @@ export { Navbar, useNavbar } from './chunk-IWXP2YUP.js';
|
|
|
41
41
|
export { OtpInput } from './chunk-XDJSFGXW.js';
|
|
42
42
|
export { Pagination } from './chunk-YF2EHBTV.js';
|
|
43
43
|
export { InputTag, contentEditableAdapter, controlledAdapter, inputAdapter, textareaAdapter } from './chunk-Q7O5TLVU.js';
|
|
44
|
-
export { JSON_FIELD_TYPES, JsonEditor, applyJsonEdit, describeEdit, findJsonConflicts, getAtPath, inferType, parseKeyMap, parsePath, pathToString, resolveKeyRule, typeMatches } from './chunk-
|
|
44
|
+
export { JSON_FIELD_TYPES, JsonEditor, applyJsonEdit, describeEdit, findJsonConflicts, getAtPath, inferType, parseKeyMap, parsePath, pathToString, resolveKeyRule, typeMatches } from './chunk-7MJ7VEKE.js';
|
|
45
45
|
export { Input } from './chunk-EEWRLFTI.js';
|
|
46
46
|
export { Select } from './chunk-IECPLOSZ.js';
|
|
47
47
|
export { Switch } from './chunk-NBAHXZHJ.js';
|
|
48
48
|
export { DatePicker } from './chunk-OC75GWX5.js';
|
|
49
49
|
export { Kanban, useKanban } from './chunk-O6E2WC3J.js';
|
|
50
50
|
export { Kbd } from './chunk-TJJ63UJV.js';
|
|
51
|
-
export { MagicWand } from './chunk-
|
|
51
|
+
export { MagicWand } from './chunk-FU6R6BZ4.js';
|
|
52
52
|
export { Textarea } from './chunk-DEFGT75G.js';
|
|
53
53
|
import './chunk-PWEZCMIY.js';
|
|
54
54
|
export { DisplayValue } from './chunk-KKWNKBKR.js';
|
|
55
55
|
export { Field } from './chunk-5MU6X3KO.js';
|
|
56
56
|
import './chunk-GFYSELJF.js';
|
|
57
57
|
export { Marquee } from './chunk-RSLZL6VP.js';
|
|
58
|
-
export { MediaViewer, resolveMediaType } from './chunk-
|
|
58
|
+
export { MediaViewer, resolveMediaType } from './chunk-YOTCZUNW.js';
|
|
59
59
|
export { VideoViewer } from './chunk-VOGI7GX3.js';
|
|
60
|
-
export { PdfViewer } from './chunk-
|
|
60
|
+
export { PdfViewer } from './chunk-VB3QJ6QE.js';
|
|
61
61
|
export { Menu, useMenu } from './chunk-RA2VOQ46.js';
|
|
62
62
|
export { FileBrowser, FileBrowserNewFolder, useFileBrowser, validateFolderName } from './chunk-2KAJ4L7C.js';
|
|
63
63
|
export { FileUpload, useFileUpload } from './chunk-W6RDAZJC.js';
|
|
64
64
|
export { Grid } from './chunk-TM3RTWKI.js';
|
|
65
65
|
import './chunk-CFH6CJQG.js';
|
|
66
|
-
export { ImageViewer } from './chunk-
|
|
67
|
-
export { FauxClient } from './chunk-
|
|
66
|
+
export { ImageViewer } from './chunk-ASS6EWNI.js';
|
|
67
|
+
export { FauxClient } from './chunk-XZUGREDI.js';
|
|
68
68
|
export { IndexList } from './chunk-UKUNWGL5.js';
|
|
69
69
|
import './chunk-AUTW5O4W.js';
|
|
70
70
|
export { ContextMenu, useContextMenu } from './chunk-SWBF2BXA.js';
|
|
71
71
|
export { Drawer, useDrawer } from './chunk-VFIVF5YO.js';
|
|
72
72
|
export { Dropdown, useDropdown } from './chunk-YQJWD53X.js';
|
|
73
|
-
export { Editor, useEditor } from './chunk-
|
|
73
|
+
export { Editor, useEditor } from './chunk-PCTZNK2Z.js';
|
|
74
74
|
export { THEME_STORAGE_KEY, getThemePreference, initTheme, resolveTheme, setThemePreference, subscribeTheme, useId, useNodeRegistry, useTheme } from './chunk-FWCREAIT.js';
|
|
75
75
|
export { usePanZoom } from './chunk-CPY7NHXM.js';
|
|
76
|
-
export { ContentRenderer, registerExtension, registerExtensions } from './chunk-
|
|
76
|
+
export { ContentRenderer, registerExtension, registerExtensions, renderMarkdown } from './chunk-K6EJLBBQ.js';
|
|
77
77
|
export { Emoji } from './chunk-YTMQ2K64.js';
|
|
78
78
|
export { EmojiSelect } from './chunk-VYHZEQIG.js';
|
|
79
79
|
export { Eyebrow } from './chunk-Y4UPKJN5.js';
|
|
@@ -97,8 +97,8 @@ export { Badge } from './chunk-6FCQD2KQ.js';
|
|
|
97
97
|
export { Brand, BrandMark } from './chunk-FCSR2WVS.js';
|
|
98
98
|
export { Breadcrumbs } from './chunk-TDDWWAM5.js';
|
|
99
99
|
import './chunk-LQ4ICCN2.js';
|
|
100
|
-
export { Action, Button } from './chunk-
|
|
101
|
-
export { sanitizeHref, sanitizeHtml } from './chunk-
|
|
100
|
+
export { Action, Button } from './chunk-KODD54GT.js';
|
|
101
|
+
export { sanitizeHref, sanitizeHtml } from './chunk-6TBRBN7H.js';
|
|
102
102
|
export { EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, SKIN_TONES, applyTone, find, hasSkinTones, resolve, search, skinTones } from './chunk-45BBNJQD.js';
|
|
103
103
|
export { Icon, configureIcons, registerIconAddendum, registerIconSet, registerIcons } from './chunk-IVRYSSM7.js';
|
|
104
104
|
export { Calendar } from './chunk-NTMHP7FS.js';
|
package/dist/json-editor.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkVWBKFQQN_cjs = require('./chunk-VWBKFQQN.cjs');
|
|
4
4
|
require('./chunk-2QIGXSSZ.cjs');
|
|
5
5
|
require('./chunk-AR3JOPGT.cjs');
|
|
6
6
|
require('./chunk-Y52NXM73.cjs');
|
|
@@ -14,8 +14,8 @@ require('./chunk-BVRPDMB7.cjs');
|
|
|
14
14
|
require('./chunk-MSRYJETY.cjs');
|
|
15
15
|
require('./chunk-X7H75WVP.cjs');
|
|
16
16
|
require('./chunk-MOU6O324.cjs');
|
|
17
|
-
require('./chunk-
|
|
18
|
-
require('./chunk-
|
|
17
|
+
require('./chunk-FWA4PCW7.cjs');
|
|
18
|
+
require('./chunk-X2FC7ODX.cjs');
|
|
19
19
|
require('./chunk-XCZZVRBY.cjs');
|
|
20
20
|
require('./chunk-QKFOJKVE.cjs');
|
|
21
21
|
require('./chunk-LCNHEYIM.cjs');
|
|
@@ -33,47 +33,47 @@ require('./chunk-ZU5Q77OT.cjs');
|
|
|
33
33
|
|
|
34
34
|
Object.defineProperty(exports, "JsonEditor", {
|
|
35
35
|
enumerable: true,
|
|
36
|
-
get: function () { return
|
|
36
|
+
get: function () { return chunkVWBKFQQN_cjs.JsonEditor; }
|
|
37
37
|
});
|
|
38
38
|
Object.defineProperty(exports, "applyJsonEdit", {
|
|
39
39
|
enumerable: true,
|
|
40
|
-
get: function () { return
|
|
40
|
+
get: function () { return chunkVWBKFQQN_cjs.applyJsonEdit; }
|
|
41
41
|
});
|
|
42
42
|
Object.defineProperty(exports, "describeEdit", {
|
|
43
43
|
enumerable: true,
|
|
44
|
-
get: function () { return
|
|
44
|
+
get: function () { return chunkVWBKFQQN_cjs.describeEdit; }
|
|
45
45
|
});
|
|
46
46
|
Object.defineProperty(exports, "findJsonConflicts", {
|
|
47
47
|
enumerable: true,
|
|
48
|
-
get: function () { return
|
|
48
|
+
get: function () { return chunkVWBKFQQN_cjs.findJsonConflicts; }
|
|
49
49
|
});
|
|
50
50
|
Object.defineProperty(exports, "getAtPath", {
|
|
51
51
|
enumerable: true,
|
|
52
|
-
get: function () { return
|
|
52
|
+
get: function () { return chunkVWBKFQQN_cjs.getAtPath; }
|
|
53
53
|
});
|
|
54
54
|
Object.defineProperty(exports, "inferType", {
|
|
55
55
|
enumerable: true,
|
|
56
|
-
get: function () { return
|
|
56
|
+
get: function () { return chunkVWBKFQQN_cjs.inferType; }
|
|
57
57
|
});
|
|
58
58
|
Object.defineProperty(exports, "parseKeyMap", {
|
|
59
59
|
enumerable: true,
|
|
60
|
-
get: function () { return
|
|
60
|
+
get: function () { return chunkVWBKFQQN_cjs.parseKeyMap; }
|
|
61
61
|
});
|
|
62
62
|
Object.defineProperty(exports, "parsePath", {
|
|
63
63
|
enumerable: true,
|
|
64
|
-
get: function () { return
|
|
64
|
+
get: function () { return chunkVWBKFQQN_cjs.parsePath; }
|
|
65
65
|
});
|
|
66
66
|
Object.defineProperty(exports, "pathToString", {
|
|
67
67
|
enumerable: true,
|
|
68
|
-
get: function () { return
|
|
68
|
+
get: function () { return chunkVWBKFQQN_cjs.pathToString; }
|
|
69
69
|
});
|
|
70
70
|
Object.defineProperty(exports, "resolveKeyRule", {
|
|
71
71
|
enumerable: true,
|
|
72
|
-
get: function () { return
|
|
72
|
+
get: function () { return chunkVWBKFQQN_cjs.resolveKeyRule; }
|
|
73
73
|
});
|
|
74
74
|
Object.defineProperty(exports, "typeMatches", {
|
|
75
75
|
enumerable: true,
|
|
76
|
-
get: function () { return
|
|
76
|
+
get: function () { return chunkVWBKFQQN_cjs.typeMatches; }
|
|
77
77
|
});
|
|
78
78
|
//# sourceMappingURL=json-editor.cjs.map
|
|
79
79
|
//# sourceMappingURL=json-editor.cjs.map
|
package/dist/json-editor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { JsonEditor, applyJsonEdit, describeEdit, findJsonConflicts, getAtPath, inferType, parseKeyMap, parsePath, pathToString, resolveKeyRule, typeMatches } from './chunk-
|
|
1
|
+
export { JsonEditor, applyJsonEdit, describeEdit, findJsonConflicts, getAtPath, inferType, parseKeyMap, parsePath, pathToString, resolveKeyRule, typeMatches } from './chunk-7MJ7VEKE.js';
|
|
2
2
|
import './chunk-EEWRLFTI.js';
|
|
3
3
|
import './chunk-IECPLOSZ.js';
|
|
4
4
|
import './chunk-NBAHXZHJ.js';
|
|
@@ -12,8 +12,8 @@ import './chunk-F2GAZZVS.js';
|
|
|
12
12
|
import './chunk-KYZNCVRD.js';
|
|
13
13
|
import './chunk-CF5KRDN4.js';
|
|
14
14
|
import './chunk-6FCQD2KQ.js';
|
|
15
|
-
import './chunk-
|
|
16
|
-
import './chunk-
|
|
15
|
+
import './chunk-KODD54GT.js';
|
|
16
|
+
import './chunk-6TBRBN7H.js';
|
|
17
17
|
import './chunk-45BBNJQD.js';
|
|
18
18
|
import './chunk-IVRYSSM7.js';
|
|
19
19
|
import './chunk-ZXZJYVWP.js';
|
package/dist/magic-wand.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkNAQJF3G6_cjs = require('./chunk-NAQJF3G6.cjs');
|
|
4
4
|
require('./chunk-V6VFSX6V.cjs');
|
|
5
5
|
require('./chunk-7EZBMGEE.cjs');
|
|
6
6
|
require('./chunk-XKDW6B7X.cjs');
|
|
@@ -9,8 +9,8 @@ require('./chunk-YLGTDBB2.cjs');
|
|
|
9
9
|
require('./chunk-VBWRH4UW.cjs');
|
|
10
10
|
require('./chunk-MOU6O324.cjs');
|
|
11
11
|
require('./chunk-M5MUGSON.cjs');
|
|
12
|
-
require('./chunk-
|
|
13
|
-
require('./chunk-
|
|
12
|
+
require('./chunk-FWA4PCW7.cjs');
|
|
13
|
+
require('./chunk-X2FC7ODX.cjs');
|
|
14
14
|
require('./chunk-XCZZVRBY.cjs');
|
|
15
15
|
require('./chunk-QKFOJKVE.cjs');
|
|
16
16
|
require('./chunk-KJ22KE56.cjs');
|
|
@@ -21,7 +21,7 @@ require('./chunk-ZU5Q77OT.cjs');
|
|
|
21
21
|
|
|
22
22
|
Object.defineProperty(exports, "MagicWand", {
|
|
23
23
|
enumerable: true,
|
|
24
|
-
get: function () { return
|
|
24
|
+
get: function () { return chunkNAQJF3G6_cjs.MagicWand; }
|
|
25
25
|
});
|
|
26
26
|
//# sourceMappingURL=magic-wand.cjs.map
|
|
27
27
|
//# sourceMappingURL=magic-wand.cjs.map
|
package/dist/magic-wand.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { MagicWand } from './chunk-
|
|
1
|
+
export { MagicWand } from './chunk-FU6R6BZ4.js';
|
|
2
2
|
import './chunk-DEFGT75G.js';
|
|
3
3
|
import './chunk-PWEZCMIY.js';
|
|
4
4
|
import './chunk-KKWNKBKR.js';
|
|
@@ -7,8 +7,8 @@ import './chunk-GFYSELJF.js';
|
|
|
7
7
|
import './chunk-IQ4KQJAO.js';
|
|
8
8
|
import './chunk-6FCQD2KQ.js';
|
|
9
9
|
import './chunk-LQ4ICCN2.js';
|
|
10
|
-
import './chunk-
|
|
11
|
-
import './chunk-
|
|
10
|
+
import './chunk-KODD54GT.js';
|
|
11
|
+
import './chunk-6TBRBN7H.js';
|
|
12
12
|
import './chunk-45BBNJQD.js';
|
|
13
13
|
import './chunk-IVRYSSM7.js';
|
|
14
14
|
import './chunk-OL53XYHF.js';
|
package/dist/media-viewer.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkNCXH5O4I_cjs = require('./chunk-NCXH5O4I.cjs');
|
|
4
4
|
require('./chunk-TH7VP4CL.cjs');
|
|
5
|
-
require('./chunk-
|
|
6
|
-
require('./chunk-
|
|
7
|
-
require('./chunk-
|
|
5
|
+
require('./chunk-IYVV4RD3.cjs');
|
|
6
|
+
require('./chunk-2KZINS6D.cjs');
|
|
7
|
+
require('./chunk-RU6ZTA4M.cjs');
|
|
8
8
|
require('./chunk-T6YELZPJ.cjs');
|
|
9
9
|
require('./chunk-QW66UHWO.cjs');
|
|
10
10
|
require('./chunk-SNHU2AI4.cjs');
|
|
@@ -14,7 +14,7 @@ require('./chunk-ZU5Q77OT.cjs');
|
|
|
14
14
|
|
|
15
15
|
Object.defineProperty(exports, "MediaViewer", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkNCXH5O4I_cjs.MediaViewer; }
|
|
18
18
|
});
|
|
19
19
|
//# sourceMappingURL=media-viewer.cjs.map
|
|
20
20
|
//# sourceMappingURL=media-viewer.cjs.map
|
package/dist/media-viewer.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { MediaViewer } from './chunk-
|
|
1
|
+
export { MediaViewer } from './chunk-YOTCZUNW.js';
|
|
2
2
|
import './chunk-VOGI7GX3.js';
|
|
3
|
-
import './chunk-
|
|
4
|
-
import './chunk-
|
|
5
|
-
import './chunk-
|
|
3
|
+
import './chunk-VB3QJ6QE.js';
|
|
4
|
+
import './chunk-ASS6EWNI.js';
|
|
5
|
+
import './chunk-XZUGREDI.js';
|
|
6
6
|
import './chunk-CPY7NHXM.js';
|
|
7
7
|
import './chunk-UIJR26YW.js';
|
|
8
8
|
import './chunk-EDYAXGUM.js';
|
package/dist/pdf-viewer.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunkIYVV4RD3_cjs = require('./chunk-IYVV4RD3.cjs');
|
|
4
|
+
require('./chunk-RU6ZTA4M.cjs');
|
|
5
5
|
require('./chunk-SNHU2AI4.cjs');
|
|
6
6
|
require('./chunk-ZU5Q77OT.cjs');
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ require('./chunk-ZU5Q77OT.cjs');
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "PdfViewer", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunkIYVV4RD3_cjs.PdfViewer; }
|
|
13
13
|
});
|
|
14
14
|
//# sourceMappingURL=pdf-viewer.cjs.map
|
|
15
15
|
//# sourceMappingURL=pdf-viewer.cjs.map
|
package/dist/pdf-viewer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { PdfViewer } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { PdfViewer } from './chunk-VB3QJ6QE.js';
|
|
2
|
+
import './chunk-XZUGREDI.js';
|
|
3
3
|
import './chunk-EDYAXGUM.js';
|
|
4
4
|
import './chunk-MMW2JGKZ.js';
|
|
5
5
|
//# sourceMappingURL=pdf-viewer.js.map
|
package/dist/prompt-input.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkIPBEVSSC_cjs = require('./chunk-IPBEVSSC.cjs');
|
|
4
4
|
require('./chunk-AIA5UNQ5.cjs');
|
|
5
5
|
require('./chunk-MSRYJETY.cjs');
|
|
6
6
|
require('./chunk-X7H75WVP.cjs');
|
|
7
7
|
require('./chunk-M5MUGSON.cjs');
|
|
8
|
-
require('./chunk-
|
|
9
|
-
require('./chunk-
|
|
8
|
+
require('./chunk-FWA4PCW7.cjs');
|
|
9
|
+
require('./chunk-X2FC7ODX.cjs');
|
|
10
10
|
require('./chunk-XCZZVRBY.cjs');
|
|
11
11
|
require('./chunk-QKFOJKVE.cjs');
|
|
12
12
|
require('./chunk-J2DI6RMR.cjs');
|
|
@@ -18,7 +18,7 @@ require('./chunk-ZU5Q77OT.cjs');
|
|
|
18
18
|
|
|
19
19
|
Object.defineProperty(exports, "PromptInput", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkIPBEVSSC_cjs.PromptInput; }
|
|
22
22
|
});
|
|
23
23
|
//# sourceMappingURL=prompt-input.cjs.map
|
|
24
24
|
//# sourceMappingURL=prompt-input.cjs.map
|
package/dist/prompt-input.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { PromptInput } from './chunk-
|
|
1
|
+
export { PromptInput } from './chunk-XBC3M4BL.js';
|
|
2
2
|
import './chunk-TJ66S5K6.js';
|
|
3
3
|
import './chunk-KYZNCVRD.js';
|
|
4
4
|
import './chunk-CF5KRDN4.js';
|
|
5
5
|
import './chunk-LQ4ICCN2.js';
|
|
6
|
-
import './chunk-
|
|
7
|
-
import './chunk-
|
|
6
|
+
import './chunk-KODD54GT.js';
|
|
7
|
+
import './chunk-6TBRBN7H.js';
|
|
8
8
|
import './chunk-45BBNJQD.js';
|
|
9
9
|
import './chunk-IVRYSSM7.js';
|
|
10
10
|
import './chunk-MQ6VGG62.js';
|
package/dist/reason-tag.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkGCWIZNN2_cjs = require('./chunk-GCWIZNN2.cjs');
|
|
4
4
|
require('./chunk-WKNVZUWZ.cjs');
|
|
5
5
|
require('./chunk-M5MUGSON.cjs');
|
|
6
|
-
require('./chunk-
|
|
7
|
-
require('./chunk-
|
|
6
|
+
require('./chunk-FWA4PCW7.cjs');
|
|
7
|
+
require('./chunk-X2FC7ODX.cjs');
|
|
8
8
|
require('./chunk-XCZZVRBY.cjs');
|
|
9
9
|
require('./chunk-QKFOJKVE.cjs');
|
|
10
10
|
require('./chunk-J2DI6RMR.cjs');
|
|
@@ -17,7 +17,7 @@ require('./chunk-ZU5Q77OT.cjs');
|
|
|
17
17
|
|
|
18
18
|
Object.defineProperty(exports, "ReasonTag", {
|
|
19
19
|
enumerable: true,
|
|
20
|
-
get: function () { return
|
|
20
|
+
get: function () { return chunkGCWIZNN2_cjs.ReasonTag; }
|
|
21
21
|
});
|
|
22
22
|
//# sourceMappingURL=reason-tag.cjs.map
|
|
23
23
|
//# sourceMappingURL=reason-tag.cjs.map
|
package/dist/reason-tag.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { ReasonTag } from './chunk-
|
|
1
|
+
export { ReasonTag } from './chunk-UDEEPMQ4.js';
|
|
2
2
|
import './chunk-6KXAFP2T.js';
|
|
3
3
|
import './chunk-LQ4ICCN2.js';
|
|
4
|
-
import './chunk-
|
|
5
|
-
import './chunk-
|
|
4
|
+
import './chunk-KODD54GT.js';
|
|
5
|
+
import './chunk-6TBRBN7H.js';
|
|
6
6
|
import './chunk-45BBNJQD.js';
|
|
7
7
|
import './chunk-IVRYSSM7.js';
|
|
8
8
|
import './chunk-MQ6VGG62.js';
|
package/docs/ContentRenderer.md
CHANGED
|
@@ -91,3 +91,39 @@ registerExtension({
|
|
|
91
91
|
```tsx
|
|
92
92
|
<ContentRenderer value="# Title\n\nParagraph with **bold** text." format="markdown" />
|
|
93
93
|
```
|
|
94
|
+
|
|
95
|
+
## Markdown and sanitising without the component
|
|
96
|
+
|
|
97
|
+
`renderMarkdown(markdown, sanitize?)` returns the same HTML `ContentRenderer`
|
|
98
|
+
renders, already sanitised, so a host never imports the markdown parser itself.
|
|
99
|
+
|
|
100
|
+
`sanitizeHtml(html)` is a blocklist: it strips what can run (script, iframe,
|
|
101
|
+
event handlers, `javascript:` URLs, ...) and keeps the rest. Pass options and it
|
|
102
|
+
becomes an **allowlist** that keeps only what you list:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { renderMarkdown, sanitizeHtml, type SanitizeHtmlOptions } from "@particle-academy/react-fancy";
|
|
106
|
+
|
|
107
|
+
const CHAT_PROSE: SanitizeHtmlOptions = {
|
|
108
|
+
allowedTags: ["p", "br", "strong", "em", "a", "ul", "ol", "li", "code", "pre"],
|
|
109
|
+
allowedAttributes: ["href", "title"], // or { "*": ["title"], a: ["href"], span: ["data-*"] }
|
|
110
|
+
allowedSchemes: ["https:", "http:", "mailto:"], // the default
|
|
111
|
+
allowRelative: true, // /x, ../x, ?q, #frag; never //host. Default false
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
renderMarkdown(md, CHAT_PROSE); // same as sanitizeHtml(renderMarkdown(md), CHAT_PROSE)
|
|
115
|
+
sanitizeHtml(html, CHAT_PROSE);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
| Rule | Allowlist mode |
|
|
119
|
+
|------|----------------|
|
|
120
|
+
| Tag not listed | removed, its text and cleaned children kept |
|
|
121
|
+
| `script`, `style`, `iframe`, `frame(set)`, `object`, `embed`, `applet`, `link`, `meta`, `base`, `form`, `title`, `template`, `noscript`, `noembed`, `noframes`, `xmp`, `plaintext`, `svg`, `math` | removed WITH content, even when listed |
|
|
122
|
+
| Attribute not listed | removed |
|
|
123
|
+
| `on*`, `srcdoc`, `srcset` | removed, even when listed |
|
|
124
|
+
| URL attribute with an unlisted scheme | removed |
|
|
125
|
+
| `javascript:`, `vbscript:` | removed, even when listed |
|
|
126
|
+
| Comments | removed |
|
|
127
|
+
| No DOM (SSR) | input returned as escaped text (fails closed) |
|
|
128
|
+
|
|
129
|
+
The allowlist can only narrow: nothing you list widens past the blocklist.
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/FauxClient/FauxClient.tsx"],"names":["forwardRef","useRef","useState","useControllableState","useLayoutEffect","useEffect","useCallback","jsxs","cn","Fragment","jsx"],"mappings":"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","file":"chunk-DUOZSOSB.cjs","sourcesContent":["import { forwardRef, useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport type { FauxClientProps } from \"./FauxClient.types\";\n\nconst DOT_COLORS = [\"bg-rose-300\", \"bg-amber-300\", \"bg-green-300\"];\n\n/** One click of the zoom bar. Matches `ImageViewer`, so the kit zooms one way. */\nconst ZOOM_STEP = 1.25;\n\nconst clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n));\n\n/**\n * A frame that mimics a browser window or device, rendering **real UI** inside.\n * With a logical `width` + `scale=\"fit\"` it renders a full-size page/app and\n * scales it down to fit any container (live thumbnails, device mockups) — the\n * content is real and interactive, just zoomed.\n *\n * Omit `width` for chrome around natural-size content (e.g. a code/preview card).\n *\n * `controls` adds a zoom bar and a full-screen button, for content that has to be\n * READ rather than glanced at: a slide or a sheet shrunk to fit a panel.\n */\nexport const FauxClient = forwardRef<HTMLDivElement, FauxClientProps>(\n (\n {\n variant = \"browser\",\n url,\n meta,\n dots = true,\n width,\n scale = \"fit\",\n controls = false,\n zoom: controlledZoom,\n defaultZoom = 1,\n onZoomChange,\n minZoom = 0.5,\n maxZoom = 4,\n onFullscreenChange,\n fill = false,\n applyZoom = true,\n className,\n barClassName,\n bodyClassName,\n children,\n ...rest\n },\n ref,\n ) => {\n const scaled = typeof width === \"number\";\n const rootRef = useRef<HTMLDivElement | null>(null);\n const viewportRef = useRef<HTMLDivElement>(null);\n const stageRef = useRef<HTMLDivElement>(null);\n const [fit, setFit] = useState(typeof scale === \"number\" ? scale : 1);\n const [naturalHeight, setNaturalHeight] = useState<number | undefined>(undefined);\n\n const showZoom = controls === true || (typeof controls === \"object\" && controls.zoom !== false);\n const showFullscreen = controls === true || (typeof controls === \"object\" && controls.fullscreen !== false);\n const [zoom, setZoom] = useControllableState(controlledZoom, defaultZoom, onZoomChange);\n const [fullscreen, setFullscreen] = useState(false);\n\n useLayoutEffect(() => {\n if (!scaled) return;\n const viewport = viewportRef.current;\n const stage = stageRef.current;\n if (!viewport || !stage) return;\n if (typeof ResizeObserver === \"undefined\") return;\n\n const measure = () => {\n const avail = viewport.clientWidth;\n setFit(scale === \"fit\" ? (width && width > 0 ? avail / width : 1) : scale);\n // offsetHeight is the pre-transform layout height (CSS transforms don't affect it).\n setNaturalHeight(stage.offsetHeight);\n };\n\n measure();\n const ro = new ResizeObserver(measure);\n ro.observe(viewport);\n ro.observe(stage);\n return () => ro.disconnect();\n }, [scaled, scale, width]);\n\n // Full screen is the browser's state, not ours: follow it, so Esc and the\n // browser's own exit leave the button telling the truth.\n useEffect(() => {\n if (!showFullscreen || typeof document === \"undefined\") return;\n const sync = () => {\n const on = document.fullscreenElement != null && document.fullscreenElement === rootRef.current;\n setFullscreen(on);\n onFullscreenChange?.(on);\n };\n document.addEventListener(\"fullscreenchange\", sync);\n return () => document.removeEventListener(\"fullscreenchange\", sync);\n }, [showFullscreen, onFullscreenChange]);\n\n const toggleFullscreen = useCallback(() => {\n const el = rootRef.current;\n if (!el || typeof document === \"undefined\") return;\n if (document.fullscreenElement === el) void document.exitFullscreen?.();\n else void el.requestFullscreen?.();\n }, []);\n\n const zoomBy = (factor: number) => {\n // Rounded so ten clicks in and ten out land back on 100%, not 99.99%.\n setZoom(clamp(Math.round(zoom * factor * 100) / 100, minZoom, maxZoom));\n };\n\n const setRefs = (el: HTMLDivElement | null) => {\n rootRef.current = el;\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n };\n\n const isBrowser = variant === \"browser\";\n const isDevice = variant === \"device\";\n // The zoom the FRAME applies: none when the content zooms itself.\n const appliedZoom = applyZoom ? zoom : 1;\n const effective = fit * appliedZoom;\n const zoomed = appliedZoom !== 1;\n const hasControls = showZoom || showFullscreen;\n\n /*\n * Out of the way until wanted: hidden, and revealed when the pointer is over\n * the frame or focus is inside it (keyboard). Always shown where there is no\n * hover to reveal it (touch), or it could never be reached.\n *\n * In the browser chrome it sits in the address bar, inline. On a device or a\n * bare frame there is no chrome, so it floats top-right as a slim strip: the\n * bottom corners belong to the content (a slide viewer's page count lives\n * there).\n */\n const controlsBar = hasControls ? (\n <div\n data-react-fancy-faux-client-controls=\"\"\n className={cn(\n \"pointer-events-auto flex shrink-0 items-center gap-px opacity-0 transition-opacity duration-150\",\n \"group-hover/faux-client:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100\",\n isBrowser\n ? \"-my-1 text-zinc-400 dark:text-zinc-500\"\n : \"rounded-full bg-zinc-900/60 px-1 py-0.5 text-white/80 shadow-sm backdrop-blur-sm\",\n )}\n >\n {showZoom && (\n <>\n <button\n type=\"button\"\n data-react-fancy-faux-client-zoom-out=\"\"\n aria-label=\"Zoom out\"\n title=\"Zoom out\"\n disabled={zoom <= minZoom}\n onClick={() => zoomBy(1 / ZOOM_STEP)}\n className={controlButton(isBrowser)}\n >\n <ZoomOutIcon />\n </button>\n <button\n type=\"button\"\n data-react-fancy-faux-client-zoom-reset=\"\"\n aria-label=\"Reset zoom\"\n title=\"Reset zoom\"\n onClick={() => setZoom(1)}\n className={cn(controlButton(isBrowser), \"w-auto min-w-[2.25rem] px-1 font-sans text-[10.5px] tabular-nums\")}\n >\n {Math.round(zoom * 100)}%\n </button>\n <button\n type=\"button\"\n data-react-fancy-faux-client-zoom-in=\"\"\n aria-label=\"Zoom in\"\n title=\"Zoom in\"\n disabled={zoom >= maxZoom}\n onClick={() => zoomBy(ZOOM_STEP)}\n className={controlButton(isBrowser)}\n >\n <ZoomInIcon />\n </button>\n </>\n )}\n {showFullscreen && (\n <button\n type=\"button\"\n data-react-fancy-faux-client-fullscreen=\"\"\n aria-label={fullscreen ? \"Exit full screen\" : \"Full screen\"}\n aria-pressed={fullscreen}\n title={fullscreen ? \"Exit full screen\" : \"Full screen\"}\n onClick={toggleFullscreen}\n className={controlButton(isBrowser)}\n >\n {fullscreen ? <ExitFullscreenIcon /> : <FullscreenIcon />}\n </button>\n )}\n </div>\n ) : null;\n\n return (\n <div\n ref={setRefs}\n data-react-fancy-faux-client=\"\"\n data-fullscreen={showFullscreen ? String(fullscreen) : undefined}\n className={cn(\n \"group/faux-client relative overflow-hidden bg-white dark:bg-zinc-900\",\n isBrowser && \"rounded-2xl border border-zinc-200 shadow-xl dark:border-zinc-800\",\n isDevice && \"rounded-[2rem] border-[10px] border-zinc-800 shadow-2xl dark:border-zinc-700\",\n variant === \"bare\" && \"rounded-lg border border-zinc-200 dark:border-zinc-800\",\n // Fill (or full screen): the frame takes its parent's height and its\n // body takes whatever the chrome leaves.\n (fill || fullscreen) && \"flex flex-col\",\n fill && \"h-full\",\n fullscreen && \"rounded-none\",\n className,\n )}\n {...rest}\n >\n {isBrowser && (\n <div\n className={cn(\n \"flex items-center gap-2 border-b border-zinc-200 bg-zinc-50 px-3.5 py-2.5 font-mono text-[11.5px] text-zinc-500 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-400\",\n barClassName,\n )}\n >\n {dots && (\n <div className=\"mr-1.5 flex gap-[5px]\">\n {DOT_COLORS.map((color, i) => (\n <span key={i} className={cn(\"h-[9px] w-[9px] rounded-full\", color)} />\n ))}\n </div>\n )}\n {url != null && <span className=\"min-w-0 flex-1 truncate\">{url}</span>}\n {meta != null && <span className=\"shrink-0 text-zinc-400 dark:text-zinc-500\">{meta}</span>}\n {hasControls && <div className={cn(url == null && meta == null && \"ml-auto\")}>{controlsBar}</div>}\n </div>\n )}\n\n <div\n ref={viewportRef}\n className={cn(\n \"relative\",\n // Zoomed in, the content is bigger than the frame: scroll to it.\n zoomed ? \"overflow-auto\" : \"overflow-hidden\",\n (fill || fullscreen) && \"min-h-0 flex-1\",\n bodyClassName,\n )}\n // The frame keeps its FIT height whatever the zoom; zooming scrolls.\n style={scaled && !fullscreen && naturalHeight !== undefined ? { height: naturalHeight * fit } : undefined}\n >\n {scaled ? (\n // A sizer the size of the zoomed content, so the scrollbars are right.\n <div\n style={\n naturalHeight !== undefined && width !== undefined\n ? { width: width * effective, height: naturalHeight * effective, position: \"relative\" }\n : undefined\n }\n >\n <div\n ref={stageRef}\n data-react-fancy-faux-client-content=\"\"\n className=\"absolute left-0 top-0 origin-top-left\"\n style={{ width, transform: `scale(${effective})` }}\n >\n {children}\n </div>\n </div>\n ) : (\n <div\n data-react-fancy-faux-client-content=\"\"\n className={cn((fill || fullscreen) && \"h-full\")}\n // CSS `zoom` rather than a transform: it changes layout size, so the\n // content reflows and the viewport scrolls to all of it.\n style={zoomed ? { zoom: String(appliedZoom) } : undefined}\n >\n {children}\n </div>\n )}\n </div>\n\n {hasControls && !isBrowser && (\n <div className=\"pointer-events-none absolute right-2 top-2 z-10\">{controlsBar}</div>\n )}\n </div>\n );\n },\n);\n\nFauxClient.displayName = \"FauxClient\";\n\n/** Ghost icon buttons: no box of their own, so the bar reads as part of the frame. */\nfunction controlButton(inBar: boolean): string {\n return cn(\n \"flex h-6 w-6 items-center justify-center rounded-full transition-colors disabled:pointer-events-none disabled:opacity-30\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/50\",\n inBar\n ? \"hover:bg-zinc-900/5 hover:text-zinc-700 dark:hover:bg-white/10 dark:hover:text-zinc-200\"\n : \"hover:bg-white/15 hover:text-white\",\n );\n}\n\nfunction ZoomOutIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n <path d=\"M8 11h6\" />\n </svg>\n );\n}\n\nfunction ZoomInIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n <path d=\"M8 11h6\" />\n <path d=\"M11 8v6\" />\n </svg>\n );\n}\n\n/** Inline, like `Input`'s reveal icons: a frame should not need an icon set configured. */\nfunction FullscreenIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M8 3H5a2 2 0 0 0-2 2v3\" />\n <path d=\"M21 8V5a2 2 0 0 0-2-2h-3\" />\n <path d=\"M3 16v3a2 2 0 0 0 2 2h3\" />\n <path d=\"M16 21h3a2 2 0 0 0 2-2v-3\" />\n </svg>\n );\n}\n\nfunction ExitFullscreenIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M8 3v3a2 2 0 0 1-2 2H3\" />\n <path d=\"M21 8h-3a2 2 0 0 1-2-2V3\" />\n <path d=\"M3 16h3a2 2 0 0 1 2 2v3\" />\n <path d=\"M16 21v-3a2 2 0 0 1 2-2h3\" />\n </svg>\n );\n}\n"]}
|