@adminide-stack/yantra-mobile 12.0.131 → 12.0.132

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 (149) hide show
  1. package/lib/components/CustomDrawer.js +2 -2
  2. package/lib/components/CustomDrawer.js.map +1 -1
  3. package/lib/features/apps/AppsCatalog.js +7 -1
  4. package/lib/features/apps/AppsCatalog.js.map +1 -1
  5. package/lib/features/apps/nativeSurfaceTwin.js +35 -0
  6. package/lib/features/apps/nativeSurfaceTwin.js.map +1 -0
  7. package/lib/features/canvas/CanvasBoardsGrid.js +49 -49
  8. package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
  9. package/lib/features/canvas/CanvasExperience.js +69 -28
  10. package/lib/features/canvas/CanvasExperience.js.map +1 -1
  11. package/lib/features/canvas/audioEditor/AudioWaveform.js +1 -1
  12. package/lib/features/canvas/designCatalog.js +63 -39
  13. package/lib/features/canvas/designCatalog.js.map +1 -1
  14. package/lib/features/canvas/designCategories.js +56 -0
  15. package/lib/features/canvas/designCategories.js.map +1 -1
  16. package/lib/features/canvas/generator/DirectorSheet.js +3 -2
  17. package/lib/features/canvas/generator/DirectorSheet.js.map +1 -1
  18. package/lib/features/canvas/home/HeroComposer.js +165 -76
  19. package/lib/features/canvas/home/HeroComposer.js.map +1 -1
  20. package/lib/features/canvas/home/HeroMonitor.js +75 -46
  21. package/lib/features/canvas/home/HeroMonitor.js.map +1 -1
  22. package/lib/features/canvas/home/TemplatesGallery.js +273 -138
  23. package/lib/features/canvas/home/TemplatesGallery.js.map +1 -1
  24. package/lib/features/canvas/home/templatesGallerySources.js +221 -0
  25. package/lib/features/canvas/home/templatesGallerySources.js.map +1 -0
  26. package/lib/features/canvas/homeWork.js +12 -11
  27. package/lib/features/canvas/homeWork.js.map +1 -1
  28. package/lib/features/canvas/lazyEditors.js +51 -0
  29. package/lib/features/canvas/lazyEditors.js.map +1 -0
  30. package/lib/features/canvas/rankedCatalogSearch.js +33 -23
  31. package/lib/features/canvas/rankedCatalogSearch.js.map +1 -1
  32. package/lib/features/canvas/set/SetViewportWebView.js +1 -1
  33. package/lib/features/canvas/set/agent/tools.js +1 -1
  34. package/lib/features/canvas/studioCatalog.js +2 -2
  35. package/lib/features/canvas/studioCatalog.js.map +1 -1
  36. package/lib/features/canvas/templateSearch.js +8 -1
  37. package/lib/features/canvas/templateSearch.js.map +1 -1
  38. package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +1 -1
  39. package/lib/features/design/DesignEditorExperience.js +103 -29
  40. package/lib/features/design/DesignEditorExperience.js.map +1 -1
  41. package/lib/features/design/DesignExperience.js +4 -3
  42. package/lib/features/design/DesignExperience.js.map +1 -1
  43. package/lib/features/design/doc/aiDesign.js +1 -1
  44. package/lib/features/design/doc/aiDesign.js.map +1 -1
  45. package/lib/features/design/doc/artifacts.js +40 -13
  46. package/lib/features/design/doc/artifacts.js.map +1 -1
  47. package/lib/features/design/doc/chart.js +387 -13
  48. package/lib/features/design/doc/chart.js.map +1 -1
  49. package/lib/features/design/doc/copyStyle.js +47 -0
  50. package/lib/features/design/doc/copyStyle.js.map +1 -0
  51. package/lib/features/design/doc/docOps.js +22 -4
  52. package/lib/features/design/doc/docOps.js.map +1 -1
  53. package/lib/features/design/doc/geometry.js +32 -18
  54. package/lib/features/design/doc/geometry.js.map +1 -1
  55. package/lib/features/design/doc/newDoc.js +5 -1
  56. package/lib/features/design/doc/newDoc.js.map +1 -1
  57. package/lib/features/design/doc/resize.js +101 -0
  58. package/lib/features/design/doc/resize.js.map +1 -0
  59. package/lib/features/design/doc/sizes.js +15 -2
  60. package/lib/features/design/doc/sizes.js.map +1 -1
  61. package/lib/features/design/editor/ChartDataPanel.js +49 -9
  62. package/lib/features/design/editor/ChartDataPanel.js.map +1 -1
  63. package/lib/features/design/editor/CropOverlay.js +1 -1
  64. package/lib/features/design/editor/DesignCanvas.js +14 -13
  65. package/lib/features/design/editor/DesignCanvas.js.map +1 -1
  66. package/lib/features/design/editor/ExportSheet.js +8 -4
  67. package/lib/features/design/editor/ExportSheet.js.map +1 -1
  68. package/lib/features/design/editor/LayerTools.js +37 -5
  69. package/lib/features/design/editor/LayerTools.js.map +1 -1
  70. package/lib/features/design/editor/Slideshow.js +30 -5
  71. package/lib/features/design/editor/Slideshow.js.map +1 -1
  72. package/lib/features/design/editor/useDesignSave.js +21 -36
  73. package/lib/features/design/editor/useDesignSave.js.map +1 -1
  74. package/lib/features/design/export/exportDesign.js +3 -1
  75. package/lib/features/design/export/exportDesign.js.map +1 -1
  76. package/lib/features/design/home/DesignHome.js +7 -2
  77. package/lib/features/design/home/DesignHome.js.map +1 -1
  78. package/lib/features/design/render/DesignPageView.js +1 -1
  79. package/lib/features/design/render/DesignPageView.js.map +1 -1
  80. package/lib/features/design/render/PageCapture.js +11 -10
  81. package/lib/features/design/render/PageCapture.js.map +1 -1
  82. package/lib/features/design/render/fontRegistry.js +27 -3
  83. package/lib/features/design/render/fontRegistry.js.map +1 -1
  84. package/lib/features/design/render/svgParts.js +27 -74
  85. package/lib/features/design/render/svgParts.js.map +1 -1
  86. package/lib/features/devices/brands/qnScale.js +7 -2
  87. package/lib/features/devices/brands/qnScale.js.map +1 -1
  88. package/lib/features/devices/brands/uuids.js +2 -1
  89. package/lib/features/devices/brands/uuids.js.map +1 -1
  90. package/lib/features/devices/devices.js +2 -1
  91. package/lib/features/devices/devices.js.map +1 -1
  92. package/lib/features/docs/DocBlockRow.js +1 -1
  93. package/lib/features/docs/docArtifacts.js +2 -2
  94. package/lib/features/docs/docArtifacts.js.map +1 -1
  95. package/lib/features/health/healthSync.js +3 -1
  96. package/lib/features/health/healthSync.js.map +1 -1
  97. package/lib/features/health/nativeHealth.js +8 -0
  98. package/lib/features/health/nativeHealth.js.map +1 -0
  99. package/lib/features/links/openInApp.js +11 -1
  100. package/lib/features/links/openInApp.js.map +1 -1
  101. package/lib/features/webbuilder/WebBuilderExperience.js +135 -28
  102. package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
  103. package/lib/features/webbuilder/buildFragments.js +14 -6
  104. package/lib/features/webbuilder/buildFragments.js.map +1 -1
  105. package/lib/features/webbuilder/components/PreviewFrame.js +28 -3
  106. package/lib/features/webbuilder/components/PreviewFrame.js.map +1 -1
  107. package/lib/features/webbuilder/components/PreviewScreen.js +1 -1
  108. package/lib/features/webbuilder/components/PreviewScreen.js.map +1 -1
  109. package/lib/features/webbuilder/components/ProjectChat.js +24 -5
  110. package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
  111. package/lib/features/webbuilder/components/ProjectsScreen.js +18 -2
  112. package/lib/features/webbuilder/components/ProjectsScreen.js.map +1 -1
  113. package/lib/features/webbuilder/components/ui.js +20 -6
  114. package/lib/features/webbuilder/components/ui.js.map +1 -1
  115. package/lib/features/webbuilder/exportCode.js +52 -0
  116. package/lib/features/webbuilder/exportCode.js.map +1 -0
  117. package/lib/features/webbuilder/siteAddress.js +71 -0
  118. package/lib/features/webbuilder/siteAddress.js.map +1 -0
  119. package/lib/features/webbuilder/widgetBlocks.js +30 -0
  120. package/lib/features/webbuilder/widgetBlocks.js.map +1 -0
  121. package/lib/screens/Chat/index.js +5 -6
  122. package/lib/screens/Chat/index.js.map +1 -1
  123. package/lib/screens/ChatHistory/index.js +3 -2
  124. package/lib/screens/ChatHistory/index.js.map +1 -1
  125. package/lib/screens/Home/HomeScreen.js +20 -4
  126. package/lib/screens/Home/HomeScreen.js.map +1 -1
  127. package/lib/screens/Home/components/WebBuilderCodePrewarm.js +18 -0
  128. package/lib/screens/Home/components/WebBuilderCodePrewarm.js.map +1 -0
  129. package/lib/screens/WebBuilderNative/index.js +1 -1
  130. package/lib/screens/WebBuilderNative/index.js.map +1 -1
  131. package/lib/screens/WebBuilderNative/keepAlive.js +112 -0
  132. package/lib/screens/WebBuilderNative/keepAlive.js.map +1 -0
  133. package/lib/screens/WebBuilderNative/runningBuilds.js +40 -0
  134. package/lib/screens/WebBuilderNative/runningBuilds.js.map +1 -0
  135. package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js +57 -0
  136. package/lib/screens/WebBuilderNative/useSandboxKeepAlive.js.map +1 -0
  137. package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +73 -14
  138. package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -1
  139. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +143 -34
  140. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
  141. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +17 -5
  142. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
  143. package/lib/screens/WebBuilderNative/versionUndo.js +144 -0
  144. package/lib/screens/WebBuilderNative/versionUndo.js.map +1 -0
  145. package/lib/screens/WebBuilderNative/webbuilderSnapshotKey.js +1 -0
  146. package/lib/screens/WebBuilderNative/webbuilderSnapshotKey.js.map +1 -0
  147. package/lib/screens/WebBuilderNative/webbuilderTransport.js +90 -6
  148. package/lib/screens/WebBuilderNative/webbuilderTransport.js.map +1 -1
  149. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"sizes.js","sources":["../../../../src/features/design/doc/sizes.ts"],"sourcesContent":["/**\n * Design sizes offered by the create screen and the Details size picker -\n * native twin of canvas-surface `editors/carousel-editor/utils/sizes.ts`,\n * copied verbatim so a blank design opens at the web's own pixel size.\n *\n * Pure: runs under jest as-is.\n */\nimport type { DesignKind } from './types';\n\nexport type { DesignKind };\n\nexport type SizeCategory =\n | 'popular'\n | 'social'\n | 'carousel'\n | 'flyer'\n | 'business-card'\n | 'presentation'\n | 'pitch-deck'\n | 'logo'\n | 'banner'\n | 'brochure'\n | 'branding'\n | 'certificate'\n | 'worksheet'\n | 'proposal'\n | 'newsletter'\n | 'menu'\n | 'infographic'\n | 'technology'\n | 'custom';\ntype PrintCategory =\n | 'flyer'\n | 'business-card'\n | 'brochure'\n | 'branding'\n | 'certificate'\n | 'worksheet'\n | 'proposal'\n | 'newsletter'\n | 'menu';\n/** Views over other categories' templates, with no sizes of their own: a kind of deck, and a topic. */\ntype ViewCategory = 'pitch-deck' | 'technology';\nexport type SizeUnit = 'px' | 'in' | 'mm';\n\nexport interface DesignSize {\n id: string;\n label: string;\n category: Exclude<SizeCategory, 'popular' | 'custom' | ViewCategory>;\n width: number;\n height: number;\n /** Artifact kind the design saves as — print sizes are flyers. */\n kind: DesignKind;\n /** Stands in for the wizard's platform answer on a blank design. */\n platform: string;\n /** Extra search terms beyond the label. */\n keywords: string;\n /** Print sizes: the exact finished size, which the rounded px can't carry. */\n trimMm?: { w: number; h: number };\n /** Print sizes: how a person reads the size (\"3.5 × 2 in\"). */\n physical?: string;\n /** One blank page per name; absent = a single page. */\n pageNames?: string[];\n}\n\nconst PRINT_CATEGORIES: readonly SizeCategory[] = [\n 'flyer',\n 'business-card',\n 'brochure',\n 'branding',\n 'certificate',\n 'worksheet',\n 'proposal',\n 'newsletter',\n 'menu',\n];\n\n/** Print sizes save as flyers and carry a bleed. */\nexport function isPrintCategory(category: SizeCategory): category is PrintCategory {\n return PRINT_CATEGORIES.includes(category);\n}\n\n/**\n * The platform a blank print design names, which picks its catalog in the Templates tab\n * (catalogDoc.ts). Flyers and business cards both say Print and are told apart by shape;\n * a brochure, a letterhead, a certificate, a worksheet and a proposal are flyer-shaped, so they\n * name their own.\n */\nexport const PRINT_PLATFORM: Record<PrintCategory, string> = {\n flyer: 'Print',\n 'business-card': 'Print',\n brochure: 'Brochure',\n branding: 'Stationery',\n certificate: 'Certificate',\n worksheet: 'Worksheet',\n proposal: 'Proposal',\n newsletter: 'Newsletter',\n menu: 'Menu',\n};\n\n// ponytail: print at 150 DPI keeps A2 under the 4096 raster cap; add an export scale for 300 DPI\nexport const PRINT_DPI = 150;\n// ponytail: 5000 px per side, below Safari's canvas limits; raise when export tiles\nexport const MIN_PX = 40;\nexport const MAX_PX = 5000;\n\nexport function toPx(value: number, unit: SizeUnit): number {\n if (unit === 'in') return Math.round(value * PRINT_DPI);\n if (unit === 'mm') return Math.round((value / 25.4) * PRINT_DPI);\n return Math.round(value);\n}\n\n/** Inverse of `toPx`, rounded to what a person would type. */\nexport function fromPx(px: number, unit: SizeUnit): string {\n if (unit === 'in') return String(Math.round((px / PRINT_DPI) * 100) / 100);\n if (unit === 'mm') return String(Math.round((px / PRINT_DPI) * 254) / 10);\n return String(px);\n}\n\nexport function inRange(px: number): boolean {\n return Number.isFinite(px) && px >= MIN_PX && px <= MAX_PX;\n}\n\nfunction social(\n id: string,\n label: string,\n width: number,\n height: number,\n platform: string,\n keywords: string,\n): DesignSize {\n return { id, label, category: 'social', width, height, kind: 'deck', platform, keywords };\n}\n\n/** A carousel: swipeable slides at a feed size, one page to start - pages are added as slides. */\nfunction carousel(id: string, label: string, width: number, height: number, keywords: string): DesignSize {\n return { id, label, category: 'carousel', width, height, kind: 'deck', platform: 'Instagram', keywords };\n}\n\nfunction slides(id: string, label: string, width: number, height: number, keywords: string): DesignSize {\n return { id, label, category: 'presentation', width, height, kind: 'deck', platform: 'Presentation', keywords };\n}\n\nfunction logo(id: string, label: string, side: number, keywords: string): DesignSize {\n return { id, label, category: 'logo', width: side, height: side, kind: 'deck', platform: 'Logo', keywords };\n}\n\n/**\n * A banner. The printed ones (vinyl, 6 x 3 ft) are screen designs at the catalog's 2:1, since\n * 72 in at 150 DPI is past MAX_PX; the web and social ones name their own platform, so their\n * Templates tab does not offer 2:1 vinyl banners for a 4:1 header.\n */\nfunction banner(\n id: string,\n label: string,\n width: number,\n height: number,\n keywords: string,\n platform = 'Banner',\n): DesignSize {\n return { id, label, category: 'banner', width, height, kind: 'deck', platform, keywords };\n}\n\nconst MM_PER_UNIT: Record<SizeUnit, number> = { px: 25.4 / PRINT_DPI, in: 25.4, mm: 1 };\n\n/** Physical size in mm, to 0.01 mm. */\nexport function toMm(value: number, unit: SizeUnit): number {\n return Math.round(value * MM_PER_UNIT[unit] * 100) / 100;\n}\n\nfunction print(\n id: string,\n label: string,\n w: number,\n h: number,\n unit: SizeUnit,\n keywords: string,\n category: PrintCategory = 'flyer',\n): DesignSize {\n return {\n id,\n label,\n category,\n width: toPx(w, unit),\n height: toPx(h, unit),\n kind: 'flyer',\n platform: PRINT_PLATFORM[category],\n keywords,\n trimMm: { w: toMm(w, unit), h: toMm(h, unit) },\n physical: `${w} × ${h} ${unit}`,\n };\n}\n\n/** Business cards print both sides, so they open with a Front and a Back. */\nfunction card(id: string, label: string, w: number, h: number, unit: SizeUnit, keywords: string): DesignSize {\n return {\n ...print(id, label, w, h, unit, `card visiting double-sided ${w}x${h} ${keywords}`, 'business-card'),\n pageNames: ['Front', 'Back'],\n };\n}\n\n/** A brochure prints both sides of one sheet, folded: the Outside (cover, back, flap) and the Inside. */\nfunction brochure(id: string, label: string, w: number, h: number, unit: SizeUnit, keywords: string): DesignSize {\n return {\n ...print(id, label, w, h, unit, `leaflet pamphlet trifold tri-fold bifold folded ${keywords}`, 'brochure'),\n pageNames: ['Outside', 'Inside'],\n };\n}\n\nconst stationery = (id: string, label: string, w: number, h: number, unit: SizeUnit, keywords: string): DesignSize =>\n print(id, label, w, h, unit, `branding stationery brand ${keywords}`, 'branding');\n\nexport const DESIGN_SIZES: readonly DesignSize[] = [\n social('ig-post-portrait', 'Instagram Post (4:5)', 1080, 1350, 'Instagram', 'carousel portrait'),\n social('ig-post-square', 'Instagram Post (Square)', 1080, 1080, 'Instagram', 'square'),\n social('ig-story', 'Instagram Story', 1080, 1920, 'Instagram', 'reel whatsapp status tiktok vertical'),\n social('fb-post', 'Facebook Post', 1200, 630, 'Facebook', 'landscape'),\n social('li-post', 'LinkedIn Post', 1200, 627, 'LinkedIn', 'landscape'),\n social('x-post', 'X Post', 1600, 900, 'X', 'twitter landscape'),\n social('yt-thumb', 'YouTube Thumbnail', 1280, 720, 'YouTube', 'video cover'),\n social('pin', 'Pinterest Pin', 1000, 1500, 'Pinterest', 'tall'),\n carousel('carousel-portrait', 'Carousel (4:5)', 1080, 1350, 'instagram linkedin swipe swipeable portrait'),\n carousel('carousel-square', 'Carousel (Square)', 1080, 1080, 'instagram linkedin swipe swipeable'),\n carousel('carousel-3-4', 'Carousel (3:4)', 1080, 1440, 'instagram swipe swipeable portrait'),\n carousel('carousel-tall', 'Carousel (2:3)', 1080, 1620, 'instagram swipe swipeable tall portrait'),\n slides('slides-16-9', 'Presentation (16:9)', 1920, 1080, 'slides deck pitch widescreen'),\n slides('slides-4-3', 'Presentation (4:3)', 1024, 768, 'slides deck pitch'),\n slides('slides-mobile', 'Presentation (Mobile)', 1080, 1920, 'slides deck vertical'),\n print('a4', 'A4 Document', 210, 297, 'mm', 'paper document flyer'),\n print('letter', 'Flyer (US Letter)', 8.5, 11, 'in', 'paper document'),\n print('a3', 'A3 Poster', 297, 420, 'mm', 'paper'),\n print('a2', 'A2 Poster', 420, 594, 'mm', 'paper large'),\n print('poster-18-24', 'Poster', 18, 24, 'in', 'large'),\n print('invitation', 'Invitation', 5, 7, 'in', 'card wedding party'),\n print('postcard', 'Postcard', 6, 4, 'in', 'card landscape'),\n card('business-card', 'Business Card (US)', 3.5, 2, 'in', 'us standard'),\n card('business-card-eu', 'Business Card (EU)', 85, 55, 'mm', 'eu europe standard'),\n card('business-card-90x55', 'Business Card (AU / NZ)', 90, 55, 'mm', 'australia new zealand'),\n card('business-card-90x50', 'Business Card (Wide)', 90, 50, 'mm', 'wide slim'),\n // The catalog's logos are 500 px squares (Canva's Logo), some 2000 px.\n logo('logo', 'Logo', 500, 'brand mark icon emblem square'),\n logo('logo-large', 'Logo (Large)', 2000, 'brand mark icon emblem square high resolution'),\n banner('banner-landscape', 'Banner (Landscape)', 4800, 2400, 'vinyl printed 72x36 6x3 ft event party wedding'),\n banner('banner-portrait', 'Banner (Portrait)', 2400, 4800, 'vinyl printed 36x72 3x6 ft vertical'),\n banner('linkedin-banner', 'LinkedIn Banner', 1584, 396, 'background cover header profile', 'LinkedIn'),\n banner('youtube-banner', 'YouTube Banner', 2560, 1440, 'channel art cover', 'YouTube'),\n banner('x-header', 'X Header', 1500, 500, 'twitter banner cover', 'X'),\n banner('facebook-cover', 'Facebook Cover', 1640, 624, 'banner header', 'Facebook'),\n banner('web-banner', 'Web Banner', 728, 90, 'ad display leaderboard', 'Web'),\n // Canva's brochures: Letter and A4 landscape, a few tabloid, each an Outside and an Inside.\n brochure('brochure-letter', 'Brochure (US Letter)', 11, 8.5, 'in', 'us landscape'),\n brochure('brochure-a4', 'Brochure (A4)', 297, 210, 'mm', 'a4 landscape'),\n brochure('brochure-tabloid', 'Brochure (Tabloid)', 17, 11, 'in', 'tabloid ledger large'),\n stationery('letterhead-a4', 'Letterhead (A4)', 210, 297, 'mm', 'letter paper a4 company'),\n stationery('letterhead-letter', 'Letterhead (US Letter)', 8.5, 11, 'in', 'letter paper us company'),\n stationery('envelope-10', 'Envelope (#10)', 9.5, 4.125, 'in', 'business us mail'),\n stationery('envelope-dl', 'Envelope (DL)', 220, 110, 'mm', 'business eu mail'),\n // Canva's certificates are landscape Letter or A4; a diploma may stand.\n print('certificate-letter', 'Certificate (US Letter)', 11, 8.5, 'in', 'award diploma recognition', 'certificate'),\n print('certificate-a4', 'Certificate (A4)', 297, 210, 'mm', 'award diploma recognition', 'certificate'),\n print('certificate-portrait', 'Certificate (Portrait)', 210, 297, 'mm', 'award diploma a4 portrait', 'certificate'),\n print('worksheet-letter', 'Worksheet (US Letter)', 8.5, 11, 'in', 'classroom lesson activity school', 'worksheet'),\n print('worksheet-a4', 'Worksheet (A4)', 210, 297, 'mm', 'classroom lesson activity school', 'worksheet'),\n print('proposal-letter', 'Proposal (US Letter)', 8.5, 11, 'in', 'business project quote document', 'proposal'),\n print('proposal-a4', 'Proposal (A4)', 210, 297, 'mm', 'business project quote document', 'proposal'),\n print('newsletter-letter', 'Newsletter (US Letter)', 8.5, 11, 'in', 'bulletin school church company', 'newsletter'),\n print('newsletter-a4', 'Newsletter (A4)', 210, 297, 'mm', 'bulletin school church company', 'newsletter'),\n print('menu-letter', 'Menu (US Letter)', 8.5, 11, 'in', 'restaurant cafe bar food drinks', 'menu'),\n print('menu-a4', 'Menu (A4)', 210, 297, 'mm', 'restaurant cafe bar food drinks', 'menu'),\n print('menu-tabloid', 'Menu (Tabloid)', 11, 17, 'in', 'restaurant cafe bar large', 'menu'),\n // Canva's infographic is a tall screen page, 800 x 2000 px.\n {\n id: 'infographic',\n label: 'Infographic',\n category: 'infographic',\n width: 800,\n height: 2000,\n kind: 'deck',\n platform: 'Infographic',\n keywords: 'timeline process statistics chart data how-to',\n },\n];\n\nexport const POPULAR_SIZE_IDS = [\n 'ig-post-portrait',\n 'ig-story',\n 'slides-16-9',\n 'a4',\n 'ig-post-square',\n 'yt-thumb',\n 'a2',\n 'fb-post',\n];\n\nexport const SIZE_CATEGORIES: { id: SizeCategory; label: string }[] = [\n { id: 'popular', label: 'Popular' },\n { id: 'social', label: 'Social media' },\n { id: 'carousel', label: 'Carousels' },\n { id: 'flyer', label: 'Flyers' },\n { id: 'business-card', label: 'Business cards' },\n { id: 'presentation', label: 'Presentations' },\n { id: 'pitch-deck', label: 'Pitch decks' },\n { id: 'logo', label: 'Logos' },\n { id: 'banner', label: 'Banners' },\n { id: 'brochure', label: 'Brochures' },\n { id: 'branding', label: 'Branding' },\n { id: 'certificate', label: 'Certificates' },\n { id: 'worksheet', label: 'Worksheets' },\n { id: 'proposal', label: 'Proposals' },\n { id: 'newsletter', label: 'Newsletters' },\n { id: 'menu', label: 'Menus' },\n { id: 'infographic', label: 'Infographics' },\n { id: 'technology', label: 'Technology' },\n { id: 'custom', label: 'Custom size' },\n];\n\n/** A pitch deck is a presentation: its blanks are the presentation sizes. A topic has none. */\nconst SIZES_OF: Partial<Record<SizeCategory, SizeCategory>> = { 'pitch-deck': 'presentation' };\n\nexport function sizesIn(category: SizeCategory): DesignSize[] {\n if (category === 'popular') return POPULAR_SIZE_IDS.map((id) => DESIGN_SIZES.find((s) => s.id === id)!);\n const own = SIZES_OF[category] ?? category;\n return DESIGN_SIZES.filter((s) => s.category === own);\n}\n\n/** Case-insensitive substring match on label, category and keywords. */\nexport function searchSizes(query: string): DesignSize[] {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n return DESIGN_SIZES.filter((s) => `${s.label} ${s.category} ${s.platform} ${s.keywords}`.toLowerCase().includes(q));\n}\n\n// Aspects the carousel connector's layout and image generation accept.\nconst CONNECTOR_ASPECTS: [string, number][] = [\n ['1:1', 1],\n ['4:5', 4 / 5],\n ['2:3', 2 / 3],\n ['16:9', 16 / 9],\n];\n\n/** Nearest connector aspect, compared in log space so 2:1 and 1:2 are equally far from 1:1. */\nexport function snapAspect(width: number, height: number): string {\n const r = Math.log(width / height);\n let best = CONNECTOR_ASPECTS[0];\n for (const a of CONNECTOR_ASPECTS) if (Math.abs(r - Math.log(a[1])) < Math.abs(r - Math.log(best[1]))) best = a;\n return best[0];\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sizes.js","sources":["../../../../src/features/design/doc/sizes.ts"],"sourcesContent":["/**\n * Design sizes offered by the create screen and the Details size picker -\n * native twin of canvas-surface `editors/carousel-editor/utils/sizes.ts`,\n * copied verbatim so a blank design opens at the web's own pixel size.\n *\n * Pure: runs under jest as-is.\n */\nimport type { DesignKind } from './types';\n\nexport type { DesignKind };\n\nexport type SizeCategory =\n | 'popular'\n | 'social'\n | 'carousel'\n | 'flyer'\n | 'business-card'\n | 'presentation'\n | 'pitch-deck'\n | 'logo'\n | 'banner'\n | 'brochure'\n | 'branding'\n | 'certificate'\n | 'worksheet'\n | 'proposal'\n | 'newsletter'\n | 'menu'\n | 'infographic'\n | 'document'\n | 'report'\n | 'letter'\n | 'resume'\n | 'technology'\n | 'custom';\ntype PrintCategory =\n | 'flyer'\n | 'business-card'\n | 'brochure'\n | 'branding'\n | 'certificate'\n | 'worksheet'\n | 'proposal'\n | 'newsletter'\n | 'menu'\n | 'document'\n | 'report'\n | 'letter'\n | 'resume';\n/** Views over other categories' templates, with no sizes of their own: a kind of deck, and a topic. */\ntype ViewCategory = 'pitch-deck' | 'technology';\nexport type SizeUnit = 'px' | 'in' | 'mm';\n\nexport interface DesignSize {\n id: string;\n label: string;\n category: Exclude<SizeCategory, 'popular' | 'custom' | ViewCategory>;\n width: number;\n height: number;\n /** Artifact kind the design saves as — print sizes are flyers. */\n kind: DesignKind;\n /** Stands in for the wizard's platform answer on a blank design. */\n platform: string;\n /** Extra search terms beyond the label. */\n keywords: string;\n /** Print sizes: the exact finished size, which the rounded px can't carry. */\n trimMm?: { w: number; h: number };\n /** Print sizes: how a person reads the size (\"3.5 × 2 in\"). */\n physical?: string;\n /** One blank page per name; absent = a single page. */\n pageNames?: string[];\n}\n\nconst PRINT_CATEGORIES: readonly SizeCategory[] = [\n 'flyer',\n 'business-card',\n 'brochure',\n 'branding',\n 'certificate',\n 'worksheet',\n 'proposal',\n 'newsletter',\n 'menu',\n 'document',\n 'report',\n 'letter',\n 'resume',\n];\n\n/** Print sizes save as flyers and carry a bleed. */\nexport function isPrintCategory(category: SizeCategory): category is PrintCategory {\n return PRINT_CATEGORIES.includes(category);\n}\n\n/**\n * The platform a blank print design names, which picks its catalog in the Templates tab\n * (catalogDoc.ts). Flyers and business cards both say Print and are told apart by shape;\n * a brochure, a letterhead, a certificate, a worksheet, a proposal and a document, report, letter\n * or resume are flyer-shaped, so they name their own.\n */\nexport const PRINT_PLATFORM: Record<PrintCategory, string> = {\n flyer: 'Print',\n 'business-card': 'Print',\n brochure: 'Brochure',\n branding: 'Stationery',\n certificate: 'Certificate',\n worksheet: 'Worksheet',\n proposal: 'Proposal',\n newsletter: 'Newsletter',\n menu: 'Menu',\n document: 'Document',\n report: 'Report',\n letter: 'Letter',\n resume: 'Resume',\n};\n\n// ponytail: print at 150 DPI keeps A2 under the 4096 raster cap; add an export scale for 300 DPI\nexport const PRINT_DPI = 150;\n// ponytail: 5000 px per side, below Safari's canvas limits; raise when export tiles\nexport const MIN_PX = 40;\nexport const MAX_PX = 5000;\n\nexport function toPx(value: number, unit: SizeUnit): number {\n if (unit === 'in') return Math.round(value * PRINT_DPI);\n if (unit === 'mm') return Math.round((value / 25.4) * PRINT_DPI);\n return Math.round(value);\n}\n\n/** Inverse of `toPx`, rounded to what a person would type. */\nexport function fromPx(px: number, unit: SizeUnit): string {\n if (unit === 'in') return String(Math.round((px / PRINT_DPI) * 100) / 100);\n if (unit === 'mm') return String(Math.round((px / PRINT_DPI) * 254) / 10);\n return String(px);\n}\n\nexport function inRange(px: number): boolean {\n return Number.isFinite(px) && px >= MIN_PX && px <= MAX_PX;\n}\n\nfunction social(\n id: string,\n label: string,\n width: number,\n height: number,\n platform: string,\n keywords: string,\n): DesignSize {\n return { id, label, category: 'social', width, height, kind: 'deck', platform, keywords };\n}\n\n/** A carousel: swipeable slides at a feed size, one page to start - pages are added as slides. */\nfunction carousel(id: string, label: string, width: number, height: number, keywords: string): DesignSize {\n return { id, label, category: 'carousel', width, height, kind: 'deck', platform: 'Instagram', keywords };\n}\n\nfunction slides(id: string, label: string, width: number, height: number, keywords: string): DesignSize {\n return { id, label, category: 'presentation', width, height, kind: 'deck', platform: 'Presentation', keywords };\n}\n\nfunction logo(id: string, label: string, side: number, keywords: string): DesignSize {\n return { id, label, category: 'logo', width: side, height: side, kind: 'deck', platform: 'Logo', keywords };\n}\n\n/**\n * A banner. The printed ones (vinyl, 6 x 3 ft) are screen designs at the catalog's 2:1, since\n * 72 in at 150 DPI is past MAX_PX; the web and social ones name their own platform, so their\n * Templates tab does not offer 2:1 vinyl banners for a 4:1 header.\n */\nfunction banner(\n id: string,\n label: string,\n width: number,\n height: number,\n keywords: string,\n platform = 'Banner',\n): DesignSize {\n return { id, label, category: 'banner', width, height, kind: 'deck', platform, keywords };\n}\n\nconst MM_PER_UNIT: Record<SizeUnit, number> = { px: 25.4 / PRINT_DPI, in: 25.4, mm: 1 };\n\n/** Physical size in mm, to 0.01 mm. */\nexport function toMm(value: number, unit: SizeUnit): number {\n return Math.round(value * MM_PER_UNIT[unit] * 100) / 100;\n}\n\nfunction print(\n id: string,\n label: string,\n w: number,\n h: number,\n unit: SizeUnit,\n keywords: string,\n category: PrintCategory = 'flyer',\n): DesignSize {\n return {\n id,\n label,\n category,\n width: toPx(w, unit),\n height: toPx(h, unit),\n kind: 'flyer',\n platform: PRINT_PLATFORM[category],\n keywords,\n trimMm: { w: toMm(w, unit), h: toMm(h, unit) },\n physical: `${w} × ${h} ${unit}`,\n };\n}\n\n/** Business cards print both sides, so they open with a Front and a Back. */\nfunction card(id: string, label: string, w: number, h: number, unit: SizeUnit, keywords: string): DesignSize {\n return {\n ...print(id, label, w, h, unit, `card visiting double-sided ${w}x${h} ${keywords}`, 'business-card'),\n pageNames: ['Front', 'Back'],\n };\n}\n\n/** A brochure prints both sides of one sheet, folded: the Outside (cover, back, flap) and the Inside. */\nfunction brochure(id: string, label: string, w: number, h: number, unit: SizeUnit, keywords: string): DesignSize {\n return {\n ...print(id, label, w, h, unit, `leaflet pamphlet trifold tri-fold bifold folded ${keywords}`, 'brochure'),\n pageNames: ['Outside', 'Inside'],\n };\n}\n\nconst stationery = (id: string, label: string, w: number, h: number, unit: SizeUnit, keywords: string): DesignSize =>\n print(id, label, w, h, unit, `branding stationery brand ${keywords}`, 'branding');\n\nexport const DESIGN_SIZES: readonly DesignSize[] = [\n social('ig-post-portrait', 'Instagram Post (4:5)', 1080, 1350, 'Instagram', 'carousel portrait'),\n social('ig-post-square', 'Instagram Post (Square)', 1080, 1080, 'Instagram', 'square'),\n social('ig-story', 'Instagram Story', 1080, 1920, 'Instagram', 'reel whatsapp status tiktok vertical'),\n social('fb-post', 'Facebook Post', 1200, 630, 'Facebook', 'landscape'),\n social('li-post', 'LinkedIn Post', 1200, 627, 'LinkedIn', 'landscape'),\n social('x-post', 'X Post', 1600, 900, 'X', 'twitter landscape'),\n social('yt-thumb', 'YouTube Thumbnail', 1280, 720, 'YouTube', 'video cover'),\n social('pin', 'Pinterest Pin', 1000, 1500, 'Pinterest', 'tall'),\n carousel('carousel-portrait', 'Carousel (4:5)', 1080, 1350, 'instagram linkedin swipe swipeable portrait'),\n carousel('carousel-square', 'Carousel (Square)', 1080, 1080, 'instagram linkedin swipe swipeable'),\n carousel('carousel-3-4', 'Carousel (3:4)', 1080, 1440, 'instagram swipe swipeable portrait'),\n carousel('carousel-tall', 'Carousel (2:3)', 1080, 1620, 'instagram swipe swipeable tall portrait'),\n slides('slides-16-9', 'Presentation (16:9)', 1920, 1080, 'slides deck pitch widescreen'),\n slides('slides-4-3', 'Presentation (4:3)', 1024, 768, 'slides deck pitch'),\n slides('slides-mobile', 'Presentation (Mobile)', 1080, 1920, 'slides deck vertical'),\n print('a4', 'A4 Document', 210, 297, 'mm', 'paper document flyer'),\n print('letter', 'Flyer (US Letter)', 8.5, 11, 'in', 'paper document'),\n print('a3', 'A3 Poster', 297, 420, 'mm', 'paper'),\n print('a2', 'A2 Poster', 420, 594, 'mm', 'paper large'),\n print('poster-18-24', 'Poster', 18, 24, 'in', 'large'),\n print('invitation', 'Invitation', 5, 7, 'in', 'card wedding party'),\n print('postcard', 'Postcard', 6, 4, 'in', 'card landscape'),\n card('business-card', 'Business Card (US)', 3.5, 2, 'in', 'us standard'),\n card('business-card-eu', 'Business Card (EU)', 85, 55, 'mm', 'eu europe standard'),\n card('business-card-90x55', 'Business Card (AU / NZ)', 90, 55, 'mm', 'australia new zealand'),\n card('business-card-90x50', 'Business Card (Wide)', 90, 50, 'mm', 'wide slim'),\n // The catalog's logos are 500 px squares (Canva's Logo), some 2000 px.\n logo('logo', 'Logo', 500, 'brand mark icon emblem square'),\n logo('logo-large', 'Logo (Large)', 2000, 'brand mark icon emblem square high resolution'),\n banner('banner-landscape', 'Banner (Landscape)', 4800, 2400, 'vinyl printed 72x36 6x3 ft event party wedding'),\n banner('banner-portrait', 'Banner (Portrait)', 2400, 4800, 'vinyl printed 36x72 3x6 ft vertical'),\n banner('linkedin-banner', 'LinkedIn Banner', 1584, 396, 'background cover header profile', 'LinkedIn'),\n banner('youtube-banner', 'YouTube Banner', 2560, 1440, 'channel art cover', 'YouTube'),\n banner('x-header', 'X Header', 1500, 500, 'twitter banner cover', 'X'),\n banner('facebook-cover', 'Facebook Cover', 1640, 624, 'banner header', 'Facebook'),\n banner('web-banner', 'Web Banner', 728, 90, 'ad display leaderboard', 'Web'),\n // Canva's brochures: Letter and A4 landscape, a few tabloid, each an Outside and an Inside.\n brochure('brochure-letter', 'Brochure (US Letter)', 11, 8.5, 'in', 'us landscape'),\n brochure('brochure-a4', 'Brochure (A4)', 297, 210, 'mm', 'a4 landscape'),\n brochure('brochure-tabloid', 'Brochure (Tabloid)', 17, 11, 'in', 'tabloid ledger large'),\n stationery('letterhead-a4', 'Letterhead (A4)', 210, 297, 'mm', 'letter paper a4 company'),\n stationery('letterhead-letter', 'Letterhead (US Letter)', 8.5, 11, 'in', 'letter paper us company'),\n stationery('envelope-10', 'Envelope (#10)', 9.5, 4.125, 'in', 'business us mail'),\n stationery('envelope-dl', 'Envelope (DL)', 220, 110, 'mm', 'business eu mail'),\n // Canva's certificates are landscape Letter or A4; a diploma may stand.\n print('certificate-letter', 'Certificate (US Letter)', 11, 8.5, 'in', 'award diploma recognition', 'certificate'),\n print('certificate-a4', 'Certificate (A4)', 297, 210, 'mm', 'award diploma recognition', 'certificate'),\n print('certificate-portrait', 'Certificate (Portrait)', 210, 297, 'mm', 'award diploma a4 portrait', 'certificate'),\n print('worksheet-letter', 'Worksheet (US Letter)', 8.5, 11, 'in', 'classroom lesson activity school', 'worksheet'),\n print('worksheet-a4', 'Worksheet (A4)', 210, 297, 'mm', 'classroom lesson activity school', 'worksheet'),\n print('proposal-letter', 'Proposal (US Letter)', 8.5, 11, 'in', 'business project quote document', 'proposal'),\n print('proposal-a4', 'Proposal (A4)', 210, 297, 'mm', 'business project quote document', 'proposal'),\n print('newsletter-letter', 'Newsletter (US Letter)', 8.5, 11, 'in', 'bulletin school church company', 'newsletter'),\n print('newsletter-a4', 'Newsletter (A4)', 210, 297, 'mm', 'bulletin school church company', 'newsletter'),\n print('menu-letter', 'Menu (US Letter)', 8.5, 11, 'in', 'restaurant cafe bar food drinks', 'menu'),\n print('menu-a4', 'Menu (A4)', 210, 297, 'mm', 'restaurant cafe bar food drinks', 'menu'),\n print('menu-tabloid', 'Menu (Tabloid)', 11, 17, 'in', 'restaurant cafe bar large', 'menu'),\n // Canva's documents, reports, letters and resumes are portrait Letter or A4 pages.\n print('document-letter', 'Document (US Letter)', 8.5, 11, 'in', 'agenda form plan handout doc paper', 'document'),\n print('document-a4', 'Document (A4)', 210, 297, 'mm', 'agenda form plan handout doc paper', 'document'),\n print('report-letter', 'Report (US Letter)', 8.5, 11, 'in', 'annual business project research school', 'report'),\n print('report-a4', 'Report (A4)', 210, 297, 'mm', 'annual business project research school', 'report'),\n print('letter-us', 'Letter (US Letter)', 8.5, 11, 'in', 'cover business formal thank you', 'letter'),\n print('letter-a4', 'Letter (A4)', 210, 297, 'mm', 'cover business formal thank you', 'letter'),\n print('resume-letter', 'Resume (US Letter)', 8.5, 11, 'in', 'cv curriculum vitae job career', 'resume'),\n print('resume-a4', 'Resume (A4)', 210, 297, 'mm', 'cv curriculum vitae job career', 'resume'),\n // Canva's infographic is a tall screen page, 800 x 2000 px.\n {\n id: 'infographic',\n label: 'Infographic',\n category: 'infographic',\n width: 800,\n height: 2000,\n kind: 'deck',\n platform: 'Infographic',\n keywords: 'timeline process statistics chart data how-to',\n },\n];\n\nexport const POPULAR_SIZE_IDS = [\n 'ig-post-portrait',\n 'ig-story',\n 'slides-16-9',\n 'a4',\n 'ig-post-square',\n 'yt-thumb',\n 'a2',\n 'fb-post',\n];\n\nexport const SIZE_CATEGORIES: { id: SizeCategory; label: string }[] = [\n { id: 'popular', label: 'Popular' },\n { id: 'social', label: 'Social media' },\n { id: 'carousel', label: 'Carousels' },\n { id: 'flyer', label: 'Flyers' },\n { id: 'business-card', label: 'Business cards' },\n { id: 'presentation', label: 'Presentations' },\n { id: 'pitch-deck', label: 'Pitch decks' },\n { id: 'logo', label: 'Logos' },\n { id: 'banner', label: 'Banners' },\n { id: 'brochure', label: 'Brochures' },\n { id: 'branding', label: 'Branding' },\n { id: 'certificate', label: 'Certificates' },\n { id: 'worksheet', label: 'Worksheets' },\n { id: 'proposal', label: 'Proposals' },\n { id: 'newsletter', label: 'Newsletters' },\n { id: 'menu', label: 'Menus' },\n { id: 'infographic', label: 'Infographics' },\n { id: 'document', label: 'Documents' },\n { id: 'report', label: 'Reports' },\n { id: 'letter', label: 'Letters' },\n { id: 'resume', label: 'Resumes' },\n { id: 'technology', label: 'Technology' },\n { id: 'custom', label: 'Custom size' },\n];\n\n/** A pitch deck is a presentation: its blanks are the presentation sizes. A topic has none. */\nconst SIZES_OF: Partial<Record<SizeCategory, SizeCategory>> = { 'pitch-deck': 'presentation' };\n\nexport function sizesIn(category: SizeCategory): DesignSize[] {\n if (category === 'popular') return POPULAR_SIZE_IDS.map((id) => DESIGN_SIZES.find((s) => s.id === id)!);\n const own = SIZES_OF[category] ?? category;\n return DESIGN_SIZES.filter((s) => s.category === own);\n}\n\n/** Case-insensitive substring match on label, category and keywords. */\nexport function searchSizes(query: string): DesignSize[] {\n const q = query.trim().toLowerCase();\n if (!q) return [];\n return DESIGN_SIZES.filter((s) => `${s.label} ${s.category} ${s.platform} ${s.keywords}`.toLowerCase().includes(q));\n}\n\n// Aspects the carousel connector's layout and image generation accept.\nconst CONNECTOR_ASPECTS: [string, number][] = [\n ['1:1', 1],\n ['4:5', 4 / 5],\n ['2:3', 2 / 3],\n ['16:9', 16 / 9],\n];\n\n/** Nearest connector aspect, compared in log space so 2:1 and 1:2 are equally far from 1:1. */\nexport function snapAspect(width: number, height: number): string {\n const r = Math.log(width / height);\n let best = CONNECTOR_ASPECTS[0];\n for (const a of CONNECTOR_ASPECTS) if (Math.abs(r - Math.log(a[1])) < Math.abs(r - Math.log(best[1]))) best = a;\n return best[0];\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsxs,jsx}from'react/jsx-runtime';import {View,ScrollView,TextInput,Text,StyleSheet}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {useCanvasTheme,themedStyles}from'../../canvas/canvasTheme.js';import {Pressable,SPACE,RADIUS,TYPE}from'../../canvas/canvasUi.js';import {readChartData,parseCell,writeChartData}from'../doc/chart.js';import {ChipRow,ToolChip,ToggleRow}from'./controls.js';var __defProp = Object.defineProperty;
1
+ import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {View,ScrollView,TextInput,Text,StyleSheet}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {useCanvasTheme,themedStyles}from'../../canvas/canvasTheme.js';import {Pressable,SPACE,RADIUS,TYPE}from'../../canvas/canvasUi.js';import {readChartData,parseCell,writeChartData}from'../doc/chart.js';import {ChipRow,ToolChip,ToggleRow,ValueSlider}from'./controls.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -47,6 +47,7 @@ function ChartDataPanel({
47
47
  layer,
48
48
  patch
49
49
  }) {
50
+ var _a, _b;
50
51
  const theme = useCanvasTheme();
51
52
  const styles = makeStyles(theme);
52
53
  const data = readChartData(layer);
@@ -87,11 +88,11 @@ function ChartDataPanel({
87
88
  /* @__PURE__ */ jsx(TextInput, { value: cat, onChangeText: (t) => edit((d) => d.categories[ri] = t, `chart-cat:${layer.id}:${ri}`), placeholder: `Item ${ri + 1}`, placeholderTextColor: theme.edInk3, style: [styles.input, styles.head] })
88
89
  ] }),
