Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

brainly-style-guide

Package Overview
Dependencies
Maintainers
13
Versions
330
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

brainly-style-guide - npm Package Compare versions

Comparing version 186.2.0 to 187.0.0

commonjs/components/utils/invariant.js

142

commonjs/components/accordion/Accordion.js

@@ -16,2 +16,6 @@ "use strict";

var _utils = require("../utils");
var _invariant = _interopRequireDefault(require("../utils/invariant"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -33,9 +37,17 @@

function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

@@ -71,8 +83,55 @@ var KEY_CODES = {

_ref$reduceMotion = _ref.reduceMotion,
reduceMotion = _ref$reduceMotion === void 0 ? false : _ref$reduceMotion;
reduceMotion = _ref$reduceMotion === void 0 ? false : _ref$reduceMotion,
defaultExpanded = _ref.defaultExpanded,
expanded = _ref.expanded,
onChange = _ref.onChange;
var wrapperRef = (0, React.useRef)(null);
var isControlled = expanded !== undefined;
var _useReducer = (0, React.useReducer)(reducer, {
opened: {},
focusedElementId: null
var _useRef = (0, React.useRef)(isControlled),
wasControlled = _useRef.current;
if (_utils.__DEV__) {
(0, _invariant.default)(!(isControlled && !onChange), // eslint-disable-next-line max-len
' You provided an `expanded` prop to a Accordion without an `onChange` handler. Users won`t be able to switch between expanded/collapsed state.');
(0, _invariant.default)(!(wasControlled && !isControlled), 'You cannot change Accordion component from controlled to uncontrolled variant.');
(0, _invariant.default)(!(!wasControlled && isControlled), 'You cannot change Accordion component from uncontrolled to controlled variant.');
(0, _invariant.default)(!(isControlled && allowMultiple), 'allowMultiple is not working in controlled Accordion');
(0, _invariant.default)(!(!allowMultiple && Array.isArray(defaultExpanded) && defaultExpanded.length > 1), // eslint-disable-next-line max-len
'defaultExpanded is an array with more than 1 element but allowMultiple prop is not set. The first value from the array was picked as a default expanded. Set allowMultiple attribute or provide only one default expanded.');
}
var getUpdatedOpenedItems = (0, React.useCallback)(function (expanded, id, value) {
if (value) {
return allowMultiple ? _toConsumableArray(new Set([].concat(_toConsumableArray(expanded), [id]))) : [id];
}
return allowMultiple ? expanded.filter(function (item) {
return item !== id;
}) : [];
}, [allowMultiple]);
var _useReducer = (0, React.useReducer)(reducer, null, function () {
if (isControlled) {
return {
expanded: [],
focusedElementId: null
};
}
if (defaultExpanded !== undefined) {
var expandedArray = Array.isArray(defaultExpanded) ? defaultExpanded : [defaultExpanded];
var newState = expandedArray.filter(function (item, idx) {
return allowMultiple || idx < 1;
});
return {
expanded: newState,
focusedElementId: null
};
}
return {
expanded: [],
focusedElementId: null
};
}),

@@ -96,3 +155,3 @@ _useReducer2 = _slicedToArray(_useReducer, 2),

dispatch({
type: 'accordion/KEYBOARD_SET_OPENED'
type: 'accordion/KEYBOARD_SET_EXPANDED'
});

@@ -110,25 +169,19 @@ }

function getUpdatedOpenedItems(opened, id, value) {
return allowMultiple ? _objectSpread(_objectSpread({}, opened), {}, _defineProperty({}, id, value)) : _defineProperty({}, id, value);
}
function reducer(state, action) {
switch (action.type) {
case 'accordion/SET_OPENED':
case 'accordion/SET_EXPANDED':
{
var _action$payload = action.payload,
id = _action$payload.id,
value = _action$payload.value;
var _expanded = action.payload.expanded;
return _objectSpread(_objectSpread({}, state), {}, {
opened: getUpdatedOpenedItems(state.opened, id, value)
expanded: _expanded
});
}
case 'accordion/KEYBOARD_SET_OPENED':
case 'accordion/KEYBOARD_SET_EXPANDED':
{
var opened = state.opened,
var _expanded2 = state.expanded,
focusedElementId = state.focusedElementId;
if (focusedElementId === null) return state;
return _objectSpread(_objectSpread({}, state), {}, {
opened: getUpdatedOpenedItems(state.opened, focusedElementId, !opened[focusedElementId])
expanded: getUpdatedOpenedItems(state.expanded, focusedElementId, !_expanded2.includes(focusedElementId))
});

@@ -149,17 +202,50 @@ }

var _useState = (0, React.useState)(),
_useState2 = _slicedToArray(_useState, 2),
prevExpanded = _useState2[0],
setPrevExpanded = _useState2[1];
if (isControlled && expanded !== prevExpanded) {
setPrevExpanded(expanded); // expanded || '' is to satisfy flow.
// isControlled flag is true when expanded !== undefined but this condition is not interpreted
// correctly by flow causing type error. Replacing isControlled with expanded !== undefined would work but using isControlled is more clear
var expandedArray = Array.isArray(expanded) ? expanded : [expanded || ''];
dispatch({
type: 'accordion/SET_EXPANDED',
payload: {
expanded: expandedArray
}
});
}
var noGapBetweenElements = spacing === 'none';
var spaceClass = spacing === 'none' ? undefined : spaceClasses[spacing];
return /*#__PURE__*/React.createElement(AccordionContext.Provider, {
value: {
var onItemSelect = (0, React.useCallback)(function (id, value) {
onChange && onChange(id);
if (!isControlled) {
dispatch({
type: 'accordion/SET_EXPANDED',
payload: {
expanded: getUpdatedOpenedItems(state.expanded, id, value)
}
});
}
}, [getUpdatedOpenedItems, isControlled, onChange, state.expanded]);
var context = (0, React.useMemo)(function () {
return {
noGapBetweenElements: noGapBetweenElements,
opened: state.opened,
expanded: state.expanded,
focusedElementId: state.focusedElementId,
dispatch: dispatch,
reduceMotion: hasReduceMotion
}
reduceMotion: hasReduceMotion,
onItemSelect: onItemSelect
};
}, [hasReduceMotion, noGapBetweenElements, onItemSelect, state.focusedElementId, state.expanded]);
return /*#__PURE__*/React.createElement(AccordionContext.Provider, {
value: context
}, /*#__PURE__*/React.createElement("div", {
ref: wrapperRef,
className: (0, _classnames.default)(spaceClass, className),
"data-allow-multiple": allowMultiple,
"data-allow-toggle": !allowMultiple
className: (0, _classnames.default)(spaceClass, className)
}, children));

@@ -166,0 +252,0 @@ };

156

commonjs/components/accordion/Accordion.stories.js

@@ -8,3 +8,3 @@ "use strict";

});
exports.NoGaps = exports.Default = exports.default = void 0;
exports.Controlled = exports.NoGaps = exports.Default = exports.default = void 0;

@@ -25,2 +25,20 @@ var React = _interopRequireWildcard(require("react"));

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var _default = {

@@ -40,2 +58,17 @@ title: 'Layout/Accordion',

}
},
onChange: {
table: {
category: 'Events'
}
},
defaultExpanded: {
control: {
type: 'array'
}
},
expanded: {
control: {
type: 'array'
}
}

@@ -86,47 +119,2 @@ }

cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})));

