@flexkit/studio 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/chat-page-YWENJEUP.js +4 -0
  2. package/dist/chat-page-YWENJEUP.js.map +1 -0
  3. package/dist/chunk-2FQWBOU6.js +6 -0
  4. package/dist/chunk-2FQWBOU6.js.map +1 -0
  5. package/dist/chunk-3FIKCGSP.js +4 -0
  6. package/dist/{chunk-ANVO5P65.js.map → chunk-3FIKCGSP.js.map} +1 -1
  7. package/dist/{chunk-JYHZU2UZ.js → chunk-4BX7OJJ6.js} +2 -2
  8. package/dist/{chunk-JYHZU2UZ.js.map → chunk-4BX7OJJ6.js.map} +1 -1
  9. package/dist/{chunk-ZBI744KS.js → chunk-66N44IKJ.js} +3 -3
  10. package/dist/chunk-66N44IKJ.js.map +1 -0
  11. package/dist/{chunk-2IRKGO2B.js → chunk-7ZDMZVDA.js} +5 -5
  12. package/dist/{chunk-2IRKGO2B.js.map → chunk-7ZDMZVDA.js.map} +1 -1
  13. package/dist/{chunk-S7M5CQ5S.js → chunk-GW37ZTR2.js} +2 -2
  14. package/dist/{chunk-S7M5CQ5S.js.map → chunk-GW37ZTR2.js.map} +1 -1
  15. package/dist/chunk-H6TOYVW2.js +3 -0
  16. package/dist/chunk-H6TOYVW2.js.map +1 -0
  17. package/dist/{chunk-5TQF5UQQ.js → chunk-LYGHDJ5A.js} +2 -2
  18. package/dist/{chunk-5TQF5UQQ.js.map → chunk-LYGHDJ5A.js.map} +1 -1
  19. package/dist/chunk-OFLU53AC.js +2 -0
  20. package/dist/{chunk-LQVZWFM2.js.map → chunk-OFLU53AC.js.map} +1 -1
  21. package/dist/chunk-YIGEER6B.js +7 -0
  22. package/dist/chunk-YIGEER6B.js.map +1 -0
  23. package/dist/chunk-Z6IEBNKV.js +2 -0
  24. package/dist/{chunk-GM5OZTHL.js.map → chunk-Z6IEBNKV.js.map} +1 -1
  25. package/dist/index.css +378 -0
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +9 -9
  28. package/dist/index.js.map +1 -1
  29. package/dist/list-3K2PBGML.js +2 -0
  30. package/dist/{list-ZQJ6NHKQ.js.map → list-3K2PBGML.js.map} +1 -1
  31. package/dist/pages-BDZ4ZXBS.js +3 -0
  32. package/dist/{pages-2GQVTLL2.js.map → pages-BDZ4ZXBS.js.map} +1 -1
  33. package/dist/plugin-pages-Q77CBW45.js +2 -0
  34. package/dist/{plugin-pages-E5TUDDT5.js.map → plugin-pages-Q77CBW45.js.map} +1 -1
  35. package/dist/root-4TME2KMP.js +2 -0
  36. package/dist/{root-HC5QZ2JM.js.map → root-4TME2KMP.js.map} +1 -1
  37. package/dist/root-4ZVGVCYY.js +23 -0
  38. package/dist/{root-TXKDRPOK.js.map → root-4ZVGVCYY.js.map} +1 -1
  39. package/dist/{root-BD4VN3RD.js → root-EZWV5VA4.js} +3 -3
  40. package/dist/{root-BD4VN3RD.js.map → root-EZWV5VA4.js.map} +1 -1
  41. package/dist/{root-P6CVZ5ZB.js → root-YKNISFWH.js} +2 -2
  42. package/dist/{root-P6CVZ5ZB.js.map → root-YKNISFWH.js.map} +1 -1
  43. package/dist/{search-PVXTPIYJ.js → search-7NX232AW.js} +2 -2
  44. package/dist/{search-PVXTPIYJ.js.map → search-7NX232AW.js.map} +1 -1
  45. package/dist/{skills-pages-N5KDEHLT.js → skills-pages-SMJ4EWZW.js} +2 -2
  46. package/dist/{skills-pages-N5KDEHLT.js.map → skills-pages-SMJ4EWZW.js.map} +1 -1
  47. package/dist/{spec-renderer-ZZ3GPVKU.js → spec-renderer-5YGDRF52.js} +2 -2
  48. package/dist/{spec-renderer-ZZ3GPVKU.js.map → spec-renderer-5YGDRF52.js.map} +1 -1
  49. package/dist/ui.d.ts +28 -4
  50. package/dist/ui.js +1 -1
  51. package/package.json +4 -4
  52. package/dist/chat-page-H6I3XOKS.js +0 -2
  53. package/dist/chat-page-H6I3XOKS.js.map +0 -1
  54. package/dist/chunk-ANVO5P65.js +0 -4
  55. package/dist/chunk-BURKG2UC.js +0 -6
  56. package/dist/chunk-BURKG2UC.js.map +0 -1
  57. package/dist/chunk-GM5OZTHL.js +0 -2
  58. package/dist/chunk-HROHAMPM.js +0 -3
  59. package/dist/chunk-HROHAMPM.js.map +0 -1
  60. package/dist/chunk-LQVZWFM2.js +0 -2
  61. package/dist/chunk-QHDL6CA2.js +0 -7
  62. package/dist/chunk-QHDL6CA2.js.map +0 -1
  63. package/dist/chunk-ZBI744KS.js.map +0 -1
  64. package/dist/list-ZQJ6NHKQ.js +0 -2
  65. package/dist/pages-2GQVTLL2.js +0 -3
  66. package/dist/plugin-pages-E5TUDDT5.js +0 -2
  67. package/dist/root-HC5QZ2JM.js +0 -2
  68. package/dist/root-TXKDRPOK.js +0 -23