89
90
  data.series.map((s, si) => {
90
- var _a;
91
+ var _a2;
91
92
  return /* @__PURE__ */ jsx(
92
93
  TextInput,
93
94
  {
94
- defaultValue: String((_a = s.values[ri]) != null ? _a : 0),
95
+ defaultValue: String((_a2 = s.values[ri]) != null ? _a2 : 0),
95
96
  onChangeText: (t) => edit((d) => d.series[si].values[ri] = parseCell(t), `chart-cell:${layer.id}:${si}:${ri}`),
96
97
  keyboardType: "numbers-and-punctuation",
97
98
  selectTextOnFocus: true,
@@ -109,18 +110,57 @@ function ChartDataPanel({
109
110
  /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "plus", size: 18, color: theme.edInk2 }),
110
111
  /* @__PURE__ */ jsx(Text, { style: styles.addLabel, children: "Add row" })
111
112
  ] }),
112
- !pie && layer.chart !== "line" ? /* @__PURE__ */ jsx(ToggleRow, { label: "Stacked", value: Boolean(layer.stacked), onChange: (v) => patch({
113
- stacked: v || void 0
114
- }) }) : null,
115
- /* @__PURE__ */ jsx(ToggleRow, { label: "Legend", value: Boolean(layer.legend), onChange: (v) => patch({
116
- legend: v || void 0
117
- }) })
113
+ /* @__PURE__ */ jsxs(ChipRow, { children: [
114
+ /* @__PURE__ */ jsx(ToolChip, { icon: "swap-horizontal", label: "Swap rows and columns", onPress: () => patch(writeChartData({
115
+ categories: data.series.map((s, i) => s.name || `Series ${i + 1}`),
116
+ series: data.categories.map((name, r) => ({
117
+ name,
118
+ values: data.series.map((s) => {
119
+ var _a2;
120
+ return (_a2 = s.values[r]) != null ? _a2 : 0;
121
+ })
122
+ }))
123
+ })) }),
124
+ /* @__PURE__ */ jsx(ToolChip, { icon: "delete-outline", label: "Clear data", onPress: () => patch(writeChartData({
125
+ categories: ["Item 1"],
126
+ series: [{
127
+ name: "Series 1",
128
+ values: [0]
129
+ }]
130
+ })) })
131
+ ] }),
132
+ /* @__PURE__ */ jsx(TextInput, { value: (_a = layer.title) != null ? _a : "", onChangeText: (title) => patch({
133
+ title
134
+ }, "chart-title"), placeholder: "Chart title (none)", placeholderTextColor: theme.edInk3, style: [styles.input, styles.title], accessibilityLabel: "Chart title" }),
135
+ /* @__PURE__ */ jsx(ToggleRow, { label: "Legend", value: layer.legend !== false, onChange: (v) => patch({
136
+ legend: v
137
+ }) }),
138
+ /* @__PURE__ */ jsx(ToggleRow, { label: "Value labels", value: Boolean(layer.valueLabels), onChange: (v) => patch({
139
+ valueLabels: v
140
+ }) }),
141
+ !pie ? /* @__PURE__ */ jsxs(Fragment, { children: [
142
+ /* @__PURE__ */ jsx(ToggleRow, { label: "Gridlines", value: layer.gridlines !== false, onChange: (v) => patch({
143
+ gridlines: v
144
+ }) }),
145
+ /* @__PURE__ */ jsx(ToggleRow, { label: "Axis labels", value: layer.axisLabels !== false, onChange: (v) => patch({
146
+ axisLabels: v
147
+ }) }),
148
+ /* @__PURE__ */ jsx(ToggleRow, { label: "Stacked", value: Boolean(layer.stacked), onChange: (v) => patch({
149
+ stacked: v
150
+ }) })
151
+ ] }) : null,
152
+ layer.chart === "donut" ? /* @__PURE__ */ jsx(ValueSlider, { label: "Hole", value: (_b = layer.holeFrac) != null ? _b : 0.55, min: 0.1, max: 0.85, step: 0.05, format: (v) => `${Math.round(v * 100)}%`, onChange: (holeFrac) => patch({
153
+ holeFrac
154
+ }, "chart-hole") }) : null
118
155
  ] });
