@deque/cauldron-react 2.0.0-canary.22e43f33 → 2.0.0-canary.83f76419

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/cauldron.css CHANGED
@@ -1,28 +1,66 @@
1
+ :root {
2
+ --expandcollapse-trigger-background-color: transparent;
3
+ --expandcollapse-trigger-color: var(--gray-90);
4
+ --expandcollapse-panel-background-color: transparent;
5
+ --expandcollapse-panel-color: var(--gray-90);
6
+ }
7
+
1
8
  .ExpandCollapse__trigger {
2
9
  font-size: inherit;
3
10
  display: flex;
4
11
  align-items: center;
12
+ background-color: var(--expandcollapse-trigger-background-color);
13
+ color: var(--expandcollapse-trigger-color);
14
+ }
15
+
16
+ .fullWidth {
17
+ width: 100%;
18
+ }
19
+
20
+ .ExpandCollapse__trigger-title {
21
+ flex-grow: 1;
22
+ text-align: left;
23
+ }
24
+
25
+ .ExpandCollapse__panel {
26
+ background-color: var(--expandcollapse-panel-background-color);
27
+ color: var(--expandcollapse-panel-color);
28
+ }
29
+
30
+ /* Dark Theme */
31
+
32
+ .cauldron--theme-dark {
33
+ --expandcollapse-trigger-color: var(--white);
34
+ --expandcollapse-panel-color: var(--accent-light);
5
35
  }
36
+
6
37
  a.Button--primary {
7
38
  text-decoration: none;
8
39
  padding: 9px 18px;
9
40
  }
41
+
10
42
  .Icon {
11
43
  display: inline-block;
12
44
  vertical-align: middle;
13
45
  }
46
+
14
47
  .Icon svg {
15
48
  display: block;
16
49
  }
50
+
17
51
  /* Icon--right is the default orientation */
52
+
18
53
  .Icon__right {
19
54
  }
55
+
20
56
  .Icon__left {
21
57
  transform: scaleX(-1);
22
58
  }
59
+
23
60
  .Icon__up {
24
61
  transform: rotate(-90deg);
25
62
  }
63
+
26
64
  .Icon__down {
27
65
  transform: rotate(90deg);
28
66
  }
@@ -5,9 +5,10 @@ export interface PanelTriggerProps extends React.ButtonHTMLAttributes<HTMLButton
5
5
  open: boolean;
6
6
  }) => React.ReactNode) | React.ReactNode;
7
7
  open?: boolean;
8
+ fullWidth?: string;
8
9
  onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
9
10
  }