@@ -0,0 +1,2 @@
1
+ import'./index.css';import {q as q$1,o,r}from'./chunk-7ZDMZVDA.js';import {f}from'./chunk-66N44IKJ.js';import {e}from'./chunk-NNA4MLFC.js';import {useCallback}from'react';import {toast}from'sonner';import {useApolloClient}from'@apollo/client/react';function E(i){let{currentProjectSchema:t}=f();return useCallback(a=>{t&&q$1(o(i,t),a);},[i,t])}var g=["image/jpeg","image/png","image/webp","image/vnd.microsoft.icon","image/bmp","image/gif","image/tiff","image/svg+xml","image/avif","image/heic","image/heif","image/heic-sequence","image/heif-sequence","image/apng","audio/aac","audio/mpeg","audio/wav","audio/webm","audio/midi","audio/x-midi","audio/ogg","video/x-msvideo","video/mp4","video/mpeg","video/webm","video/quicktime","video/ogg","video/mp2t","video/3gpp","video/3gpp2","application/x-7z-compressed","application/zip","application/vnd.amazon.ebook","application/octet-stream","application/epub+zip","application/pdf","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-fontobject","application/gzip","application/x-gzip","application/java-archive","application/json","application/ld+json","text/javascript","application/vnd.oasis.opendocument.presentation","application/vnd.oasis.opendocument.spreadsheet","application/vnd.oasis.opendocument.text","application/ogg","application/vnd.ms-powerpoint","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.rar","application/x-tar","application/vnd.visio","application/xhtml+xml","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/xml"];function F(i,t){if(!i.type)return true;let a=t?t.split(",").map(e=>e.trim()).filter(Boolean):g;return a.length===0?true:a.some(e=>e.endsWith("/*")?i.type.startsWith(e.slice(0,-1)):i.type===e)}async function x(i,t){let a=new URLSearchParams({filename:i.name}),e$1=await fetch(`${e(t).assets}?${a.toString()}`,{method:"POST",headers:{"Content-Type":i.type||"application/octet-stream"},body:i});if(!e$1.ok)throw new Error(`Upload failed for ${i.name}`);let n=await e$1.json(),o={_id:n._id,path:n.path??"",originalFilename:n.originalFilename??i.name,size:n.size??i.size,mimeType:n.mimeType??i.type,lqip:n.lqip??"",width:n.width??0,height:n.height??0};return {pathname:o.path,lqip:o.lqip||void 0,originalFilename:o.originalFilename,size:o.size,mimeType:o.mimeType,width:o.width||void 0,height:o.height||void 0,_id:o._id,asset:o}}async function h(i,t){let{projectId:a,accept:e,maxBytes:n=4*1024*1024,onUploadStart:o}=t,l=[];for(let p of Array.from(i)){if(p.size>n){toast.error(`File size too big (max ${(n/(1024*1024)).toFixed(0)}MB): ${p.name}`);continue}if(!F(p,e)){toast.error(`Unsupported file type: ${p.name}`);continue}l.push(p);}if(l.length===0)return [];o?.();try{let p=await Promise.all(l.map(async f=>x(f,a)));return p.length>0&&toast.success(`Uploaded ${p.length} file${p.length>1?"s":""}`),p}catch(p){return console.error(p),toast.error("Upload failed. Please try again."),[]}}async function b(i){let{accept:t,multiple:a=true}=i,e=document.createElement("input");e.type="file",e.accept=t??g.join(","),e.multiple=a,e.style.display="none",document.body.appendChild(e);try{let n=await new Promise(o=>{e.addEventListener("change",()=>o(e.files),{once:!0}),e.addEventListener("cancel",()=>o(null),{once:!0}),e.click();});return !n||n.length===0?[]:h(n,i)}finally{document.body.removeChild(e);}}function q(){let i=useApolloClient();return useCallback(async t=>{let a=t.files?await h(t.files,t):await b(t);return a.length>0&&await r(i,"GetAssets").catch(e=>{console.error("Error refreshing asset lists after upload:",e);}),a},[i])}export{E as a,x as b,q as c};//# sourceMappingURL=chunk-Z6IEBNKV.js.map
2
+ //# sourceMappingURL=chunk-Z6IEBNKV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/graphql-client/use-patch-entity-list.ts","../src/core/upload.ts"],"names":["usePatchEntityList","entityNameOrPlural","schema","useConfig","useCallback","patches","scheduleEntityListPatch","getEntityListQueryName","ACCEPTED_MIME_TYPES","isAcceptedMimeType","file","accept","allowed","pattern","uploadAssetFile","projectId","params","response","apiPaths","data","asset","uploadSelectedFiles","files","options","maxBytes","onUploadStart","validFiles","toast","uploads","error","openFileDialogAndUpload","multiple","input","resolve","useUploadAssets","apolloClient","useApolloClient","scheduleEntityListRefetch"],"mappings":"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","file":"chunk-GM5OZTHL.js","sourcesContent":["import { useCallback } from 'react';\nimport { useConfig } from '../core/config/config-context';\nimport {\n getEntityListQueryName,\n scheduleEntityListPatch,\n type EntityListRowPatch,\n} from './refetch-entity-lists';\n\n/**\n * Patch active list rows for an entity without a soft-refetch.\n * Prefer this after mutations that only change row fields (e.g. tag connect/disconnect).\n */\nexport function usePatchEntityList(entityNameOrPlural: string): (patches: EntityListRowPatch[]) => void {\n const { currentProjectSchema: schema } = useConfig();\n\n return useCallback(\n (patches: EntityListRowPatch[]) => {\n if (!schema) {\n return;\n }\n\n scheduleEntityListPatch(getEntityListQueryName(entityNameOrPlural, schema), patches);\n },\n [entityNameOrPlural, schema]\n );\n}\n","import { useCallback } from 'react';\nimport { toast } from 'sonner';\nimport { useApolloClient } from '@apollo/client/react';\nimport { apiPaths } from './api-paths';\nimport { scheduleEntityListRefetch } from '../graphql-client/refetch-entity-lists';\nimport type { OrderedAssetValue } from '../graphql-client/types';\n\nexport const ACCEPTED_MIME_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/webp',\n 'image/vnd.microsoft.icon',\n 'image/bmp',\n 'image/gif',\n 'image/tiff',\n 'image/svg+xml',\n 'image/avif',\n 'image/heic',\n 'image/heif',\n 'image/heic-sequence',\n 'image/heif-sequence',\n 'image/apng',\n 'audio/aac',\n 'audio/mpeg',\n 'audio/wav',\n 'audio/webm',\n 'audio/midi',\n 'audio/x-midi',\n 'audio/ogg',\n 'video/x-msvideo',\n 'video/mp4',\n 'video/mpeg',\n 'video/webm',\n 'video/quicktime',\n 'video/ogg',\n 'video/mp2t',\n 'video/3gpp',\n 'video/3gpp2',\n 'application/x-7z-compressed',\n 'application/zip',\n 'application/vnd.amazon.ebook',\n 'application/octet-stream',\n 'application/epub+zip',\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-fontobject',\n 'application/gzip',\n 'application/x-gzip',\n 'application/java-archive',\n 'application/json',\n 'application/ld+json',\n 'text/javascript',\n 'application/vnd.oasis.opendocument.presentation',\n 'application/vnd.oasis.opendocument.spreadsheet',\n 'application/vnd.oasis.opendocument.text',\n 'application/ogg',\n 'application/vnd.ms-powerpoint',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'application/vnd.rar',\n 'application/x-tar',\n 'application/vnd.visio',\n 'application/xhtml+xml',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/xml',\n];\n\nexport type UploadedFileResult = {\n pathname: string;\n lqip?: string;\n size: number;\n mimeType: string;\n originalFilename: string;\n width?: number;\n height?: number;\n};\n\nexport type UploadedAssetResult = UploadedFileResult & {\n asset: OrderedAssetValue;\n _id: string;\n};\n\ntype AssetUploadResponse = {\n _id: string;\n path: string | null;\n mimeType: string | null;\n originalFilename: string | null;\n size: number | null;\n width: number | null;\n height: number | null;\n lqip: string | null;\n sha256: string | null;\n deduped: boolean;\n};\n\nexport type OpenFileDialogAndUploadOptions = {\n projectId: string | undefined;\n accept?: string;\n files?: File[] | FileList;\n multiple?: boolean;\n maxBytes?: number;\n onUploadStart?: () => void;\n};\n\nfunction isAcceptedMimeType(file: File, accept?: string): boolean {\n if (!file.type) {\n return true;\n }\n\n const allowed = accept\n ? accept\n .split(',')\n .map((pattern) => pattern.trim())\n .filter(Boolean)\n : ACCEPTED_MIME_TYPES;\n\n if (allowed.length === 0) {\n return true;\n }\n\n return allowed.some((pattern) => {\n if (pattern.endsWith('/*')) {\n return file.type.startsWith(pattern.slice(0, -1));\n }\n\n return file.type === pattern;\n });\n}\n\n/**\n * Uploads a single file to the one-shot /assets endpoint, which stores the\n * blob and creates the _asset node in a single request.\n */\nexport async function uploadAssetFile(file: File, projectId: string | undefined): Promise<UploadedAssetResult> {\n const params = new URLSearchParams({ filename: file.name });\n const response = await fetch(`${apiPaths(projectId).assets}?${params.toString()}`, {\n method: 'POST',\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n body: file,\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed for ${file.name}`);\n }\n\n const data = (await response.json()) as AssetUploadResponse;\n const asset: OrderedAssetValue = {\n _id: data._id,\n path: data.path ?? '',\n originalFilename: data.originalFilename ?? file.name,\n size: data.size ?? file.size,\n mimeType: data.mimeType ?? file.type,\n lqip: data.lqip ?? '',\n width: data.width ?? 0,\n height: data.height ?? 0,\n };\n\n return {\n pathname: asset.path,\n lqip: asset.lqip || undefined,\n originalFilename: asset.originalFilename,\n size: asset.size,\n mimeType: asset.mimeType,\n width: asset.width || undefined,\n height: asset.height || undefined,\n _id: asset._id,\n asset,\n };\n}\n\nasync function uploadSelectedFiles(\n files: File[] | FileList,\n options: OpenFileDialogAndUploadOptions\n): Promise<UploadedAssetResult[]> {\n const { projectId, accept, maxBytes = 4 * 1024 * 1024, onUploadStart } = options;\n const validFiles: File[] = [];\n\n for (const file of Array.from(files)) {\n if (file.size > maxBytes) {\n toast.error(`File size too big (max ${(maxBytes / (1024 * 1024)).toFixed(0)}MB): ${file.name}`);\n\n continue;\n }\n\n if (!isAcceptedMimeType(file, accept)) {\n toast.error(`Unsupported file type: ${file.name}`);\n\n continue;\n }\n\n validFiles.push(file);\n }\n\n if (validFiles.length === 0) {\n return [];\n }\n\n onUploadStart?.();\n\n try {\n const uploads = await Promise.all(validFiles.map(async (file) => uploadAssetFile(file, projectId)));\n\n if (uploads.length > 0) {\n toast.success(`Uploaded ${uploads.length} file${uploads.length > 1 ? 's' : ''}`);\n }\n\n return uploads;\n } catch (error) {\n console.error(error);\n toast.error('Upload failed. Please try again.');\n\n return [];\n }\n}\n\n/**\n * Opens a native file picker and uploads selected files to the Flexkit assets\n * endpoint, which also creates an asset node in the database.\n * Returns a list of uploaded file results. Skips files that exceed maxBytes.\n */\nasync function openFileDialogAndUpload(options: OpenFileDialogAndUploadOptions): Promise<UploadedAssetResult[]> {\n const { accept, multiple = true } = options;\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = accept ?? ACCEPTED_MIME_TYPES.join(',');\n input.multiple = multiple;\n input.style.display = 'none';\n document.body.appendChild(input);\n\n try {\n const files = await new Promise<FileList | null>((resolve) => {\n input.addEventListener('change', () => resolve(input.files), { once: true });\n input.addEventListener('cancel', () => resolve(null), { once: true });\n input.click();\n });\n\n if (!files || files.length === 0) {\n return [];\n }\n\n return uploadSelectedFiles(files, options);\n } finally {\n document.body.removeChild(input);\n }\n}\n\nexport function useUploadAssets(): (options: OpenFileDialogAndUploadOptions) => Promise<UploadedAssetResult[]> {\n const apolloClient = useApolloClient();\n\n return useCallback(\n async (options: OpenFileDialogAndUploadOptions) => {\n const uploads = options.files\n ? await uploadSelectedFiles(options.files, options)\n : await openFileDialogAndUpload(options);\n\n if (uploads.length > 0) {\n // Upload is outside Apollo; soft-refresh mounted asset lists via useEntityQuery.\n await scheduleEntityListRefetch(apolloClient, 'GetAssets').catch((error: unknown) => {\n console.error('Error refreshing asset lists after upload:', error);\n });\n }\n\n return uploads;\n },\n [apolloClient]\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/graphql-client/use-patch-entity-list.ts","../src/core/upload.ts"],"names":["usePatchEntityList","entityNameOrPlural","schema","useConfig","useCallback","patches","scheduleEntityListPatch","getEntityListQueryName","ACCEPTED_MIME_TYPES","isAcceptedMimeType","file","accept","allowed","pattern","uploadAssetFile","projectId","params","response","apiPaths","data","asset","uploadSelectedFiles","files","options","maxBytes","onUploadStart","validFiles","toast","uploads","error","openFileDialogAndUpload","multiple","input","resolve","useUploadAssets","apolloClient","useApolloClient","scheduleEntityListRefetch"],"mappings":"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","file":"chunk-Z6IEBNKV.js","sourcesContent":["import { useCallback } from 'react';\nimport { useConfig } from '../core/config/config-context';\nimport {\n getEntityListQueryName,\n scheduleEntityListPatch,\n type EntityListRowPatch,\n} from './refetch-entity-lists';\n\n/**\n * Patch active list rows for an entity without a soft-refetch.\n * Prefer this after mutations that only change row fields (e.g. tag connect/disconnect).\n */\nexport function usePatchEntityList(entityNameOrPlural: string): (patches: EntityListRowPatch[]) => void {\n const { currentProjectSchema: schema } = useConfig();\n\n return useCallback(\n (patches: EntityListRowPatch[]) => {\n if (!schema) {\n return;\n }\n\n scheduleEntityListPatch(getEntityListQueryName(entityNameOrPlural, schema), patches);\n },\n [entityNameOrPlural, schema]\n );\n}\n","import { useCallback } from 'react';\nimport { toast } from 'sonner';\nimport { useApolloClient } from '@apollo/client/react';\nimport { apiPaths } from './api-paths';\nimport { scheduleEntityListRefetch } from '../graphql-client/refetch-entity-lists';\nimport type { OrderedAssetValue } from '../graphql-client/types';\n\nexport const ACCEPTED_MIME_TYPES = [\n 'image/jpeg',\n 'image/png',\n 'image/webp',\n 'image/vnd.microsoft.icon',\n 'image/bmp',\n 'image/gif',\n 'image/tiff',\n 'image/svg+xml',\n 'image/avif',\n 'image/heic',\n 'image/heif',\n 'image/heic-sequence',\n 'image/heif-sequence',\n 'image/apng',\n 'audio/aac',\n 'audio/mpeg',\n 'audio/wav',\n 'audio/webm',\n 'audio/midi',\n 'audio/x-midi',\n 'audio/ogg',\n 'video/x-msvideo',\n 'video/mp4',\n 'video/mpeg',\n 'video/webm',\n 'video/quicktime',\n 'video/ogg',\n 'video/mp2t',\n 'video/3gpp',\n 'video/3gpp2',\n 'application/x-7z-compressed',\n 'application/zip',\n 'application/vnd.amazon.ebook',\n 'application/octet-stream',\n 'application/epub+zip',\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-fontobject',\n 'application/gzip',\n 'application/x-gzip',\n 'application/java-archive',\n 'application/json',\n 'application/ld+json',\n 'text/javascript',\n 'application/vnd.oasis.opendocument.presentation',\n 'application/vnd.oasis.opendocument.spreadsheet',\n 'application/vnd.oasis.opendocument.text',\n 'application/ogg',\n 'application/vnd.ms-powerpoint',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n 'application/vnd.rar',\n 'application/x-tar',\n 'application/vnd.visio',\n 'application/xhtml+xml',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/xml',\n];\n\nexport type UploadedFileResult = {\n pathname: string;\n lqip?: string;\n size: number;\n mimeType: string;\n originalFilename: string;\n width?: number;\n height?: number;\n};\n\nexport type UploadedAssetResult = UploadedFileResult & {\n asset: OrderedAssetValue;\n _id: string;\n};\n\ntype AssetUploadResponse = {\n _id: string;\n path: string | null;\n mimeType: string | null;\n originalFilename: string | null;\n size: number | null;\n width: number | null;\n height: number | null;\n lqip: string | null;\n sha256: string | null;\n deduped: boolean;\n};\n\nexport type OpenFileDialogAndUploadOptions = {\n projectId: string | undefined;\n accept?: string;\n files?: File[] | FileList;\n multiple?: boolean;\n maxBytes?: number;\n onUploadStart?: () => void;\n};\n\nfunction isAcceptedMimeType(file: File, accept?: string): boolean {\n if (!file.type) {\n return true;\n }\n\n const allowed = accept\n ? accept\n .split(',')\n .map((pattern) => pattern.trim())\n .filter(Boolean)\n : ACCEPTED_MIME_TYPES;\n\n if (allowed.length === 0) {\n return true;\n }\n\n return allowed.some((pattern) => {\n if (pattern.endsWith('/*')) {\n return file.type.startsWith(pattern.slice(0, -1));\n }\n\n return file.type === pattern;\n });\n}\n\n/**\n * Uploads a single file to the one-shot /assets endpoint, which stores the\n * blob and creates the _asset node in a single request.\n */\nexport async function uploadAssetFile(file: File, projectId: string | undefined): Promise<UploadedAssetResult> {\n const params = new URLSearchParams({ filename: file.name });\n const response = await fetch(`${apiPaths(projectId).assets}?${params.toString()}`, {\n method: 'POST',\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n body: file,\n });\n\n if (!response.ok) {\n throw new Error(`Upload failed for ${file.name}`);\n }\n\n const data = (await response.json()) as AssetUploadResponse;\n const asset: OrderedAssetValue = {\n _id: data._id,\n path: data.path ?? '',\n originalFilename: data.originalFilename ?? file.name,\n size: data.size ?? file.size,\n mimeType: data.mimeType ?? file.type,\n lqip: data.lqip ?? '',\n width: data.width ?? 0,\n height: data.height ?? 0,\n };\n\n return {\n pathname: asset.path,\n lqip: asset.lqip || undefined,\n originalFilename: asset.originalFilename,\n size: asset.size,\n mimeType: asset.mimeType,\n width: asset.width || undefined,\n height: asset.height || undefined,\n _id: asset._id,\n asset,\n };\n}\n\nasync function uploadSelectedFiles(\n files: File[] | FileList,\n options: OpenFileDialogAndUploadOptions\n): Promise<UploadedAssetResult[]> {\n const { projectId, accept, maxBytes = 4 * 1024 * 1024, onUploadStart } = options;\n const validFiles: File[] = [];\n\n for (const file of Array.from(files)) {\n if (file.size > maxBytes) {\n toast.error(`File size too big (max ${(maxBytes / (1024 * 1024)).toFixed(0)}MB): ${file.name}`);\n\n continue;\n }\n\n if (!isAcceptedMimeType(file, accept)) {\n toast.error(`Unsupported file type: ${file.name}`);\n\n continue;\n }\n\n validFiles.push(file);\n }\n\n if (validFiles.length === 0) {\n return [];\n }\n\n onUploadStart?.();\n\n try {\n const uploads = await Promise.all(validFiles.map(async (file) => uploadAssetFile(file, projectId)));\n\n if (uploads.length > 0) {\n toast.success(`Uploaded ${uploads.length} file${uploads.length > 1 ? 's' : ''}`);\n }\n\n return uploads;\n } catch (error) {\n console.error(error);\n toast.error('Upload failed. Please try again.');\n\n return [];\n }\n}\n\n/**\n * Opens a native file picker and uploads selected files to the Flexkit assets\n * endpoint, which also creates an asset node in the database.\n * Returns a list of uploaded file results. Skips files that exceed maxBytes.\n */\nasync function openFileDialogAndUpload(options: OpenFileDialogAndUploadOptions): Promise<UploadedAssetResult[]> {\n const { accept, multiple = true } = options;\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = accept ?? ACCEPTED_MIME_TYPES.join(',');\n input.multiple = multiple;\n input.style.display = 'none';\n document.body.appendChild(input);\n\n try {\n const files = await new Promise<FileList | null>((resolve) => {\n input.addEventListener('change', () => resolve(input.files), { once: true });\n input.addEventListener('cancel', () => resolve(null), { once: true });\n input.click();\n });\n\n if (!files || files.length === 0) {\n return [];\n }\n\n return uploadSelectedFiles(files, options);\n } finally {\n document.body.removeChild(input);\n }\n}\n\nexport function useUploadAssets(): (options: OpenFileDialogAndUploadOptions) => Promise<UploadedAssetResult[]> {\n const apolloClient = useApolloClient();\n\n return useCallback(\n async (options: OpenFileDialogAndUploadOptions) => {\n const uploads = options.files\n ? await uploadSelectedFiles(options.files, options)\n : await openFileDialogAndUpload(options);\n\n if (uploads.length > 0) {\n // Upload is outside Apollo; soft-refresh mounted asset lists via useEntityQuery.\n await scheduleEntityListRefetch(apolloClient, 'GetAssets').catch((error: unknown) => {\n console.error('Error refreshing asset lists after upload:', error);\n });\n }\n\n return uploads;\n },\n [apolloClient]\n );\n}\n"]}
package/dist/index.css CHANGED
@@ -80,11 +80,13 @@
80
80
  --fk-tracking-tight: -0.025em;
81
81
  --fk-tracking-wide: 0.025em;
82
82
  --fk-tracking-widest: 0.1em;
83
+ --fk-leading-tight: 1.25;
83
84
  --fk-leading-snug: 1.375;
84
85
  --fk-leading-normal: 1.5;
85
86
  --fk-leading-relaxed: 1.625;
86
87
  --fk-radius-xs: 0.125rem;
87
88
  --fk-radius-xl: 0.75rem;
89
+ --fk-radius-3xl: 1.5rem;
88
90
  --fk-drop-shadow-md: 0 3px 3px rgb(0 0 0 / 0.12);
89
91
  --fk-ease-out: cubic-bezier(0, 0, 0.2, 1);
90
92
  --fk-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
@@ -1805,6 +1807,9 @@
1805
1807
  .fk\:min-w-34 {
1806
1808
  min-width: calc(var(--fk-spacing) * 34);
1807
1809
  }
1810
+ .fk\:min-w-40 {
1811
+ min-width: calc(var(--fk-spacing) * 40);
1812
+ }
1808
1813
  .fk\:min-w-44 {
1809
1814
  min-width: calc(var(--fk-spacing) * 44);
1810
1815
  }
@@ -1919,6 +1924,48 @@
1919
1924
  animation-direction: reverse;
