Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block border #139

Merged
merged 28 commits into from
Dec 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
db3a205
Move and rename InspectorControls file
psrpinto Nov 24, 2022
7260473
Add component for HomeserverPanel
psrpinto Nov 24, 2022
739e4a6
Add component for RoomPanel
psrpinto Nov 24, 2022
f34450f
Add component for StylePanel
psrpinto Nov 24, 2022
7154224
Improve labels
psrpinto Nov 24, 2022
bcb5a0f
Extract style to a variable
psrpinto Nov 30, 2022
2c313f8
Make focusable a prop
psrpinto Nov 30, 2022
cacd68b
Make attributes a prop
psrpinto Nov 30, 2022
69e90df
Extract props
psrpinto Nov 30, 2022
29b1727
Specify type for iframe props
psrpinto Nov 30, 2022
313017a
Pass iframe params explicitely
psrpinto Nov 30, 2022
5f53183
Don't pass block's attributes to iframe component
psrpinto Nov 30, 2022
ddd5a93
Extract attribute types to its own file
psrpinto Nov 30, 2022
cbeca33
Make height an object
psrpinto Nov 30, 2022
65ccd7c
Pass height object to iframe
psrpinto Nov 30, 2022
9279d7c
Define Attributes object
psrpinto Nov 30, 2022
85bbbef
Create generic ValueWithUnit object
psrpinto Nov 30, 2022
473eb2e
Add border attribute
psrpinto Nov 30, 2022
62f4c4f
Don't use multiple levels of objects
psrpinto Nov 30, 2022
cd99112
Specify border attributes
psrpinto Nov 30, 2022
1b009dc
Simplify props
psrpinto Nov 30, 2022
1dd7cf1
When border width is not set, it should be 0
psrpinto Nov 30, 2022
a960ee0
Inheriting border radius should now be done on the iframe
psrpinto Dec 2, 2022
ddf0218
Apply styles in PHP
psrpinto Dec 2, 2022
f27486d
Add TextControlWithUnit component
psrpinto Dec 2, 2022
8721ad9
Use TextControlWithUnit where appropriate
psrpinto Dec 2, 2022
e7f4577
Fix formatting
psrpinto Dec 2, 2022
eaa095c
Remove border FAQ
psrpinto Dec 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,3 @@ add_filter( 'chatrix_instances', function ( array $default_instances ) {
);
} );
~~~

### How can I add a border around the block?
To add a border around the Chatrix block, you can place it inside a Group block. The Group block allows you to set a border, rounded corners, and other styling properties.
74 changes: 74 additions & 0 deletions block/attributes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
interface Attributes {
defaultHomeserver?: string,
roomId?: string,
height: Height,
borderWidth: BorderWidth,
borderRadius: BorderRadius,
borderStyle: string,
borderColor: string,
}

export function parseAttributes(attributes): Attributes {
return {
defaultHomeserver: attributes.defaultHomeserver ?? '',
roomId: attributes.roomId ?? '',
height: new Height(attributes.height.value, attributes.height.unit),
borderWidth: new BorderWidth(attributes.borderWidth.value, attributes.borderWidth.unit),
borderRadius: new BorderRadius(attributes.borderRadius.value, attributes.borderRadius.unit),
borderStyle: attributes.borderStyle,
borderColor: attributes.borderColor,
};
}

export enum Unit {
px = "px",
}

function unitFromString(value: string): Unit | undefined {
switch (value) {
case Unit.px:
return Unit.px;
}
return undefined;
}

class ValueWithUnit {
protected readonly value: number;
protected readonly unit?: Unit;

constructor(value: number, unit: Unit | string) {
this.value = value;

if (typeof unit === "string") {
this.unit = unitFromString(unit);
} else {
this.unit = unit;
}
}

public toString(): string {
return this.value && this.unit ? `${this.value}${this.unit}` : '';
}
}

export class Height extends ValueWithUnit {
constructor(value: number, unit: Unit | string) {
super(value, unit);
}
}

