@engie-group/fluid-design-system-react
Version:
Fluid Design System React
1,522 lines (1,442 loc) • 418 kB
JavaScript
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var ReactDOM = require('react-dom');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
var ReactDOM__namespace = /*#__PURE__*/_interopNamespaceDefault(ReactDOM);
const isUndefinedOrNull = (value) => {
return typeof value === 'undefined' || value === null;
};
/**
* Generates a string from arguments that can be a string, number, array or objects with {key: value} where key is a class and value is a boolean
*/
const classNames = (...args) => {
const classes = [];
for (const arg of args) {
if (!arg) {
continue;
}
const argType = typeof arg;
if (argType === 'string' || argType === 'number') {
classes.push(arg);
}
else if (Array.isArray(arg)) {
if (arg.length) {
const inner = Utils.classNames.apply(null, arg);
if (inner) {
classes.push(inner);
}
}
}
else if (argType === 'object') {
const typedArg = arg;
if (typedArg.toString === Object.prototype.toString) {
for (const key in typedArg) {
if (Object.prototype.hasOwnProperty.call(typedArg, key) && typedArg[key]) {
classes.push(key);
}
}
}
else {
classes.push(typedArg.toString());
}
}
}
if (classes.length === 0) {
return undefined;
}
return classes.join(' ');
};
const coerceFunction = (func) => {
if (!isUndefinedOrNull(func) && typeof func === 'function') {
return func;
}
else {
return null;
}
};
const mergeRefs = (refs) => {
return (value) => {
refs.forEach((ref) => {
if (typeof ref === 'function') {
ref(value);
}
else if (ref != null) {
ref.current = value;
}
});
};
};
const normalizeString = (text) => {
return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
};
const normalizeAndSearchInText = (text, search) => {
if (Utils.isUndefinedOrNull(text) || Utils.isUndefinedOrNull(search)) {
return false;
}
const normalizedText = Utils.normalizeString(text);
// removed in 2.13.0: `normalizedSearch` used to filter out (, ) and \ through `.replace(/\(|\)|\\/gi, '');`
const normalizedSearch = Utils.normalizeString(search);
const regExp = new RegExp(Utils.escapeRegExp(normalizedSearch), 'gi');
return normalizedText.search(regExp) !== -1;
};
// Escape special characters in a string (so regex behave properly)
const escapeRegExp = (string) => {
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
};
const highlightTextAsHtml = (content, textToHighlight, caseSensitive = false, escapeAccents = true, openingTag = '<mark class="nj-highlight">', closingTag = '</mark>') => {
const regexFlags = caseSensitive ? 'g' : 'gi';
// Escape the textToHighlight to handle special characters
const escapedTextToHighlight = Utils.escapeRegExp(textToHighlight);
let innerHtml;
if (Utils.isUndefinedOrNull(textToHighlight)) {
innerHtml = content;
}
else {
if (escapeAccents) {
const regExp = new RegExp(Utils.normalizeString(escapedTextToHighlight), regexFlags);
const matches = Utils.normalizeString(content).matchAll(regExp);
let finalText = content;
let buffer = 0;
if (!Utils.isUndefinedOrNull(matches)) {
for (const match of matches) {
const updatedIndex = buffer + match.index;
const textBeforeOccurrence = finalText.slice(0, updatedIndex);
const occurrence = finalText.slice(updatedIndex, updatedIndex + textToHighlight.length);
const textAfterOccurrence = finalText.slice(updatedIndex + textToHighlight.length, finalText.length);
finalText = `${textBeforeOccurrence}${openingTag}${occurrence}${closingTag}${textAfterOccurrence}`;
buffer = buffer + openingTag.length + closingTag.length;
}
}
innerHtml = finalText;
}
else {
const regExp = new RegExp(escapedTextToHighlight, regexFlags);
innerHtml = content.replace(regExp, `${openingTag}$&${closingTag}`);
}
}
return innerHtml;
};
const omit = (obj, ...keys) => {
return Object.fromEntries(Object.entries(obj).filter(([key]) => {
return !keys.includes(key);
}));
};
const initializeContext = (rootComponentNamespace, message = 'Context not provided') => {
const InitializedContext = React.createContext(undefined);
const useInitializedContext = () => {
const context = React.useContext(InitializedContext);
if (!context) {
const errorMessage = rootComponentNamespace
? `${rootComponentNamespace} components must be wrapped in <${rootComponentNamespace}Root> or <${rootComponentNamespace}.Root> component`
: message;
throw new Error(errorMessage);
}
return context;
};
return [InitializedContext, useInitializedContext];
};
const initializeSoftContext = () => {
const InitializedContext = React.createContext(undefined);
const useInitializedContext = () => {
return React.useContext(InitializedContext);
};
return [InitializedContext, useInitializedContext];
};
const Utils = {
isUndefinedOrNull,
classNames,
coerceFunction,
mergeRefs,
normalizeString,
normalizeAndSearchInText,
escapeRegExp,
highlightTextAsHtml,
omit,
initializeContext,
initializeSoftContext
};
const NJAccordionContext = React.createContext({});
const NJAccordion = React.forwardRef(({ children, isSeparated, withoutBorder, className, ...props }, forwardedRef) => {
const ref = React.useRef(null);
const newRef = Utils.mergeRefs([forwardedRef, ref]);
const [hasAlternativeToggleIcon, setHasAlternativeToggleIcon] = React.useState();
const [customIcon, setCustomIcon] = React.useState();
const action = (type) => () => {
const allItems = ref.current?.querySelectorAll(`details.nj-accordion-item`);
allItems?.forEach((item) => {
if (type === 'expand') {
item.setAttribute('open', '');
}
else {
item.removeAttribute('open');
}
});
};
const classNames = Utils.classNames('nj-accordion', {
'nj-accordion--no-border': withoutBorder,
'nj-accordion--separated': isSeparated
}, className);
return (jsxRuntime.jsx(NJAccordionContext.Provider, { value: {
action,
hasAlternativeToggleIcon,
setHasAlternativeToggleIcon,
customIcon,
setCustomIcon
}, children: jsxRuntime.jsx("div", { ...props, className: classNames, ref: newRef, children: children }) }));
});
NJAccordion.displayName = 'NJAccordion';
// packages/react/compose-refs/src/compose-refs.tsx
function setRef(ref, value) {
if (typeof ref === "function") {
return ref(value);
} else if (ref !== null && ref !== void 0) {
ref.current = value;
}
}
function composeRefs(...refs) {
return (node) => {
let hasCleanup = false;
const cleanups = refs.map((ref) => {
const cleanup = setRef(ref, node);
if (!hasCleanup && typeof cleanup == "function") {
hasCleanup = true;
}
return cleanup;
});
if (hasCleanup) {
return () => {
for (let i = 0; i < cleanups.length; i++) {
const cleanup = cleanups[i];
if (typeof cleanup == "function") {
cleanup();
} else {
setRef(refs[i], null);
}
}
};
}
};
}
// src/slot.tsx
// @__NO_SIDE_EFFECTS__
function createSlot(ownerName) {
const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
const Slot2 = React__namespace.forwardRef((props, forwardedRef) => {
const { children, ...slotProps } = props;
const childrenArray = React__namespace.Children.toArray(children);
const slottable = childrenArray.find(isSlottable);
if (slottable) {
const newElement = slottable.props.children;
const newChildren = childrenArray.map((child) => {
if (child === slottable) {
if (React__namespace.Children.count(newElement) > 1) return React__namespace.Children.only(null);
return React__namespace.isValidElement(newElement) ? newElement.props.children : null;
} else {
return child;
}
});
return /* @__PURE__ */ jsxRuntime.jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React__namespace.isValidElement(newElement) ? React__namespace.cloneElement(newElement, void 0, newChildren) : null });
}
return /* @__PURE__ */ jsxRuntime.jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
});
Slot2.displayName = `${ownerName}.Slot`;
return Slot2;
}
var Slot = /* @__PURE__ */ createSlot("Slot");
// @__NO_SIDE_EFFECTS__
function createSlotClone(ownerName) {
const SlotClone = React__namespace.forwardRef((props, forwardedRef) => {
const { children, ...slotProps } = props;
if (React__namespace.isValidElement(children)) {
const childrenRef = getElementRef(children);
const props2 = mergeProps$1(slotProps, children.props);
if (children.type !== React__namespace.Fragment) {
props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
}
return React__namespace.cloneElement(children, props2);
}
return React__namespace.Children.count(children) > 1 ? React__namespace.Children.only(null) : null;
});
SlotClone.displayName = `${ownerName}.SlotClone`;
return SlotClone;
}
var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
// @__NO_SIDE_EFFECTS__
function createSlottable(ownerName) {
const Slottable2 = ({ children }) => {
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
};
Slottable2.displayName = `${ownerName}.Slottable`;
Slottable2.__radixId = SLOTTABLE_IDENTIFIER;
return Slottable2;
}
var Slottable = /* @__PURE__ */ createSlottable("Slottable");
function isSlottable(child) {
return React__namespace.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
}
function mergeProps$1(slotProps, childProps) {
const overrideProps = { ...childProps };
for (const propName in childProps) {
const slotPropValue = slotProps[propName];
const childPropValue = childProps[propName];
const isHandler = /^on[A-Z]/.test(propName);
if (isHandler) {
if (slotPropValue && childPropValue) {
overrideProps[propName] = (...args) => {
const result = childPropValue(...args);
slotPropValue(...args);
return result;
};
} else if (slotPropValue) {
overrideProps[propName] = slotPropValue;
}
} else if (propName === "style") {
overrideProps[propName] = { ...slotPropValue, ...childPropValue };
} else if (propName === "className") {
overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
}
}
return { ...slotProps, ...overrideProps };
}
function getElementRef(element) {
let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
if (mayWarn) {
return element.ref;
}
getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
if (mayWarn) {
return element.props.ref;
}
return element.props.ref || element.ref;
}
/**
* Type guard to check if we're rendering the default component for the action. (`actionAsChild` is false)
* @param props - The props to check, they should be of type {@link ActionAsChild}.
* @returns whether or not we are rendering the default action component.
*/
function isDefaultAction(props) {
return !props.actionAsChild;
}
/**
* Type guard to check if we are using the default component (not asChild or actionAsChild).
* @param discriminant Used to discriminate between default and child rendering (mostly asChild props).
* @param props The rest of the destructured props intersection. All common props must be extracted from this object.
* @returns Wether or not we are using the default component.
*/
function isDefaultComponent(discriminant, props) {
return discriminant !== true;
}
// src/components/avatar/properties.ts
var AVATAR_SCALES = ["sm", "md", "lg", "xl", "2xl", "3xl"];
// src/components/badge/properties.ts
var BADGE_VARIANTS = [
"neutral",
"danger",
"warning",
"success",
"information",
"discovery",
"planet",
"ai"
];
var BADGE_EMPHASIS = ["bold", "subtle", "minimal"];
var BADGE_SCALES = ["sm", "md", "lg"];
// src/components/bullet/properties.ts
var BULLET_SIZES = ["sm", "md"];
var BULLET_VARIANTS = [
"grey",
"blue",
"teal",
"pink",
"orange",
"red",
"green",
"ultramarine",
"yellow",
"purple",
"lime"
];
// src/components/button/properties.ts
var BUTTON_SCALES = ["xs", "sm", "md", "lg", "xl"];
var BUTTON_VARIANTS = [
"primary",
"secondary",
"inverse",
"destructive",
"ai"
];
var BUTTON_EMPHASIS = ["bold", "subtle", "minimal"];
// src/components/chat-input-action-button/properties.ts
var CHAT_INPUT_ACTION_BUTTON_VARIANT = ["default", "ai"];
// src/components/chat-input/properties.ts
var CHAT_INPUT_VARIANT = ["default", "ai"];
// src/components/checkbox/properties.ts
var CHECKBOX_SCALES = ["md", "lg", "xl"];
var CHECKBOX_SUBSCRIPT_VARIANTS = ["error", "success"];
// src/components/display/properties.ts
var DISPLAY_SCALES = ["xs", "sm", "md", "xl", "2xl"];
var DISPLAY_VARIANTS = [
"danger",
"danger-contrast",
"warning",
"warning-contrast",
"success",
"success-contrast",
"information",
"information-contrast",
"discovery",
"discovery-contrast",
"planet",
"planet-contrast",
"brand",
"brand-contrast",
"signature",
"ai",
"primary",
"secondary",
"tertiary",
"contrast",
"inverse"
];
// src/components/divider/properties.ts
var DIVIDER_SCALES = [
"2xs",
"xs",
"sm",
"md",
"lg",
"xl",
"2xl",
"3xl"
];
// src/components/footer-card/properties.ts
var FOOTER_CARD_VARIANTS = [
"danger",
"warning",
"success",
"information",
"discovery",
"planet",
"neutral",
"brand"
];
// src/components/link/properties.ts
var LINK_VARIANTS = [
"default",
"inverse",
"grayed",
"contextual",
"high-contrast"
];
var LINK_SCALES = ["sm", "md"];
// src/components/footer-item/properties.ts
var FOOTER_ITEM_SCALES = LINK_SCALES;
var FOOTER_ITEM_PADDING = ["xs", "sm", "md", "lg"];
// src/components/footer/properties.ts
var FOOTER_VARIANTS = ["neutral", "brand"];
// src/components/header/properties.ts
var HEADER_LAYOUTS = ["expanded", "responsive", "retracted"];
var HEADER_LOGO_POSITIONS = ["left", "center"];
// src/components/heading/properties.ts
var HEADING_SCALES = ["xs", "sm", "md", "lg", "xl"];
var SEMANTIC_BY_SCALE = {
xl: "h2",
lg: "h3",
md: "h4",
sm: "h5",
xs: "h6"
};
var HEADING_VARIANTS = [
"danger",
"danger-contrast",
"warning",
"warning-contrast",
"success",
"success-contrast",
"information",
"information-contrast",
"discovery",
"discovery-contrast",
"planet",
"planet-contrast",
"brand",
"brand-contrast",
"signature",
"ai",
"primary",
"secondary",
"tertiary",
"contrast",
"inverse"
];
// src/components/icon-button/properties.ts
var ICON_BUTTON_SCALES = [
"2xs",
"xs",
"sm",
"md",
"lg",
"xl"
];
var ICON_BUTTON_VARIANTS = [
"primary",
"secondary",
"tertiary",
"brand",
"destructive",
"inverse"
];
// src/components/icon/properties.ts
var ICON_ENGIE_NAME = [
"engie_ai"
];
var ICON_SCALES = [
"2xs",
"xs",
"sm",
"md",
"lg",
"xl",
"2xl",
"3xl",
"4xl",
"5xl",
"6xl",
"inherit"
];
var ICON_VARIANTS = [
"brand",
"brand-contrast",
"primary",
"secondary",
"tertiary",
"contrast",
"inverse",
"danger",
"warning",
"success",
"information",
"discovery",
"planet",
"danger-contrast",
"warning-contrast",
"success-contrast",
"information-contrast",
"discovery-contrast",
"planet-contrast",
"grey",
"blue",
"teal",
"pink",
"orange",
"red",
"green",
"ultramarine",
"yellow",
"purple",
"lime",
"signature",
"ai",
"inherit"
];
var ICON_ENGIE_PREFIX = "engie_";
// src/components/inline-message/properties.ts
var INLINE_MESSAGE_VARIANTS = [
"error",
"fatal-error",
"information",
"success",
"warning",
"discovery",
"planet"
];
var INLINE_MESSAGE_ACTION_POSITION = ["bottom", "right"];
var INLINE_MESSAGE_SCALES = ["sm", "md"];
// src/components/input/properties.ts
var INPUT_SCALES = ["sm", "md", "lg", "xl"];
var INPUT_LABEL_KIND = ["static", "floating"];
var INPUT_SUBSCRIPT_VARIANT = ["error", "success"];
// src/components/list-item/list-navigation-item/properties.ts
var LIST_NAVIGATION_ITEM_VARIANTS = ["primary", "discovery"];
// src/components/list-item/properties.ts
var LIST_ITEM_TEXT_DISTRIBUTION = ["vertical", "horizontal"];
// src/components/list/properties.ts
var LIST_SCALES = ["sm", "md", "lg"];
// src/components/modal/modal-confirmation/properties.ts
var INFORMATION_MODAL_STATUS = ["neutral", "danger"];
// src/components/modal/modal-information/properties.ts
var CONFIRMATION_MODAL_STATUS = [
"information",
"success",
"warning",
"error",
"waiting"
];
// src/components/modal/properties.ts
var MODAL_CLOSED_BY = ["any", "closerequest", "none"];
// src/components/navigation/action/properties.ts
var NAVIGATION_ACTION_VARIANTS = [
"primary",
"brand",
"tertiary",
"inverse",
"discovery"
];
var NAVIGATION_ACTION_SCALES = ["xs", "sm", "md", "lg"];
// src/components/navigation/tab/properties.ts
var NAVIGATION_TAB_VARIANTS = [
"primary",
"brand",
"tertiary",
"inverse",
"discovery"
];
// src/components/segmented-control/properties.ts
var SEGMENTED_CONTROL_SCALES = ["sm", "md", "lg"];
// src/components/skeleton-circle/properties.ts
var SKELETON_CIRCLE_SCALES = [
"sm",
"md",
"lg",
"xl",
"2xl",
"3xl"
];
// src/components/skeleton-rectangle/properties.ts
var SKELETON_RECTANGLE_SCALES = [
"peta",
"tera",
"giga",
"mega",
"kilo",
"hecto",
"deca",
"base",
"deci",
"centi"
];
// src/components/spinner/properties.ts
var SPINNER_VARIANTS = ["normal", "inverse", "grey", "ai"];
var SPINNER_SCALES = ["2xs", "xs", "sm", "md", "lg"];
// src/components/status-indicator/properties.ts
var STATUS_INDICATOR_SCALES = ["sm", "md", "lg"];
var STATUS_INDICATOR_STATUSES = [
"offline",
"online",
"away",
"do-not-disturb",
"busy",
"unknown",
"error",
"success",
"warning",
"in-progress",
"information",
"discovery",
"planet",
"ai"
];
// src/components/sub-header/properties.ts
var SUB_HEADER_LAYOUT = ["rows", "columns", "single-column"];
// src/components/tabs/properties.ts
var TAB_SCALES = ["xs", "sm", "md", "lg"];
// src/components/tag/properties.ts
var TAG_VARIANTS = [
"brand",
"grey",
"blue",
"teal",
"pink",
"orange",
"red",
"green",
"ultramarine",
"yellow",
"purple",
"lime"
];
var TAG_SCALES = ["xs", "sm", "md", "lg", "xl"];
// src/components/text/properties.ts
var TEXT_SCALES = ["xs", "sm", "md", "lg"];
var TEXT_VARIANTS = [
"danger",
"danger-contrast",
"warning",
"warning-contrast",
"success",
"success-contrast",
"information",
"information-contrast",
"discovery",
"discovery-contrast",
"planet",
"planet-contrast",
"brand",
"brand-contrast",
"signature",
"primary",
"secondary",
"tertiary",
"contrast",
"inverse"
];
// src/components/textarea/properties.ts
var TEXTAREA_SCALES = ["sm", "md", "lg", "xl"];
var TEXTAREA_LABEL_KIND = ["static", "floating"];
var TEXTAREA_SUBSCRIPT_VARIANT = ["error", "success"];
// src/components/toggle/properties.ts
var TOGGLE_VARIANTS = ["brand", "ai"];
var TOGGLE_SCALES = ["md", "lg", "xl"];
// src/variations/scale.ts
var SCALES = [
"2xs",
"xs",
"sm",
"md",
"lg",
"xl",
"2xl",
"3xl",
"4xl",
"5xl",
"6xl"
];
// src/variations/variant.ts
var STATUS_PRIMARY_VARIANTS = [
"danger",
"warning",
"success",
"information",
"discovery",
"planet"
];
var STATUS_CONTRAST_VARIANTS = [
"danger-contrast",
"warning-contrast",
"success-contrast",
"information-contrast",
"discovery-contrast",
"planet-contrast"
];
var STATUS_VARIANTS = [
...STATUS_PRIMARY_VARIANTS,
...STATUS_CONTRAST_VARIANTS
];
var NEUTRAL_VARIANTS = [
"neutral",
"primary",
"secondary",
"tertiary",
"contrast",
"inverse"
];
var BRAND_VARIANTS = ["brand", "brand-contrast"];
var ACCENT_VARIANTS = [
"grey",
"blue",
"teal",
"pink",
"orange",
"red",
"green",
"ultramarine",
"yellow",
"purple",
"lime"
];
var ADDITIONAL_VARIANTS = ["signature", "ai"];
// src/variations/emphasis.ts
var EMPHASIS_VARIANTS = ["bold", "subtle", "minimal"];
const NJIcon = React.forwardRef(({ name, variant, scale: initialScale, // Fixme: Do not rename when size will be deleted
className, ...htmlProps }, ref) => {
const scale = initialScale;
const classes = Utils.classNames('material-icons', 'nj-icon-material', {
[`nj-icon-material--${scale === 'inherit' ? 'size-inherit' : scale}`]: !!scale,
[`nj-icon-material--${variant === 'inherit' ? 'color-inherit' : variant}`]: !!variant,
'nj-icon-material--engie': name.startsWith(ICON_ENGIE_PREFIX)
}, className);
return (jsxRuntime.jsx("span", { ...htmlProps, ref: ref, className: classes, style: htmlProps.onClick ? { ...htmlProps.style, cursor: 'pointer' } : htmlProps.style, "aria-hidden": "true", children: name }));
});
NJIcon.displayName = 'NJIcon';
const rootComponentClassName$2 = 'nj-spinner';
const NJSpinner = React.forwardRef((props, ref) => {
const { variant, scale, className, 'aria-label': ariaLabel = 'loading', ...htmlProps } = props;
// Visually hide the spinner wrapper if it is not loading
const spinnerClass = Utils.classNames('nj-spinner', {
[`${rootComponentClassName$2}--${variant}`]: variant,
[`${rootComponentClassName$2}--${scale}`]: scale
}, className);
return jsxRuntime.jsx("div", { ...htmlProps, ref: ref, className: spinnerClass, "aria-label": ariaLabel });
});
NJSpinner.displayName = 'NJSpinner';
function getCustomIconWithClassName(customIcon) {
if (!customIcon) {
return;
}
const className = Utils.classNames(customIcon.props.className, 'nj-btn__icon');
return React.cloneElement(customIcon, { className });
}
const NJButton = React.forwardRef((props, ref) => {
const { variant, emphasis, scale, isLoading, icon, children, visuallyDisabled, asChild, ...defaultProps } = props;
let btnClasses = Utils.classNames('nj-btn', {
[`nj-btn--${scale}`]: scale && scale !== 'md',
[`nj-btn--${variant}`]: variant && variant !== 'primary',
[`nj-btn--${emphasis}`]: emphasis && emphasis !== 'bold',
[`nj-btn--is-loading`]: isLoading,
[`nj-btn--disabled`]: visuallyDisabled
});
if (isDefaultComponent(asChild)) {
let customIcon;
let customLabel;
React.Children.forEach(children, (child) => {
if (!child) {
return;
}
if (React.isValidElement(child)) {
if (child.props['data-child-name'] === 'customIcon') {
customIcon = child;
}
if (child.props['data-child-name'] === 'customLabel') {
customLabel = child;
}
}
});
const { label, iconClassName, className, ...htmlProps } = defaultProps;
const hasLabel = label || customLabel;
const iconClass = Utils.classNames('nj-btn__icon', iconClassName);
const currentLabel = customLabel ? customLabel : label;
btnClasses = Utils.classNames(btnClasses, className);
return (jsxRuntime.jsxs("button", { type: "button", ref: ref, ...htmlProps, className: btnClasses, disabled: htmlProps.disabled || isLoading, children: [isLoading ? (jsxRuntime.jsx(NJSpinner, {})) : hasLabel && customIcon ? (getCustomIconWithClassName(customIcon)) : (icon && jsxRuntime.jsx(NJIcon, { name: icon, className: iconClass })), currentLabel] }));
}
const child = React.Children.only(children);
if (!React.isValidElement(child)) {
throw new Error('NJButton: When using asChild, a valid React element must be provided as a child.');
}
const clonedChild = React.cloneElement(child, {
className: Utils.classNames(btnClasses, child.props.className),
ref: ref
});
return jsxRuntime.jsx(Slot, { children: clonedChild });
});
NJButton.displayName = 'NJButton';
const NJAccordionAction = React.forwardRef(({ className, action: actionType, ...props }, forwardedRef) => {
const { action } = React.useContext(NJAccordionContext);
const onClick = (e) => {
action?.(actionType)();
props.onClick?.(e);
};
return (jsxRuntime.jsx(NJButton, { ...props, onClick: onClick, className: Utils.classNames('nj-accordion__action', className), ref: forwardedRef }));
});
NJAccordionAction.displayName = 'NJAccordionAction';
const NJAccordionActions = React.forwardRef(({ children, className, ...props }, forwardedRef) => {
return (jsxRuntime.jsx("div", { ...props, className: Utils.classNames('nj-accordion__actions', className), ref: forwardedRef, children: children }));
});
NJAccordionActions.displayName = 'NJAccordionActions';
const NJAccordionItem = React.forwardRef(({ children, scale, hasLeadingToggleIcon, hasAlternativeToggleIcon, icon, className, ...props }, forwardedRef) => {
const { setHasAlternativeToggleIcon, setCustomIcon } = React.useContext(NJAccordionContext);
React.useEffect(() => {
setHasAlternativeToggleIcon?.(hasAlternativeToggleIcon);
}, [hasAlternativeToggleIcon]);
React.useEffect(() => {
setCustomIcon?.(icon);
}, [icon]);
const ref = React.useRef(null);
const newRef = Utils.mergeRefs([forwardedRef, ref]);
const onToggle = (e) => {
if (e.nativeEvent.newState === 'open' || e.currentTarget.open) {
const allItems = document.querySelectorAll(`details.nj-accordion-item[name=${props.name}]`);
allItems.forEach((item) => {
if (item !== ref.current) {
item.removeAttribute('open');
}
});
}
props.onToggle?.(e);
};
const classNames = Utils.classNames('nj-accordion-item', {
[`nj-accordion-item--${scale}`]: !!scale && scale !== 'md',
[`nj-accordion-item--leading-toggle`]: hasLeadingToggleIcon
}, className);
return (jsxRuntime.jsx("details", { ref: newRef, ...props, onToggle: onToggle, className: classNames, children: children }));
});
NJAccordionItem.displayName = 'NJAccordionItem';
const NJAccordionItemContent = React.forwardRef(({ children, className, ...props }, forwardedRef) => {
return (jsxRuntime.jsx("div", { ...props, className: Utils.classNames('nj-accordion-item__content', className), ref: forwardedRef, children: children }));
});
NJAccordionItemContent.displayName = 'NJAccordionItemContent';
const NJAccordionItemHeader = React.forwardRef(({ children, ...props }, forwardedRef) => {
const { hasAlternativeToggleIcon, customIcon } = React.useContext(NJAccordionContext);
const newIcon = React.isValidElement(customIcon)
? React.cloneElement(customIcon, {
className: Utils.classNames(customIcon.props.className, 'nj-accordion-item__icon')
})
: null;
return (jsxRuntime.jsxs("summary", { ...props, ref: forwardedRef, children: [newIcon, jsxRuntime.jsx("span", { className: "nj-accordion-item__label", children: children }), hasAlternativeToggleIcon ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(NJIcon, { name: "add", className: "nj-accordion-item__toggle nj-accordion-item__toggle--closed" }), jsxRuntime.jsx(NJIcon, { name: "remove", className: "nj-accordion-item__toggle nj-accordion-item__toggle--opened" })] })) : (jsxRuntime.jsx(NJIcon, { name: "expand_more", className: "nj-accordion-item__toggle" }))] }));
});
NJAccordionItemHeader.displayName = 'NJAccordionItemHeader';
function hasWindow() {
return typeof window !== 'undefined';
}
function getNodeName(node) {
if (isNode(node)) {
return (node.nodeName || '').toLowerCase();
}
// Mocked nodes in testing environments may not be instances of Node. By
// returning `#document` an infinite loop won't occur.
// https://github.com/floating-ui/floating-ui/issues/2317
return '#document';
}
function getWindow(node) {
var _node$ownerDocument;
return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
}
function getDocumentElement(node) {
var _ref;
return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
}
function isNode(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Node || value instanceof getWindow(value).Node;
}
function isElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof Element || value instanceof getWindow(value).Element;
}
function isHTMLElement(value) {
if (!hasWindow()) {
return false;
}
return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
}
function isShadowRoot(value) {
if (!hasWindow() || typeof ShadowRoot === 'undefined') {
return false;
}
return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
}
const invalidOverflowDisplayValues = /*#__PURE__*/new Set(['inline', 'contents']);
function isOverflowElement(element) {
const {
overflow,
overflowX,
overflowY,
display
} = getComputedStyle$1(element);
return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
}
const tableElements = /*#__PURE__*/new Set(['table', 'td', 'th']);
function isTableElement(element) {
return tableElements.has(getNodeName(element));
}
const topLayerSelectors = [':popover-open', ':modal'];
function isTopLayer(element) {
return topLayerSelectors.some(selector => {
try {
return element.matches(selector);
} catch (_e) {
return false;
}
});
}
const transformProperties = ['transform', 'translate', 'scale', 'rotate', 'perspective'];
const willChangeValues = ['transform', 'translate', 'scale', 'rotate', 'perspective', 'filter'];
const containValues = ['paint', 'layout', 'strict', 'content'];
function isContainingBlock(elementOrCss) {
const webkit = isWebKit();
const css = isElement(elementOrCss) ? getComputedStyle$1(elementOrCss) : elementOrCss;
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
// https://drafts.csswg.org/css-transforms-2/#individual-transforms
return transformProperties.some(value => css[value] ? css[value] !== 'none' : false) || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || willChangeValues.some(value => (css.willChange || '').includes(value)) || containValues.some(value => (css.contain || '').includes(value));
}
function getContainingBlock(element) {
let currentNode = getParentNode(element);
while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
if (isContainingBlock(currentNode)) {
return currentNode;
} else if (isTopLayer(currentNode)) {
return null;
}
currentNode = getParentNode(currentNode);
}
return null;
}
function isWebKit() {
if (typeof CSS === 'undefined' || !CSS.supports) return false;
return CSS.supports('-webkit-backdrop-filter', 'none');
}
const lastTraversableNodeNames = /*#__PURE__*/new Set(['html', 'body', '#document']);
function isLastTraversableNode(node) {
return lastTraversableNodeNames.has(getNodeName(node));
}
function getComputedStyle$1(element) {
return getWindow(element).getComputedStyle(element);
}
function getNodeScroll(element) {
if (isElement(element)) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
return {
scrollLeft: element.scrollX,
scrollTop: element.scrollY
};
}
function getParentNode(node) {
if (getNodeName(node) === 'html') {
return node;
}
const result =
// Step into the shadow DOM of the parent of a slotted node.
node.assignedSlot ||
// DOM Element detected.
node.parentNode ||
// ShadowRoot detected.
isShadowRoot(node) && node.host ||
// Fallback.
getDocumentElement(node);
return isShadowRoot(result) ? result.host : result;
}
function getNearestOverflowAncestor(node) {
const parentNode = getParentNode(node);
if (isLastTraversableNode(parentNode)) {
return node.ownerDocument ? node.ownerDocument.body : node.body;
}
if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
return parentNode;
}
return getNearestOverflowAncestor(parentNode);
}
function getOverflowAncestors(node, list, traverseIframes) {
var _node$ownerDocument2;
if (list === void 0) {
list = [];
}
if (traverseIframes === void 0) {
traverseIframes = true;
}
const scrollableAncestor = getNearestOverflowAncestor(node);
const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
const win = getWindow(scrollableAncestor);
if (isBody) {
const frameElement = getFrameElement(win);
return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
}
return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
}
function getFrameElement(win) {
return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
}
function activeElement(doc) {
let activeElement = doc.activeElement;
while (((_activeElement = activeElement) == null || (_activeElement = _activeElement.shadowRoot) == null ? void 0 : _activeElement.activeElement) != null) {
var _activeElement;
activeElement = activeElement.shadowRoot.activeElement;
}
return activeElement;
}
function contains(parent, child) {
if (!parent || !child) {
return false;
}
const rootNode = child.getRootNode == null ? void 0 : child.getRootNode();
// First, attempt with faster native method
if (parent.contains(child)) {
return true;
}
// then fallback to custom implementation with Shadow DOM support
if (rootNode && isShadowRoot(rootNode)) {
let next = child;
while (next) {
if (parent === next) {
return true;
}
// @ts-ignore
next = next.parentNode || next.host;
}
}
// Give up, the result is false
return false;
}
// Avoid Chrome DevTools blue warning.
function getPlatform() {
const uaData = navigator.userAgentData;
if (uaData != null && uaData.platform) {
return uaData.platform;
}
return navigator.platform;
}
function getUserAgent() {
const uaData = navigator.userAgentData;
if (uaData && Array.isArray(uaData.brands)) {
return uaData.brands.map(_ref => {
let {
brand,
version
} = _ref;
return brand + "/" + version;
}).join(' ');
}
return navigator.userAgent;
}
// License: https://github.com/adobe/react-spectrum/blob/b35d5c02fe900badccd0cf1a8f23bb593419f238/packages/@react-aria/utils/src/isVirtualEvent.ts
function isVirtualClick(event) {
// FIXME: Firefox is now emitting a deprecation warning for `mozInputSource`.
// Try to find a workaround for this. `react-aria` source still has the check.
if (event.mozInputSource === 0 && event.isTrusted) {
return true;
}
if (isAndroid() && event.pointerType) {
return event.type === 'click' && event.buttons === 1;
}
return event.detail === 0 && !event.pointerType;
}
function isVirtualPointerEvent(event) {
if (isJSDOM()) return false;
return !isAndroid() && event.width === 0 && event.height === 0 || isAndroid() && event.width === 1 && event.height === 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === 'mouse' ||
// iOS VoiceOver returns 0.333• for width/height.
event.width < 1 && event.height < 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === 'touch';
}
function isSafari() {
// Chrome DevTools does not complain about navigator.vendor
return /apple/i.test(navigator.vendor);
}
function isAndroid() {
const re = /android/i;
return re.test(getPlatform()) || re.test(getUserAgent());
}
function isMac() {
return getPlatform().toLowerCase().startsWith('mac') && !navigator.maxTouchPoints;
}
function isJSDOM() {
return getUserAgent().includes('jsdom/');
}
function isMouseLikePointerType(pointerType, strict) {
// On some Linux machines with Chromium, mouse inputs return a `pointerType`
// of "pen": https://github.com/floating-ui/floating-ui/issues/2015
const values = ['mouse', 'pen'];
if (!strict) {
values.push('', undefined);
}
return values.includes(pointerType);
}
function isReactEvent(event) {
return 'nativeEvent' in event;
}
function isRootElement(element) {
return element.matches('html,body');
}
function getDocument(node) {
return (node == null ? void 0 : node.ownerDocument) || document;
}
function isEventTargetWithin(event, node) {
if (node == null) {
return false;
}
if ('composedPath' in event) {
return event.composedPath().includes(node);
}
// TS thinks `event` is of type never as it assumes all browsers support composedPath, but browsers without shadow dom don't
const e = event;
return e.target != null && node.contains(e.target);
}
function getTarget(event) {
if ('composedPath' in event) {
return event.composedPath()[0];
}
// TS thinks `event` is of type never as it assumes all browsers support
// `composedPath()`, but browsers without shadow DOM don't.
return event.target;
}
const TYPEABLE_SELECTOR = "input:not([type='hidden']):not([disabled])," + "[contenteditable]:not([contenteditable='false']),textarea:not([disabled])";
function isTypeableElement(element) {
return isHTMLElement(element) && element.matches(TYPEABLE_SELECTOR);
}
function stopEvent(event) {
event.preventDefault();
event.stopPropagation();
}
function isTypeableCombobox(element) {
if (!element) return false;
return element.getAttribute('role') === 'combobox' && isTypeableElement(element);
}
/**
* Custom positioning reference element.
* @see https://floating-ui.com/docs/virtual-elements
*/
const sides = ['top', 'right', 'bottom', 'left'];
const min = Math.min;
const max = Math.max;
const round = Math.round;
const floor = Math.floor;
const createCoords = v => ({
x: v,
y: v
});
const oppositeSideMap = {
left: 'right',
right: 'left',
bottom: 'top',
top: 'bottom'
};
const oppositeAlignmentMap = {
start: 'end',
end: 'start'
};
function clamp(start, value, end) {
return max(start, min(value, end));
}
function evaluate(value, param) {
return typeof value === 'function' ? value(param) : value;
}
function getSide(placement) {
return placement.split('-')[0];
}
function getAlignment(placement) {
return placement.split('-')[1];
}
function getOppositeAxis(axis) {
return axis === 'x' ? 'y' : 'x';
}
function getAxisLength(axis) {
return axis === 'y' ? 'height' : 'width';
}
const yAxisSides = /*#__PURE__*/new Set(['top', 'bottom']);
function getSideAxis(placement) {
return yAxisSides.has(getSide(placement)) ? 'y' : 'x';
}
function getAlignmentAxis(placement) {
return getOppositeAxis(getSideAxis(placement));
}
function getAlignmentSides(placement, rects, rtl) {
if (rtl === void 0) {
rtl = false;
}
const alignment = getAlignment(placement);
const alignmentAxis = getAlignmentAxis(placement);
const length = getAxisLength(alignmentAxis);
let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
if (rects.reference[length] > rects.floating[length]) {
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
}
return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
}
function getExpandedPlacements(placement) {
const oppositePlacement = getOppositePlacement(placement);
return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
}
function getOppositeAlignmentPlacement(placement) {
return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);
}
const lrPlacement = ['left', 'right'];
const rlPlacement = ['right', 'left'];
const tbPlacement = ['top', 'bottom'];
const btPlacement = ['bottom', 'top'];
function getSideList(side, isStart, rtl) {
switch (side) {
case 'top':
case 'bottom':
if (rtl) return isStart ? rlPlacement : lrPlacement;
return isStart ? lrPlacement : rlPlacement;
case 'left':
case 'right':
return isStart ? tbPlacement : btPlacement;
default:
return [];
}
}
function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
const alignment = getAlignment(placement);
let list = getSideList(getSide(placement), direction === 'start', rtl);
if (alignment) {
list = list.map(side => side + "-" + alignment);
if (flipAlignment) {
list = list.concat(list.map(getOppositeAlignmentPlacement));
}
}
return list;
}
function getOppositePlacement(placement) {
return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]);
}
function expandPaddingObject(padding) {
return {
top: 0,
right: 0,
bottom: 0,
left: 0,
...padding
};
}
function getPaddingObject(padding) {
return typeof padding !== 'number' ? expandPaddingObject(padding) : {
top: padding,
right: padding,
bottom: padding,
left: padding
};
}
function rectToClientRect(rect) {
const {
x,
y,
width,
height
} = rect;
return {
width,
height,
top: y,
left: x,
right: x + width,
bottom: y + height,
x,
y
};
}
/*!
* tabbable 6.2.0
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
*/
// NOTE: separate `:not()` selectors has broader browser support than the newer
// `:not([inert], [inert] *)` (Feb 2023)
// CAREFUL: JSDom does not support `:not([inert] *)` as a selector; using it causes
// the entire query to fail, resulting in no nodes found, which will break a lot
// of things... so we have to rely on JS to identify nodes inside an inert container
var candidateSelectors = ['input:not([inert])', 'select:not([inert])', 'textarea:not([inert])', 'a[href]:not([inert])', 'button:not([inert])', '[tabindex]:not(slot):not([inert])', 'audio[controls]:not([inert])', 'video[controls]:not([inert])', '[contenteditable]:not([contenteditable="false"]):not([inert])', 'details>summary:first-of-type:not([inert])', 'details:not([inert])'];
var candidateSelector = /* #__PURE__ */candidateSelectors.join(',');
var NoElement = typeof Element === 'undefined';
var matches = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
var getRootNode = !NoElement && Element.prototype.getRootNode ? function (element) {
var _element$getRootNode;
return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element);
} : function (element) {
return element === null || element === void 0 ? void 0 : element.ownerDocument;
};
/**
* Determines if a node is inert or in an inert ancestor.
* @param {Element} [node]
* @param {boolean} [lookUp] If true and `node` is not inert, looks up at ancestors to
* see if any of them are inert. If false, only `node` itself is considered.
* @returns {boolean} True if inert itself or by way of being in an inert ancestor.
* False if `node` is falsy.
*/
var isInert = function isInert(node, lookUp) {
var _node$getAttribute;
if (lookUp === void 0) {
lookUp = true;
}
// CAREFUL: JSDom does not support inert at all, so we can't use the `HTMLElement.inert`
// JS API property; we have to check the attribute, which can either be empty or 'true';
// if it's `null` (not specified) or 'false', it's an active element
var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, 'inert');
var inert = inertAtt === '' || inertAtt === 'true';
// NOTE: this could also be handled with `node.matches('[inert], :is([inert] *)')`
// if it weren't for `matches()` not being a function on shadow roots; the following
// code works for any kind of node
// CAREFUL: JSDom does not appear to support certain selectors like `:not([inert] *)`
// so it likely would not support `:is([inert] *)` either...
var result = inert || lookUp && node && isInert(node.parentNode); // recursive
return result;
};
/**
* Determines if a node's content is editable.
* @param {Element} [node]
* @returns True if it's content-editable; false if it's not or `node` is falsy.
*/
var isContentEditable = function isContentEditable(node) {
var _node$getAttribute2;
// CAREFUL: JSDom does not support the `HTMLElement.isContentEditable` API so we have
// to use the attribute directly to check for this, which can either be empty or 'true';
// if it's `null` (not specified) or 'false', it's a non-editable element
var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, 'contenteditable');
return attValue === '' || attValue === 'true';
};
/**
* @param {Element} el container to check in
* @param {boolean} includeContainer add container to check
* @param {(node: Element) => boolean} filter filter candidates
* @returns {Element[]}
*/
var getCandidates = function getCandidates(el, includeContainer, filter) {
// even if `includeContainer=false`, we still have to check it for inertness because
// if it's inert, all its children are inert
if (isInert(el)) {
return [];
}
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
if (includeContainer && matches.call(el, candidateSelector)) {
candidates.unshift(el);
}
candidates = candidates.filter(filter);
return candidates;
};
/**
* @callback GetShadowRoot
* @param {Element} element to check for shadow root
* @returns {ShadowRoot|boolean} ShadowRoot if available or boolean indicating if a shadowRoot is attached but not available.
*/
/**
* @callback ShadowRootFilter
* @param {Element} shadowHostNode the element which contains shadow content
* @returns {boolean} true if a shadow root could potentially contain valid candidates.
*/
/**
* @typedef {Object} CandidateScope
* @property {Element} scopeParent contains inner candidates
* @property {Element[]} candidates list of candidates found in the scope parent
*/
/**
* @typedef {Object} IterativeOptions
* @property {GetShadowRoot|boolean} getShadowRoot true if shadow support is enabled; falsy if not;
* if a function, implies shadow support is enabled and either returns the shadow root of an element
* or a boolean stating if it has an undisclosed shadow root
* @property {(node: Element) => boolean} filter filter candidates
* @property {boolean} flatten if true then result will flatten any CandidateScope into the returned list
* @property {ShadowRootFilter} shadowRootFilter filter shadow roots;
*/
/**
* @param {Element[]} elements list of element containers to match candidates from
* @param {boolean} includeContainer add container list to check
* @param {IterativeOptions} options
* @returns {Array.<Element|CandidateScope>}
*/
var getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
var candidates = [];
var elementsToCheck = Array.from(elements);
while (elementsToCheck.length) {
var element = elementsToCheck.shift();
if (isInert(element, false)) {
// no need to look up since we're drilling down
// anything inside this container will also be inert
continue;
}
if (element.tagName === 'SLOT') {
// add shadow dom slot scope (slot itself cannot be focusable)
var assigned = element.assignedElements();
var content = assigned.length ? assigned : element.children;
var nestedCandidates = getCandidatesIteratively(c