@workday/canvas-kit-preview-react
Version:
Canvas Kit Preview is made up of components that have the full design and a11y review, are part of the DS ecosystem and are approved for use in product. The API's could be subject to change, but not without strong communication and migration strategies.
254 lines (253 loc) • 11 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeprecatedMenuItem = void 0;
const React = __importStar(require("react"));
const styled_1 = __importDefault(require("@emotion/styled"));
const tokens_1 = require("@workday/canvas-kit-react/tokens");
const icon_1 = require("@workday/canvas-kit-react/icon");
const Item = (0, styled_1.default)('li')({
...tokens_1.type.levels.subtext.large,
padding: `${tokens_1.space.xxs} ${tokens_1.space.s}`,
height: tokens_1.space.xl,
boxSizing: 'border-box',
cursor: 'pointer',
color: tokens_1.colors.blackPepper300,
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
transition: 'background-color 80ms, color 80ms',
'&:focus': {
outline: 'none',
},
}, ({ isHeader }) => {
return { pointerEvents: isHeader ? 'none' : 'all' };
}, ({ isFocused, isDisabled }) => {
if (!isFocused && !isDisabled) {
return {
backgroundColor: 'inherit',
'&:hover': {
backgroundColor: tokens_1.commonColors.hoverBackground,
color: tokens_1.colors.blackPepper300,
'.wd-icon-fill, .wd-icon-accent, .wd-icon-accent2': {
fill: tokens_1.iconColors.hover,
},
},
};
}
else if (isDisabled && !isFocused) {
return {
color: tokens_1.colors.licorice100,
cursor: 'default',
};
}
else {
// Is focused or focused and disabled
return {
backgroundColor: isDisabled ? tokens_1.colors.blueberry200 : tokens_1.commonColors.focusBackground,
color: tokens_1.typeColors.inverse,
'span .wd-icon-background ~ .wd-icon-accent, .wd-icon-background ~ .wd-icon-accent2': {
fill: isDisabled ? tokens_1.iconColors.disabled : tokens_1.iconColors.active,
},
'&:hover': {
'span .wd-icon-fill, span .wd-icon-accent, span .wd-icon-accent2': {
fill: tokens_1.iconColors.inverse,
},
'span .wd-icon-background ~ .wd-icon-accent, span .wd-icon-background ~ .wd-icon-accent2': {
fill: isDisabled ? tokens_1.iconColors.disabled : tokens_1.iconColors.active,
},
'span .wd-icon-background': {
fill: tokens_1.iconColors.inverse,
},
},
[`[data-whatinput='mouse'] &,
[data-whatinput='touch'] &,
[data-whatinput='pointer'] &`]: {
backgroundColor: 'inherit',
color: tokens_1.colors.blackPepper300,
'span .wd-icon-background ~ .wd-icon-accent, span .wd-icon-background ~ .wd-icon-accent2': {
fill: tokens_1.iconColors.standard,
},
'&:hover': {
backgroundColor: tokens_1.commonColors.hoverBackground,
'span .wd-icon-fill, span .wd-icon-accent, span .wd-icon-accent2': {
fill: tokens_1.iconColors.hover,
},
},
'.wd-icon-fill, .wd-icon-accent, .wd-icon-accent2': {
fill: tokens_1.iconColors.standard,
},
},
};
}
});
const LabelContainer = (0, styled_1.default)('span')({
flex: '1 1 auto',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
});
const Divider = (0, styled_1.default)('hr')({
display: 'block',
height: 1,
border: 0,
borderTop: `1px solid ${tokens_1.colors.soap400}`,
margin: `${tokens_1.space.xxs} 0`,
});
const iconSize = 24;
const iconPadding = 16;
const StyledSystemIcon = (0, styled_1.default)(icon_1.SystemIcon)({
minWidth: iconSize + iconPadding, // gives padding between LabelContainer, no matter the direction
});
const SecondaryStyledSystemIcon = (0, styled_1.default)(icon_1.SystemIcon)({
display: `flex`,
minWidth: iconSize + iconPadding,
justifyContent: `flex-end`,
});
let iconProps = null;
let secondaryIconProps = null;
const setIconProps = (icon, isDisabled, isFocused) => {
if (!icon) {
return null;
}
let props = {
icon: icon,
size: iconSize,
};
if (isDisabled) {
props = {
...props,
fill: tokens_1.iconColors.disabled,
fillHover: tokens_1.iconColors.disabled,
accent: tokens_1.iconColors.disabled,
accentHover: tokens_1.iconColors.disabled,
};
}
if (isFocused) {
props = {
...props,
fill: tokens_1.iconColors.inverse,
fillHover: tokens_1.iconColors.inverse,
accent: tokens_1.iconColors.inverse,
accentHover: tokens_1.iconColors.inverse,
background: tokens_1.iconColors.inverse,
};
}
return props;
};
const scrollIntoViewIfNeeded = (elem, centerIfNeeded = true) => {
const parent = elem.parentElement;
if (elem && parent) {
const parentComputedStyle = window.getComputedStyle(parent, null), parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width'), 10), parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width'), 10), overTop = elem.offsetTop - parent.offsetTop < parent.scrollTop, overBottom = elem.offsetTop - parent.offsetTop + elem.clientHeight - parentBorderTopWidth >
parent.scrollTop + parent.clientHeight, overLeft = elem.offsetLeft - parent.offsetLeft < parent.scrollLeft, overRight = elem.offsetLeft - parent.offsetLeft + elem.clientWidth - parentBorderLeftWidth >
parent.scrollLeft + parent.clientWidth, alignWithTop = overTop && !overBottom;
if ((overTop || overBottom) && centerIfNeeded) {
parent.scrollTop =
elem.offsetTop -
parent.offsetTop -
parent.clientHeight / 2 -
parentBorderTopWidth +
elem.clientHeight / 2;
}
if ((overLeft || overRight) && centerIfNeeded) {
parent.scrollLeft =
elem.offsetLeft -
parent.offsetLeft -
parent.clientWidth / 2 -
parentBorderLeftWidth +
elem.clientWidth / 2;
}
if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
elem.scrollIntoView(alignWithTop);
}
}
};
/**
* `DeprecatedMenuItem` renders an `<li>` element with the correct attributes to ensure it is
* accessible. If you choose to implement your own custom menu items, be sure to use semantic `<li>`
* elements with the following attributes:
*
* - `role="menuitem"`
* - `tabindex={-1}`
* - `id`s following this pattern: `${MenuId}-${index}`
*
* Undocumented props are spread to the underlying `<li>` element.
*
* @deprecated ⚠️ `DeprecatedMenuItem` has been deprecated and will be removed in a future major version. Please use [Menu in Main](https://workday.github.io/canvas-kit/?path=/docs/components-popups-menu--basic) instead.
*
*/
class DeprecatedMenuItem extends React.Component {
constructor() {
super(...arguments);
this.ref = React.createRef();
this.componentDidUpdate = (prevProps) => {
if (!prevProps.isFocused && this.props.isFocused) {
if (this.ref.current) {
scrollIntoViewIfNeeded(this.ref.current);
}
}
};
this.handleClick = (event) => {
if (this.props.isDisabled) {
return;
}
if (this.props.onClick) {
this.props.onClick(event);
}
};
}
componentDidMount() {
console.warn(`This component is being deprecated and will be removed in a future major version.\n
For more information, please see the V8 upgrade guide:\n
https://workday.github.io/canvas-kit/?path=/docs/guides-upgrade-guides-v8-0--docs#menu-preview
`);
}
render() {
const { onClick, children, id, icon, secondaryIcon, hasDivider, isDisabled, isFocused, isHeader, role, ...elemProps } = this.props;
iconProps = setIconProps(icon, isDisabled, isFocused);
secondaryIconProps = setIconProps(secondaryIcon, isDisabled, isFocused);
return (React.createElement(React.Fragment, null,
hasDivider && React.createElement(Divider, { "aria-hidden": "true" }),
React.createElement(Item, { ref: this.ref, tabIndex: -1, id: id, role: isHeader ? 'presentation' : role, "aria-hidden": isHeader ? true : undefined, onClick: this.handleClick, "aria-disabled": isDisabled ? true : undefined, isDisabled: !!isDisabled, isFocused: !!isFocused, isHeader: !!isHeader, ...elemProps },
icon && iconProps && React.createElement(StyledSystemIcon, { ...iconProps }),
React.createElement(LabelContainer, null, children),
secondaryIcon && secondaryIconProps && (React.createElement(SecondaryStyledSystemIcon, { ...secondaryIconProps })))));
}
}
exports.DeprecatedMenuItem = DeprecatedMenuItem;
/**
* If we destructure props, shouldClose will be undefined because the value is only applied for the render method only.
* We have to use defaultProps so that the value of shouldClose is applied for every method and therefore references in the Menu component.
* For reference: https://github.com/Workday/canvas-kit/blob/f6d4d29e9bb2eb2af0b204e6f4ce2e5ed5a98e57/modules/_labs/menu/react/lib/Menu.tsx#L259,
*/
// TODO: Remove this ts-ignore when we convert to a functional component
// @ts-ignore
DeprecatedMenuItem.defaultProps = {
shouldClose: true,
role: 'menuitem',
};
;