This repository has been archived by the owner on Sep 11, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 828
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Polls: Creation form & start event (#7001)
* PSFD-423: Permission check for polls dialog * PSFD-423: Implement compound scrollable dialog and skeleton create poll * PSFD-325: Ask the question * PSFD-328: Ask for options * PSFD-423: Ensure form submission semantics work for dialogs * PSFD-328: Option semantics * Can delete all option to end up with zero * Minimum 2 to submit the form * PSFD-316: Send poll start event * Appease the linter * PSFD-328: Reduce padding between options to account for field size * Iterate per design * Fix submission
- Loading branch information
Showing
13 changed files
with
546 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
Copyright 2021 The Matrix.org Foundation C.I.C. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
// -------------------------------------------------------------------------------- | ||
// DEV NOTE: This stylesheet covers dialogs listed by the compound, including | ||
// over multiple React components. The actual inner contents of the dialog should | ||
// be in their respective stylesheets. | ||
// -------------------------------------------------------------------------------- | ||
|
||
// Override legacy/default styles for dialogs | ||
.mx_Dialog_wrapper.mx_CompoundDialog > .mx_Dialog { | ||
padding: 0; // we'll manage it ourselves | ||
color: $primary-content; | ||
} | ||
|
||
.mx_CompoundDialog { | ||
.mx_CompoundDialog_header { | ||
padding: 32px 32px 16px 32px; | ||
|
||
h1 { | ||
display: inline-block; | ||
font-weight: 600; | ||
font-size: $font-24px; | ||
margin: 0; // managed by header class | ||
} | ||
|
||
.mx_CompoundDialog_cancelButton { | ||
mask: url('$(res)/img/feather-customised/cancel.svg'); | ||
mask-repeat: no-repeat; | ||
mask-position: center; | ||
mask-size: cover; | ||
width: 20px; | ||
height: 20px; | ||
background-color: $dialog-close-fg-color; | ||
cursor: pointer; | ||
|
||
// Align with middle of title, 34px from right edge | ||
position: absolute; | ||
top: 34px; | ||
right: 34px; | ||
} | ||
} | ||
|
||
.mx_CompoundDialog_content { | ||
overflow: auto; | ||
padding: 8px 32px; | ||
} | ||
|
||
.mx_CompoundDialog_footer { | ||
padding: 20px 32px; | ||
text-align: right; | ||
position: absolute; | ||
bottom: 0; | ||
left: 0; | ||
right: 0; | ||
|
||
.mx_AccessibleButton { | ||
margin-left: 24px; | ||
} | ||
} | ||
} | ||
|
||
.mx_ScrollableBaseDialog { | ||
width: 544px; // fixed | ||
height: 516px; // fixed | ||
|
||
.mx_CompoundDialog_content { | ||
height: 349px; // dialogHeight - header - footer | ||
} | ||
|
||
.mx_CompoundDialog_footer { | ||
box-shadow: 0px -4px 4px rgba(0, 0, 0, 0.05); // hardcoded colour for both themes | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
Copyright 2021 The Matrix.org Foundation C.I.C. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
.mx_PollCreateDialog { | ||
h2 { | ||
font-weight: 600; | ||
font-size: $font-15px; | ||
line-height: $font-24px; | ||
margin-top: 0; | ||
margin-bottom: 8px; | ||
|
||
&:nth-child(n + 2) { | ||
margin-top: 20px; | ||
} | ||
} | ||
|
||
.mx_PollCreateDialog_option { | ||
display: flex; | ||
align-items: center; | ||
margin-top: 11px; | ||
margin-bottom: 16px; // 11px from the top will collapse, so this creates a 16px gap between options | ||
|
||
.mx_Field { | ||
flex: 1; | ||
margin: 0; | ||
} | ||
|
||
.mx_PollCreateDialog_removeOption { | ||
margin-left: 12px; | ||
width: 20px; | ||
height: 20px; | ||
border-radius: 50%; | ||
background-color: $quinary-content; | ||
cursor: pointer; | ||
position: relative; | ||
|
||
&::before { | ||
content: ""; | ||
mask: url('$(res)/img/element-icons/x-8px.svg'); | ||
mask-repeat: no-repeat; | ||
mask-position: center; | ||
mask-size: cover; | ||
width: 8px; | ||
height: 8px; | ||
position: absolute; | ||
top: 6px; | ||
left: 6px; | ||
background-color: $secondary-content; | ||
} | ||
} | ||
} | ||
|
||
.mx_PollCreateDialog_addOption { | ||
padding: 0; | ||
margin-bottom: 40px; // arbitrary to create scrollable area under the poll | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
Copyright 2021 The Matrix.org Foundation C.I.C. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import React, { FormEvent } from "react"; | ||
import { MatrixClient } from "matrix-js-sdk/src/client"; | ||
import { MatrixClientPeg } from "../../../MatrixClientPeg"; | ||
import { Key } from "../../../Keyboard"; | ||
import { IDialogProps } from "./IDialogProps"; | ||
import MatrixClientContext from "../../../contexts/MatrixClientContext"; | ||
import FocusLock from "react-focus-lock"; | ||
import { _t } from "../../../languageHandler"; | ||
import AccessibleButton from "../elements/AccessibleButton"; | ||
|
||
export interface IScrollableBaseState { | ||
canSubmit: boolean; | ||
title: string; | ||
actionLabel: string; | ||
} | ||
|
||
/** | ||
* Scrollable dialog base from Compound (Web Components). | ||
*/ | ||
export default abstract class ScrollableBaseModal<TProps extends IDialogProps, TState extends IScrollableBaseState> | ||
extends React.PureComponent<TProps, TState> { | ||
protected constructor(props: TProps) { | ||
super(props); | ||
} | ||
|
||
protected get matrixClient(): MatrixClient { | ||
return MatrixClientPeg.get(); | ||
} | ||
|
||
private onKeyDown = (e: KeyboardEvent | React.KeyboardEvent): void => { | ||
if (e.key === Key.ESCAPE) { | ||
e.stopPropagation(); | ||
e.preventDefault(); | ||
this.cancel(); | ||
} | ||
}; | ||
|
||
private onCancel = () => { | ||
this.cancel(); | ||
}; | ||
|
||
private onSubmit = (e: MouseEvent | FormEvent) => { | ||
e.stopPropagation(); | ||
e.preventDefault(); | ||
if (!this.state.canSubmit) return; // pretend the submit button was disabled | ||
this.submit(); | ||
}; | ||
|
||
protected abstract cancel(): void; | ||
protected abstract submit(): void; | ||
protected abstract renderContent(): React.ReactNode; | ||
|
||
public render(): JSX.Element { | ||
return ( | ||
<MatrixClientContext.Provider value={this.matrixClient}> | ||
<FocusLock | ||
returnFocus={true} | ||
lockProps={{ | ||
onKeyDown: this.onKeyDown, | ||
role: "dialog", | ||
["aria-labelledby"]: "mx_CompoundDialog_title", | ||
|
||
// Like BaseDialog, we'll just point this at the whole content | ||
["aria-describedby"]: "mx_CompoundDialog_content", | ||
}} | ||
className="mx_CompoundDialog mx_ScrollableBaseDialog" | ||
> | ||
<div className="mx_CompoundDialog_header"> | ||
<h1>{ this.state.title }</h1> | ||
<AccessibleButton | ||
onClick={this.onCancel} | ||
className="mx_CompoundDialog_cancelButton" | ||
aria-label={_t("Close dialog")} | ||
/> | ||
</div> | ||
<form onSubmit={this.onSubmit}> | ||
<div className="mx_CompoundDialog_content"> | ||
{ this.renderContent() } | ||
</div> | ||
<div className="mx_CompoundDialog_footer"> | ||
<AccessibleButton onClick={this.onCancel} kind="primary_outline"> | ||
{ _t("Cancel") } | ||
</AccessibleButton> | ||
<AccessibleButton | ||
onClick={this.onSubmit} | ||
kind="primary" | ||
disabled={!this.state.canSubmit} | ||
type="submit" | ||
element="button" | ||
className="mx_Dialog_nonDialogButton" | ||
> | ||
{ this.state.actionLabel } | ||
</AccessibleButton> | ||
</div> | ||
</form> | ||
</FocusLock> | ||
</MatrixClientContext.Provider> | ||
); | ||
} | ||
} |
Oops, something went wrong.