Skip to content

Commit 2c0848e

Browse files
author
FalkWolsky
committed
New Components and updated Readme
1 parent 2a096be commit 2c0848e

20 files changed

+2232
-117
lines changed

README.md

+18-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
<div align="center">
55
<h1 style="border-bottom: none; margin-bottom: 0">Lowcoder</h1>
6-
<h3 style="margin-top: 0">This is the only Platform, which closes the gap between App Development, Website Development and Slide-Presentations.</h3>
6+
<h3 style="margin-top: 0">This is the only Platform, which closes the gap between App Development, Website Development, interactive Slides/Presentations and Collaboration Tools!</h3>
77
<p>
88
Create software applications (internal and customer-facing!) and Meeting/Collaboration tools for your Company and your Customers with minimal coding experience.
99
</p>
@@ -12,12 +12,15 @@
1212

1313
<img src="https://1167272343-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjNgeI0mUzgw6Re92iTOw%2Fuploads%2FnwXJC1XBqP2MvTQitPyo%2FApp%20Editor%20%7C%20Main%20Screeen%20clean.png?alt=media&token=e5fba81b-82a7-4c0e-a15d-baa781d5b13a"/>
1414

15+
1516
## 📢 Use Lowcoder in 3 steps
1617
1. Connect to any data sources or APIs.
1718
2. Build UI with 60+ components.
1819
3. Share with colleagues and customers.
1920

2021
## 💡 Why Lowcoder
22+
One platform for everything instead so many different softwares. (like Website Builders, CMS, CRM, POS, ERP, Dashboards & Data Story Visualization, Collaboration Tools).
23+
2124
It's cumbersome to create a single app. You had to design user interfaces, write code in multiple languages and frameworks, and understand how all of that code works together.
2225

2326
Low-code/No-code platforms are fast to get started with but quickly become unmaintainable and inflexible. This creates more problems than it solves.
@@ -26,26 +29,27 @@ NewGen Lowcode Platforms like Retool and others are great for their simplicity a
2629