119
156
  }
120
157
  const makeStyles = themedStyles((theme) => StyleSheet.create({
121
158
  stack: {
122
159
  gap: SPACE.sm
123
160
  },
161
+ title: {
162
+ width: "100%"
163
+ },
124
164
  gridScroll: {
125
165
  flexGrow: 0
126
166
  },
@@ -1 +1 @@
1
- {"version":3,"file":"ChartDataPanel.js","sources":["../../../../src/features/design/editor/ChartDataPanel.tsx"],"sourcesContent":["/**\n * The chart sheet (web ChartPanel + ChartDataGrid): the chart's kind, its\n * numbers as a small spreadsheet (rows are categories, columns named series),\n * and the stacked and legend switches. Every edit writes `categories`/`series`\n * and the legacy `data` mirror (doc/chart.ts writeChartData), as web does.\n */\nimport React from 'react';\nimport { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { themedStyles, useCanvasTheme, type CanvasPalette } from '../../canvas/canvasTheme';\nimport { Pressable, RADIUS, SPACE, TYPE } from '../../canvas/canvasUi';\nimport { parseCell, readChartData, writeChartData, type ChartData } from '../doc/chart';\nimport type { ChartKind, ChartLayer, EditorLayer } from '../doc/types';\nimport { ChipRow, ToggleRow, ToolChip } from './controls';\n\nconst KINDS: Array<{\n id: ChartKind;\n label: string;\n icon: React.ComponentProps<typeof MaterialCommunityIcons>['name'];\n}> = [\n { id: 'bar', label: 'Bar', icon: 'chart-bar' },\n { id: 'row', label: 'Row', icon: 'chart-gantt' },\n { id: 'line', label: 'Line', icon: 'chart-line' },\n { id: 'area', label: 'Area', icon: 'chart-areaspline' },\n { id: 'pie', label: 'Pie', icon: 'chart-pie' },\n { id: 'donut', label: 'Donut', icon: 'chart-donut' },\n];\n\nconst CELL_W = 84;\n\nexport function ChartDataPanel({\n layer,\n patch,\n}: {\n layer: ChartLayer;\n patch: (p: Partial<EditorLayer>, coalesce?: string) => void;\n}) {\n const theme = useCanvasTheme();\n const styles = makeStyles(theme);\n const data = readChartData(layer);\n const edit = (fn: (d: ChartData) => void, coalesce?: string) => {\n const draft: ChartData = {\n categories: [...data.categories],\n series: data.series.map((s) => ({ name: s.name, values: [...s.values] })),\n };\n fn(draft);\n patch(writeChartData(draft), coalesce);\n };\n const pie = layer.chart === 'pie' || layer.chart === 'donut';\n return (\n <View style={styles.stack}>\n <ChipRow>\n {KINDS.map((k) => (\n <ToolChip\n key={k.id}\n icon={k.icon}\n label={k.label}\n active={layer.chart === k.id}\n onPress={() => patch({ chart: k.id })}\n />\n ))}\n </ChipRow>\n <ScrollView\n horizontal\n style={styles.gridScroll}\n keyboardShouldPersistTaps=\"handled\"\n showsHorizontalScrollIndicator={false}\n >\n <View>\n <View style={styles.gridRow}>\n <View style={[styles.cell, styles.corner]} />\n {data.series.map((s, si) => (\n <View key={si} style={styles.headCell}>\n <TextInput\n value={s.name}\n onChangeText={(t) =>\n edit((d) => (d.series[si].name = t), `chart-name:${layer.id}:${si}`)\n }\n placeholder={`Series ${si + 1}`}\n placeholderTextColor={theme.edInk3}\n style={[styles.input, styles.head]}\n />\n {data.series.length > 1 ? (\n <Pressable\n onPress={() => edit((d) => d.series.splice(si, 1))}\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel={`Remove ${s.name || `series ${si + 1}`}`}\n >\n <MaterialCommunityIcons name=\"close\" size={14} color={theme.edInk3} />\n </Pressable>\n ) : null}\n </View>\n ))}\n {!pie ? (\n <Pressable\n onPress={() =>\n edit((d) =>\n d.series.push({\n name: `Series ${d.series.length + 1}`,\n values: d.categories.map(() => 0),\n }),\n )\n }\n style={styles.addCol}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Add series\"\n >\n <MaterialCommunityIcons name=\"plus\" size={18} color={theme.edInk2} />\n </Pressable>\n ) : null}\n </View>\n {data.categories.map((cat, ri) => (\n <View key={ri} style={styles.gridRow}>\n <View style={styles.rowHead}>\n {data.categories.length > 1 ? (\n <Pressable\n onPress={() =>\n edit((d) => {\n d.categories.splice(ri, 1);\n d.series.forEach((s) => s.values.splice(ri, 1));\n })\n }\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel={`Remove ${cat || `row ${ri + 1}`}`}\n >\n <MaterialCommunityIcons name=\"close\" size={14} color={theme.edInk3} />\n </Pressable>\n ) : null}\n <TextInput\n value={cat}\n onChangeText={(t) =>\n edit((d) => (d.categories[ri] = t), `chart-cat:${layer.id}:${ri}`)\n }\n placeholder={`Item ${ri + 1}`}\n placeholderTextColor={theme.edInk3}\n style={[styles.input, styles.head]}\n />\n </View>\n {data.series.map((s, si) => (\n <TextInput\n // Re-keyed when rows or series move, so a cell never shows its neighbour's number.\n key={`${si}:${ri}:${data.series.length}:${data.categories.length}`}\n defaultValue={String(s.values[ri] ?? 0)}\n onChangeText={(t) =>\n edit(\n (d) => (d.series[si].values[ri] = parseCell(t)),\n `chart-cell:${layer.id}:${si}:${ri}`,\n )\n }\n keyboardType=\"numbers-and-punctuation\"\n selectTextOnFocus\n style={[styles.input, styles.cell]}\n />\n ))}\n </View>\n ))}\n </View>\n </ScrollView>\n <Pressable\n onPress={() =>\n edit((d) => {\n d.categories.push(`Item ${d.categories.length + 1}`);\n d.series.forEach((s) => s.values.push(0));\n })\n }\n style={styles.addRow}\n accessibilityRole=\"button\"\n >\n <MaterialCommunityIcons name=\"plus\" size={18} color={theme.edInk2} />\n <Text style={styles.addLabel}>Add row</Text>\n </Pressable>\n {!pie && layer.chart !== 'line' ? (\n <ToggleRow\n label=\"Stacked\"\n value={Boolean(layer.stacked)}\n onChange={(v) => patch({ stacked: v || undefined })}\n />\n ) : null}\n <ToggleRow\n label=\"Legend\"\n value={Boolean(layer.legend)}\n onChange={(v) => patch({ legend: v || undefined })}\n />\n </View>\n );\n}\n\nconst makeStyles = themedStyles((theme: CanvasPalette) =>\n StyleSheet.create({\n stack: { gap: SPACE.sm },\n gridScroll: { flexGrow: 0 },\n gridRow: { flexDirection: 'row', alignItems: 'center', gap: 4, marginBottom: 4 },\n corner: { width: CELL_W + 18, backgroundColor: 'transparent' },\n headCell: { width: CELL_W, flexDirection: 'row', alignItems: 'center', gap: 2 },\n rowHead: { width: CELL_W + 18, flexDirection: 'row', alignItems: 'center', gap: 2 },\n input: {\n height: 34,\n borderRadius: RADIUS.sm,\n paddingHorizontal: SPACE.sm,\n backgroundColor: theme.edRaised,\n color: theme.edInk,\n ...TYPE.caption,\n },\n head: { flex: 1, fontWeight: '600' },\n cell: { width: CELL_W, textAlign: 'right' },\n addCol: {\n width: 34,\n height: 34,\n borderRadius: RADIUS.sm,\n alignItems: 'center',\n justifyContent: 'center',\n borderWidth: 1,\n borderColor: theme.edLine,\n },\n addRow: { flexDirection: 'row', alignItems: 'center', gap: SPACE.xs, height: 36 },\n addLabel: { ...TYPE.label, color: theme.edInk2 },\n }),\n);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChartDataPanel.js","sources":["../../../../src/features/design/editor/ChartDataPanel.tsx"],"sourcesContent":["/**\n * The chart sheet (web ChartPanel + ChartDataGrid): the chart's kind, its\n * numbers as a small spreadsheet (rows are categories, columns named series),\n * swap and clear, the title, web's Show switches and the donut hole. Every edit writes `categories`/`series`\n * and the legacy `data` mirror (doc/chart.ts writeChartData), as web does.\n */\nimport React from 'react';\nimport { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { themedStyles, useCanvasTheme, type CanvasPalette } from '../../canvas/canvasTheme';\nimport { Pressable, RADIUS, SPACE, TYPE } from '../../canvas/canvasUi';\nimport { parseCell, readChartData, writeChartData, type ChartData } from '../doc/chart';\nimport type { ChartKind, ChartLayer, EditorLayer } from '../doc/types';\nimport { ChipRow, ToggleRow, ToolChip, ValueSlider } from './controls';\n\nconst KINDS: Array<{\n id: ChartKind;\n label: string;\n icon: React.ComponentProps<typeof MaterialCommunityIcons>['name'];\n}> = [\n { id: 'bar', label: 'Bar', icon: 'chart-bar' },\n { id: 'row', label: 'Row', icon: 'chart-gantt' },\n { id: 'line', label: 'Line', icon: 'chart-line' },\n { id: 'area', label: 'Area', icon: 'chart-areaspline' },\n { id: 'pie', label: 'Pie', icon: 'chart-pie' },\n { id: 'donut', label: 'Donut', icon: 'chart-donut' },\n];\n\nconst CELL_W = 84;\n\nexport function ChartDataPanel({\n layer,\n patch,\n}: {\n layer: ChartLayer;\n patch: (p: Partial<EditorLayer>, coalesce?: string) => void;\n}) {\n const theme = useCanvasTheme();\n const styles = makeStyles(theme);\n const data = readChartData(layer);\n const edit = (fn: (d: ChartData) => void, coalesce?: string) => {\n const draft: ChartData = {\n categories: [...data.categories],\n series: data.series.map((s) => ({ name: s.name, values: [...s.values] })),\n };\n fn(draft);\n patch(writeChartData(draft), coalesce);\n };\n const pie = layer.chart === 'pie' || layer.chart === 'donut';\n return (\n <View style={styles.stack}>\n <ChipRow>\n {KINDS.map((k) => (\n <ToolChip\n key={k.id}\n icon={k.icon}\n label={k.label}\n active={layer.chart === k.id}\n onPress={() => patch({ chart: k.id })}\n />\n ))}\n </ChipRow>\n <ScrollView\n horizontal\n style={styles.gridScroll}\n keyboardShouldPersistTaps=\"handled\"\n showsHorizontalScrollIndicator={false}\n >\n <View>\n <View style={styles.gridRow}>\n <View style={[styles.cell, styles.corner]} />\n {data.series.map((s, si) => (\n <View key={si} style={styles.headCell}>\n <TextInput\n value={s.name}\n onChangeText={(t) =>\n edit((d) => (d.series[si].name = t), `chart-name:${layer.id}:${si}`)\n }\n placeholder={`Series ${si + 1}`}\n placeholderTextColor={theme.edInk3}\n style={[styles.input, styles.head]}\n />\n {data.series.length > 1 ? (\n <Pressable\n onPress={() => edit((d) => d.series.splice(si, 1))}\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel={`Remove ${s.name || `series ${si + 1}`}`}\n >\n <MaterialCommunityIcons name=\"close\" size={14} color={theme.edInk3} />\n </Pressable>\n ) : null}\n </View>\n ))}\n {!pie ? (\n <Pressable\n onPress={() =>\n edit((d) =>\n d.series.push({\n name: `Series ${d.series.length + 1}`,\n values: d.categories.map(() => 0),\n }),\n )\n }\n style={styles.addCol}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Add series\"\n >\n <MaterialCommunityIcons name=\"plus\" size={18} color={theme.edInk2} />\n </Pressable>\n ) : null}\n </View>\n {data.categories.map((cat, ri) => (\n <View key={ri} style={styles.gridRow}>\n <View style={styles.rowHead}>\n {data.categories.length > 1 ? (\n <Pressable\n onPress={() =>\n edit((d) => {\n d.categories.splice(ri, 1);\n d.series.forEach((s) => s.values.splice(ri, 1));\n })\n }\n hitSlop={6}\n accessibilityRole=\"button\"\n accessibilityLabel={`Remove ${cat || `row ${ri + 1}`}`}\n >\n <MaterialCommunityIcons name=\"close\" size={14} color={theme.edInk3} />\n </Pressable>\n ) : null}\n <TextInput\n value={cat}\n onChangeText={(t) =>\n edit((d) => (d.categories[ri] = t), `chart-cat:${layer.id}:${ri}`)\n }\n placeholder={`Item ${ri + 1}`}\n placeholderTextColor={theme.edInk3}\n style={[styles.input, styles.head]}\n />\n </View>\n {data.series.map((s, si) => (\n <TextInput\n // Re-keyed when rows or series move, so a cell never shows its neighbour's number.\n key={`${si}:${ri}:${data.series.length}:${data.categories.length}`}\n defaultValue={String(s.values[ri] ?? 0)}\n onChangeText={(t) =>\n edit(\n (d) => (d.series[si].values[ri] = parseCell(t)),\n `chart-cell:${layer.id}:${si}:${ri}`,\n )\n }\n keyboardType=\"numbers-and-punctuation\"\n selectTextOnFocus\n style={[styles.input, styles.cell]}\n />\n ))}\n </View>\n ))}\n </View>\n </ScrollView>\n <Pressable\n onPress={() =>\n edit((d) => {\n d.categories.push(`Item ${d.categories.length + 1}`);\n d.series.forEach((s) => s.values.push(0));\n })\n }\n style={styles.addRow}\n accessibilityRole=\"button\"\n >\n <MaterialCommunityIcons name=\"plus\" size={18} color={theme.edInk2} />\n <Text style={styles.addLabel}>Add row</Text>\n </Pressable>\n <ChipRow>\n <ToolChip\n icon=\"swap-horizontal\"\n label=\"Swap rows and columns\"\n onPress={() =>\n patch(\n writeChartData({\n categories: data.series.map((s, i) => s.name || `Series ${i + 1}`),\n series: data.categories.map((name, r) => ({\n name,\n values: data.series.map((s) => s.values[r] ?? 0),\n })),\n }),\n )\n }\n />\n <ToolChip\n icon=\"delete-outline\"\n label=\"Clear data\"\n onPress={() =>\n patch(writeChartData({ categories: ['Item 1'], series: [{ name: 'Series 1', values: [0] }] }))\n }\n />\n </ChipRow>\n <TextInput\n value={layer.title ?? ''}\n onChangeText={(title) => patch({ title }, 'chart-title')}\n placeholder=\"Chart title (none)\"\n placeholderTextColor={theme.edInk3}\n style={[styles.input, styles.title]}\n accessibilityLabel=\"Chart title\"\n />\n {/* Web's switches, written as web writes them: legend, gridlines and axis labels are on unless false. */}\n <ToggleRow label=\"Legend\" value={layer.legend !== false} onChange={(v) => patch({ legend: v })} />\n <ToggleRow\n label=\"Value labels\"\n value={Boolean(layer.valueLabels)}\n onChange={(v) => patch({ valueLabels: v })}\n />\n {!pie ? (\n <>\n <ToggleRow\n label=\"Gridlines\"\n value={layer.gridlines !== false}\n onChange={(v) => patch({ gridlines: v })}\n />\n <ToggleRow\n label=\"Axis labels\"\n value={layer.axisLabels !== false}\n onChange={(v) => patch({ axisLabels: v })}\n />\n <ToggleRow label=\"Stacked\" value={Boolean(layer.stacked)} onChange={(v) => patch({ stacked: v })} />\n </>\n ) : null}\n {layer.chart === 'donut' ? (\n <ValueSlider\n label=\"Hole\"\n value={layer.holeFrac ?? 0.55}\n min={0.1}\n max={0.85}\n step={0.05}\n format={(v) => `${Math.round(v * 100)}%`}\n onChange={(holeFrac) => patch({ holeFrac }, 'chart-hole')}\n />\n ) : null}\n </View>\n );\n}\n\nconst makeStyles = themedStyles((theme: CanvasPalette) =>\n StyleSheet.create({\n stack: { gap: SPACE.sm },\n title: { width: '100%' },\n gridScroll: { flexGrow: 0 },\n gridRow: { flexDirection: 'row', alignItems: 'center', gap: 4, marginBottom: 4 },\n corner: { width: CELL_W + 18, backgroundColor: 'transparent' },\n headCell: { width: CELL_W, flexDirection: 'row', alignItems: 'center', gap: 2 },\n rowHead: { width: CELL_W + 18, flexDirection: 'row', alignItems: 'center', gap: 2 },\n input: {\n height: 34,\n borderRadius: RADIUS.sm,\n paddingHorizontal: SPACE.sm,\n backgroundColor: theme.edRaised,\n color: theme.edInk,\n ...TYPE.caption,\n },\n head: { flex: 1, fontWeight: '600' },\n cell: { width: CELL_W, textAlign: 'right' },\n addCol: {\n width: 34,\n height: 34,\n borderRadius: RADIUS.sm,\n alignItems: 'center',\n justifyContent: 'center',\n borderWidth: 1,\n borderColor: theme.edLine,\n },\n addRow: { flexDirection: 'row', alignItems: 'center', gap: SPACE.xs, height: 36 },\n addLabel: { ...TYPE.label, color: theme.edInk2 },\n }),\n);\n"],"names":["_a"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsxs,jsx}from'react/jsx-runtime';import {useState,useMemo,useRef}from'react';import {StyleSheet,PanResponder,View,Text}from'react-native';import {Image}from'expo-image';import {useCanvasTheme}from'../../canvas/canvasTheme.js';import {RADIUS,SPACE,Pressable,TYPE}from'../../canvas/canvasUi.js';import {cropStart,cropPan,cropResize,cropCommit}from'../doc/crop.js';import {CANVAS_MARGIN}from'./DesignCanvas.js';var __defProp = Object.defineProperty;
1
+ import {jsxs,jsx}from'react/jsx-runtime';import {useState,useMemo,useRef}from'react';import {PanResponder,View,StyleSheet,Text}from'react-native';import {Image}from'expo-image';import {useCanvasTheme}from'../../canvas/canvasTheme.js';import {Pressable,RADIUS,SPACE,TYPE}from'../../canvas/canvasUi.js';import {cropStart,cropPan,cropResize,cropCommit}from'../doc/crop.js';import {CANVAS_MARGIN}from'./DesignCanvas.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -1,4 +1,4 @@
1
- import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useState,useRef,useMemo}from'react';import {StyleSheet,PanResponder,View}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {useCanvasTheme}from'../../canvas/canvasTheme.js';import {snapToPage,resizeBox,rotateFromDrag,layerBox,handlePoint,hitTest,rotateKnobPoint}from'../doc/geometry.js';import {DesignPageView}from'../render/DesignPageView.js';var __defProp = Object.defineProperty;
1
+ import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useState,useRef,useMemo}from'react';import {PanResponder,View,StyleSheet}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {useCanvasTheme}from'../../canvas/canvasTheme.js';import {layerBox,snapMove,snapLines,resizeBox,rotateFromDrag,rotateKnobPoint,handlePoint,hitTest}from'../doc/geometry.js';import {DesignPageView}from'../render/DesignPageView.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -42,8 +42,8 @@ function DesignCanvas({
42
42
  h: 0
43
43
  });
44
44
  const [guides, setGuides] = useState({
45
- x: false,
46
- y: false
45
+ x: null,
46
+ y: null
47
47
  });
48
48
  const aspect = doc.pageWidth / Math.max(1, doc.pageHeight);
49
49
  const W = Math.max(1, Math.min(area.w - MARGIN * 2, (area.h - MARGIN * 2) * aspect));
@@ -146,10 +146,11 @@ function DesignCanvas({
146
146
  const key = `${m.kind}:${m.layer.id}:${s.gestureId}`;
147
147
  if (m.kind === "move") {
148
148
  if (m.layer.locked) return;
149
- const snapped = snapToPage(__spreadProps(__spreadValues({}, m.box), {
149
+ const others = s.layers.filter((l) => l.id !== m.layer.id).map((l) => layerBox(l, s.W, s.H));
150
+ const snapped = snapMove(__spreadProps(__spreadValues({}, m.box), {
150
151
  x: m.box.x + g.dx,
151
152
  y: m.box.y + g.dy
152
- }), s.W, s.H);
153
+ }), snapLines(others, s.W, s.H));
153
154
  setGuides((prev) => prev.x === snapped.guideX && prev.y === snapped.guideY ? prev : {
154
155
  x: snapped.guideX,
155
156
  y: snapped.guideY
@@ -193,8 +194,8 @@ function DesignCanvas({
193
194
  kind: "none"
194
195
  };
195
196
  setGuides({
196
- x: false,
197
- y: false
197
+ x: null,
198
+ y: null
198
199
  });
199
200
  if (m.kind === "page" && !m.moved) s.onSelect(null);
200
201
  if (m.kind === "move" && !m.moved && m.wasSelected && m.layer.kind === "text" && !m.layer.locked) {
@@ -206,8 +207,8 @@ function DesignCanvas({
206
207
  kind: "none"
207
208
  };
208
209
  setGuides({
209
- x: false,
210
- y: false
210
+ x: null,
211
+ y: null
211
212
  });
212
213
  }
213
214
  }), []);
@@ -229,14 +230,14 @@ function DesignCanvas({
229
230
  width: W,
230
231
  height: H
231
232
  }], children: /* @__PURE__ */ jsx(DesignPageView, { doc, page, width: W }) }),
232
- guides.x ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: [styles.guideV, {
233
- left: ox + W / 2,
233
+ guides.x !== null ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: [styles.guideV, {
234
+ left: ox + guides.x,
234
235
  top: oy,
235
236
  height: H,
236
237
  backgroundColor: "#ec4899"
237
238
  }] }) : null,
238
- guides.y ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: [styles.guideH, {
239
- top: oy + H / 2,
239
+ guides.y !== null ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: [styles.guideH, {
240
+ top: oy + guides.y,
240
241
  left: ox,
241
242
  width: W,
242
243
  backgroundColor: "#ec4899"
@@ -1 +1 @@
1
- {"version":3,"file":"DesignCanvas.js","sources":["../../../../src/features/design/editor/DesignCanvas.tsx"],"sourcesContent":["/**\n * The page being edited, and every touch on it.\n *\n * One gesture surface lies over the page with nothing touchable inside it,\n * so `locationX/Y` is always in its own frame. A touch starts on the\n * selected layer's handle (resize), its knob (rotate), a layer (select and\n * move) or the bare page (deselect on tap). A tap on text that is already\n * selected opens it for typing, as Canva does.\n *\n * Moves, resizes and turns stream as `patchLayer`s keyed per gesture, which the\n * reducer coalesces into one undo step (doc/docOps.ts).\n */\nimport React, { useMemo, useRef, useState } from 'react';\nimport { PanResponder, StyleSheet, View, type LayoutChangeEvent } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { useCanvasTheme } from '../../canvas/canvasTheme';\nimport {\n handlePoint,\n hitTest,\n layerBox,\n resizeBox,\n rotateFromDrag,\n rotateKnobPoint,\n snapToPage,\n type Box,\n type Handle,\n} from '../doc/geometry';\nimport type { DesignDoc, DesignPage, EditorLayer, TextLayer } from '../doc/types';\nimport { DesignPageView } from '../render/DesignPageView';\n\nconst MARGIN = 20;\n/** The page's inset from the canvas area's edge: overlays over the canvas (crop) frame the page the same way. */\nexport const CANVAS_MARGIN = MARGIN;\nconst HANDLE_HIT = 24;\nconst KNOB_GAP = 28;\n/** Movement under this many px is still a tap. */\nconst TAP_SLOP = 6;\n\ntype Mode =\n | { kind: 'none' }\n | { kind: 'page'; moved: boolean }\n | { kind: 'move'; layer: EditorLayer; box: Box; wasSelected: boolean; moved: boolean }\n | { kind: 'resize'; layer: EditorLayer; box: Box; handle: Handle; moved: boolean }\n | { kind: 'rotate'; layer: EditorLayer; box: Box; from: [number, number]; moved: boolean };\n\n/** The handles a layer offers: text grows sideways (its height follows its words); others every way. */\nfunction handlesFor(layer: EditorLayer): Handle[] {\n if (layer.kind === 'text') return ['nw', 'ne', 'se', 'sw', 'e', 'w'];\n return ['nw', 'ne', 'se', 'sw', 'n', 'e', 's', 'w'];\n}\n\nexport interface DesignCanvasProps {\n doc: DesignDoc;\n page: DesignPage;\n selectedId: string | null;\n /** A layer being typed into: drawn, but not selectable by touch. */\n editingId?: string | null;\n onSelect: (layerId: string | null) => void;\n onPatch: (layerId: string, patch: Partial<EditorLayer>, coalesce: string) => void;\n onEditText: (layerId: string) => void;\n}\n\nexport function DesignCanvas({ doc, page, selectedId, editingId, onSelect, onPatch, onEditText }: DesignCanvasProps) {\n const theme = useCanvasTheme();\n const [area, setArea] = useState({ w: 0, h: 0 });\n const [guides, setGuides] = useState({ x: false, y: false });\n\n const aspect = doc.pageWidth / Math.max(1, doc.pageHeight);\n const W = Math.max(1, Math.min(area.w - MARGIN * 2, (area.h - MARGIN * 2) * aspect));\n const H = W / aspect;\n const ox = (area.w - W) / 2;\n const oy = (area.h - H) / 2;\n\n const layers = page.layers ?? [];\n const selected = layers.find((l) => l.id === selectedId) ?? null;\n\n // The responder is created once; it reads the live frame through this ref.\n const live = useRef({ W, H, ox, oy, layers, selected, onSelect, onPatch, onEditText, gestureId: 0 });\n live.current = { ...live.current, W, H, ox, oy, layers, selected, onSelect, onPatch, onEditText };\n const mode = useRef<Mode>({ kind: 'none' });\n\n const responder = useMemo(\n () =>\n PanResponder.create({\n onStartShouldSetPanResponder: () => true,\n onMoveShouldSetPanResponder: () => true,\n onPanResponderTerminationRequest: () => false,\n onPanResponderGrant: (e) => {\n const s = live.current;\n s.gestureId += 1;\n const px = e.nativeEvent.locationX - s.ox;\n const py = e.nativeEvent.locationY - s.oy;\n const sel = s.selected;\n if (sel && !sel.locked) {\n const box = layerBox(sel, s.W, s.H);\n const deg = sel.rotation ?? 0;\n const [kx, ky] = rotateKnobPoint(box, deg, KNOB_GAP);\n if (Math.hypot(px - kx, py - ky) <= HANDLE_HIT) {\n mode.current = { kind: 'rotate', layer: sel, box, from: [px, py], moved: false };\n return;\n }\n for (const handle of handlesFor(sel)) {\n const [hx, hy] = handlePoint(box, deg, handle);\n if (Math.hypot(px - hx, py - hy) <= HANDLE_HIT) {\n mode.current = { kind: 'resize', layer: sel, box, handle, moved: false };\n return;\n }\n }\n }\n const hit = hitTest(s.layers, px, py, s.W, s.H);\n if (!hit) {\n mode.current = { kind: 'page', moved: false };\n return;\n }\n const wasSelected = hit.id === sel?.id;\n if (!wasSelected) s.onSelect(hit.id);\n mode.current = {\n kind: 'move',\n layer: hit,\n box: layerBox(hit, s.W, s.H),\n wasSelected,\n moved: false,\n };\n },\n onPanResponderMove: (e, g) => {\n const s = live.current;\n const m = mode.current;\n if (m.kind === 'none') return;\n if (!m.moved && Math.hypot(g.dx, g.dy) < TAP_SLOP) return;\n m.moved = true;\n if (m.kind === 'page') return;\n const key = `${m.kind}:${m.layer.id}:${s.gestureId}`;\n if (m.kind === 'move') {\n if (m.layer.locked) return;\n const snapped = snapToPage({ ...m.box, x: m.box.x + g.dx, y: m.box.y + g.dy }, s.W, s.H);\n setGuides((prev) =>\n prev.x === snapped.guideX && prev.y === snapped.guideY\n ? prev\n : { x: snapped.guideX, y: snapped.guideY },\n );\n s.onPatch(m.layer.id, { x: snapped.box.x / s.W, y: snapped.box.y / s.H }, key);\n return;\n }\n if (m.kind === 'resize') {\n const corner = m.handle.length === 2;\n const keepAspect = corner && (m.layer.kind === 'image' || m.layer.kind === 'text');\n const next = resizeBox(m.box, m.layer.rotation ?? 0, m.handle, g.dx, g.dy, {\n keepAspect,\n minSize: 12,\n });\n const patch: Partial<EditorLayer> = {\n x: next.x / s.W,\n y: next.y / s.H,\n w: next.w / s.W,\n h: next.h / s.H,\n };\n // A text corner scales its words with the box, as Canva's does.\n if (m.layer.kind === 'text' && corner) {\n const scale = next.w / m.box.w;\n (patch as Partial<TextLayer>).fontSizeFrac = (m.layer as TextLayer).fontSizeFrac * scale;\n }\n s.onPatch(m.layer.id, patch, key);\n return;\n }\n const px = e.nativeEvent.locationX - s.ox;\n const py = e.nativeEvent.locationY - s.oy;\n s.onPatch(\n m.layer.id,\n { rotation: rotateFromDrag(m.box, m.layer.rotation ?? 0, m.from, [px, py]) },\n key,\n );\n },\n onPanResponderRelease: () => {\n const s = live.current;\n const m = mode.current;\n mode.current = { kind: 'none' };\n setGuides({ x: false, y: false });\n if (m.kind === 'page' && !m.moved) s.onSelect(null);\n if (m.kind === 'move' && !m.moved && m.wasSelected && m.layer.kind === 'text' && !m.layer.locked) {\n s.onEditText(m.layer.id);\n }\n },\n onPanResponderTerminate: () => {\n mode.current = { kind: 'none' };\n setGuides({ x: false, y: false });\n },\n }),\n [],\n );\n\n const onLayout = (e: LayoutChangeEvent) => {\n const { width, height } = e.nativeEvent.layout;\n setArea((prev) => (prev.w === width && prev.h === height ? prev : { w: width, h: height }));\n };\n\n const accent = theme.edAccent;\n return (\n <View style={styles.fill} onLayout={onLayout}>\n {area.w > 0 ? (\n <>\n <View style={[styles.pageShadow, { left: ox, top: oy, width: W, height: H }]}>\n <DesignPageView doc={doc} page={page} width={W} />\n </View>\n {guides.x ? (\n <View\n pointerEvents=\"none\"\n style={[\n styles.guideV,\n { left: ox + W / 2, top: oy, height: H, backgroundColor: '#ec4899' },\n ]}\n />\n ) : null}\n {guides.y ? (\n <View\n pointerEvents=\"none\"\n style={[styles.guideH, { top: oy + H / 2, left: ox, width: W, backgroundColor: '#ec4899' }]}\n />\n ) : null}\n {selected && selected.id !== editingId ? (\n <SelectionFrame layer={selected} W={W} H={H} ox={ox} oy={oy} accent={accent} />\n ) : null}\n <View style={StyleSheet.absoluteFill} {...responder.panHandlers} />\n </>\n ) : null}\n </View>\n );\n}\n\n/** The selected layer's outline, handles and rotate knob, turned with it. Draw-only. */\nfunction SelectionFrame({\n layer,\n W,\n H,\n ox,\n oy,\n accent,\n}: {\n layer: EditorLayer;\n W: number;\n H: number;\n ox: number;\n oy: number;\n accent: string;\n}) {\n const box = layerBox(layer, W, H);\n const deg = layer.rotation ?? 0;\n const locked = Boolean(layer.locked);\n return (\n <View\n pointerEvents=\"none\"\n style={{\n position: 'absolute',\n left: ox + box.x,\n top: oy + box.y,\n width: box.w,\n height: box.h,\n transform: deg ? [{ rotate: `${deg}deg` }] : undefined,\n }}\n >\n <View\n style={[StyleSheet.absoluteFill, styles.frame, { borderColor: accent }, locked && styles.frameLocked]}\n />\n {locked ? (\n <View style={[styles.lockBadge, { backgroundColor: accent }]}>\n <MaterialCommunityIcons name=\"lock\" size={12} color=\"#fff\" />\n </View>\n ) : (\n <>\n {handlesFor(layer).map((handle) => {\n const corner = handle.length === 2;\n const left = handle.includes('w') ? 0 : handle.includes('e') ? box.w : box.w / 2;\n const top = handle.includes('n') ? 0 : handle.includes('s') ? box.h : box.h / 2;\n const vertical = handle === 'e' || handle === 'w';\n const size = corner ? { w: 14, h: 14 } : vertical ? { w: 8, h: 22 } : { w: 22, h: 8 };\n return (\n <View\n key={handle}\n style={[\n styles.handle,\n {\n left: left - size.w / 2,\n top: top - size.h / 2,\n width: size.w,\n height: size.h,\n borderRadius: corner ? 7 : 4,\n borderColor: accent,\n },\n ]}\n />\n );\n })}\n <View\n style={[styles.knob, { left: box.w / 2 - 14, top: box.h + KNOB_GAP - 14, borderColor: accent }]}\n >\n <MaterialCommunityIcons name=\"rotate-right\" size={16} color={accent} />\n </View>\n </>\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n pageShadow: {\n position: 'absolute',\n backgroundColor: '#ffffff',\n shadowColor: '#000',\n shadowOpacity: 0.16,\n shadowRadius: 12,\n shadowOffset: { width: 0, height: 4 },\n elevation: 4,\n },\n frame: { borderWidth: 1.5 },\n frameLocked: { borderStyle: 'dashed' },\n handle: { position: 'absolute', backgroundColor: '#ffffff', borderWidth: 1.5 },\n knob: {\n position: 'absolute',\n width: 28,\n height: 28,\n borderRadius: 14,\n backgroundColor: '#ffffff',\n borderWidth: 1.5,\n alignItems: 'center',\n justifyContent: 'center',\n },\n lockBadge: {\n position: 'absolute',\n right: -10,\n top: -10,\n width: 20,\n height: 20,\n borderRadius: 10,\n alignItems: 'center',\n justifyContent: 'center',\n },\n guideV: { position: 'absolute', width: 1 },\n guideH: { position: 'absolute', height: 1 },\n});\n"],"names":["_a","_b"],"mappings":"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"}
1
+ {"version":3,"file":"DesignCanvas.js","sources":["../../../../src/features/design/editor/DesignCanvas.tsx"],"sourcesContent":["/**\n * The page being edited, and every touch on it.\n *\n * One gesture surface lies over the page with nothing touchable inside it,\n * so `locationX/Y` is always in its own frame. A touch starts on the\n * selected layer's handle (resize), its knob (rotate), a layer (select and\n * move) or the bare page (deselect on tap). A tap on text that is already\n * selected opens it for typing, as Canva does.\n *\n * Moves, resizes and turns stream as `patchLayer`s keyed per gesture, which the\n * reducer coalesces into one undo step (doc/docOps.ts).\n */\nimport React, { useMemo, useRef, useState } from 'react';\nimport { PanResponder, StyleSheet, View, type LayoutChangeEvent } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { useCanvasTheme } from '../../canvas/canvasTheme';\nimport {\n handlePoint,\n hitTest,\n layerBox,\n resizeBox,\n rotateFromDrag,\n rotateKnobPoint,\n snapLines,\n snapMove,\n type Box,\n type Handle,\n} from '../doc/geometry';\nimport type { DesignDoc, DesignPage, EditorLayer, TextLayer } from '../doc/types';\nimport { DesignPageView } from '../render/DesignPageView';\n\nconst MARGIN = 20;\n/** The page's inset from the canvas area's edge: overlays over the canvas (crop) frame the page the same way. */\nexport const CANVAS_MARGIN = MARGIN;\nconst HANDLE_HIT = 24;\nconst KNOB_GAP = 28;\n/** Movement under this many px is still a tap. */\nconst TAP_SLOP = 6;\n\ntype Mode =\n | { kind: 'none' }\n | { kind: 'page'; moved: boolean }\n | { kind: 'move'; layer: EditorLayer; box: Box; wasSelected: boolean; moved: boolean }\n | { kind: 'resize'; layer: EditorLayer; box: Box; handle: Handle; moved: boolean }\n | { kind: 'rotate'; layer: EditorLayer; box: Box; from: [number, number]; moved: boolean };\n\n/** The handles a layer offers: text grows sideways (its height follows its words); others every way. */\nfunction handlesFor(layer: EditorLayer): Handle[] {\n if (layer.kind === 'text') return ['nw', 'ne', 'se', 'sw', 'e', 'w'];\n return ['nw', 'ne', 'se', 'sw', 'n', 'e', 's', 'w'];\n}\n\nexport interface DesignCanvasProps {\n doc: DesignDoc;\n page: DesignPage;\n selectedId: string | null;\n /** A layer being typed into: drawn, but not selectable by touch. */\n editingId?: string | null;\n onSelect: (layerId: string | null) => void;\n onPatch: (layerId: string, patch: Partial<EditorLayer>, coalesce: string) => void;\n onEditText: (layerId: string) => void;\n}\n\nexport function DesignCanvas({ doc, page, selectedId, editingId, onSelect, onPatch, onEditText }: DesignCanvasProps) {\n const theme = useCanvasTheme();\n const [area, setArea] = useState({ w: 0, h: 0 });\n const [guides, setGuides] = useState<{ x: number | null; y: number | null }>({ x: null, y: null });\n\n const aspect = doc.pageWidth / Math.max(1, doc.pageHeight);\n const W = Math.max(1, Math.min(area.w - MARGIN * 2, (area.h - MARGIN * 2) * aspect));\n const H = W / aspect;\n const ox = (area.w - W) / 2;\n const oy = (area.h - H) / 2;\n\n const layers = page.layers ?? [];\n const selected = layers.find((l) => l.id === selectedId) ?? null;\n\n // The responder is created once; it reads the live frame through this ref.\n const live = useRef({ W, H, ox, oy, layers, selected, onSelect, onPatch, onEditText, gestureId: 0 });\n live.current = { ...live.current, W, H, ox, oy, layers, selected, onSelect, onPatch, onEditText };\n const mode = useRef<Mode>({ kind: 'none' });\n\n const responder = useMemo(\n () =>\n PanResponder.create({\n onStartShouldSetPanResponder: () => true,\n onMoveShouldSetPanResponder: () => true,\n onPanResponderTerminationRequest: () => false,\n onPanResponderGrant: (e) => {\n const s = live.current;\n s.gestureId += 1;\n const px = e.nativeEvent.locationX - s.ox;\n const py = e.nativeEvent.locationY - s.oy;\n const sel = s.selected;\n if (sel && !sel.locked) {\n const box = layerBox(sel, s.W, s.H);\n const deg = sel.rotation ?? 0;\n const [kx, ky] = rotateKnobPoint(box, deg, KNOB_GAP);\n if (Math.hypot(px - kx, py - ky) <= HANDLE_HIT) {\n mode.current = { kind: 'rotate', layer: sel, box, from: [px, py], moved: false };\n return;\n }\n for (const handle of handlesFor(sel)) {\n const [hx, hy] = handlePoint(box, deg, handle);\n if (Math.hypot(px - hx, py - hy) <= HANDLE_HIT) {\n mode.current = { kind: 'resize', layer: sel, box, handle, moved: false };\n return;\n }\n }\n }\n const hit = hitTest(s.layers, px, py, s.W, s.H);\n if (!hit) {\n mode.current = { kind: 'page', moved: false };\n return;\n }\n const wasSelected = hit.id === sel?.id;\n if (!wasSelected) s.onSelect(hit.id);\n mode.current = {\n kind: 'move',\n layer: hit,\n box: layerBox(hit, s.W, s.H),\n wasSelected,\n moved: false,\n };\n },\n onPanResponderMove: (e, g) => {\n const s = live.current;\n const m = mode.current;\n if (m.kind === 'none') return;\n if (!m.moved && Math.hypot(g.dx, g.dy) < TAP_SLOP) return;\n m.moved = true;\n if (m.kind === 'page') return;\n const key = `${m.kind}:${m.layer.id}:${s.gestureId}`;\n if (m.kind === 'move') {\n if (m.layer.locked) return;\n // Web snaps to the page and to every other layer's edges and centre.\n const others = s.layers.filter((l) => l.id !== m.layer.id).map((l) => layerBox(l, s.W, s.H));\n const snapped = snapMove(\n { ...m.box, x: m.box.x + g.dx, y: m.box.y + g.dy },\n snapLines(others, s.W, s.H),\n );\n setGuides((prev) =>\n prev.x === snapped.guideX && prev.y === snapped.guideY\n ? prev\n : { x: snapped.guideX, y: snapped.guideY },\n );\n s.onPatch(m.layer.id, { x: snapped.box.x / s.W, y: snapped.box.y / s.H }, key);\n return;\n }\n if (m.kind === 'resize') {\n const corner = m.handle.length === 2;\n const keepAspect = corner && (m.layer.kind === 'image' || m.layer.kind === 'text');\n const next = resizeBox(m.box, m.layer.rotation ?? 0, m.handle, g.dx, g.dy, {\n keepAspect,\n minSize: 12,\n });\n const patch: Partial<EditorLayer> = {\n x: next.x / s.W,\n y: next.y / s.H,\n w: next.w / s.W,\n h: next.h / s.H,\n };\n // A text corner scales its words with the box, as Canva's does.\n if (m.layer.kind === 'text' && corner) {\n const scale = next.w / m.box.w;\n (patch as Partial<TextLayer>).fontSizeFrac = (m.layer as TextLayer).fontSizeFrac * scale;\n }\n s.onPatch(m.layer.id, patch, key);\n return;\n }\n const px = e.nativeEvent.locationX - s.ox;\n const py = e.nativeEvent.locationY - s.oy;\n s.onPatch(\n m.layer.id,\n { rotation: rotateFromDrag(m.box, m.layer.rotation ?? 0, m.from, [px, py]) },\n key,\n );\n },\n onPanResponderRelease: () => {\n const s = live.current;\n const m = mode.current;\n mode.current = { kind: 'none' };\n setGuides({ x: null, y: null });\n if (m.kind === 'page' && !m.moved) s.onSelect(null);\n if (m.kind === 'move' && !m.moved && m.wasSelected && m.layer.kind === 'text' && !m.layer.locked) {\n s.onEditText(m.layer.id);\n }\n },\n onPanResponderTerminate: () => {\n mode.current = { kind: 'none' };\n setGuides({ x: null, y: null });\n },\n }),\n [],\n );\n\n const onLayout = (e: LayoutChangeEvent) => {\n const { width, height } = e.nativeEvent.layout;\n setArea((prev) => (prev.w === width && prev.h === height ? prev : { w: width, h: height }));\n };\n\n const accent = theme.edAccent;\n return (\n <View style={styles.fill} onLayout={onLayout}>\n {area.w > 0 ? (\n <>\n <View style={[styles.pageShadow, { left: ox, top: oy, width: W, height: H }]}>\n <DesignPageView doc={doc} page={page} width={W} />\n </View>\n {guides.x !== null ? (\n <View\n pointerEvents=\"none\"\n style={[\n styles.guideV,\n { left: ox + guides.x, top: oy, height: H, backgroundColor: '#ec4899' },\n ]}\n />\n ) : null}\n {guides.y !== null ? (\n <View\n pointerEvents=\"none\"\n style={[\n styles.guideH,\n { top: oy + guides.y, left: ox, width: W, backgroundColor: '#ec4899' },\n ]}\n />\n ) : null}\n {selected && selected.id !== editingId ? (\n <SelectionFrame layer={selected} W={W} H={H} ox={ox} oy={oy} accent={accent} />\n ) : null}\n <View style={StyleSheet.absoluteFill} {...responder.panHandlers} />\n </>\n ) : null}\n </View>\n );\n}\n\n/** The selected layer's outline, handles and rotate knob, turned with it. Draw-only. */\nfunction SelectionFrame({\n layer,\n W,\n H,\n ox,\n oy,\n accent,\n}: {\n layer: EditorLayer;\n W: number;\n H: number;\n ox: number;\n oy: number;\n accent: string;\n}) {\n const box = layerBox(layer, W, H);\n const deg = layer.rotation ?? 0;\n const locked = Boolean(layer.locked);\n return (\n <View\n pointerEvents=\"none\"\n style={{\n position: 'absolute',\n left: ox + box.x,\n top: oy + box.y,\n width: box.w,\n height: box.h,\n transform: deg ? [{ rotate: `${deg}deg` }] : undefined,\n }}\n >\n <View\n style={[StyleSheet.absoluteFill, styles.frame, { borderColor: accent }, locked && styles.frameLocked]}\n />\n {locked ? (\n <View style={[styles.lockBadge, { backgroundColor: accent }]}>\n <MaterialCommunityIcons name=\"lock\" size={12} color=\"#fff\" />\n </View>\n ) : (\n <>\n {handlesFor(layer).map((handle) => {\n const corner = handle.length === 2;\n const left = handle.includes('w') ? 0 : handle.includes('e') ? box.w : box.w / 2;\n const top = handle.includes('n') ? 0 : handle.includes('s') ? box.h : box.h / 2;\n const vertical = handle === 'e' || handle === 'w';\n const size = corner ? { w: 14, h: 14 } : vertical ? { w: 8, h: 22 } : { w: 22, h: 8 };\n return (\n <View\n key={handle}\n style={[\n styles.handle,\n {\n left: left - size.w / 2,\n top: top - size.h / 2,\n width: size.w,\n height: size.h,\n borderRadius: corner ? 7 : 4,\n borderColor: accent,\n },\n ]}\n />\n );\n })}\n <View\n style={[styles.knob, { left: box.w / 2 - 14, top: box.h + KNOB_GAP - 14, borderColor: accent }]}\n >\n <MaterialCommunityIcons name=\"rotate-right\" size={16} color={accent} />\n </View>\n </>\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1 },\n pageShadow: {\n position: 'absolute',\n backgroundColor: '#ffffff',\n shadowColor: '#000',\n shadowOpacity: 0.16,\n shadowRadius: 12,\n shadowOffset: { width: 0, height: 4 },\n elevation: 4,\n },\n frame: { borderWidth: 1.5 },\n frameLocked: { borderStyle: 'dashed' },\n handle: { position: 'absolute', backgroundColor: '#ffffff', borderWidth: 1.5 },\n knob: {\n position: 'absolute',\n width: 28,\n height: 28,\n borderRadius: 14,\n backgroundColor: '#ffffff',\n borderWidth: 1.5,\n alignItems: 'center',\n justifyContent: 'center',\n },\n lockBadge: {\n position: 'absolute',\n right: -10,\n top: -10,\n width: 20,\n height: 20,\n borderRadius: 10,\n alignItems: 'center',\n justifyContent: 'center',\n },\n guideV: { position: 'absolute', width: 1 },\n guideH: { position: 'absolute', height: 1 },\n});\n"],"names":["_a","_b"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {useState,useMemo}from'react';import {View,Text,TextInput,StyleSheet}from'react-native';import {useCanvasTheme,themedStyles}from'../../canvas/canvasTheme.js';import {SPACE,TYPE,RADIUS}from'../../canvas/canvasUi.js';import {parsePageRange}from'../doc/pageRange.js';import {exportPixelWidth}from'../export/exportDesign.js';import {Segmented,PrimaryButton}from'./controls.js';var __defProp = Object.defineProperty;
1
+ import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {useState,useMemo}from'react';import {View,Text,TextInput,StyleSheet}from'react-native';import {useCanvasTheme,themedStyles}from'../../canvas/canvasTheme.js';import {SPACE,TYPE,RADIUS}from'../../canvas/canvasUi.js';import {parsePageRange}from'../doc/pageRange.js';import {exportPixelWidth}from'../export/exportDesign.js';import {Segmented,ToggleRow,PrimaryButton}from'./controls.js';var __defProp = Object.defineProperty;
2
2
  var __defProps = Object.defineProperties;
3
3
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -28,6 +28,7 @@ function ExportSheet({
28
28
  const count = doc.pages.length;
29
29
  const [format, setFormat] = useState(count > 1 ? "pdf" : "png");
30
30
  const [scale, setScale] = useState(2);
31
+ const [transparent, setTransparent] = useState(false);
31
32
  const [which, setWhich] = useState(count > 1 ? "all" : "current");
32
33
  const [range, setRange] = useState("");
33
34
  const indices = useMemo(() => {
@@ -68,7 +69,8 @@ function ExportSheet({
68
69
  " x ",
69
70
  py,
70
71
  " px"
71
- ] })
72
+ ] }),
73
+ format === "png" ? /* @__PURE__ */ jsx(ToggleRow, { label: "Transparent background", value: transparent, onChange: setTransparent }) : null
72
74
  ] }) : null,
73
75
  count > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
74
76
  /* @__PURE__ */ jsx(Text, { style: styles.heading, children: "Pages" }),
@@ -93,11 +95,13 @@ function ExportSheet({
93
95
  ", like 1-3, 5."
94
96
  ] }) : null
95
97
  ] }) : null,
96
- /* @__PURE__ */ jsx(PrimaryButton, { label: busy != null ? busy : format === "pdf" ? "Download PDF" : `Download ${(indices == null ? void 0 : indices.length) && indices.length > 1 ? `${indices.length} pages` : format.toUpperCase()}`, busy: Boolean(busy), disabled: bad, onPress: () => indices && onExport({
98
+ /* @__PURE__ */ jsx(PrimaryButton, { label: busy != null ? busy : format === "pdf" ? "Download PDF" : `Download ${(indices == null ? void 0 : indices.length) && indices.length > 1 ? `${indices.length} pages` : format.toUpperCase()}`, busy: Boolean(busy), disabled: bad, onPress: () => indices && onExport(__spreadValues({
97
99
  format,
98
100
  scale,
99
101
  pageIndices: indices
100
- }) })
102
+ }, format === "png" && transparent ? {
103
+ transparent
104
+ } : {})) })
101
105
  ] });
102
106
  }
103
107
  const makeStyles = themedStyles((theme) => StyleSheet.create({