Skip to content

Commit

Permalink
Layout and padding changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Vorlias committed Aug 10, 2023
1 parent 727f026 commit 64a891b
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 60 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rbxts/zenui-core",
"version": "0.7.0",
"version": "0.8.0",
"description": "",
"main": "out/init.lua",
"scripts": {
Expand Down
118 changes: 97 additions & 21 deletions src/Layouts/RowView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Roact from "@rbxts/roact";
import Padding, { UPaddingDim } from "../Utility/Padding";
import { InferEnumNames, RoactEnum } from "../Utility/Types";
import { InferEnumNames, WritablePropertiesOf, RoactEnum } from "../Utility/Types";
import { View } from "../Views/View";

export interface RowProps {
Expand All @@ -13,6 +13,12 @@ export interface RowProps {
* The maximum height of this row
*/
readonly MaxHeight?: number;

// /**
// * Automatic Height
// */
// readonly AutomaticHeight?: boolean;

/**
* The minimum height of this row
*/
Expand Down Expand Up @@ -46,6 +52,11 @@ export function Row(props: Roact.PropsWithChildren<RowProps>) {
return <>{props[Roact.Children]}</>;
}

type ScrollingFrameProperties = WritablePropertiesOf<
Omit<ScrollingFrame, "CanvasSize" | "CanvasPosition">,
keyof GuiObject
>;

interface RowViewDefaultProps {
/**
* The size of this row view container
Expand All @@ -56,6 +67,11 @@ interface RowViewDefaultProps {
* The width of the rows (if not set, will be automatic)
*/
readonly RowWidth: UDim;

/**
* Whether or not this `RowView` scrols
*/
readonly Scrolling: boolean | Partial<ScrollingFrameProperties>;
}

export interface RowViewProps extends RowViewDefaultProps {
Expand All @@ -66,7 +82,7 @@ export interface RowViewProps extends RowViewDefaultProps {
/**
* The amount of padding around the column view
*/
readonly Padding?: Padding | UPaddingDim;
readonly Padding?: UPaddingDim;

/**
* The horizontal alignment of the row
Expand All @@ -93,11 +109,30 @@ export interface RowViewProps extends RowViewDefaultProps {
* etc.
*/
export class RowView extends Roact.Component<RowViewProps> {
public contentsSize: Roact.Binding<Vector2>;
public setContentSize: Roact.BindingFunction<Vector2>;

public static defaultProps: RowViewDefaultProps = {
RowWidth: new UDim(),
Size: new UDim2(1, 0, 1, 0),
Scrolling: false,
};

private layoutRef = Roact.createRef<UIListLayout>();

public constructor(props: RowViewProps) {
super(props);
[this.contentsSize, this.setContentSize] = Roact.createBinding(new Vector2());
}

protected didMount(): void {
const layoutRef = this.layoutRef.getValue();

if (layoutRef !== undefined) {
this.setContentSize(layoutRef.AbsoluteContentSize);
}
}

/**
* Represents a Row in a `<RowView/>` ({@link RowView})
*/
Expand Down Expand Up @@ -138,6 +173,7 @@ export class RowView extends Roact.Component<RowViewProps> {
for (const [key, child] of children) {
if (child.component === Row) {
const props = child.props as RowProps;

containerMap.set(
key,
<View
Expand Down Expand Up @@ -190,25 +226,65 @@ export class RowView extends Roact.Component<RowViewProps> {
}
}

return (
<View Size={this.props.Size} AutomaticSize={this.props.RowWidth !== new UDim() ? "None" : "X"}>
<uilistlayout
Key="RowLayout"
SortOrder="LayoutOrder"
FillDirection="Vertical"
Padding={colPadding}
VerticalAlignment={this.props.VerticalAlignment ?? "Center"}
/>
{(this.props.MinSize !== undefined || this.props.MaxSize !== undefined) && (
<uisizeconstraint
Key="RowSizeConstraint"
MinSize={this.props.MinSize}
MaxSize={this.props.MaxSize}
if (this.props.Scrolling !== undefined && !!this.props.Scrolling) {
const defaultProperties = identity<Partial<ScrollingFrameProperties>>({
ScrollBarThickness: 5,
ScrollBarImageColor3: Color3.fromRGB(0, 0, 0),
});
const properties = typeIs(this.props.Scrolling, "boolean")
? defaultProperties
: { ...defaultProperties, ...this.props.Scrolling };

return (
<scrollingframe
BorderSizePixel={0}
BackgroundTransparency={1}
Size={this.props.Size}
{...properties}
AutomaticSize={this.props.RowWidth !== new UDim() ? "None" : "X"}
CanvasSize={this.contentsSize.map((size) => new UDim2(0, size.X, 0, size.Y))}
>
<uilistlayout
Ref={this.layoutRef}
Key="RowLayout"
SortOrder="LayoutOrder"
FillDirection="Vertical"
Padding={colPadding}
VerticalAlignment={this.props.VerticalAlignment ?? "Center"}
/>
)}
{padding && <Padding Key="RowPadding" Padding={padding} />}
{containerMap}
</View>
);
{(this.props.MinSize !== undefined || this.props.MaxSize !== undefined) && (
<uisizeconstraint
Key="RowSizeConstraint"
MinSize={this.props.MinSize}
MaxSize={this.props.MaxSize}
/>
)}
{padding && <Padding Key="RowPadding" Padding={padding} />}
{containerMap}
</scrollingframe>
);
} else {
return (
<View Size={this.props.Size} AutomaticSize={this.props.RowWidth !== new UDim() ? "None" : "X"}>
<uilistlayout
Ref={this.layoutRef}
Key="RowLayout"
SortOrder="LayoutOrder"
FillDirection="Vertical"
Padding={colPadding}
VerticalAlignment={this.props.VerticalAlignment ?? "Center"}
/>
{(this.props.MinSize !== undefined || this.props.MaxSize !== undefined) && (
<uisizeconstraint
Key="RowSizeConstraint"
MinSize={this.props.MinSize}
MaxSize={this.props.MaxSize}
/>
)}
{padding && <Padding Key="RowPadding" Padding={padding} />}
{containerMap}
</View>
);
}
}
}
52 changes: 25 additions & 27 deletions src/Utility/Padding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ export class UPaddingDim {
return new UPaddingDim(new UDim(), udim, new UDim(), udim);
}

public static uniform(this: void, scale: number, offset: number) {
return UPaddingDim.axis(new UDim(scale, offset), new UDim(scale, offset));
}

/** @deprecated */
public static fromScale(this: void, scale: Padding) {
const { Left = 0, Right = 0, Top = 0, Bottom = 0, Vertical = 0, Horizontal = 0 } = scale;
Expand Down Expand Up @@ -161,13 +165,22 @@ export class UPaddingDim {
this.Bottom.sub(other.Bottom),
);
}

public Into(): Omit<UIPadding, keyof Instance> {
return {
PaddingLeft: this.Left,
PaddingTop: this.Top,
PaddingRight: this.Right,
PaddingBottom: this.Bottom,
} as Omit<UIPadding, keyof Instance>;
}
}

/** @deprecated Now `UPaddingDim` */
export const PaddingDim = UPaddingDim;
export type PaddingDim = UPaddingDim;

export default interface Padding {
export interface Padding {
Left?: number;
Top?: number;
Right?: number;
Expand All @@ -176,37 +189,22 @@ export default interface Padding {
Horizontal?: number;
}
export interface PaddingProps {
Padding: Padding | UPaddingDim;
/** @deprecated */
ForwardRef?: (rbx: UIPadding, padding: Padding) => void;
Padding: UPaddingDim | Padding;
}
export default function Padding({ Padding: padding, ForwardRef: forwardRef }: PaddingProps) {
if (padding instanceof UPaddingDim) {
return (
<uipadding
PaddingLeft={padding.Left}
PaddingTop={padding.Top}
PaddingRight={padding.Right}
PaddingBottom={padding.Bottom}
/>
);
export function Padding(props: PaddingProps) {
if (!(props.Padding instanceof UPaddingDim)) {
props.Padding = UPaddingDim.fromOffset(props.Padding);
}

const { Left = 0, Right = 0, Top = 0, Bottom = 0, Vertical = 0, Horizontal = 0 } = padding;

const padding = props.Padding;
return (
<uipadding
Ref={
forwardRef !== undefined
? (ref) => {
forwardRef(ref, padding);
}
: undefined
}
PaddingBottom={new UDim(0, Bottom + Vertical)}
PaddingTop={new UDim(0, Top + Vertical)}
PaddingRight={new UDim(0, Right + Horizontal)}
PaddingLeft={new UDim(0, Left + Horizontal)}
PaddingLeft={padding.Left}
PaddingTop={padding.Top}
PaddingRight={padding.Right}
PaddingBottom={padding.Bottom}
/>
);
}

export default Padding;
5 changes: 5 additions & 0 deletions src/Utility/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ export interface ElementOf<T extends Roact.AnyComponent> extends Roact.Element {

/** @internal */
export const isArray = t.array(t.any);

export type WritablePropertiesOf<
TInstance extends Instance,
TExcludeProps extends keyof TInstance = keyof Instance,
> = WritableProperties<ExcludeMembers<Omit<TInstance, TExcludeProps>, symbol>>;
14 changes: 3 additions & 11 deletions src/Views/ListView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Roact from "@rbxts/roact";
import Padding from "../Utility/Padding";
import Padding, { UPaddingDim } from "../Utility/Padding";
import { InferEnumNames } from "../Utility/Types";
import { View, ViewProps } from "./View";

Expand All @@ -18,7 +18,7 @@ export interface ListViewProps extends Pick<ViewProps, "Position" | "AnchorPoint

readonly HorizontalAlignment?: InferEnumNames<Enum.HorizontalAlignment>;
readonly VerticalAlignment?: InferEnumNames<Enum.VerticalAlignment>;
readonly Padding?: Padding;
readonly Padding?: UPaddingDim;
}

/**
Expand Down Expand Up @@ -94,15 +94,7 @@ export class ListView extends Roact.Component<ListViewProps> {
},
}}
/>
{padding !== undefined && (
<Padding
Padding={padding}
ForwardRef={(_, padding) => {
const { Left = 0, Right = 0, Top = 0, Bottom = 0, Vertical = 0, Horizontal = 0 } = padding;
this.setPadding(new Vector2(Left + Right + Horizontal * 2, Top + Bottom + Vertical * 2));
}}
/>
)}
{padding !== undefined && <Padding Padding={padding} />}
{this.props[Roact.Children]}
</View>
);
Expand Down

0 comments on commit 64a891b

Please sign in to comment.