1920
1925
  }
1921
1926
  }
1927
+ .fk\:scroll-fade-x {
1928
+ --_scroll-fade-size-s: var(
1929
+ --scroll-fade-s-size,
1930
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
1931
+ );
1932
+ --_scroll-fade-size-e: var(
1933
+ --scroll-fade-e-size,
1934
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
1935
+ );
1936
+ --scroll-fade-inline: linear-gradient(
1937
+ to right,
1938
+ transparent 0,
1939
+ #000 var(--scroll-fade-s, 0px),
1940
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
1941
+ transparent 100%
1942
+ );
1943
+ &:where([dir="rtl"], [dir="rtl"] *) {
1944
+ --scroll-fade-inline: linear-gradient(
1945
+ to left,
1946
+ transparent 0,
1947
+ #000 var(--scroll-fade-s, 0px),
1948
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
1949
+ transparent 100%
1950
+ );
1951
+ }
1952
+ -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
1953
+ mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
1954
+ -webkit-mask-composite: source-in;
1955
+ mask-composite: intersect;
1956
+ -webkit-mask-repeat: no-repeat;
1957
+ mask-repeat: no-repeat;
1958
+ @supports (animation-timeline: scroll()) {
1959
+ animation: scroll-fade-reveal-s 1ms ease-in-out, scroll-fade-reveal-e 1ms ease-in-out;
1960
+ animation-timeline: scroll(self inline), scroll(self inline);
1961
+ animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)), calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
1962
+ animation-fill-mode: both;
1963
+ }
1964
+ @supports not (animation-timeline: scroll()) {
1965
+ --scroll-fade-s: var(--_scroll-fade-size-s);
1966
+ --scroll-fade-e: var(--_scroll-fade-size-e);
1967
+ }
1968
+ }
1922
1969
  .fk\:animate-bounce {
1923
1970
  animation: var(--fk-animate-bounce);
1924
1971
  }
