reblend-ui
Version:
Utilities for creating robust overlay components
121 lines (119 loc) • 3.95 kB
JavaScript
"use strict";
exports.__esModule = true;
exports.default = void 0;
exports.useNavItem = useNavItem;
var _reblendjs = require("reblendjs");
var Reblend = _reblendjs;
var _reblendHooks = require("reblend-hooks");
var _NavContext = require("./NavContext");
var _SelectableContext = require("./SelectableContext");
var _Button = require("./Button");
var _DataKey = require("./DataKey");
var _TabContext = require("./TabContext");
function useNavItem({
key,
onClick,
active,
id,
role,
disabled
}) {
const [parentOnSelect] = _reblendjs.useContext.bind(this)(_SelectableContext.default, "parentOnSelect");
this.state.parentOnSelect = parentOnSelect;
const [navContext] = _reblendjs.useContext.bind(this)(_NavContext.default, "navContext");
this.state.navContext = navContext;
const [tabContext] = _reblendjs.useContext.bind(this)(_TabContext.default, "tabContext");
this.state.tabContext = tabContext;
let isActive = active;
this.state.isActive = isActive;
const props = {
role
};
this.state.props = props;
if (this.state.navContext) {
if (!role && this.state.navContext.role === 'tablist') this.state.props.role = 'tab';
const contextControllerId = this.state.navContext.getControllerId(key ?? null);
const contextControlledId = this.state.navContext.getControlledId(key ?? null);
this.state.props[(0, _DataKey.dataAttr)('event-key')] = key;
this.state.props.id = contextControllerId || id;
this.state.isActive = active == null && key != null ? this.state.navContext.activeKey === key : active;
/**
* Simplified scenario for `mountOnEnter`.
*
* While it would make sense to keep 'aria-controls' for tabs that have been mounted at least
* once, it would also complicate the code quite a bit, for very little gain.
* The following implementation is probably good enough.
*
* @see https://github.com/react-restart/ui/pull/40#issuecomment-1009971561
*/
if (this.state.isActive || !this.state.tabContext?.unmountOnExit && !this.state.tabContext?.mountOnEnter) this.state.props['aria-controls'] = contextControlledId;
}
if (this.state.props.role === 'tab') {
this.state.props['aria-selected'] = this.state.isActive;
if (!this.state.isActive) {
this.state.props.tabIndex = -1;
}
if (disabled) {
this.state.props.tabIndex = -1;
this.state.props['aria-disabled'] = true;
}
}
this.state.props.onClick = _reblendHooks.useEventCallback.bind(this)(e => {
if (disabled) return;
onClick?.(e);
if (key == null) {
return;
}
if (this.state.parentOnSelect && !e.isPropagationStopped()) {
this.state.parentOnSelect(key, e);
}
});
return [this.state.props, {
isActive: this.state.isActive
}];
}
/* @Reblend: Transformed from function to class */
const NavItem = class
/* @Reblend: Transformed from function to class */
extends Reblend.Reblend {
static ELEMENT_NAME = "NavItem";
constructor() {
super();
}
async initState() {
const [props, meta] = useNavItem.bind(this)({
key: (0, _SelectableContext.makeEventKey)(this.props.eventKey, this.props.href),
active: this.props.active,
...this.props
});
this.state.props = props;
this.state.meta = meta;
this.state.props[(0, _DataKey.dataAttr)('active')] = this.state.meta.isActive;
}
async initProps({
as: Component = _Button.default,
active,
eventKey,
ref,
...options
}) {
this.props = {};
this.props.Component = Component;
this.props.active = active;
this.props.eventKey = eventKey;
this.props.ref = ref;
this.props = {
...this.props,
...options
};
}
async html() {
return Reblend.Reblend.construct.bind(this)(this.props.Component, {
...this.props,
...this.state.props,
ref: this.props.ref
});
}
};
NavItem.displayName = 'NavItem';
var _default = exports.default = NavItem;