@@ -137,9 +125,6 @@ };

var NoGaps = function NoGaps() {
return /*#__PURE__*/React.createElement(_Accordion.default, {
spacing: "none",
allowMultiple: true
}, /*#__PURE__*/React.createElement(_AccordionItem.default, {
var NoGaps = function NoGaps(args) {
return /*#__PURE__*/React.createElement(_Accordion.default, args, /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title,
defaultOpened: true
id: "first"
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {

@@ -150,3 +135,3 @@ url: copy.url,

title: copy.title,
defaultOpened: true
id: "second"
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {

@@ -168,2 +153,65 @@ url: copy.url,

exports.NoGaps = NoGaps;
exports.NoGaps = NoGaps;
NoGaps.args = {
spacing: 'none',
allowMultiple: true,
defaultExpanded: ['first', 'second']
};
var CONTROLLED_ACCORDION_IDS = ['accrodion item 1', 'accordion item 2', 'accordion item 3'];
var Controlled = function Controlled(args) {
var _React$useState = React.useState(),
_React$useState2 = _slicedToArray(_React$useState, 2),
prevExpanded = _React$useState2[0],
setPrevExpanded = _React$useState2[1];
var _React$useState3 = React.useState(''),
_React$useState4 = _slicedToArray(_React$useState3, 2),
expanded = _React$useState4[0],
setExpanded = _React$useState4[1];
var handleChange = function handleChange(id) {
return setExpanded(id);
};
var propsExpanded = args.expanded,
props = _objectWithoutProperties(args, ["expanded"]);
if (propsExpanded !== prevExpanded) {
setPrevExpanded(propsExpanded);
setExpanded(propsExpanded);
}
return /*#__PURE__*/React.createElement(_Accordion.default, _extends({
onChange: handleChange,
expanded: expanded
}, props), CONTROLLED_ACCORDION_IDS.map(function (id) {
return /*#__PURE__*/React.createElement(_AccordionItem.default, {
title: copy.title,
key: id,
id: id
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
}));
}));
};
exports.Controlled = Controlled;
Controlled.args = {
expanded: CONTROLLED_ACCORDION_IDS[0]
};
Controlled.argTypes = {
expanded: {
control: {
type: 'select',
options: CONTROLLED_ACCORDION_IDS
}
},
allowMultiple: {
control: null
},
defaultExpanded: {
control: null
}
};

@@ -55,12 +55,10 @@ "use strict";

className = _ref$className === void 0 ? '' : _ref$className,
_ref$defaultOpened = _ref.defaultOpened,
defaultOpened = _ref$defaultOpened === void 0 ? false : _ref$defaultOpened,
_ref$padding = _ref.padding,
padding = _ref$padding === void 0 ? 'm' : _ref$padding,
_ref$tabIndex = _ref.tabIndex,
tabIndex = _ref$tabIndex === void 0 ? 0 : _ref$tabIndex;
var hasRendered = (0, React.useRef)(false);
tabIndex = _ref$tabIndex === void 0 ? 0 : _ref$tabIndex,
customId = _ref.id;
var contentRef = (0, React.useRef)(null);
var _useRef = (0, React.useRef)("AccordionItem_".concat(generateId())),
var _useRef = (0, React.useRef)(customId !== null && customId !== void 0 ? customId : "AccordionItem_".concat(generateId())),
id = _useRef.current;

@@ -72,6 +70,7 @@

noGapBetweenElements = _useContext.noGapBetweenElements,
opened = _useContext.opened,
expanded = _useContext.expanded,
focusedElementId = _useContext.focusedElementId,
dispatch = _useContext.dispatch,
reduceMotion = _useContext.reduceMotion;
reduceMotion = _useContext.reduceMotion,
onItemSelect = _useContext.onItemSelect;

@@ -83,15 +82,10 @@ var _useState = (0, React.useState)(false),

var isHidden = !opened[id];
var isCollapsed = !expanded.includes(id);
var isFocused = focusedElementId === id;
var isHighlighted = isHovered || isFocused;
var isBorderHighlighted = isHighlighted && !noGapBetweenElements;
var isTitleString = typeof title === 'string';
var toggleOpen = function toggleOpen() {
dispatch({
type: 'accordion/SET_OPENED',
payload: {
id: id,
value: isHidden
}
});
onItemSelect(id, isCollapsed);
};

@@ -118,15 +112,2 @@

(0, React.useEffect)(function () {
if (defaultOpened) {
dispatch({
type: 'accordion/SET_OPENED',
payload: {
id: id,
value: true
}
});
}
hasRendered.current = true; //eslint-disable-next-line
}, []);
(0, React.useLayoutEffect)(function () {
var content = contentRef.current;

@@ -193,4 +174,3 @@

if (hasRendered.current === false) return;
isHidden ? collapse() : expand();
isCollapsed ? collapse() : expand();
return function () {

@@ -203,3 +183,3 @@ if (!content) {

};
}, [isHidden, reduceMotion]);
}, [isCollapsed, reduceMotion]);
return /*#__PURE__*/React.createElement(_Box.default, {

@@ -227,3 +207,3 @@ color: "light",

onBlur: handleBlur,
"aria-expanded": !isHidden,
"aria-expanded": !isCollapsed,
"aria-controls": contentId,

@@ -237,3 +217,3 @@ id: id,

alignItems: "center"
}, /*#__PURE__*/React.createElement(_Link.default, {
}, isTitleString ? /*#__PURE__*/React.createElement(_Link.default, {
size: titleSize,

@@ -243,2 +223,4 @@ color: "black",

underlined: isHighlighted
}, title) : /*#__PURE__*/React.createElement("span", {
className: "sg-accordion-item__title"
}, title), /*#__PURE__*/React.createElement(_Flex.default, {

@@ -254,3 +236,3 @@ justifyContent: "center",

className: (0, _classnames.default)('sg-accordion-item__arrow', {
'sg-accordion-item__arrow--visible': !isHidden
'sg-accordion-item__arrow--visible': !isCollapsed
})

@@ -257,0 +239,0 @@ })))), /*#__PURE__*/React.createElement("div", {

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";

@@ -9,7 +10,9 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

// eslint-disable-next-line import/no-duplicates
import * as React from 'react'; // eslint-disable-next-line import/no-duplicates
import { createContext, useReducer, useEffect, useRef } from 'react';
import * as React from 'react';
import { createContext, useReducer, useEffect, useRef, useCallback, useMemo, useState // eslint-disable-next-line import/no-duplicates
} from 'react';
import cx from 'classnames';
import useReducedMotion from '../utils/useReducedMotion';
import { __DEV__ } from '../utils';
import invariant from '../utils/invariant';
export var KEY_CODES = {

@@ -41,8 +44,55 @@ '32': 'space',

_ref$reduceMotion = _ref.reduceMotion,
reduceMotion = _ref$reduceMotion === void 0 ? false : _ref$reduceMotion;
reduceMotion = _ref$reduceMotion === void 0 ? false : _ref$reduceMotion,
defaultExpanded = _ref.defaultExpanded,
expanded = _ref.expanded,
onChange = _ref.onChange;
var wrapperRef = useRef(null);
var isControlled = expanded !== undefined;
var _useReducer = useReducer(reducer, {
opened: {},
focusedElementId: null
var _useRef = useRef(isControlled),
wasControlled = _useRef.current;
if (__DEV__) {
invariant(!(isControlled && !onChange), // eslint-disable-next-line max-len
' You provided an `expanded` prop to a Accordion without an `onChange` handler. Users won`t be able to switch between expanded/collapsed state.');
invariant(!(wasControlled && !isControlled), 'You cannot change Accordion component from controlled to uncontrolled variant.');
invariant(!(!wasControlled && isControlled), 'You cannot change Accordion component from uncontrolled to controlled variant.');
invariant(!(isControlled && allowMultiple), 'allowMultiple is not working in controlled Accordion');
invariant(!(!allowMultiple && Array.isArray(defaultExpanded) && defaultExpanded.length > 1), // eslint-disable-next-line max-len
'defaultExpanded is an array with more than 1 element but allowMultiple prop is not set. The first value from the array was picked as a default expanded. Set allowMultiple attribute or provide only one default expanded.');
}
var getUpdatedOpenedItems = useCallback(function (expanded, id, value) {
if (value) {
return allowMultiple ? _toConsumableArray(new Set([].concat(_toConsumableArray(expanded), [id]))) : [id];
}
return allowMultiple ? expanded.filter(function (item) {
return item !== id;
}) : [];
}, [allowMultiple]);
var _useReducer = useReducer(reducer, null, function () {
if (isControlled) {
return {
expanded: [],
focusedElementId: null
};
}
if (defaultExpanded !== undefined) {
var expandedArray = Array.isArray(defaultExpanded) ? defaultExpanded : [defaultExpanded];
var newState = expandedArray.filter(function (item, idx) {
return allowMultiple || idx < 1;
});
return {
expanded: newState,
focusedElementId: null
};
}
return {
expanded: [],
focusedElementId: null
};
}),

@@ -66,3 +116,3 @@ _useReducer2 = _slicedToArray(_useReducer, 2),

dispatch({
type: 'accordion/KEYBOARD_SET_OPENED'
type: 'accordion/KEYBOARD_SET_EXPANDED'
});

@@ -80,25 +130,19 @@ }

function getUpdatedOpenedItems(opened, id, value) {
return allowMultiple ? _objectSpread(_objectSpread({}, opened), {}, _defineProperty({}, id, value)) : _defineProperty({}, id, value);
}
function reducer(state, action) {
switch (action.type) {
case 'accordion/SET_OPENED':
case 'accordion/SET_EXPANDED':
{
var _action$payload = action.payload,
id = _action$payload.id,
value = _action$payload.value;
var _expanded = action.payload.expanded;
return _objectSpread(_objectSpread({}, state), {}, {
opened: getUpdatedOpenedItems(state.opened, id, value)
expanded: _expanded
});
}
case 'accordion/KEYBOARD_SET_OPENED':
case 'accordion/KEYBOARD_SET_EXPANDED':
{
var opened = state.opened,
var _expanded2 = state.expanded,
focusedElementId = state.focusedElementId;
if (focusedElementId === null) return state;
return _objectSpread(_objectSpread({}, state), {}, {
opened: getUpdatedOpenedItems(state.opened, focusedElementId, !opened[focusedElementId])
expanded: getUpdatedOpenedItems(state.expanded, focusedElementId, !_expanded2.includes(focusedElementId))
});

@@ -119,17 +163,50 @@ }

var _useState = useState(),
_useState2 = _slicedToArray(_useState, 2),
prevExpanded = _useState2[0],
setPrevExpanded = _useState2[1];
if (isControlled && expanded !== prevExpanded) {
setPrevExpanded(expanded); // expanded || '' is to satisfy flow.
// isControlled flag is true when expanded !== undefined but this condition is not interpreted
// correctly by flow causing type error. Replacing isControlled with expanded !== undefined would work but using isControlled is more clear
var expandedArray = Array.isArray(expanded) ? expanded : [expanded || ''];
dispatch({
type: 'accordion/SET_EXPANDED',
payload: {
expanded: expandedArray
}
});
}
var noGapBetweenElements = spacing === 'none';
var spaceClass = spacing === 'none' ? undefined : spaceClasses[spacing];
return /*#__PURE__*/React.createElement(AccordionContext.Provider, {
value: {
var onItemSelect = useCallback(function (id, value) {
onChange && onChange(id);
if (!isControlled) {
dispatch({
type: 'accordion/SET_EXPANDED',
payload: {
expanded: getUpdatedOpenedItems(state.expanded, id, value)
}
});
}
}, [getUpdatedOpenedItems, isControlled, onChange, state.expanded]);
var context = useMemo(function () {
return {
noGapBetweenElements: noGapBetweenElements,
opened: state.opened,
expanded: state.expanded,
focusedElementId: state.focusedElementId,
dispatch: dispatch,
reduceMotion: hasReduceMotion
}
reduceMotion: hasReduceMotion,
onItemSelect: onItemSelect
};
}, [hasReduceMotion, noGapBetweenElements, onItemSelect, state.focusedElementId, state.expanded]);
return /*#__PURE__*/React.createElement(AccordionContext.Provider, {
value: context
}, /*#__PURE__*/React.createElement("div", {
ref: wrapperRef,
className: cx(spaceClass, className),
"data-allow-multiple": allowMultiple,
"data-allow-toggle": !allowMultiple
className: cx(spaceClass, className)
}, children));

@@ -136,0 +213,0 @@ };

@@ -0,1 +1,4 @@

import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import * as React from 'react';

@@ -19,2 +22,17 @@ import Accordion from './Accordion';

}
},
onChange: {
table: {
category: 'Events'
}
},
defaultExpanded: {
control: {
type: 'array'
}
},
expanded: {
control: {
type: 'array'
}
}

@@ -64,56 +82,8 @@ }

cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})), /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
})));
};
export var NoGaps = function NoGaps() {
return /*#__PURE__*/React.createElement(Accordion, {
spacing: "none",
allowMultiple: true
}, /*#__PURE__*/React.createElement(AccordionItem, {
export var NoGaps = function NoGaps(args) {
return /*#__PURE__*/React.createElement(Accordion, args, /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title,
defaultOpened: true
id: "first"
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {

@@ -124,3 +94,3 @@ url: copy.url,

title: copy.title,
defaultOpened: true
id: "second"
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {

@@ -140,2 +110,62 @@ url: copy.url,

})));
};
NoGaps.args = {
spacing: 'none',
allowMultiple: true,
defaultExpanded: ['first', 'second']
};
var CONTROLLED_ACCORDION_IDS = ['accrodion item 1', 'accordion item 2', 'accordion item 3'];
export var Controlled = function Controlled(args) {
var _React$useState = React.useState(),
_React$useState2 = _slicedToArray(_React$useState, 2),
prevExpanded = _React$useState2[0],
setPrevExpanded = _React$useState2[1];
var _React$useState3 = React.useState(''),
_React$useState4 = _slicedToArray(_React$useState3, 2),
expanded = _React$useState4[0],
setExpanded = _React$useState4[1];
var handleChange = function handleChange(id) {
return setExpanded(id);
};
var propsExpanded = args.expanded,
props = _objectWithoutProperties(args, ["expanded"]);
if (propsExpanded !== prevExpanded) {
setPrevExpanded(propsExpanded);
setExpanded(propsExpanded);
}
return /*#__PURE__*/React.createElement(Accordion, _extends({
onChange: handleChange,
expanded: expanded
}, props), CONTROLLED_ACCORDION_IDS.map(function (id) {
return /*#__PURE__*/React.createElement(AccordionItem, {
title: copy.title,
key: id,
id: id
}, copy.description, " ", /*#__PURE__*/React.createElement(CallToAction, {
url: copy.url,
cta: copy.cta
}));
}));
};
Controlled.args = {
expanded: CONTROLLED_ACCORDION_IDS[0]
};
Controlled.argTypes = {
expanded: {
control: {
type: 'select',
options: CONTROLLED_ACCORDION_IDS
}
},
allowMultiple: {
control: null
},
defaultExpanded: {
control: null
}
};

@@ -5,3 +5,3 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";

import { useContext, useLayoutEffect, useEffect, useRef, useState } from 'react';
import { useContext, useEffect, useRef, useState } from 'react';
import cx from 'classnames';

@@ -26,12 +26,10 @@ import Box from '../box/Box';

className = _ref$className === void 0 ? '' : _ref$className,
_ref$defaultOpened = _ref.defaultOpened,
defaultOpened = _ref$defaultOpened === void 0 ? false : _ref$defaultOpened,
_ref$padding = _ref.padding,
padding = _ref$padding === void 0 ? 'm' : _ref$padding,
_ref$tabIndex = _ref.tabIndex,
tabIndex = _ref$tabIndex === void 0 ? 0 : _ref$tabIndex;
var hasRendered = useRef(false);
tabIndex = _ref$tabIndex === void 0 ? 0 : _ref$tabIndex,
customId = _ref.id;
var contentRef = useRef(null);
var _useRef = useRef("AccordionItem_".concat(generateId())),
var _useRef = useRef(customId !== null && customId !== void 0 ? customId : "AccordionItem_".concat(generateId())),
id = _useRef.current;

@@ -43,6 +41,7 @@

noGapBetweenElements = _useContext.noGapBetweenElements,
opened = _useContext.opened,
expanded = _useContext.expanded,
focusedElementId = _useContext.focusedElementId,
dispatch = _useContext.dispatch,
reduceMotion = _useContext.reduceMotion;
reduceMotion = _useContext.reduceMotion,
onItemSelect = _useContext.onItemSelect;

@@ -54,15 +53,10 @@ var _useState = useState(false),

var isHidden = !opened[id];
var isCollapsed = !expanded.includes(id);
var isFocused = focusedElementId === id;
var isHighlighted = isHovered || isFocused;
var isBorderHighlighted = isHighlighted && !noGapBetweenElements;
var isTitleString = typeof title === 'string';
var toggleOpen = function toggleOpen() {
dispatch({
type: 'accordion/SET_OPENED',
payload: {
id: id,
value: isHidden
}
});
onItemSelect(id, isCollapsed);
};

@@ -89,15 +83,2 @@

useEffect(function () {
if (defaultOpened) {
dispatch({
type: 'accordion/SET_OPENED',
payload: {
id: id,
value: true
}
});
}
hasRendered.current = true; //eslint-disable-next-line
}, []);
useLayoutEffect(function () {
var content = contentRef.current;

@@ -164,4 +145,3 @@

if (hasRendered.current === false) return;
isHidden ? collapse() : expand();
isCollapsed ? collapse() : expand();
return function () {

@@ -174,3 +154,3 @@ if (!content) {

};
}, [isHidden, reduceMotion]);
}, [isCollapsed, reduceMotion]);
return /*#__PURE__*/React.createElement(Box, {

@@ -198,3 +178,3 @@ color: "light",

onBlur: handleBlur,
"aria-expanded": !isHidden,
"aria-expanded": !isCollapsed,
"aria-controls": contentId,

@@ -208,3 +188,3 @@ id: id,

alignItems: "center"
}, /*#__PURE__*/React.createElement(Link, {
}, isTitleString ? /*#__PURE__*/React.createElement(Link, {
size: titleSize,

@@ -214,2 +194,4 @@ color: "black",

underlined: isHighlighted
}, title) : /*#__PURE__*/React.createElement("span", {
className: "sg-accordion-item__title"
}, title), /*#__PURE__*/React.createElement(Flex, {

@@ -225,3 +207,3 @@ justifyContent: "center",

className: cx('sg-accordion-item__arrow', {
'sg-accordion-item__arrow--visible': !isHidden
'sg-accordion-item__arrow--visible': !isCollapsed
})

@@ -228,0 +210,0 @@ })))), /*#__PURE__*/React.createElement("div", {

{
"name": "brainly-style-guide",
"version": "186.2.0",
"version": "187.0.0",
"description": "Brainly Front-End Style Guide",

@@ -5,0 +5,0 @@ "repository": "https://github.com/brainly/style-guide.git",

@@ -5,6 +5,16 @@ //@flow strict

import * as React from 'react';
// eslint-disable-next-line import/no-duplicates
import {createContext, useReducer, useEffect, useRef} from 'react';
import {
createContext,
useReducer,
useEffect,
useRef,
useCallback,
useMemo,
useState,
// eslint-disable-next-line import/no-duplicates
} from 'react';
import cx from 'classnames';
import useReducedMotion from '../utils/useReducedMotion';
import {__DEV__} from '../utils';
import invariant from '../utils/invariant';

@@ -16,9 +26,6 @@ export const KEY_CODES = {

type OpenedItemsType = {
[string]: boolean,
...,
};
type ExpandedItemsType = Array<string>;
type StateType = $ReadOnly<{
opened: OpenedItemsType,
expanded: ExpandedItemsType,
focusedElementId: string | null,

@@ -29,6 +36,6 @@ }>;

| {
type: 'accordion/SET_OPENED',
payload: {id: string, value: boolean},
type: 'accordion/SET_EXPANDED',
payload: {expanded: ExpandedItemsType},
}
| {type: 'accordion/KEYBOARD_SET_OPENED'}
| {type: 'accordion/KEYBOARD_SET_EXPANDED'}
| {

@@ -55,2 +62,5 @@ type: 'accordion/SET_FOCUSED',

reduceMotion?: boolean,
expanded?: string | Array<string>,
defaultExpanded?: string | Array<string>,
onChange?: string => void,
}>;

@@ -60,6 +70,7 @@

noGapBetweenElements: boolean,
opened: OpenedItemsType,
expanded: ExpandedItemsType,
focusedElementId: string | null,
dispatch: (action: ActionType) => void,
reduceMotion: boolean,
onItemSelect: (id: string, value: boolean) => void,
...

@@ -88,7 +99,80 @@ };

reduceMotion = false,
defaultExpanded,
expanded,
onChange,
}: AccordionPropsType) => {
const wrapperRef = useRef<HTMLDivElement | null>(null);
const [state, dispatch] = useReducer(reducer, {
opened: {},
focusedElementId: null,
const isControlled = expanded !== undefined;
const {current: wasControlled} = useRef<boolean>(isControlled);
if (__DEV__) {
invariant(
!(isControlled && !onChange),
// eslint-disable-next-line max-len
' You provided an `expanded` prop to a Accordion without an `onChange` handler. Users won`t be able to switch between expanded/collapsed state.'
);
invariant(
!(wasControlled && !isControlled),
'You cannot change Accordion component from controlled to uncontrolled variant.'
);
invariant(
!(!wasControlled && isControlled),
'You cannot change Accordion component from uncontrolled to controlled variant.'
);
invariant(
!(isControlled && allowMultiple),
'allowMultiple is not working in controlled Accordion'
);
invariant(
!(
!allowMultiple &&
Array.isArray(defaultExpanded) &&
defaultExpanded.length > 1
),
// eslint-disable-next-line max-len
'defaultExpanded is an array with more than 1 element but allowMultiple prop is not set. The first value from the array was picked as a default expanded. Set allowMultiple attribute or provide only one default expanded.'
);
}
const getUpdatedOpenedItems = useCallback(
(expanded: ExpandedItemsType, id: string, value: boolean) => {
if (value) {
return allowMultiple ? [...new Set([...expanded, id])] : [id];
}
return allowMultiple ? expanded.filter(item => item !== id) : [];
},
[allowMultiple]
);
const [state, dispatch] = useReducer(reducer, null, () => {
if (isControlled) {
return {
expanded: [],
focusedElementId: null,
};
}
if (defaultExpanded !== undefined) {
const expandedArray = Array.isArray(defaultExpanded)
? defaultExpanded
: [defaultExpanded];
const newState = expandedArray.filter(
(item, idx) => allowMultiple || idx < 1
);
return {
expanded: newState,
focusedElementId: null,
};
}
return {
expanded: [],
focusedElementId: null,
};
});

@@ -111,3 +195,3 @@ const hasReduceMotion = useReducedMotion() || reduceMotion;

dispatch({type: 'accordion/KEYBOARD_SET_OPENED'});
dispatch({type: 'accordion/KEYBOARD_SET_EXPANDED'});
}

@@ -125,23 +209,15 @@ }

function getUpdatedOpenedItems(
opened: OpenedItemsType,
id: string,
value: boolean
) {
return allowMultiple ? {...opened, [id]: value} : {[id]: value};
}
function reducer(state: StateType, action: ActionType): StateType {
switch (action.type) {
case 'accordion/SET_OPENED': {
const {id, value} = action.payload;
case 'accordion/SET_EXPANDED': {
const {expanded} = action.payload;
return {
...state,
opened: getUpdatedOpenedItems(state.opened, id, value),
expanded,
};
}
case 'accordion/KEYBOARD_SET_OPENED': {
const {opened, focusedElementId} = state;
case 'accordion/KEYBOARD_SET_EXPANDED': {
const {expanded, focusedElementId} = state;

@@ -152,6 +228,6 @@ if (focusedElementId === null) return state;

...state,
opened: getUpdatedOpenedItems(
state.opened,
expanded: getUpdatedOpenedItems(
state.expanded,
focusedElementId,
!opened[focusedElementId]
!expanded.includes(focusedElementId)
),

@@ -173,21 +249,58 @@ };

const [prevExpanded, setPrevExpanded] = useState();
if (isControlled && expanded !== prevExpanded) {
setPrevExpanded(expanded);
// expanded || '' is to satisfy flow.
// isControlled flag is true when expanded !== undefined but this condition is not interpreted
// correctly by flow causing type error. Replacing isControlled with expanded !== undefined would work but using isControlled is more clear
const expandedArray = Array.isArray(expanded) ? expanded : [expanded || ''];
dispatch({
type: 'accordion/SET_EXPANDED',
payload: {expanded: expandedArray},
});
}
const noGapBetweenElements = spacing === 'none';
const spaceClass = spacing === 'none' ? undefined : spaceClasses[spacing];
const onItemSelect = useCallback(
(id, value) => {
onChange && onChange(id);
if (!isControlled) {
dispatch({
type: 'accordion/SET_EXPANDED',
payload: {
expanded: getUpdatedOpenedItems(state.expanded, id, value),
},
});
}
},
[getUpdatedOpenedItems, isControlled, onChange, state.expanded]
);
const context = useMemo(
() => ({
noGapBetweenElements,
expanded: state.expanded,
focusedElementId: state.focusedElementId,
dispatch,
reduceMotion: hasReduceMotion,
onItemSelect,
}),
[
hasReduceMotion,
noGapBetweenElements,
onItemSelect,
state.focusedElementId,
state.expanded,
]
);
return (
<AccordionContext.Provider
value={{
noGapBetweenElements,
opened: state.opened,
focusedElementId: state.focusedElementId,
dispatch,
reduceMotion: hasReduceMotion,
}}
>
<div
ref={wrapperRef}
className={cx(spaceClass, className)}
data-allow-multiple={allowMultiple}
data-allow-toggle={!allowMultiple}
>
<AccordionContext.Provider value={context}>
<div ref={wrapperRef} className={cx(spaceClass, className)}>
{children}

@@ -194,0 +307,0 @@ </div>

@@ -5,2 +5,3 @@ import * as React from 'react';

import AccordionItem from './AccordionItem';
import Link from '../text/Link';

@@ -151,9 +152,9 @@ describe('<Accordion>', () => {

it('by default expands items that have "defaultOpened" prop', () => {
it('by default expands items that have "defaultExpanded" prop', () => {
const accordion = mount(
<Accordion allowMultiple>
<AccordionItem title="Item 1" defaultOpened>
<Accordion allowMultiple defaultExpanded={['id-1', 'id-2']}>
<AccordionItem title="Item 1" id="id-1">
Accordion Item Description
</AccordionItem>
<AccordionItem title="Item 2" defaultOpened>
<AccordionItem title="Item 2" id="id-2">
Accordion Item Description

@@ -168,2 +169,85 @@ </AccordionItem>

});
it('expands controlled items when expanded is type of array', () => {
const accordionIds = ['id-1', 'id-2', 'id-3'];
const accordion = mount(
<Accordion expanded={accordionIds} onChange={() => undefined}>
{accordionIds.map(id => (
<AccordionItem title={id} id={id} key={id}>
Accordion Item Description
</AccordionItem>
))}
</Accordion>
);
expect(accordion.find('[aria-labelledby]').hostNodes()).toHaveLength(
accordionIds.length
);
expect(accordion.find('[aria-expanded=true]').hostNodes()).toHaveLength(3);
});
it('expands controlled item when expanded is type of string', () => {
const accordionIds = ['id-1', 'id-2', 'id-3'];
const accordion = mount(
<Accordion expanded={accordionIds[0]} onChange={noop => noop}>
{accordionIds.map(id => (
<AccordionItem title={id} id={id} key={id}>
Accordion Item Description
</AccordionItem>
))}
</Accordion>
);
expect(accordion.find('[aria-labelledby]').hostNodes()).toHaveLength(
accordionIds.length
);
expect(accordion.find('[aria-expanded=true]').hostNodes()).toHaveLength(1);
});
it('calls callback when cliking on item', () => {
const accordionIds = ['id-1', 'id-2', 'id-3'];
const handleOnChange = jest.fn();
const accordion = mount(
<Accordion expanded={accordionIds[0]} onChange={handleOnChange}>
{accordionIds.map(id => (
<AccordionItem title={id} id={id} key={id}>
Accordion Item Description
</AccordionItem>
))}
</Accordion>
);
const item = accordionIds[0];
accordion
.find({title: item})
.find({role: 'button'})
.hostNodes()
.simulate('click');
expect(handleOnChange).toHaveBeenCalled();
expect(handleOnChange).toHaveBeenCalledWith(item);
});
it('renders Link when title is string', () => {
const accordion = mount(
<Accordion>
<AccordionItem title="Item 1">Accordion Item Description</AccordionItem>
</Accordion>
);
expect(accordion.find(Link).exists()).toBe(true);
});
it('does not render Link when title is not string', () => {
const accordion = mount(
<Accordion>
<AccordionItem title={<div>info</div>}>
Accordion Item Description
</AccordionItem>
</Accordion>
);
expect(accordion.find(Link).exists()).toBe(false);
});
});

@@ -21,2 +21,17 @@ //@flow

},
onChange: {
table: {
category: 'Events',
},
},
defaultExpanded: {
control: {
type: 'array',
},
},
expanded: {
control: {
type: 'array',
},
},
},

@@ -58,38 +73,11 @@ };

</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
</Accordion>
);
export const NoGaps = () => (
<Accordion spacing="none" allowMultiple>
<AccordionItem title={copy.title} defaultOpened>
export const NoGaps = (args: any) => (
<Accordion {...args}>
<AccordionItem title={copy.title} id="first">
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
<AccordionItem title={copy.title} defaultOpened>
<AccordionItem title={copy.title} id="second">
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />

@@ -105,1 +93,48 @@ </AccordionItem>

);
NoGaps.args = {
spacing: 'none',
allowMultiple: true,
defaultExpanded: ['first', 'second'],
};
const CONTROLLED_ACCORDION_IDS = [
'accrodion item 1',
'accordion item 2',
'accordion item 3',
];
export const Controlled = (args: any) => {
const [prevExpanded, setPrevExpanded] = React.useState();
const [expanded, setExpanded] = React.useState('');
const handleChange = id => setExpanded(id);
const {expanded: propsExpanded, ...props} = args;
if (propsExpanded !== prevExpanded) {
setPrevExpanded(propsExpanded);
setExpanded(propsExpanded);
}
return (
<Accordion onChange={handleChange} expanded={expanded} {...props}>
{CONTROLLED_ACCORDION_IDS.map(id => (
<AccordionItem title={copy.title} key={id} id={id}>
{copy.description} <CallToAction url={copy.url} cta={copy.cta} />
</AccordionItem>
))}
</Accordion>
);
};
Controlled.args = {
expanded: CONTROLLED_ACCORDION_IDS[0],
};
Controlled.argTypes = {
expanded: {
control: {type: 'select', options: CONTROLLED_ACCORDION_IDS},
},
allowMultiple: {control: null},
defaultExpanded: {control: null},
};

@@ -6,3 +6,3 @@ //@flow strict

// eslint-disable-next-line import/no-duplicates
import {useContext, useLayoutEffect, useEffect, useRef, useState} from 'react';
import {useContext, useEffect, useRef, useState} from 'react';

@@ -24,5 +24,5 @@ import cx from 'classnames';

className?: string,
defaultOpened?: boolean,
padding?: PaddingType,
tabIndex?: number,
id?: string,
}>;

@@ -41,9 +41,10 @@

className = '',
defaultOpened = false,
padding = 'm',
tabIndex = 0,
id: customId,
}: AccordionItemPropsType) => {
const hasRendered = useRef(false);
const contentRef = useRef<HTMLDivElement | null>(null);
const {current: id} = useRef<string>(`AccordionItem_${generateId()}`);
const {current: id} = useRef<string>(
customId ?? `AccordionItem_${generateId()}`
);
const contentId = `Section_${id}`;

@@ -53,19 +54,18 @@

noGapBetweenElements,
opened,
expanded,
focusedElementId,
dispatch,
reduceMotion,
onItemSelect,
} = useContext(AccordionContext);
const [isHovered, setIsHovered] = useState(false);
const isHidden = !opened[id];
const isCollapsed = !expanded.includes(id);
const isFocused = focusedElementId === id;
const isHighlighted = isHovered || isFocused;
const isBorderHighlighted = isHighlighted && !noGapBetweenElements;
const isTitleString = typeof title === 'string';
const toggleOpen = () => {
dispatch({
type: 'accordion/SET_OPENED',
payload: {id, value: isHidden},
});
onItemSelect(id, isCollapsed);
};

@@ -88,14 +88,2 @@

useEffect(() => {
if (defaultOpened) {
dispatch({
type: 'accordion/SET_OPENED',
payload: {id, value: true},
});
}
hasRendered.current = true;
//eslint-disable-next-line
}, []);
useLayoutEffect(() => {
const content = contentRef.current;

@@ -166,6 +154,4 @@

if (hasRendered.current === false) return;
isCollapsed ? collapse() : expand();
isHidden ? collapse() : expand();
return () => {

@@ -177,3 +163,3 @@ if (!content) {

};
}, [isHidden, reduceMotion]);
}, [isCollapsed, reduceMotion]);

@@ -204,3 +190,3 @@ return (

onBlur={handleBlur}
aria-expanded={!isHidden}
aria-expanded={!isCollapsed}
aria-controls={contentId}

@@ -216,10 +202,14 @@ id={id}

>
<Link
size={titleSize}
color="black"
weight="bold"
underlined={isHighlighted}
>
{title}
</Link>
{isTitleString ? (
<Link
size={titleSize}
color="black"
weight="bold"
underlined={isHighlighted}
>
{title}
</Link>
) : (
<span className="sg-accordion-item__title">{title}</span>
)}
<Flex

@@ -236,3 +226,3 @@ justifyContent="center"

className={cx('sg-accordion-item__arrow', {
'sg-accordion-item__arrow--visible': !isHidden,
'sg-accordion-item__arrow--visible': !isCollapsed,
})}

@@ -239,0 +229,0 @@ />

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc