mirror of
https://github.com/flarum/core.git
synced 2025-08-13 20:04:24 +02:00
Compare commits
2 Commits
dw/remove-
...
as/dropdow
Author | SHA1 | Date | |
---|---|---|---|
|
fbd7ff6683 | ||
|
d2a755c515 |
@@ -38,11 +38,13 @@ export default class PermissionGrid<CustomAttrs extends IPermissionGridAttrs = I
|
||||
|
||||
const permissionCells = (permission: PermissionGridEntry | { children: PermissionGridEntry[] }) => {
|
||||
return scopes.map((scope) => {
|
||||
// This indicates the "permission" is a permission category,
|
||||
// in which case we return an empty table cell.
|
||||
if ('children' in permission) {
|
||||
return <td></td>;
|
||||
}
|
||||
|
||||
return scope.render(permission);
|
||||
return <td>{scope.render(permission)}</td>;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -416,7 +418,7 @@ export default class PermissionGrid<CustomAttrs extends IPermissionGridAttrs = I
|
||||
});
|
||||
}
|
||||
|
||||
return '';
|
||||
return undefined;
|
||||
},
|
||||
},
|
||||
100
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import app from '../../admin/app';
|
||||
import app from '../app';
|
||||
import SelectDropdown from '../../common/components/SelectDropdown';
|
||||
import Button from '../../common/components/Button';
|
||||
import saveSettings from '../utils/saveSettings';
|
||||
@@ -11,18 +11,23 @@ export default class SettingDropdown extends SelectDropdown {
|
||||
attrs.buttonClassName = 'Button Button--text';
|
||||
attrs.caretIcon = 'fas fa-caret-down';
|
||||
attrs.defaultLabel = 'Custom';
|
||||
|
||||
if (key in attrs) {
|
||||
attrs.setting = attrs.key;
|
||||
delete attrs.key;
|
||||
}
|
||||
}
|
||||
|
||||
view(vnode) {
|
||||
return super.view({
|
||||
...vnode,
|
||||
children: this.attrs.options.map(({ value, label }) => {
|
||||
const active = app.data.settings[this.attrs.key] === value;
|
||||
const active = app.data.settings[this.attrs.setting] === value;
|
||||
|
||||
return Button.component(
|
||||
{
|
||||
icon: active ? 'fas fa-check' : true,
|
||||
onclick: saveSettings.bind(this, { [this.attrs.key]: value }),
|
||||
onclick: saveSettings.bind(this, { [this.attrs.setting]: value }),
|
||||
active,
|
||||
},
|
||||
label
|
||||
|
@@ -1,27 +1,61 @@
|
||||
import type Mithril from 'mithril';
|
||||
|
||||
import app from '../../common/app';
|
||||
import Component from '../Component';
|
||||
import Component, { ComponentAttrs } from '../Component';
|
||||
import icon from '../helpers/icon';
|
||||
import listItems from '../helpers/listItems';
|
||||
|
||||
export interface IDropdownAttrs extends ComponentAttrs{
|
||||
/**
|
||||
* A class name to apply to the dropdown toggle button.
|
||||
*/
|
||||
buttonClassName?: string;
|
||||
|
||||
/**
|
||||
* A class name to apply to the dropdown menu.
|
||||
*/
|
||||
menuClassName?: string;
|
||||
|
||||
/**
|
||||
* The name of an icon to show in the dropdown toggle button.
|
||||
*/
|
||||
icon?: string;
|
||||
|
||||
/**
|
||||
* The name of an icon to show on the right of the button.
|
||||
*/
|
||||
caretIcon?: string;
|
||||
|
||||
/**
|
||||
* The label of the dropdown toggle button. Defaults to 'Controls'.
|
||||
*/
|
||||
label?: Mithril.Children;
|
||||
|
||||
/**
|
||||
* The label used to describe the dropdown toggle button to assistive readers.
|
||||
* Defaults to 'Toggle dropdown menu'.
|
||||
*/
|
||||
accessibleToggleLabel?: string;
|
||||
|
||||
/**
|
||||
* A callback to run when the dropdown is shown.
|
||||
*/
|
||||
onshow?: () => void;
|
||||
|
||||
/**
|
||||
* A callback to run when the dropdown is hidden.
|
||||
*/
|
||||
onhide?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Dropdown` component displays a button which, when clicked, shows a
|
||||
* dropdown menu beneath it.
|
||||
*
|
||||
* ### Attrs
|
||||
*
|
||||
* - `buttonClassName` A class name to apply to the dropdown toggle button.
|
||||
* - `menuClassName` A class name to apply to the dropdown menu.
|
||||
* - `icon` The name of an icon to show in the dropdown toggle button.
|
||||
* - `caretIcon` The name of an icon to show on the right of the button.
|
||||
* - `label` The label of the dropdown toggle button. Defaults to 'Controls'.
|
||||
* - `accessibleToggleLabel` The label used to describe the dropdown toggle button to assistive readers. Defaults to 'Toggle dropdown menu'.
|
||||
* - `onhide`
|
||||
* - `onshow`
|
||||
*
|
||||
* The children will be displayed as a list inside of the dropdown menu.
|
||||
*/
|
||||
export default class Dropdown extends Component {
|
||||
static initAttrs(attrs) {
|
||||
export default class Dropdown<CustomAttrs extends IDropdownAttrs = IDropdownAttrs> extends Component<CustomAttrs> {
|
||||
static initAttrs(attrs: IDropdownAttrs) {
|
||||
attrs.className = attrs.className || '';
|
||||
attrs.buttonClassName = attrs.buttonClassName || '';
|
||||
attrs.menuClassName = attrs.menuClassName || '';
|
||||
@@ -30,13 +64,9 @@ export default class Dropdown extends Component {
|
||||
attrs.accessibleToggleLabel = attrs.accessibleToggleLabel || app.translator.trans('core.lib.dropdown.toggle_dropdown_accessible_label');
|
||||
}
|
||||
|
||||
oninit(vnode) {
|
||||
super.oninit(vnode);
|
||||
protected showing = false;
|
||||
|
||||
this.showing = false;
|
||||
}
|
||||
|
||||
view(vnode) {
|
||||
view(vnode: Mithril.VnodeDOM<CustomAttrs, this>) {
|
||||
const items = vnode.children ? listItems(vnode.children) : [];
|
||||
const renderItems = this.attrs.lazyDraw ? this.showing : true;
|
||||
|
||||
@@ -48,7 +78,7 @@ export default class Dropdown extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
oncreate(vnode) {
|
||||
oncreate(vnode: Mithril.VnodeDOM<CustomAttrs, this>) {
|
||||
super.oncreate(vnode);
|
||||
|
||||
// When opening the dropdown menu, work out if the menu goes beyond the
|
||||
@@ -80,13 +110,13 @@ export default class Dropdown extends Component {
|
||||
|
||||
$menu.removeClass('Dropdown-menu--top Dropdown-menu--right');
|
||||
|
||||
$menu.toggleClass('Dropdown-menu--top', $menu.offset().top + $menu.height() > $(window).scrollTop() + $(window).height());
|
||||
$menu.toggleClass('Dropdown-menu--top', $menu.offset()!.top + $menu.height()! > $(window).scrollTop()! + $(window).height()!);
|
||||
|
||||
if ($menu.offset().top < 0) {
|
||||
if ($menu.offset()!.top < 0) {
|
||||
$menu.removeClass('Dropdown-menu--top');
|
||||
}
|
||||
|
||||
$menu.toggleClass('Dropdown-menu--right', isRight || $menu.offset().left + $menu.width() > $(window).scrollLeft() + $(window).width());
|
||||
$menu.toggleClass('Dropdown-menu--right', isRight || $menu.offset()!.left + $menu.width()! > $(window).scrollLeft()! + $(window).width()!);
|
||||
});
|
||||
|
||||
this.$().on('hidden.bs.dropdown', () => {
|
||||
@@ -102,11 +132,8 @@ export default class Dropdown extends Component {
|
||||
|
||||
/**
|
||||
* Get the template for the button.
|
||||
*
|
||||
* @return {*}
|
||||
* @protected
|
||||
*/
|
||||
getButton(children) {
|
||||
protected getButton(children: Mithril.Children): Mithril.Children {
|
||||
return (
|
||||
<button
|
||||
className={'Dropdown-toggle ' + this.attrs.buttonClassName}
|
||||
@@ -122,11 +149,8 @@ export default class Dropdown extends Component {
|
||||
|
||||
/**
|
||||
* Get the template for the button's content.
|
||||
*
|
||||
* @return {*}
|
||||
* @protected
|
||||
*/
|
||||
getButtonContent(children) {
|
||||
protected getButtonContent(children: Mithril.Children): Mithril.Children {
|
||||
return [
|
||||
this.attrs.icon ? icon(this.attrs.icon, { className: 'Button-icon' }) : '',
|
||||
<span className="Button-label">{this.attrs.label}</span>,
|
||||
@@ -134,7 +158,7 @@ export default class Dropdown extends Component {
|
||||
];
|
||||
}
|
||||
|
||||
getMenu(items) {
|
||||
protected getMenu(items: Mithril.Children): Mithril.Children {
|
||||
return <ul className={'Dropdown-menu dropdown-menu ' + this.attrs.menuClassName}>{items}</ul>;
|
||||
}
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
import Dropdown from './Dropdown';
|
||||
import type Mithril from 'mithril';
|
||||
import Dropdown, { IDropdownAttrs } from './Dropdown';
|
||||
import icon from '../helpers/icon';
|
||||
import { ModdedVnode } from '../helpers/listItems';
|
||||
|
||||
/**
|
||||
* Determines via a vnode is currently "active".
|
||||
@@ -9,8 +11,8 @@ import icon from '../helpers/icon';
|
||||
*
|
||||
* This is a temporary patch, and as so, is not exported / placed in utils.
|
||||
*/
|
||||
function isActive(vnode) {
|
||||
const tag = vnode.tag;
|
||||
function isActive(vnode: ModdedVnode<{}>) {
|
||||
const tag = vnode.tag as VnodeElementTag;
|
||||
|
||||
// Allow non-selectable dividers/headers to be added.
|
||||
if (typeof tag === 'string' && tag !== 'a' && tag !== 'button') return false;
|
||||
@@ -19,21 +21,29 @@ function isActive(vnode) {
|
||||
tag.initAttrs(vnode.attrs);
|
||||
}
|
||||
|
||||
return 'isActive' in tag ? tag.isActive(vnode.attrs) : vnode.attrs.active;
|
||||
return 'isActive' in tag ? tag.isActive(vnode.attrs) : (vnode.attrs as any).active;
|
||||
}
|
||||
|
||||
export interface ISelectDropdownAttrs extends IDropdownAttrs {
|
||||
/**
|
||||
* An icon for the select dropdown's caret.
|
||||
*/
|
||||
caretIcon?: string;
|
||||
|
||||
/**
|
||||
* The default label if no child is active.
|
||||
*/
|
||||
defaultLabel?: Mithril.Children;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The `SelectDropdown` component is the same as a `Dropdown`, except the toggle
|
||||
* button's label is set as the label of the first child which has a truthy
|
||||
* `active` prop.
|
||||
*
|
||||
* ### Attrs
|
||||
*
|
||||
* - `caretIcon`
|
||||
* - `defaultLabel`
|
||||
*/
|
||||
export default class SelectDropdown extends Dropdown {
|
||||
static initAttrs(attrs) {
|
||||
export default class SelectDropdown<CustomAttrs extends ISelectDropdownAttrs = ISelectDropdownAttrs> extends Dropdown<CustomAttrs> {
|
||||
static initAttrs(attrs: ISelectDropdownAttrs) {
|
||||
attrs.caretIcon = typeof attrs.caretIcon !== 'undefined' ? attrs.caretIcon : 'fas fa-sort';
|
||||
|
||||
super.initAttrs(attrs);
|
||||
@@ -41,12 +51,12 @@ export default class SelectDropdown extends Dropdown {
|
||||
attrs.className += ' Dropdown--select';
|
||||
}
|
||||
|
||||
getButtonContent(children) {
|
||||
const activeChild = children.find(isActive);
|
||||
let label = (activeChild && activeChild.children) || this.attrs.defaultLabel;
|
||||
protected getButtonContent(children: Mithril.Children): Mithril.ChildArray {
|
||||
const activeChild = Array.isArray(children) ? children.find(isActive) : children;
|
||||
let label = (activeChild && typeof activeChild === 'object' && 'children' in activeChild && activeChild.children) || this.attrs.defaultLabel;
|
||||
|
||||
if (label instanceof Array) label = label[0];
|
||||
|
||||
return [<span className="Button-label">{label}</span>, icon(this.attrs.caretIcon, { className: 'Button-caret' })];
|
||||
return [<span className="Button-label">{label}</span>, icon(this.attrs.caretIcon!, { className: 'Button-caret' })];
|
||||
}
|
||||
}
|
@@ -1,20 +1,25 @@
|
||||
import Dropdown from './Dropdown';
|
||||
import type Mithril from 'mithril';
|
||||
import Dropdown, { IDropdownAttrs } from './Dropdown';
|
||||
import Button from './Button';
|
||||
import icon from '../helpers/icon';
|
||||
|
||||
export interface ISplitDropdownAttrs extends IDropdownAttrs {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The `SplitDropdown` component is similar to `Dropdown`, but the first child
|
||||
* is displayed as its own button prior to the toggle button.
|
||||
*/
|
||||
export default class SplitDropdown extends Dropdown {
|
||||
static initAttrs(attrs) {
|
||||
export default class SplitDropdown<CustomAttrs extends ISplitDropdownAttrs = ISplitDropdownAttrs> extends Dropdown<CustomAttrs> {
|
||||
static initAttrs(attrs: ISplitDropdownAttrs) {
|
||||
super.initAttrs(attrs);
|
||||
|
||||
attrs.className += ' Dropdown--split';
|
||||
attrs.menuClassName += ' Dropdown-menu--right';
|
||||
}
|
||||
|
||||
getButton(children) {
|
||||
getButton(children: Mithril.ChildArray): Mithril.Children {
|
||||
// Make a copy of the attrs of the first child component. We will assign
|
||||
// these attrs to a new button, so that it has exactly the same behaviour as
|
||||
// the first child.
|
||||
@@ -39,11 +44,8 @@ export default class SplitDropdown extends Dropdown {
|
||||
/**
|
||||
* Get the first child. If the first child is an array, the first item in that
|
||||
* array will be returned.
|
||||
*
|
||||
* @return {*}
|
||||
* @protected
|
||||
*/
|
||||
getFirstChild(children) {
|
||||
protected getFirstChild(children: Mithril.Children): Mithril.Vnode {
|
||||
let firstChild = children;
|
||||
|
||||
while (firstChild instanceof Array) firstChild = firstChild[0];
|
Reference in New Issue
Block a user