@developer_tribe/react-builder 0.1.31 → 1.0.1
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/DeviceMockFrame.d.ts +1 -17
- package/dist/RenderPage.d.ts +1 -9
- package/dist/build-components/Button/ButtonProps.generated.d.ts +2 -1
- package/dist/build-components/CarouselButtons/CarouselButtonsProps.generated.d.ts +2 -1
- package/dist/build-components/CarouselDots/CarouselDotsProps.generated.d.ts +2 -1
- package/dist/build-components/Image/ImageProps.generated.d.ts +2 -1
- package/dist/build-components/OnboardButton/OnboardButtonProps.generated.d.ts +8 -4
- package/dist/build-components/OnboardButtons/OnboardButtonsProps.generated.d.ts +6 -3
- package/dist/build-components/OnboardDot/OnboardDotProps.generated.d.ts +2 -1
- package/dist/build-components/OnboardFooter/OnboardFooterProps.generated.d.ts +10 -5
- package/dist/build-components/OnboardImage/OnboardImageProps.generated.d.ts +4 -1
- package/dist/build-components/OnboardItem/OnboardItemProps.generated.d.ts +4 -2
- package/dist/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.d.ts +10 -5
- package/dist/build-components/OnboardTitle/OnboardTitleProps.generated.d.ts +10 -5
- package/dist/build-components/Text/TextProps.generated.d.ts +10 -5
- package/dist/build-components/View/ViewProps.generated.d.ts +6 -3
- package/dist/build-components/index.d.ts +1 -0
- package/dist/build-components/patterns.generated.d.ts +7 -2
- package/dist/components/AttributesEditorPanel.d.ts +9 -0
- package/dist/components/Breadcrumb.d.ts +13 -0
- package/dist/components/Builder.d.ts +9 -0
- package/dist/components/EditorHeader.d.ts +15 -0
- package/dist/index.cjs.js +7 -4
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.esm.js +7 -4
- package/dist/index.esm.js.map +1 -0
- package/dist/pages/ProjectPage.d.ts +11 -0
- package/dist/pages/tabs/BuilderTab.d.ts +9 -0
- package/dist/pages/tabs/DebugTab.d.ts +7 -0
- package/dist/pages/tabs/PreviewTab.d.ts +3 -0
- package/dist/store.d.ts +17 -18
- package/dist/styles.css +1 -1
- package/dist/types/PreviewConfig.d.ts +6 -3
- package/dist/types/Project.d.ts +12 -2
- package/dist/utils/copyNode.d.ts +2 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/useLogRender.d.ts +1 -0
- package/package.json +17 -9
- package/scripts/prebuild/utils/createBuildComponentsIndex.js +15 -1
- package/scripts/prebuild/utils/createGeneratedProps.js +64 -5
- package/src/AttributesEditor.tsx +2 -0
- package/src/DeviceMockFrame.tsx +22 -31
- package/src/RenderPage.tsx +5 -42
- package/src/assets/images/android.svg +43 -0
- package/src/assets/images/apple.svg +16 -0
- package/src/assets/images/background.jpg +0 -0
- package/src/assets/samples/carousel-sample.json +2 -3
- package/src/assets/samples/getSamples.ts +51 -8
- package/src/assets/samples/simple-1.json +1 -2
- package/src/assets/samples/simple-2.json +1 -2
- package/src/assets/samples/vpn-onboard-1.json +1 -2
- package/src/assets/samples/vpn-onboard-2.json +1 -2
- package/src/assets/samples/vpn-onboard-3.json +1 -2
- package/src/assets/samples/vpn-onboard-4.json +1 -2
- package/src/assets/samples/vpn-onboard-5.json +1024 -0
- package/src/assets/samples/vpn-onboard-6.json +708 -0
- package/src/build-components/Button/Button.tsx +2 -0
- package/src/build-components/Button/ButtonProps.generated.ts +14 -12
- package/src/build-components/Carousel/Carousel.tsx +2 -0
- package/src/build-components/CarouselButtons/CarouselButtons.tsx +2 -0
- package/src/build-components/CarouselButtons/CarouselButtonsProps.generated.ts +6 -1
- package/src/build-components/CarouselDots/CarouselDots.tsx +2 -0
- package/src/build-components/CarouselDots/CarouselDotsProps.generated.ts +9 -7
- package/src/build-components/CarouselItem/CarouselItem.tsx +2 -0
- package/src/build-components/Image/Image.tsx +2 -0
- package/src/build-components/Image/ImageProps.generated.ts +3 -1
- package/src/build-components/Onboard/Onboard.tsx +2 -0
- package/src/build-components/OnboardButton/OnboardButton.tsx +7 -4
- package/src/build-components/OnboardButton/OnboardButtonProps.generated.ts +14 -9
- package/src/build-components/OnboardButton/pattern.json +3 -2
- package/src/build-components/OnboardButtons/OnboardButtons.tsx +7 -7
- package/src/build-components/OnboardButtons/OnboardButtonsProps.generated.ts +10 -3
- package/src/build-components/OnboardDot/OnboardDot.tsx +2 -0
- package/src/build-components/OnboardDot/OnboardDotProps.generated.ts +9 -7
- package/src/build-components/OnboardFooter/OnboardFooter.tsx +5 -3
- package/src/build-components/OnboardFooter/OnboardFooterProps.generated.ts +33 -22
- package/src/build-components/OnboardImage/OnboardImage.tsx +26 -1
- package/src/build-components/OnboardImage/OnboardImageProps.generated.ts +5 -1
- package/src/build-components/OnboardImage/pattern.json +3 -5
- package/src/build-components/OnboardItem/OnboardItem.tsx +2 -0
- package/src/build-components/OnboardItem/OnboardItemProps.generated.ts +5 -2
- package/src/build-components/OnboardProvider/OnboardProvider.tsx +2 -0
- package/src/build-components/OnboardSubtitle/OnboardSubtitle.tsx +2 -0
- package/src/build-components/OnboardSubtitle/OnboardSubtitleProps.generated.ts +33 -22
- package/src/build-components/OnboardTitle/OnboardTitle.tsx +2 -0
- package/src/build-components/OnboardTitle/OnboardTitleProps.generated.ts +33 -22
- package/src/build-components/Text/Text.tsx +5 -3
- package/src/build-components/Text/TextProps.generated.ts +33 -22
- package/src/build-components/View/View.tsx +2 -0
- package/src/build-components/View/ViewProps.generated.ts +18 -9
- package/src/build-components/index.ts +22 -0
- package/src/build-components/patterns.generated.ts +7 -2
- package/src/components/AttributesEditorPanel.tsx +112 -0
- package/src/components/Breadcrumb.tsx +48 -0
- package/src/components/Builder.tsx +272 -0
- package/src/components/EditorHeader.tsx +186 -0
- package/src/index.ts +8 -4
- package/src/pages/ProjectPage.tsx +152 -0
- package/src/pages/tabs/BuilderTab.tsx +33 -0
- package/src/pages/tabs/DebugTab.tsx +23 -0
- package/src/pages/tabs/PreviewTab.tsx +194 -0
- package/src/size-matters/index.ts +5 -1
- package/src/store.ts +60 -38
- package/src/styles/_mixins.scss +21 -0
- package/src/styles/_variables.scss +27 -0
- package/src/styles/builder.scss +60 -0
- package/src/styles/components.scss +88 -0
- package/src/styles/editor.scss +174 -0
- package/src/styles/global.scss +200 -0
- package/src/styles/index.scss +7 -0
- package/src/styles/pages.scss +2 -0
- package/src/types/PreviewConfig.ts +14 -5
- package/src/types/Project.ts +15 -2
- package/src/utils/copyNode.ts +7 -0
- package/src/utils/extractTextStyle.ts +4 -2
- package/src/utils/getDevices.ts +1 -0
- package/src/utils/logger.ts +76 -0
- package/src/utils/novaToJson.ts +5 -0
- package/src/utils/useLogRender.ts +13 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Project } from '..';
|
|
2
|
+
import { AppConfig } from '../types/PreviewConfig';
|
|
3
|
+
import type { LogLevel } from '../types/Project';
|
|
4
|
+
export type Tab = 'builder' | 'preview' | 'debug';
|
|
5
|
+
export type ProjectPageProps = {
|
|
6
|
+
project: Project;
|
|
7
|
+
onSaveProject: (project: Project) => void;
|
|
8
|
+
appConfig?: AppConfig;
|
|
9
|
+
logLevel?: LogLevel;
|
|
10
|
+
};
|
|
11
|
+
export declare function ProjectPage({ project, appConfig, onSaveProject, logLevel, }: ProjectPageProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Node } from '../..';
|
|
2
|
+
type BuilderTabProps = {
|
|
3
|
+
data: Node;
|
|
4
|
+
setData: (data: Node) => void;
|
|
5
|
+
current: Node;
|
|
6
|
+
setCurrent: (current: Node) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare function BuilderTab({ data, setData, current, setCurrent, }: BuilderTabProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
package/dist/store.d.ts
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import type { Device } from './types/Device';
|
|
2
|
-
import type
|
|
3
|
-
import {
|
|
2
|
+
import { type AppConfig } from './types/PreviewConfig';
|
|
3
|
+
import { Node } from './types/Node';
|
|
4
|
+
import type { LogEntry, LogLevel } from './types/Project';
|
|
4
5
|
type RenderStore = {
|
|
6
|
+
copiedNode: Node | null;
|
|
7
|
+
setCopiedNode: (node: Node | null) => void;
|
|
5
8
|
device: Device;
|
|
6
|
-
localication: Localication | null;
|
|
7
|
-
defaultLanguage?: string;
|
|
8
|
-
baseSize: {
|
|
9
|
-
width: number;
|
|
10
|
-
height: number;
|
|
11
|
-
};
|
|
12
|
-
theme: 'dark' | 'light';
|
|
13
|
-
screenStyle: ScreenStyle;
|
|
14
|
-
setBaseSize: (baseSize: {
|
|
15
|
-
width: number;
|
|
16
|
-
height: number;
|
|
17
|
-
}) => void;
|
|
18
9
|
setDevice: (device: Device) => void;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
appConfig: AppConfig;
|
|
11
|
+
setAppConfig: (appConfig: AppConfig) => void;
|
|
12
|
+
renderCount: number;
|
|
13
|
+
forceRender: () => void;
|
|
14
|
+
logs: LogEntry[];
|
|
15
|
+
logLevel: LogLevel;
|
|
16
|
+
setLogLevel: (level: LogLevel) => void;
|
|
17
|
+
addLog: (entry: Omit<LogEntry, 'id' | 'timestamp'> & {
|
|
18
|
+
id?: string;
|
|
19
|
+
timestamp?: number;
|
|
20
|
+
}) => void;
|
|
21
|
+
clearLogs: () => void;
|
|
23
22
|
};
|
|
24
23
|
export declare const useRenderStore: import("zustand/traditional").UseBoundStoreWithEqualityFn<import("zustand/vanilla").StoreApi<RenderStore>>;
|
|
25
24
|
export {};
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
*,*::before,*::after{box-sizing:border-box}html,body,#root{height:100%;margin:0;padding:0}body{background:#fff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overflow:hidden}button{font-family:inherit}input,button{font-size:100%}p{margin:0;padding:0}.embla{max-width:48rem;margin:auto;--slide-height: 19rem;--slide-spacing: 1rem;--slide-size: 70%}.embla__viewport{overflow:hidden}.embla__container{display:flex;touch-action:pan-y pinch-zoom;margin-left:calc(var(--slide-spacing)*-1)}.embla__slide{transform:translate3d(0, 0, 0);flex:0 0 var(--slide-size);min-width:0;padding-left:var(--slide-spacing);flex:0 0 100%}.embla__slide__number{box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);border-radius:1.8rem;font-size:4rem;font-weight:600;display:flex;align-items:center;justify-content:center;height:var(--slide-height);user-select:none}.embla__controls{display:grid;grid-template-columns:auto 1fr;justify-content:space-between;gap:1.2rem;margin-top:1.8rem}.embla__buttons{display:grid;grid-template-columns:repeat(2, 1fr);gap:.6rem;align-items:center}.embla__button{-webkit-tap-highlight-color:rgba(var(--text-high-contrast-rgb-value), 0.5);-webkit-appearance:none;appearance:none;background-color:rgba(0,0,0,0);touch-action:manipulation;display:inline-flex;text-decoration:none;cursor:pointer;border:0;padding:0;margin:0;box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);width:3.6rem;height:3.6rem;z-index:1;border-radius:50%;color:var(--text-body);display:flex;align-items:center;justify-content:center}.embla__button:disabled{color:var(--detail-high-contrast)}.embla__button__svg{width:35%;height:35%}.embla__dots{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;margin-right:0;height:50px}.embla__dot{-webkit-tap-highlight-color:rgba(var(--text-high-contrast-rgb-value), 0.5);-webkit-appearance:none;appearance:none;background-color:rgba(0,0,0,0);touch-action:manipulation;display:inline-flex;text-decoration:none;cursor:pointer;border:0;padding:0;margin:0;width:2.6rem;height:2.6rem;display:flex;align-items:center;justify-content:center;border-radius:50%}.embla__dot:after{box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);width:1.4rem;height:1.4rem;border-radius:50%;display:flex;align-items:center;content:""}.embla__dot--selected:after{box-shadow:inset 0 0 0 .2rem var(--text-body)}.carousel-provider{height:100%}.embla{height:100%}.embla__viewport{height:100%;display:flex;flex-direction:column}.embla__container{flex:1}
|
|
1
|
+
*,*::before,*::after{box-sizing:border-box}html,body,#root{height:100%;margin:0;padding:0}body{background:#fff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overflow:hidden}button{font-family:inherit}input,button{font-size:100%}p{margin:0;padding:0}html,body,#root{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol",sans-serif}.editor-container{height:100vh;width:100vw;display:flex;overflow:hidden}.editor-panel-builder{padding:4px 8px}.app-shell{min-height:100vh;display:flex;flex-direction:column}.app-main{flex:1 1 auto;background:#f3f4f6}.page-bg{background:#f3f4f6}.grid-cards{display:grid;grid-template-columns:repeat(auto-fill, minmax(160px, 1fr));gap:16px}.btn-add{height:120px;border:2px dashed #9ca3af;border-radius:12px;background:#fff;cursor:pointer;font-weight:600;color:#111827;transition:border-color .2s ease,transform .1s ease,box-shadow .2s ease;box-shadow:0 1px 2px rgba(0,0,0,.04)}.btn-add:hover{border-color:rgb(127.7932960894,136.7877094972,152.2067039106);transform:translateY(-1px);box-shadow:0 6px 16px rgba(0,0,0,.1)}.split-left{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.25) rgba(0,0,0,0)}.split-left::-webkit-scrollbar{width:8px;height:4px}.split-left{flex:1 1 30%;min-width:0;border-right:1px solid #e5e7eb;overflow:auto}.split-right{position:relative;flex:1 1 45%;min-width:0;max-height:calc(100vh - 120px);overflow:auto}.split-third{flex:1 1 25%;min-width:0;border-right:1px solid #e5e7eb;overflow:auto;max-height:calc(100vh - 120px)}.split-right-background{position:absolute;inset:0;background-size:cover;background-position:center;background-repeat:repeat;background-size:500px auto;opacity:.2}.stage-wrapper{display:flex;justify-content:center;background:#f3f4f6;padding:16px}.stage{background:#fff;border:1px solid #e5e7eb;border-radius:4px;border:1px solid #e5e7eb}.stage .scroll-container::-webkit-scrollbar{width:8px;height:8px}.stage .scroll-container::-webkit-scrollbar-track{background:rgba(0,0,0,0)}.stage .scroll-container::-webkit-scrollbar-thumb{background:rgba(0,0,0,.25);border-radius:8px}.stage .scroll-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.25) rgba(0,0,0,0)}.app-header{position:sticky;top:0;z-index:10;background:#fff;border-bottom:1px solid #e5e7eb;height:60px;padding:0 16px;display:flex;align-items:center;justify-content:space-between}.app-header a{color:#111827;text-decoration:none}.app-header__brand{font-weight:700}.app-header__nav{display:flex;gap:16px}.warning{color:#ef4444;font-size:12px;font-weight:600;margin-bottom:16px}.breadcrumb{display:block;font-size:12px;color:#9ca3af}.breadcrumb__list{list-style:none;padding:0;margin:0;display:flex;align-items:center;gap:8px}.breadcrumb__item{display:inline-flex;align-items:center}.breadcrumb__separator{color:#e5e7eb;margin:0 4px}.breadcrumb__link{color:#111827;text-decoration:none}.breadcrumb__link:hover{text-decoration:underline}.breadcrumb__current{color:#9ca3af}.editor-controls{display:grid;grid-template-columns:auto 1fr;gap:12px;padding:16px}.editor-section{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:16px}.form-row{display:grid;grid-template-columns:160px 1fr;align-items:center;gap:12px;margin-bottom:12px}.form-actions{display:flex;gap:12px;margin-top:16px}.btn{padding:8px 12px;border-radius:8px;border:1px solid #e5e7eb;background:#fff;cursor:pointer;transition:background .2s ease,box-shadow .2s ease}.btn:hover{background:#f9fafb;box-shadow:0 6px 16px rgba(0,0,0,.06)}.input{display:inline-flex;align-items:center;height:32px;padding:0 8px;border:1px solid #e5e7eb;border-radius:12px;background:#fff;color:#111827;font:inherit;outline:none;transition:border-color .15s ease,box-shadow .15s ease}.input:focus{border-color:hsl(220,13.0434782609%,82.9803921569%);box-shadow:0 0 0 3px rgba(0,0,0,.04)}.input--color{padding:0;width:40px;height:28px;border-radius:6px;cursor:pointer}.input--color::-webkit-color-swatch-wrapper{padding:0}.input--color::-webkit-color-swatch{border:none;border-radius:4px}.input--color::-moz-color-swatch{border:none;border-radius:4px}.builder{display:flex;flex-direction:column;gap:12px}.builder__breadcrumbs{display:flex;flex-direction:row;gap:8px}.builder__breadcrumb{color:#9ca3af;font-size:12px}.builder__current{font-weight:600}.builder__list{display:flex;flex-wrap:wrap;gap:8px}.builder__button{background:#fff;border:1px solid #e5e7eb;border-radius:4px;padding:12px 12px;font-size:14px;background:#6495ed;color:#fff;cursor:pointer}.builder__node{background:#fff;border:1px solid #e5e7eb;border-radius:4px;padding:12px}.builder__node-type{margin:0 0 8px 0;font-weight:600}.builder__children{display:flex;flex-direction:column;gap:8px}.builder__text,.builder__placeholder{color:#9ca3af;font-size:12px}.editor-tabs{display:flex;gap:8px;border-bottom:1px solid #e5e7eb}.editor-tab{padding:8px 12px;cursor:pointer;border:1px solid rgba(0,0,0,0);border-top-left-radius:4px;border-top-right-radius:4px;color:#111827;padding:8px 12px}.editor-tab--active{background:#fff;border-color:#e5e7eb #e5e7eb #fff #e5e7eb}.editor-panels{padding:12px}.editor-panels.editor-panels-debug{padding:0}.jer-editor-container{padding-left:0 !important;padding-right:0 !important}.editor-panel{display:none}.editor-panel--active{display:block}.editor-header{display:flex;align-items:center;gap:12px;padding:0 16px;height:60px;background:#f9fafb;border-bottom:1px solid #e5e7eb}.editor-header__title{color:#111827;font-weight:600}.editor-header__devices{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.25) rgba(0,0,0,0)}.editor-header__devices::-webkit-scrollbar{width:8px;height:4px}.editor-header__devices{display:flex;flex-direction:row;align-items:stretch;gap:8px;overflow:auto;height:60px;padding:4px}.editor-device-button{position:relative;min-width:160px;height:100%;border:1px solid #e5e7eb;border-radius:6px;background:#fff;color:#111827;cursor:pointer;font-size:12px}.editor-device-button.editor-device-button--selected{border-color:#000}.editor-device-button img{position:absolute;bottom:4px;right:4px;width:16px;height:16px}.editor-header__actions{margin-left:auto;display:flex;align-items:center;gap:8px}.editor-button{display:inline-flex;align-items:center;justify-content:center;height:36px;min-width:120px;padding:0 12px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;color:#111827;cursor:pointer}.editor-button:disabled{opacity:.6;cursor:default}.editor-save-button,.editor-save-previewconfig-button{color:#000;font-weight:600;font-size:12px}.editor-modal{position:fixed;inset:0;z-index:1000}.editor-modal__overlay{position:absolute;inset:0;background:rgba(0,0,0,.4)}.editor-modal__content{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background:#fff;border-radius:8px;box-shadow:0 10px 30px rgba(0,0,0,.2);width:min(960px,100vw - 40px);max-height:calc(100vh - 120px);display:flex;flex-direction:column}.editor-modal__header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #e5e7eb}.editor-device-grid{padding:16px;display:grid;grid-template-columns:repeat(auto-fill, minmax(180px, 1fr));gap:12px;overflow:auto}.editor-device-grid .editor-device-button{height:80px;min-width:unset}.embla{max-width:48rem;margin:auto;--slide-height: 19rem;--slide-spacing: 1rem;--slide-size: 70%}.embla__viewport{overflow:hidden}.embla__container{display:flex;touch-action:pan-y pinch-zoom;margin-left:calc(var(--slide-spacing)*-1)}.embla__slide{transform:translate3d(0, 0, 0);flex:0 0 var(--slide-size);min-width:0;padding-left:var(--slide-spacing);flex:0 0 100%}.embla__slide__number{box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);border-radius:1.8rem;font-size:4rem;font-weight:600;display:flex;align-items:center;justify-content:center;height:var(--slide-height);user-select:none}.embla__controls{display:grid;grid-template-columns:auto 1fr;justify-content:space-between;gap:1.2rem;margin-top:1.8rem}.embla__buttons{display:grid;grid-template-columns:repeat(2, 1fr);gap:.6rem;align-items:center}.embla__button{-webkit-tap-highlight-color:rgba(var(--text-high-contrast-rgb-value), 0.5);-webkit-appearance:none;appearance:none;background-color:rgba(0,0,0,0);touch-action:manipulation;display:inline-flex;text-decoration:none;cursor:pointer;border:0;padding:0;margin:0;box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);width:3.6rem;height:3.6rem;z-index:1;border-radius:50%;color:var(--text-body);display:flex;align-items:center;justify-content:center}.embla__button:disabled{color:var(--detail-high-contrast)}.embla__button__svg{width:35%;height:35%}.embla__dots{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;margin-right:0;height:50px}.embla__dot{-webkit-tap-highlight-color:rgba(var(--text-high-contrast-rgb-value), 0.5);-webkit-appearance:none;appearance:none;background-color:rgba(0,0,0,0);touch-action:manipulation;display:inline-flex;text-decoration:none;cursor:pointer;border:0;padding:0;margin:0;width:2.6rem;height:2.6rem;display:flex;align-items:center;justify-content:center;border-radius:50%}.embla__dot:after{box-shadow:inset 0 0 0 .2rem var(--detail-medium-contrast);width:1.4rem;height:1.4rem;border-radius:50%;display:flex;align-items:center;content:""}.embla__dot--selected:after{box-shadow:inset 0 0 0 .2rem var(--text-body)}.carousel-provider{height:100%}.embla{height:100%}.embla__viewport{height:100%;display:flex;flex-direction:column}.embla__container{flex:1}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export interface PreviewConfig {
|
|
1
|
+
export interface AppConfig {
|
|
3
2
|
theme: 'light' | 'dark';
|
|
4
|
-
screenSize: TargetedScreenSize;
|
|
5
3
|
isRtl: boolean;
|
|
6
4
|
screenStyle: {
|
|
7
5
|
light: {
|
|
@@ -17,7 +15,12 @@ export interface PreviewConfig {
|
|
|
17
15
|
};
|
|
18
16
|
localication: Localication;
|
|
19
17
|
defaultLanguage?: string;
|
|
18
|
+
baseSize: {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
};
|
|
20
22
|
}
|
|
23
|
+
export declare const defaultAppConfig: AppConfig;
|
|
21
24
|
export type Localication = {
|
|
22
25
|
[key: string]: {
|
|
23
26
|
[key: string]: string;
|
package/dist/types/Project.d.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { Node } from '../types/Node';
|
|
2
|
-
import {
|
|
2
|
+
import { AppConfig } from './PreviewConfig';
|
|
3
3
|
export interface ProjectBase<T> {
|
|
4
4
|
name: string;
|
|
5
5
|
version: string;
|
|
6
6
|
data: T;
|
|
7
|
-
|
|
7
|
+
appConfig?: AppConfig;
|
|
8
8
|
}
|
|
9
9
|
export interface Project extends ProjectBase<Node> {
|
|
10
10
|
}
|
|
11
|
+
export type LogLevel = 'NONE' | 'ERROR' | 'WARN' | 'INFO' | 'VERBOSE';
|
|
12
|
+
export type LogSource = string;
|
|
13
|
+
export interface LogEntry {
|
|
14
|
+
id: string;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
level: LogLevel;
|
|
17
|
+
source: LogSource;
|
|
18
|
+
message: string;
|
|
19
|
+
payload?: unknown;
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LogLevel, LogSource } from '../types/Project';
|
|
2
|
+
export declare const logger: {
|
|
3
|
+
setLevel(level: LogLevel): void;
|
|
4
|
+
log(level: LogLevel, source: LogSource, message: string, payload?: unknown): void;
|
|
5
|
+
verbose(source: LogSource, message: string, payload?: unknown): void;
|
|
6
|
+
info(source: LogSource, message: string, payload?: unknown): void;
|
|
7
|
+
warn(source: LogSource, message: string, payload?: unknown): void;
|
|
8
|
+
error(source: LogSource, message: string, payload?: unknown): void;
|
|
9
|
+
clear(): void;
|
|
10
|
+
};
|
|
11
|
+
export type { LogLevel };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useLogRender(sourceName: string, payload?: unknown): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@developer_tribe/react-builder",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"restricted": true,
|
|
6
6
|
"main": "dist/index.cjs.js",
|
|
@@ -27,24 +27,24 @@
|
|
|
27
27
|
"bin": {
|
|
28
28
|
"builder": "./scripts/public/bin.js"
|
|
29
29
|
},
|
|
30
|
-
"peerDependencies": {
|
|
31
|
-
"react": ">=17",
|
|
32
|
-
"react-dom": ">=17"
|
|
33
|
-
},
|
|
34
30
|
"devDependencies": {
|
|
35
31
|
"@eslint/compat": "^1.4.0",
|
|
36
32
|
"@eslint/eslintrc": "^3.3.1",
|
|
37
33
|
"@eslint/js": "^9.36.0",
|
|
38
34
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
35
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
39
36
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
40
37
|
"@svgr/rollup": "^8.1.0",
|
|
41
38
|
"@types/node": "^22.7.4",
|
|
42
39
|
"@types/react": "^18.3.9",
|
|
43
40
|
"@types/react-dom": "^18.3.0",
|
|
41
|
+
"embla-carousel-react": "^8.6.0",
|
|
44
42
|
"eslint": "^9.36.0",
|
|
45
43
|
"eslint-plugin-react": "^7.37.5",
|
|
46
44
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
47
45
|
"globals": "^16.4.0",
|
|
46
|
+
"json-edit-react": "^1.29.0",
|
|
47
|
+
"lottie-react": "^2.4.1",
|
|
48
48
|
"prettier": "^3.6.2",
|
|
49
49
|
"react": "^18.3.1",
|
|
50
50
|
"rimraf": "^6.0.1",
|
|
@@ -57,7 +57,17 @@
|
|
|
57
57
|
"typescript": "^5.9.2",
|
|
58
58
|
"typescript-eslint": "^8.44.1",
|
|
59
59
|
"use-sync-external-store": "^1.6.0",
|
|
60
|
-
"yargs": "^18.0.0"
|
|
60
|
+
"yargs": "^18.0.0",
|
|
61
|
+
"zustand": "^5.0.8"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"react": ">=17",
|
|
65
|
+
"react-dom": ">=17",
|
|
66
|
+
"react-router-dom": ">=6.0.0"
|
|
67
|
+
},
|
|
68
|
+
"optionalDependencies": {
|
|
69
|
+
"embla-carousel-react": ">=8.6.0",
|
|
70
|
+
"json-edit-react": ">=1.29.0"
|
|
61
71
|
},
|
|
62
72
|
"engines": {
|
|
63
73
|
"node": ">=18"
|
|
@@ -66,8 +76,6 @@
|
|
|
66
76
|
"access": "public"
|
|
67
77
|
},
|
|
68
78
|
"dependencies": {
|
|
69
|
-
"
|
|
70
|
-
"embla-carousel-react": "^8.6.0",
|
|
71
|
-
"zustand": "^5.0.8"
|
|
79
|
+
"axios": "^1.12.2"
|
|
72
80
|
}
|
|
73
81
|
}
|
|
@@ -18,7 +18,21 @@ export async function createBuildComponentsIndex(validated, paths) {
|
|
|
18
18
|
|
|
19
19
|
const patternsExport = `export { patterns } from './patterns.generated';`;
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
// Export array of all component names derived from pattern.type
|
|
22
|
+
const allComponentNames = validated
|
|
23
|
+
.map(({ patternJson }) => patternJson?.pattern?.type)
|
|
24
|
+
.filter(t => typeof t === 'string');
|
|
25
|
+
const allcomponentNamesExport =
|
|
26
|
+
`export const allcomponentNames = [\n ` +
|
|
27
|
+
allComponentNames.map(t => JSON.stringify(t)).join(', ') +
|
|
28
|
+
`\n] as const;`;
|
|
29
|
+
|
|
30
|
+
const sections = [
|
|
31
|
+
renderNodeExport,
|
|
32
|
+
patternsExport,
|
|
33
|
+
allcomponentNamesExport,
|
|
34
|
+
exportLines,
|
|
35
|
+
]
|
|
22
36
|
.filter(Boolean)
|
|
23
37
|
.join('\n\n');
|
|
24
38
|
|
|
@@ -7,15 +7,43 @@ import { formatWithPrettier } from './formatWithPrettier.js';
|
|
|
7
7
|
const isPrimitive = t => t === 'string' || t === 'number' || t === 'boolean';
|
|
8
8
|
const getArrayItem = t =>
|
|
9
9
|
typeof t === 'string' && t.endsWith('[]') ? t.slice(0, -2) : null;
|
|
10
|
+
// Convert a property name like "animation" or "on-press" to PascalCase
|
|
11
|
+
const toPascalCase = s =>
|
|
12
|
+
String(s)
|
|
13
|
+
.replace(/([A-Z]+)/g, ' $1')
|
|
14
|
+
.split(/[^a-zA-Z0-9]+|\s+/)
|
|
15
|
+
.filter(Boolean)
|
|
16
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
17
|
+
.join('');
|
|
10
18
|
|
|
11
19
|
// Convert attribute type spec to TS type. Supports enum arrays, primitives, CustomType, and CustomType[]
|
|
12
|
-
|
|
20
|
+
// If an enum array is detected, "registerEnumAlias" will be called to create an exported alias
|
|
21
|
+
function tsTypeFromAttributeType(
|
|
22
|
+
attrType,
|
|
23
|
+
allTypes,
|
|
24
|
+
propertyName,
|
|
25
|
+
registerEnumAlias
|
|
26
|
+
) {
|
|
13
27
|
if (attrType === 'string') return 'string';
|
|
14
28
|
if (attrType === 'number') return 'number';
|
|
15
29
|
if (attrType === 'boolean') return 'boolean';
|
|
16
30
|
if (Array.isArray(attrType)) {
|
|
17
|
-
const
|
|
18
|
-
|
|
31
|
+
const rawMembers = attrType;
|
|
32
|
+
if (rawMembers.length === 0) return 'string';
|
|
33
|
+
const hasNull = rawMembers.some(v => v === 'null');
|
|
34
|
+
const nonNullMembers = rawMembers.filter(v => v !== 'null');
|
|
35
|
+
const nonNullLiteralMembers = nonNullMembers.map(v => JSON.stringify(v));
|
|
36
|
+
|
|
37
|
+
// Only null specified
|
|
38
|
+
if (hasNull && nonNullLiteralMembers.length === 0) return 'null';
|
|
39
|
+
|
|
40
|
+
if (typeof registerEnumAlias === 'function' && propertyName) {
|
|
41
|
+
const alias = registerEnumAlias(propertyName, nonNullLiteralMembers);
|
|
42
|
+
return hasNull ? `${alias} | null` : alias;
|
|
43
|
+
}
|
|
44
|
+
// Fallback if no registrar provided
|
|
45
|
+
const baseUnion = nonNullLiteralMembers.join(' | ');
|
|
46
|
+
return hasNull ? `${baseUnion} | null` : baseUnion;
|
|
19
47
|
}
|
|
20
48
|
if (typeof attrType === 'string') {
|
|
21
49
|
const item = getArrayItem(attrType);
|
|
@@ -44,11 +72,36 @@ export async function createGeneratedProps(
|
|
|
44
72
|
const attributes = pattern.attributes || {};
|
|
45
73
|
const allTypes = patternJson.types || {};
|
|
46
74
|
|
|
75
|
+
// Collect option type aliases for any enum arrays encountered across attributes and custom types
|
|
76
|
+
const optionAliases = new Map(); // name -> union (string like `'a' | 'b'`)
|
|
77
|
+
const registerEnumAlias = (propName, literalMembers) => {
|
|
78
|
+
const base = `${toPascalCase(propName)}OptionType`;
|
|
79
|
+
const union = literalMembers.join(' | ');
|
|
80
|
+
if (!optionAliases.has(base)) {
|
|
81
|
+
optionAliases.set(base, union);
|
|
82
|
+
return base;
|
|
83
|
+
}
|
|
84
|
+
const existing = optionAliases.get(base);
|
|
85
|
+
if (existing === union) return base;
|
|
86
|
+
let i = 2;
|
|
87
|
+
// find a non-conflicting alias name
|
|
88
|
+
// eslint-disable-next-line no-constant-condition
|
|
89
|
+
while (true) {
|
|
90
|
+
const candidate = `${base}${i}`;
|
|
91
|
+
if (!optionAliases.has(candidate)) {
|
|
92
|
+
optionAliases.set(candidate, union);
|
|
93
|
+
return candidate;
|
|
94
|
+
}
|
|
95
|
+
if (optionAliases.get(candidate) === union) return candidate;
|
|
96
|
+
i += 1;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
47
100
|
// Emit custom type interfaces if present
|
|
48
101
|
const customTypeEntries = Object.entries(allTypes);
|
|
49
102
|
const customTypeBlocks = customTypeEntries.map(([typeName, schema]) => {
|
|
50
103
|
const fields = Object.entries(schema).map(([k, t]) => {
|
|
51
|
-
const tsType = tsTypeFromAttributeType(t, allTypes);
|
|
104
|
+
const tsType = tsTypeFromAttributeType(t, allTypes, k, registerEnumAlias);
|
|
52
105
|
return ` ${k}?: ${tsType};`;
|
|
53
106
|
});
|
|
54
107
|
return (
|
|
@@ -59,7 +112,7 @@ export async function createGeneratedProps(
|
|
|
59
112
|
});
|
|
60
113
|
|
|
61
114
|
const attributeLines = Object.entries(attributes).map(([key, t]) => {
|
|
62
|
-
const tsType = tsTypeFromAttributeType(t, allTypes);
|
|
115
|
+
const tsType = tsTypeFromAttributeType(t, allTypes, key, registerEnumAlias);
|
|
63
116
|
return ` ${key}?: ${tsType};`;
|
|
64
117
|
});
|
|
65
118
|
|
|
@@ -81,6 +134,12 @@ export async function createGeneratedProps(
|
|
|
81
134
|
// Re-export a component props helper to avoid repeating the local type in each component file
|
|
82
135
|
`import type { NodeData } from '../../types/Node';\n` +
|
|
83
136
|
`\n` +
|
|
137
|
+
// Export per-property option types for enum arrays
|
|
138
|
+
(optionAliases.size
|
|
139
|
+
? Array.from(optionAliases.entries())
|
|
140
|
+
.map(([name, union]) => `export type ${name} = ${union};`)
|
|
141
|
+
.join('\n') + '\n\n'
|
|
142
|
+
: '') +
|
|
84
143
|
(customTypeBlocks.length ? customTypeBlocks.join('\n') + '\n' : '') +
|
|
85
144
|
`\n` +
|
|
86
145
|
`export interface ${componentName}PropsGenerated {\n` +
|
package/src/AttributesEditor.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Node, NodeData, NodeDefaultAttribute } from './types/Node';
|
|
3
3
|
import { isNodeString } from './utils/analyseNode';
|
|
4
|
+
import { useLogRender } from './utils/useLogRender';
|
|
4
5
|
import {
|
|
5
6
|
getAttributeSchema,
|
|
6
7
|
getTypeSchema,
|
|
@@ -306,6 +307,7 @@ function Field({
|
|
|
306
307
|
}
|
|
307
308
|
|
|
308
309
|
export function AttributesEditor({ node, onChange }: AttributesEditorProps) {
|
|
310
|
+
useLogRender('AttributesEditor');
|
|
309
311
|
if (!node || isNodeString(node)) return null;
|
|
310
312
|
const data = node as NodeData<NodeDefaultAttribute>;
|
|
311
313
|
const schema = getAttributeSchema(data?.type) ?? {};
|
package/src/DeviceMockFrame.tsx
CHANGED
|
@@ -1,29 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useRenderStore } from './store';
|
|
3
|
+
import { useLogRender } from './utils/useLogRender';
|
|
3
4
|
|
|
4
5
|
type DeviceMockFrameProps = {
|
|
5
|
-
width: number;
|
|
6
|
-
height: number;
|
|
7
|
-
isRtl: boolean;
|
|
8
|
-
screenStyle: {
|
|
9
|
-
light: { backgroundColor: string; color: string };
|
|
10
|
-
dark: { backgroundColor: string; color: string };
|
|
11
|
-
};
|
|
12
|
-
theme: 'dark' | 'light';
|
|
13
6
|
children: React.ReactNode;
|
|
14
|
-
device: Device;
|
|
15
7
|
};
|
|
16
8
|
|
|
17
|
-
export function DeviceMockFrame({
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
device,
|
|
25
|
-
}: DeviceMockFrameProps) {
|
|
26
|
-
const isDark = theme === 'dark';
|
|
9
|
+
export function DeviceMockFrame({ children }: DeviceMockFrameProps) {
|
|
10
|
+
useLogRender('DeviceMockFrame');
|
|
11
|
+
const { appConfig, device } = useRenderStore((s) => ({
|
|
12
|
+
appConfig: s.appConfig,
|
|
13
|
+
device: s.device,
|
|
14
|
+
}));
|
|
15
|
+
const isDark = appConfig.theme === 'dark';
|
|
27
16
|
const [insetTop, insetRight, insetBottom, insetLeft] = device.insets ?? [
|
|
28
17
|
0, 0, 0, 0,
|
|
29
18
|
];
|
|
@@ -58,22 +47,24 @@ export function DeviceMockFrame({
|
|
|
58
47
|
<div
|
|
59
48
|
className="stage"
|
|
60
49
|
style={{
|
|
61
|
-
width: width,
|
|
62
|
-
height: height,
|
|
63
|
-
minWidth: width,
|
|
64
|
-
maxWidth: width,
|
|
65
|
-
minHeight: height,
|
|
66
|
-
maxHeight: height,
|
|
50
|
+
width: device.width,
|
|
51
|
+
height: device.height,
|
|
52
|
+
minWidth: device.width,
|
|
53
|
+
maxWidth: device.width,
|
|
54
|
+
minHeight: device.height,
|
|
55
|
+
maxHeight: device.height,
|
|
67
56
|
overflow: 'hidden',
|
|
68
57
|
position: 'relative',
|
|
69
58
|
padding: 4,
|
|
70
|
-
direction: isRtl ? 'rtl' : 'ltr',
|
|
59
|
+
direction: appConfig.isRtl ? 'rtl' : 'ltr',
|
|
71
60
|
backgroundColor:
|
|
72
|
-
theme === 'dark'
|
|
73
|
-
? screenStyle.dark.backgroundColor
|
|
74
|
-
: screenStyle.light.backgroundColor,
|
|
61
|
+
appConfig.theme === 'dark'
|
|
62
|
+
? appConfig.screenStyle.dark.backgroundColor
|
|
63
|
+
: appConfig.screenStyle.light.backgroundColor,
|
|
75
64
|
color:
|
|
76
|
-
theme === 'dark'
|
|
65
|
+
appConfig.theme === 'dark'
|
|
66
|
+
? appConfig.screenStyle.dark.color
|
|
67
|
+
: appConfig.screenStyle.light.color,
|
|
77
68
|
display: 'flex',
|
|
78
69
|
flexDirection: 'column',
|
|
79
70
|
borderRadius: device.radius ?? 0,
|
package/src/RenderPage.tsx
CHANGED
|
@@ -1,33 +1,18 @@
|
|
|
1
|
-
import { Localication } from './types/PreviewConfig';
|
|
2
|
-
import { TargetedScreenSize } from './types/TargetedScreenSize';
|
|
3
1
|
import { DeviceMockFrame } from './DeviceMockFrame';
|
|
4
2
|
import { Node } from './types/Node';
|
|
5
3
|
import { RenderNode } from './build-components';
|
|
6
|
-
import { Device } from './types/Device';
|
|
7
|
-
import { useEffect } from 'react';
|
|
8
4
|
import { useRenderStore } from './store';
|
|
5
|
+
import { useLogRender } from './utils/useLogRender';
|
|
9
6
|
export type ScreenStyle = {
|
|
10
7
|
light: { backgroundColor: string; color: string; seperatorColor?: string };
|
|
11
8
|
dark: { backgroundColor: string; color: string; seperatorColor?: string };
|
|
12
9
|
};
|
|
13
10
|
type RenderPageProps = {
|
|
14
11
|
data: Node;
|
|
15
|
-
isRtl: boolean;
|
|
16
|
-
screenStyle: ScreenStyle;
|
|
17
|
-
theme: 'dark' | 'light';
|
|
18
|
-
localication: Localication;
|
|
19
|
-
defaultLanguage?: string;
|
|
20
|
-
device: Device;
|
|
21
12
|
};
|
|
22
|
-
export function RenderPage({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
isRtl,
|
|
26
|
-
screenStyle,
|
|
27
|
-
localication,
|
|
28
|
-
defaultLanguage,
|
|
29
|
-
device,
|
|
30
|
-
}: RenderPageProps) {
|
|
13
|
+
export function RenderPage({ data }: RenderPageProps) {
|
|
14
|
+
useLogRender('RenderPage');
|
|
15
|
+
const { device } = useRenderStore((s) => ({ device: s.device }));
|
|
31
16
|
const screenPreviewHeight = 800;
|
|
32
17
|
// The calculation is correct for maintaining the aspect ratio of the target screen size.
|
|
33
18
|
// It scales the width proportionally to a fixed preview height.
|
|
@@ -35,30 +20,8 @@ export function RenderPage({
|
|
|
35
20
|
const height = screenPreviewHeight;
|
|
36
21
|
const width = (height * device.width) / device.height;
|
|
37
22
|
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
const {
|
|
40
|
-
setDevice,
|
|
41
|
-
setLocalication,
|
|
42
|
-
setDefaultLanguage,
|
|
43
|
-
setTheme,
|
|
44
|
-
setScreenStyle,
|
|
45
|
-
} = useRenderStore.getState();
|
|
46
|
-
setDevice(device);
|
|
47
|
-
setLocalication(localication);
|
|
48
|
-
setDefaultLanguage(defaultLanguage);
|
|
49
|
-
setTheme(theme);
|
|
50
|
-
setScreenStyle(screenStyle);
|
|
51
|
-
}, [device, localication, defaultLanguage, theme, screenStyle]);
|
|
52
|
-
|
|
53
23
|
return (
|
|
54
|
-
<DeviceMockFrame
|
|
55
|
-
width={width}
|
|
56
|
-
height={height}
|
|
57
|
-
isRtl={isRtl}
|
|
58
|
-
screenStyle={screenStyle}
|
|
59
|
-
theme={theme}
|
|
60
|
-
device={device}
|
|
61
|
-
>
|
|
24
|
+
<DeviceMockFrame>
|
|
62
25
|
<RenderNode node={data} />
|
|
63
26
|
</DeviceMockFrame>
|
|
64
27
|
);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
4
|
+
viewBox="0 0 502.857 502.857" xml:space="preserve">
|
|
5
|
+
<g>
|
|
6
|
+
<path style="fill:#57C927;" d="M115.428,155.433v217.664c0,17,10.208,30.336,27.704,30.336h22.84c-0.784,0-2.544,5.768-2.544,8.6
|
|
7
|
+
v61.648c0,16.112,15.448,29.176,32,29.176c16.56,0,32-13.064,32-29.176v-61.648c0-2.832-3.088-8.6-3.848-8.6h55.712
|
|
8
|
+
c-0.76,0-3.864,5.768-3.864,8.6v61.648c0,16.112,15.416,29.176,31.968,29.176c16.592,0,32.032-13.064,32.032-29.176v-61.648
|
|
9
|
+
c0-2.832-1.752-8.6-2.536-8.6h22.872c17.496,0,27.664-13.336,27.664-30.336V155.433H113.596H115.428z"/>
|
|
10
|
+
<path style="fill:#57C927;" d="M59.428,158.977c-16.568,0-32,13.072-32,29.176v124.92c0,16.112,15.432,29.176,32,29.176
|
|
11
|
+
c16.56,0,32-13.064,32-29.176V188.161C91.428,172.049,75.988,158.977,59.428,158.977z"/>
|
|
12
|
+
<path style="fill:#57C927;" d="M320.3,42.057l5.584-8.192l5.592-8.096l12.456-18.2c1.56-2.256,0.912-5.264-1.384-6.744
|
|
13
|
+
c-2.272-1.512-5.416-0.88-6.904,1.36l-19.016,27.704l-5.72,8.344c-18.072-6.832-38.208-10.64-59.48-10.64
|
|
14
|
+
c-21.224,0-41.4,3.816-59.472,10.64l-5.688-8.336l-5.624-8.184l-13.36-19.512c-1.544-2.248-4.648-2.84-6.952-1.36
|
|
15
|
+
c-2.28,1.488-2.912,4.496-1.392,6.744l12.448,18.208l5.592,8.104l5.616,8.168c-42.432,19.24-71.144,57.368-71.144,97.368h279.96
|
|
16
|
+
C391.412,99.433,362.708,61.305,320.3,42.057z M191.436,100.593c-8.312,0-15.008-6.536-15.008-14.608s6.696-14.576,15.008-14.576
|
|
17
|
+
c8.288,0,15,6.504,15,14.576S199.732,100.593,191.436,100.593z M311.436,100.593c-8.304,0-15.016-6.536-15.016-14.608
|
|
18
|
+
s6.712-14.576,15.016-14.576c8.288,0,15,6.504,15,14.576S319.724,100.593,311.436,100.593z"/>
|
|
19
|
+
</g>
|
|
20
|
+
<path style="fill:#1CB71C;" d="M60.852,224.193c-12.472,0-25.424-11.768-33.424-30.432v119.32c0,16.112,15.432,29.176,32,29.176
|
|
21
|
+
c16.56,0,32-13.064,32-29.176V199.985C83.428,214.977,71.86,224.193,60.852,224.193z"/>
|
|
22
|
+
<path style="fill:#57C927;" d="M443.428,158.977c-16.568,0-32,13.072-32,29.176v124.92c0,16.112,15.432,29.176,32,29.176
|
|
23
|
+
c16.56,0,32-13.064,32-29.176V188.161C475.428,172.049,459.988,158.977,443.428,158.977z"/>
|
|
24
|
+
<g>
|
|
25
|
+
<path style="fill:#1CB71C;" d="M444.852,224.193c-12.472,0-25.424-11.768-33.424-30.432v119.32c0,16.112,15.432,29.176,32,29.176
|
|
26
|
+
c16.56,0,32-13.064,32-29.176V199.985C467.428,214.977,455.86,224.193,444.852,224.193z"/>
|
|
27
|
+
<path style="fill:#1CB71C;" d="M251.428,179.337c-63.28,0-120-7.32-136-17.712v211.472c0,17,10.208,30.336,27.704,30.336h22.84
|
|
28
|
+
c-0.784,0-2.544,5.768-2.544,8.6v61.648c0,16.112,15.448,29.176,32,29.176c16.56,0,32-13.064,32-29.176v-61.648
|
|
29
|
+
c0-2.832-3.088-8.6-3.848-8.6h55.712c-0.76,0-3.864,5.768-3.864,8.6v61.648c0,16.112,15.416,29.176,31.968,29.176
|
|
30
|
+
c16.592,0,32.032-13.064,32.032-29.176v-61.648c0-2.832-1.752-8.6-2.536-8.6h22.872c17.496,0,27.664-13.336,27.664-30.336v-211.48
|
|
31
|
+
C371.428,172.009,314.716,179.337,251.428,179.337z"/>
|
|
32
|
+
<path style="fill:#1CB71C;" d="M326.436,85.977c0,8.072-6.712,14.608-15,14.608c-8.304,0-15.016-6.536-15.016-14.608
|
|
33
|
+
c0-4.376,2.008-8.24,5.136-10.912c-15.816-2.64-32.64-4.088-50.128-4.088s-34.304,1.448-50.128,4.088
|
|
34
|
+
c3.136,2.664,5.144,6.536,5.144,10.912c0,8.072-6.712,14.608-15,14.608c-8.312,0-15.008-6.536-15.008-14.608
|
|
35
|
+
c0-2.064,0.456-4.024,1.248-5.808c-23.984,6.304-44.592,15.504-60.144,26.808c-3.92,10.296-6.088,24.456-6.088,32.456h279.96
|
|
36
|
+
c0-8-2.168-22.152-6.08-32.44c-15.544-11.32-36.16-20.536-60.128-26.84C325.988,81.937,326.436,83.921,326.436,85.977z"/>
|
|
37
|
+
</g>
|
|
38
|
+
<path style="fill:#049E42;" d="M251.428,262.817c-53.896,0-104-10.632-136-28.056v138.336c0,17,10.208,30.336,27.704,30.336h22.84
|
|
39
|
+
c-0.784,0-2.544,5.768-2.544,8.6v61.648c0,16.112,15.448,29.176,32,29.176c16.56,0,32-13.064,32-29.176v-61.648
|
|
40
|
+
c0-2.832-3.088-8.6-3.848-8.6h55.712c-0.76,0-3.864,5.768-3.864,8.6v61.648c0,16.112,15.416,29.176,31.968,29.176
|
|
41
|
+
c16.592,0,32.032-13.064,32.032-29.176v-61.648c0-2.832-1.752-8.6-2.536-8.6h22.872c17.496,0,27.664-13.336,27.664-30.336V234.761
|
|
42
|
+
C355.428,252.193,305.324,262.817,251.428,262.817z"/>
|
|
43
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
4
|
+
viewBox="0 0 496.412 496.412" xml:space="preserve">
|
|
5
|
+
<path d="M317.222,80.584C333.414,59.696,345.686,30.152,341.246,0c-26.472,1.84-57.384,18.768-75.432,40.832
|
|
6
|
+
c-16.456,20-29.976,49.728-24.688,78.608C270.054,120.344,299.91,103.008,317.222,80.584z"/>
|
|
7
|
+
<path style="fill:#1B546B;" d="M445.838,166.544c-25.4-31.872-61.12-50.344-94.848-50.344c-44.512,0-63.352,21.312-94.264,21.312
|
|
8
|
+
c-31.896,0-56.12-21.248-94.624-21.248c-37.832,0-78.112,23.12-103.64,62.64C22.574,234.576,28.694,339.2,86.894,428.336
|
|
9
|
+
c20.808,31.904,48.592,67.744,84.952,68.072c32.36,0.32,41.488-20.752,85.336-20.992c43.832-0.256,52.16,21.264,84.456,20.896
|
|
10
|
+
c36.384-0.288,65.712-40.016,86.512-71.92c14.912-22.848,20.48-34.376,32.056-60.184
|
|
11
|
+
C376.014,332.184,362.518,212.488,445.838,166.544z"/>
|
|
12
|
+
<path d="M394.774,228.08c-63.632,51.52-153.592,83.712-253.44,83.712c-35.776,0-70.288-4.144-102.768-11.808
|
|
13
|
+
c5.496,41.808,21.16,86.736,48.336,128.344c20.808,31.904,48.592,67.744,84.952,68.072c32.36,0.32,41.488-20.752,85.336-20.992
|
|
14
|
+
c43.832-0.256,52.16,21.264,84.456,20.896c36.384-0.288,65.712-40.016,86.512-71.92c14.912-22.848,20.48-34.376,32.056-60.184
|
|
15
|
+
C402.966,342.44,378.454,280.176,394.774,228.08z"/>
|
|
16
|
+
</svg>
|
|
Binary file
|