10
- declare function PanelTrigger({ children, className, open, onClick, ...other }: PanelTriggerProps): JSX.Element;
11
+ declare function PanelTrigger({ children, className, open, fullWidth, onClick, ...other }: PanelTriggerProps): JSX.Element;
11
12
  declare namespace PanelTrigger {
12
13
  var propTypes: {
13
14
  children: PropTypes.Requireable<string | number | boolean | {} | PropTypes.ReactElementLike | PropTypes.ReactNodeArray>;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { TooltipProps } from '../Tooltip';
3
- interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
3
+ export interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
4
4
  icon: string;
5
5
  label: string;
6
6
  tooltipPlacement?: TooltipProps['placement'];
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import IconButton from '../IconButton';
4
+ declare const Panel: {
5
+ ({ className, title, actions, children }: {
6
+ className?: string | undefined;
7
+ title?: string | undefined;
8
+ actions?: React.ForwardRefExoticComponent<import("../IconButton").IconButtonProps & React.RefAttributes<HTMLButtonElement>>[] | undefined;
9
+ children: React.ReactNode;
10
+ }): JSX.Element;
11
+ displayName: string;
12
+ propTypes: {
13
+ children: PropTypes.Validator<string | number | boolean | {} | PropTypes.ReactElementLike | PropTypes.ReactNodeArray>;
14
+ className: PropTypes.Requireable<string>;
15
+ };
16
+ };
17
+ export default Panel;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ interface TabProps extends React.HTMLAttributes<HTMLLIElement> {
3
+ children?: React.ReactNode;
4
+ }
5
+ declare const Tab: React.ForwardRefExoticComponent<TabProps & React.RefAttributes<HTMLLIElement>>;
6
+ export default Tab;
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ interface TabPanelProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ children?: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ declare const TabPanel: {
8
+ ({ children, ...other }: TabPanelProps): JSX.Element;
9
+ displayName: string;
10
+ Proptypes: {
11
+ children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
12
+ className: PropTypes.Requireable<string>;
13
+ };
14
+ };
15
+ export default TabPanel;
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ declare type TabsVariant = 'full-width';
4
+ declare type LabelProps = {
5
+ 'aria-label': string;
6
+ } | {
7
+ 'aria-labelledby': string;
8
+ };
9
+ declare type TabsProps = {
10
+ children: React.ReactNode;
11
+ initialActiveIndex?: number;
12
+ id?: string;
13
+ thin?: boolean;
14
+ className?: string;
15
+ variant?: TabsVariant;
16
+ } & LabelProps;
17
+ declare const Tabs: {
18
+ ({ children, thin, id: propId, initialActiveIndex, variant, className, ...labelProp }: TabsProps): JSX.Element;
19
+ displayName: string;
20
+ propTypes: {
21
+ children: PropTypes.Validator<string | number | boolean | {} | PropTypes.ReactElementLike | PropTypes.ReactNodeArray>;
22
+ label: PropTypes.Requireable<string>;
23
+ labelledby: PropTypes.Requireable<string>;
24
+ id: PropTypes.Requireable<string>;
25
+ initialActiveIndex: PropTypes.Requireable<number>;
26
+ thin: PropTypes.Requireable<boolean>;
27
+ className: PropTypes.Requireable<string>;
28
+ variant: PropTypes.Requireable<string>;
29
+ };
30
+ };
31
+ export default Tabs;
@@ -0,0 +1,3 @@
1
+ export { default } from './Tabs';
2
+ export { default as Tab } from './Tab';
3
+ export { default as TabPanel } from './TabPanel';
@@ -42,7 +42,6 @@ export default class TextField extends React.Component<TextFieldProps, TextField
42
42
  private errorId;
43
43
  private input;
44
44
  constructor(props: TextFieldProps);
45
- componentDidUpdate(prevProps: TextFieldProps): void;
46
45
  render(): JSX.Element;
47
46
  onChange(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void;
48
47
  }
package/lib/index.d.ts CHANGED
@@ -37,13 +37,16 @@ export { default as LoaderOverlay } from './components/LoaderOverlay';
37
37
  export { default as Line } from './components/Line';
38
38
  export { default as Tag, TagLabel } from './components/Tag';
39
39
  export { default as Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './components/Table';
40
+ export { default as Tabs, Tab, TabPanel } from './components/Tabs';
40
41
  export { DescriptionList, DescriptionListItem, DescriptionTerm, DescriptionDetails } from './components/DescriptionList';
41
42
  export { default as Stepper, Step } from './components/Stepper';
43
+ export { default as Panel } from './components/Panel';
42
44
  /**
43
45
  * Helpers / Utils
44
46
  */
45
47
  export { default as AriaIsolate } from './utils/aria-isolate';
46
48
  export { default as focusableSelector } from './utils/focusable-selector';
49
+ export { default as useDidUpdate } from './utils/use-did-update';
47
50
  /**
48
51
  * Contexts
49
52
  */
package/lib/index.js CHANGED
@@ -2291,21 +2291,12 @@ var TextField = /** @class */ (function (_super) {
2291
2291
  _this.onChange = _this.onChange.bind(_this);
2292
2292
  return _this;
2293
2293
  }
2294
- TextField.prototype.componentDidUpdate = function (prevProps) {
2295
- var value = this.props.value;
2296
- if (value === prevProps.value) {
2297
- return;
2298
- }
2299
- this.setState({ value: value });
2300
- };
2301
2294
  TextField.prototype.render = function () {
2302
2295
  var _this = this;
2303
2296
  var isRequired = !!this.props.required;
2304
2297
  // disabling `no-unused-vars` to prevent specific
2305
2298
  // props from being passed through to the input
2306
- var _a = this.props, label = _a.label, fieldRef = _a.fieldRef,
2307
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2308
- value = _a.value,
2299
+ var _a = this.props, label = _a.label, fieldRef = _a.fieldRef, value = _a.value,
2309
2300
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2310
2301
  onChange = _a.onChange,
2311
2302
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -2330,7 +2321,7 @@ var TextField = /** @class */ (function (_super) {
2330
2321
  'Field__text-input': !multiline,
2331
2322
  Field__textarea: multiline,
2332
2323
  'Field--has-error': error
2333
- }), id: this.inputId, value: this.state.value, onChange: this.onChange, "aria-invalid": !!error, ref: function (input) {
2324
+ }), id: this.inputId, value: typeof value !== 'undefined' ? value : this.state.value, onChange: this.onChange, "aria-invalid": !!error, ref: function (input) {
2334
2325
  _this.input = input;
2335
2326
  setRef(fieldRef, input);
2336
2327
  } }, other, inputProps)),
@@ -2380,10 +2371,9 @@ var TextField = /** @class */ (function (_super) {
2380
2371
  }(React__default.Component));
2381
2372
 
2382
2373
  function PanelTrigger(_a) {
2383
- var children = _a.children, className = _a.className, open = _a.open, onClick = _a.onClick, other = tslib.__rest(_a, ["children", "className", "open", "onClick"]);
2384
- return (React__default.createElement("button", tslib.__assign({}, other, { className: classNames('ExpandCollapse__trigger', className), type: "button", "aria-expanded": open, onClick: onClick }),
2385
- typeof children === 'function' ? children({ open: !!open }) : children,
2386
- ' ',
2374
+ var children = _a.children, className = _a.className, open = _a.open, fullWidth = _a.fullWidth, onClick = _a.onClick, other = tslib.__rest(_a, ["children", "className", "open", "fullWidth", "onClick"]);
2375
+ return (React__default.createElement("button", tslib.__assign({}, other, { className: classNames('ExpandCollapse__trigger', fullWidth ? 'fullWidth' : '', className), type: "button", "aria-expanded": open, onClick: onClick }),
2376
+ React__default.createElement("div", { className: "ExpandCollapse__trigger-title" }, typeof children === 'function' ? children({ open: !!open }) : children),
2387
2377
  React__default.createElement(Icon, { type: "chevron-" + (open ? 'down' : 'right') })));
2388
2378
  }
2389
2379
  PanelTrigger.propTypes = {
@@ -2506,7 +2496,7 @@ var ExpandCollapsePanel = /** @class */ (function (_super) {
2506
2496
  open: isOpen,
2507
2497
  onClick: this.handleToggle
2508
2498
  }),
2509
- React__default.createElement("div", tslib.__assign({}, other, { className: classNames(animationClass, className, {
2499
+ React__default.createElement("div", tslib.__assign({}, other, { className: classNames('ExpandCollapse__panel', animationClass, className, {
2510
2500
  'is--hidden': !isOpen && !isAnimating
2511
2501
  }), ref: this.panel }), panelElements)));
2512
2502
  };
@@ -7872,6 +7862,113 @@ TableRow.propTypes = {
7872
7862
  className: PropTypes.string
7873
7863
  };
7874
7864
 
7865
+ var TabPanel = function (_a) {
7866
+ var children = _a.children, other = tslib.__rest(_a, ["children"]);
7867
+ return (React__default.createElement("div", tslib.__assign({ role: "tabpanel" }, other), children));
7868
+ };
7869
+ TabPanel.displayName = 'TabPanel';
7870
+ TabPanel.Proptypes = {
7871
+ children: PropTypes.node,
7872
+ className: PropTypes.string
7873
+ };
7874
+
7875
+ var Tab = React__default.forwardRef(function (_a, ref) {
7876
+ var children = _a.children, other = tslib.__rest(_a, ["children"]);
7877
+ return (React__default.createElement("li", tslib.__assign({ ref: ref, role: "tab" }, other), children));
7878
+ });
7879
+ Tab.displayName = 'Tab';
7880
+ Tab.propTypes = {
7881
+ children: PropTypes.node
7882
+ };
7883
+
7884
+ var _a$1 = [37, 39, 36, 35], left = _a$1[0], right = _a$1[1], home = _a$1[2], end = _a$1[3];
7885
+ var Tabs = function (_a) {
7886
+ var children = _a.children, thin = _a.thin, propId = _a.id, _b = _a.initialActiveIndex, initialActiveIndex = _b === void 0 ? 0 : _b, variant = _a.variant, className = _a.className, labelProp = tslib.__rest(_a, ["children", "thin", "id", "initialActiveIndex", "variant", "className"]);
7887
+ var _c = React.useState(initialActiveIndex), activeIndex = _c[0], setActiveIndex = _c[1];
7888
+ var id = (propId ? [propId] : nextId.useId(1, 'tabs'))[0];
7889
+ var focusedTabRef = React.useRef(null);
7890
+ var tabs = React__default.Children.toArray(children).filter(function (child) { return child.type === Tab; });
7891
+ var panels = React__default.Children.toArray(children).filter(function (child) { return child.type === TabPanel; });
7892
+ var tabCount = tabs.length;
7893
+ var handleClick = function (index) {
7894
+ setActiveIndex(index);
7895
+ };
7896
+ var handleKeyDown = function (event) {
7897
+ var which = event.which;
7898
+ var newIndex = activeIndex;
7899
+ switch (which) {
7900
+ case left: {
7901
+ newIndex = activeIndex - 1;
7902
+ // circularity
7903
+ if (newIndex === -1) {
7904
+ newIndex = tabCount - 1;
7905
+ }
7906
+ setActiveIndex(newIndex);
7907
+ break;
7908
+ }
7909
+ case right: {
7910
+ newIndex = activeIndex + 1;
7911
+ // circularity
7912
+ if (newIndex === tabCount) {
7913
+ newIndex = 0;
7914
+ }
7915
+ setActiveIndex(newIndex);
7916
+ break;
7917
+ }
7918
+ case home: {
7919
+ newIndex = 0;
7920
+ setActiveIndex(newIndex);
7921
+ break;
7922
+ }
7923
+ case end: {
7924
+ newIndex = tabCount - 1;
7925
+ setActiveIndex(newIndex);
7926
+ break;
7927
+ }
7928
+ }
7929
+ };
7930
+ var tabComponents = tabs.map(function (child, index) {
7931
+ var _a;
7932
+ var other = tslib.__rest(child.props, []);
7933
+ var selected = index === activeIndex;
7934
+ var config = tslib.__assign((_a = { id: id + "-" + index, className: classNames('Tab', {
7935
+ 'Tab--active': selected,
7936
+ 'Tab--full-width': variant === 'full-width'
7937
+ }), tabIndex: index === activeIndex ? 0 : -1 }, _a['aria-controls'] = id + "-panel-" + index, _a['aria-selected'] = selected, _a.ref = index === activeIndex ? focusedTabRef : null, _a.onClick = function () { return handleClick(index); }, _a), other);
7938
+ return React__default.cloneElement(child, config);
7939
+ });
7940
+ var tabPanelComponents = panels.map(function (child, index) {
7941
+ var _a;
7942
+ var _b = child.props, className = _b.className, other = tslib.__rest(_b, ["className"]);
7943
+ var panelId = id + "-panel-" + index;
7944
+ return React__default.cloneElement(child, tslib.__assign((_a = { id: panelId }, _a['aria-labelledby'] = id + "-" + index, _a.className = classNames('TabPanel', className, {
7945
+ 'TabPanel--hidden': activeIndex !== index
7946
+ }), _a), other));
7947
+ });
7948
+ useDidUpdate(function () {
7949
+ var _a;
7950
+ (_a = focusedTabRef.current) === null || _a === void 0 ? void 0 : _a.focus();
7951
+ }, [activeIndex]);
7952
+ return (React__default.createElement("div", { className: classNames('Tabs', className, {
7953
+ 'Tabs--thin': thin
7954
+ }) },
7955
+ React__default.createElement("ul", tslib.__assign({ role: "tablist", className: classNames('Tablist', {
7956
+ 'Tablist--full-width': variant === 'full-width'
7957
+ }) }, labelProp, { onKeyDown: handleKeyDown }), tabComponents),
7958
+ tabPanelComponents));
7959
+ };
7960
+ Tabs.displayName = 'Tabs';
7961
+ Tabs.propTypes = {
7962
+ children: PropTypes.node.isRequired,
7963
+ label: PropTypes.string,
7964
+ labelledby: PropTypes.string,
7965
+ id: PropTypes.string,
7966
+ initialActiveIndex: PropTypes.number,
7967
+ thin: PropTypes.bool,
7968
+ className: PropTypes.string,
7969
+ variant: PropTypes.string
7970
+ };
7971
+
7875
7972
  var commonPropTypes = {
7876
7973
  children: PropTypes.node.isRequired,
7877
7974
  className: PropTypes.string
@@ -7937,6 +8034,39 @@ Stepper.propTypes = {
7937
8034
  className: PropTypes.string
7938
8035
  };
7939
8036
 
8037
+ var Panel = function (_a) {
8038
+ var className = _a.className, _b = _a.title, title = _b === void 0 ? '' : _b, actions = _a.actions, children = _a.children;
8039
+ return (React__default.createElement("div", { className: classNames('Panel', className) },
8040
+ React__default.createElement("div", { className: "Panel__Header" },
8041
+ title && React__default.createElement("div", { className: "Panel__Header-title" }, title),
8042
+ actions && React__default.createElement("div", { className: "Panel__Header-actions" }, actions)),
8043
+ React__default.createElement("div", { className: "Panel__Content" }, children)));
8044
+ };
8045
+ Panel.displayName = 'Panel';
8046
+ Panel.propTypes = {
8047
+ children: PropTypes.node.isRequired,
8048
+ className: PropTypes.string
8049
+ };
8050
+
8051
+ /**
8052
+ * Hook to be used similarly to the React.Component#componentDidMount.
8053
+ * Executes the provided `effect` when `dependencies` change but does not
8054
+ * execute the effect initially (on mount) - only on update.
8055
+ *
8056
+ * @param effect {Function} function to be executed when dependencies update
8057
+ * @param dependencies {Any} any valid dependency argument to React.useEffect
8058
+ */
8059
+ var useDidUpdate = function (effect, dependencies) {
8060
+ var mounted = React__default.useRef(false);
8061
+ React__default.useEffect(function () {
8062
+ if (!mounted.current) {
8063
+ mounted.current = true;
8064
+ return;
8065
+ }
8066
+ effect();
8067
+ }, dependencies);
8068
+ };
8069
+
7940
8070
  var LIGHT_THEME_CLASS = 'cauldron--theme-light';
7941
8071
  var DARK_THEME_CLASS = 'cauldron--theme-dark';
7942
8072
  var ThemeContext = React.createContext({});
@@ -8025,6 +8155,7 @@ exports.OptionsMenuItem = OptionsMenuItem;
8025
8155
  exports.OptionsMenuList = OptionsMenuList;
8026
8156
  exports.OptionsMenuTrigger = OptionsMenuTrigger;
8027
8157
  exports.OptionsMenuWrapper = OptionsMenuWrapper;
8158
+ exports.Panel = Panel;
8028
8159
  exports.PanelTrigger = PanelTrigger$1;
8029
8160
  exports.Pointout = Pointout;
8030
8161
  exports.RadioGroup = RadioGroup;
@@ -8036,12 +8167,15 @@ exports.Sidebar = SideBar;
8036
8167
  exports.SkipLink = SkipLink;
8037
8168
  exports.Step = Step;
8038
8169
  exports.Stepper = Stepper;
8170
+ exports.Tab = Tab;
8171
+ exports.TabPanel = TabPanel;
8039
8172
  exports.Table = Table;
8040
8173
  exports.TableBody = TableBody;
8041
8174
  exports.TableCell = TableCell;
8042
8175
  exports.TableHead = TableHead;
8043
8176
  exports.TableHeader = TableHeader;
8044
8177
  exports.TableRow = TableRow;
8178
+ exports.Tabs = Tabs;
8045
8179
  exports.Tag = Tag;
8046
8180
  exports.TagLabel = TagLabel;
8047
8181
  exports.TextField = TextField;
@@ -8058,4 +8192,5 @@ exports.TopBarMenu = TopBarMenu;
8058
8192
  exports.TopBarTrigger = TopBarTrigger;
8059
8193
  exports.Workspace = Workspace;
8060
8194
  exports.focusableSelector = focusableSelector;
8195
+ exports.useDidUpdate = useDidUpdate;
8061
8196
  exports.useThemeContext = useThemeContext;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hook to be used similarly to the React.Component#componentDidMount.
3
+ * Executes the provided `effect` when `dependencies` change but does not
4
+ * execute the effect initially (on mount) - only on update.
5
+ *
6
+ * @param effect {Function} function to be executed when dependencies update
7
+ * @param dependencies {Any} any valid dependency argument to React.useEffect
8
+ */
9
+ declare const useDidUpdate: (effect: () => void, dependencies: unknown[]) => void;
10
+ export default useDidUpdate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deque/cauldron-react",
3
- "version": "2.0.0-canary.22e43f33",
3
+ "version": "2.0.0-canary.83f76419",
4
4
  "description": "Fully accessible react components library for Deque Cauldron",
5
5
  "publishConfig": {
6
6
  "access": "public"