2730
Lowcoder wants to take a step forward. More specifically, Lowcoder is:
2831
- An all-in-one IDE to create internal or customer-facing (external) apps.
29-
- A place to create, build and share building blocks of web applications.
32+
- A place to create, build and share building blocks of web applications and whole websites.
3033
- The tool and community to support your business, and lower the cost and time to develop interactive applications.
3134
- The only platform to embed Lowcode Apps natively in Websites (no iFrame!)
3235
- The only platform where you can build your own Meeting Tool - like Teams, Zoom or Google Meets, - just in the Lowcode way.
36+
- The only platform which has extensibility plugin architecture [Check Community Contributions](https://www.npmjs.com/search?q=lowcoder-comp)
3337

3438
## 🪄 Features
35-
- **Visual UI builder** with 70+ built-in components. Save 90% of time to build apps.
36-
- **Modules** for reusable (!) component sets in the UI builder.
37-
- **Embed Lowcoder Apps as native parts of any Website** instead of iFrame (!). [Demo](https://github.com/lowcoder-org/lowcoder-sdk-demo)
39+
- **Visual UI builder** with 85+ built-in components. Save 90% of time to build apps.
40+
- **Modules** for reusable (!) embedable component sets in the UI builder.
41+
- **Embed Lowcoder Apps as native parts of any Website** instead of iFrame (!). [Demo](https://lowcoder.cloud/about), [Docu](https://docs.lowcoder.cloud/lowcoder-documentation/lowcoder-extension/native-embed-sdk)
3842
- **Video Meeting Components** to create your own individual Web-Meeting tool.
3943
- **Query Library** for reusable data queries of your data sources.
4044
- **Custom components** to develop own components and use them in the UI builder.
4145
- **Native Data connections** to PostgreSQL, MongoDB, MySQL, Redis, Elasticsearch, REST API, SMTP, etc.
42-
- **Stream Data connections** to Websockets for realtime data updates & collaboration
46+
- **Stream Data connections** to Websockets for realtime data updates & collaboration! [Docu](https://docs.lowcoder.cloud/lowcoder-documentation/connect-your-data/data-sources-in-lowcoder/websocket-datasource)
4347
- **JavaScript supported everywhere** to transform data, control components, etc.
44-
- **Role-based access control (RBAC)** for granular permission management.
48+
- **Role-based access control (RBAC)** for granular permission management. [Docu](https://docs.lowcoder.cloud/lowcoder-documentation/workspaces-and-teamwork/members-and-groups)
4549
- **Auto-saved and restorable history** for release and version control.
4650
- **App Themes and Theme Editor** to precisely align with your company's brand guidelines.
4751

48-
- **Self Hosting** to use Lowcoder in your internal company network, even behind the firewall.
52+
- **Self Hosting** to use Lowcoder in your internal company network, even behind the firewall. [Docu](https://docs.lowcoder.cloud/lowcoder-documentation/setup-and-run/self-hosting)
4953
- **Free Community Cloud** to start within a minute and build your first Apps. [Start here](https://app.lowcoder.cloud)
5054

5155
## 🏆 Comparisons
@@ -95,10 +99,14 @@ You can access Lowcoder from [cloud-hosted version](https://app.lowcoder.cloud/)
9599
## 💪 Contributing
96100
- Language support: If you have experience with a language that isn't currently supported by our product, send us a pull request.
97101
- Create and share components or demos: If you've created something that might be useful to others, add the link here.
98-
- [Frontend contributing guide](https://github.com/lowcoder-org/lowcoder/tree/main/client)
102+
- [Contributing guide](https://docs.lowcoder.cloud/lowcoder-documentation/lowcoder-extension/opensource-contribution)
99103

100104
## 🥇 Sponsors
101105
Accelerate the growth of Lowcoder and unleash its potential with your Sponsorship – together, we're shaping the future of Lowcode for everyone!
102106
[Be a Sponsor](https://github.com/sponsors/lowcoder-org)
103107

104-
Like ... [@Darkjamin](https://github.com/Darkjamin), [@spacegoats-io](https://github.com/spacegoats-io), [@Jomedya](https://github.com/Jomedya), [@CHSchuepfer](https://github.com/CHSchuepfer), Thank you very much!!
108+
Like ... [@Darkjamin](https://github.com/Darkjamin), [@spacegoats-io](https://github.com/spacegoats-io), [@Jomedya](https://github.com/Jomedya), [@CHSchuepfer](https://github.com/CHSchuepfer), Thank you very much!!
109+
110+
## Intro Video
111+
112+
[![Watch the video](https://i.ytimg.com/vi/s4ltAqS0hzM/maxresdefault.jpg?sqp=-oaymwEmCIAKENAF8quKqQMa8AEB-AH-CYAC0AWKAgwIABABGD0gSShyMA8=&rs=AOn4CLAlPOIFdtauythoBKNPXhi6XGwlDQ)](https://youtu.be/s4ltAqS0hzM?feature=shared)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
import styled from "styled-components";
2+
import { RecordConstructorToView } from "lowcoder-core";
3+
import { styleControl } from "comps/controls/styleControl";
4+
import _ from "lodash";
5+
import {
6+
AvatarStyle,
7+
AvatarStyleType,
8+
} from "comps/controls/styleControlConstants";
9+
import { UICompBuilder } from "comps/generators/uiCompBuilder";
10+
import { withDefault } from "../generators";
11+
import {
12+
NameConfig,
13+
NameConfigHidden,
14+
withExposingConfigs,
15+
} from "comps/generators/withExposing";
16+
import { Section, sectionNames } from "lowcoder-design";
17+
import { hiddenPropertyView } from "comps/utils/propertyUtils";
18+
import { trans } from "i18n";
19+
import { NumberControl } from "comps/controls/codeControl";
20+
import { IconControl } from "comps/controls/iconControl";
21+
import {
22+
clickEvent,
23+
eventHandlerControl,
24+
} from "../controls/eventHandlerControl";
25+
import { Avatar, AvatarProps, Badge, Dropdown, Menu } from "antd";
26+
import { LeftRightControl, dropdownControl } from "../controls/dropdownControl";
27+
import { stringExposingStateControl } from "../controls/codeStateControl";
28+
import { BoolControl } from "../controls/boolControl";
29+
import { BadgeBasicSection, badgeChildren } from "./badgeComp/badgeConstants";
30+
import { DropdownOptionControl } from "../controls/optionsControl";
31+
import { ReactElement, useContext } from "react";
32+
import { CompNameContext, EditorContext } from "../editorState";
33+
34+
const AvatarWrapper = styled(Avatar) <AvatarProps & { $cursorPointer: boolean, $style: AvatarStyleType }>`
35+
background: ${(props) => props.$style.background};
36+
color: ${(props) => props.$style.fill};
37+
cursor: ${(props) => props.$cursorPointer ? 'pointer' : ''};
38+
`;
39+
40+
const Wrapper = styled.div <{ iconSize: number, labelPosition: string }>`
41+
display: flex;
42+
width: 100%;
43+
height: 100%;
44+
padding: 0px;
45+
align-items: center;
46+
flex-direction: ${(props) => props.labelPosition === 'left' ? 'row' : 'row-reverse'};
47+
`
48+
49+
const LabelWrapper = styled.div<{ iconSize: number, alignmentPosition: string }>`
50+
width: calc(100% - ${(props) => props.iconSize}px);
51+
display: flex;
52+
padding-left: 5px;
53+
padding-right: 5px;
54+
flex-direction: column;
55+
justify-content: flex-end;
56+
align-items: ${(props) => props.alignmentPosition === 'left' ? 'flex-start' : 'flex-end'};
57+
`
58+
const LabelSpan = styled.span<{ color: string }>`
59+
max-width: 100%;
60+
overflow: hidden;
61+
text-overflow: ellipsis;
62+
white-space: nowrap;
63+
font-weight: bold;
64+
color: ${(props) => props.color};
65+
`
66+
const CaptionSpan = styled.span<{ color: string }>`
67+
max-width: 100%;
68+
overflow: hidden;
69+
text-overflow: ellipsis;
70+
white-space: nowrap;
71+
color: ${(props) => props.color};
72+
`
73+
const EventOptions = [clickEvent] as const;
74+
const sharpOptions = [
75+
{ label: trans("avatarComp.square"), value: "square" },
76+
{ label: trans("avatarComp.circle"), value: "circle" },
77+
] as const;
78+
79+
const sideOptions = [
80+
{ label: trans('labelProp.left'), value: "left" },
81+
{ label: trans('labelProp.right'), value: "right" },
82+
] as const;
83+
84+
const childrenMap = {
85+
style: styleControl(AvatarStyle),
86+
icon: withDefault(IconControl, "/icon:solid/user"),
87+
iconSize: withDefault(NumberControl, 40),
88+
onEvent: eventHandlerControl(EventOptions),
89+
shape: dropdownControl(sharpOptions, "circle"),
90+
title: stringExposingStateControl("title", ""),
91+
src: stringExposingStateControl("src", ""),
92+
avatarLabel: stringExposingStateControl("avatarLabel", "{{currentUser.name}}"),
93+
avatarCatption: stringExposingStateControl("avatarCatption", "{{currentUser.email}}"),
94+
labelPosition: dropdownControl(sideOptions, 'left'),
95+
alignmentPosition: withDefault(LeftRightControl, 'left'),
96+
enableDropdownMenu: BoolControl,
97+
options: DropdownOptionControl,
98+
...badgeChildren,
99+
};
100+
101+
const AvatarView = (props: RecordConstructorToView<typeof childrenMap>) => {
102+
const { shape, title, src, iconSize } = props;
103+
const comp = useContext(EditorContext).getUICompByName(useContext(CompNameContext));
104+
const eventsCount = comp ? Object.keys(comp?.children.comp.children.onEvent.children).length : 0;
105+
const hasIcon = props.options.findIndex((option) => (option.prefixIcon as ReactElement)?.props.value) > -1;
106+
const items = props.options
107+
.filter((option) => !option.hidden)
108+
.map((option, index) => ({
109+
title: option.label,
110+
label: option.label,
111+
key: option.label + " - " + index,
112+
disabled: option.disabled,
113+
icon: hasIcon && <span>{option.prefixIcon}</span>,
114+
onEvent: option.onEvent,
115+
}));
116+
const menu = (
117+
<Menu
118+
items={items}
119+
onClick={({ key }) => items.find((o) => o.key === key)?.onEvent("click")}
120+
/>
121+
);
122+
return (
123+
<Dropdown
124+
menu={{ items }}
125+
placement={props.labelPosition === 'left' ? "bottomLeft" : "bottomRight"}
126+
arrow
127+
disabled={!props.enableDropdownMenu}
128+
dropdownRender={() => menu}
129+
>
130+
<Wrapper iconSize={props.iconSize} labelPosition={props.labelPosition}>
131+
<Badge
132+
count={props.badgeCount.value}
133+
dot={props.badgeType === 'dot'}
134+
size={props.badgeSize}
135+
overflowCount={props.overflowCount}
136+
title={props.badgeTitle}
137+
offset={props.shape === 'circle' ? [-2, 6] : [0, 0]}
138+
>
139+
<AvatarWrapper
140+
size={iconSize}
141+
icon={title.value !== '' ? null : props.icon}
142+
shape={shape}
143+
$style={props.style}
144+
src={src.value}
145+
$cursorPointer={eventsCount > 0}
146+
onClick={() => props.onEvent("click")}
147+
>
148+
{title.value}
149+
</AvatarWrapper>
150+
</Badge>
151+
<LabelWrapper iconSize={props.iconSize} alignmentPosition={props.alignmentPosition}>
152+
<LabelSpan color={props.style.label}>{props.avatarLabel.value}</LabelSpan>
153+
<CaptionSpan color={props.style.caption}>{props.avatarCatption.value}</CaptionSpan>
154+
</LabelWrapper>
155+
</Wrapper>
156+
</Dropdown>
157+
);
158+
};
159+
160+
let AvatarBasicComp = (function () {
161+
return new UICompBuilder(childrenMap, (props) => <AvatarView {...props} />)
162+
.setPropertyViewFn((children) => (
163+
<>
164+
<Section name={sectionNames.basic}>
165+
{children.src.propertyView({
166+
label: trans("avatarComp.src"),
167+
placeholder: "http://xxxx/xx.jpg",
168+
tooltip: trans("avatarComp.avatarCompTooltip"),
169+
})}
170+
{children.title.propertyView({
171+
label: trans("avatarComp.title"),
172+
tooltip: trans("avatarComp.avatarCompTooltip"),
173+
})}
174+
{children.icon.propertyView({
175+
label: trans("avatarComp.icon"),
176+
IconType: "All",
177+
tooltip: trans("avatarComp.avatarCompTooltip"),
178+
})}
179+
{children.shape.propertyView({
180+
label: trans("avatarComp.shape"),
181+
radioButton: true,
182+
})}
183+
{
184+
children.iconSize.propertyView({
185+
label: trans("avatarComp.iconSize"),
186+
})}
187+
{
188+
children.enableDropdownMenu.propertyView({
189+
label: trans("avatarComp.enableDropDown")
190+
})}
191+
{children.enableDropdownMenu.getView() && children.options.propertyView({})}
192+
</Section>
193+
<Section name={trans('avatarComp.label')}>
194+
{
195+
children.avatarLabel.propertyView({
196+
label: trans("avatarComp.label"),
197+
})}
198+
{
199+
children.avatarCatption.propertyView({
200+
label: trans("avatarComp.caption"),
201+
})}
202+
{
203+
children.labelPosition.propertyView({
204+
label: trans("avatarComp.labelPosition"),
205+
radioButton: true,
206+
})}
207+
{
208+
children.alignmentPosition.propertyView({
209+
label: trans("avatarComp.alignmentPosition"),
210+
radioButton: true,
211+
})}
212+
</Section>
213+
{<BadgeBasicSection {...children} />}
214+
<Section name={sectionNames.interaction}>
215+
{children.onEvent.getPropertyView()}
216+
</Section>
217+
<Section name={sectionNames.layout}>
218+
{hiddenPropertyView(children)}
219+
</Section>
220+
<Section name={sectionNames.style}>
221+
{children.style.getPropertyView()}
222+
</Section>
223+
</>
224+
))
225+
.build();
226+
})();
227+
228+
229+
export const AvatarComp = withExposingConfigs(AvatarBasicComp, [
230+
NameConfigHidden,
231+
new NameConfig("badgeCount", trans("button.textDesc")),
232+
]);

0 commit comments

Comments
 (0)