mirror of
https://github.com/flarum/core.git
synced 2025-07-27 11:40:24 +02:00
Various TypeScript improvements (#2309)
- Use Mithril.Attributes as base for ComponentAttrs, remove =any from class signature for Component - Convert Alert to TypeScript, introduce AlertAttrs interface - Convert AlertManagerState to TypeScript, add overload signatures for `show`, introduce AlertState interface for stored Alerts. - Set ComponentAttrs as default T for Component - Make attrs in AlertAttrs optional - Add AlertIdentifier interface, simplify show type signature - Remove mithril patch shim, as all patches onto m are now deprecated - Use Mithril.Static for shim
This commit is contained in:
committed by
GitHub
parent
dc4884485a
commit
d695d96e00
12
js/shims.d.ts
vendored
12
js/shims.d.ts
vendored
@@ -1,6 +1,5 @@
|
|||||||
// Mithril
|
// Mithril
|
||||||
import * as Mithril from 'mithril';
|
import Mithril from 'mithril';
|
||||||
import Stream from 'mithril/stream';
|
|
||||||
|
|
||||||
// Other third-party libs
|
// Other third-party libs
|
||||||
import * as _dayjs from 'dayjs';
|
import * as _dayjs from 'dayjs';
|
||||||
@@ -9,13 +8,6 @@ import * as _$ from 'jquery';
|
|||||||
// Globals from flarum/core
|
// Globals from flarum/core
|
||||||
import Application from './src/common/Application';
|
import Application from './src/common/Application';
|
||||||
|
|
||||||
/**
|
|
||||||
* Helpers that flarum/core patches into Mithril
|
|
||||||
*/
|
|
||||||
interface m extends Mithril.Static {
|
|
||||||
prop: typeof Stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export Mithril typings globally.
|
* Export Mithril typings globally.
|
||||||
*
|
*
|
||||||
@@ -36,7 +28,7 @@ export as namespace Mithril;
|
|||||||
*/
|
*/
|
||||||
declare global {
|
declare global {
|
||||||
const $: typeof _$;
|
const $: typeof _$;
|
||||||
const m: m;
|
const m: Mithril.Static;
|
||||||
const dayjs: typeof _dayjs;
|
const dayjs: typeof _dayjs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,11 +3,7 @@ import * as Mithril from 'mithril';
|
|||||||
let deprecatedPropsWarned = false;
|
let deprecatedPropsWarned = false;
|
||||||
let deprecatedInitPropsWarned = false;
|
let deprecatedInitPropsWarned = false;
|
||||||
|
|
||||||
export type ComponentAttrs = {
|
export interface ComponentAttrs extends Mithril.Attributes {}
|
||||||
className?: string;
|
|
||||||
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `Component` class defines a user interface 'building block'. A component
|
* The `Component` class defines a user interface 'building block'. A component
|
||||||
@@ -36,7 +32,7 @@ export type ComponentAttrs = {
|
|||||||
*
|
*
|
||||||
* @see https://mithril.js.org/components.html
|
* @see https://mithril.js.org/components.html
|
||||||
*/
|
*/
|
||||||
export default abstract class Component<T extends ComponentAttrs = any> implements Mithril.ClassComponent<T> {
|
export default abstract class Component<T extends ComponentAttrs = ComponentAttrs> implements Mithril.ClassComponent<T> {
|
||||||
/**
|
/**
|
||||||
* The root DOM element for the component.
|
* The root DOM element for the component.
|
||||||
*/
|
*/
|
||||||
|
@@ -1,31 +1,33 @@
|
|||||||
import Component from '../Component';
|
import Component, { ComponentAttrs } from '../Component';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
import listItems from '../helpers/listItems';
|
import listItems from '../helpers/listItems';
|
||||||
import extract from '../utils/extract';
|
import extract from '../utils/extract';
|
||||||
|
import Mithril from 'mithril';
|
||||||
|
|
||||||
|
export interface AlertAttrs extends ComponentAttrs {
|
||||||
|
/** The type of alert this is. Will be used to give the alert a class name of `Alert--{type}`. */
|
||||||
|
type?: string;
|
||||||
|
/** An array of controls to show in the alert. */
|
||||||
|
controls?: Mithril.Children;
|
||||||
|
/** Whether or not the alert can be dismissed. */
|
||||||
|
dismissible?: boolean;
|
||||||
|
/** A callback to run when the alert is dismissed */
|
||||||
|
ondismiss?: Function;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `Alert` component represents an alert box, which contains a message,
|
* The `Alert` component represents an alert box, which contains a message,
|
||||||
* some controls, and may be dismissible.
|
* some controls, and may be dismissible.
|
||||||
*
|
|
||||||
* ### Attrs
|
|
||||||
*
|
|
||||||
* - `type` The type of alert this is. Will be used to give the alert a class
|
|
||||||
* name of `Alert--{type}`.
|
|
||||||
* - `controls` An array of controls to show in the alert.
|
|
||||||
* - `dismissible` Whether or not the alert can be dismissed.
|
|
||||||
* - `ondismiss` A callback to run when the alert is dismissed.
|
|
||||||
*
|
|
||||||
* All other attrs will be assigned as attributes on the DOM element.
|
|
||||||
*/
|
*/
|
||||||
export default class Alert extends Component {
|
export default class Alert<T extends AlertAttrs = AlertAttrs> extends Component<T> {
|
||||||
view(vnode) {
|
view(vnode: Mithril.Vnode) {
|
||||||
const attrs = Object.assign({}, this.attrs);
|
const attrs = Object.assign({}, this.attrs);
|
||||||
|
|
||||||
const type = extract(attrs, 'type');
|
const type = extract(attrs, 'type');
|
||||||
attrs.className = 'Alert Alert--' + type + ' ' + (attrs.className || '');
|
attrs.className = 'Alert Alert--' + type + ' ' + (attrs.className || '');
|
||||||
|
|
||||||
const content = extract(attrs, 'content') || vnode.children;
|
const content = extract(attrs, 'content') || vnode.children;
|
||||||
const controls = extract(attrs, 'controls') || [];
|
const controls = (extract(attrs, 'controls') || []) as Mithril.ChildArray;
|
||||||
|
|
||||||
// If the alert is meant to be dismissible (which is the case by default),
|
// If the alert is meant to be dismissible (which is the case by default),
|
||||||
// then we will create a dismiss button to append as the final control in
|
// then we will create a dismiss button to append as the final control in
|
@@ -1,10 +1,20 @@
|
|||||||
import Alert from '../components/Alert';
|
import Mithril from 'mithril';
|
||||||
|
import Alert, { AlertAttrs } from '../components/Alert';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returned by `AlertManagerState.show`. Used to dismiss alerts.
|
||||||
|
*/
|
||||||
|
export type AlertIdentifier = number;
|
||||||
|
|
||||||
|
export interface AlertState {
|
||||||
|
componentClass: typeof Alert;
|
||||||
|
attrs: AlertAttrs;
|
||||||
|
children: Mithril.Children;
|
||||||
|
}
|
||||||
|
|
||||||
export default class AlertManagerState {
|
export default class AlertManagerState {
|
||||||
constructor() {
|
protected activeAlerts: { [id: number]: AlertState } = {};
|
||||||
this.activeAlerts = {};
|
protected alertId = 0;
|
||||||
this.alertId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
getActiveAlerts() {
|
getActiveAlerts() {
|
||||||
return this.activeAlerts;
|
return this.activeAlerts;
|
||||||
@@ -12,19 +22,27 @@ export default class AlertManagerState {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an Alert in the alerts area.
|
* Show an Alert in the alerts area.
|
||||||
|
*
|
||||||
|
* @returns The alert's ID, which can be used to dismiss the alert.
|
||||||
*/
|
*/
|
||||||
show(arg1, arg2, arg3) {
|
show(children: Mithril.Children): AlertIdentifier;
|
||||||
|
show(attrs: AlertAttrs, children: Mithril.Children): AlertIdentifier;
|
||||||
|
show(componentClass: Alert, attrs: AlertAttrs, children: Mithril.Children): AlertIdentifier;
|
||||||
|
|
||||||
|
show(arg1: any, arg2?: any, arg3?: any) {
|
||||||
|
// Assigns variables as per the above signatures
|
||||||
let componentClass = Alert;
|
let componentClass = Alert;
|
||||||
let attrs = {};
|
let attrs: AlertAttrs = {};
|
||||||
let children;
|
let children: Mithril.Children;
|
||||||
|
|
||||||
if (arguments.length == 1) {
|
if (arguments.length == 1) {
|
||||||
children = arg1;
|
children = arg1 as Mithril.Children;
|
||||||
} else if (arguments.length == 2) {
|
} else if (arguments.length == 2) {
|
||||||
attrs = arg1;
|
attrs = arg1 as AlertAttrs;
|
||||||
children = arg2;
|
children = arg2 as Mithril.Children;
|
||||||
} else if (arguments.length == 3) {
|
} else if (arguments.length == 3) {
|
||||||
componentClass = arg1;
|
componentClass = arg1 as typeof Alert;
|
||||||
attrs = arg2;
|
attrs = arg2 as AlertAttrs;
|
||||||
children = arg3;
|
children = arg3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +63,7 @@ export default class AlertManagerState {
|
|||||||
/**
|
/**
|
||||||
* Dismiss an alert.
|
* Dismiss an alert.
|
||||||
*/
|
*/
|
||||||
dismiss(key) {
|
dismiss(key: AlertIdentifier): void {
|
||||||
if (!key || !(key in this.activeAlerts)) return;
|
if (!key || !(key in this.activeAlerts)) return;
|
||||||
|
|
||||||
delete this.activeAlerts[key];
|
delete this.activeAlerts[key];
|
||||||
@@ -54,10 +72,8 @@ export default class AlertManagerState {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all alerts.
|
* Clear all alerts.
|
||||||
*
|
|
||||||
* @public
|
|
||||||
*/
|
*/
|
||||||
clear() {
|
clear(): void {
|
||||||
this.activeAlerts = {};
|
this.activeAlerts = {};
|
||||||
m.redraw();
|
m.redraw();
|
||||||
}
|
}
|
Reference in New Issue
Block a user