@@ -1958,9 +2005,18 @@
1958
2005
  .fk\:resize-none {
1959
2006
  resize: none;
1960
2007
  }
2008
+ .fk\:snap-x {
2009
+ scroll-snap-type: x var(--tw-scroll-snap-strictness);
2010
+ }
2011
+ .fk\:snap-mandatory {
2012
+ --tw-scroll-snap-strictness: mandatory;
2013
+ }
1961
2014
  .fk\:scroll-my-1 {
1962
2015
  scroll-margin-block: calc(var(--fk-spacing) * 1);
1963
2016
  }
2017
+ .fk\:scroll-px-1 {
2018
+ scroll-padding-inline: calc(var(--fk-spacing) * 1);
2019
+ }
1964
2020
  .fk\:scroll-py-1 {
1965
2021
  scroll-padding-block: calc(var(--fk-spacing) * 1);
1966
2022
  }
@@ -2241,9 +2297,15 @@
2241
2297
  .fk\:overflow-y-hidden {
2242
2298
  overflow-y: hidden;
2243
2299
  }
2300
+ .fk\:overscroll-x-contain {
2301
+ overscroll-behavior-x: contain;
2302
+ }
2244
2303
  .fk\:rounded {
2245
2304
  border-radius: 0.25rem;
2246
2305
  }
2306
+ .fk\:rounded-3xl {
2307
+ border-radius: var(--fk-radius-3xl);
2308
+ }
2247
2309
  .fk\:rounded-\[2px\] {
2248
2310
  border-radius: 2px;
2249
2311
  }
@@ -2955,6 +3017,9 @@
2955
3017
  .fk\:pb-20 {
2956
3018
  padding-bottom: calc(var(--fk-spacing) * 20);
2957
3019
  }
3020
+ .fk\:pb-\[12vh\] {
3021
+ padding-bottom: 12vh;
3022
+ }
2958
3023
  .fk\:pl-0 {
2959
3024
  padding-left: calc(var(--fk-spacing) * 0);
2960
3025
  }
@@ -3093,6 +3158,10 @@
3093
3158
  --tw-leading: var(--fk-leading-snug);
3094
3159
  line-height: var(--fk-leading-snug);
3095
3160
  }
3161
+ .fk\:leading-tight {
3162
+ --tw-leading: var(--fk-leading-tight);
3163
+ line-height: var(--fk-leading-tight);
3164
+ }
3096
3165
  .fk\:font-bold {
3097
3166
  --tw-font-weight: var(--fk-font-weight-bold);
3098
3167
  font-weight: var(--fk-font-weight-bold);
@@ -3787,6 +3856,36 @@
3787
3856
  height: calc(var(--fk-spacing) * 9);
3788
3857
  }
3789
3858
  }
3859
+ .fk\:group-data-\[orientation\=vertical\]\/attachment\:absolute {
3860
+ &:is(:where(.fk\:group\/attachment)[data-orientation="vertical"] *) {
3861
+ position: absolute;
3862
+ }
3863
+ }
3864
+ .fk\:group-data-\[orientation\=vertical\]\/attachment\:top-3 {
3865
+ &:is(:where(.fk\:group\/attachment)[data-orientation="vertical"] *) {
3866
+ top: calc(var(--fk-spacing) * 3);
3867
+ }
3868
+ }
3869
+ .fk\:group-data-\[orientation\=vertical\]\/attachment\:right-3 {
3870
+ &:is(:where(.fk\:group\/attachment)[data-orientation="vertical"] *) {
3871
+ right: calc(var(--fk-spacing) * 3);
3872
+ }
3873
+ }
3874
+ .fk\:group-data-\[orientation\=vertical\]\/attachment\:w-full {
3875
+ &:is(:where(.fk\:group\/attachment)[data-orientation="vertical"] *) {
3876
+ width: 100%;
3877
+ }
3878
+ }
3879
+ .fk\:group-data-\[orientation\=vertical\]\/attachment\:gap-1 {
3880
+ &:is(:where(.fk\:group\/attachment)[data-orientation="vertical"] *) {
3881
+ gap: calc(var(--fk-spacing) * 1);
3882
+ }
3883
+ }
3884
+ .fk\:group-data-\[orientation\=vertical\]\/attachment\:px-1 {
3885
+ &:is(:where(.fk\:group\/attachment)[data-orientation="vertical"] *) {
3886
+ padding-inline: calc(var(--fk-spacing) * 1);
3887
+ }
3888
+ }
3790
3889
  .fk\:group-data-\[orientation\=vertical\]\/tabs\:h-fit {
3791
3890
  &:is(:where(.fk\:group\/tabs)[data-orientation="vertical"] *) {
3792
3891
  height: fit-content;
@@ -3862,6 +3961,11 @@
3862
3961
  grid-template-columns: repeat(2, minmax(0, 1fr));
3863
3962
  }
3864
3963
  }
