@clicktap/ui 0.15.2 → 0.16.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/components/AssetRenderer/AssetRenderer.d.ts +74 -0
- package/components/AssetRenderer/AssetRenderer.js +1 -0
- package/components/AssetRenderer/index.d.ts +2 -0
- package/components/AssetRenderer/index.js +1 -0
- package/components/AssetRenderer/renderers/AudioRenderer.d.ts +50 -0
- package/components/AssetRenderer/renderers/AudioRenderer.js +1 -0
- package/components/AssetRenderer/renderers/DownloadLink.d.ts +40 -0
- package/components/AssetRenderer/renderers/DownloadLink.js +1 -0
- package/components/AssetRenderer/renderers/ImageRenderer.d.ts +32 -0
- package/components/AssetRenderer/renderers/ImageRenderer.js +1 -0
- package/components/AssetRenderer/renderers/PdfRenderer.d.ts +67 -0
- package/components/AssetRenderer/renderers/PdfRenderer.js +1 -0
- package/components/AssetRenderer/renderers/VideoRenderer.d.ts +61 -0
- package/components/AssetRenderer/renderers/VideoRenderer.js +1 -0
- package/components/AssetRenderer/renderers/index.d.ts +5 -0
- package/components/AssetRenderer/renderers/index.js +1 -0
- package/components/Collapsible/CollapsibleTrigger.js +1 -1
- package/components/FeatureGate/AccessDenied.d.ts +37 -0
- package/components/FeatureGate/AccessDenied.js +1 -0
- package/components/FeatureGate/FeatureGate.d.ts +62 -0
- package/components/FeatureGate/FeatureGate.js +1 -0
- package/components/FeatureGate/PermissionRequired.d.ts +32 -0
- package/components/FeatureGate/PermissionRequired.js +1 -0
- package/components/FeatureGate/PermissionsProvider.d.ts +61 -0
- package/components/FeatureGate/PermissionsProvider.js +1 -0
- package/components/FeatureGate/UpgradePrompt.d.ts +46 -0
- package/components/FeatureGate/UpgradePrompt.js +1 -0
- package/components/FeatureGate/index.d.ts +5 -0
- package/components/FeatureGate/index.js +1 -0
- package/components/Icon/ArrowLeftIcon.d.ts +7 -0
- package/components/Icon/ArrowLeftIcon.js +1 -0
- package/components/Icon/CloseIcon.d.ts +7 -0
- package/components/Icon/CloseIcon.js +1 -0
- package/components/Icon/CreateIcon.d.ts +7 -0
- package/components/Icon/CreateIcon.js +1 -0
- package/components/Icon/DeleteIcon.d.ts +7 -0
- package/components/Icon/DeleteIcon.js +1 -0
- package/components/Icon/GemIcon.d.ts +7 -0
- package/components/Icon/GemIcon.js +1 -0
- package/components/Icon/IncludedIcon.d.ts +11 -0
- package/components/Icon/IncludedIcon.js +1 -0
- package/components/Icon/InfoIcon.d.ts +7 -0
- package/components/Icon/InfoIcon.js +1 -0
- package/components/Icon/InvoiceIcon.d.ts +7 -0
- package/components/Icon/InvoiceIcon.js +1 -0
- package/components/Icon/LockIcon.d.ts +7 -0
- package/components/Icon/LockIcon.js +1 -0
- package/components/Icon/NoEntryIcon.d.ts +7 -0
- package/components/Icon/NoEntryIcon.js +1 -0
- package/components/Icon/NoteIcon.d.ts +7 -0
- package/components/Icon/NoteIcon.js +1 -0
- package/components/Icon/PencilIcon.d.ts +7 -0
- package/components/Icon/PencilIcon.js +1 -0
- package/components/Icon/PermissionIcon.d.ts +7 -0
- package/components/Icon/PermissionIcon.js +1 -0
- package/components/Icon/ProductBoxIcon.d.ts +7 -0
- package/components/Icon/ProductBoxIcon.js +1 -0
- package/components/Icon/ProductIcon.d.ts +7 -0
- package/components/Icon/ProductIcon.js +1 -0
- package/components/Icon/QuoteIcon.d.ts +7 -0
- package/components/Icon/QuoteIcon.js +1 -0
- package/components/Icon/ResetPasswordIcon.d.ts +7 -0
- package/components/Icon/ResetPasswordIcon.js +1 -0
- package/components/Icon/RoleIcon.d.ts +7 -0
- package/components/Icon/RoleIcon.js +1 -0
- package/components/Icon/ShieldUserIcon.d.ts +7 -0
- package/components/Icon/ShieldUserIcon.js +1 -0
- package/components/Icon/SyncIcon.d.ts +6 -0
- package/components/Icon/SyncIcon.js +1 -0
- package/components/Icon/UpdateIcon.d.ts +7 -0
- package/components/Icon/UpdateIcon.js +1 -0
- package/components/Icon/UserEditIcon.d.ts +7 -0
- package/components/Icon/UserEditIcon.js +1 -0
- package/components/Icon/UserIcon.d.ts +7 -0
- package/components/Icon/UserIcon.js +1 -0
- package/components/Icon/index.d.ts +23 -0
- package/components/Icon/index.js +1 -1
- package/components/Image/Image.d.ts +1 -1
- package/components/Image/Image.js +1 -1
- package/components/Radio/Radio.js +1 -1
- package/components/Select/Select.js +1 -1
- package/hooks/useAssetDownload.d.ts +14 -0
- package/hooks/useAssetDownload.js +1 -0
- package/package.json +2 -1
- package/utils/asset-url.d.ts +69 -0
- package/utils/asset-url.js +1 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface AssetRendererProps {
|
|
3
|
+
/** Asset UUID */
|
|
4
|
+
uuid: string;
|
|
5
|
+
/** Asset mime type (e.g., 'image/png', 'application/pdf') */
|
|
6
|
+
mimeType: string;
|
|
7
|
+
/** Asset name for display and accessibility */
|
|
8
|
+
name: string;
|
|
9
|
+
/** Optional filename for URL */
|
|
10
|
+
filename?: string;
|
|
11
|
+
/** Optional specific version */
|
|
12
|
+
version?: number;
|
|
13
|
+
/** JWT token for authenticated access */
|
|
14
|
+
token?: string;
|
|
15
|
+
/** Custom className for the container */
|
|
16
|
+
className?: string;
|
|
17
|
+
/** Alt text for images (defaults to name) */
|
|
18
|
+
alt?: string;
|
|
19
|
+
/** Custom renderers by mime type pattern */
|
|
20
|
+
renderers?: Partial<Record<MimeCategory, AssetRendererFunction>>;
|
|
21
|
+
/** Fallback renderer for unknown types */
|
|
22
|
+
fallback?: AssetRendererFunction;
|
|
23
|
+
}
|
|
24
|
+
export type MimeCategory = 'image' | 'video' | 'audio' | 'pdf' | 'text' | 'unknown';
|
|
25
|
+
export interface AssetRenderContext {
|
|
26
|
+
uuid: string;
|
|
27
|
+
url: string;
|
|
28
|
+
mimeType: string;
|
|
29
|
+
name: string;
|
|
30
|
+
filename?: string;
|
|
31
|
+
version?: number;
|
|
32
|
+
token?: string;
|
|
33
|
+
className?: string;
|
|
34
|
+
alt?: string;
|
|
35
|
+
}
|
|
36
|
+
export type AssetRendererFunction = (context: AssetRenderContext) => ReactNode;
|
|
37
|
+
/**
|
|
38
|
+
* Renders an asset based on its mime type.
|
|
39
|
+
*
|
|
40
|
+
* Supports images, videos, audio, PDFs, and text files out of the box.
|
|
41
|
+
* Unknown types render as download links.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Basic image
|
|
45
|
+
* <AssetRenderer
|
|
46
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
47
|
+
* mimeType="image/png"
|
|
48
|
+
* name="Company Logo"
|
|
49
|
+
* />
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // PDF with custom class
|
|
53
|
+
* <AssetRenderer
|
|
54
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
55
|
+
* mimeType="application/pdf"
|
|
56
|
+
* name="Annual Report"
|
|
57
|
+
* className="w-full h-[600px]"
|
|
58
|
+
* />
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // With custom renderer for images
|
|
62
|
+
* <AssetRenderer
|
|
63
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
64
|
+
* mimeType="image/png"
|
|
65
|
+
* name="Product Image"
|
|
66
|
+
* renderers={{
|
|
67
|
+
* image: ({ url, alt }) => (
|
|
68
|
+
* <NextImage src={url} alt={alt} width={300} height={200} />
|
|
69
|
+
* ),
|
|
70
|
+
* }}
|
|
71
|
+
* />
|
|
72
|
+
*/
|
|
73
|
+
export declare function AssetRenderer({ uuid, mimeType, name, filename, version, token, className, alt, renderers, fallback, }: AssetRendererProps): ReactNode;
|
|
74
|
+
export default AssetRenderer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as s}from"react/jsx-runtime";import{getAssetUrl as p}from"../../utils/asset-url.js";import{AudioRenderer as x}from"./renderers/AudioRenderer.js";import{DownloadLink as h}from"./renderers/DownloadLink.js";import{ImageRenderer as A}from"./renderers/ImageRenderer.js";import{PdfRenderer as W}from"./renderers/PdfRenderer.js";import{VideoRenderer as k}from"./renderers/VideoRenderer.js";function w(t){return t.startsWith("image/")?"image":t.startsWith("video/")?"video":t.startsWith("audio/")?"audio":t==="application/pdf"?"pdf":t.startsWith("text/")?"text":"unknown"}const v=({uuid:t,alt:r,name:e,version:o,filename:n,token:d,className:i})=>s(A,{uuid:t,alt:r??e,version:o,filename:n,token:d,className:i,loading:"lazy"}),I=({uuid:t,mimeType:r,name:e,version:o,filename:n,token:d,className:i})=>s(k,{uuid:t,mimeType:r,title:e,version:o,filename:n,token:d,className:i,controls:!0}),O=({uuid:t,mimeType:r,name:e,version:o,filename:n,token:d,className:i})=>s(x,{uuid:t,mimeType:r,title:e,version:o,filename:n,token:d,className:i,controls:!0}),P=({uuid:t,name:r,version:e,filename:o,token:n,className:d})=>s(W,{uuid:t,title:r,version:e,filename:o,token:n,className:d}),V=({url:t,name:r,className:e})=>s("iframe",{src:t,title:r,className:e}),l=({uuid:t,name:r,version:e,filename:o,token:n,className:d})=>s(h,{uuid:t,name:r,version:e,filename:o,token:n,className:d}),b={image:v,video:I,audio:O,pdf:P,text:V,unknown:l};function B({uuid:t,mimeType:r,name:e,filename:o,version:n,token:d,className:i,alt:c,renderers:R={},fallback:m}){const g=p(t,{version:n,filename:o,token:d}),a=w(r),u={uuid:t,url:g,mimeType:r,name:e,filename:o,version:n,token:d,className:i,alt:c},f=R[a];return f?f(u):(b[a]??m??l)(u)}export{B as AssetRenderer,B as default};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { AssetRenderer, type AssetRendererProps, type AssetRenderContext, type AssetRendererFunction, type MimeCategory, } from './AssetRenderer';
|
|
2
|
+
export { AudioRenderer, type AudioRendererProps, DownloadLink, type DownloadLinkProps, ImageRenderer, type ImageRendererProps, PdfRenderer, type PdfRendererProps, type PdfViewerOptions, VideoRenderer, type VideoRendererProps, } from './renderers';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AssetRenderer as m}from"./AssetRenderer.js";import{AudioRenderer as p}from"./renderers/AudioRenderer.js";import{DownloadLink as n}from"./renderers/DownloadLink.js";import{ImageRenderer as i}from"./renderers/ImageRenderer.js";import{PdfRenderer as a}from"./renderers/PdfRenderer.js";import{VideoRenderer as A}from"./renderers/VideoRenderer.js";import"react/jsx-runtime";import"../../utils/asset-url.js";export{m as AssetRenderer,p as AudioRenderer,n as DownloadLink,i as ImageRenderer,a as PdfRenderer,A as VideoRenderer};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface AudioRendererProps {
|
|
2
|
+
/** Asset UUID */
|
|
3
|
+
uuid: string;
|
|
4
|
+
/** Audio mime type (e.g., 'audio/mpeg') */
|
|
5
|
+
mimeType: string;
|
|
6
|
+
/** Title for the audio (accessibility) */
|
|
7
|
+
title: string;
|
|
8
|
+
/** Optional specific version */
|
|
9
|
+
version?: number;
|
|
10
|
+
/** Optional filename for URL */
|
|
11
|
+
filename?: string;
|
|
12
|
+
/** JWT token for authenticated access */
|
|
13
|
+
token?: string;
|
|
14
|
+
/** CSS class name */
|
|
15
|
+
className?: string;
|
|
16
|
+
/** Show audio controls */
|
|
17
|
+
controls?: boolean;
|
|
18
|
+
/** Autoplay the audio */
|
|
19
|
+
autoPlay?: boolean;
|
|
20
|
+
/** Loop the audio */
|
|
21
|
+
loop?: boolean;
|
|
22
|
+
/** Mute the audio */
|
|
23
|
+
muted?: boolean;
|
|
24
|
+
/** Preload strategy */
|
|
25
|
+
preload?: 'none' | 'metadata' | 'auto';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Renders an audio asset with native HTML5 audio player.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Basic audio player
|
|
32
|
+
* <AudioRenderer
|
|
33
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
34
|
+
* mimeType="audio/mpeg"
|
|
35
|
+
* title="Podcast Episode 1"
|
|
36
|
+
* className="w-full"
|
|
37
|
+
* />
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // With preload and loop
|
|
41
|
+
* <AudioRenderer
|
|
42
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
43
|
+
* mimeType="audio/wav"
|
|
44
|
+
* title="Background Music"
|
|
45
|
+
* preload="auto"
|
|
46
|
+
* loop
|
|
47
|
+
* />
|
|
48
|
+
*/
|
|
49
|
+
export declare function AudioRenderer({ uuid, mimeType, title, version, filename, token, className, controls, autoPlay, loop, muted, preload, }: AudioRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
50
|
+
export default AudioRenderer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as a,jsx as f}from"react/jsx-runtime";import{getAssetUrl as x}from"../../../utils/asset-url.js";function O({uuid:r,mimeType:o,title:e,version:t,filename:s,token:u,className:n,controls:i=!0,autoPlay:p,loop:d,muted:l,preload:c}){const m=x(r,{version:t,filename:s,token:u});return a("audio",{controls:i,title:e,className:n,autoPlay:p,loop:d,muted:l,preload:c,children:[f("source",{src:m,type:o}),"Your browser does not support the audio element."]})}export{O as AudioRenderer,O as default};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface DownloadLinkProps {
|
|
3
|
+
/** Asset UUID */
|
|
4
|
+
uuid: string;
|
|
5
|
+
/** Display name for the download */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Optional specific version */
|
|
8
|
+
version?: number;
|
|
9
|
+
/** Optional filename for URL and download attribute */
|
|
10
|
+
filename?: string;
|
|
11
|
+
/** JWT token for authenticated access */
|
|
12
|
+
token?: string;
|
|
13
|
+
/** CSS class name */
|
|
14
|
+
className?: string;
|
|
15
|
+
/** Custom children (defaults to "Download {name}") */
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Renders a download link for an asset.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Basic download link
|
|
23
|
+
* <DownloadLink
|
|
24
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
25
|
+
* name="Report.xlsx"
|
|
26
|
+
* className="text-blue-600 hover:underline"
|
|
27
|
+
* />
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // With custom content
|
|
31
|
+
* <DownloadLink
|
|
32
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
33
|
+
* name="Document"
|
|
34
|
+
* filename="important-document.pdf"
|
|
35
|
+
* >
|
|
36
|
+
* <DownloadIcon /> Download Document
|
|
37
|
+
* </DownloadLink>
|
|
38
|
+
*/
|
|
39
|
+
export declare function DownloadLink({ uuid, name, version, filename, token, className, children, }: DownloadLinkProps): import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
export default DownloadLink;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as i}from"react/jsx-runtime";import{getAssetUrl as a}from"../../../utils/asset-url.js";function f({uuid:t,name:o,version:n,filename:r,token:l,className:d,children:s}){const u=a(t,{version:n,filename:r,token:l,download:!0});return i("a",{href:u,download:r??o,className:d,children:s??`Download ${o}`})}export{f as DownloadLink,f as default};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface ImageRendererProps {
|
|
2
|
+
/** Asset UUID */
|
|
3
|
+
uuid: string;
|
|
4
|
+
/** Alt text for the image */
|
|
5
|
+
alt: string;
|
|
6
|
+
/** Optional specific version */
|
|
7
|
+
version?: number;
|
|
8
|
+
/** Optional filename for URL */
|
|
9
|
+
filename?: string;
|
|
10
|
+
/** JWT token for authenticated access */
|
|
11
|
+
token?: string;
|
|
12
|
+
/** CSS class name */
|
|
13
|
+
className?: string;
|
|
14
|
+
/** Loading strategy */
|
|
15
|
+
loading?: 'lazy' | 'eager';
|
|
16
|
+
/** Width attribute */
|
|
17
|
+
width?: number | string;
|
|
18
|
+
/** Height attribute */
|
|
19
|
+
height?: number | string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Renders an image asset.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* <ImageRenderer
|
|
26
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
27
|
+
* alt="Company Logo"
|
|
28
|
+
* className="w-full max-w-md"
|
|
29
|
+
* />
|
|
30
|
+
*/
|
|
31
|
+
export declare function ImageRenderer({ uuid, alt, version, filename, token, className, loading, width, height, }: ImageRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export default ImageRenderer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as p}from"react/jsx-runtime";import{getAssetUrl as a}from"../../../utils/asset-url.js";function d({uuid:r,alt:t,version:o,filename:e,token:s,className:n,loading:i="lazy",width:l,height:m}){const u=a(r,{version:o,filename:e,token:s});return p("img",{src:u,alt:t,className:n,loading:i,width:l,height:m})}export{d as ImageRenderer,d as default};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export interface PdfRendererProps {
|
|
2
|
+
/** Asset UUID */
|
|
3
|
+
uuid: string;
|
|
4
|
+
/** Title for the PDF viewer (accessibility) */
|
|
5
|
+
title: string;
|
|
6
|
+
/** Optional specific version */
|
|
7
|
+
version?: number;
|
|
8
|
+
/** Optional filename for URL */
|
|
9
|
+
filename?: string;
|
|
10
|
+
/** JWT token for authenticated access */
|
|
11
|
+
token?: string;
|
|
12
|
+
/** CSS class name */
|
|
13
|
+
className?: string;
|
|
14
|
+
/** Width attribute */
|
|
15
|
+
width?: number | string;
|
|
16
|
+
/** Height attribute */
|
|
17
|
+
height?: number | string;
|
|
18
|
+
/**
|
|
19
|
+
* PDF viewer options (appended to URL fragment)
|
|
20
|
+
* @see https://pdfobject.com/pdf/pdf_open_parameters_acro8.pdf
|
|
21
|
+
*/
|
|
22
|
+
viewerOptions?: PdfViewerOptions;
|
|
23
|
+
}
|
|
24
|
+
export interface PdfViewerOptions {
|
|
25
|
+
/** Initial page number */
|
|
26
|
+
page?: number;
|
|
27
|
+
/** Initial zoom level (e.g., 100, 'fit', 'fitH', 'fitV') */
|
|
28
|
+
zoom?: number | 'fit' | 'fitH' | 'fitV' | 'fitB' | 'fitBH' | 'fitBV';
|
|
29
|
+
/** Page mode (e.g., 'none', 'thumbs', 'bookmarks') */
|
|
30
|
+
pagemode?: 'none' | 'thumbs' | 'bookmarks' | 'attachments';
|
|
31
|
+
/** Show toolbar */
|
|
32
|
+
toolbar?: boolean;
|
|
33
|
+
/** Show navigation panes */
|
|
34
|
+
navpanes?: boolean;
|
|
35
|
+
/** Show scrollbar */
|
|
36
|
+
scrollbar?: boolean;
|
|
37
|
+
/** Show status bar */
|
|
38
|
+
statusbar?: boolean;
|
|
39
|
+
/** Show messages */
|
|
40
|
+
messages?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Renders a PDF asset in an iframe with native browser PDF viewer.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* // Basic PDF embed
|
|
47
|
+
* <PdfRenderer
|
|
48
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
49
|
+
* title="Annual Report 2024"
|
|
50
|
+
* className="w-full h-[800px] border-0"
|
|
51
|
+
* />
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // With viewer options
|
|
55
|
+
* <PdfRenderer
|
|
56
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
57
|
+
* title="Contract"
|
|
58
|
+
* viewerOptions={{
|
|
59
|
+
* page: 2,
|
|
60
|
+
* zoom: 'fit',
|
|
61
|
+
* toolbar: true,
|
|
62
|
+
* navpanes: false,
|
|
63
|
+
* }}
|
|
64
|
+
* />
|
|
65
|
+
*/
|
|
66
|
+
export declare function PdfRenderer({ uuid, title, version, filename, token, className, width, height, viewerOptions, }: PdfRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
67
|
+
export default PdfRenderer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as b}from"react/jsx-runtime";import{getAssetUrl as t}from"../../../utils/asset-url.js";function v(a){const r=[];return a.page!==void 0&&r.push(`page=${a.page}`),a.zoom!==void 0&&r.push(`zoom=${a.zoom}`),a.pagemode!==void 0&&r.push(`pagemode=${a.pagemode}`),a.toolbar!==void 0&&r.push(`toolbar=${a.toolbar?1:0}`),a.navpanes!==void 0&&r.push(`navpanes=${a.navpanes?1:0}`),a.scrollbar!==void 0&&r.push(`scrollbar=${a.scrollbar?1:0}`),a.statusbar!==void 0&&r.push(`statusbar=${a.statusbar?1:0}`),a.messages!==void 0&&r.push(`messages=${a.messages?1:0}`),r.length>0?`#${r.join("&")}`:""}function c({uuid:a,title:r,version:u,filename:f,token:l,className:d,width:m,height:g,viewerOptions:e}){let s=t(a,{version:u,filename:f,token:l});return e&&(s+=v(e)),b("iframe",{src:s,title:r,className:d,width:m,height:g})}export{c as PdfRenderer,c as default};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { AssetUrlOptions } from '../../../utils/asset-url';
|
|
2
|
+
export interface VideoRendererProps {
|
|
3
|
+
/** Asset UUID */
|
|
4
|
+
uuid: string;
|
|
5
|
+
/** Video mime type (e.g., 'video/mp4') */
|
|
6
|
+
mimeType: string;
|
|
7
|
+
/** Title for the video (accessibility) */
|
|
8
|
+
title: string;
|
|
9
|
+
/** Optional specific version */
|
|
10
|
+
version?: number;
|
|
11
|
+
/** Optional filename for URL */
|
|
12
|
+
filename?: string;
|
|
13
|
+
/** JWT token for authenticated access */
|
|
14
|
+
token?: string;
|
|
15
|
+
/** Optional poster image UUID */
|
|
16
|
+
posterUuid?: string;
|
|
17
|
+
/** Poster image options */
|
|
18
|
+
posterOptions?: AssetUrlOptions;
|
|
19
|
+
/** CSS class name */
|
|
20
|
+
className?: string;
|
|
21
|
+
/** Show video controls */
|
|
22
|
+
controls?: boolean;
|
|
23
|
+
/** Autoplay the video */
|
|
24
|
+
autoPlay?: boolean;
|
|
25
|
+
/** Loop the video */
|
|
26
|
+
loop?: boolean;
|
|
27
|
+
/** Mute the video */
|
|
28
|
+
muted?: boolean;
|
|
29
|
+
/** Preload strategy */
|
|
30
|
+
preload?: 'none' | 'metadata' | 'auto';
|
|
31
|
+
/** Width attribute */
|
|
32
|
+
width?: number | string;
|
|
33
|
+
/** Height attribute */
|
|
34
|
+
height?: number | string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Renders a video asset with native HTML5 video player.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Basic video
|
|
41
|
+
* <VideoRenderer
|
|
42
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
43
|
+
* mimeType="video/mp4"
|
|
44
|
+
* title="Product Demo"
|
|
45
|
+
* className="w-full max-w-2xl"
|
|
46
|
+
* />
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // With poster image and autoplay
|
|
50
|
+
* <VideoRenderer
|
|
51
|
+
* uuid="550e8400-e29b-41d4-a716-446655440000"
|
|
52
|
+
* mimeType="video/mp4"
|
|
53
|
+
* title="Welcome Video"
|
|
54
|
+
* posterUuid="poster-uuid-here"
|
|
55
|
+
* autoPlay
|
|
56
|
+
* muted
|
|
57
|
+
* loop
|
|
58
|
+
* />
|
|
59
|
+
*/
|
|
60
|
+
export declare function VideoRenderer({ uuid, mimeType, title, version, filename, token, posterUuid, posterOptions, className, controls, autoPlay, loop, muted, preload, width, height, }: VideoRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
61
|
+
export default VideoRenderer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as O,jsx as b}from"react/jsx-runtime";import{getAssetUrl as o}from"../../../utils/asset-url.js";function A({uuid:r,mimeType:t,title:s,version:n,filename:i,token:u,posterUuid:e,posterOptions:p,className:c,controls:d=!0,autoPlay:l,loop:m,muted:f,preload:v,width:x,height:a}){const h=o(r,{version:n,filename:i,token:u}),j=e?o(e,p):void 0;return O("video",{controls:d,poster:j,title:s,className:c,autoPlay:l,loop:m,muted:f,preload:v,width:x,height:a,children:[b("source",{src:h,type:t}),"Your browser does not support the video element."]})}export{A as VideoRenderer,A as default};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AudioRenderer, type AudioRendererProps } from './AudioRenderer';
|
|
2
|
+
export { DownloadLink, type DownloadLinkProps } from './DownloadLink';
|
|
3
|
+
export { ImageRenderer, type ImageRendererProps } from './ImageRenderer';
|
|
4
|
+
export { PdfRenderer, type PdfRendererProps, type PdfViewerOptions, } from './PdfRenderer';
|
|
5
|
+
export { VideoRenderer, type VideoRendererProps } from './VideoRenderer';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AudioRenderer as m}from"./AudioRenderer.js";import{DownloadLink as t}from"./DownloadLink.js";import{ImageRenderer as n}from"./ImageRenderer.js";import{PdfRenderer as x}from"./PdfRenderer.js";import{VideoRenderer as a}from"./VideoRenderer.js";import"react/jsx-runtime";import"../../../utils/asset-url.js";export{m as AudioRenderer,t as DownloadLink,n as ImageRenderer,x as PdfRenderer,a as VideoRenderer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as p}from"react/jsx-runtime";import{Provider as w}from"react-aria-components";import a,{useState as N,useRef as d,useEffect as y,useCallback as x,useMemo as R,useContext as k,createContext as A,useId as E}from"react";import{cn as S}from"../../utils/cn.js";function j(e,r,t){let[o,n]=N(e||r),c=d(e!==void 0),f=e!==void 0;y(()=>{let s=c.current;s!==f&&console.warn(`WARN: A component changed from ${s?"controlled":"uncontrolled"} to ${f?"controlled":"uncontrolled"}.`),c.current=f},[f]);let l=f?e:o,O=x((s,...$)=>{let m=(u,...i)=>{t&&(Object.is(l,u)||t(u,...i)),f||(l=u)};typeof s=="function"?(console.warn("We can not support a function callback. See Github Issues for details https://github.com/adobe/react-spectrum/issues/2320"),n((i,...P)=>{let g=s(f?l:i,...P);return m(g,...$),f?i:g})):(f||n(s),m(s,...$))},[f,l,t]);return[l,O]}const I=typeof document<"u"?a.useLayoutEffect:()=>{};let h=new Map;function M(e,r){if(e===r)return e;let t=h.get(e);if(t)return t(r),r;let o=h.get(r);return o?(o(e),e):r}function V(...e){return(...r)=>{for(let t of e)typeof t=="function"&&t(...r)}}function C(e){var r,t,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var n=e.length;for(r=0;r<n;r++)e[r]&&(t=C(e[r]))&&(o&&(o+=" "),o+=t)}else for(t in e)e[t]&&(o&&(o+=" "),o+=t);return o}function F(){for(var e,r,t=0,o="",n=arguments.length;t<n;t++)(e=arguments[t])&&(r=C(e))&&(o&&(o+=" "),o+=r);return o}function _(...e){let r={...e[0]};for(let t=1;t<e.length;t++){let o=e[t];for(let n in o){let c=r[n],f=o[n];typeof c=="function"&&typeof f=="function"&&n[0]==="o"&&n[1]==="n"&&n.charCodeAt(2)>=65&&n.charCodeAt(2)<=90?r[n]=V(c,f):(n==="className"||n==="UNSAFE_className")&&typeof c=="string"&&typeof f=="string"?r[n]=F(c,f):n==="id"&&c&&f?r.id=M(c,f):r[n]=f!==void 0?f:c}}return r}function v(e){const r=d(null);return R(()=>({get current(){return r.current},set current(t){r.current=t,typeof e=="function"?e(t):e&&(e.current=t)}}),[e])}function T(e,r){I(()=>{if(e&&e.ref&&r)return e.ref.current=r.current,()=>{e.ref&&(e.ref.current=null)}})}const b=a.createContext({register:()=>{}});b.displayName="PressResponderContext";const U=a.forwardRef(({children:e,...r},t)=>{let o=d(!1),n=k(b);t=v(t||(n==null?void 0:n.ref));let c=_(n||{},{...r,ref:t,register(){o.current=!0,n&&n.register()}});return T(n,t),y(()=>{o.current||(console.warn("A PressResponder was rendered without a pressable child. Either call the usePress hook, or wrap your DOM node with <Pressable> component."),o.current=!0)},[]),a.createElement(b.Provider,{value:c},e)}),W=A({});function z({children:e,className:r,...t}){const o=E(),[n,c]=j(t.isOpen,t.defaultOpen||!1,t.onOpenChange),f=d(null),l=x(()=>{c(!n)},[c,n]);return p(w,{values:[[W,{isOpen:n,id:o,defaultOpen:t.defaultOpen||!1}]],children:p(U,{ref:f,isPressed:n,onPress:l,"aria-expanded":n,"aria-controls":o,children:p("div",{className:S("w-full",r),children:e})})})}export{z as CollapsibleTrigger,W as CollapsibleTriggerStateContext,z as default};
|
|
1
|
+
import{jsx as oe}from"react/jsx-runtime";import{Provider as xe}from"react-aria-components";import ge,{useState as ve,useRef as B,useEffect as re,useCallback as U,useMemo as Oe,useContext as _e,createContext as ke,useId as Le}from"react";import{cn as Me}from"../../utils/cn.js";function Ce(e,r,i){let[n,s]=ve(e||r),u=B(e!==void 0),c=e!==void 0;re(()=>{let y=u.current;y!==c&&console.warn(`WARN: A component changed from ${y?"controlled":"uncontrolled"} to ${c?"controlled":"uncontrolled"}.`),u.current=c},[c]);let d=c?e:n,g=U((y,...$)=>{let K=(_,...k)=>{i&&(Object.is(d,_)||i(_,...k)),c||(d=_)};typeof y=="function"?(console.warn("We can not support a function callback. See Github Issues for details https://github.com/adobe/react-spectrum/issues/2320"),s((k,...F)=>{let m=y(c?d:k,...F);return K(m,...$),c?k:m})):(c||s(y),K(y,...$))},[c,d,i]);return[d,g]}const ye=typeof document<"u"?ge.useLayoutEffect:()=>{};function G(e){const r=B(null);return ye(()=>{r.current=e},[e]),U((...i)=>{const n=r.current;return n==null?void 0:n(...i)},[])}let ae=new Map;function Ae(e,r){if(e===r)return e;let i=ae.get(e);if(i)return i(r),r;let n=ae.get(r);return n?(n(e),e):r}function $e(...e){return(...r)=>{for(let i of e)typeof i=="function"&&i(...r)}}const w=e=>{var r;return(r=e==null?void 0:e.ownerDocument)!==null&&r!==void 0?r:document},Z=e=>e&&"window"in e&&e.window===e?e:w(e).defaultView||window;function Te(e){var r,i,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e)){var s=e.length;for(r=0;r<s;r++)e[r]&&(i=Te(e[r]))&&(n&&(n+=" "),n+=i)}else for(i in e)e[i]&&(n&&(n+=" "),n+=i);return n}function Ie(){for(var e,r,i=0,n="",s=arguments.length;i<s;i++)(e=arguments[i])&&(r=Te(e))&&(n&&(n+=" "),n+=r);return n}function be(...e){let r={...e[0]};for(let i=1;i<e.length;i++){let n=e[i];for(let s in n){let u=r[s],c=n[s];typeof u=="function"&&typeof c=="function"&&s[0]==="o"&&s[1]==="n"&&s.charCodeAt(2)>=65&&s.charCodeAt(2)<=90?r[s]=$e(u,c):(s==="className"||s==="UNSAFE_className")&&typeof u=="string"&&typeof c=="string"?r[s]=Ie(u,c):s==="id"&&u&&c?r.id=Ae(u,c):r[s]=c!==void 0?c:u}}return r}function X(e){if(De())e.focus({preventScroll:!0});else{let r=Ue(e);e.focus(),Ge(r)}}let H=null;function De(){if(H==null){H=!1;try{document.createElement("div").focus({get preventScroll(){return H=!0,!0}})}catch{}}return H}function Ue(e){let r=e.parentNode,i=[],n=document.scrollingElement||document.documentElement;for(;r instanceof HTMLElement&&r!==n;)(r.offsetHeight<r.scrollHeight||r.offsetWidth<r.scrollWidth)&&i.push({element:r,scrollTop:r.scrollTop,scrollLeft:r.scrollLeft}),r=r.parentNode;return n instanceof HTMLElement&&i.push({element:n,scrollTop:n.scrollTop,scrollLeft:n.scrollLeft}),i}function Ge(e){for(let{element:r,scrollTop:i,scrollLeft:n}of e)r.scrollTop=i,r.scrollLeft=n}function q(e){var r;return typeof window>"u"||window.navigator==null?!1:((r=window.navigator.userAgentData)===null||r===void 0?void 0:r.brands.some(i=>e.test(i.brand)))||e.test(window.navigator.userAgent)}function ne(e){var r;return typeof window<"u"&&window.navigator!=null?e.test(((r=window.navigator.userAgentData)===null||r===void 0?void 0:r.platform)||window.navigator.platform):!1}function S(e){let r=null;return()=>(r==null&&(r=e()),r)}const j=S(function(){return ne(/^Mac/i)}),Xe=S(function(){return ne(/^iPhone/i)}),me=S(function(){return ne(/^iPad/i)||j()&&navigator.maxTouchPoints>1}),he=S(function(){return Xe()||me()}),Ye=S(function(){return q(/AppleWebKit/i)&&!Fe()}),Fe=S(function(){return q(/Chrome/i)}),Pe=S(function(){return q(/Android/i)}),Ne=S(function(){return q(/Firefox/i)});function Y(e,r,i=!0){var n,s;let{metaKey:u,ctrlKey:c,altKey:d,shiftKey:g}=r;Ne()&&(!((s=window.event)===null||s===void 0||(n=s.type)===null||n===void 0)&&n.startsWith("key"))&&e.target==="_blank"&&(j()?u=!0:c=!0);let y=Ye()&&j()&&!me()?new KeyboardEvent("keydown",{keyIdentifier:"Enter",metaKey:u,ctrlKey:c,altKey:d,shiftKey:g}):new MouseEvent("click",{metaKey:u,ctrlKey:c,altKey:d,shiftKey:g,bubbles:!0,cancelable:!0});Y.isOpening=i,X(e),e.dispatchEvent(y),Y.isOpening=!1}Y.isOpening=!1;let I=new Map,ee=new Set;function se(){if(typeof window>"u")return;function e(n){return"propertyName"in n}let r=n=>{if(!e(n)||!n.target)return;let s=I.get(n.target);s||(s=new Set,I.set(n.target,s),n.target.addEventListener("transitioncancel",i,{once:!0})),s.add(n.propertyName)},i=n=>{if(!e(n)||!n.target)return;let s=I.get(n.target);if(s&&(s.delete(n.propertyName),s.size===0&&(n.target.removeEventListener("transitioncancel",i),I.delete(n.target)),I.size===0)){for(let u of ee)u();ee.clear()}};document.body.addEventListener("transitionrun",r),document.body.addEventListener("transitionend",i)}typeof document<"u"&&(document.readyState!=="loading"?se():document.addEventListener("DOMContentLoaded",se));function He(e){requestAnimationFrame(()=>{I.size===0?e():ee.add(e)})}function Re(){let e=B(new Map),r=U((s,u,c,d)=>{let g=d!=null&&d.once?(...y)=>{e.current.delete(c),c(...y)}:c;e.current.set(c,{type:u,eventTarget:s,fn:g,options:d}),s.addEventListener(u,c,d)},[]),i=U((s,u,c,d)=>{var g;let y=((g=e.current.get(c))===null||g===void 0?void 0:g.fn)||c;s.removeEventListener(u,y,d),e.current.delete(c)},[]),n=U(()=>{e.current.forEach((s,u)=>{i(s.eventTarget,s.type,u,s.options)})},[i]);return re(()=>n,[n]),{addGlobalListener:r,removeGlobalListener:i,removeAllGlobalListeners:n}}function Ve(e,r){ye(()=>{if(e&&e.ref&&r)return e.ref.current=r.current,()=>{e.ref&&(e.ref.current=null)}})}function le(e){return e.mozInputSource===0&&e.isTrusted?!0:Pe()&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function We(e){return!Pe()&&e.width===0&&e.height===0||e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType==="mouse"}let D="default",te="",z=new WeakMap;function ce(e){if(he()){if(D==="default"){const r=w(e);te=r.documentElement.style.webkitUserSelect,r.documentElement.style.webkitUserSelect="none"}D="disabled"}else(e instanceof HTMLElement||e instanceof SVGElement)&&(z.set(e,e.style.userSelect),e.style.userSelect="none")}function R(e){if(he()){if(D!=="disabled")return;D="restoring",setTimeout(()=>{He(()=>{if(D==="restoring"){const r=w(e);r.documentElement.style.webkitUserSelect==="none"&&(r.documentElement.style.webkitUserSelect=te||""),te="",D="default"}})},300)}else if((e instanceof HTMLElement||e instanceof SVGElement)&&e&&z.has(e)){let r=z.get(e);e.style.userSelect==="none"&&(e.style.userSelect=r),e.getAttribute("style")===""&&e.removeAttribute("style"),z.delete(e)}}const Ee=ge.createContext({register:()=>{}});Ee.displayName="PressResponderContext";function ze(e,r){return r.get?r.get.call(e):r.value}function we(e,r,i){if(!r.has(e))throw new TypeError("attempted to "+i+" private field on non-instance");return r.get(e)}function je(e,r){var i=we(e,r,"get");return ze(e,i)}function Be(e,r){if(r.has(e))throw new TypeError("Cannot initialize the same private elements twice on an object")}function qe(e,r,i){Be(e,r),r.set(e,i)}function Je(e,r,i){if(r.set)r.set.call(e,i);else{if(!r.writable)throw new TypeError("attempted to set read only private field");r.value=i}}function ue(e,r,i){var n=we(e,r,"set");return Je(e,n,i),i}function Qe(e){let r=_e(Ee);if(r){let{register:i,...n}=r;e=be(n,e),i()}return Ve(r,e.ref),e}var V=new WeakMap;class W{continuePropagation(){ue(this,V,!1)}get shouldStopPropagation(){return je(this,V)}constructor(r,i,n,s){qe(this,V,{writable:!0,value:void 0}),ue(this,V,!0);var u;let c=(u=s==null?void 0:s.target)!==null&&u!==void 0?u:n.currentTarget;const d=c==null?void 0:c.getBoundingClientRect();let g,y=0,$,K=null;n.clientX!=null&&n.clientY!=null&&($=n.clientX,K=n.clientY),d&&($!=null&&K!=null?(g=$-d.left,y=K-d.top):(g=d.width/2,y=d.height/2)),this.type=r,this.pointerType=i,this.target=n.currentTarget,this.shiftKey=n.shiftKey,this.metaKey=n.metaKey,this.ctrlKey=n.ctrlKey,this.altKey=n.altKey,this.x=g,this.y=y}}const fe=Symbol("linkClicked");function Ze(e){let{onPress:r,onPressChange:i,onPressStart:n,onPressEnd:s,onPressUp:u,isDisabled:c,isPressed:d,preventFocusOnPress:g,shouldCancelOnPointerExit:y,allowTextSelectionOnPress:$,ref:K,..._}=Qe(e),[k,F]=ve(!1),m=B({isPressed:!1,ignoreEmulatedMouseEvents:!1,ignoreClickAfterPress:!1,didFirePressStart:!1,isTriggeringEvent:!1,activePointerId:null,target:null,isOverTarget:!1,pointerType:null}),{addGlobalListener:x,removeAllGlobalListeners:L}=Re(),h=G((t,f)=>{let b=m.current;if(c||b.didFirePressStart)return!1;let l=!0;if(b.isTriggeringEvent=!0,n){let p=new W("pressstart",f,t);n(p),l=p.shouldStopPropagation}return i&&i(!0),b.isTriggeringEvent=!1,b.didFirePressStart=!0,F(!0),l}),T=G((t,f,b=!0)=>{let l=m.current;if(!l.didFirePressStart)return!1;l.ignoreClickAfterPress=!0,l.didFirePressStart=!1,l.isTriggeringEvent=!0;let p=!0;if(s){let o=new W("pressend",f,t);s(o),p=o.shouldStopPropagation}if(i&&i(!1),F(!1),r&&b&&!c){let o=new W("press",f,t);r(o),p&&(p=o.shouldStopPropagation)}return l.isTriggeringEvent=!1,p}),M=G((t,f)=>{let b=m.current;if(c)return!1;if(u){b.isTriggeringEvent=!0;let l=new W("pressup",f,t);return u(l),b.isTriggeringEvent=!1,l.shouldStopPropagation}return!0}),O=G(t=>{let f=m.current;f.isPressed&&f.target&&(f.isOverTarget&&f.pointerType!=null&&T(P(f.target,t),f.pointerType,!1),f.isPressed=!1,f.isOverTarget=!1,f.activePointerId=null,f.pointerType=null,L(),$||R(f.target))}),N=G(t=>{y&&O(t)}),Ke=Oe(()=>{let t=m.current,f={onKeyDown(l){if(J(l.nativeEvent,l.currentTarget)&&l.currentTarget.contains(l.target)){var p;pe(l.target,l.key)&&l.preventDefault();let o=!0;if(!t.isPressed&&!l.repeat){t.target=l.currentTarget,t.isPressed=!0,o=h(l,"keyboard");let a=l.currentTarget,v=C=>{J(C,a)&&!C.repeat&&a.contains(C.target)&&t.target&&M(P(t.target,C),"keyboard")};x(w(l.currentTarget),"keyup",$e(v,b),!0)}o&&l.stopPropagation(),l.metaKey&&j()&&((p=t.metaKeyEvents)===null||p===void 0||p.set(l.key,l.nativeEvent))}else l.key==="Meta"&&(t.metaKeyEvents=new Map)},onClick(l){if(!(l&&!l.currentTarget.contains(l.target))&&l&&l.button===0&&!t.isTriggeringEvent&&!Y.isOpening){let p=!0;if(c&&l.preventDefault(),!t.ignoreClickAfterPress&&!t.ignoreEmulatedMouseEvents&&!t.isPressed&&(t.pointerType==="virtual"||le(l.nativeEvent))){!c&&!g&&X(l.currentTarget);let o=h(l,"virtual"),a=M(l,"virtual"),v=T(l,"virtual");p=o&&a&&v}t.ignoreEmulatedMouseEvents=!1,t.ignoreClickAfterPress=!1,p&&l.stopPropagation()}}},b=l=>{var p;if(t.isPressed&&t.target&&J(l,t.target)){var o;pe(l.target,l.key)&&l.preventDefault();let v=l.target;T(P(t.target,l),"keyboard",t.target.contains(v)),L(),l.key!=="Enter"&&ie(t.target)&&t.target.contains(v)&&!l[fe]&&(l[fe]=!0,Y(t.target,l,!1)),t.isPressed=!1,(o=t.metaKeyEvents)===null||o===void 0||o.delete(l.key)}else if(l.key==="Meta"&&(!((p=t.metaKeyEvents)===null||p===void 0)&&p.size)){var a;let v=t.metaKeyEvents;t.metaKeyEvents=void 0;for(let C of v.values())(a=t.target)===null||a===void 0||a.dispatchEvent(new KeyboardEvent("keyup",C))}};if(typeof PointerEvent<"u"){f.onPointerDown=a=>{if(a.button!==0||!a.currentTarget.contains(a.target))return;if(We(a.nativeEvent)){t.pointerType="virtual";return}Q(a.currentTarget)&&a.preventDefault(),t.pointerType=a.pointerType;let v=!0;t.isPressed||(t.isPressed=!0,t.isOverTarget=!0,t.activePointerId=a.pointerId,t.target=a.currentTarget,!c&&!g&&X(a.currentTarget),$||ce(t.target),v=h(a,t.pointerType),x(w(a.currentTarget),"pointermove",l,!1),x(w(a.currentTarget),"pointerup",p,!1),x(w(a.currentTarget),"pointercancel",o,!1)),v&&a.stopPropagation()},f.onMouseDown=a=>{a.currentTarget.contains(a.target)&&a.button===0&&(Q(a.currentTarget)&&a.preventDefault(),a.stopPropagation())},f.onPointerUp=a=>{!a.currentTarget.contains(a.target)||t.pointerType==="virtual"||a.button===0&&A(a,a.currentTarget)&&M(a,t.pointerType||a.pointerType)};let l=a=>{a.pointerId===t.activePointerId&&(t.target&&A(a,t.target)?!t.isOverTarget&&t.pointerType!=null&&(t.isOverTarget=!0,h(P(t.target,a),t.pointerType)):t.target&&t.isOverTarget&&t.pointerType!=null&&(t.isOverTarget=!1,T(P(t.target,a),t.pointerType,!1),N(a)))},p=a=>{a.pointerId===t.activePointerId&&t.isPressed&&a.button===0&&t.target&&(A(a,t.target)&&t.pointerType!=null?T(P(t.target,a),t.pointerType):t.isOverTarget&&t.pointerType!=null&&T(P(t.target,a),t.pointerType,!1),t.isPressed=!1,t.isOverTarget=!1,t.activePointerId=null,t.pointerType=null,L(),$||R(t.target))},o=a=>{O(a)};f.onDragStart=a=>{a.currentTarget.contains(a.target)&&O(a)}}else{f.onMouseDown=o=>{if(o.button!==0||!o.currentTarget.contains(o.target))return;if(Q(o.currentTarget)&&o.preventDefault(),t.ignoreEmulatedMouseEvents){o.stopPropagation();return}t.isPressed=!0,t.isOverTarget=!0,t.target=o.currentTarget,t.pointerType=le(o.nativeEvent)?"virtual":"mouse",!c&&!g&&X(o.currentTarget),h(o,t.pointerType)&&o.stopPropagation(),x(w(o.currentTarget),"mouseup",l,!1)},f.onMouseEnter=o=>{if(!o.currentTarget.contains(o.target))return;let a=!0;t.isPressed&&!t.ignoreEmulatedMouseEvents&&t.pointerType!=null&&(t.isOverTarget=!0,a=h(o,t.pointerType)),a&&o.stopPropagation()},f.onMouseLeave=o=>{if(!o.currentTarget.contains(o.target))return;let a=!0;t.isPressed&&!t.ignoreEmulatedMouseEvents&&t.pointerType!=null&&(t.isOverTarget=!1,a=T(o,t.pointerType,!1),N(o)),a&&o.stopPropagation()},f.onMouseUp=o=>{o.currentTarget.contains(o.target)&&!t.ignoreEmulatedMouseEvents&&o.button===0&&M(o,t.pointerType||"mouse")};let l=o=>{if(o.button===0){if(t.isPressed=!1,L(),t.ignoreEmulatedMouseEvents){t.ignoreEmulatedMouseEvents=!1;return}t.target&&A(o,t.target)&&t.pointerType!=null?T(P(t.target,o),t.pointerType):t.target&&t.isOverTarget&&t.pointerType!=null&&T(P(t.target,o),t.pointerType,!1),t.isOverTarget=!1}};f.onTouchStart=o=>{if(!o.currentTarget.contains(o.target))return;let a=et(o.nativeEvent);if(!a)return;t.activePointerId=a.identifier,t.ignoreEmulatedMouseEvents=!0,t.isOverTarget=!0,t.isPressed=!0,t.target=o.currentTarget,t.pointerType="touch",!c&&!g&&X(o.currentTarget),$||ce(t.target),h(E(t.target,o),t.pointerType)&&o.stopPropagation(),x(Z(o.currentTarget),"scroll",p,!0)},f.onTouchMove=o=>{if(!o.currentTarget.contains(o.target))return;if(!t.isPressed){o.stopPropagation();return}let a=de(o.nativeEvent,t.activePointerId),v=!0;a&&A(a,o.currentTarget)?!t.isOverTarget&&t.pointerType!=null&&(t.isOverTarget=!0,v=h(E(t.target,o),t.pointerType)):t.isOverTarget&&t.pointerType!=null&&(t.isOverTarget=!1,v=T(E(t.target,o),t.pointerType,!1),N(E(t.target,o))),v&&o.stopPropagation()},f.onTouchEnd=o=>{if(!o.currentTarget.contains(o.target))return;if(!t.isPressed){o.stopPropagation();return}let a=de(o.nativeEvent,t.activePointerId),v=!0;a&&A(a,o.currentTarget)&&t.pointerType!=null?(M(E(t.target,o),t.pointerType),v=T(E(t.target,o),t.pointerType)):t.isOverTarget&&t.pointerType!=null&&(v=T(E(t.target,o),t.pointerType,!1)),v&&o.stopPropagation(),t.isPressed=!1,t.activePointerId=null,t.isOverTarget=!1,t.ignoreEmulatedMouseEvents=!0,t.target&&!$&&R(t.target),L()},f.onTouchCancel=o=>{o.currentTarget.contains(o.target)&&(o.stopPropagation(),t.isPressed&&O(E(t.target,o)))};let p=o=>{t.isPressed&&o.target.contains(t.target)&&O({currentTarget:t.target,shiftKey:!1,ctrlKey:!1,metaKey:!1,altKey:!1})};f.onDragStart=o=>{o.currentTarget.contains(o.target)&&O(o)}}return f},[x,c,g,L,$,O,N,T,h,M]);return re(()=>()=>{var t;$||R((t=m.current.target)!==null&&t!==void 0?t:void 0)},[$]),{isPressed:d||k,pressProps:be(_,Ke)}}function ie(e){return e.tagName==="A"&&e.hasAttribute("href")}function J(e,r){const{key:i,code:n}=e,s=r,u=s.getAttribute("role");return(i==="Enter"||i===" "||i==="Spacebar"||n==="Space")&&!(s instanceof Z(s).HTMLInputElement&&!Se(s,i)||s instanceof Z(s).HTMLTextAreaElement||s.isContentEditable)&&!((u==="link"||!u&&ie(s))&&i!=="Enter")}function et(e){const{targetTouches:r}=e;return r.length>0?r[0]:null}function de(e,r){const i=e.changedTouches;for(let n=0;n<i.length;n++){const s=i[n];if(s.identifier===r)return s}return null}function E(e,r){let i=0,n=0;return r.targetTouches&&r.targetTouches.length===1&&(i=r.targetTouches[0].clientX,n=r.targetTouches[0].clientY),{currentTarget:e,shiftKey:r.shiftKey,ctrlKey:r.ctrlKey,metaKey:r.metaKey,altKey:r.altKey,clientX:i,clientY:n}}function P(e,r){let i=r.clientX,n=r.clientY;return{currentTarget:e,shiftKey:r.shiftKey,ctrlKey:r.ctrlKey,metaKey:r.metaKey,altKey:r.altKey,clientX:i,clientY:n}}function tt(e){let r=0,i=0;return e.width!==void 0?r=e.width/2:e.radiusX!==void 0&&(r=e.radiusX),e.height!==void 0?i=e.height/2:e.radiusY!==void 0&&(i=e.radiusY),{top:e.clientY-i,right:e.clientX+r,bottom:e.clientY+i,left:e.clientX-r}}function rt(e,r){return!(e.left>r.right||r.left>e.right||e.top>r.bottom||r.top>e.bottom)}function A(e,r){let i=r.getBoundingClientRect(),n=tt(e);return rt(i,n)}function Q(e){return!(e instanceof HTMLElement)||!e.hasAttribute("draggable")}function pe(e,r){return e instanceof HTMLInputElement?!Se(e,r):e instanceof HTMLButtonElement?e.type!=="submit"&&e.type!=="reset":!ie(e)}const nt=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);function Se(e,r){return e.type==="checkbox"||e.type==="radio"?r===" ":nt.has(e.type)}const it=ke({});function ct({children:e,className:r,...i}){const n=Le(),[s,u]=Ce(i.isOpen,i.defaultOpen||!1,i.onOpenChange),c=U(()=>{u(!s)},[u,s]),{pressProps:d}=Ze({onPress:c});return oe(xe,{values:[[it,{isOpen:s,id:n,defaultOpen:i.defaultOpen||!1}]],children:oe("div",{...d,role:"button",tabIndex:0,"aria-expanded":s,"aria-controls":n,className:Me("w-full",r),children:e})})}export{ct as CollapsibleTrigger,it as CollapsibleTriggerStateContext,ct as default};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface AccessDeniedProps {
|
|
3
|
+
/** Custom title (defaults to "Access Denied") */
|
|
4
|
+
title?: string;
|
|
5
|
+
/** Custom message */
|
|
6
|
+
message?: string;
|
|
7
|
+
/** Custom icon to render instead of default */
|
|
8
|
+
icon?: ReactNode;
|
|
9
|
+
/** Custom content to render instead of default */
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generic access denied message component.
|
|
14
|
+
* Used for 401/403 responses or when access checks fail.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* // Default message
|
|
19
|
+
* <AccessDenied />
|
|
20
|
+
*
|
|
21
|
+
* // Custom message
|
|
22
|
+
* <AccessDenied
|
|
23
|
+
* title="Authentication Required"
|
|
24
|
+
* message="Please log in to continue."
|
|
25
|
+
* />
|
|
26
|
+
*
|
|
27
|
+
* // Custom icon
|
|
28
|
+
* <AccessDenied icon={<LockIcon size={24} className="text-red-500" />} />
|
|
29
|
+
*
|
|
30
|
+
* // Fully custom content
|
|
31
|
+
* <AccessDenied>
|
|
32
|
+
* <CustomErrorPage />
|
|
33
|
+
* </AccessDenied>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function AccessDenied({ title, message, icon, children, }: AccessDeniedProps): string | number | bigint | true | Iterable<ReactNode> | Promise<import('react').AwaitedReactNode> | import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export default AccessDenied;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsxs as i,jsx as e}from"react/jsx-runtime";import{LockIcon as n}from"../Icon/LockIcon.js";import"../../utils/cn.js";function m({title:s,message:r,icon:c,children:t}){return t||i("div",{className:"flex flex-col items-center justify-center min-h-[50vh] px-4",children:[e("div",{className:"w-12 h-12 rounded-full bg-red-100 flex items-center justify-center mb-4",children:c??e(n,{size:24,className:"text-red-500"})}),e("h1",{className:"text-xl font-semibold text-slate-900 mb-2",children:s??"Access Denied"}),e("p",{className:"text-sm text-slate-600 text-center max-w-md",children:r??"You don't have permission to access this resource. If you believe this is an error, please contact support."})]})}export{m as AccessDenied,m as default};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { UpgradePromptProps } from './UpgradePrompt';
|
|
3
|
+
import { PermissionRequiredProps } from './PermissionRequired';
|
|
4
|
+
export interface FeatureGateProps {
|
|
5
|
+
/** The permission code to check */
|
|
6
|
+
permission: string;
|
|
7
|
+
/** Human-readable feature name for error messages */
|
|
8
|
+
featureName?: string;
|
|
9
|
+
/** Content to show when user has permission */
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
/** Custom content to show when account needs to upgrade (subscription-based) */
|
|
12
|
+
upgradeContent?: ReactNode;
|
|
13
|
+
/** Custom icon for the upgrade prompt */
|
|
14
|
+
upgradeIcon?: UpgradePromptProps['icon'];
|
|
15
|
+
/** URL to navigate to for subscription management */
|
|
16
|
+
upgradeUrl?: UpgradePromptProps['upgradeUrl'];
|
|
17
|
+
/** Callback when "Manage Subscription" is clicked in upgrade prompt */
|
|
18
|
+
onManageSubscription?: UpgradePromptProps['onManageSubscription'];
|
|
19
|
+
/** Custom content to show when user's role lacks permission */
|
|
20
|
+
permissionContent?: ReactNode;
|
|
21
|
+
/** Custom icon for the permission required prompt */
|
|
22
|
+
permissionIcon?: PermissionRequiredProps['icon'];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Gates content based on user and account permissions.
|
|
26
|
+
*
|
|
27
|
+
* Permission checks happen in two stages:
|
|
28
|
+
* 1. Account level - Does the account's subscription include this feature?
|
|
29
|
+
* If not, show UpgradePrompt.
|
|
30
|
+
* 2. User level - Does the user's role grant this permission?
|
|
31
|
+
* If not, show PermissionRequired.
|
|
32
|
+
*
|
|
33
|
+
* While permissions are loading (null), children are shown (assume access).
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* // Basic usage
|
|
38
|
+
* <FeatureGate permission="reports:view" featureName="Reports">
|
|
39
|
+
* <ReportsPage />
|
|
40
|
+
* </FeatureGate>
|
|
41
|
+
*
|
|
42
|
+
* // With upgrade URL
|
|
43
|
+
* <FeatureGate
|
|
44
|
+
* permission="analytics:advanced"
|
|
45
|
+
* featureName="Advanced Analytics"
|
|
46
|
+
* upgradeUrl="/settings/subscription"
|
|
47
|
+
* >
|
|
48
|
+
* <AnalyticsDashboard />
|
|
49
|
+
* </FeatureGate>
|
|
50
|
+
*
|
|
51
|
+
* // With custom prompts
|
|
52
|
+
* <FeatureGate
|
|
53
|
+
* permission="analytics:advanced"
|
|
54
|
+
* featureName="Advanced Analytics"
|
|
55
|
+
* upgradeContent={<CustomUpgradeBanner />}
|
|
56
|
+
* >
|
|
57
|
+
* <AnalyticsDashboard />
|
|
58
|
+
* </FeatureGate>
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function FeatureGate({ permission, featureName, children, upgradeContent, upgradeIcon, upgradeUrl, onManageSubscription, permissionContent, permissionIcon, }: FeatureGateProps): string | number | bigint | boolean | Iterable<ReactNode> | Promise<import('react').AwaitedReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
62
|
+
export default FeatureGate;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as n}from"react/jsx-runtime";import{usePermissions as P,useAccountPermissions as d}from"./PermissionsProvider.js";import{UpgradePrompt as A}from"./UpgradePrompt.js";import{PermissionRequired as h}from"./PermissionRequired.js";import"react";import"../Button/Button.js";import"react-aria-components";import"../../utils/cn.js";import"../Link/Link.js";import"../Link/LinkContext.js";import"../Link/utils.js";import"../Icon/GemIcon.js";import"../Icon/LockIcon.js";function y({permission:r,featureName:i,children:o,upgradeContent:m,upgradeIcon:e,upgradeUrl:u,onManageSubscription:c,permissionContent:p,permissionIcon:l}){const t=P(),s=d();if(t===null||s===null)return o;const f=s.includes(r),a=t.includes(r);return f?a?o:n(h,{featureName:i,icon:l,children:p}):n(A,{featureName:i,icon:e,upgradeUrl:u,onManageSubscription:c,children:m})}export{y as FeatureGate,y as default};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface PermissionRequiredProps {
|
|
3
|
+
/** Human-readable feature name for error message */
|
|
4
|
+
featureName?: string;
|
|
5
|
+
/** Custom icon to render instead of default */
|
|
6
|
+
icon?: ReactNode;
|
|
7
|
+
/** Custom content to render instead of default */
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Shown when the user's role doesn't grant permission for a feature.
|
|
12
|
+
* The account has the feature, but this specific user needs role access.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* // Default message
|
|
17
|
+
* <PermissionRequired featureName="Reports" />
|
|
18
|
+
*
|
|
19
|
+
* // Custom icon
|
|
20
|
+
* <PermissionRequired
|
|
21
|
+
* featureName="Reports"
|
|
22
|
+
* icon={<ShieldIcon size={24} className="text-yellow-500" />}
|
|
23
|
+
* />
|
|
24
|
+
*
|
|
25
|
+
* // Custom content
|
|
26
|
+
* <PermissionRequired>
|
|
27
|
+
* <ContactAdminForm />
|
|
28
|
+
* </PermissionRequired>
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function PermissionRequired({ featureName, icon, children, }: PermissionRequiredProps): string | number | bigint | true | Iterable<ReactNode> | Promise<import('react').AwaitedReactNode> | import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export default PermissionRequired;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import{LockIcon as o}from"../Icon/LockIcon.js";import"../../utils/cn.js";function l({featureName:t,icon:i,children:s}){return s||e("div",{className:"border border-slate-200 rounded-lg bg-white",children:r("div",{className:"flex flex-col items-center justify-center py-12 px-4",children:[e("div",{className:"w-12 h-12 rounded-full bg-yellow-100 flex items-center justify-center mb-4",children:i??e(o,{size:24})}),e("p",{className:"text-lg font-medium text-slate-600 mb-2",children:"Permission Required"}),r("p",{className:"text-sm text-slate-500 text-center max-w-md",children:[t?`You don't have permission to access ${t}.`:"You don't have permission to access this feature."," ","Please contact your account administrator to request access."]})]})})}export{l as PermissionRequired,l as default};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { default as React, PropsWithChildren } from 'react';
|
|
2
|
+
type Permissions = string[];
|
|
3
|
+
interface AccountInfo {
|
|
4
|
+
id: string | null;
|
|
5
|
+
name: string | null;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Returns the user's effective permissions (role-based).
|
|
9
|
+
* Returns null while permissions are being loaded from JWT.
|
|
10
|
+
*/
|
|
11
|
+
export declare const usePermissions: () => Permissions | null;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the account's available permissions (what the subscription grants).
|
|
14
|
+
* Use this to determine if a feature requires an upgrade vs just a role change.
|
|
15
|
+
* Returns null while permissions are being loaded from JWT.
|
|
16
|
+
*/
|
|
17
|
+
export declare const useAccountPermissions: () => Permissions | null;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the current account info (id and name) from the JWT.
|
|
20
|
+
*/
|
|
21
|
+
export declare const useAccount: () => AccountInfo;
|
|
22
|
+
export interface PermissionsProviderProps {
|
|
23
|
+
accessToken: string | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Provider that decodes JWT token and provides permission context to children.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <PermissionsProvider accessToken={token}>
|
|
31
|
+
* <FeatureGate permission="reports:view">
|
|
32
|
+
* <ReportsPage />
|
|
33
|
+
* </FeatureGate>
|
|
34
|
+
* </PermissionsProvider>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function PermissionsProvider({ accessToken, children, }: PropsWithChildren<PermissionsProviderProps>): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export interface IsAllowedToProps {
|
|
39
|
+
/** Permissions to check */
|
|
40
|
+
to: string[];
|
|
41
|
+
/** If true, renders children when user does NOT have the permissions */
|
|
42
|
+
isRestricted?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Conditional render helper based on permissions.
|
|
46
|
+
* Renders children if user has any of the specified permissions.
|
|
47
|
+
* If isRestricted is true, renders children if user does NOT have any of the permissions.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* <IsAllowedTo to={['admin:manage']}>
|
|
52
|
+
* <AdminPanel />
|
|
53
|
+
* </IsAllowedTo>
|
|
54
|
+
*
|
|
55
|
+
* <IsAllowedTo to={['premium:feature']} isRestricted>
|
|
56
|
+
* <UpgradePrompt />
|
|
57
|
+
* </IsAllowedTo>
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function IsAllowedTo({ to, isRestricted, children, }: PropsWithChildren<IsAllowedToProps>): React.ReactNode;
|
|
61
|
+
export default PermissionsProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as u}from"react/jsx-runtime";import{createContext as d,useContext as m,useState as a,useEffect as g}from"react";class c extends Error{}c.prototype.name="InvalidTokenError";function w(n){return decodeURIComponent(atob(n).replace(/(.)/g,(t,r)=>{let e=r.charCodeAt(0).toString(16).toUpperCase();return e.length<2&&(e="0"+e),"%"+e}))}function P(n){let t=n.replace(/-/g,"+").replace(/_/g,"/");switch(t.length%4){case 0:break;case 2:t+="==";break;case 3:t+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return w(t)}catch{return atob(t)}}function b(n,t){if(typeof n!="string")throw new c("Invalid token specified: must be a string");t||(t={});const r=t.header===!0?0:1,e=n.split(".")[r];if(typeof e!="string")throw new c(`Invalid token specified: missing part #${r+1}`);let l;try{l=P(e)}catch(o){throw new c(`Invalid token specified: invalid base64 for part #${r+1} (${o.message})`)}try{return JSON.parse(l)}catch(o){throw new c(`Invalid token specified: invalid json for part #${r+1} (${o.message})`)}}const f=d(null),p=d(null),h=d({id:null,name:null}),x=()=>m(f),I=()=>m(p),k=()=>m(h);function y({accessToken:n,children:t}){const[r,e]=a(null),[l,o]=a(null),[v,i]=a({id:null,name:null});return g(()=>{if(n)try{const s=b(n);e(s.permissions??null),o(s.account_permissions??null),i({id:s.account_id??null,name:s.account_name??null})}catch(s){console.error("Failed to decode JWT token:",s),e(null),o(null),i({id:null,name:null})}else e(null),o(null),i({id:null,name:null})},[n]),u(f.Provider,{value:r,children:u(p.Provider,{value:l,children:u(h.Provider,{value:v,children:t})})})}function E({to:n,isRestricted:t=!1,children:r}){const e=x();return(n==null?void 0:n.some(o=>t?!(e!=null&&e.includes(o)):e==null?void 0:e.includes(o)))?r:null}export{E as IsAllowedTo,y as PermissionsProvider,y as default,k as useAccount,I as useAccountPermissions,x as usePermissions};
|