@bendyline/squisq 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Doc-Ch4tc3vv.d.ts → Doc-BeSeH2iX.d.ts} +118 -41
- package/dist/ImageEditDoc-BTIvw0oq.d.ts +84 -0
- package/dist/__tests__/colorUtils.test.d.ts +2 -0
- package/dist/__tests__/colorUtils.test.d.ts.map +1 -0
- package/dist/__tests__/colorUtils.test.js +94 -0
- package/dist/__tests__/colorUtils.test.js.map +1 -0
- package/dist/__tests__/getLayers.test.js +31 -7
- package/dist/__tests__/getLayers.test.js.map +1 -1
- package/dist/__tests__/iconResolve.test.d.ts +2 -0
- package/dist/__tests__/iconResolve.test.d.ts.map +1 -0
- package/dist/__tests__/iconResolve.test.js +99 -0
- package/dist/__tests__/iconResolve.test.js.map +1 -0
- package/dist/__tests__/imageEditState.test.d.ts +2 -0
- package/dist/__tests__/imageEditState.test.d.ts.map +1 -0
- package/dist/__tests__/imageEditState.test.js +61 -0
- package/dist/__tests__/imageEditState.test.js.map +1 -0
- package/dist/__tests__/imageEditVersions.test.d.ts +2 -0
- package/dist/__tests__/imageEditVersions.test.d.ts.map +1 -0
- package/dist/__tests__/imageEditVersions.test.js +141 -0
- package/dist/__tests__/imageEditVersions.test.js.map +1 -0
- package/dist/__tests__/inferDocumentTitle.test.d.ts +2 -0
- package/dist/__tests__/inferDocumentTitle.test.d.ts.map +1 -0
- package/dist/__tests__/inferDocumentTitle.test.js +42 -0
- package/dist/__tests__/inferDocumentTitle.test.js.map +1 -0
- package/dist/__tests__/jsonForm.chooseControl.test.d.ts +2 -0
- package/dist/__tests__/jsonForm.chooseControl.test.d.ts.map +1 -0
- package/dist/__tests__/jsonForm.chooseControl.test.js +74 -0
- package/dist/__tests__/jsonForm.chooseControl.test.js.map +1 -0
- package/dist/__tests__/jsonForm.evaluateWhen.test.d.ts +2 -0
- package/dist/__tests__/jsonForm.evaluateWhen.test.d.ts.map +1 -0
- package/dist/__tests__/jsonForm.evaluateWhen.test.js +51 -0
- package/dist/__tests__/jsonForm.evaluateWhen.test.js.map +1 -0
- package/dist/__tests__/jsonForm.inferSchema.test.d.ts +2 -0
- package/dist/__tests__/jsonForm.inferSchema.test.d.ts.map +1 -0
- package/dist/__tests__/jsonForm.inferSchema.test.js +23 -0
- package/dist/__tests__/jsonForm.inferSchema.test.js.map +1 -0
- package/dist/__tests__/jsonForm.pointer.test.d.ts +2 -0
- package/dist/__tests__/jsonForm.pointer.test.d.ts.map +1 -0
- package/dist/__tests__/jsonForm.pointer.test.js +94 -0
- package/dist/__tests__/jsonForm.pointer.test.js.map +1 -0
- package/dist/__tests__/markdownIcons.test.d.ts +2 -0
- package/dist/__tests__/markdownIcons.test.d.ts.map +1 -0
- package/dist/__tests__/markdownIcons.test.js +93 -0
- package/dist/__tests__/markdownIcons.test.js.map +1 -0
- package/dist/__tests__/markdownToDoc.test.js +15 -4
- package/dist/__tests__/markdownToDoc.test.js.map +1 -1
- package/dist/__tests__/recommendTemplates.test.d.ts +2 -0
- package/dist/__tests__/recommendTemplates.test.d.ts.map +1 -0
- package/dist/__tests__/recommendTemplates.test.js +158 -0
- package/dist/__tests__/recommendTemplates.test.js.map +1 -0
- package/dist/__tests__/scopedContentContainer.test.d.ts +2 -0
- package/dist/__tests__/scopedContentContainer.test.d.ts.map +1 -0
- package/dist/__tests__/scopedContentContainer.test.js +74 -0
- package/dist/__tests__/scopedContentContainer.test.js.map +1 -0
- package/dist/__tests__/slideshowGenerator.test.js +1 -1
- package/dist/__tests__/slideshowGenerator.test.js.map +1 -1
- package/dist/__tests__/templateAnnotationParse.test.d.ts +2 -0
- package/dist/__tests__/templateAnnotationParse.test.d.ts.map +1 -0
- package/dist/__tests__/templateAnnotationParse.test.js +42 -0
- package/dist/__tests__/templateAnnotationParse.test.js.map +1 -0
- package/dist/__tests__/templates.test.js +90 -9
- package/dist/__tests__/templates.test.js.map +1 -1
- package/dist/__tests__/themeCompile.test.d.ts +2 -0
- package/dist/__tests__/themeCompile.test.d.ts.map +1 -0
- package/dist/__tests__/themeCompile.test.js +134 -0
- package/dist/__tests__/themeCompile.test.js.map +1 -0
- package/dist/__tests__/themeValidator.test.d.ts +2 -0
- package/dist/__tests__/themeValidator.test.d.ts.map +1 -0
- package/dist/__tests__/themeValidator.test.js +107 -0
- package/dist/__tests__/themeValidator.test.js.map +1 -0
- package/dist/__tests__/versions.test.d.ts +2 -0
- package/dist/__tests__/versions.test.d.ts.map +1 -0
- package/dist/__tests__/versions.test.js +339 -0
- package/dist/__tests__/versions.test.js.map +1 -0
- package/dist/{chunk-CYQHG27J.js → chunk-2TMAWB4Y.js} +74 -1
- package/dist/chunk-2TMAWB4Y.js.map +1 -0
- package/dist/{chunk-OASJKWO5.js → chunk-3K5OG6KI.js} +92 -7
- package/dist/chunk-3K5OG6KI.js.map +1 -0
- package/dist/chunk-57CVQCFX.js +193 -0
- package/dist/chunk-57CVQCFX.js.map +1 -0
- package/dist/{chunk-QM5PKNPW.js → chunk-5WFRKURX.js} +1 -1
- package/dist/chunk-5WFRKURX.js.map +1 -0
- package/dist/chunk-B4EEON3N.js +1317 -0
- package/dist/chunk-B4EEON3N.js.map +1 -0
- package/dist/chunk-DBS6RIFL.js +81 -0
- package/dist/chunk-DBS6RIFL.js.map +1 -0
- package/dist/{chunk-MIBRIRGJ.js → chunk-FR2RBTKO.js} +3 -3
- package/dist/{chunk-MIBRIRGJ.js.map → chunk-FR2RBTKO.js.map} +1 -1
- package/dist/chunk-H3AXU4MJ.js +179 -0
- package/dist/chunk-H3AXU4MJ.js.map +1 -0
- package/dist/chunk-JELIRVDP.js +24 -0
- package/dist/chunk-JELIRVDP.js.map +1 -0
- package/dist/chunk-K32VJONL.js +193 -0
- package/dist/chunk-K32VJONL.js.map +1 -0
- package/dist/{chunk-6BAVXFYC.js → chunk-KSWJR66U.js} +218 -42
- package/dist/chunk-KSWJR66U.js.map +1 -0
- package/dist/{chunk-TSG2OSE6.js → chunk-MYIH7FWD.js} +3 -3
- package/dist/chunk-MYIH7FWD.js.map +1 -0
- package/dist/chunk-VLJJHDAC.js +218 -0
- package/dist/chunk-VLJJHDAC.js.map +1 -0
- package/dist/chunk-WMOI7FN3.js +182 -0
- package/dist/chunk-WMOI7FN3.js.map +1 -0
- package/dist/chunk-ZTX4PFFT.js +520 -0
- package/dist/chunk-ZTX4PFFT.js.map +1 -0
- package/dist/doc/audioMapping.d.ts.map +1 -1
- package/dist/doc/audioMapping.js +42 -7
- package/dist/doc/audioMapping.js.map +1 -1
- package/dist/doc/getLayers.d.ts.map +1 -1
- package/dist/doc/getLayers.js +29 -18
- package/dist/doc/getLayers.js.map +1 -1
- package/dist/doc/markdownToDoc.d.ts.map +1 -1
- package/dist/doc/markdownToDoc.js +40 -6
- package/dist/doc/markdownToDoc.js.map +1 -1
- package/dist/doc/templates/featureBlock.d.ts +18 -0
- package/dist/doc/templates/featureBlock.d.ts.map +1 -0
- package/dist/doc/templates/featureBlock.js +180 -0
- package/dist/doc/templates/featureBlock.js.map +1 -0
- package/dist/doc/templates/fullBleedQuote.d.ts +12 -0
- package/dist/doc/templates/fullBleedQuote.d.ts.map +1 -1
- package/dist/doc/templates/fullBleedQuote.js +12 -0
- package/dist/doc/templates/fullBleedQuote.js.map +1 -1
- package/dist/doc/templates/index.d.ts +28 -4
- package/dist/doc/templates/index.d.ts.map +1 -1
- package/dist/doc/templates/index.js +45 -12
- package/dist/doc/templates/index.js.map +1 -1
- package/dist/doc/templates/listBlock.d.ts.map +1 -1
- package/dist/doc/templates/listBlock.js +22 -5
- package/dist/doc/templates/listBlock.js.map +1 -1
- package/dist/doc/templates/statHighlight.d.ts +12 -0
- package/dist/doc/templates/statHighlight.d.ts.map +1 -1
- package/dist/doc/templates/statHighlight.js +12 -0
- package/dist/doc/templates/statHighlight.js.map +1 -1
- package/dist/doc/templates/titleBlock.d.ts +11 -0
- package/dist/doc/templates/titleBlock.d.ts.map +1 -1
- package/dist/doc/templates/titleBlock.js +8 -0
- package/dist/doc/templates/titleBlock.js.map +1 -1
- package/dist/doc/utils/themeUtils.d.ts +4 -4
- package/dist/doc/utils/themeUtils.d.ts.map +1 -1
- package/dist/doc/utils/themeUtils.js +8 -7
- package/dist/doc/utils/themeUtils.js.map +1 -1
- package/dist/generate/slideshowGenerator.js +1 -1
- package/dist/generate/slideshowGenerator.js.map +1 -1
- package/dist/generate/templateMapper.js +2 -2
- package/dist/generate/templateMapper.js.map +1 -1
- package/dist/icons/iconData.d.ts +26 -0
- package/dist/icons/iconData.d.ts.map +1 -0
- package/dist/icons/iconData.js +12 -0
- package/dist/icons/iconData.js.map +1 -0
- package/dist/icons/index.d.ts +12 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/index.js +10 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/resolve.d.ts +61 -0
- package/dist/icons/resolve.d.ts.map +1 -0
- package/dist/icons/resolve.js +130 -0
- package/dist/icons/resolve.js.map +1 -0
- package/dist/imageEdit/ImageEditVersionManager.d.ts +31 -0
- package/dist/imageEdit/ImageEditVersionManager.d.ts.map +1 -0
- package/dist/imageEdit/ImageEditVersionManager.js +39 -0
- package/dist/imageEdit/ImageEditVersionManager.js.map +1 -0
- package/dist/imageEdit/export.d.ts +33 -0
- package/dist/imageEdit/export.d.ts.map +1 -0
- package/dist/imageEdit/export.js +253 -0
- package/dist/imageEdit/export.js.map +1 -0
- package/dist/imageEdit/index.d.ts +14 -0
- package/dist/imageEdit/index.d.ts.map +1 -0
- package/dist/imageEdit/index.js +22 -0
- package/dist/imageEdit/index.js.map +1 -0
- package/dist/imageEdit/persistence.d.ts +15 -0
- package/dist/imageEdit/persistence.d.ts.map +1 -0
- package/dist/imageEdit/persistence.js +49 -0
- package/dist/imageEdit/persistence.js.map +1 -0
- package/dist/imageEdit/state.d.ts +42 -0
- package/dist/imageEdit/state.d.ts.map +1 -0
- package/dist/imageEdit/state.js +98 -0
- package/dist/imageEdit/state.js.map +1 -0
- package/dist/imageEdit/versionPaths.d.ts +27 -0
- package/dist/imageEdit/versionPaths.d.ts.map +1 -0
- package/dist/imageEdit/versionPaths.js +57 -0
- package/dist/imageEdit/versionPaths.js.map +1 -0
- package/dist/imageEdit/versions.d.ts +67 -0
- package/dist/imageEdit/versions.d.ts.map +1 -0
- package/dist/imageEdit/versions.js +161 -0
- package/dist/imageEdit/versions.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/jsonForm/chooseControl.d.ts +20 -0
- package/dist/jsonForm/chooseControl.d.ts.map +1 -0
- package/dist/jsonForm/chooseControl.js +82 -0
- package/dist/jsonForm/chooseControl.js.map +1 -0
- package/dist/jsonForm/evaluateWhen.d.ts +12 -0
- package/dist/jsonForm/evaluateWhen.d.ts.map +1 -0
- package/dist/jsonForm/evaluateWhen.js +65 -0
- package/dist/jsonForm/evaluateWhen.js.map +1 -0
- package/dist/jsonForm/index.d.ts +14 -0
- package/dist/jsonForm/index.d.ts.map +1 -0
- package/dist/jsonForm/index.js +12 -0
- package/dist/jsonForm/index.js.map +1 -0
- package/dist/jsonForm/inferSchema.d.ts +12 -0
- package/dist/jsonForm/inferSchema.d.ts.map +1 -0
- package/dist/jsonForm/inferSchema.js +15 -0
- package/dist/jsonForm/inferSchema.js.map +1 -0
- package/dist/jsonForm/pointer.d.ts +26 -0
- package/dist/jsonForm/pointer.d.ts.map +1 -0
- package/dist/jsonForm/pointer.js +102 -0
- package/dist/jsonForm/pointer.js.map +1 -0
- package/dist/jsonForm/types.d.ts +120 -0
- package/dist/jsonForm/types.d.ts.map +1 -0
- package/dist/jsonForm/types.js +10 -0
- package/dist/jsonForm/types.js.map +1 -0
- package/dist/markdown/convert.d.ts +11 -1
- package/dist/markdown/convert.d.ts.map +1 -1
- package/dist/markdown/convert.js +135 -5
- package/dist/markdown/convert.js.map +1 -1
- package/dist/markdown/index.d.ts +1 -1
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +1 -1
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/types.d.ts +17 -2
- package/dist/markdown/types.d.ts.map +1 -1
- package/dist/markdown/utils.d.ts +40 -0
- package/dist/markdown/utils.d.ts.map +1 -1
- package/dist/markdown/utils.js +155 -0
- package/dist/markdown/utils.js.map +1 -1
- package/dist/recommend/index.d.ts +16 -0
- package/dist/recommend/index.d.ts.map +1 -0
- package/dist/recommend/index.js +15 -0
- package/dist/recommend/index.js.map +1 -0
- package/dist/recommend/templates.d.ts +39 -0
- package/dist/recommend/templates.d.ts.map +1 -0
- package/dist/recommend/templates.js +235 -0
- package/dist/recommend/templates.js.map +1 -0
- package/dist/schemas/BlockTemplates.d.ts +46 -8
- package/dist/schemas/BlockTemplates.d.ts.map +1 -1
- package/dist/schemas/BlockTemplates.js +3 -3
- package/dist/schemas/BlockTemplates.js.map +1 -1
- package/dist/schemas/ImageEditDoc.d.ts +81 -0
- package/dist/schemas/ImageEditDoc.d.ts.map +1 -0
- package/dist/schemas/ImageEditDoc.js +20 -0
- package/dist/schemas/ImageEditDoc.js.map +1 -0
- package/dist/schemas/Theme.d.ts +70 -31
- package/dist/schemas/Theme.d.ts.map +1 -1
- package/dist/schemas/Theme.js +48 -16
- package/dist/schemas/Theme.js.map +1 -1
- package/dist/schemas/colorUtils.d.ts +51 -0
- package/dist/schemas/colorUtils.d.ts.map +1 -0
- package/dist/schemas/colorUtils.js +154 -0
- package/dist/schemas/colorUtils.js.map +1 -0
- package/dist/schemas/fontStacks.d.ts +57 -0
- package/dist/schemas/fontStacks.d.ts.map +1 -0
- package/dist/schemas/fontStacks.js +227 -0
- package/dist/schemas/fontStacks.js.map +1 -0
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +4 -0
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/themeCompile.d.ts +45 -0
- package/dist/schemas/themeCompile.d.ts.map +1 -0
- package/dist/schemas/themeCompile.js +160 -0
- package/dist/schemas/themeCompile.js.map +1 -0
- package/dist/schemas/themeLibrary.d.ts +11 -15
- package/dist/schemas/themeLibrary.d.ts.map +1 -1
- package/dist/schemas/themeLibrary.js +18 -566
- package/dist/schemas/themeLibrary.js.map +1 -1
- package/dist/schemas/themeValidator.d.ts +26 -0
- package/dist/schemas/themeValidator.d.ts.map +1 -0
- package/dist/schemas/themeValidator.js +352 -0
- package/dist/schemas/themeValidator.js.map +1 -0
- package/dist/schemas/themes/bold.json +48 -0
- package/dist/schemas/themes/cinematic.json +54 -0
- package/dist/schemas/themes/documentary.json +49 -0
- package/dist/schemas/themes/gezellig.json +44 -0
- package/dist/schemas/themes/index.d.ts +26 -0
- package/dist/schemas/themes/index.d.ts.map +1 -0
- package/dist/schemas/themes/index.js +49 -0
- package/dist/schemas/themes/index.js.map +1 -0
- package/dist/schemas/themes/magazine.json +44 -0
- package/dist/schemas/themes/minimalist.json +45 -0
- package/dist/schemas/themes/morning-light.json +42 -0
- package/dist/schemas/themes/standard-dark.json +50 -0
- package/dist/schemas/themes/standard.json +42 -0
- package/dist/schemas/themes/tech-dark.json +48 -0
- package/dist/schemas/themes/warm-earth.json +50 -0
- package/dist/storage/ScopedContentContainer.d.ts +44 -0
- package/dist/storage/ScopedContentContainer.d.ts.map +1 -0
- package/dist/storage/ScopedContentContainer.js +94 -0
- package/dist/storage/ScopedContentContainer.js.map +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +1 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/story/index.d.ts +53 -13
- package/dist/story/index.js +12 -4
- package/dist/themeLibrary-BHjJ0Qx6.d.ts +40 -0
- package/dist/{types-CkNttVSF.d.ts → types-BdZkdJ3z.d.ts} +17 -2
- package/dist/types-D98li1gV.d.ts +93 -0
- package/dist/versions/DocumentVersionManager.d.ts +31 -0
- package/dist/versions/DocumentVersionManager.d.ts.map +1 -0
- package/dist/versions/DocumentVersionManager.js +33 -0
- package/dist/versions/DocumentVersionManager.js.map +1 -0
- package/dist/versions/index.d.ts +29 -0
- package/dist/versions/index.d.ts.map +1 -0
- package/dist/versions/index.js +28 -0
- package/dist/versions/index.js.map +1 -0
- package/dist/versions/operations.d.ts +44 -0
- package/dist/versions/operations.d.ts.map +1 -0
- package/dist/versions/operations.js +190 -0
- package/dist/versions/operations.js.map +1 -0
- package/dist/versions/paths.d.ts +29 -0
- package/dist/versions/paths.d.ts.map +1 -0
- package/dist/versions/paths.js +66 -0
- package/dist/versions/paths.js.map +1 -0
- package/dist/versions/timestamp.d.ts +22 -0
- package/dist/versions/timestamp.d.ts.map +1 -0
- package/dist/versions/timestamp.js +44 -0
- package/dist/versions/timestamp.js.map +1 -0
- package/dist/versions/types.d.ts +92 -0
- package/dist/versions/types.d.ts.map +1 -0
- package/dist/versions/types.js +11 -0
- package/dist/versions/types.js.map +1 -0
- package/package.json +28 -1
- package/src/__tests__/colorUtils.test.ts +112 -0
- package/src/__tests__/getLayers.test.ts +32 -7
- package/src/__tests__/iconResolve.test.ts +122 -0
- package/src/__tests__/imageEditState.test.ts +74 -0
- package/src/__tests__/imageEditVersions.test.ts +169 -0
- package/src/__tests__/inferDocumentTitle.test.ts +50 -0
- package/src/__tests__/jsonForm.chooseControl.test.ts +86 -0
- package/src/__tests__/jsonForm.evaluateWhen.test.ts +59 -0
- package/src/__tests__/jsonForm.inferSchema.test.ts +25 -0
- package/src/__tests__/jsonForm.pointer.test.ts +103 -0
- package/src/__tests__/markdownIcons.test.ts +104 -0
- package/src/__tests__/markdownToDoc.test.ts +19 -4
- package/src/__tests__/recommendTemplates.test.ts +183 -0
- package/src/__tests__/scopedContentContainer.test.ts +89 -0
- package/src/__tests__/slideshowGenerator.test.ts +1 -1
- package/src/__tests__/templateAnnotationParse.test.ts +42 -0
- package/src/__tests__/templates.test.ts +93 -9
- package/src/__tests__/themeCompile.test.ts +156 -0
- package/src/__tests__/themeValidator.test.ts +125 -0
- package/src/__tests__/versions.test.ts +415 -0
- package/src/doc/audioMapping.ts +55 -11
- package/src/doc/getLayers.ts +32 -21
- package/src/doc/markdownToDoc.ts +45 -7
- package/src/doc/templates/featureBlock.ts +202 -0
- package/src/doc/templates/fullBleedQuote.ts +13 -0
- package/src/doc/templates/index.ts +50 -16
- package/src/doc/templates/listBlock.ts +24 -5
- package/src/doc/templates/statHighlight.ts +13 -0
- package/src/doc/templates/titleBlock.ts +9 -0
- package/src/doc/utils/themeUtils.ts +8 -7
- package/src/generate/slideshowGenerator.ts +1 -1
- package/src/generate/templateMapper.ts +2 -2
- package/src/icons/iconData.ts +31 -0
- package/src/icons/index.ts +18 -0
- package/src/icons/resolve.ts +139 -0
- package/src/imageEdit/ImageEditVersionManager.ts +73 -0
- package/src/imageEdit/export.ts +326 -0
- package/src/imageEdit/index.ts +71 -0
- package/src/imageEdit/persistence.ts +62 -0
- package/src/imageEdit/state.ts +112 -0
- package/src/imageEdit/versionPaths.ts +57 -0
- package/src/imageEdit/versions.ts +231 -0
- package/src/index.ts +4 -0
- package/src/jsonForm/chooseControl.ts +88 -0
- package/src/jsonForm/evaluateWhen.ts +59 -0
- package/src/jsonForm/index.ts +22 -0
- package/src/jsonForm/inferSchema.ts +25 -0
- package/src/jsonForm/pointer.ts +109 -0
- package/src/jsonForm/types.ts +167 -0
- package/src/markdown/convert.ts +145 -5
- package/src/markdown/index.ts +3 -0
- package/src/markdown/types.ts +19 -2
- package/src/markdown/utils.ts +159 -0
- package/src/recommend/index.ts +16 -0
- package/src/recommend/templates.ts +273 -0
- package/src/schemas/BlockTemplates.ts +50 -7
- package/src/schemas/ImageEditDoc.ts +95 -0
- package/src/schemas/Theme.ts +98 -31
- package/src/schemas/colorUtils.ts +186 -0
- package/src/schemas/fontStacks.ts +257 -0
- package/src/schemas/index.ts +12 -0
- package/src/schemas/themeCompile.ts +203 -0
- package/src/schemas/themeLibrary.ts +18 -597
- package/src/schemas/themeValidator.ts +388 -0
- package/src/schemas/themes/bold.json +48 -0
- package/src/schemas/themes/cinematic.json +54 -0
- package/src/schemas/themes/documentary.json +49 -0
- package/src/schemas/themes/gezellig.json +44 -0
- package/src/schemas/themes/index.ts +53 -0
- package/src/schemas/themes/magazine.json +44 -0
- package/src/schemas/themes/minimalist.json +45 -0
- package/src/schemas/themes/morning-light.json +42 -0
- package/src/schemas/themes/standard-dark.json +50 -0
- package/src/schemas/themes/standard.json +42 -0
- package/src/schemas/themes/tech-dark.json +48 -0
- package/src/schemas/themes/warm-earth.json +50 -0
- package/src/storage/ScopedContentContainer.ts +113 -0
- package/src/storage/index.ts +1 -0
- package/src/versions/DocumentVersionManager.ts +70 -0
- package/src/versions/index.ts +54 -0
- package/src/versions/operations.ts +230 -0
- package/src/versions/paths.ts +66 -0
- package/src/versions/timestamp.ts +48 -0
- package/src/versions/types.ts +91 -0
- package/dist/chunk-6BAVXFYC.js.map +0 -1
- package/dist/chunk-7GF6RDED.js +0 -82
- package/dist/chunk-7GF6RDED.js.map +0 -1
- package/dist/chunk-CYQHG27J.js.map +0 -1
- package/dist/chunk-F22AE6BY.js +0 -121
- package/dist/chunk-F22AE6BY.js.map +0 -1
- package/dist/chunk-FIQR4AJG.js +0 -517
- package/dist/chunk-FIQR4AJG.js.map +0 -1
- package/dist/chunk-OASJKWO5.js.map +0 -1
- package/dist/chunk-QM5PKNPW.js.map +0 -1
- package/dist/chunk-TSG2OSE6.js.map +0 -1
- package/dist/themeLibrary-CEo2D4b6.d.ts +0 -44
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature Block Templates — `leftFeature` and `rightFeature`
|
|
3
|
+
*
|
|
4
|
+
* Pairs a "feature" image on one side of the block with a title + body
|
|
5
|
+
* paragraph on the other. The two templates are mirror images, so the
|
|
6
|
+
* actual layer-builder lives here once and the per-side template files
|
|
7
|
+
* just call it with a `side` parameter.
|
|
8
|
+
*
|
|
9
|
+
* Used for editorial layouts like product highlights, profile cards,
|
|
10
|
+
* and section intros where a single image deserves to sit next to a
|
|
11
|
+
* short text block rather than behind it (which is what
|
|
12
|
+
* `imageWithCaption` does).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { Layer } from '../../schemas/Doc.js';
|
|
16
|
+
import type {
|
|
17
|
+
LeftFeatureInput,
|
|
18
|
+
RightFeatureInput,
|
|
19
|
+
TemplateContext,
|
|
20
|
+
} from '../../schemas/BlockTemplates.js';
|
|
21
|
+
import { scaledFontSize } from '../../schemas/BlockTemplates.js';
|
|
22
|
+
import { getThemeFont } from '../utils/themeUtils.js';
|
|
23
|
+
|
|
24
|
+
type FeatureInput = LeftFeatureInput | RightFeatureInput;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Build the layer list for either feature template. Layers are in
|
|
28
|
+
* back-to-front order: background, image, then text.
|
|
29
|
+
*/
|
|
30
|
+
function buildFeatureLayers(
|
|
31
|
+
input: FeatureInput,
|
|
32
|
+
context: TemplateContext,
|
|
33
|
+
side: 'left' | 'right',
|
|
34
|
+
): Layer[] {
|
|
35
|
+
const { imageSrc, imageAlt, imageWidth, imageHeight, title, body } = input;
|
|
36
|
+
const { theme, layout } = context;
|
|
37
|
+
// Treat the image as "sized" when the host gave us an explicit width
|
|
38
|
+
// or height — that's our cue that the user resized the image in the
|
|
39
|
+
// editor and we should respect that as a sizing hint instead of
|
|
40
|
+
// stretching the image to fill the whole half.
|
|
41
|
+
const sized = (imageWidth ?? 0) > 0 || (imageHeight ?? 0) > 0;
|
|
42
|
+
// In portrait the image stacks above the text rather than splitting
|
|
43
|
+
// horizontally — same flag the twoColumn template uses, so the two
|
|
44
|
+
// behave consistently on narrow viewports.
|
|
45
|
+
const stack = layout.stackColumns;
|
|
46
|
+
|
|
47
|
+
const titleFontSize = scaledFontSize(48, context, true);
|
|
48
|
+
const bodyFontSize = scaledFontSize(24, context, false);
|
|
49
|
+
|
|
50
|
+
// Image takes the full left or right half. The text column gets the
|
|
51
|
+
// opposite half, with a comfortable inset so the text doesn't kiss
|
|
52
|
+
// the image edge or the card border. All values are percentages of
|
|
53
|
+
// the block viewport so they scale with the card size.
|
|
54
|
+
//
|
|
55
|
+
// When the image is "sized" we shrink it inside its half: the half
|
|
56
|
+
// still claims the space (so the text column stays the same width
|
|
57
|
+
// and the layout doesn't shift around when dimensions are toggled)
|
|
58
|
+
// but the image itself sits centered with padding around it. The
|
|
59
|
+
// sized box uses a square envelope sized to the smaller dimension of
|
|
60
|
+
// its half so the image breathes regardless of viewport aspect.
|
|
61
|
+
let imgX: string;
|
|
62
|
+
let imgY: string;
|
|
63
|
+
let imgW: string;
|
|
64
|
+
let imgH: string;
|
|
65
|
+
let imageFit: 'cover' | 'contain';
|
|
66
|
+
if (stack) {
|
|
67
|
+
imgX = '0';
|
|
68
|
+
imgY = '0';
|
|
69
|
+
imgW = '100%';
|
|
70
|
+
imgH = '50%';
|
|
71
|
+
imageFit = sized ? 'contain' : 'cover';
|
|
72
|
+
} else if (sized) {
|
|
73
|
+
// 90% of the half (with explicit aspect via fit='contain') so the
|
|
74
|
+
// image keeps its natural proportions and never touches the card
|
|
75
|
+
// edges. We don't try to honor the literal pixel value — block
|
|
76
|
+
// viewports are designed in their own coordinate space — but the
|
|
77
|
+
// *intent* (smaller image, padded, centered) is what comes through.
|
|
78
|
+
const halfStart = side === 'left' ? 5 : 55; // %
|
|
79
|
+
imgX = `${halfStart}%`;
|
|
80
|
+
imgY = '5%';
|
|
81
|
+
imgW = '40%';
|
|
82
|
+
imgH = '90%';
|
|
83
|
+
imageFit = 'contain';
|
|
84
|
+
} else {
|
|
85
|
+
imgX = side === 'left' ? '0' : '50%';
|
|
86
|
+
imgY = '0';
|
|
87
|
+
imgW = '50%';
|
|
88
|
+
imgH = '100%';
|
|
89
|
+
imageFit = 'cover';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Text-column geometry. `textX` is the LEFT edge of the column when
|
|
93
|
+
// the side is "left" (image left, text right), and the RIGHT edge of
|
|
94
|
+
// the column when the side is "right" — we use top-left / top-right
|
|
95
|
+
// anchors below so text reads left-aligned in both cases without
|
|
96
|
+
// having to flip the column origin manually.
|
|
97
|
+
const COLUMN_INSET = 4; // % of block width — padding from card edge / divider
|
|
98
|
+
const textColumnWidth = stack ? 90 : 42;
|
|
99
|
+
const textX = stack
|
|
100
|
+
? `${(100 - textColumnWidth) / 2}%`
|
|
101
|
+
: side === 'left'
|
|
102
|
+
? `${50 + COLUMN_INSET}%` // text column starts just past the divider
|
|
103
|
+
: `${50 - COLUMN_INSET}%`; // right edge of left-half text column
|
|
104
|
+
|
|
105
|
+
// Stack the title above the body, with the pair vertically centered
|
|
106
|
+
// in the text column. The title sits 8% above center; body sits 2%
|
|
107
|
+
// below — these offsets keep both lines visible at the small card
|
|
108
|
+
// sizes used by the inline preview gutter without overflowing.
|
|
109
|
+
const titleY = stack ? '60%' : body ? '42%' : '50%';
|
|
110
|
+
const bodyY = stack ? '78%' : title ? '55%' : '50%';
|
|
111
|
+
const textAnchor = side === 'right' && !stack ? 'top-right' : 'top-left';
|
|
112
|
+
const textAlign: 'left' | 'right' = side === 'right' && !stack ? 'right' : 'left';
|
|
113
|
+
|
|
114
|
+
// Paint our own background so the text column has a theme-paired
|
|
115
|
+
// surface to sit on. The host wrapper's surface isn't always theme-
|
|
116
|
+
// aware (e.g. the InlinePreviewGutter card uses a fixed light SVG
|
|
117
|
+
// background), and `theme.colors.text` is only guaranteed legible
|
|
118
|
+
// against `theme.colors.background` — themes like Gezellig pair
|
|
119
|
+
// cream text with a dark warm-brown background, which would
|
|
120
|
+
// disappear on a light wrapper. Matching the convention every other
|
|
121
|
+
// text-bearing template uses (see twoColumn / listBlock).
|
|
122
|
+
const layers: Layer[] = [
|
|
123
|
+
{
|
|
124
|
+
type: 'shape',
|
|
125
|
+
id: 'feature-bg',
|
|
126
|
+
content: { shape: 'rect', fill: theme.colors.background },
|
|
127
|
+
position: { x: 0, y: 0, width: '100%', height: '100%' },
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
if (imageSrc) {
|
|
132
|
+
layers.push({
|
|
133
|
+
type: 'image',
|
|
134
|
+
id: 'feature-image',
|
|
135
|
+
content: {
|
|
136
|
+
src: imageSrc,
|
|
137
|
+
alt: imageAlt ?? title ?? '',
|
|
138
|
+
fit: imageFit,
|
|
139
|
+
},
|
|
140
|
+
position: { x: imgX, y: imgY, width: imgW, height: imgH },
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (title) {
|
|
145
|
+
layers.push({
|
|
146
|
+
type: 'text',
|
|
147
|
+
id: 'feature-title',
|
|
148
|
+
content: {
|
|
149
|
+
text: title,
|
|
150
|
+
style: {
|
|
151
|
+
fontSize: titleFontSize,
|
|
152
|
+
fontFamily: getThemeFont(context, 'title'),
|
|
153
|
+
fontWeight: 'bold',
|
|
154
|
+
color: theme.colors.text,
|
|
155
|
+
textAlign,
|
|
156
|
+
lineHeight: 1.2,
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
position: {
|
|
160
|
+
x: textX,
|
|
161
|
+
y: titleY,
|
|
162
|
+
anchor: textAnchor,
|
|
163
|
+
width: `${textColumnWidth}%`,
|
|
164
|
+
},
|
|
165
|
+
animation: { type: 'fadeIn', duration: 0.8 },
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (body) {
|
|
170
|
+
layers.push({
|
|
171
|
+
type: 'text',
|
|
172
|
+
id: 'feature-body',
|
|
173
|
+
content: {
|
|
174
|
+
text: body,
|
|
175
|
+
style: {
|
|
176
|
+
fontSize: bodyFontSize,
|
|
177
|
+
fontFamily: getThemeFont(context, 'body'),
|
|
178
|
+
color: theme.colors.textMuted,
|
|
179
|
+
textAlign,
|
|
180
|
+
lineHeight: 1.5,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
position: {
|
|
184
|
+
x: textX,
|
|
185
|
+
y: bodyY,
|
|
186
|
+
anchor: textAnchor,
|
|
187
|
+
width: `${textColumnWidth}%`,
|
|
188
|
+
},
|
|
189
|
+
animation: { type: 'fadeIn', duration: 0.8, delay: 0.2 },
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return layers;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function leftFeature(input: LeftFeatureInput, context: TemplateContext): Layer[] {
|
|
197
|
+
return buildFeatureLayers(input, context, 'left');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function rightFeature(input: RightFeatureInput, context: TemplateContext): Layer[] {
|
|
201
|
+
return buildFeatureLayers(input, context, 'right');
|
|
202
|
+
}
|
|
@@ -13,6 +13,19 @@ import type { FullBleedQuoteInput, TemplateContext } from '../../schemas/BlockTe
|
|
|
13
13
|
import { scaledFontSize } from '../../schemas/BlockTemplates.js';
|
|
14
14
|
import { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Hint schema published for the theme validator + future customizer hint UI.
|
|
18
|
+
* Themes may set `templateHints.fullBleedQuote` entries matching these keys.
|
|
19
|
+
*/
|
|
20
|
+
export const fullBleedQuoteHintSchema = {
|
|
21
|
+
/** Entrance style for the quote text. 'subtle' or 'dramatic'. */
|
|
22
|
+
entrance: {
|
|
23
|
+
type: 'string' as const,
|
|
24
|
+
options: ['subtle', 'dramatic'] as const,
|
|
25
|
+
default: 'subtle',
|
|
26
|
+
},
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
16
29
|
export function fullBleedQuote(input: FullBleedQuoteInput, context: TemplateContext): Layer[] {
|
|
17
30
|
const { text, colorScheme = 'blue' } = input;
|
|
18
31
|
const { theme } = context;
|
|
@@ -35,6 +35,7 @@ import { factCard } from './factCard.js';
|
|
|
35
35
|
import { twoColumn } from './twoColumn.js';
|
|
36
36
|
import { dateEvent } from './dateEvent.js';
|
|
37
37
|
import { imageWithCaption } from './imageWithCaption.js';
|
|
38
|
+
import { leftFeature, rightFeature } from './featureBlock.js';
|
|
38
39
|
import { mapBlock } from './mapBlock.js';
|
|
39
40
|
import { fullBleedQuote } from './fullBleedQuote.js';
|
|
40
41
|
import { listBlock } from './listBlock.js';
|
|
@@ -47,22 +48,33 @@ import { videoPullQuote } from './videoPullQuote.js';
|
|
|
47
48
|
import { dataTable } from './dataTable.js';
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
|
-
* Registry mapping template
|
|
51
|
-
*
|
|
52
|
-
*
|
|
51
|
+
* Registry mapping template ids (the strings that appear in
|
|
52
|
+
* `{[name]}` markdown annotations) to their implementation functions.
|
|
53
|
+
*
|
|
54
|
+
* Some implementation functions keep historical "Block" suffixes
|
|
55
|
+
* (`titleBlock`, `quoteBlock`, `mapBlock`, `listBlock`) for source
|
|
56
|
+
* readability — the registry surfaces them under the cleaner short
|
|
57
|
+
* ids (`title`, `quote`, `map`, `list`). {@link TEMPLATE_ALIASES} keeps
|
|
58
|
+
* the legacy long ids resolvable for documents written before the
|
|
59
|
+
* rename.
|
|
60
|
+
*
|
|
61
|
+
* Note: coverBlock is not in the registry as it's used directly for
|
|
62
|
+
* start blocks, not as a regular template in the block sequence.
|
|
53
63
|
*/
|
|
54
64
|
export const templateRegistry: TemplateRegistry = {
|
|
55
|
-
titleBlock,
|
|
65
|
+
title: titleBlock,
|
|
56
66
|
sectionHeader,
|
|
57
67
|
statHighlight,
|
|
58
|
-
quoteBlock,
|
|
68
|
+
quote: quoteBlock,
|
|
59
69
|
factCard,
|
|
60
70
|
twoColumn,
|
|
61
71
|
dateEvent,
|
|
62
72
|
imageWithCaption,
|
|
63
|
-
|
|
73
|
+
leftFeature,
|
|
74
|
+
rightFeature,
|
|
75
|
+
map: mapBlock,
|
|
64
76
|
fullBleedQuote,
|
|
65
|
-
listBlock,
|
|
77
|
+
list: listBlock,
|
|
66
78
|
photoGrid,
|
|
67
79
|
definitionCard,
|
|
68
80
|
comparisonBar,
|
|
@@ -72,11 +84,35 @@ export const templateRegistry: TemplateRegistry = {
|
|
|
72
84
|
dataTable,
|
|
73
85
|
};
|
|
74
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Back-compat: maps legacy template ids (kept around for documents
|
|
89
|
+
* authored before the "Block" suffix was dropped) to the canonical
|
|
90
|
+
* short ids. Resolved by {@link resolveTemplateName} so both the
|
|
91
|
+
* registry lookup and `hasTemplate()` accept either form.
|
|
92
|
+
*/
|
|
93
|
+
export const TEMPLATE_ALIASES: Readonly<Record<string, string>> = {
|
|
94
|
+
titleBlock: 'title',
|
|
95
|
+
quoteBlock: 'quote',
|
|
96
|
+
mapBlock: 'map',
|
|
97
|
+
listBlock: 'list',
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Resolve a template id through {@link TEMPLATE_ALIASES}. Returns the
|
|
102
|
+
* input unchanged when no alias is registered.
|
|
103
|
+
*/
|
|
104
|
+
export function resolveTemplateName(name: string): string {
|
|
105
|
+
return TEMPLATE_ALIASES[name] ?? name;
|
|
106
|
+
}
|
|
107
|
+
|
|
75
108
|
/**
|
|
76
109
|
* Expand a template block into a full Block with layers.
|
|
77
110
|
*/
|
|
78
111
|
export function expandTemplateBlock(templateBlock: TemplateBlock, context: TemplateContext): Block {
|
|
79
|
-
const
|
|
112
|
+
const resolved = resolveTemplateName(templateBlock.template);
|
|
113
|
+
const templateFn = (templateRegistry as Record<string, unknown>)[resolved] as
|
|
114
|
+
| ((input: TemplateBlock, ctx: TemplateContext) => Layer[])
|
|
115
|
+
| undefined;
|
|
80
116
|
|
|
81
117
|
if (!templateFn) {
|
|
82
118
|
console.warn(`Unknown template: ${templateBlock.template}`);
|
|
@@ -94,12 +130,7 @@ export function expandTemplateBlock(templateBlock: TemplateBlock, context: Templ
|
|
|
94
130
|
// Generate layers from template with error handling
|
|
95
131
|
let layers: Layer[];
|
|
96
132
|
try {
|
|
97
|
-
|
|
98
|
-
// discriminated union guarantees the shapes match at runtime.
|
|
99
|
-
layers = (templateFn as (input: TemplateBlock, ctx: TemplateContext) => Layer[])(
|
|
100
|
-
templateBlock,
|
|
101
|
-
context,
|
|
102
|
-
);
|
|
133
|
+
layers = templateFn(templateBlock, context);
|
|
103
134
|
if (!Array.isArray(layers)) {
|
|
104
135
|
console.error(
|
|
105
136
|
`Template ${templateBlock.template} did not return an array, got:`,
|
|
@@ -503,10 +534,12 @@ export function getAvailableTemplates(): string[] {
|
|
|
503
534
|
}
|
|
504
535
|
|
|
505
536
|
/**
|
|
506
|
-
* Check if a template exists.
|
|
537
|
+
* Check if a template exists. Accepts both the canonical short id
|
|
538
|
+
* (`title`, `quote`, `map`, `list`) and legacy aliases
|
|
539
|
+
* (`titleBlock`, `quoteBlock`, `mapBlock`, `listBlock`).
|
|
507
540
|
*/
|
|
508
541
|
export function hasTemplate(name: string): boolean {
|
|
509
|
-
return name in templateRegistry;
|
|
542
|
+
return resolveTemplateName(name) in templateRegistry;
|
|
510
543
|
}
|
|
511
544
|
|
|
512
545
|
// Re-export types and utilities from schemas
|
|
@@ -556,6 +589,7 @@ export { factCard } from './factCard.js';
|
|
|
556
589
|
export { twoColumn } from './twoColumn.js';
|
|
557
590
|
export { dateEvent } from './dateEvent.js';
|
|
558
591
|
export { imageWithCaption } from './imageWithCaption.js';
|
|
592
|
+
export { leftFeature, rightFeature } from './featureBlock.js';
|
|
559
593
|
export { mapBlock } from './mapBlock.js';
|
|
560
594
|
export { coverBlock, expandCoverBlock } from './coverBlock.js';
|
|
561
595
|
export type { CoverBlockInput } from './coverBlock.js';
|
|
@@ -15,7 +15,13 @@ import { getThemeFont } from '../utils/themeUtils.js';
|
|
|
15
15
|
import { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';
|
|
16
16
|
|
|
17
17
|
export function listBlock(input: ListBlockInput, context: TemplateContext): Layer[] {
|
|
18
|
-
const {
|
|
18
|
+
const { title, accentImage } = input;
|
|
19
|
+
// `items` is required by the schema, but malformed / partially-authored
|
|
20
|
+
// blocks (e.g. someone wrote `template: list` with no items yet) reach
|
|
21
|
+
// this code path during live preview. Treat missing/non-array as empty
|
|
22
|
+
// so we render the title-and-background frame instead of blowing up
|
|
23
|
+
// every keystroke with a TypeError.
|
|
24
|
+
const items: string[] = Array.isArray(input.items) ? input.items : [];
|
|
19
25
|
const { theme } = context;
|
|
20
26
|
|
|
21
27
|
// Get layout adjustments if accent image is present
|
|
@@ -68,7 +74,20 @@ export function listBlock(input: ListBlockInput, context: TemplateContext): Laye
|
|
|
68
74
|
});
|
|
69
75
|
}
|
|
70
76
|
|
|
71
|
-
//
|
|
77
|
+
// Left edge of the text column — derived from the center+width pair so
|
|
78
|
+
// items sit flush with the column's left margin instead of being
|
|
79
|
+
// centered. Falls back to a safe 8% if the layout strings ever turn
|
|
80
|
+
// out unparseable (they're authored, but defensive against future
|
|
81
|
+
// edits to the accent-layout types).
|
|
82
|
+
const centerX = parseFloat(accentLayout.textCenterX);
|
|
83
|
+
const widthPct = parseFloat(accentLayout.textWidth);
|
|
84
|
+
const leftX =
|
|
85
|
+
Number.isFinite(centerX) && Number.isFinite(widthPct) ? `${centerX - widthPct / 2}%` : '8%';
|
|
86
|
+
|
|
87
|
+
// Calculate vertical spacing for items. We keep the available band
|
|
88
|
+
// (startY → endY) but use a tighter line-height (1.2) so wrapped
|
|
89
|
+
// items don't bleed into the next entry as aggressively as the old
|
|
90
|
+
// 1.4 value did.
|
|
72
91
|
const endY = 80;
|
|
73
92
|
const spacing = items.length > 1 ? (endY - startY) / (items.length - 1) : 0;
|
|
74
93
|
|
|
@@ -86,14 +105,14 @@ export function listBlock(input: ListBlockInput, context: TemplateContext): Laye
|
|
|
86
105
|
fontSize: itemFontSize,
|
|
87
106
|
fontFamily: getThemeFont(context, 'body'),
|
|
88
107
|
color: theme.colors.text,
|
|
89
|
-
|
|
108
|
+
textAlign: 'left',
|
|
109
|
+
lineHeight: 1.2,
|
|
90
110
|
shadow: !!accentImage,
|
|
91
111
|
},
|
|
92
112
|
},
|
|
93
113
|
position: {
|
|
94
|
-
x:
|
|
114
|
+
x: leftX,
|
|
95
115
|
y: adjustY(`${y}%`, accentLayout),
|
|
96
|
-
anchor: 'center',
|
|
97
116
|
width: accentLayout.textWidth,
|
|
98
117
|
},
|
|
99
118
|
animation: { type: 'fadeIn', duration: 0.8, delay: 0.3 + 0.3 * i },
|
|
@@ -17,6 +17,19 @@ import { resolveColorScheme, getThemeFont } from '../utils/themeUtils.js';
|
|
|
17
17
|
import { createAccentLayers, getAccentLayout, adjustY, DEFAULT_LAYOUT } from './accentImage.js';
|
|
18
18
|
import { createBackgroundLayer } from './captionUtils.js';
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Hint schema published for the theme validator + future customizer hint UI.
|
|
22
|
+
* Themes may set `templateHints.statHighlight` entries matching these keys.
|
|
23
|
+
*/
|
|
24
|
+
export const statHighlightHintSchema = {
|
|
25
|
+
/** Entrance style for the stat number. 'subtle' or 'dramatic'. */
|
|
26
|
+
entrance: {
|
|
27
|
+
type: 'string' as const,
|
|
28
|
+
options: ['subtle', 'dramatic'] as const,
|
|
29
|
+
default: 'subtle',
|
|
30
|
+
},
|
|
31
|
+
} as const;
|
|
32
|
+
|
|
20
33
|
export function statHighlight(input: StatHighlightInput, context: TemplateContext): Layer[] {
|
|
21
34
|
const { stat, description, detail, colorScheme = 'blue', accentImage } = input;
|
|
22
35
|
const { theme } = context;
|
|
@@ -13,6 +13,15 @@ import type { TitleBlockInput, TemplateContext } from '../../schemas/BlockTempla
|
|
|
13
13
|
import { scaledFontSize } from '../../schemas/BlockTemplates.js';
|
|
14
14
|
import { getThemeFont } from '../utils/themeUtils.js';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Hint schema published for the theme validator + future customizer hint UI.
|
|
18
|
+
* Themes may set `templateHints.title` entries matching these keys.
|
|
19
|
+
*/
|
|
20
|
+
export const titleBlockHintSchema = {
|
|
21
|
+
/** Whether to render a thin accent line above the title. Default: theme-dependent. */
|
|
22
|
+
showAccentLine: { type: 'boolean' as const, default: true },
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
16
25
|
export function titleBlock(input: TitleBlockInput, context: TemplateContext): Layer[] {
|
|
17
26
|
const { title, subtitle, backgroundColor } = input;
|
|
18
27
|
const { theme, layout } = context;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { TemplateContext } from '../../schemas/BlockTemplates.js';
|
|
10
10
|
import type { ThemeColorScheme, RenderStyle } from '../../schemas/Theme.js';
|
|
11
11
|
import type { AnimationType } from '../../schemas/Doc.js';
|
|
12
|
+
import { resolveFontFamily } from '../../schemas/fontStacks.js';
|
|
12
13
|
|
|
13
14
|
// ============================================
|
|
14
15
|
// Color Scheme Resolution
|
|
@@ -47,22 +48,22 @@ const FALLBACK_TITLE = 'Georgia, "Times New Roman", serif';
|
|
|
47
48
|
const FALLBACK_MONO = 'Consolas, "Courier New", monospace';
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
|
-
* Get the theme font family for a given role.
|
|
51
|
+
* Get the theme font family for a given role, resolved to a CSS string.
|
|
51
52
|
* Templates call this to set `fontFamily` on text layers.
|
|
52
53
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
54
|
+
* Theme fields are structured `FontFamily` references (`{ stackId }` or
|
|
55
|
+
* `{ custom: { name, fallback } }`); this helper resolves them to a
|
|
56
|
+
* CSS font-family string with safe fallbacks.
|
|
56
57
|
*/
|
|
57
58
|
export function getThemeFont(context: TemplateContext, role: 'title' | 'body' | 'mono'): string {
|
|
58
59
|
const { typography } = context.theme;
|
|
59
60
|
switch (role) {
|
|
60
61
|
case 'title':
|
|
61
|
-
return typography.
|
|
62
|
+
return resolveFontFamily(typography.titleFont, FALLBACK_TITLE);
|
|
62
63
|
case 'body':
|
|
63
|
-
return typography.
|
|
64
|
+
return resolveFontFamily(typography.bodyFont, FALLBACK_BODY);
|
|
64
65
|
case 'mono':
|
|
65
|
-
return typography.
|
|
66
|
+
return resolveFontFamily(typography.monoFont, FALLBACK_MONO);
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -109,7 +109,7 @@ function mapDate(data: DateData, base: Base, opts: MapOptions): DateEventInput {
|
|
|
109
109
|
function mapQuote(data: QuoteData, base: Base, opts: MapOptions): QuoteBlockInput {
|
|
110
110
|
return {
|
|
111
111
|
...base,
|
|
112
|
-
template: '
|
|
112
|
+
template: 'quote',
|
|
113
113
|
quote: data.quote,
|
|
114
114
|
attribution: data.attribution,
|
|
115
115
|
accentImage: opts.accentImage,
|
|
@@ -149,7 +149,7 @@ function mapImpactLine(data: ImpactLineData, base: Base, opts: MapOptions): Full
|
|
|
149
149
|
function mapList(data: ListData, base: Base, opts: MapOptions): ListBlockInput {
|
|
150
150
|
return {
|
|
151
151
|
...base,
|
|
152
|
-
template: '
|
|
152
|
+
template: 'list',
|
|
153
153
|
items: data.items,
|
|
154
154
|
title: data.title,
|
|
155
155
|
colorScheme: opts.colorScheme,
|