@elliemae/ds-chip 3.70.0-next.60 → 3.70.0-next.61
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/dist/cjs/DSChip.js +23 -1
- package/dist/cjs/DSChip.js.map +2 -2
- package/dist/cjs/config/useEscapeDismiss.js +48 -0
- package/dist/cjs/config/useEscapeDismiss.js.map +7 -0
- package/dist/cjs/config/useLabelExpansion.js +111 -0
- package/dist/cjs/config/useLabelExpansion.js.map +7 -0
- package/dist/cjs/styles.js +7 -8
- package/dist/cjs/styles.js.map +2 -2
- package/dist/esm/DSChip.js +23 -1
- package/dist/esm/DSChip.js.map +2 -2
- package/dist/esm/config/useEscapeDismiss.js +18 -0
- package/dist/esm/config/useEscapeDismiss.js.map +7 -0
- package/dist/esm/config/useLabelExpansion.js +81 -0
- package/dist/esm/config/useLabelExpansion.js.map +7 -0
- package/dist/esm/styles.js +7 -8
- package/dist/esm/styles.js.map +2 -2
- package/dist/types/config/useEscapeDismiss.d.ts +1 -0
- package/dist/types/config/useLabelExpansion.d.ts +18 -0
- package/dist/types/styles.d.ts +2 -1
- package/package.json +6 -6
package/dist/cjs/DSChip.js
CHANGED
|
@@ -39,6 +39,7 @@ var import_ds_props_helpers = require("@elliemae/ds-props-helpers");
|
|
|
39
39
|
var import_ds_typography = require("@elliemae/ds-typography");
|
|
40
40
|
var import_ds_icon = require("@elliemae/ds-icon");
|
|
41
41
|
var import_useConfig = require("./config/useConfig.js");
|
|
42
|
+
var import_useLabelExpansion = require("./config/useLabelExpansion.js");
|
|
42
43
|
var import_styles = require("./styles.js");
|
|
43
44
|
var import_constants = require("./constants/index.js");
|
|
44
45
|
var import_react_desc_prop_types = require("./react-desc-prop-types.js");
|
|
@@ -56,7 +57,24 @@ const DSChip = (props) => {
|
|
|
56
57
|
ownerPropsConfig,
|
|
57
58
|
wrapText
|
|
58
59
|
} = (0, import_useConfig.useConfig)(props);
|
|
59
|
-
const {
|
|
60
|
+
const {
|
|
61
|
+
disabled,
|
|
62
|
+
className,
|
|
63
|
+
onClick,
|
|
64
|
+
// Composed into the expansion handlers below. `onKeyDown` is not intercepted — Escape is handled
|
|
65
|
+
// at the document level, so it passes through untouched.
|
|
66
|
+
onMouseEnter: consumerMouseEnter,
|
|
67
|
+
onMouseLeave: consumerMouseLeave,
|
|
68
|
+
onFocus: consumerFocus,
|
|
69
|
+
onBlur: consumerBlur,
|
|
70
|
+
...restGlobals
|
|
71
|
+
} = globalAttrs;
|
|
72
|
+
const { expanded, labelRef, expansionHandlers } = (0, import_useLabelExpansion.useLabelExpansion)(wrapText, {
|
|
73
|
+
onMouseEnter: consumerMouseEnter,
|
|
74
|
+
onMouseLeave: consumerMouseLeave,
|
|
75
|
+
onFocus: consumerFocus,
|
|
76
|
+
onBlur: consumerBlur
|
|
77
|
+
});
|
|
60
78
|
const handleOnClick = (0, import_react.useCallback)(
|
|
61
79
|
(e) => {
|
|
62
80
|
if (applyAriaDisabled) return;
|
|
@@ -86,6 +104,9 @@ const DSChip = (props) => {
|
|
|
86
104
|
role: "button",
|
|
87
105
|
onClick: handleOnClick,
|
|
88
106
|
buttonSize: size,
|
|
107
|
+
expanded,
|
|
108
|
+
"data-expanded": expanded || void 0,
|
|
109
|
+
...expansionHandlers,
|
|
89
110
|
...restGlobals,
|
|
90
111
|
...ownerPropsConfig,
|
|
91
112
|
children: [
|
|
@@ -96,6 +117,7 @@ const DSChip = (props) => {
|
|
|
96
117
|
component: "span",
|
|
97
118
|
variant: import_ds_typography.TYPOGRAPHY_VARIANTS.B4,
|
|
98
119
|
wrapText,
|
|
120
|
+
innerRef: labelRef,
|
|
99
121
|
...ownerPropsConfig,
|
|
100
122
|
children: label
|
|
101
123
|
}
|
package/dist/cjs/DSChip.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/DSChip.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["import React, { useCallback } from 'react';\nimport { describe } from '@elliemae/ds-props-helpers';\nimport { TYPOGRAPHY_VARIANTS } from '@elliemae/ds-typography';\nimport { DSIconSizes } from '@elliemae/ds-icon';\nimport { useConfig } from './config/useConfig.js';\nimport { StyledChip, StyledChipLabel, StyledWrapper, StyledRoundShape, StyledSpanWithEllipsis } from './styles.js';\nimport { CHIP_SHAPES } from './constants/index.js';\nimport type { DSChipT } from './react-desc-prop-types.js';\nimport { DSChipPropTypesSchema } from './react-desc-prop-types.js';\n\nconst DSChip: React.ComponentType<DSChipT.Props> = (props) => {\n const {\n size,\n shape,\n selected,\n applyAriaDisabled,\n innerRef,\n icon: Icon,\n label,\n globalAttrs,\n xStyledAttrs,\n ownerPropsConfig,\n wrapText,\n } = useConfig(props);\n\n const {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;
|
|
4
|
+
"sourcesContent": ["import React, { useCallback } from 'react';\nimport { describe } from '@elliemae/ds-props-helpers';\nimport { TYPOGRAPHY_VARIANTS } from '@elliemae/ds-typography';\nimport { DSIconSizes } from '@elliemae/ds-icon';\nimport { useConfig } from './config/useConfig.js';\nimport { useLabelExpansion } from './config/useLabelExpansion.js';\nimport { StyledChip, StyledChipLabel, StyledWrapper, StyledRoundShape, StyledSpanWithEllipsis } from './styles.js';\nimport { CHIP_SHAPES } from './constants/index.js';\nimport type { DSChipT } from './react-desc-prop-types.js';\nimport { DSChipPropTypesSchema } from './react-desc-prop-types.js';\n\nconst DSChip: React.ComponentType<DSChipT.Props> = (props) => {\n const {\n size,\n shape,\n selected,\n applyAriaDisabled,\n innerRef,\n icon: Icon,\n label,\n globalAttrs,\n xStyledAttrs,\n ownerPropsConfig,\n wrapText,\n } = useConfig(props);\n\n const {\n disabled,\n className,\n onClick,\n // Composed into the expansion handlers below. `onKeyDown` is not intercepted \u2014 Escape is handled\n // at the document level, so it passes through untouched.\n onMouseEnter: consumerMouseEnter,\n onMouseLeave: consumerMouseLeave,\n onFocus: consumerFocus,\n onBlur: consumerBlur,\n ...restGlobals\n } = globalAttrs;\n\n const { expanded, labelRef, expansionHandlers } = useLabelExpansion(wrapText, {\n onMouseEnter: consumerMouseEnter,\n onMouseLeave: consumerMouseLeave,\n onFocus: consumerFocus,\n onBlur: consumerBlur,\n });\n\n const handleOnClick = useCallback(\n (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (applyAriaDisabled) return;\n if (onClick) {\n onClick(e);\n }\n },\n [applyAriaDisabled, onClick],\n );\n\n return (\n <StyledWrapper\n wrapText={wrapText}\n buttonShape={shape}\n buttonSize={size}\n className={className}\n {...xStyledAttrs}\n {...ownerPropsConfig}\n >\n <StyledChip\n buttonShape={shape}\n aria-disabled={disabled || applyAriaDisabled}\n disabled={disabled}\n innerRef={innerRef}\n selected={selected}\n role=\"button\"\n onClick={handleOnClick}\n buttonSize={size}\n expanded={expanded}\n data-expanded={expanded || undefined}\n {...expansionHandlers}\n {...restGlobals}\n {...ownerPropsConfig}\n >\n {shape === CHIP_SHAPES.ROUND ? (\n <StyledRoundShape disabled={disabled} size={size} {...ownerPropsConfig}>\n <Icon size={DSIconSizes.M} />\n </StyledRoundShape>\n ) : (\n <Icon size={DSIconSizes.M} />\n )}\n <StyledChipLabel size={size} {...ownerPropsConfig}>\n <StyledSpanWithEllipsis\n component=\"span\"\n variant={TYPOGRAPHY_VARIANTS.B4}\n wrapText={wrapText}\n innerRef={labelRef}\n {...ownerPropsConfig}\n >\n {label}\n </StyledSpanWithEllipsis>\n </StyledChipLabel>\n </StyledChip>\n </StyledWrapper>\n );\n};\n\nDSChip.displayName = 'DSChip';\nconst DSChipWithSchema = describe(DSChip);\nDSChipWithSchema.propTypes = DSChipPropTypesSchema;\n\nexport { DSChip, DSChipWithSchema };\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADiEjB;AAjEN,mBAAmC;AACnC,8BAAyB;AACzB,2BAAoC;AACpC,qBAA4B;AAC5B,uBAA0B;AAC1B,+BAAkC;AAClC,oBAAqG;AACrG,uBAA4B;AAE5B,mCAAsC;AAEtC,MAAM,SAA6C,CAAC,UAAU;AAC5D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,QAAI,4BAAU,KAAK;AAEnB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,cAAc;AAAA,IACd,cAAc;AAAA,IACd,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,EAAE,UAAU,UAAU,kBAAkB,QAAI,4CAAkB,UAAU;AAAA,IAC5E,cAAc;AAAA,IACd,cAAc;AAAA,IACd,SAAS;AAAA,IACT,QAAQ;AAAA,EACV,CAAC;AAED,QAAM,oBAAgB;AAAA,IACpB,CAAC,MAAuD;AACtD,UAAI,kBAAmB;AACvB,UAAI,SAAS;AACX,gBAAQ,CAAC;AAAA,MACX;AAAA,IACF;AAAA,IACA,CAAC,mBAAmB,OAAO;AAAA,EAC7B;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAa;AAAA,MACb,YAAY;AAAA,MACZ;AAAA,MACC,GAAG;AAAA,MACH,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,aAAa;AAAA,UACb,iBAAe,YAAY;AAAA,UAC3B;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAK;AAAA,UACL,SAAS;AAAA,UACT,YAAY;AAAA,UACZ;AAAA,UACA,iBAAe,YAAY;AAAA,UAC1B,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG;AAAA,UAEH;AAAA,sBAAU,6BAAY,QACrB,4CAAC,kCAAiB,UAAoB,MAAa,GAAG,kBACpD,sDAAC,QAAK,MAAM,2BAAY,GAAG,GAC7B,IAEA,4CAAC,QAAK,MAAM,2BAAY,GAAG;AAAA,YAE7B,4CAAC,iCAAgB,MAAa,GAAG,kBAC/B;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAAS,yCAAoB;AAAA,gBAC7B;AAAA,gBACA,UAAU;AAAA,gBACT,GAAG;AAAA,gBAEH;AAAA;AAAA,YACH,GACF;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAEA,OAAO,cAAc;AACrB,MAAM,uBAAmB,kCAAS,MAAM;AACxC,iBAAiB,YAAY;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var useEscapeDismiss_exports = {};
|
|
30
|
+
__export(useEscapeDismiss_exports, {
|
|
31
|
+
useEscapeDismiss: () => useEscapeDismiss
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useEscapeDismiss_exports);
|
|
34
|
+
var React = __toESM(require("react"));
|
|
35
|
+
var import_react = require("react");
|
|
36
|
+
const useEscapeDismiss = (active, onDismiss) => {
|
|
37
|
+
(0, import_react.useEffect)(() => {
|
|
38
|
+
if (!active) return void 0;
|
|
39
|
+
const handleDocumentKeyDown = (e) => {
|
|
40
|
+
if (e.key !== "Escape") return;
|
|
41
|
+
onDismiss();
|
|
42
|
+
e.stopPropagation();
|
|
43
|
+
};
|
|
44
|
+
document.addEventListener("keydown", handleDocumentKeyDown, true);
|
|
45
|
+
return () => document.removeEventListener("keydown", handleDocumentKeyDown, true);
|
|
46
|
+
}, [active, onDismiss]);
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=useEscapeDismiss.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/config/useEscapeDismiss.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import { useEffect } from 'react';\n\n// A hover-expanded label can't see keydown from the chip itself \u2014 the event targets whatever holds\n// focus. Capture on document runs before React's root delegation, so stopPropagation here also blocks\n// ancestor Escape handlers. Subscribed only while active, so Escape is consumed only when it dismisses.\nexport const useEscapeDismiss = (active: boolean, onDismiss: () => void): void => {\n useEffect(() => {\n if (!active) return undefined;\n const handleDocumentKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n onDismiss();\n e.stopPropagation();\n };\n document.addEventListener('keydown', handleDocumentKeyDown, true);\n return () => document.removeEventListener('keydown', handleDocumentKeyDown, true);\n }, [active, onDismiss]);\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAA0B;AAKnB,MAAM,mBAAmB,CAAC,QAAiB,cAAgC;AAChF,8BAAU,MAAM;AACd,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,wBAAwB,CAAC,MAAqB;AAClD,UAAI,EAAE,QAAQ,SAAU;AACxB,gBAAU;AACV,QAAE,gBAAgB;AAAA,IACpB;AACA,aAAS,iBAAiB,WAAW,uBAAuB,IAAI;AAChE,WAAO,MAAM,SAAS,oBAAoB,WAAW,uBAAuB,IAAI;AAAA,EAClF,GAAG,CAAC,QAAQ,SAAS,CAAC;AACxB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var useLabelExpansion_exports = {};
|
|
30
|
+
__export(useLabelExpansion_exports, {
|
|
31
|
+
useLabelExpansion: () => useLabelExpansion
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useLabelExpansion_exports);
|
|
34
|
+
var React = __toESM(require("react"));
|
|
35
|
+
var import_react = require("react");
|
|
36
|
+
var import_useEscapeDismiss = require("./useEscapeDismiss.js");
|
|
37
|
+
const useLabelExpansion = (wrapText, consumer) => {
|
|
38
|
+
const [isHovered, setIsHovered] = (0, import_react.useState)(false);
|
|
39
|
+
const [isFocused, setIsFocused] = (0, import_react.useState)(false);
|
|
40
|
+
const [isDismissed, setIsDismissed] = (0, import_react.useState)(false);
|
|
41
|
+
const [isOverflowing, setIsOverflowing] = (0, import_react.useState)(false);
|
|
42
|
+
const hoveredRef = (0, import_react.useRef)(false);
|
|
43
|
+
const focusedRef = (0, import_react.useRef)(false);
|
|
44
|
+
const dismissedRef = (0, import_react.useRef)(false);
|
|
45
|
+
const labelRef = (0, import_react.useRef)(null);
|
|
46
|
+
const expanded = !wrapText && isOverflowing && (isHovered || isFocused) && !isDismissed;
|
|
47
|
+
const measureOverflowOnEntry = (0, import_react.useCallback)(() => {
|
|
48
|
+
if (wrapText || hoveredRef.current || focusedRef.current) return;
|
|
49
|
+
const node = labelRef.current;
|
|
50
|
+
setIsOverflowing(!!node && node.scrollWidth > node.clientWidth);
|
|
51
|
+
}, [wrapText]);
|
|
52
|
+
const rearmIfLeft = (0, import_react.useCallback)(() => {
|
|
53
|
+
if (!hoveredRef.current && !focusedRef.current && dismissedRef.current) {
|
|
54
|
+
dismissedRef.current = false;
|
|
55
|
+
setIsDismissed(false);
|
|
56
|
+
}
|
|
57
|
+
}, []);
|
|
58
|
+
const { onMouseEnter, onMouseLeave, onFocus, onBlur } = consumer;
|
|
59
|
+
const handleMouseEnter = (0, import_react.useCallback)(
|
|
60
|
+
(e) => {
|
|
61
|
+
measureOverflowOnEntry();
|
|
62
|
+
hoveredRef.current = true;
|
|
63
|
+
setIsHovered(true);
|
|
64
|
+
onMouseEnter?.(e);
|
|
65
|
+
},
|
|
66
|
+
[onMouseEnter, measureOverflowOnEntry]
|
|
67
|
+
);
|
|
68
|
+
const handleMouseLeave = (0, import_react.useCallback)(
|
|
69
|
+
(e) => {
|
|
70
|
+
hoveredRef.current = false;
|
|
71
|
+
setIsHovered(false);
|
|
72
|
+
rearmIfLeft();
|
|
73
|
+
onMouseLeave?.(e);
|
|
74
|
+
},
|
|
75
|
+
[onMouseLeave, rearmIfLeft]
|
|
76
|
+
);
|
|
77
|
+
const handleFocus = (0, import_react.useCallback)(
|
|
78
|
+
(e) => {
|
|
79
|
+
measureOverflowOnEntry();
|
|
80
|
+
focusedRef.current = true;
|
|
81
|
+
setIsFocused(true);
|
|
82
|
+
onFocus?.(e);
|
|
83
|
+
},
|
|
84
|
+
[onFocus, measureOverflowOnEntry]
|
|
85
|
+
);
|
|
86
|
+
const handleBlur = (0, import_react.useCallback)(
|
|
87
|
+
(e) => {
|
|
88
|
+
focusedRef.current = false;
|
|
89
|
+
setIsFocused(false);
|
|
90
|
+
rearmIfLeft();
|
|
91
|
+
onBlur?.(e);
|
|
92
|
+
},
|
|
93
|
+
[onBlur, rearmIfLeft]
|
|
94
|
+
);
|
|
95
|
+
const handleEscapeDismiss = (0, import_react.useCallback)(() => {
|
|
96
|
+
dismissedRef.current = true;
|
|
97
|
+
setIsDismissed(true);
|
|
98
|
+
}, []);
|
|
99
|
+
(0, import_useEscapeDismiss.useEscapeDismiss)(expanded, handleEscapeDismiss);
|
|
100
|
+
return {
|
|
101
|
+
expanded,
|
|
102
|
+
labelRef,
|
|
103
|
+
expansionHandlers: {
|
|
104
|
+
onMouseEnter: handleMouseEnter,
|
|
105
|
+
onMouseLeave: handleMouseLeave,
|
|
106
|
+
onFocus: handleFocus,
|
|
107
|
+
onBlur: handleBlur
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=useLabelExpansion.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/config/useLabelExpansion.ts", "../../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
+
"sourcesContent": ["import type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { useEscapeDismiss } from './useEscapeDismiss.js';\n\ninterface ConsumerHandlersT {\n onMouseEnter?: React.MouseEventHandler<HTMLButtonElement>;\n onMouseLeave?: React.MouseEventHandler<HTMLButtonElement>;\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n}\n\n// PUI-17950 \u2014 the expanded label overlays adjacent content, so WCAG 1.4.13 requires it be dismissible\n// without moving pointer or focus. That rules out CSS :hover/:focus, which a keypress cannot switch off.\n// `isOverflowing` matters beyond the visuals: without it a label that already fits would still claim an\n// expansion and swallow an Escape meant for an ancestor.\nexport const useLabelExpansion = (wrapText: boolean, consumer: ConsumerHandlersT) => {\n const [isHovered, setIsHovered] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [isDismissed, setIsDismissed] = useState(false);\n const [isOverflowing, setIsOverflowing] = useState(false);\n\n // Mirrored so the leave handlers read both signals in the same tick, without a useEffect.\n const hoveredRef = useRef(false);\n const focusedRef = useRef(false);\n const dismissedRef = useRef(false);\n const labelRef = useRef<HTMLDivElement | null>(null);\n\n const expanded = !wrapText && isOverflowing && (isHovered || isFocused) && !isDismissed;\n\n // Only on a fresh entry: an already-expanded label is no longer clipped and would measure as fitting.\n const measureOverflowOnEntry = useCallback(() => {\n if (wrapText || hoveredRef.current || focusedRef.current) return;\n const node = labelRef.current;\n setIsOverflowing(!!node && node.scrollWidth > node.clientWidth);\n }, [wrapText]);\n\n const rearmIfLeft = useCallback(() => {\n if (!hoveredRef.current && !focusedRef.current && dismissedRef.current) {\n dismissedRef.current = false;\n setIsDismissed(false);\n }\n }, []);\n\n const { onMouseEnter, onMouseLeave, onFocus, onBlur } = consumer;\n\n const handleMouseEnter = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n measureOverflowOnEntry();\n hoveredRef.current = true;\n setIsHovered(true);\n onMouseEnter?.(e);\n },\n [onMouseEnter, measureOverflowOnEntry],\n );\n\n const handleMouseLeave = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n hoveredRef.current = false;\n setIsHovered(false);\n rearmIfLeft();\n onMouseLeave?.(e);\n },\n [onMouseLeave, rearmIfLeft],\n );\n\n const handleFocus = useCallback(\n (e: React.FocusEvent<HTMLButtonElement>) => {\n measureOverflowOnEntry();\n focusedRef.current = true;\n setIsFocused(true);\n onFocus?.(e);\n },\n [onFocus, measureOverflowOnEntry],\n );\n\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLButtonElement>) => {\n focusedRef.current = false;\n setIsFocused(false);\n rearmIfLeft();\n onBlur?.(e);\n },\n [onBlur, rearmIfLeft],\n );\n\n // Stable, or useEscapeDismiss resubscribes every render.\n const handleEscapeDismiss = useCallback(() => {\n dismissedRef.current = true;\n setIsDismissed(true);\n }, []);\n\n useEscapeDismiss(expanded, handleEscapeDismiss);\n\n return {\n expanded,\n labelRef,\n expansionHandlers: {\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n onFocus: handleFocus,\n onBlur: handleBlur,\n },\n };\n};\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,mBAA8C;AAC9C,8BAAiC;AAa1B,MAAM,oBAAoB,CAAC,UAAmB,aAAgC;AACnF,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAChD,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,KAAK;AACpD,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,KAAK;AAGxD,QAAM,iBAAa,qBAAO,KAAK;AAC/B,QAAM,iBAAa,qBAAO,KAAK;AAC/B,QAAM,mBAAe,qBAAO,KAAK;AACjC,QAAM,eAAW,qBAA8B,IAAI;AAEnD,QAAM,WAAW,CAAC,YAAY,kBAAkB,aAAa,cAAc,CAAC;AAG5E,QAAM,6BAAyB,0BAAY,MAAM;AAC/C,QAAI,YAAY,WAAW,WAAW,WAAW,QAAS;AAC1D,UAAM,OAAO,SAAS;AACtB,qBAAiB,CAAC,CAAC,QAAQ,KAAK,cAAc,KAAK,WAAW;AAAA,EAChE,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,kBAAc,0BAAY,MAAM;AACpC,QAAI,CAAC,WAAW,WAAW,CAAC,WAAW,WAAW,aAAa,SAAS;AACtE,mBAAa,UAAU;AACvB,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,EAAE,cAAc,cAAc,SAAS,OAAO,IAAI;AAExD,QAAM,uBAAmB;AAAA,IACvB,CAAC,MAA2C;AAC1C,6BAAuB;AACvB,iBAAW,UAAU;AACrB,mBAAa,IAAI;AACjB,qBAAe,CAAC;AAAA,IAClB;AAAA,IACA,CAAC,cAAc,sBAAsB;AAAA,EACvC;AAEA,QAAM,uBAAmB;AAAA,IACvB,CAAC,MAA2C;AAC1C,iBAAW,UAAU;AACrB,mBAAa,KAAK;AAClB,kBAAY;AACZ,qBAAe,CAAC;AAAA,IAClB;AAAA,IACA,CAAC,cAAc,WAAW;AAAA,EAC5B;AAEA,QAAM,kBAAc;AAAA,IAClB,CAAC,MAA2C;AAC1C,6BAAuB;AACvB,iBAAW,UAAU;AACrB,mBAAa,IAAI;AACjB,gBAAU,CAAC;AAAA,IACb;AAAA,IACA,CAAC,SAAS,sBAAsB;AAAA,EAClC;AAEA,QAAM,iBAAa;AAAA,IACjB,CAAC,MAA2C;AAC1C,iBAAW,UAAU;AACrB,mBAAa,KAAK;AAClB,kBAAY;AACZ,eAAS,CAAC;AAAA,IACZ;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EACtB;AAGA,QAAM,0BAAsB,0BAAY,MAAM;AAC5C,iBAAa,UAAU;AACvB,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,gDAAiB,UAAU,mBAAmB;AAE9C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,MACjB,cAAc;AAAA,MACd,cAAc;AAAA,MACd,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/cjs/styles.js
CHANGED
|
@@ -192,14 +192,13 @@ const StyledChip = (0, import_ds_system.styled)("button", { name: import_constan
|
|
|
192
192
|
color: ${({ theme }) => theme.colors.neutral[600]};
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
195
|
+
z-index: ${({ expanded }) => expanded ? 10 : "auto"};
|
|
196
|
+
/* Keep this interpolation always present — making it conditional changes the styled wrapper's hook
|
|
197
|
+
count between renders. */
|
|
198
|
+
${StyledSpanWithEllipsis} {
|
|
199
|
+
${({ expanded }) => expanded && import_ds_system.css`
|
|
200
|
+
${wrapTextStyles}
|
|
201
|
+
`}
|
|
203
202
|
}
|
|
204
203
|
|
|
205
204
|
&:hover {
|
package/dist/cjs/styles.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/styles.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable max-lines */\nimport { styled, css, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSTypography } from '@elliemae/ds-typography';\nimport {\n basicSizes,\n shapeSizes,\n CHIP_SHAPES,\n CHIP_SIZES,\n roundShapeLarge,\n roundShapeSmall,\n DSChipName,\n CHIP_SLOTS,\n roundShapeLargeMobile,\n roundShapeSmallMobile,\n} from './constants/index.js';\nimport type { ChipShapesT, ChipSizesT } from './sharedTypes.js';\n\nexport interface StyledChipPropsT {\n buttonSize: ChipSizesT;\n buttonShape: ChipShapesT;\n selected?: boolean;\n wrapText?: boolean;\n}\n\nexport interface StyledRoundShapePropsT {\n size: ChipSizesT;\n disabled?: boolean;\n}\n\nconst getChipSize = (shape: ChipShapesT) => (shape === CHIP_SHAPES.ROUND ? shapeSizes : basicSizes);\n\nconst wrapTextStyles = css`\n overflow-wrap: break-word;\n white-space: pre-wrap;\n overflow: visible;\n`;\n\nconst ellipsisStyles = css`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport const StyledChipLabel = styled('div', { name: DSChipName, slot: CHIP_SLOTS.LABEL })<{ size: ChipSizesT }>`\n font-size: ${({ theme }) => theme.fontSizes.label[200]};\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n word-wrap: break-word;\n text-align: center;\n padding-top: ${({ size }) => (size === CHIP_SIZES.L ? '2px' : '4px')};\n z-index: 0;\n line-height: 1.27;\n width: inherit;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nexport const StyledSpanWithEllipsis = styled(DSTypography, {\n name: DSChipName,\n slot: CHIP_SLOTS.ELLIPSIS,\n})<{ wrapText?: boolean }>`\n ${({ wrapText }) => (wrapText ? wrapTextStyles : ellipsisStyles)};\n max-width: 100%;\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n`;\n\nexport const StyledWrapper = styled('div', {\n name: DSChipName,\n slot: CHIP_SLOTS.ROOT,\n})<StyledChipPropsT>`\n display: flex;\n width: ${({ buttonSize, buttonShape }) => getChipSize(buttonShape)[buttonSize].width};\n ${xStyledCommonProps}\n max-width: ${({ buttonSize }) => basicSizes[buttonSize].maxWidth};\n ${({ wrapText, buttonSize, buttonShape }) =>\n wrapText ? `height: auto;` : ` height: ${getChipSize(buttonShape)[buttonSize].height};`}\n`;\n\nconst disabledRoundShape = css`\n background-color: ${({ theme }) => theme.colors.neutral[400]};\n\n & .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral['000']};\n }\n`;\n\nexport const StyledRoundShape = styled('div', {\n name: DSChipName,\n slot: CHIP_SLOTS.ROUND_SHAPE,\n})<StyledRoundShapePropsT>`\n background-color: ${({ theme }) => theme.colors.brand[600]};\n width: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLarge : roundShapeSmall)};\n height: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLarge : roundShapeSmall)};\n border-radius: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n @media (max-width: ${({ theme }) => theme.breakpoints.small}) {\n width: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLargeMobile : roundShapeSmallMobile)};\n height: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLargeMobile : roundShapeSmallMobile)};\n }\n`;\n\nconst styledChipSelectedCss = css`\n // TODO: wrap css processor to process new HOC wrapping styled components\n ${StyledRoundShape.toString()} {\n background-color: ${({ theme }) => theme.colors.brand[800]};\n }\n color: ${({ theme }) => theme.colors.brand[800]};\n background-color: ${({ theme }) => theme.colors.brand[200]};\n\n .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.brand[800]};\n }\n\n &:before {\n border: 1px solid ${({ theme }) => theme.colors.brand[600]};\n }\n\n &:focus {\n &:before {\n border: 2px solid ${({ theme }) => theme.colors.brand[700]};\n }\n }\n`;\n\nconst disabledStyles = css`\n color: ${({ theme }) => theme.colors.neutral[500]};\n\n .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral[400]};\n }\n\n &:hover {\n ${StyledRoundShape} {\n background-color: ${({ theme }) => theme.colors.neutral[200]};\n }\n background-color: ${({ theme }) => theme.colors.neutral['050']};\n cursor: not-allowed;\n &:before {\n border-color: transparent;\n }\n }\n`;\n\nexport const StyledChip = styled('button', { name: DSChipName, slot: CHIP_SLOTS.BUTTON })<\n Pick<StyledChipPropsT, 'selected' | 'buttonShape' | 'buttonSize' | '
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,uBAAgD;AAChD,2BAA6B;AAC7B,uBAWO;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable max-lines */\nimport { styled, css, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSTypography } from '@elliemae/ds-typography';\nimport {\n basicSizes,\n shapeSizes,\n CHIP_SHAPES,\n CHIP_SIZES,\n roundShapeLarge,\n roundShapeSmall,\n DSChipName,\n CHIP_SLOTS,\n roundShapeLargeMobile,\n roundShapeSmallMobile,\n} from './constants/index.js';\nimport type { ChipShapesT, ChipSizesT } from './sharedTypes.js';\n\nexport interface StyledChipPropsT {\n buttonSize: ChipSizesT;\n buttonShape: ChipShapesT;\n selected?: boolean;\n wrapText?: boolean;\n expanded?: boolean;\n}\n\nexport interface StyledRoundShapePropsT {\n size: ChipSizesT;\n disabled?: boolean;\n}\n\nconst getChipSize = (shape: ChipShapesT) => (shape === CHIP_SHAPES.ROUND ? shapeSizes : basicSizes);\n\nconst wrapTextStyles = css`\n overflow-wrap: break-word;\n white-space: pre-wrap;\n overflow: visible;\n`;\n\nconst ellipsisStyles = css`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport const StyledChipLabel = styled('div', { name: DSChipName, slot: CHIP_SLOTS.LABEL })<{ size: ChipSizesT }>`\n font-size: ${({ theme }) => theme.fontSizes.label[200]};\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n word-wrap: break-word;\n text-align: center;\n padding-top: ${({ size }) => (size === CHIP_SIZES.L ? '2px' : '4px')};\n z-index: 0;\n line-height: 1.27;\n width: inherit;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nexport const StyledSpanWithEllipsis = styled(DSTypography, {\n name: DSChipName,\n slot: CHIP_SLOTS.ELLIPSIS,\n})<{ wrapText?: boolean }>`\n ${({ wrapText }) => (wrapText ? wrapTextStyles : ellipsisStyles)};\n max-width: 100%;\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n`;\n\nexport const StyledWrapper = styled('div', {\n name: DSChipName,\n slot: CHIP_SLOTS.ROOT,\n})<StyledChipPropsT>`\n display: flex;\n width: ${({ buttonSize, buttonShape }) => getChipSize(buttonShape)[buttonSize].width};\n ${xStyledCommonProps}\n max-width: ${({ buttonSize }) => basicSizes[buttonSize].maxWidth};\n ${({ wrapText, buttonSize, buttonShape }) =>\n wrapText ? `height: auto;` : ` height: ${getChipSize(buttonShape)[buttonSize].height};`}\n`;\n\nconst disabledRoundShape = css`\n background-color: ${({ theme }) => theme.colors.neutral[400]};\n\n & .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral['000']};\n }\n`;\n\nexport const StyledRoundShape = styled('div', {\n name: DSChipName,\n slot: CHIP_SLOTS.ROUND_SHAPE,\n})<StyledRoundShapePropsT>`\n background-color: ${({ theme }) => theme.colors.brand[600]};\n width: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLarge : roundShapeSmall)};\n height: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLarge : roundShapeSmall)};\n border-radius: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n @media (max-width: ${({ theme }) => theme.breakpoints.small}) {\n width: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLargeMobile : roundShapeSmallMobile)};\n height: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLargeMobile : roundShapeSmallMobile)};\n }\n`;\n\nconst styledChipSelectedCss = css`\n // TODO: wrap css processor to process new HOC wrapping styled components\n ${StyledRoundShape.toString()} {\n background-color: ${({ theme }) => theme.colors.brand[800]};\n }\n color: ${({ theme }) => theme.colors.brand[800]};\n background-color: ${({ theme }) => theme.colors.brand[200]};\n\n .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.brand[800]};\n }\n\n &:before {\n border: 1px solid ${({ theme }) => theme.colors.brand[600]};\n }\n\n &:focus {\n &:before {\n border: 2px solid ${({ theme }) => theme.colors.brand[700]};\n }\n }\n`;\n\nconst disabledStyles = css`\n color: ${({ theme }) => theme.colors.neutral[500]};\n\n .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral[400]};\n }\n\n &:hover {\n ${StyledRoundShape} {\n background-color: ${({ theme }) => theme.colors.neutral[200]};\n }\n background-color: ${({ theme }) => theme.colors.neutral['050']};\n cursor: not-allowed;\n &:before {\n border-color: transparent;\n }\n }\n`;\n\nexport const StyledChip = styled('button', { name: DSChipName, slot: CHIP_SLOTS.BUTTON })<\n Pick<StyledChipPropsT, 'selected' | 'buttonShape' | 'buttonSize' | 'expanded'>\n>`\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n border: none;\n min-height: 100%;\n height: fit-content;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral['000']};\n color: ${({ theme }) => theme.colors.brand[600]};\n border-radius: 4px;\n cursor: pointer;\n outline: none;\n ${({ buttonShape, buttonSize }) => {\n if (buttonShape === CHIP_SHAPES.ROUND && buttonSize === CHIP_SIZES.L) {\n return css`\n padding: 6px;\n `;\n }\n return css`\n padding: 10px 6px;\n `;\n }}\n ${StyledRoundShape} {\n & .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral['000']};\n }\n ${({ disabled }) => disabled && disabledRoundShape}\n }\n &:before {\n content: '';\n position: absolute;\n z-index: 20;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border-radius: 4px;\n border: 2px solid transparent;\n pointer-events: none;\n }\n & .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.brand[600]};\n color: ${({ theme }) => theme.colors.neutral[600]};\n }\n\n z-index: ${({ expanded }) => (expanded ? 10 : 'auto')};\n /* Keep this interpolation always present \u2014 making it conditional changes the styled wrapper's hook\n count between renders. */\n ${StyledSpanWithEllipsis} {\n ${({ expanded }) =>\n expanded &&\n css`\n ${wrapTextStyles}\n `}\n }\n\n &:hover {\n ${StyledRoundShape} {\n background-color: ${({ theme }) => theme.colors.brand[800]};\n }\n color: ${({ theme }) => theme.colors.brand[800]};\n background-color: ${({ theme }) => theme.colors.brand[200]};\n .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.brand[800]};\n }\n }\n\n &:focus {\n &:before {\n ${({ buttonShape }) =>\n buttonShape === CHIP_SHAPES.ROUND\n ? css`\n border: 2px solid ${({ theme }) => theme.colors.brand[800]};\n `\n : css`\n border: 2px solid ${({ theme }) => theme.colors.brand[700]};\n `}\n }\n }\n\n &:disabled {\n ${disabledStyles}\n }\n\n &[aria-disabled='true'] {\n ${disabledStyles}\n ${StyledRoundShape} {\n ${disabledRoundShape}\n }\n\n &:focus {\n &:before {\n border: 2px solid ${({ theme }) => theme.colors.neutral[400]};\n }\n }\n }\n\n ${({ selected, buttonShape }) =>\n !selected\n ? ''\n : css`\n ${styledChipSelectedCss}\n &:focus {\n &:before {\n ${\n buttonShape === CHIP_SHAPES.ROUND\n ? css`\n border: 2px solid ${({ theme }) => theme.colors.brand[800]};\n `\n : css`\n border: 2px solid ${({ theme }) => theme.colors.brand[700]};\n `\n }\n }\n }\n `}\n`;\n", "import * as React from 'react';\nexport { React };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/DSChip.js
CHANGED
|
@@ -5,6 +5,7 @@ import { describe } from "@elliemae/ds-props-helpers";
|
|
|
5
5
|
import { TYPOGRAPHY_VARIANTS } from "@elliemae/ds-typography";
|
|
6
6
|
import { DSIconSizes } from "@elliemae/ds-icon";
|
|
7
7
|
import { useConfig } from "./config/useConfig.js";
|
|
8
|
+
import { useLabelExpansion } from "./config/useLabelExpansion.js";
|
|
8
9
|
import { StyledChip, StyledChipLabel, StyledWrapper, StyledRoundShape, StyledSpanWithEllipsis } from "./styles.js";
|
|
9
10
|
import { CHIP_SHAPES } from "./constants/index.js";
|
|
10
11
|
import { DSChipPropTypesSchema } from "./react-desc-prop-types.js";
|
|
@@ -22,7 +23,24 @@ const DSChip = (props) => {
|
|
|
22
23
|
ownerPropsConfig,
|
|
23
24
|
wrapText
|
|
24
25
|
} = useConfig(props);
|
|
25
|
-
const {
|
|
26
|
+
const {
|
|
27
|
+
disabled,
|
|
28
|
+
className,
|
|
29
|
+
onClick,
|
|
30
|
+
// Composed into the expansion handlers below. `onKeyDown` is not intercepted — Escape is handled
|
|
31
|
+
// at the document level, so it passes through untouched.
|
|
32
|
+
onMouseEnter: consumerMouseEnter,
|
|
33
|
+
onMouseLeave: consumerMouseLeave,
|
|
34
|
+
onFocus: consumerFocus,
|
|
35
|
+
onBlur: consumerBlur,
|
|
36
|
+
...restGlobals
|
|
37
|
+
} = globalAttrs;
|
|
38
|
+
const { expanded, labelRef, expansionHandlers } = useLabelExpansion(wrapText, {
|
|
39
|
+
onMouseEnter: consumerMouseEnter,
|
|
40
|
+
onMouseLeave: consumerMouseLeave,
|
|
41
|
+
onFocus: consumerFocus,
|
|
42
|
+
onBlur: consumerBlur
|
|
43
|
+
});
|
|
26
44
|
const handleOnClick = useCallback(
|
|
27
45
|
(e) => {
|
|
28
46
|
if (applyAriaDisabled) return;
|
|
@@ -52,6 +70,9 @@ const DSChip = (props) => {
|
|
|
52
70
|
role: "button",
|
|
53
71
|
onClick: handleOnClick,
|
|
54
72
|
buttonSize: size,
|
|
73
|
+
expanded,
|
|
74
|
+
"data-expanded": expanded || void 0,
|
|
75
|
+
...expansionHandlers,
|
|
55
76
|
...restGlobals,
|
|
56
77
|
...ownerPropsConfig,
|
|
57
78
|
children: [
|
|
@@ -62,6 +83,7 @@ const DSChip = (props) => {
|
|
|
62
83
|
component: "span",
|
|
63
84
|
variant: TYPOGRAPHY_VARIANTS.B4,
|
|
64
85
|
wrapText,
|
|
86
|
+
innerRef: labelRef,
|
|
65
87
|
...ownerPropsConfig,
|
|
66
88
|
children: label
|
|
67
89
|
}
|
package/dist/esm/DSChip.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/DSChip.tsx"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useCallback } from 'react';\nimport { describe } from '@elliemae/ds-props-helpers';\nimport { TYPOGRAPHY_VARIANTS } from '@elliemae/ds-typography';\nimport { DSIconSizes } from '@elliemae/ds-icon';\nimport { useConfig } from './config/useConfig.js';\nimport { StyledChip, StyledChipLabel, StyledWrapper, StyledRoundShape, StyledSpanWithEllipsis } from './styles.js';\nimport { CHIP_SHAPES } from './constants/index.js';\nimport type { DSChipT } from './react-desc-prop-types.js';\nimport { DSChipPropTypesSchema } from './react-desc-prop-types.js';\n\nconst DSChip: React.ComponentType<DSChipT.Props> = (props) => {\n const {\n size,\n shape,\n selected,\n applyAriaDisabled,\n innerRef,\n icon: Icon,\n label,\n globalAttrs,\n xStyledAttrs,\n ownerPropsConfig,\n wrapText,\n } = useConfig(props);\n\n const {
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import React, { useCallback } from 'react';\nimport { describe } from '@elliemae/ds-props-helpers';\nimport { TYPOGRAPHY_VARIANTS } from '@elliemae/ds-typography';\nimport { DSIconSizes } from '@elliemae/ds-icon';\nimport { useConfig } from './config/useConfig.js';\nimport { useLabelExpansion } from './config/useLabelExpansion.js';\nimport { StyledChip, StyledChipLabel, StyledWrapper, StyledRoundShape, StyledSpanWithEllipsis } from './styles.js';\nimport { CHIP_SHAPES } from './constants/index.js';\nimport type { DSChipT } from './react-desc-prop-types.js';\nimport { DSChipPropTypesSchema } from './react-desc-prop-types.js';\n\nconst DSChip: React.ComponentType<DSChipT.Props> = (props) => {\n const {\n size,\n shape,\n selected,\n applyAriaDisabled,\n innerRef,\n icon: Icon,\n label,\n globalAttrs,\n xStyledAttrs,\n ownerPropsConfig,\n wrapText,\n } = useConfig(props);\n\n const {\n disabled,\n className,\n onClick,\n // Composed into the expansion handlers below. `onKeyDown` is not intercepted \u2014 Escape is handled\n // at the document level, so it passes through untouched.\n onMouseEnter: consumerMouseEnter,\n onMouseLeave: consumerMouseLeave,\n onFocus: consumerFocus,\n onBlur: consumerBlur,\n ...restGlobals\n } = globalAttrs;\n\n const { expanded, labelRef, expansionHandlers } = useLabelExpansion(wrapText, {\n onMouseEnter: consumerMouseEnter,\n onMouseLeave: consumerMouseLeave,\n onFocus: consumerFocus,\n onBlur: consumerBlur,\n });\n\n const handleOnClick = useCallback(\n (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (applyAriaDisabled) return;\n if (onClick) {\n onClick(e);\n }\n },\n [applyAriaDisabled, onClick],\n );\n\n return (\n <StyledWrapper\n wrapText={wrapText}\n buttonShape={shape}\n buttonSize={size}\n className={className}\n {...xStyledAttrs}\n {...ownerPropsConfig}\n >\n <StyledChip\n buttonShape={shape}\n aria-disabled={disabled || applyAriaDisabled}\n disabled={disabled}\n innerRef={innerRef}\n selected={selected}\n role=\"button\"\n onClick={handleOnClick}\n buttonSize={size}\n expanded={expanded}\n data-expanded={expanded || undefined}\n {...expansionHandlers}\n {...restGlobals}\n {...ownerPropsConfig}\n >\n {shape === CHIP_SHAPES.ROUND ? (\n <StyledRoundShape disabled={disabled} size={size} {...ownerPropsConfig}>\n <Icon size={DSIconSizes.M} />\n </StyledRoundShape>\n ) : (\n <Icon size={DSIconSizes.M} />\n )}\n <StyledChipLabel size={size} {...ownerPropsConfig}>\n <StyledSpanWithEllipsis\n component=\"span\"\n variant={TYPOGRAPHY_VARIANTS.B4}\n wrapText={wrapText}\n innerRef={labelRef}\n {...ownerPropsConfig}\n >\n {label}\n </StyledSpanWithEllipsis>\n </StyledChipLabel>\n </StyledChip>\n </StyledWrapper>\n );\n};\n\nDSChip.displayName = 'DSChip';\nconst DSChipWithSchema = describe(DSChip);\nDSChipWithSchema.propTypes = DSChipPropTypesSchema;\n\nexport { DSChip, DSChipWithSchema };\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACiEjB,SAiBM,KAjBN;AAjEN,SAAgB,mBAAmB;AACnC,SAAS,gBAAgB;AACzB,SAAS,2BAA2B;AACpC,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAClC,SAAS,YAAY,iBAAiB,eAAe,kBAAkB,8BAA8B;AACrG,SAAS,mBAAmB;AAE5B,SAAS,6BAA6B;AAEtC,MAAM,SAA6C,CAAC,UAAU;AAC5D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,UAAU,KAAK;AAEnB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,cAAc;AAAA,IACd,cAAc;AAAA,IACd,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,EAAE,UAAU,UAAU,kBAAkB,IAAI,kBAAkB,UAAU;AAAA,IAC5E,cAAc;AAAA,IACd,cAAc;AAAA,IACd,SAAS;AAAA,IACT,QAAQ;AAAA,EACV,CAAC;AAED,QAAM,gBAAgB;AAAA,IACpB,CAAC,MAAuD;AACtD,UAAI,kBAAmB;AACvB,UAAI,SAAS;AACX,gBAAQ,CAAC;AAAA,MACX;AAAA,IACF;AAAA,IACA,CAAC,mBAAmB,OAAO;AAAA,EAC7B;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAa;AAAA,MACb,YAAY;AAAA,MACZ;AAAA,MACC,GAAG;AAAA,MACH,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACC,aAAa;AAAA,UACb,iBAAe,YAAY;AAAA,UAC3B;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAK;AAAA,UACL,SAAS;AAAA,UACT,YAAY;AAAA,UACZ;AAAA,UACA,iBAAe,YAAY;AAAA,UAC1B,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG;AAAA,UAEH;AAAA,sBAAU,YAAY,QACrB,oBAAC,oBAAiB,UAAoB,MAAa,GAAG,kBACpD,8BAAC,QAAK,MAAM,YAAY,GAAG,GAC7B,IAEA,oBAAC,QAAK,MAAM,YAAY,GAAG;AAAA,YAE7B,oBAAC,mBAAgB,MAAa,GAAG,kBAC/B;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,SAAS,oBAAoB;AAAA,gBAC7B;AAAA,gBACA,UAAU;AAAA,gBACT,GAAG;AAAA,gBAEH;AAAA;AAAA,YACH,GACF;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAEA,OAAO,cAAc;AACrB,MAAM,mBAAmB,SAAS,MAAM;AACxC,iBAAiB,YAAY;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
const useEscapeDismiss = (active, onDismiss) => {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (!active) return void 0;
|
|
6
|
+
const handleDocumentKeyDown = (e) => {
|
|
7
|
+
if (e.key !== "Escape") return;
|
|
8
|
+
onDismiss();
|
|
9
|
+
e.stopPropagation();
|
|
10
|
+
};
|
|
11
|
+
document.addEventListener("keydown", handleDocumentKeyDown, true);
|
|
12
|
+
return () => document.removeEventListener("keydown", handleDocumentKeyDown, true);
|
|
13
|
+
}, [active, onDismiss]);
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
useEscapeDismiss
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=useEscapeDismiss.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/config/useEscapeDismiss.ts"],
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import { useEffect } from 'react';\n\n// A hover-expanded label can't see keydown from the chip itself \u2014 the event targets whatever holds\n// focus. Capture on document runs before React's root delegation, so stopPropagation here also blocks\n// ancestor Escape handlers. Subscribed only while active, so Escape is consumed only when it dismisses.\nexport const useEscapeDismiss = (active: boolean, onDismiss: () => void): void => {\n useEffect(() => {\n if (!active) return undefined;\n const handleDocumentKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n onDismiss();\n e.stopPropagation();\n };\n document.addEventListener('keydown', handleDocumentKeyDown, true);\n return () => document.removeEventListener('keydown', handleDocumentKeyDown, true);\n }, [active, onDismiss]);\n};\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACAvB,SAAS,iBAAiB;AAKnB,MAAM,mBAAmB,CAAC,QAAiB,cAAgC;AAChF,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,wBAAwB,CAAC,MAAqB;AAClD,UAAI,EAAE,QAAQ,SAAU;AACxB,gBAAU;AACV,QAAE,gBAAgB;AAAA,IACpB;AACA,aAAS,iBAAiB,WAAW,uBAAuB,IAAI;AAChE,WAAO,MAAM,SAAS,oBAAoB,WAAW,uBAAuB,IAAI;AAAA,EAClF,GAAG,CAAC,QAAQ,SAAS,CAAC;AACxB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useCallback, useRef, useState } from "react";
|
|
3
|
+
import { useEscapeDismiss } from "./useEscapeDismiss.js";
|
|
4
|
+
const useLabelExpansion = (wrapText, consumer) => {
|
|
5
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
6
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
7
|
+
const [isDismissed, setIsDismissed] = useState(false);
|
|
8
|
+
const [isOverflowing, setIsOverflowing] = useState(false);
|
|
9
|
+
const hoveredRef = useRef(false);
|
|
10
|
+
const focusedRef = useRef(false);
|
|
11
|
+
const dismissedRef = useRef(false);
|
|
12
|
+
const labelRef = useRef(null);
|
|
13
|
+
const expanded = !wrapText && isOverflowing && (isHovered || isFocused) && !isDismissed;
|
|
14
|
+
const measureOverflowOnEntry = useCallback(() => {
|
|
15
|
+
if (wrapText || hoveredRef.current || focusedRef.current) return;
|
|
16
|
+
const node = labelRef.current;
|
|
17
|
+
setIsOverflowing(!!node && node.scrollWidth > node.clientWidth);
|
|
18
|
+
}, [wrapText]);
|
|
19
|
+
const rearmIfLeft = useCallback(() => {
|
|
20
|
+
if (!hoveredRef.current && !focusedRef.current && dismissedRef.current) {
|
|
21
|
+
dismissedRef.current = false;
|
|
22
|
+
setIsDismissed(false);
|
|
23
|
+
}
|
|
24
|
+
}, []);
|
|
25
|
+
const { onMouseEnter, onMouseLeave, onFocus, onBlur } = consumer;
|
|
26
|
+
const handleMouseEnter = useCallback(
|
|
27
|
+
(e) => {
|
|
28
|
+
measureOverflowOnEntry();
|
|
29
|
+
hoveredRef.current = true;
|
|
30
|
+
setIsHovered(true);
|
|
31
|
+
onMouseEnter?.(e);
|
|
32
|
+
},
|
|
33
|
+
[onMouseEnter, measureOverflowOnEntry]
|
|
34
|
+
);
|
|
35
|
+
const handleMouseLeave = useCallback(
|
|
36
|
+
(e) => {
|
|
37
|
+
hoveredRef.current = false;
|
|
38
|
+
setIsHovered(false);
|
|
39
|
+
rearmIfLeft();
|
|
40
|
+
onMouseLeave?.(e);
|
|
41
|
+
},
|
|
42
|
+
[onMouseLeave, rearmIfLeft]
|
|
43
|
+
);
|
|
44
|
+
const handleFocus = useCallback(
|
|
45
|
+
(e) => {
|
|
46
|
+
measureOverflowOnEntry();
|
|
47
|
+
focusedRef.current = true;
|
|
48
|
+
setIsFocused(true);
|
|
49
|
+
onFocus?.(e);
|
|
50
|
+
},
|
|
51
|
+
[onFocus, measureOverflowOnEntry]
|
|
52
|
+
);
|
|
53
|
+
const handleBlur = useCallback(
|
|
54
|
+
(e) => {
|
|
55
|
+
focusedRef.current = false;
|
|
56
|
+
setIsFocused(false);
|
|
57
|
+
rearmIfLeft();
|
|
58
|
+
onBlur?.(e);
|
|
59
|
+
},
|
|
60
|
+
[onBlur, rearmIfLeft]
|
|
61
|
+
);
|
|
62
|
+
const handleEscapeDismiss = useCallback(() => {
|
|
63
|
+
dismissedRef.current = true;
|
|
64
|
+
setIsDismissed(true);
|
|
65
|
+
}, []);
|
|
66
|
+
useEscapeDismiss(expanded, handleEscapeDismiss);
|
|
67
|
+
return {
|
|
68
|
+
expanded,
|
|
69
|
+
labelRef,
|
|
70
|
+
expansionHandlers: {
|
|
71
|
+
onMouseEnter: handleMouseEnter,
|
|
72
|
+
onMouseLeave: handleMouseLeave,
|
|
73
|
+
onFocus: handleFocus,
|
|
74
|
+
onBlur: handleBlur
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
export {
|
|
79
|
+
useLabelExpansion
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=useLabelExpansion.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/config/useLabelExpansion.ts"],
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "import type React from 'react';\nimport { useCallback, useRef, useState } from 'react';\nimport { useEscapeDismiss } from './useEscapeDismiss.js';\n\ninterface ConsumerHandlersT {\n onMouseEnter?: React.MouseEventHandler<HTMLButtonElement>;\n onMouseLeave?: React.MouseEventHandler<HTMLButtonElement>;\n onFocus?: React.FocusEventHandler<HTMLButtonElement>;\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n}\n\n// PUI-17950 \u2014 the expanded label overlays adjacent content, so WCAG 1.4.13 requires it be dismissible\n// without moving pointer or focus. That rules out CSS :hover/:focus, which a keypress cannot switch off.\n// `isOverflowing` matters beyond the visuals: without it a label that already fits would still claim an\n// expansion and swallow an Escape meant for an ancestor.\nexport const useLabelExpansion = (wrapText: boolean, consumer: ConsumerHandlersT) => {\n const [isHovered, setIsHovered] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [isDismissed, setIsDismissed] = useState(false);\n const [isOverflowing, setIsOverflowing] = useState(false);\n\n // Mirrored so the leave handlers read both signals in the same tick, without a useEffect.\n const hoveredRef = useRef(false);\n const focusedRef = useRef(false);\n const dismissedRef = useRef(false);\n const labelRef = useRef<HTMLDivElement | null>(null);\n\n const expanded = !wrapText && isOverflowing && (isHovered || isFocused) && !isDismissed;\n\n // Only on a fresh entry: an already-expanded label is no longer clipped and would measure as fitting.\n const measureOverflowOnEntry = useCallback(() => {\n if (wrapText || hoveredRef.current || focusedRef.current) return;\n const node = labelRef.current;\n setIsOverflowing(!!node && node.scrollWidth > node.clientWidth);\n }, [wrapText]);\n\n const rearmIfLeft = useCallback(() => {\n if (!hoveredRef.current && !focusedRef.current && dismissedRef.current) {\n dismissedRef.current = false;\n setIsDismissed(false);\n }\n }, []);\n\n const { onMouseEnter, onMouseLeave, onFocus, onBlur } = consumer;\n\n const handleMouseEnter = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n measureOverflowOnEntry();\n hoveredRef.current = true;\n setIsHovered(true);\n onMouseEnter?.(e);\n },\n [onMouseEnter, measureOverflowOnEntry],\n );\n\n const handleMouseLeave = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n hoveredRef.current = false;\n setIsHovered(false);\n rearmIfLeft();\n onMouseLeave?.(e);\n },\n [onMouseLeave, rearmIfLeft],\n );\n\n const handleFocus = useCallback(\n (e: React.FocusEvent<HTMLButtonElement>) => {\n measureOverflowOnEntry();\n focusedRef.current = true;\n setIsFocused(true);\n onFocus?.(e);\n },\n [onFocus, measureOverflowOnEntry],\n );\n\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLButtonElement>) => {\n focusedRef.current = false;\n setIsFocused(false);\n rearmIfLeft();\n onBlur?.(e);\n },\n [onBlur, rearmIfLeft],\n );\n\n // Stable, or useEscapeDismiss resubscribes every render.\n const handleEscapeDismiss = useCallback(() => {\n dismissedRef.current = true;\n setIsDismissed(true);\n }, []);\n\n useEscapeDismiss(expanded, handleEscapeDismiss);\n\n return {\n expanded,\n labelRef,\n expansionHandlers: {\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n onFocus: handleFocus,\n onBlur: handleBlur,\n },\n };\n};\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,WAAW;ACCvB,SAAS,aAAa,QAAQ,gBAAgB;AAC9C,SAAS,wBAAwB;AAa1B,MAAM,oBAAoB,CAAC,UAAmB,aAAgC;AACnF,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AAGxD,QAAM,aAAa,OAAO,KAAK;AAC/B,QAAM,aAAa,OAAO,KAAK;AAC/B,QAAM,eAAe,OAAO,KAAK;AACjC,QAAM,WAAW,OAA8B,IAAI;AAEnD,QAAM,WAAW,CAAC,YAAY,kBAAkB,aAAa,cAAc,CAAC;AAG5E,QAAM,yBAAyB,YAAY,MAAM;AAC/C,QAAI,YAAY,WAAW,WAAW,WAAW,QAAS;AAC1D,UAAM,OAAO,SAAS;AACtB,qBAAiB,CAAC,CAAC,QAAQ,KAAK,cAAc,KAAK,WAAW;AAAA,EAChE,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,cAAc,YAAY,MAAM;AACpC,QAAI,CAAC,WAAW,WAAW,CAAC,WAAW,WAAW,aAAa,SAAS;AACtE,mBAAa,UAAU;AACvB,qBAAe,KAAK;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,EAAE,cAAc,cAAc,SAAS,OAAO,IAAI;AAExD,QAAM,mBAAmB;AAAA,IACvB,CAAC,MAA2C;AAC1C,6BAAuB;AACvB,iBAAW,UAAU;AACrB,mBAAa,IAAI;AACjB,qBAAe,CAAC;AAAA,IAClB;AAAA,IACA,CAAC,cAAc,sBAAsB;AAAA,EACvC;AAEA,QAAM,mBAAmB;AAAA,IACvB,CAAC,MAA2C;AAC1C,iBAAW,UAAU;AACrB,mBAAa,KAAK;AAClB,kBAAY;AACZ,qBAAe,CAAC;AAAA,IAClB;AAAA,IACA,CAAC,cAAc,WAAW;AAAA,EAC5B;AAEA,QAAM,cAAc;AAAA,IAClB,CAAC,MAA2C;AAC1C,6BAAuB;AACvB,iBAAW,UAAU;AACrB,mBAAa,IAAI;AACjB,gBAAU,CAAC;AAAA,IACb;AAAA,IACA,CAAC,SAAS,sBAAsB;AAAA,EAClC;AAEA,QAAM,aAAa;AAAA,IACjB,CAAC,MAA2C;AAC1C,iBAAW,UAAU;AACrB,mBAAa,KAAK;AAClB,kBAAY;AACZ,eAAS,CAAC;AAAA,IACZ;AAAA,IACA,CAAC,QAAQ,WAAW;AAAA,EACtB;AAGA,QAAM,sBAAsB,YAAY,MAAM;AAC5C,iBAAa,UAAU;AACvB,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,CAAC;AAEL,mBAAiB,UAAU,mBAAmB;AAE9C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,MACjB,cAAc;AAAA,MACd,cAAc;AAAA,MACd,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/esm/styles.js
CHANGED
|
@@ -166,14 +166,13 @@ const StyledChip = styled("button", { name: DSChipName, slot: CHIP_SLOTS.BUTTON
|
|
|
166
166
|
color: ${({ theme }) => theme.colors.neutral[600]};
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
169
|
+
z-index: ${({ expanded }) => expanded ? 10 : "auto"};
|
|
170
|
+
/* Keep this interpolation always present — making it conditional changes the styled wrapper's hook
|
|
171
|
+
count between renders. */
|
|
172
|
+
${StyledSpanWithEllipsis} {
|
|
173
|
+
${({ expanded }) => expanded && css`
|
|
174
|
+
${wrapTextStyles}
|
|
175
|
+
`}
|
|
177
176
|
}
|
|
178
177
|
|
|
179
178
|
&:hover {
|
package/dist/esm/styles.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../scripts/build/transpile/react-shim.js", "../../src/styles.tsx"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport { styled, css, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSTypography } from '@elliemae/ds-typography';\nimport {\n basicSizes,\n shapeSizes,\n CHIP_SHAPES,\n CHIP_SIZES,\n roundShapeLarge,\n roundShapeSmall,\n DSChipName,\n CHIP_SLOTS,\n roundShapeLargeMobile,\n roundShapeSmallMobile,\n} from './constants/index.js';\nimport type { ChipShapesT, ChipSizesT } from './sharedTypes.js';\n\nexport interface StyledChipPropsT {\n buttonSize: ChipSizesT;\n buttonShape: ChipShapesT;\n selected?: boolean;\n wrapText?: boolean;\n}\n\nexport interface StyledRoundShapePropsT {\n size: ChipSizesT;\n disabled?: boolean;\n}\n\nconst getChipSize = (shape: ChipShapesT) => (shape === CHIP_SHAPES.ROUND ? shapeSizes : basicSizes);\n\nconst wrapTextStyles = css`\n overflow-wrap: break-word;\n white-space: pre-wrap;\n overflow: visible;\n`;\n\nconst ellipsisStyles = css`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport const StyledChipLabel = styled('div', { name: DSChipName, slot: CHIP_SLOTS.LABEL })<{ size: ChipSizesT }>`\n font-size: ${({ theme }) => theme.fontSizes.label[200]};\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n word-wrap: break-word;\n text-align: center;\n padding-top: ${({ size }) => (size === CHIP_SIZES.L ? '2px' : '4px')};\n z-index: 0;\n line-height: 1.27;\n width: inherit;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nexport const StyledSpanWithEllipsis = styled(DSTypography, {\n name: DSChipName,\n slot: CHIP_SLOTS.ELLIPSIS,\n})<{ wrapText?: boolean }>`\n ${({ wrapText }) => (wrapText ? wrapTextStyles : ellipsisStyles)};\n max-width: 100%;\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n`;\n\nexport const StyledWrapper = styled('div', {\n name: DSChipName,\n slot: CHIP_SLOTS.ROOT,\n})<StyledChipPropsT>`\n display: flex;\n width: ${({ buttonSize, buttonShape }) => getChipSize(buttonShape)[buttonSize].width};\n ${xStyledCommonProps}\n max-width: ${({ buttonSize }) => basicSizes[buttonSize].maxWidth};\n ${({ wrapText, buttonSize, buttonShape }) =>\n wrapText ? `height: auto;` : ` height: ${getChipSize(buttonShape)[buttonSize].height};`}\n`;\n\nconst disabledRoundShape = css`\n background-color: ${({ theme }) => theme.colors.neutral[400]};\n\n & .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral['000']};\n }\n`;\n\nexport const StyledRoundShape = styled('div', {\n name: DSChipName,\n slot: CHIP_SLOTS.ROUND_SHAPE,\n})<StyledRoundShapePropsT>`\n background-color: ${({ theme }) => theme.colors.brand[600]};\n width: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLarge : roundShapeSmall)};\n height: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLarge : roundShapeSmall)};\n border-radius: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n @media (max-width: ${({ theme }) => theme.breakpoints.small}) {\n width: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLargeMobile : roundShapeSmallMobile)};\n height: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLargeMobile : roundShapeSmallMobile)};\n }\n`;\n\nconst styledChipSelectedCss = css`\n // TODO: wrap css processor to process new HOC wrapping styled components\n ${StyledRoundShape.toString()} {\n background-color: ${({ theme }) => theme.colors.brand[800]};\n }\n color: ${({ theme }) => theme.colors.brand[800]};\n background-color: ${({ theme }) => theme.colors.brand[200]};\n\n .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.brand[800]};\n }\n\n &:before {\n border: 1px solid ${({ theme }) => theme.colors.brand[600]};\n }\n\n &:focus {\n &:before {\n border: 2px solid ${({ theme }) => theme.colors.brand[700]};\n }\n }\n`;\n\nconst disabledStyles = css`\n color: ${({ theme }) => theme.colors.neutral[500]};\n\n .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral[400]};\n }\n\n &:hover {\n ${StyledRoundShape} {\n background-color: ${({ theme }) => theme.colors.neutral[200]};\n }\n background-color: ${({ theme }) => theme.colors.neutral['050']};\n cursor: not-allowed;\n &:before {\n border-color: transparent;\n }\n }\n`;\n\nexport const StyledChip = styled('button', { name: DSChipName, slot: CHIP_SLOTS.BUTTON })<\n Pick<StyledChipPropsT, 'selected' | 'buttonShape' | 'buttonSize' | '
|
|
5
|
-
"mappings": "AAAA,YAAY,WAAW;ACCvB,SAAS,QAAQ,KAAK,0BAA0B;AAChD,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable max-lines */\nimport { styled, css, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSTypography } from '@elliemae/ds-typography';\nimport {\n basicSizes,\n shapeSizes,\n CHIP_SHAPES,\n CHIP_SIZES,\n roundShapeLarge,\n roundShapeSmall,\n DSChipName,\n CHIP_SLOTS,\n roundShapeLargeMobile,\n roundShapeSmallMobile,\n} from './constants/index.js';\nimport type { ChipShapesT, ChipSizesT } from './sharedTypes.js';\n\nexport interface StyledChipPropsT {\n buttonSize: ChipSizesT;\n buttonShape: ChipShapesT;\n selected?: boolean;\n wrapText?: boolean;\n expanded?: boolean;\n}\n\nexport interface StyledRoundShapePropsT {\n size: ChipSizesT;\n disabled?: boolean;\n}\n\nconst getChipSize = (shape: ChipShapesT) => (shape === CHIP_SHAPES.ROUND ? shapeSizes : basicSizes);\n\nconst wrapTextStyles = css`\n overflow-wrap: break-word;\n white-space: pre-wrap;\n overflow: visible;\n`;\n\nconst ellipsisStyles = css`\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\nexport const StyledChipLabel = styled('div', { name: DSChipName, slot: CHIP_SLOTS.LABEL })<{ size: ChipSizesT }>`\n font-size: ${({ theme }) => theme.fontSizes.label[200]};\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n word-wrap: break-word;\n text-align: center;\n padding-top: ${({ size }) => (size === CHIP_SIZES.L ? '2px' : '4px')};\n z-index: 0;\n line-height: 1.27;\n width: inherit;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nexport const StyledSpanWithEllipsis = styled(DSTypography, {\n name: DSChipName,\n slot: CHIP_SLOTS.ELLIPSIS,\n})<{ wrapText?: boolean }>`\n ${({ wrapText }) => (wrapText ? wrapTextStyles : ellipsisStyles)};\n max-width: 100%;\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n`;\n\nexport const StyledWrapper = styled('div', {\n name: DSChipName,\n slot: CHIP_SLOTS.ROOT,\n})<StyledChipPropsT>`\n display: flex;\n width: ${({ buttonSize, buttonShape }) => getChipSize(buttonShape)[buttonSize].width};\n ${xStyledCommonProps}\n max-width: ${({ buttonSize }) => basicSizes[buttonSize].maxWidth};\n ${({ wrapText, buttonSize, buttonShape }) =>\n wrapText ? `height: auto;` : ` height: ${getChipSize(buttonShape)[buttonSize].height};`}\n`;\n\nconst disabledRoundShape = css`\n background-color: ${({ theme }) => theme.colors.neutral[400]};\n\n & .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral['000']};\n }\n`;\n\nexport const StyledRoundShape = styled('div', {\n name: DSChipName,\n slot: CHIP_SLOTS.ROUND_SHAPE,\n})<StyledRoundShapePropsT>`\n background-color: ${({ theme }) => theme.colors.brand[600]};\n width: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLarge : roundShapeSmall)};\n height: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLarge : roundShapeSmall)};\n border-radius: 50px;\n display: flex;\n align-items: center;\n justify-content: center;\n @media (max-width: ${({ theme }) => theme.breakpoints.small}) {\n width: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLargeMobile : roundShapeSmallMobile)};\n height: ${({ size }) => (size === CHIP_SIZES.L ? roundShapeLargeMobile : roundShapeSmallMobile)};\n }\n`;\n\nconst styledChipSelectedCss = css`\n // TODO: wrap css processor to process new HOC wrapping styled components\n ${StyledRoundShape.toString()} {\n background-color: ${({ theme }) => theme.colors.brand[800]};\n }\n color: ${({ theme }) => theme.colors.brand[800]};\n background-color: ${({ theme }) => theme.colors.brand[200]};\n\n .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.brand[800]};\n }\n\n &:before {\n border: 1px solid ${({ theme }) => theme.colors.brand[600]};\n }\n\n &:focus {\n &:before {\n border: 2px solid ${({ theme }) => theme.colors.brand[700]};\n }\n }\n`;\n\nconst disabledStyles = css`\n color: ${({ theme }) => theme.colors.neutral[500]};\n\n .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral[400]};\n }\n\n &:hover {\n ${StyledRoundShape} {\n background-color: ${({ theme }) => theme.colors.neutral[200]};\n }\n background-color: ${({ theme }) => theme.colors.neutral['050']};\n cursor: not-allowed;\n &:before {\n border-color: transparent;\n }\n }\n`;\n\nexport const StyledChip = styled('button', { name: DSChipName, slot: CHIP_SLOTS.BUTTON })<\n Pick<StyledChipPropsT, 'selected' | 'buttonShape' | 'buttonSize' | 'expanded'>\n>`\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n border: none;\n min-height: 100%;\n height: fit-content;\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral['000']};\n color: ${({ theme }) => theme.colors.brand[600]};\n border-radius: 4px;\n cursor: pointer;\n outline: none;\n ${({ buttonShape, buttonSize }) => {\n if (buttonShape === CHIP_SHAPES.ROUND && buttonSize === CHIP_SIZES.L) {\n return css`\n padding: 6px;\n `;\n }\n return css`\n padding: 10px 6px;\n `;\n }}\n ${StyledRoundShape} {\n & .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.neutral['000']};\n }\n ${({ disabled }) => disabled && disabledRoundShape}\n }\n &:before {\n content: '';\n position: absolute;\n z-index: 20;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border-radius: 4px;\n border: 2px solid transparent;\n pointer-events: none;\n }\n & .DSIcon-root .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.brand[600]};\n color: ${({ theme }) => theme.colors.neutral[600]};\n }\n\n z-index: ${({ expanded }) => (expanded ? 10 : 'auto')};\n /* Keep this interpolation always present \u2014 making it conditional changes the styled wrapper's hook\n count between renders. */\n ${StyledSpanWithEllipsis} {\n ${({ expanded }) =>\n expanded &&\n css`\n ${wrapTextStyles}\n `}\n }\n\n &:hover {\n ${StyledRoundShape} {\n background-color: ${({ theme }) => theme.colors.brand[800]};\n }\n color: ${({ theme }) => theme.colors.brand[800]};\n background-color: ${({ theme }) => theme.colors.brand[200]};\n .DSIcon-svg {\n fill: ${({ theme }) => theme.colors.brand[800]};\n }\n }\n\n &:focus {\n &:before {\n ${({ buttonShape }) =>\n buttonShape === CHIP_SHAPES.ROUND\n ? css`\n border: 2px solid ${({ theme }) => theme.colors.brand[800]};\n `\n : css`\n border: 2px solid ${({ theme }) => theme.colors.brand[700]};\n `}\n }\n }\n\n &:disabled {\n ${disabledStyles}\n }\n\n &[aria-disabled='true'] {\n ${disabledStyles}\n ${StyledRoundShape} {\n ${disabledRoundShape}\n }\n\n &:focus {\n &:before {\n border: 2px solid ${({ theme }) => theme.colors.neutral[400]};\n }\n }\n }\n\n ${({ selected, buttonShape }) =>\n !selected\n ? ''\n : css`\n ${styledChipSelectedCss}\n &:focus {\n &:before {\n ${\n buttonShape === CHIP_SHAPES.ROUND\n ? css`\n border: 2px solid ${({ theme }) => theme.colors.brand[800]};\n `\n : css`\n border: 2px solid ${({ theme }) => theme.colors.brand[700]};\n `\n }\n }\n }\n `}\n`;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useEscapeDismiss: (active: boolean, onDismiss: () => void) => void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
interface ConsumerHandlersT {
|
|
3
|
+
onMouseEnter?: React.MouseEventHandler<HTMLButtonElement>;
|
|
4
|
+
onMouseLeave?: React.MouseEventHandler<HTMLButtonElement>;
|
|
5
|
+
onFocus?: React.FocusEventHandler<HTMLButtonElement>;
|
|
6
|
+
onBlur?: React.FocusEventHandler<HTMLButtonElement>;
|
|
7
|
+
}
|
|
8
|
+
export declare const useLabelExpansion: (wrapText: boolean, consumer: ConsumerHandlersT) => {
|
|
9
|
+
expanded: boolean;
|
|
10
|
+
labelRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
11
|
+
expansionHandlers: {
|
|
12
|
+
onMouseEnter: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
13
|
+
onMouseLeave: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
14
|
+
onFocus: (e: React.FocusEvent<HTMLButtonElement>) => void;
|
|
15
|
+
onBlur: (e: React.FocusEvent<HTMLButtonElement>) => void;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export {};
|
package/dist/types/styles.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export interface StyledChipPropsT {
|
|
|
4
4
|
buttonShape: ChipShapesT;
|
|
5
5
|
selected?: boolean;
|
|
6
6
|
wrapText?: boolean;
|
|
7
|
+
expanded?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export interface StyledRoundShapePropsT {
|
|
9
10
|
size: ChipSizesT;
|
|
@@ -17,4 +18,4 @@ export declare const StyledSpanWithEllipsis: import("styled-components").StyledC
|
|
|
17
18
|
} & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<import("react").FC<import("@elliemae/ds-typography").DSTypographyT.Props>>, never>;
|
|
18
19
|
export declare const StyledWrapper: import("styled-components").StyledComponent<"div", import("@elliemae/ds-system").Theme, StyledChipPropsT & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"div">, never>;
|
|
19
20
|
export declare const StyledRoundShape: import("styled-components").StyledComponent<"div", import("@elliemae/ds-system").Theme, StyledRoundShapePropsT & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"div">, never>;
|
|
20
|
-
export declare const StyledChip: import("styled-components").StyledComponent<"button", import("@elliemae/ds-system").Theme, Pick<StyledChipPropsT, "selected" | "
|
|
21
|
+
export declare const StyledChip: import("styled-components").StyledComponent<"button", import("@elliemae/ds-system").Theme, Pick<StyledChipPropsT, "selected" | "buttonSize" | "buttonShape" | "expanded"> & import("@elliemae/ds-system").OwnerInterface & import("@elliemae/ds-system").InnerRefInterface<"button">, never>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliemae/ds-chip",
|
|
3
|
-
"version": "3.70.0-next.
|
|
3
|
+
"version": "3.70.0-next.61",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "ICE MT - Dimsum - Chip",
|
|
6
6
|
"files": [
|
|
@@ -36,15 +36,15 @@
|
|
|
36
36
|
"indent": 4
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@elliemae/ds-props-helpers": "3.70.0-next.
|
|
40
|
-
"@elliemae/ds-
|
|
41
|
-
"@elliemae/ds-
|
|
39
|
+
"@elliemae/ds-props-helpers": "3.70.0-next.61",
|
|
40
|
+
"@elliemae/ds-typescript-helpers": "3.70.0-next.61",
|
|
41
|
+
"@elliemae/ds-system": "3.70.0-next.61"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"jest": "^30.0.0",
|
|
45
45
|
"styled-components": "~5.3.11",
|
|
46
|
-
"@elliemae/ds-
|
|
47
|
-
"@elliemae/ds-
|
|
46
|
+
"@elliemae/ds-monorepo-devops": "3.70.0-next.61",
|
|
47
|
+
"@elliemae/ds-test-utils": "3.70.0-next.61"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"lodash-es": "^4.18.1",
|