3964
+ .fk\:group-data-\[size\=sm\]\/attachment\:w-8 {
3965
+ &:is(:where(.fk\:group\/attachment)[data-size="sm"] *) {
3966
+ width: calc(var(--fk-spacing) * 8);
3967
+ }
3968
+ }
3865
3969
  .fk\:group-data-\[size\=sm\]\/avatar\:size-2 {
3866
3970
  &:is(:where(.fk\:group\/avatar)[data-size="sm"] *) {
3867
3971
  width: calc(var(--fk-spacing) * 2);
@@ -3880,6 +3984,47 @@
3880
3984
  height: calc(var(--fk-spacing) * 3);
3881
3985
  }
3882
3986
  }
3987
+ .fk\:group-data-\[size\=xs\]\/attachment\:w-7 {
3988
+ &:is(:where(.fk\:group\/attachment)[data-size="xs"] *) {
3989
+ width: calc(var(--fk-spacing) * 7);
3990
+ }
3991
+ }
3992
+ .fk\:group-data-\[size\=xs\]\/attachment\:rounded-md {
3993
+ &:is(:where(.fk\:group\/attachment)[data-size="xs"] *) {
3994
+ border-radius: calc(var(--radius) - 2px);
3995
+ }
3996
+ }
3997
+ .fk\:group-data-\[state\=done\]\/attachment\:opacity-100 {
3998
+ &:is(:where(.fk\:group\/attachment)[data-state="done"] *) {
3999
+ opacity: 100%;
4000
+ }
4001
+ }
4002
+ .fk\:group-data-\[state\=error\]\/attachment\:bg-destructive\/10 {
4003
+ &:is(:where(.fk\:group\/attachment)[data-state="error"] *) {
4004
+ background-color: hsl(var(--destructive));
4005
+ @supports (color: color-mix(in lab, red, red)) {
4006
+ background-color: color-mix(in oklab, hsl(var(--destructive)) 10%, transparent);
4007
+ }
4008
+ }
4009
+ }
4010
+ .fk\:group-data-\[state\=error\]\/attachment\:text-destructive {
4011
+ &:is(:where(.fk\:group\/attachment)[data-state="error"] *) {
4012
+ color: hsl(var(--destructive));
4013
+ }
4014
+ }
4015
+ .fk\:group-data-\[state\=error\]\/attachment\:text-destructive\/80 {
4016
+ &:is(:where(.fk\:group\/attachment)[data-state="error"] *) {
4017
+ color: hsl(var(--destructive));
4018
+ @supports (color: color-mix(in lab, red, red)) {
4019
+ color: color-mix(in oklab, hsl(var(--destructive)) 80%, transparent);
4020
+ }
4021
+ }
4022
+ }
4023
+ .fk\:group-data-\[state\=idle\]\/attachment\:opacity-100 {
4024
+ &:is(:where(.fk\:group\/attachment)[data-state="idle"] *) {
4025
+ opacity: 100%;
4026
+ }
4027
+ }
3883
4028
  .fk\:group-data-\[state\=open\]\:rotate-90 {
3884
4029
  &:is(:where(.fk\:group)[data-state="open"] *) {
3885
4030
  rotate: 90deg;
@@ -3890,6 +4035,66 @@
3890
4035
  rotate: 180deg;
3891
4036
  }
3892
4037
  }
4038
+ .fk\:group-data-\[state\=processing\]\/attachment\:shimmer {
4039
+ &:is(:where(.fk\:group\/attachment)[data-state="processing"] *) {
4040
+ --_spread: var(--shimmer-spread, calc(3ch + 40px));
4041
+ --_base: currentColor;
4042
+ --_highlight: var(
4043
+ --shimmer-color,
4044
+ oklch(from currentColor l c h / calc(alpha* 0.2))
4045
+ );
4046
+ background-image: var( --shimmer-image, linear-gradient( calc(90deg + var(--shimmer-angle)), var(--_base) calc(50% - var(--_spread)), var(--_highlight) calc(50% - var(--_spread) * 0.5), var(--_highlight) 50%, var(--_highlight) calc(50% + var(--_spread) * 0.5), var(--_base) calc(50% + var(--_spread)) ) );
4047
+ @supports (color: color-mix(in lab, red, red)) {
4048
+ background-image: var( --shimmer-image, linear-gradient( calc(90deg + var(--shimmer-angle)), var(--_base) calc(50% - var(--_spread)), color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% - var(--_spread) * 0.5), var(--_highlight) 50%, color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% + var(--_spread) * 0.5), var(--_base) calc(50% + var(--_spread)) ) );
4049
+ }
4050
+ background-repeat: no-repeat;
4051
+ background-size: calc(200% + var(--_spread) * 2) 100%;
4052
+ background-position: 0 0;
4053
+ background-clip: text;
4054
+ -webkit-background-clip: text;
4055
+ -webkit-text-fill-color: var(--shimmer-text-fill, transparent);
4056
+ animation: tw-shimmer var(--shimmer-duration, 2s) linear infinite;
4057
+ &:is([style="color-scheme: dark;"] *) {
4058
+ --_highlight: var(
4059
+ --shimmer-color,
4060
+ oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.4))
4061
+ );
4062
+ }
4063
+ &:where([dir="rtl"], [dir="rtl"] *) {
4064
+ animation-direction: reverse;
4065
+ }
4066
+ }
4067
+ }
4068
+ .fk\:group-data-\[state\=uploading\]\/attachment\:shimmer {
4069
+ &:is(:where(.fk\:group\/attachment)[data-state="uploading"] *) {
4070
+ --_spread: var(--shimmer-spread, calc(3ch + 40px));
4071
+ --_base: currentColor;
4072
+ --_highlight: var(
4073
+ --shimmer-color,
4074
+ oklch(from currentColor l c h / calc(alpha* 0.2))
4075
+ );
4076
+ background-image: var( --shimmer-image, linear-gradient( calc(90deg + var(--shimmer-angle)), var(--_base) calc(50% - var(--_spread)), var(--_highlight) calc(50% - var(--_spread) * 0.5), var(--_highlight) 50%, var(--_highlight) calc(50% + var(--_spread) * 0.5), var(--_base) calc(50% + var(--_spread)) ) );
4077
+ @supports (color: color-mix(in lab, red, red)) {
4078
+ background-image: var( --shimmer-image, linear-gradient( calc(90deg + var(--shimmer-angle)), var(--_base) calc(50% - var(--_spread)), color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% - var(--_spread) * 0.5), var(--_highlight) 50%, color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% + var(--_spread) * 0.5), var(--_base) calc(50% + var(--_spread)) ) );
4079
+ }
4080
+ background-repeat: no-repeat;
4081
+ background-size: calc(200% + var(--_spread) * 2) 100%;
4082
+ background-position: 0 0;
4083
+ background-clip: text;
4084
+ -webkit-background-clip: text;
4085
+ -webkit-text-fill-color: var(--shimmer-text-fill, transparent);
4086
+ animation: tw-shimmer var(--shimmer-duration, 2s) linear infinite;
4087
+ &:is([style="color-scheme: dark;"] *) {
4088
+ --_highlight: var(
4089
+ --shimmer-color,
4090
+ oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.4))
4091
+ );
4092
+ }
4093
+ &:where([dir="rtl"], [dir="rtl"] *) {
4094
+ animation-direction: reverse;
4095
+ }
4096
+ }
4097
+ }
3893
4098
  .fk\:group-data-\[variant\=floating\]\:rounded-lg {
3894
4099
  &:is(:where(.fk\:group)[data-variant="floating"] *) {
3895
4100
  border-radius: var(--radius);
@@ -4400,6 +4605,12 @@
4400
4605
  padding-bottom: calc(var(--fk-spacing) * 0);
4401
4606
  }
4402
4607
  }
