@developer_tribe/react-builder 1.0.3 → 1.0.5
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/README.md +6 -0
- package/dist/android.svg +43 -0
- package/dist/apple.svg +16 -0
- package/dist/assets/samples/getSamples.d.ts +1 -0
- package/dist/attributes-editor/Field.d.ts +2 -1
- package/dist/attributes-editor/SizeField.d.ts +9 -0
- package/dist/background.jpg +0 -0
- package/dist/build-components/BIcon/BIcon.d.ts +5 -0
- package/dist/build-components/BIcon/BIconProps.generated.d.ts +55 -0
- package/dist/build-components/BackgroundImage/BackgroundImageProps.generated.d.ts +5 -0
- package/dist/build-components/Button/ButtonProps.generated.d.ts +5 -0
- package/dist/build-components/Carousel/CarouselProps.generated.d.ts +5 -0
- package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +5 -0
- package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +5 -0
- package/dist/build-components/CarouselItem/CarouselItemProps.generated.d.ts +5 -0
- package/dist/build-components/CarouselProvider/CarouselProviderProps.generated.d.ts +5 -0
- package/dist/build-components/Image/ImageProps.generated.d.ts +5 -0
- package/dist/build-components/Main/Main.d.ts +5 -0
- package/dist/build-components/Main/MainProps.generated.d.ts +48 -0
- package/dist/build-components/Onboard/OnboardProps.generated.d.ts +5 -0
- package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +5 -1
- package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +5 -0
- package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +6 -3
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +5 -0
- package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +6 -1
- package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +5 -0
- package/dist/build-components/OnboardProvider/OnboardProviderProps.generated.d.ts +5 -1
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +5 -0
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +5 -0
- package/dist/build-components/PaywallBackground/PaywallBackground.d.ts +5 -0
- package/dist/build-components/PaywallBackground/PaywallBackgroundProps.generated.d.ts +47 -0
- package/dist/build-components/PaywallCloseButton/PaywallCloseButton.d.ts +5 -0
- package/dist/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.d.ts +56 -0
- package/dist/build-components/PaywallOptions/PaywallOptionButton.d.ts +9 -0
- package/dist/build-components/PaywallOptions/PaywallOptions.d.ts +5 -0
- package/dist/build-components/PaywallOptions/PaywallOptionsProps.generated.d.ts +47 -0
- package/dist/build-components/PaywallOptions/usePaywallOptionParamsFactory.d.ts +10 -0
- package/dist/build-components/PaywallProvider/PaywallProvider.d.ts +5 -0
- package/dist/build-components/PaywallProvider/PaywallProviderProps.generated.d.ts +47 -0
- package/dist/build-components/PaywallSubscriButton/PaywallSubscriButton.d.ts +5 -0
- package/dist/build-components/PaywallSubscriButton/PaywallSubscriButtonProps.generated.d.ts +50 -0
- package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButton.d.ts +5 -0
- package/dist/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.d.ts +50 -0
- package/dist/build-components/RadioButton/RadioButton.d.ts +11 -0
- package/dist/build-components/RadioButton/RadioButtonProps.generated.d.ts +50 -0
- package/dist/build-components/RenderNode.generated.d.ts +1 -1
- package/dist/build-components/Text/TextProps.generated.d.ts +5 -0
- package/dist/build-components/View/ViewProps.generated.d.ts +5 -0
- package/dist/build-components/index.d.ts +10 -1
- package/dist/build-components/patterns.generated.d.ts +5030 -723
- package/dist/components/AttributesEditorPanel.d.ts +2 -1
- package/dist/components/Builder.d.ts +1 -1
- package/dist/components/BuilderButton.d.ts +1 -1
- package/dist/components/BuilderProvider.d.ts +15 -0
- package/dist/components/EditorHeader.d.ts +1 -1
- package/dist/components/Icon.generated.d.ts +11 -0
- package/dist/components/JsonTextEditor.d.ts +9 -0
- package/dist/components/LocalizationParamsProvider.d.ts +11 -0
- package/dist/components/ParamsProvider.d.ts +14 -0
- package/dist/hooks/useLocalizationParams.d.ts +1 -0
- package/dist/hooks/useLocalize.d.ts +2 -0
- package/dist/hooks/useParams.d.ts +1 -0
- package/dist/hooks/useSafeAreaViewStyle.d.ts +1 -0
- package/dist/index.cjs.js +5 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.esm.js +5 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.native.cjs.js +29 -0
- package/dist/index.native.cjs.js.map +1 -0
- package/dist/index.native.d.ts +31 -0
- package/dist/index.native.esm.js +29 -0
- package/dist/index.native.esm.js.map +1 -0
- package/dist/mockOS/components/MockOSRouter.d.ts +1 -1
- package/dist/mockOS/context/MockOSContext.d.ts +4 -18
- package/dist/mockOS/context/MockOSContextBase.d.ts +21 -0
- package/dist/mockOS/index.d.ts +3 -2
- package/dist/modals/BenefitEditModal.d.ts +13 -0
- package/dist/modals/BenefitPresetsModal.d.ts +9 -0
- package/dist/modals/IconPickerModal.d.ts +9 -0
- package/dist/modals/MockableFeatureModal.d.ts +6 -0
- package/dist/modals/ProductEditModal.d.ts +9 -0
- package/dist/modals/ProductPresetsModal.d.ts +9 -0
- package/dist/modals/index.d.ts +6 -0
- package/dist/pages/ProjectPage.d.ts +3 -2
- package/dist/pages/tabs/BuilderPanel.d.ts +1 -1
- package/dist/pages/tabs/SideTool.d.ts +3 -2
- package/dist/paywall/hooks/index.d.ts +5 -0
- package/dist/paywall/hooks/useCalculateLocalizedPrice.d.ts +4 -0
- package/dist/paywall/hooks/useCarouselOptionsSeperator.d.ts +6 -0
- package/dist/paywall/hooks/useCloseStatusPaywall.d.ts +4 -0
- package/dist/paywall/hooks/useDiscountRate.d.ts +4 -0
- package/dist/paywall/hooks/usePaywallCounter.d.ts +4 -0
- package/dist/paywall/types/benefits.d.ts +14 -0
- package/dist/paywall/types/paywall-types.d.ts +43 -0
- package/dist/store.d.ts +31 -1
- package/dist/styles.css +1 -1
- package/dist/types/Icons.d.ts +2 -0
- package/dist/types/Project.d.ts +5 -0
- package/dist/utils/analyseNode.d.ts +1 -4
- package/dist/utils/analyseNodeByPatterns.d.ts +16 -0
- package/dist/utils/analyseNodeStructural.d.ts +11 -0
- package/dist/utils/extractImageStyle.d.ts +2 -1
- package/dist/utils/extractViewStyle.d.ts +1 -2
- package/dist/utils/findNodeByKeyNested.d.ts +2 -0
- package/dist/utils/nodeGuards.d.ts +5 -0
- package/dist/utils/novaToJson.d.ts +5 -0
- package/dist/utils/patterns.d.ts +14 -0
- package/dist/utils/replaceLocalizationParams.d.ts +1 -0
- package/dist/utils/selection.d.ts +7 -0
- package/dist/utils/useMergedStyle.d.ts +2 -0
- package/package.json +33 -6
- package/scripts/prebuild/assets/icon.template +71 -0
- package/scripts/prebuild/build-components.js +5 -0
- package/scripts/prebuild/icon-generator.js +206 -0
- package/scripts/prebuild/prebuild.js +10 -1
- package/scripts/prebuild/utils/createComponentTsx.js +6 -3
- package/scripts/prebuild/utils/createGeneratedProps.js +4 -2
- package/scripts/prebuild/utils/createRenderNodeGenerated.js +43 -8
- package/scripts/prebuild/utils/validateAllComponentsOrThrow.js +20 -9
- package/scripts/prebuild/utils/validatePatternJson.js +3 -2
- package/src/.DS_Store +0 -0
- package/src/AttributesEditor.tsx +185 -36
- package/src/DeviceMockFrame.tsx +41 -43
- package/src/RenderPage.tsx +6 -43
- package/src/assets/benefits.json +24 -0
- package/src/assets/iconset/activity-heart.svg +3 -0
- package/src/assets/iconset/activity.svg +3 -0
- package/src/assets/iconset/alert-circle.svg +3 -0
- package/src/assets/iconset/alert-triangle.svg +3 -0
- package/src/assets/iconset/anchor.svg +3 -0
- package/src/assets/iconset/archive.svg +3 -0
- package/src/assets/iconset/arrow-down.svg +3 -0
- package/src/assets/iconset/arrow-left.svg +3 -0
- package/src/assets/iconset/arrow-narrow-down-left.svg +3 -0
- package/src/assets/iconset/arrow-narrow-up-right.svg +3 -0
- package/src/assets/iconset/arrow-right-smooth.svg +4 -0
- package/src/assets/iconset/arrow-right.svg +7 -0
- package/src/assets/iconset/asterisk-01.svg +3 -0
- package/src/assets/iconset/asterisk-02.svg +3 -0
- package/src/assets/iconset/at-sign.svg +3 -0
- package/src/assets/iconset/award.svg +4 -0
- package/src/assets/iconset/battery-charging.svg +6 -0
- package/src/assets/iconset/bell-01.svg +5 -0
- package/src/assets/iconset/bell-02.svg +3 -0
- package/src/assets/iconset/bell-ringing-02.svg +3 -0
- package/src/assets/iconset/bookmark-add.svg +3 -0
- package/src/assets/iconset/bookmark-check.svg +3 -0
- package/src/assets/iconset/bookmark-minus.svg +3 -0
- package/src/assets/iconset/bookmark-x.svg +3 -0
- package/src/assets/iconset/bookmark.svg +3 -0
- package/src/assets/iconset/bubble.svg +5 -0
- package/src/assets/iconset/building-01.svg +3 -0
- package/src/assets/iconset/building-02.svg +3 -0
- package/src/assets/iconset/building-03.svg +3 -0
- package/src/assets/iconset/building-04.svg +3 -0
- package/src/assets/iconset/building-05.svg +3 -0
- package/src/assets/iconset/building-06.svg +3 -0
- package/src/assets/iconset/building-07.svg +3 -0
- package/src/assets/iconset/building-08.svg +3 -0
- package/src/assets/iconset/building-09.svg +3 -0
- package/src/assets/iconset/camera-01.svg +8 -0
- package/src/assets/iconset/camera-steel.svg +4 -0
- package/src/assets/iconset/camera.svg +4 -0
- package/src/assets/iconset/check-circle-bold.svg +3 -0
- package/src/assets/iconset/check-circle-broken.svg +3 -0
- package/src/assets/iconset/check-circle.svg +3 -0
- package/src/assets/iconset/check-done-01.svg +3 -0
- package/src/assets/iconset/check-done-02.svg +3 -0
- package/src/assets/iconset/check-heart.svg +3 -0
- package/src/assets/iconset/check-square-broken.svg +3 -0
- package/src/assets/iconset/check-square.svg +3 -0
- package/src/assets/iconset/check-verified-01.svg +3 -0
- package/src/assets/iconset/check-verified-02.svg +3 -0
- package/src/assets/iconset/check-verified-03.svg +3 -0
- package/src/assets/iconset/check.svg +3 -0
- package/src/assets/iconset/checkbox.svg +4 -0
- package/src/assets/iconset/checkv.svg +3 -0
- package/src/assets/iconset/chevron-down.svg +3 -0
- package/src/assets/iconset/chevron-down2.svg +3 -0
- package/src/assets/iconset/chevron-left-2.svg +3 -0
- package/src/assets/iconset/chevron-left.svg +3 -0
- package/src/assets/iconset/chevron-right-empty.svg +3 -0
- package/src/assets/iconset/chevron-right-smooth.svg +3 -0
- package/src/assets/iconset/chevron-right.svg +3 -0
- package/src/assets/iconset/chevron-up.svg +3 -0
- package/src/assets/iconset/circle.svg +32 -0
- package/src/assets/iconset/clock-fast-forward.svg +10 -0
- package/src/assets/iconset/clock.svg +3 -0
- package/src/assets/iconset/close-circle.svg +3 -0
- package/src/assets/iconset/close.svg +3 -0
- package/src/assets/iconset/cloud-01.svg +5 -0
- package/src/assets/iconset/cloud-blank-01.svg +3 -0
- package/src/assets/iconset/cloud-blank-02.svg +3 -0
- package/src/assets/iconset/coin.svg +5 -0
- package/src/assets/iconset/coins-02.svg +3 -0
- package/src/assets/iconset/colors.svg +3 -0
- package/src/assets/iconset/copy-01.svg +3 -0
- package/src/assets/iconset/copy-02.svg +3 -0
- package/src/assets/iconset/copy-03.svg +3 -0
- package/src/assets/iconset/copy-04.svg +3 -0
- package/src/assets/iconset/copy-05.svg +3 -0
- package/src/assets/iconset/copy-06.svg +3 -0
- package/src/assets/iconset/copy-07.svg +3 -0
- package/src/assets/iconset/corner-down-right.svg +3 -0
- package/src/assets/iconset/crypto-bold.svg +4 -0
- package/src/assets/iconset/delete-icon.svg +5 -0
- package/src/assets/iconset/diamond.svg +3 -0
- package/src/assets/iconset/dice-3.svg +3 -0
- package/src/assets/iconset/divide-01.svg +3 -0
- package/src/assets/iconset/divide-02.svg +3 -0
- package/src/assets/iconset/divide-03.svg +3 -0
- package/src/assets/iconset/document-check-bold.svg +4 -0
- package/src/assets/iconset/dots-circle.svg +10 -0
- package/src/assets/iconset/dots-grid.svg +11 -0
- package/src/assets/iconset/dots-horizontal.svg +5 -0
- package/src/assets/iconset/dots-vertical.svg +5 -0
- package/src/assets/iconset/download-01.svg +3 -0
- package/src/assets/iconset/download-02.svg +3 -0
- package/src/assets/iconset/download-03.svg +3 -0
- package/src/assets/iconset/edit-03.svg +3 -0
- package/src/assets/iconset/edit-04.svg +3 -0
- package/src/assets/iconset/edit-05.svg +3 -0
- package/src/assets/iconset/element-3.svg +6 -0
- package/src/assets/iconset/ellipse-127.svg +3 -0
- package/src/assets/iconset/exclaimation-circle.svg +8 -0
- package/src/assets/iconset/eye-off-line.svg +5 -0
- package/src/assets/iconset/face-smile.svg +5 -0
- package/src/assets/iconset/file-04.svg +3 -0
- package/src/assets/iconset/file-05.svg +3 -0
- package/src/assets/iconset/file-check-02.svg +3 -0
- package/src/assets/iconset/file-plus-01.svg +5 -0
- package/src/assets/iconset/file-shield-02.svg +5 -0
- package/src/assets/iconset/filter-funnel-01.svg +3 -0
- package/src/assets/iconset/flag-03.svg +3 -0
- package/src/assets/iconset/flash.svg +3 -0
- package/src/assets/iconset/folder-plus.svg +3 -0
- package/src/assets/iconset/folder.svg +3 -0
- package/src/assets/iconset/gallery.svg +3 -0
- package/src/assets/iconset/globe-01.svg +3 -0
- package/src/assets/iconset/globe-04.svg +5 -0
- package/src/assets/iconset/globe-bold.svg +4 -0
- package/src/assets/iconset/guard.svg +3 -0
- package/src/assets/iconset/headphones-01.svg +3 -0
- package/src/assets/iconset/headphones-02.svg +5 -0
- package/src/assets/iconset/headset-bold.svg +4 -0
- package/src/assets/iconset/heart-bold.svg +3 -0
- package/src/assets/iconset/heart.svg +3 -0
- package/src/assets/iconset/help-circle.svg +5 -0
- package/src/assets/iconset/home-2.svg +4 -0
- package/src/assets/iconset/home-line.svg +3 -0
- package/src/assets/iconset/hourglass-02.svg +5 -0
- package/src/assets/iconset/image-01.svg +5 -0
- package/src/assets/iconset/image-03.svg +3 -0
- package/src/assets/iconset/image.svg +4 -0
- package/src/assets/iconset/inbox-01.svg +3 -0
- package/src/assets/iconset/inbox-arrow-down.svg +3 -0
- package/src/assets/iconset/info-circle.svg +3 -0
- package/src/assets/iconset/keyboard-line.svg +9 -0
- package/src/assets/iconset/lamp-charge.svg +5 -0
- package/src/assets/iconset/layer.svg +3 -0
- package/src/assets/iconset/light.svg +6 -0
- package/src/assets/iconset/like-dislike.svg +6 -0
- package/src/assets/iconset/lock-03.svg +3 -0
- package/src/assets/iconset/logout.svg +3 -0
- package/src/assets/iconset/magicpen.svg +7 -0
- package/src/assets/iconset/mail-01.svg +5 -0
- package/src/assets/iconset/mail.svg +3 -0
- package/src/assets/iconset/marker.svg +3 -0
- package/src/assets/iconset/medal-star.svg +5 -0
- package/src/assets/iconset/menu-04.svg +3 -0
- package/src/assets/iconset/menu.svg +5 -0
- package/src/assets/iconset/message-circle-01.svg +5 -0
- package/src/assets/iconset/message-plus-circle.svg +3 -0
- package/src/assets/iconset/message-question-circle.svg +5 -0
- package/src/assets/iconset/message-text-circle-01.svg +5 -0
- package/src/assets/iconset/message-text-square-02.svg +3 -0
- package/src/assets/iconset/message-x-square.svg +3 -0
- package/src/assets/iconset/microphone-02.svg +3 -0
- package/src/assets/iconset/microphone-slash.svg +8 -0
- package/src/assets/iconset/mirror.svg +4 -0
- package/src/assets/iconset/moon-01.svg +3 -0
- package/src/assets/iconset/moon-bold.svg +3 -0
- package/src/assets/iconset/mouse-circle.svg +4 -0
- package/src/assets/iconset/move.svg +5 -0
- package/src/assets/iconset/notification-fill.svg +3 -0
- package/src/assets/iconset/notification-text.svg +3 -0
- package/src/assets/iconset/notification.svg +5 -0
- package/src/assets/iconset/pdf-01.svg +6 -0
- package/src/assets/iconset/pencil-01.svg +5 -0
- package/src/assets/iconset/phone-01.svg +3 -0
- package/src/assets/iconset/phone-arrow-down-left.svg +4 -0
- package/src/assets/iconset/phone-arrow-up-right.svg +8 -0
- package/src/assets/iconset/phone-hang-up.svg +5 -0
- package/src/assets/iconset/phone-hangup2.svg +8 -0
- package/src/assets/iconset/phone-incoming-01.svg +3 -0
- package/src/assets/iconset/phone-outgoing-01.svg +3 -0
- package/src/assets/iconset/phone-plus.svg +3 -0
- package/src/assets/iconset/phone-x.svg +3 -0
- package/src/assets/iconset/phone.svg +3 -0
- package/src/assets/iconset/plus-circle.svg +3 -0
- package/src/assets/iconset/plus.svg +4 -0
- package/src/assets/iconset/printer.svg +3 -0
- package/src/assets/iconset/question-mark-circle.svg +5 -0
- package/src/assets/iconset/refresh-ccw-01.svg +3 -0
- package/src/assets/iconset/refresh-cw-01.svg +3 -0
- package/src/assets/iconset/refresh-cw-04.svg +3 -0
- package/src/assets/iconset/refresh-right-square-bold.svg +3 -0
- package/src/assets/iconset/remove-circle.svg +12 -0
- package/src/assets/iconset/repeat-04.svg +3 -0
- package/src/assets/iconset/repeat-bold.svg +3 -0
- package/src/assets/iconset/ruler-pen.svg +4 -0
- package/src/assets/iconset/search-lg.svg +3 -0
- package/src/assets/iconset/search-md.svg +5 -0
- package/src/assets/iconset/search-refraction.svg +5 -0
- package/src/assets/iconset/search.svg +3 -0
- package/src/assets/iconset/send-01.svg +3 -0
- package/src/assets/iconset/send-02.svg +5 -0
- package/src/assets/iconset/send-diagonal.svg +3 -0
- package/src/assets/iconset/setting-2.svg +4 -0
- package/src/assets/iconset/settings-02.svg +4 -0
- package/src/assets/iconset/settings-04.svg +5 -0
- package/src/assets/iconset/settings-2.svg +4 -0
- package/src/assets/iconset/settings-cog.svg +3 -0
- package/src/assets/iconset/settings.svg +4 -0
- package/src/assets/iconset/share-01.svg +4 -0
- package/src/assets/iconset/share-03.svg +3 -0
- package/src/assets/iconset/share-04.svg +3 -0
- package/src/assets/iconset/share-05.svg +5 -0
- package/src/assets/iconset/share-06.svg +3 -0
- package/src/assets/iconset/share-bold.svg +3 -0
- package/src/assets/iconset/shield-01.svg +3 -0
- package/src/assets/iconset/shield-bold.svg +3 -0
- package/src/assets/iconset/solar-check.svg +3 -0
- package/src/assets/iconset/speaker-wave.svg +9 -0
- package/src/assets/iconset/speaker.svg +5 -0
- package/src/assets/iconset/speedometer-03.svg +3 -0
- package/src/assets/iconset/star-rounded.svg +3 -0
- package/src/assets/iconset/star.svg +3 -0
- package/src/assets/iconset/sun.svg +5 -0
- package/src/assets/iconset/target-03.svg +3 -0
- package/src/assets/iconset/text-input.svg +3 -0
- package/src/assets/iconset/translate.svg +7 -0
- package/src/assets/iconset/trash-02.svg +3 -0
- package/src/assets/iconset/trash-03.svg +5 -0
- package/src/assets/iconset/trash-04.svg +3 -0
- package/src/assets/iconset/trash.svg +7 -0
- package/src/assets/iconset/trush-square-bold.svg +3 -0
- package/src/assets/iconset/unlimited.svg +3 -0
- package/src/assets/iconset/user-circle.svg +3 -0
- package/src/assets/iconset/user-jogging.svg +3 -0
- package/src/assets/iconset/user-plus-01.svg +5 -0
- package/src/assets/iconset/user-square.svg +5 -0
- package/src/assets/iconset/user-x-01.svg +5 -0
- package/src/assets/iconset/user-x-02.svg +3 -0
- package/src/assets/iconset/user2.svg +3 -0
- package/src/assets/iconset/users-02.svg +5 -0
- package/src/assets/iconset/users-speaker.svg +7 -0
- package/src/assets/iconset/verify.svg +3 -0
- package/src/assets/iconset/voice-cricle.svg +8 -0
- package/src/assets/iconset/x-circle.svg +3 -0
- package/src/assets/iconset/x-close.svg +3 -0
- package/src/assets/iconset/x-sm.svg +3 -0
- package/src/assets/iconset/zap.svg +3 -0
- package/src/assets/images/background.jpg +0 -0
- package/src/assets/loading_animation.json +1 -0
- package/src/assets/products.json +98 -0
- package/src/assets/samples/carousel-sample.json +1 -0
- package/src/assets/samples/getSamples.ts +39 -66
- package/src/assets/samples/paywall-1.json +220 -0
- package/src/assets/samples/simple-1.json +1 -0
- package/src/assets/samples/simple-2.json +1 -0
- package/src/assets/samples/vpn-onboard-1.json +324 -720
- package/src/assets/samples/vpn-onboard-2.json +299 -683
- package/src/assets/samples/vpn-onboard-3.json +270 -680
- package/src/assets/samples/vpn-onboard-4.json +270 -681
- package/src/assets/samples/vpn-onboard-5.json +408 -893
- package/src/assets/samples/vpn-onboard-6.json +279 -594
- package/src/attributes-editor/Field.tsx +48 -160
- package/src/attributes-editor/SizeField.tsx +184 -0
- package/src/attributes-editor/SpecialCategorySection.tsx +11 -4
- package/src/build-components/BIcon/BIcon.tsx +56 -0
- package/src/build-components/BIcon/BIconProps.generated.ts +82 -0
- package/src/build-components/BIcon/pattern.json +47 -0
- package/src/build-components/BackgroundImage/BackgroundImage.tsx +7 -17
- package/src/build-components/BackgroundImage/BackgroundImageProps.generated.ts +5 -0
- package/src/build-components/BackgroundImage/pattern.json +2 -2
- package/src/build-components/Button/Button.tsx +20 -9
- package/src/build-components/Button/ButtonProps.generated.ts +5 -0
- package/src/build-components/Button/pattern.json +4 -1
- package/src/build-components/Carousel/Carousel.tsx +7 -9
- package/src/build-components/Carousel/CarouselProps.generated.ts +5 -0
- package/src/build-components/Carousel/pattern.json +2 -2
- package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +5 -0
- package/src/build-components/CarouselButtons/pattern.json +1 -1
- package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +5 -0
- package/src/build-components/CarouselDots/pattern.json +1 -1
- package/src/build-components/CarouselItem/CarouselItem.tsx +1 -1
- package/src/build-components/CarouselItem/CarouselItemProps.generated.ts +5 -0
- package/src/build-components/CarouselItem/pattern.json +1 -1
- package/src/build-components/CarouselProvider/CarouselProvider.tsx +1 -1
- package/src/build-components/CarouselProvider/CarouselProviderProps.generated.ts +5 -0
- package/src/build-components/CarouselProvider/pattern.json +1 -1
- package/src/build-components/Image/Image.tsx +11 -18
- package/src/build-components/Image/ImageProps.generated.ts +5 -0
- package/src/build-components/Image/pattern.json +2 -10
- package/src/build-components/Main/Main.tsx +61 -0
- package/src/build-components/Main/MainProps.generated.ts +64 -0
- package/src/build-components/Main/pattern.json +35 -0
- package/src/build-components/Onboard/OnboardProps.generated.ts +5 -0
- package/src/build-components/OnboardButton/OnboardButton.tsx +0 -3
- package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +5 -1
- package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +5 -0
- package/src/build-components/OnboardDot/OnboardDot.tsx +59 -39
- package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +6 -3
- package/src/build-components/OnboardDot/pattern.json +2 -18
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +28 -15
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +5 -0
- package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +6 -1
- package/src/build-components/OnboardItem/OnboardItem.tsx +2 -12
- package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +5 -0
- package/src/build-components/OnboardProvider/OnboardProvider.tsx +1 -8
- package/src/build-components/OnboardProvider/OnboardProviderProps.generated.ts +5 -1
- package/src/build-components/OnboardProvider/pattern.json +6 -16
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +5 -0
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +5 -0
- package/src/build-components/PaywallBackground/PaywallBackground.tsx +47 -0
- package/src/build-components/PaywallBackground/PaywallBackgroundProps.generated.ts +63 -0
- package/src/build-components/PaywallBackground/pattern.json +16 -0
- package/src/build-components/PaywallCloseButton/PaywallCloseButton.tsx +62 -0
- package/src/build-components/PaywallCloseButton/PaywallCloseButtonProps.generated.ts +83 -0
- package/src/build-components/PaywallCloseButton/pattern.json +23 -0
- package/src/build-components/PaywallOptions/PaywallOptionButton.tsx +64 -0
- package/src/build-components/PaywallOptions/PaywallOptions.tsx +92 -0
- package/src/build-components/PaywallOptions/PaywallOptionsProps.generated.ts +63 -0
- package/src/build-components/PaywallOptions/pattern.json +22 -0
- package/src/build-components/PaywallOptions/usePaywallOptionParamsFactory.ts +42 -0
- package/src/build-components/PaywallProvider/PaywallProvider.tsx +78 -0
- package/src/build-components/PaywallProvider/PaywallProviderProps.generated.ts +63 -0
- package/src/build-components/PaywallProvider/pattern.json +24 -0
- package/src/build-components/PaywallSubscriButton/PaywallSubscriButton.tsx +10 -0
- package/src/build-components/PaywallSubscriButton/PaywallSubscriButtonProps.generated.ts +77 -0
- package/src/build-components/PaywallSubscriButton/pattern.json +27 -0
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButton.tsx +60 -0
- package/src/build-components/PaywallSubscribeButton/PaywallSubscribeButtonProps.generated.ts +77 -0
- package/src/build-components/PaywallSubscribeButton/pattern.json +27 -0
- package/src/build-components/RadioButton/RadioButton.tsx +123 -0
- package/src/build-components/RadioButton/RadioButtonProps.generated.ts +66 -0
- package/src/build-components/RadioButton/pattern.json +42 -0
- package/src/build-components/RenderNode.generated.tsx +140 -37
- package/src/build-components/Text/Text.tsx +12 -18
- package/src/build-components/Text/TextProps.generated.ts +5 -0
- package/src/build-components/Text/pattern.json +1 -1
- package/src/build-components/View/View.tsx +7 -9
- package/src/build-components/View/ViewProps.generated.ts +5 -0
- package/src/build-components/View/pattern.json +50 -4
- package/src/build-components/index.ts +55 -10
- package/src/build-components/patterns.generated.ts +5085 -745
- package/src/components/AttributesEditorPanel.tsx +3 -1
- package/src/components/Builder.tsx +64 -22
- package/src/components/BuilderButton.tsx +2 -7
- package/src/components/BuilderProvider.tsx +45 -0
- package/src/components/DeviceNavigationBar.tsx +1 -2
- package/src/components/EditorHeader.tsx +15 -2
- package/src/components/Icon.generated.tsx +540 -0
- package/src/components/JsonTextEditor.tsx +185 -0
- package/src/components/LocalizationParamsProvider.tsx +22 -0
- package/src/components/ParamsProvider.tsx +38 -0
- package/src/hooks/useLocalizationParams.ts +5 -0
- package/src/hooks/useLocalize.ts +23 -0
- package/src/hooks/useParams.ts +8 -0
- package/src/hooks/useSafeAreaViewStyle.ts +67 -0
- package/src/index.native.ts +75 -0
- package/src/index.ts +26 -0
- package/src/mockOS/components/MockOSRouter.tsx +12 -11
- package/src/mockOS/context/MockOSContext.tsx +12 -41
- package/src/mockOS/context/MockOSContextBase.ts +35 -0
- package/src/mockOS/index.ts +3 -2
- package/src/mockOS/managers/mockPermissionManager.ts +0 -4
- package/src/mockOS/managers/navigationManager.ts +1 -6
- package/src/modals/AddComponentModal.tsx +1 -0
- package/src/modals/BenefitEditModal.tsx +160 -0
- package/src/modals/BenefitPresetsModal.tsx +166 -0
- package/src/modals/ColorModal.tsx +103 -25
- package/src/modals/IconPickerModal.tsx +109 -0
- package/src/modals/LocalicationModal.tsx +4 -5
- package/src/modals/MockableFeatureModal.tsx +292 -0
- package/src/modals/Modal.tsx +8 -1
- package/src/modals/ProductEditModal.tsx +215 -0
- package/src/modals/ProductPresetsModal.tsx +151 -0
- package/src/modals/index.ts +6 -0
- package/src/pages/ProjectPage.tsx +79 -16
- package/src/pages/tabs/BuilderPanel.tsx +1 -1
- package/src/pages/tabs/SideTool.tsx +13 -19
- package/src/paywall/hooks/index.ts +5 -0
- package/src/paywall/hooks/useCalculateLocalizedPrice.ts +6 -0
- package/src/paywall/hooks/useCarouselOptionsSeperator.ts +8 -0
- package/src/paywall/hooks/useCloseStatusPaywall.ts +6 -0
- package/src/paywall/hooks/useDiscountRate.ts +6 -0
- package/src/paywall/hooks/usePaywallCounter.ts +6 -0
- package/src/paywall/types/benefits.ts +44 -0
- package/src/paywall/types/paywall-types.ts +51 -0
- package/src/store.ts +157 -38
- package/src/styles/base/_global.scss +54 -41
- package/src/styles/components/_attributes-editor.scss +40 -5
- package/src/styles/components/_editor-shell.scss +5 -9
- package/src/styles/components/_ui-components.scss +2 -1
- package/src/styles/index.scss +5 -0
- package/src/styles/modals/_benefit-edit-modal.scss +17 -0
- package/src/styles/modals/_benefit-presets-modal.scss +79 -0
- package/src/styles/modals/_color-modal.scss +30 -1
- package/src/styles/modals/_mockable-feature-modal.scss +15 -0
- package/src/styles/modals/_product-edit-modal.scss +23 -0
- package/src/styles/modals/_product-presets-modal.scss +81 -0
- package/src/styles/utilities/_carousel.scss +9 -8
- package/src/types/Icons.ts +244 -0
- package/src/types/Project.ts +5 -0
- package/src/types/jest-globals.d.ts +13 -0
- package/src/utils/analyseNode.ts +22 -109
- package/src/utils/analyseNodeByPatterns.ts +438 -0
- package/src/utils/analyseNodeStructural.ts +52 -0
- package/src/utils/extractImageStyle.ts +3 -6
- package/src/utils/extractTextStyle.ts +2 -81
- package/src/utils/extractViewStyle.ts +39 -15
- package/src/utils/findNodeByKeyNested.ts +32 -0
- package/src/utils/isCarousel.ts +21 -5
- package/src/utils/nodeGuards.ts +26 -0
- package/src/utils/novaToJson.ts +21 -9
- package/src/utils/patterns.ts +62 -3
- package/src/utils/replaceLocalizationParams.ts +15 -0
- package/src/utils/selection.ts +24 -0
- package/src/utils/useMergedStyle.ts +16 -0
package/dist/utils/patterns.d.ts
CHANGED
|
@@ -6,6 +6,15 @@ export type AttributeMeta = {
|
|
|
6
6
|
specialCategory?: 'padding' | 'margin' | 'offset' | null | string;
|
|
7
7
|
sort?: number;
|
|
8
8
|
preferedScale?: 's' | 'vs' | 'f' | '%' | '' | string;
|
|
9
|
+
/**
|
|
10
|
+
* When true, this attribute should remain visible even if the component
|
|
11
|
+
* metadata requests hiding all attributes (e.g. `meta.hideAllAttributes`).
|
|
12
|
+
*/
|
|
13
|
+
forceVisible?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Alias for `forceVisible` used by some patterns.
|
|
16
|
+
*/
|
|
17
|
+
override?: boolean;
|
|
9
18
|
};
|
|
10
19
|
export type SpecialCategoryMeta = {
|
|
11
20
|
label?: string;
|
|
@@ -20,6 +29,9 @@ type PatternMeta = {
|
|
|
20
29
|
specialCategories?: Record<string, SpecialCategoryMeta>;
|
|
21
30
|
desiredParent?: string[];
|
|
22
31
|
desiredChildren?: string[];
|
|
32
|
+
mockableFeatures?: Record<string, boolean>;
|
|
33
|
+
/** If true, hide all attributes in the editor except ones with `forceVisible/override`. */
|
|
34
|
+
hideAllAttributes?: boolean;
|
|
23
35
|
};
|
|
24
36
|
type Pattern = {
|
|
25
37
|
schemaVersion: number;
|
|
@@ -34,6 +46,8 @@ type Pattern = {
|
|
|
34
46
|
types?: Record<string, Record<string, string | string[]>>;
|
|
35
47
|
meta?: PatternMeta;
|
|
36
48
|
};
|
|
49
|
+
/** Normalize legacy/variant component type strings to the canonical pattern.type (PascalCase). */
|
|
50
|
+
export declare function normalizeComponentType(type?: string | null): string | undefined;
|
|
37
51
|
export declare function getPatternByType(type?: string | null): Pattern | undefined;
|
|
38
52
|
export declare function getAttributeSchema(type?: string | null): Record<string, string | string[]> | undefined;
|
|
39
53
|
export declare function getAttributeMeta(type?: string | null): Record<string, AttributeMeta> | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function replaceLocalizationParams(text: string, params?: Record<string, string> | null): string;
|
package/package.json
CHANGED
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@developer_tribe/react-builder",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"license": "UNLICENSED",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"restricted": true,
|
|
6
7
|
"main": "dist/index.cjs.js",
|
|
7
8
|
"module": "dist/index.esm.js",
|
|
8
9
|
"types": "dist/index.d.ts",
|
|
10
|
+
"react-native": "dist/index.native.cjs.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"react-native": {
|
|
14
|
+
"types": "./dist/index.native.d.ts",
|
|
15
|
+
"default": "./dist/index.native.cjs.js"
|
|
16
|
+
},
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.esm.js",
|
|
19
|
+
"require": "./dist/index.cjs.js",
|
|
20
|
+
"default": "./dist/index.esm.js"
|
|
21
|
+
},
|
|
22
|
+
"./native": {
|
|
23
|
+
"types": "./dist/index.native.d.ts",
|
|
24
|
+
"default": "./dist/index.native.cjs.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
9
27
|
"files": [
|
|
10
28
|
"dist",
|
|
11
29
|
"src",
|
|
@@ -13,7 +31,7 @@
|
|
|
13
31
|
],
|
|
14
32
|
"scripts": {
|
|
15
33
|
"prebuild": "node ./scripts/prebuild/prebuild.js",
|
|
16
|
-
"build": "rimraf dist && rollup -c",
|
|
34
|
+
"build": "yarn prebuild && yarn rimraf dist && rollup -c",
|
|
17
35
|
"build:watch": "rollup -c -w",
|
|
18
36
|
"lint": "eslint src",
|
|
19
37
|
"format": "prettier --write .",
|
|
@@ -22,6 +40,7 @@
|
|
|
22
40
|
"example:build": "npm --prefix example run build",
|
|
23
41
|
"example:preview": "npm --prefix example run preview",
|
|
24
42
|
"builder": "node ./scripts/public/bin.js",
|
|
43
|
+
"test": "jest",
|
|
25
44
|
"release": "yarn prebuild && yarn build && yarn publish --access restricted"
|
|
26
45
|
},
|
|
27
46
|
"bin": {
|
|
@@ -35,7 +54,7 @@
|
|
|
35
54
|
"@rollup/plugin-json": "^6.1.0",
|
|
36
55
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
37
56
|
"@rollup/plugin-url": "^8.0.2",
|
|
38
|
-
"@
|
|
57
|
+
"@types/jest": "^29.5.14",
|
|
39
58
|
"@types/node": "^22.7.4",
|
|
40
59
|
"@types/react": "^18.3.9",
|
|
41
60
|
"@types/react-dom": "^18.3.0",
|
|
@@ -44,7 +63,7 @@
|
|
|
44
63
|
"eslint-plugin-react": "^7.37.5",
|
|
45
64
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
46
65
|
"globals": "^16.4.0",
|
|
47
|
-
"
|
|
66
|
+
"jest": "^29.7.0",
|
|
48
67
|
"lottie-react": "^2.4.1",
|
|
49
68
|
"prettier": "^3.6.2",
|
|
50
69
|
"react": "^18.3.1",
|
|
@@ -55,6 +74,7 @@
|
|
|
55
74
|
"rollup-plugin-terser": "^7.0.2",
|
|
56
75
|
"rollup-plugin-typescript2": "^0.36.0",
|
|
57
76
|
"sass": "^1.93.2",
|
|
77
|
+
"ts-jest": "^29.2.6",
|
|
58
78
|
"typescript": "^5.9.2",
|
|
59
79
|
"typescript-eslint": "^8.44.1",
|
|
60
80
|
"use-sync-external-store": "^1.6.0",
|
|
@@ -66,9 +86,16 @@
|
|
|
66
86
|
"react-dom": ">=17",
|
|
67
87
|
"react-router-dom": ">=6.0.0"
|
|
68
88
|
},
|
|
89
|
+
"peerDependenciesMeta": {
|
|
90
|
+
"react-dom": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"react-router-dom": {
|
|
94
|
+
"optional": true
|
|
95
|
+
}
|
|
96
|
+
},
|
|
69
97
|
"optionalDependencies": {
|
|
70
|
-
"embla-carousel-react": "
|
|
71
|
-
"json-edit-react": ">=1.29.0"
|
|
98
|
+
"embla-carousel-react": "^8.6.0"
|
|
72
99
|
},
|
|
73
100
|
"engines": {
|
|
74
101
|
"node": ">=18"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
2
|
+
// NOTE: This file is generated. Do not edit it manually.
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import type { CSSProperties, HTMLAttributes } from 'react';
|
|
5
|
+
import type { IconsType } from '../types/Icons';
|
|
6
|
+
|
|
7
|
+
{%properties1}
|
|
8
|
+
|
|
9
|
+
export type IconProps = Omit<HTMLAttributes<HTMLSpanElement>, 'color'> & {
|
|
10
|
+
iconType: IconsType;
|
|
11
|
+
size?: number;
|
|
12
|
+
color?: string;
|
|
13
|
+
strokeWidth?: number;
|
|
14
|
+
title?: string;
|
|
15
|
+
alt?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function applyStrokeWidth(svg: string, strokeWidth: number): string {
|
|
19
|
+
const w = String(strokeWidth);
|
|
20
|
+
// Override any explicit stroke-width values (on paths or root)
|
|
21
|
+
let next = svg.replace(/\bstroke-width="[^"]*"/gi, `stroke-width="${w}"`);
|
|
22
|
+
// If the SVG had no stroke-width at all, add it to the root <svg> tag
|
|
23
|
+
if (next === svg) {
|
|
24
|
+
next = svg.replace(/<svg\b([^>]*?)>/i, (full, attrs) => {
|
|
25
|
+
if (/\bstroke-width=/i.test(attrs)) return full;
|
|
26
|
+
return `<svg${attrs} stroke-width="${w}">`;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return next;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function Icon({
|
|
33
|
+
iconType,
|
|
34
|
+
size = 16,
|
|
35
|
+
color,
|
|
36
|
+
strokeWidth,
|
|
37
|
+
title,
|
|
38
|
+
alt,
|
|
39
|
+
style,
|
|
40
|
+
...rest
|
|
41
|
+
}: IconProps) {
|
|
42
|
+
const sizeStyle: CSSProperties = size
|
|
43
|
+
? { minWidth: size, minHeight: size, width: size, height: size }
|
|
44
|
+
: {};
|
|
45
|
+
const mergedStyle: CSSProperties = {
|
|
46
|
+
display: 'inline-block',
|
|
47
|
+
lineHeight: 0,
|
|
48
|
+
color,
|
|
49
|
+
...sizeStyle,
|
|
50
|
+
...style,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const baseSvg = ICON_SVGS[iconType];
|
|
54
|
+
const svg =
|
|
55
|
+
typeof strokeWidth === 'number' && Number.isFinite(strokeWidth)
|
|
56
|
+
? applyStrokeWidth(baseSvg, strokeWidth)
|
|
57
|
+
: baseSvg;
|
|
58
|
+
if (!svg) return null;
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<span
|
|
62
|
+
role="img"
|
|
63
|
+
aria-label={alt ?? title ?? iconType}
|
|
64
|
+
title={title}
|
|
65
|
+
style={mergedStyle}
|
|
66
|
+
// eslint-disable-next-line react/no-danger
|
|
67
|
+
dangerouslySetInnerHTML={{ __html: svg }}
|
|
68
|
+
{...rest}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -20,6 +20,11 @@ import {
|
|
|
20
20
|
// lintNonGeneratedOrThrow,
|
|
21
21
|
} from './utils/index.js';
|
|
22
22
|
|
|
23
|
+
// TODO: We currently repeat “provider-level” attributes across multiple pattern.json files
|
|
24
|
+
// (e.g. safe-area related flags like `use_safe_area_inset` / `useSafeAreaView`).
|
|
25
|
+
// Consider introducing shared/common attributes (or a shared `Main`/base provider pattern)
|
|
26
|
+
// to keep patterns consistent and avoid drift.
|
|
27
|
+
|
|
23
28
|
const __filename = url.fileURLToPath(import.meta.url);
|
|
24
29
|
const __dirname = path.dirname(__filename);
|
|
25
30
|
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Generates:
|
|
4
|
+
* - `src/types/Icons.ts`
|
|
5
|
+
* - `src/components/Icon.generated.tsx`
|
|
6
|
+
*
|
|
7
|
+
* Based on SVG files under `src/assets/iconset` and template at
|
|
8
|
+
* `scripts/prebuild/assets/icon.template`.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import fs from 'fs/promises';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import url from 'url';
|
|
14
|
+
|
|
15
|
+
const __filename = url.fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = path.dirname(__filename);
|
|
17
|
+
|
|
18
|
+
const PROJECT_ROOT = path.resolve(__dirname, '../..');
|
|
19
|
+
const SRC_ROOT = path.join(PROJECT_ROOT, 'src');
|
|
20
|
+
|
|
21
|
+
const ICONSET_DIR = path.join(SRC_ROOT, 'assets', 'iconset');
|
|
22
|
+
const TEMPLATE_FILE = path.join(__dirname, 'assets', 'icon.template');
|
|
23
|
+
|
|
24
|
+
const OUTPUT_TYPES_FILE = path.join(SRC_ROOT, 'types', 'Icons.ts');
|
|
25
|
+
const OUTPUT_COMPONENT_FILE = path.join(
|
|
26
|
+
SRC_ROOT,
|
|
27
|
+
'components',
|
|
28
|
+
'Icon.generated.tsx'
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
function normalizeSvg(svgText) {
|
|
32
|
+
let svg = String(svgText ?? '').trim();
|
|
33
|
+
if (!svg) return svg;
|
|
34
|
+
|
|
35
|
+
// Remove XML declarations if present
|
|
36
|
+
svg = svg.replace(/<\?xml[\s\S]*?\?>/g, '').trim();
|
|
37
|
+
|
|
38
|
+
// Ensure width/height are controlled by wrapper (100%)
|
|
39
|
+
// Replace existing width/height attributes on the root <svg>
|
|
40
|
+
svg = svg.replace(
|
|
41
|
+
/<svg\b([^>]*?)>/i,
|
|
42
|
+
(full, attrs) => {
|
|
43
|
+
let next = attrs;
|
|
44
|
+
if (/\bwidth="/i.test(next)) {
|
|
45
|
+
next = next.replace(/\bwidth="[^"]*"/i, 'width="100%"');
|
|
46
|
+
} else {
|
|
47
|
+
next += ' width="100%"';
|
|
48
|
+
}
|
|
49
|
+
if (/\bheight="/i.test(next)) {
|
|
50
|
+
next = next.replace(/\bheight="[^"]*"/i, 'height="100%"');
|
|
51
|
+
} else {
|
|
52
|
+
next += ' height="100%"';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// If root explicitly disables stroke, enable it so path-only icons render (e.g. chevrons)
|
|
56
|
+
if (/\bstroke="none"/i.test(next)) {
|
|
57
|
+
next = next.replace(/\bstroke="none"/i, 'stroke="currentColor"');
|
|
58
|
+
} else if (!/\bstroke="/i.test(next)) {
|
|
59
|
+
next += ' stroke="currentColor"';
|
|
60
|
+
} else {
|
|
61
|
+
// Normalize common stroke color values to currentColor on root
|
|
62
|
+
next = next
|
|
63
|
+
.replace(/\bstroke="black"/gi, 'stroke="currentColor"')
|
|
64
|
+
.replace(/\bstroke="#[0-9a-fA-F]{3,8}"/g, 'stroke="currentColor"')
|
|
65
|
+
.replace(/\bstroke="rgb\([^"]+\)"/gi, 'stroke="currentColor"');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Normalize common fill color values to currentColor (keep fill="none")
|
|
69
|
+
next = next
|
|
70
|
+
.replace(/\bfill="black"/gi, 'fill="currentColor"')
|
|
71
|
+
.replace(/\bfill="#[0-9a-fA-F]{3,8}"/g, 'fill="currentColor"')
|
|
72
|
+
.replace(/\bfill="rgb\([^"]+\)"/gi, 'fill="currentColor"');
|
|
73
|
+
|
|
74
|
+
return `<svg${next}>`;
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// Normalize any remaining explicit colors on child elements (keep "none")
|
|
79
|
+
svg = svg
|
|
80
|
+
.replace(/\bstroke="black"/gi, 'stroke="currentColor"')
|
|
81
|
+
.replace(/\bstroke="#[0-9a-fA-F]{3,8}"/g, 'stroke="currentColor"')
|
|
82
|
+
.replace(/\bstroke="rgb\([^"]+\)"/gi, 'stroke="currentColor"')
|
|
83
|
+
.replace(/\bfill="black"/gi, 'fill="currentColor"')
|
|
84
|
+
.replace(/\bfill="#[0-9a-fA-F]{3,8}"/g, 'fill="currentColor"')
|
|
85
|
+
.replace(/\bfill="rgb\([^"]+\)"/gi, 'fill="currentColor"');
|
|
86
|
+
|
|
87
|
+
return svg.trim();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function toIdentifier(iconName) {
|
|
91
|
+
// turns "arrow-right" into "arrowRight" etc; still avoids collisions later
|
|
92
|
+
const parts = iconName
|
|
93
|
+
.split(/[^a-zA-Z0-9]+/g)
|
|
94
|
+
.filter(Boolean)
|
|
95
|
+
.map(p => p.trim());
|
|
96
|
+
if (parts.length === 0) return 'icon';
|
|
97
|
+
const [first, ...rest] = parts;
|
|
98
|
+
const base =
|
|
99
|
+
first.toLowerCase() +
|
|
100
|
+
rest
|
|
101
|
+
.map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
|
|
102
|
+
.join('');
|
|
103
|
+
const safe = base.replace(/[^a-zA-Z0-9_]/g, '');
|
|
104
|
+
if (/^[0-9]/.test(safe)) return `icon${safe}`;
|
|
105
|
+
return safe || 'icon';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function uniqueIdentifiers(iconNames) {
|
|
109
|
+
const used = new Map();
|
|
110
|
+
const out = new Map();
|
|
111
|
+
for (const name of iconNames) {
|
|
112
|
+
const base = toIdentifier(name);
|
|
113
|
+
const count = used.get(base) ?? 0;
|
|
114
|
+
used.set(base, count + 1);
|
|
115
|
+
out.set(name, count === 0 ? base : `${base}${count + 1}`);
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function getIconNames() {
|
|
121
|
+
const entries = await fs.readdir(ICONSET_DIR, { withFileTypes: true });
|
|
122
|
+
const names = entries
|
|
123
|
+
.filter(e => e.isFile())
|
|
124
|
+
.map(e => e.name)
|
|
125
|
+
.filter(n => n.toLowerCase().endsWith('.svg'))
|
|
126
|
+
.map(n => n.slice(0, -'.svg'.length));
|
|
127
|
+
|
|
128
|
+
names.sort((a, b) => a.localeCompare(b));
|
|
129
|
+
return names;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function renderIconsTs(iconNames) {
|
|
133
|
+
const items = iconNames.map(n => ` '${n}',`).join('\n');
|
|
134
|
+
return `// NOTE: This file is generated. Do not edit it manually.
|
|
135
|
+
//TODO: we might use font-icon or something more optimize
|
|
136
|
+
export const Icons = [
|
|
137
|
+
${items}
|
|
138
|
+
] as const;
|
|
139
|
+
|
|
140
|
+
export type IconsType = (typeof Icons)[number];
|
|
141
|
+
`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function renderTemplate(template, iconNames) {
|
|
145
|
+
const entries = await Promise.all(
|
|
146
|
+
iconNames.map(async (iconName) => {
|
|
147
|
+
const svgPath = path.join(ICONSET_DIR, `${iconName}.svg`);
|
|
148
|
+
const raw = await fs.readFile(svgPath, 'utf8');
|
|
149
|
+
const normalized = normalizeSvg(raw);
|
|
150
|
+
return ` '${iconName}': ${JSON.stringify(normalized)},`;
|
|
151
|
+
}),
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const mapBlock =
|
|
155
|
+
`const ICON_SVGS: Record<IconsType, string> = {\n` +
|
|
156
|
+
entries.join('\n') +
|
|
157
|
+
`\n};\n`;
|
|
158
|
+
|
|
159
|
+
return template.replace('{%properties1}', `\n${mapBlock}\n`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function ensureDirForFile(filePath) {
|
|
163
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function writeIfChanged(filePath, content) {
|
|
167
|
+
let existing = null;
|
|
168
|
+
try {
|
|
169
|
+
existing = await fs.readFile(filePath, 'utf8');
|
|
170
|
+
} catch {
|
|
171
|
+
// ignore
|
|
172
|
+
}
|
|
173
|
+
if (existing === content) return false;
|
|
174
|
+
await ensureDirForFile(filePath);
|
|
175
|
+
await fs.writeFile(filePath, content, 'utf8');
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export default async function run() {
|
|
180
|
+
const iconNames = await getIconNames();
|
|
181
|
+
const template = await fs.readFile(TEMPLATE_FILE, 'utf8');
|
|
182
|
+
|
|
183
|
+
const iconsTs = renderIconsTs(iconNames);
|
|
184
|
+
const iconComponentTsx = await renderTemplate(template, iconNames);
|
|
185
|
+
|
|
186
|
+
const wroteTypes = await writeIfChanged(OUTPUT_TYPES_FILE, iconsTs);
|
|
187
|
+
const wroteComponent = await writeIfChanged(
|
|
188
|
+
OUTPUT_COMPONENT_FILE,
|
|
189
|
+
iconComponentTsx
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
return { wroteTypes, wroteComponent, count: iconNames.length };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Allow running directly: `node scripts/prebuild/icon-generator.js`
|
|
196
|
+
if (
|
|
197
|
+
process.argv[1] &&
|
|
198
|
+
path.resolve(process.argv[1]) === path.resolve(__filename)
|
|
199
|
+
) {
|
|
200
|
+
const res = await run();
|
|
201
|
+
console.info(
|
|
202
|
+
`Generated icons (${res.count}) -> types: ${res.wroteTypes ? 'updated' : 'unchanged'}, component: ${
|
|
203
|
+
res.wroteComponent ? 'updated' : 'unchanged'
|
|
204
|
+
}`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import run from './build-components.js';
|
|
4
|
+
import runIconGenerator from './icon-generator.js';
|
|
4
5
|
|
|
5
|
-
console.info('Building components...');
|
|
6
6
|
try {
|
|
7
|
+
console.info('Generating icons...');
|
|
8
|
+
const { count, wroteTypes, wroteComponent } = await runIconGenerator();
|
|
9
|
+
console.info(
|
|
10
|
+
`Generated icons (${count}) -> types: ${
|
|
11
|
+
wroteTypes ? 'updated' : 'unchanged'
|
|
12
|
+
}, component: ${wroteComponent ? 'updated' : 'unchanged'}`
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
console.info('Building components...');
|
|
7
16
|
await run();
|
|
8
17
|
} catch (err) {
|
|
9
18
|
console.error(err?.stack || err?.message || err);
|
|
@@ -11,9 +11,12 @@ export async function createComponentTsx(componentDir, componentName) {
|
|
|
11
11
|
if (exists) return; // Will be validated later
|
|
12
12
|
|
|
13
13
|
const content =
|
|
14
|
-
`import React from 'react';\n
|
|
15
|
-
`
|
|
16
|
-
`
|
|
14
|
+
`import React from 'react';\n` +
|
|
15
|
+
`import type { ${componentName}ComponentProps } from './${componentName}Props.generated';\n` +
|
|
16
|
+
`import useNode from '../useNode';\n\n` +
|
|
17
|
+
`function ${componentName}({ node }: ${componentName}ComponentProps) {\n` +
|
|
18
|
+
` node = useNode(node);\n` +
|
|
19
|
+
` return null;\n` +
|
|
17
20
|
`}\n\n` +
|
|
18
21
|
`export default React.memo(${componentName});\n`;
|
|
19
22
|
const formatted = await formatWithPrettier(content);
|
|
@@ -9,8 +9,10 @@ const isPrimitive = t =>
|
|
|
9
9
|
t === 'number' ||
|
|
10
10
|
t === 'boolean' ||
|
|
11
11
|
t === 'color' ||
|
|
12
|
-
t === 'size'
|
|
13
|
-
|
|
12
|
+
t === 'size' ||
|
|
13
|
+
t === 'iconType';
|
|
14
|
+
const toTsPrimitive = t =>
|
|
15
|
+
t === 'color' || t === 'size' || t === 'iconType' ? 'string' : t;
|
|
14
16
|
const getArrayItem = t =>
|
|
15
17
|
typeof t === 'string' && t.endsWith('[]') ? t.slice(0, -2) : null;
|
|
16
18
|
// Convert a property name like "animation" or "on-press" to PascalCase
|
|
@@ -6,6 +6,10 @@ export async function createRenderNodeGenerated(validated, paths) {
|
|
|
6
6
|
const { COMPONENTS_ROOT } = paths;
|
|
7
7
|
const targetPath = path.join(COMPONENTS_ROOT, 'RenderNode.generated.tsx');
|
|
8
8
|
|
|
9
|
+
const textPatternType =
|
|
10
|
+
validated.find(v => v.componentName === 'Text')?.patternJson?.pattern
|
|
11
|
+
?.type ?? 'Text';
|
|
12
|
+
|
|
9
13
|
// Build imports for all components discovered
|
|
10
14
|
const componentImports = validated
|
|
11
15
|
.map(
|
|
@@ -14,12 +18,30 @@ export async function createRenderNodeGenerated(validated, paths) {
|
|
|
14
18
|
)
|
|
15
19
|
.join('\n');
|
|
16
20
|
|
|
21
|
+
// Import each component's generated prop type so we can build a strongly-typed node union
|
|
22
|
+
const componentPropTypeImports = validated
|
|
23
|
+
.map(
|
|
24
|
+
({ componentName }) =>
|
|
25
|
+
`import type { ${componentName}ComponentProps } from './${componentName}/${componentName}Props.generated';`
|
|
26
|
+
)
|
|
27
|
+
.join('\n');
|
|
28
|
+
|
|
29
|
+
const builderNodeUnion = validated
|
|
30
|
+
.map(({ componentName, patternJson }) => {
|
|
31
|
+
const type = patternJson?.pattern?.type;
|
|
32
|
+
return typeof type === 'string'
|
|
33
|
+
? ` | (${componentName}ComponentProps['node'] & { type: ${JSON.stringify(type)} })`
|
|
34
|
+
: null;
|
|
35
|
+
})
|
|
36
|
+
.filter(Boolean)
|
|
37
|
+
.join('\n');
|
|
38
|
+
|
|
17
39
|
// Build switch cases from each component's pattern.type
|
|
18
40
|
const cases = validated
|
|
19
41
|
.map(({ componentName, patternJson }) => {
|
|
20
42
|
const type = patternJson?.pattern?.type;
|
|
21
43
|
return typeof type === 'string'
|
|
22
|
-
? ` case ${JSON.stringify(type)}:\n return <${componentName} node={
|
|
44
|
+
? ` case ${JSON.stringify(type)}:\n return <${componentName} node={normalizedNode} />;`
|
|
23
45
|
: null;
|
|
24
46
|
})
|
|
25
47
|
.filter(Boolean)
|
|
@@ -28,23 +50,28 @@ export async function createRenderNodeGenerated(validated, paths) {
|
|
|
28
50
|
const fileContent =
|
|
29
51
|
`/* AUTO-GENERATED FILE - DO NOT EDIT */\n` +
|
|
30
52
|
`import React from 'react';\n\n` +
|
|
53
|
+
`import { normalizeComponentType } from '../utils/patterns';\n\n` +
|
|
54
|
+
`import type { Node } from '../types/Node';\n` +
|
|
31
55
|
`import {\n` +
|
|
32
|
-
` Node,\n` +
|
|
33
|
-
` NodeData,\n` +
|
|
34
56
|
` isNodeArray,\n` +
|
|
35
57
|
` isNodeNullOrUndefined,\n` +
|
|
36
58
|
` isNodeString,\n` +
|
|
37
|
-
`} from '../
|
|
59
|
+
`} from '../utils/analyseNode';\n\n` +
|
|
38
60
|
`import { other } from './other';\n\n` +
|
|
39
61
|
`// Builder components\n` +
|
|
62
|
+
componentPropTypeImports +
|
|
63
|
+
`\n` +
|
|
40
64
|
componentImports +
|
|
41
65
|
`\n\n` +
|
|
66
|
+
`type BuilderNode =\n` +
|
|
67
|
+
(builderNodeUnion ? `${builderNodeUnion}\n` : ` never\n`) +
|
|
68
|
+
`;\n\n` +
|
|
42
69
|
`function RenderNode({ node }: { node: Node }) {\n` +
|
|
43
70
|
` if (isNodeNullOrUndefined(node)) {\n` +
|
|
44
71
|
` return null;\n` +
|
|
45
72
|
` }\n` +
|
|
46
73
|
` if (isNodeString(node)) {\n` +
|
|
47
|
-
` return <Text node={{ children: node as string, type:
|
|
74
|
+
` return <Text node={{ children: node as string, type: ${JSON.stringify(textPatternType)} }} />;\n` +
|
|
48
75
|
` }\n` +
|
|
49
76
|
` if (isNodeArray(node)) {\n` +
|
|
50
77
|
` return (\n` +
|
|
@@ -55,11 +82,19 @@ export async function createRenderNodeGenerated(validated, paths) {
|
|
|
55
82
|
` </>\n` +
|
|
56
83
|
` );\n` +
|
|
57
84
|
` }\n\n` +
|
|
58
|
-
` const
|
|
59
|
-
`
|
|
85
|
+
` const nodeType =\n` +
|
|
86
|
+
` typeof (node as { type?: unknown })?.type === 'string'\n` +
|
|
87
|
+
` ? (node as { type: string }).type\n` +
|
|
88
|
+
` : 'unknown';\n` +
|
|
89
|
+
`\n` +
|
|
90
|
+
` const normalizedType = normalizeComponentType(nodeType) ?? nodeType;\n` +
|
|
91
|
+
`\n` +
|
|
92
|
+
` // Force a stable discriminant so TS can narrow the BuilderNode union.\n` +
|
|
93
|
+
` const normalizedNode = { ...(node as any), type: normalizedType } as BuilderNode;\n` +
|
|
94
|
+
` switch (normalizedNode.type) {\n` +
|
|
60
95
|
cases +
|
|
61
96
|
`\n default:\n` +
|
|
62
|
-
` return other(
|
|
97
|
+
` return other(nodeType, node);\n` +
|
|
63
98
|
` }\n` +
|
|
64
99
|
`}\n\n` +
|
|
65
100
|
`export default React.memo(RenderNode);\n`;
|
|
@@ -105,6 +105,11 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
105
105
|
`[${componentName}] pattern.json -> 'pattern.type' must be a string`
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
|
+
if (pattern.type !== componentName) {
|
|
109
|
+
return fail(
|
|
110
|
+
`[${componentName}] pattern.json -> 'pattern.type' must match the component folder name '${componentName}' (PascalCase).`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
108
113
|
if (
|
|
109
114
|
typeof pattern.children !== 'string' &&
|
|
110
115
|
!Array.isArray(pattern.children)
|
|
@@ -125,7 +130,8 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
125
130
|
t === 'number' ||
|
|
126
131
|
t === 'boolean' ||
|
|
127
132
|
t === 'color' ||
|
|
128
|
-
t === 'size'
|
|
133
|
+
t === 'size' ||
|
|
134
|
+
t === 'iconType';
|
|
129
135
|
const isNeverType = t => t === 'never';
|
|
130
136
|
const hasCustomTypes = typeof data.types === 'object' && data.types != null;
|
|
131
137
|
const isCustomType = t =>
|
|
@@ -193,12 +199,18 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
193
199
|
|
|
194
200
|
// Resolve chained extends: walk up the chain, detect cycles, merge from base to child
|
|
195
201
|
const componentsRoot = path.dirname(componentDir);
|
|
196
|
-
|
|
202
|
+
// Track visited folders and visited pattern.type values separately.
|
|
203
|
+
// Because we enforce `pattern.type === component folder name` (PascalCase),
|
|
204
|
+
// mixing them in a single Set can incorrectly flag a "cycle" immediately
|
|
205
|
+
// when a component extends `View`.
|
|
206
|
+
const visitedFolders = new Set();
|
|
207
|
+
const visitedTypes = new Set();
|
|
197
208
|
const ancestorStack = [];
|
|
198
209
|
|
|
199
210
|
// Track both componentName and current type for cycle detection
|
|
200
|
-
|
|
201
|
-
if (typeof data?.pattern?.type === 'string')
|
|
211
|
+
visitedFolders.add(componentName);
|
|
212
|
+
if (typeof data?.pattern?.type === 'string')
|
|
213
|
+
visitedTypes.add(data.pattern.type);
|
|
202
214
|
|
|
203
215
|
let cursor = data;
|
|
204
216
|
// Collect raw ancestors without mutating child yet
|
|
@@ -207,12 +219,12 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
207
219
|
cursor.pattern.extends.trim().length > 0
|
|
208
220
|
) {
|
|
209
221
|
const parentName = cursor.pattern.extends.trim();
|
|
210
|
-
if (
|
|
222
|
+
if (visitedFolders.has(parentName)) {
|
|
211
223
|
return fail(
|
|
212
224
|
`Circular dependency detected in extends chain at '${parentName}'. We don't allow circular dependency.`
|
|
213
225
|
);
|
|
214
226
|
}
|
|
215
|
-
|
|
227
|
+
visitedFolders.add(parentName);
|
|
216
228
|
|
|
217
229
|
const parentDir = path.join(componentsRoot, parentName);
|
|
218
230
|
const parentDirExists = await fs
|
|
@@ -257,14 +269,13 @@ async function validatePatternJson(componentDir, componentName) {
|
|
|
257
269
|
);
|
|
258
270
|
}
|
|
259
271
|
|
|
260
|
-
// Detect cycle by type name too
|
|
261
272
|
const parentType = parentData.pattern.type;
|
|
262
|
-
if (
|
|
273
|
+
if (visitedTypes.has(parentType)) {
|
|
263
274
|
return fail(
|
|
264
275
|
`Circular dependency detected in extends chain via type '${parentType}'. We don't allow circular dependency.`
|
|
265
276
|
);
|
|
266
277
|
}
|
|
267
|
-
|
|
278
|
+
visitedTypes.add(parentType);
|
|
268
279
|
|
|
269
280
|
ancestorStack.push(parentData);
|
|
270
281
|
cursor = parentData;
|
|
@@ -65,7 +65,8 @@ export async function validatePatternJson(componentDir, componentName) {
|
|
|
65
65
|
value === 'number' ||
|
|
66
66
|
value === 'boolean' ||
|
|
67
67
|
value === 'color' ||
|
|
68
|
-
value === 'size'
|
|
68
|
+
value === 'size' ||
|
|
69
|
+
value === 'iconType';
|
|
69
70
|
|
|
70
71
|
for (const [attrName, attrType] of Object.entries(pattern.attributes)) {
|
|
71
72
|
const isValidType =
|
|
@@ -76,7 +77,7 @@ export async function validatePatternJson(componentDir, componentName) {
|
|
|
76
77
|
(Array.isArray(attrType) && attrType.every(v => typeof v === 'string'));
|
|
77
78
|
if (!isValidType) {
|
|
78
79
|
return fail(
|
|
79
|
-
`[${componentName}] pattern.json -> 'pattern.attributes.${attrName}' must be 'string' | 'number' | 'boolean' | 'color' | string[]`
|
|
80
|
+
`[${componentName}] pattern.json -> 'pattern.attributes.${attrName}' must be 'string' | 'number' | 'boolean' | 'color' | 'size' | 'iconType' | string[]`
|
|
80
81
|
);
|
|
81
82
|
}
|
|
82
83
|
}
|
package/src/.DS_Store
ADDED
|
Binary file
|