export class BorderWidth extends ValueWithUnit {
constructor(value: number, unit: Unit | string) {
super(value, unit);
}

public toString(): string {
return this.value && this.unit ? `${this.value}${this.unit}` : '0';
}
}

export class BorderRadius extends ValueWithUnit {
constructor(value: number, unit: Unit | string) {
super(value, unit);
}
}
22 changes: 22 additions & 0 deletions block/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,28 @@
"value": 600,
"unit": "px"
}
},
"borderWidth": {
"type": "object",
"default": {
"value": 1,
"unit": "px"
}
},
"borderRadius": {
"type": "object",
"default": {
"value": 10,
"unit": "px"
}
},
"borderStyle": {
"type": "string",
"default": "solid"
},
"borderColor": {
"type": "string",
"default": "black"
}
},
"supports": {
Expand Down
28 changes: 15 additions & 13 deletions block/edit.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { useBlockProps } from "@wordpress/block-editor";
import { ResizableBox } from "@wordpress/components";
import { WPElement } from '@wordpress/element';
import { parseAttributes } from "./attributes";
import './editor.scss';
import IFrame from "./iframe";
import InspectorControls from "./inspector";
import IFrame, { IframeProps } from "./iframe";
import InspectorControls from "./inspector/InspectorControls";

type Height = {
value: number
unit: string
interface Props {
attributes: object,
setAttributes: Function,
}

export default function Edit({ attributes, setAttributes }): WPElement {
const height: Height = attributes.height;
export default function Edit(props: Props): WPElement {
const { setAttributes } = props;
const attributes = parseAttributes(props.attributes);

const heightWithUnit =
height.value && height.unit
? `${height.value}${height.unit}`
: '';
const iframeProps: IframeProps = {
focusable: true,
...attributes
};

return (
<>
Expand All @@ -25,7 +27,7 @@ export default function Edit({ attributes, setAttributes }): WPElement {
<ResizableBox
size={{
width: "100%",
height: heightWithUnit,
height: attributes.height.toString(),
}}
enable={{
top: false,
Expand All @@ -41,7 +43,7 @@ export default function Edit({ attributes, setAttributes }): WPElement {
setAttributes({ height: { value: elt.clientHeight, unit: "px" } });
}}
>
<IFrame props={{ height: heightWithUnit }} attributes={attributes} focusable={true}/>
<IFrame {...iframeProps}/>
</ResizableBox>
</div>
</>
Expand Down
19 changes: 19 additions & 0 deletions block/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,22 @@

.wp-block-automattic-chatrix {
}

.chatrix-inspector-controls {
.chatrix-text-control-with-unit {
width: 100%;
}

// Place input and unit on the same line.
.chatrix-text-control-with-unit {
.components-base-control__field > span {
display: flex;
align-items: center;
justify-content: center;

& > span {
margin-left: 5px;
}
}
}
}
37 changes: 30 additions & 7 deletions block/iframe.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import { useFocusableIframe } from "@wordpress/compose";
import { WPElement } from "@wordpress/element";
import { IframeUrl } from "../frontend/parent/iframe";
import { IframeParams, IframeUrl } from "../frontend/parent/iframe";
import { containerClass, iframeClass } from "../frontend/parent/util";
import { BorderRadius, BorderWidth, Height } from "./attributes";

export default function IFrame({ props, attributes, focusable = false }): WPElement {
const ref = focusable ? useFocusableIframe() : undefined;
const url = iframeUrl(attributes);
export type IframeProps = {
focusable: boolean,
defaultHomeserver?: string,
roomId?: string,
height: Height,
borderWidth: BorderWidth,
borderRadius: BorderRadius,
borderStyle: string,
borderColor: string,
}

export default function IFrame(props: IframeProps): WPElement {
const ref = props.focusable ? useFocusableIframe() : undefined;
const style = {
height: props.height.toString(),
borderWidth: props.borderWidth ? props.borderWidth.toString() : 0,
borderRadius: props.borderRadius ? props.borderRadius.toString() : "",
borderStyle: props.borderStyle,
borderColor: props.borderColor,
};

const url = iframeUrl({
defaultHomeserver: props.defaultHomeserver,
roomId: props.roomId,
});

return (
<div className={containerClass()} style={{ height: props.height || undefined }}>
<div className={containerClass()} style={style}>
<iframe className={iframeClass()}
// @ts-ignore
ref={ref}
Expand All @@ -18,13 +41,13 @@ export default function IFrame({ props, attributes, focusable = false }): WPElem
);
}

function iframeUrl(attributes): string {
function iframeUrl(params: IframeParams): string {
const config = window.automattic_chatrix_block_config;
if (!config) {
throw new Error("Failed to initialize Chatrix block: window.automattic_chatrix_block_config is not defined");
}

const url = new IframeUrl(config.rootUrl, attributes);
const url = new IframeUrl(config.rootUrl, params);
return url.toString();
}

Expand Down
63 changes: 0 additions & 63 deletions block/inspector.tsx

This file was deleted.

20 changes: 20 additions & 0 deletions block/inspector/HomeserverPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { PanelBody, PanelRow, TextControl } from "@wordpress/components";
import { WPElement } from "@wordpress/element";
import { __ } from "@wordpress/i18n";

export default function HomeserverPanel({ attributes, setAttributes }): WPElement {
return (
<PanelBody
title={__("Homeserver", "chatrix")}
initialOpen={true}
>
<PanelRow>
<TextControl
label={__("Default Homeserver", "chatrix")}
value={attributes.defaultHomeserver}
onChange={(value) => setAttributes({ defaultHomeserver: value })}
/>
</PanelRow>
</PanelBody>
);
}
17 changes: 17 additions & 0 deletions block/inspector/InspectorControls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { InspectorControls as BaseInspectorControls } from "@wordpress/block-editor";
import { WPElement } from "@wordpress/element";
import HomeserverPanel from "./HomeserverPanel";
import RoomPanel from "./RoomPanel";
import StylePanel from "./StylePanel";

export default function InspectorControls({ attributes, setAttributes }): WPElement {
return (
<BaseInspectorControls>
<div className={"chatrix-inspector-controls"}>
<HomeserverPanel attributes={attributes} setAttributes={setAttributes}/>
<RoomPanel attributes={attributes} setAttributes={setAttributes}/>
<StylePanel attributes={attributes} setAttributes={setAttributes}/>
</div>
</BaseInspectorControls>
);
}
33 changes: 33 additions & 0 deletions block/inspector/RoomPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { PanelBody, PanelRow, TextControl } from "@wordpress/components";
import { WPElement } from "@wordpress/element";
import { __ } from "@wordpress/i18n";

export default function RoomPanel({ attributes, setAttributes }): WPElement {
return (
<PanelBody
title={__("Room", "chatrix")}
initialOpen={false}
>
<PanelRow>
<TextControl
label={__("Room id (optional)", "chatrix")}
value={attributes.roomId}
onChange={(value) => setAttributes({ roomId: value })}
help={<RoomIdHelp/>}
/>
</PanelRow>
</PanelBody>
);
}

function RoomIdHelp() {
return (
<>
<span>{__("When a room id is specified, the client will be in single-room mode.", "chatrix")}</span><br/><br/>
<span>{__("In this mode, the client opens directly in that room, with the user not having access to the screen that shows the list of rooms.", "chatrix")}</span><br/><br/>
<span>{__("The room must be public, so that the user can join without requiring an invitation.", "chatrix")}</span><br/><br/>
<span>{__("The room id must be the room's actual id, it must not be an alias.", "chatrix")}</span><br/><br/>
<span>{__("Example: !abc123:example.com", "chatrix")}</span><br/>
</>
);
}
Loading