4608
+ .fk\:focus-within\:ring-1 {
4609
+ &:focus-within {
4610
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
4611
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
4612
+ }
4613
+ }
4403
4614
  .fk\:focus-within\:ring-2 {
4404
4615
  &:focus-within {
4405
4616
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
@@ -4411,6 +4622,14 @@
4411
4622
  --tw-ring-color: hsl(var(--ring));
4412
4623
  }
4413
4624
  }
4625
+ .fk\:focus-within\:ring-ring\/50 {
4626
+ &:focus-within {
4627
+ --tw-ring-color: hsl(var(--ring));
4628
+ @supports (color: color-mix(in lab, red, red)) {
4629
+ --tw-ring-color: color-mix(in oklab, hsl(var(--ring)) 50%, transparent);
4630
+ }
4631
+ }
4632
+ }
4414
4633
  .fk\:focus-within\:ring-offset-2 {
4415
4634
  &:focus-within {
4416
4635
  --tw-ring-offset-width: 2px;
@@ -4975,6 +5194,56 @@
4975
5194
  column-gap: calc(var(--fk-spacing) * 6);
4976
5195
  }
4977
5196
  }
5197
+ .fk\:has-data-\[slot\=attachment-content\]\:w-30 {
5198
+ &:has(*[data-slot="attachment-content"]) {
5199
+ width: calc(var(--fk-spacing) * 30);
5200
+ }
5201
+ }
5202
+ .fk\:has-data-\[slot\=attachment-content\]\:px-1\.5 {
5203
+ &:has(*[data-slot="attachment-content"]) {
5204
+ padding-inline: calc(var(--fk-spacing) * 1.5);
5205
+ }
5206
+ }
5207
+ .fk\:has-data-\[slot\=attachment-content\]\:px-2 {
5208
+ &:has(*[data-slot="attachment-content"]) {
5209
+ padding-inline: calc(var(--fk-spacing) * 2);
5210
+ }
5211
+ }
5212
+ .fk\:has-data-\[slot\=attachment-content\]\:px-2\.5 {
5213
+ &:has(*[data-slot="attachment-content"]) {
5214
+ padding-inline: calc(var(--fk-spacing) * 2.5);
5215
+ }
5216
+ }
5217
+ .fk\:has-data-\[slot\=attachment-content\]\:py-1 {
5218
+ &:has(*[data-slot="attachment-content"]) {
5219
+ padding-block: calc(var(--fk-spacing) * 1);
5220
+ }
5221
+ }
5222
+ .fk\:has-data-\[slot\=attachment-content\]\:py-1\.5 {
5223
+ &:has(*[data-slot="attachment-content"]) {
5224
+ padding-block: calc(var(--fk-spacing) * 1.5);
5225
+ }
5226
+ }
5227
+ .fk\:has-data-\[slot\=attachment-content\]\:py-2 {
5228
+ &:has(*[data-slot="attachment-content"]) {
5229
+ padding-block: calc(var(--fk-spacing) * 2);
5230
+ }
5231
+ }
5232
+ .fk\:has-data-\[slot\=attachment-media\]\:p-1 {
5233
+ &:has(*[data-slot="attachment-media"]) {
5234
+ padding: calc(var(--fk-spacing) * 1);
5235
+ }
5236
+ }
5237
+ .fk\:has-data-\[slot\=attachment-media\]\:p-1\.5 {
5238
+ &:has(*[data-slot="attachment-media"]) {
5239
+ padding: calc(var(--fk-spacing) * 1.5);
5240
+ }
5241
+ }
5242
+ .fk\:has-data-\[slot\=attachment-media\]\:p-2 {
5243
+ &:has(*[data-slot="attachment-media"]) {
5244
+ padding: calc(var(--fk-spacing) * 2);
5245
+ }
5246
+ }
4978
5247
  .fk\:has-data-\[variant\=inset\]\:bg-sidebar {
4979
5248
  &:has(*[data-variant="inset"]) {
4980
5249
  background-color: hsl(var(--sidebar-background));
@@ -5048,6 +5317,18 @@
5048
5317
  gap: calc(var(--fk-spacing) * 2);
5049
5318
  }
5050
5319
  }
5320
+ .fk\:has-\[\>a\,\>button\]\:hover\:bg-muted\/50 {
5321
+ &:has(>a,>button) {
5322
+ &:hover {
5323
+ @media (hover: hover) {
5324
+ background-color: hsl(var(--muted));
5325
+ @supports (color: color-mix(in lab, red, red)) {
5326
+ background-color: color-mix(in oklab, hsl(var(--muted)) 50%, transparent);
5327
+ }
5328
+ }
5329
+ }
5330
+ }
5331
+ }
5051
5332
  .fk\:has-\[\>button\]\:mr-\[-0\.4rem\] {
5052
5333
  &:has(>button) {
5053
5334
  margin-right: -0.4rem;
@@ -5472,6 +5753,20 @@
5472
5753
  max-width: var(--fk-container-xs);
5473
5754
  }
5474
5755
  }
5756
+ .fk\:\*\:data-\[slot\=attachment\]\:flex-none {
5757
+ :is(& > *) {
5758
+ &[data-slot="attachment"] {
5759
+ flex: none;
5760
+ }
5761
+ }
5762
+ }
5763
+ .fk\:\*\:data-\[slot\=attachment\]\:snap-start {
5764
+ :is(& > *) {
5765
+ &[data-slot="attachment"] {
5766
+ scroll-snap-align: start;
5767
+ }
5768
+ }
5769
+ }
5475
5770
  .fk\:\*\:data-\[slot\=avatar\]\:ring-2 {
5476
5771
  :is(& > *) {
5477
5772
  &[data-slot="avatar"] {
@@ -5560,6 +5855,16 @@
5560
5855
  }
5561
5856
  }
5562
5857
  }
5858
+ .fk\:group-data-\[orientation\=vertical\]\/attachment\:\*\:data-\[slot\=spinner\]\:size-6\! {
5859
+ &:is(:where(.fk\:group\/attachment)[data-orientation="vertical"] *) {
5860
+ :is(& > *) {
5861
+ &[data-slot="spinner"] {
5862
+ width: calc(var(--fk-spacing) * 6) !important;
5863
+ height: calc(var(--fk-spacing) * 6) !important;
5864
+ }
5865
+ }
5866
+ }
5867
+ }
5563
5868
  .fk\:data-\[spacing\=0\]\:rounded-none {
5564
5869
  &[data-spacing="0"] {
5565
5870
  border-radius: 0;
@@ -5723,6 +6028,20 @@
5723
6028
  --tw-exit-scale: .95;
5724
6029
  }
5725
6030
  }
6031
+ .fk\:data-\[state\=error\]\:border-destructive\/30 {
6032
+ &[data-state="error"] {
6033
+ border-color: hsl(var(--destructive));
6034
+ @supports (color: color-mix(in lab, red, red)) {
6035
+ border-color: color-mix(in oklab, hsl(var(--destructive)) 30%, transparent);
6036
+ }
6037
+ }
6038
+ }
6039
+ .fk\:data-\[state\=idle\]\:border-dashed {
6040
+ &[data-state="idle"] {
6041
+ --tw-border-style: dashed;
6042
+ border-style: dashed;
6043
+ }
6044
+ }
5726
6045
  .fk\:data-\[state\=on\]\:bg-accent {
5727
6046
  &[data-state="on"] {
5728
6047
  background-color: hsl(var(--accent));
@@ -6643,6 +6962,22 @@
6643
6962
  height: calc(var(--fk-spacing) * 4);
6644
6963
  }
6645
6964
  }
6965
+ .fk\:group-data-\[orientation\=vertical\]\/attachment\:\[\&_svg\:not\(\[class\*\=size-\]\)\]\:size-6 {
6966
+ &:is(:where(.fk\:group\/attachment)[data-orientation="vertical"] *) {
6967
+ & svg:not([class*=size-]) {
6968
+ width: calc(var(--fk-spacing) * 6);
6969
+ height: calc(var(--fk-spacing) * 6);
6970
+ }
6971
+ }
6972
+ }
6973
+ .fk\:group-data-\[size\=xs\]\/attachment\:\[\&_svg\:not\(\[class\*\=size-\]\)\]\:size-3\.5 {
6974
+ &:is(:where(.fk\:group\/attachment)[data-size="xs"] *) {
6975
+ & svg:not([class*=size-]) {
6976
+ width: calc(var(--fk-spacing) * 3.5);
6977
+ height: calc(var(--fk-spacing) * 3.5);
6978
+ }
6979
+ }
6980
+ }
6646
6981
  .fk\:\[\&_table\]\:w-full {
6647
6982
  & table {
6648
6983
  width: 100%;
@@ -6769,6 +7104,27 @@
6769
7104
  }
6770
7105
  }
6771
7106
  }
7107
+ .fk\:\*\:\[img\]\:aspect-square {
7108
+ :is(& > *) {
7109
+ &:is(img) {
7110
+ aspect-ratio: 1 / 1;
7111
+ }
7112
+ }
7113
+ }
7114
+ .fk\:\*\:\[img\]\:w-full {
7115
+ :is(& > *) {
7116
+ &:is(img) {
7117
+ width: 100%;
7118
+ }
7119
+ }
7120
+ }
7121
+ .fk\:\*\:\[img\]\:object-cover {
7122
+ :is(& > *) {
7123
+ &:is(img) {
7124
+ object-fit: cover;
7125
+ }
7126
+ }
7127
+ }
6772
7128
  .fk\:data-\[variant\=destructive\]\:\*\:\[svg\]\:text-destructive\! {
6773
7129
  &[data-variant="destructive"] {
6774
7130
  :is(& > *) {
@@ -8016,6 +8372,11 @@ pre {
8016
8372
  inherits: false;
8017
8373
  initial-value: 0;
8018
8374
  }
8375
+ @property --tw-scroll-snap-strictness {
8376
+ syntax: "*";
8377
+ inherits: false;
8378
+ initial-value: proximity;
8379
+ }
8019
8380
  @property --tw-space-y-reverse {
8020
8381
  syntax: "*";
8021
8382
  inherits: false;
@@ -8266,6 +8627,22 @@ pre {
8266
8627
  animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
8267
8628
  }
8268
8629
  }
8630
+ @keyframes scroll-fade-reveal-s {
8631
+ from {
8632
+ --scroll-fade-s: 0px;
8633
+ }
8634
+ to {
8635
+ --scroll-fade-s: var(--_scroll-fade-size-s, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
8636
+ }
8637
+ }
8638
+ @keyframes scroll-fade-reveal-e {
8639
+ from {
8640
+ --scroll-fade-e: var(--_scroll-fade-size-e, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
8641
+ }
8642
+ to {
8643
+ --scroll-fade-e: 0px;
8644
+ }
8645
+ }
8269
8646
  @keyframes tw-shimmer {
8270
8647
  from {
8271
8648
  background-position: 100% 0;
@@ -8317,6 +8694,7 @@ pre {
8317
8694
  --tw-translate-x: 0;
8318
8695
  --tw-translate-y: 0;
8319
8696
  --tw-translate-z: 0;
8697
+ --tw-scroll-snap-strictness: proximity;
8320
8698
  --tw-space-y-reverse: 0;
8321
8699
  --tw-space-x-reverse: 0;
8322
8700
  --tw-divide-y-reverse: 0;
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export { gql } from '@apollo/client';
5
5
  import { UiSchema, ProjectSchemaResponse, UiEntity, UiAttribute, FieldGroup, AttributeOptions } from '@flexkit/schema';
6
6
  export { UiAttribute as Attribute, Config, Attribute as ConfigAttribute, Entity as ConfigEntity, DataType, DefaultValue, DefaultValueByDataType, UiEntity as Entity, EntityMenu, FieldGroup, MenuGroup, ProjectConfig, ProjectSchemaResponse, UiSchema as Schema, ScopeType, UiAttribute, UiEntity, UiProjectSchema, ZodValidation, defineConfig, defineEntity } from '@flexkit/schema';
7
7
  import { AgentChat, AgentChatMessage, AutomationApproval, AutomationMutationPolicy, AutomationToolAllowRule, AutomationRun } from '@flexkit/agent-protocol';
8
- export { AgentChat, AgentChatAttachment, AgentChatMessage, AgentChatMessageRole, AgentChatMessageStatus, AgentChatPart, AgentChatTurn, AutomationApproval, AutomationApprovalStatus, AutomationMutationPolicy, AutomationRun, AutomationRunStatus } from '@flexkit/agent-protocol';
8
+ export { AgentChat, AgentChatAttachment, AgentChatFollowUp, AgentChatFollowUpDelivery, AgentChatFollowUpResult, AgentChatMessage, AgentChatMessageRole, AgentChatMessageStatus, AgentChatPart, AgentChatTurn, AutomationApproval, AutomationApprovalStatus, AutomationMutationPolicy, AutomationRun, AutomationRunStatus } from '@flexkit/agent-protocol';
9
9
  export { Outlet, useLocation, useParams } from 'react-router-dom';
10
10
  import { Control, UseFormSetValue, FieldValues } from 'react-hook-form';
11
11
  import { Column, Row, ColumnDef, Table, RowSelectionState, OnChangeFn, SortingState } from '@tanstack/react-table';