@qoretechnologies/reqore 0.74.11 → 0.74.12-pr.663.g65f34a4
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/components/CollapsibleContent/index.d.ts +4 -0
- package/dist/components/CollapsibleContent/index.d.ts.map +1 -1
- package/dist/components/CollapsibleContent/index.js +25 -4
- package/dist/components/CollapsibleContent/index.js.map +1 -1
- package/dist/components/Collection/index.d.ts.map +1 -1
- package/dist/components/Collection/index.js +17 -9
- package/dist/components/Collection/index.js.map +1 -1
- package/dist/components/Header/index.d.ts.map +1 -1
- package/dist/components/Header/index.js +1 -16
- package/dist/components/Header/index.js.map +1 -1
- package/dist/components/Panel/index.d.ts +90 -0
- package/dist/components/Panel/index.d.ts.map +1 -1
- package/dist/components/Panel/index.js +349 -53
- package/dist/components/Panel/index.js.map +1 -1
- package/dist/constants/sizes.d.ts +8 -0
- package/dist/constants/sizes.d.ts.map +1 -1
- package/dist/constants/sizes.js +16 -1
- package/dist/constants/sizes.js.map +1 -1
- package/dist/hooks/useFitTextSize.d.ts +59 -0
- package/dist/hooks/useFitTextSize.d.ts.map +1 -0
- package/dist/hooks/useFitTextSize.js +75 -0
- package/dist/hooks/useFitTextSize.js.map +1 -0
- package/package.json +1 -1
- package/tests.json +0 -1
|
@@ -80,6 +80,7 @@ var styled_1 = require("../../helpers/styled");
|
|
|
80
80
|
var utils_1 = require("../../helpers/utils");
|
|
81
81
|
var useCombinedRefs_1 = require("../../hooks/useCombinedRefs");
|
|
82
82
|
var useReqoreContext_1 = require("../../hooks/useReqoreContext");
|
|
83
|
+
var useFitTextSize_1 = require("../../hooks/useFitTextSize");
|
|
83
84
|
var useTheme_1 = require("../../hooks/useTheme");
|
|
84
85
|
var styles_1 = require("../../styles");
|
|
85
86
|
var Breadcrumbs_1 = __importDefault(require("../Breadcrumbs"));
|
|
@@ -134,16 +135,29 @@ var getScrollportInset = function (el) {
|
|
|
134
135
|
border: parseFloat(style.borderTopWidth) || 0,
|
|
135
136
|
};
|
|
136
137
|
};
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
/**
|
|
139
|
+
* The box the title lives in — and, when the title may wrap, the thing that clamps it.
|
|
140
|
+
*
|
|
141
|
+
* It exists first as a measuring box: as a `min-width: 0` flex child it reports the width the
|
|
142
|
+
* row actually left for the title, where the heading itself would report what its text wants.
|
|
143
|
+
* `overflow: hidden` is what makes it shrinkable at all, and `display: flex` keeps it from
|
|
144
|
+
* opening a line box around the inline-flex heading — a block wrapper adds the row's leading on
|
|
145
|
+
* top of the heading's own box, which made a `tiny` panel 3px taller than it used to be.
|
|
146
|
+
*/
|
|
147
|
+
var StyledPanelTitleLabelBox = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n min-width: 0;\n overflow: hidden;\n flex: 0 1 auto;\n\n ", "\n"], ["\n display: flex;\n min-width: 0;\n overflow: hidden;\n flex: 0 1 auto;\n\n ", "\n"])), function (_a) {
|
|
148
|
+
var $clampLines = _a.$clampLines;
|
|
149
|
+
return $clampLines > 1 && (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n .reqore-heading {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: ", ";\n overflow: hidden;\n white-space: normal;\n /* A single word longer than the box would push past it rather than break, and the\n clamp would have nothing to ellipsize. */\n overflow-wrap: anywhere;\n max-width: 100%;\n\n /* The heading wraps its text in a span of its own, and `-webkit-line-clamp` counts the\n box's CHILDREN rather than the lines inside them \u2014 so one block-level child reads as\n a single line and nothing is ever clamped, however far the text overruns. Putting the\n text back into the heading's own line boxes is what the clamp actually measures. */\n .reqore-span {\n display: inline;\n }\n }\n "], ["\n .reqore-heading {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: ", ";\n overflow: hidden;\n white-space: normal;\n /* A single word longer than the box would push past it rather than break, and the\n clamp would have nothing to ellipsize. */\n overflow-wrap: anywhere;\n max-width: 100%;\n\n /* The heading wraps its text in a span of its own, and \\`-webkit-line-clamp\\` counts the\n box's CHILDREN rather than the lines inside them \u2014 so one block-level child reads as\n a single line and nothing is ever clamped, however far the text overruns. Putting the\n text back into the heading's own line boxes is what the clamp actually measures. */\n .reqore-span {\n display: inline;\n }\n }\n "])), $clampLines);
|
|
150
|
+
});
|
|
151
|
+
exports.StyledPanelTitleHeader = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n\n display: flex;\n justify-content: flex-start;\n align-items: center;\n /* A CONTENT basis, and both extremes were tried before settling here. Basis 0 hands the action\n group beside this one its full content width, so nothing ever overflows and the fold into the\n menu never fires \u2014 actions labelled \"hidden when small\" stay visible on a small panel. A 100%\n width does the opposite: this header claims the entire row, so the group is always crushed to\n its floor and always folds however much room there is, which hid Tree's save button behind an\n overflow menu on a panel with space to spare. On a content basis the two shrink against each\n other in proportion to what they each need, which is the only version where folding means\n \"there is no room\" rather than \"there is a header\". */\n flex: 1 1 auto;\n overflow: hidden;\n"], ["\n\n display: flex;\n justify-content: flex-start;\n align-items: center;\n /* A CONTENT basis, and both extremes were tried before settling here. Basis 0 hands the action\n group beside this one its full content width, so nothing ever overflows and the fold into the\n menu never fires \u2014 actions labelled \"hidden when small\" stay visible on a small panel. A 100%\n width does the opposite: this header claims the entire row, so the group is always crushed to\n its floor and always folds however much room there is, which hid Tree's save button behind an\n overflow menu on a panel with space to spare. On a content basis the two shrink against each\n other in proportion to what they each need, which is the only version where folding means\n \"there is no room\" rather than \"there is a header\". */\n flex: 1 1 auto;\n overflow: hidden;\n"])));
|
|
152
|
+
exports.StyledPanelTitleHeaderContent = styled_components_1.default.div(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n // When the icon lives in the outer container (iconVerticalAlign mode),\n // we use a 2-column \u00D7 N-row CSS Grid where the LABEL ROW and DESCRIPTION\n // ROW are direct grid items \u2014 not wrapped inside a span-2 stack. That\n // makes each row's auto-sized height equal to the actual text row's\n // line-box height, so 'align-self: center' on the icon (in column 1)\n // visually centres the icon against the text row it shares a grid row\n // with \u2014 no font-metric guesswork.\n display: ", ";\n ", "\n flex: 0 1 auto;\n overflow: hidden;\n min-width: ", "px;\n"], ["\n // When the icon lives in the outer container (iconVerticalAlign mode),\n // we use a 2-column \u00D7 N-row CSS Grid where the LABEL ROW and DESCRIPTION\n // ROW are direct grid items \u2014 not wrapped inside a span-2 stack. That\n // makes each row's auto-sized height equal to the actual text row's\n // line-box height, so 'align-self: center' on the icon (in column 1)\n // visually centres the icon against the text row it shares a grid row\n // with \u2014 no font-metric guesswork.\n display: ", ";\n ", "\n flex: 0 1 auto;\n overflow: hidden;\n min-width: ", "px;\n"])), function (_a) {
|
|
139
153
|
var $hasOuterIcon = _a.$hasOuterIcon;
|
|
140
154
|
return ($hasOuterIcon ? 'grid' : 'flex');
|
|
141
155
|
}, function (_a) {
|
|
142
156
|
var $hasOuterIcon = _a.$hasOuterIcon, size = _a.size, _b = _a.$iconVerticalAlign, $iconVerticalAlign = _b === void 0 ? 'center' : _b, $hasDescription = _a.$hasDescription;
|
|
143
157
|
return $hasOuterIcon
|
|
144
|
-
? (0, styled_components_1.css)(
|
|
145
|
-
? (0, styled_components_1.css)(
|
|
146
|
-
? (0, styled_components_1.css)(
|
|
158
|
+
? (0, styled_components_1.css)(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n // 'auto' lets the column grow to the icon's actual rendered size \u2014\n // important when consumers pass a custom 'iconProps.size' that does\n // not match the default size derived from 'panelSize'/'labelSize'.\n // 'iconSize' is still passed via 'min-width' below to ensure a\n // sensible minimum reservation when the row is otherwise empty.\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-rows: ", ";\n column-gap: ", "px;\n row-gap: 3px;\n align-items: start;\n\n & > .reqore-panel-title-icon {\n ", "\n grid-column: 1;\n align-self: center;\n justify-self: start;\n // Suppress 'vertical-align: super' that ReqoreIcon applies to its\n // SVG for inline-text contexts. In our grid layout the wrapper is\n // already vertically centred against the text row's line-box;\n // 'display: block' takes the SVG out of inline flow entirely so\n // baseline/super offsets cannot push it off-centre. The wrapper's\n // own 'align-items: center' then centres the SVG within itself.\n & svg {\n display: block;\n vertical-align: middle;\n }\n }\n\n & > .reqore-panel-title-label-row {\n grid-column: 2;\n grid-row: 1;\n min-width: 0;\n }\n\n & > .reqore-panel-title-description {\n grid-column: 2;\n grid-row: 2;\n min-width: 0;\n }\n "], ["\n // 'auto' lets the column grow to the icon's actual rendered size \u2014\n // important when consumers pass a custom 'iconProps.size' that does\n // not match the default size derived from 'panelSize'/'labelSize'.\n // 'iconSize' is still passed via 'min-width' below to ensure a\n // sensible minimum reservation when the row is otherwise empty.\n grid-template-columns: auto minmax(0, 1fr);\n grid-template-rows: ", ";\n column-gap: ", "px;\n row-gap: 3px;\n align-items: start;\n\n & > .reqore-panel-title-icon {\n ", "\n grid-column: 1;\n align-self: center;\n justify-self: start;\n // Suppress 'vertical-align: super' that ReqoreIcon applies to its\n // SVG for inline-text contexts. In our grid layout the wrapper is\n // already vertically centred against the text row's line-box;\n // 'display: block' takes the SVG out of inline flow entirely so\n // baseline/super offsets cannot push it off-centre. The wrapper's\n // own 'align-items: center' then centres the SVG within itself.\n & svg {\n display: block;\n vertical-align: middle;\n }\n }\n\n & > .reqore-panel-title-label-row {\n grid-column: 2;\n grid-row: 1;\n min-width: 0;\n }\n\n & > .reqore-panel-title-description {\n grid-column: 2;\n grid-row: 2;\n min-width: 0;\n }\n "])), $hasDescription ? 'auto auto' : 'auto', sizes_1.PADDING_FROM_SIZE[size || 'normal'], $iconVerticalAlign === 'top'
|
|
159
|
+
? (0, styled_components_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n grid-row: 1;\n "], ["\n grid-row: 1;\n "]))) : $iconVerticalAlign === 'bottom' && $hasDescription
|
|
160
|
+
? (0, styled_components_1.css)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n grid-row: 2;\n "], ["\n grid-row: 2;\n "]))) : (0, styled_components_1.css)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n grid-row: 1 / ", ";\n "], ["\n grid-row: 1 / ", ";\n "])), $hasDescription ? 3 : 2)) : (0, styled_components_1.css)(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n justify-content: flex-start;\n align-items: center;\n "], ["\n justify-content: flex-start;\n align-items: center;\n "])));
|
|
147
161
|
}, function (_a) {
|
|
148
162
|
var iconSize = _a.iconSize, hasIcon = _a.hasIcon;
|
|
149
163
|
var width = 0;
|
|
@@ -152,8 +166,8 @@ exports.StyledPanelTitleHeaderContent = styled_components_1.default.div(template
|
|
|
152
166
|
}
|
|
153
167
|
return width;
|
|
154
168
|
});
|
|
155
|
-
exports.StyledPanelTitleHeaderLabelAndDescription = styled_components_1.default.div(
|
|
156
|
-
exports.StyledPanelTitleHeaderLabelAndBadge = styled_components_1.default.div(
|
|
169
|
+
exports.StyledPanelTitleHeaderLabelAndDescription = styled_components_1.default.div(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n display: flex;\n flex-flow: column;\n gap: 3px;\n min-width: 0;\n flex: 1 auto;\n"], ["\n display: flex;\n flex-flow: column;\n gap: 3px;\n min-width: 0;\n flex: 1 auto;\n"])));
|
|
170
|
+
exports.StyledPanelTitleHeaderLabelAndBadge = styled_components_1.default.div(templateObject_11 || (templateObject_11 = __makeTemplateObject(["\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n"], ["\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n"])));
|
|
157
171
|
/**
|
|
158
172
|
* Does the panel wrapper draw its 1px border?
|
|
159
173
|
*
|
|
@@ -184,7 +198,7 @@ exports.StyledPanel = (0, styled_components_1.default)(Effect_1.StyledEffect).wi
|
|
|
184
198
|
// Everything else follows styled-components' own rule, so re-resizable still receives its
|
|
185
199
|
// `enable` / size / handle config — those are component props, not HTML attributes.
|
|
186
200
|
shouldForwardProp: (0, styled_1.omitStyleProps)('fill', 'accentPosition'),
|
|
187
|
-
})(
|
|
201
|
+
})(templateObject_20 || (templateObject_20 = __makeTemplateObject(["\n background-color: ", ";\n border-radius: ", "px;\n border: ", ";\n color: ", ";\n ", "\n overflow: ", ";\n display: flex;\n flex-flow: column;\n position: relative;\n backdrop-filter: ", ";\n width: ", ";\n max-width: 100%;\n flex: ", ";\n\n /* Hover-hiding applies ONLY where the pointer can hover. A touch device never\n fires :hover, so without this gate a `show: 'hover'` action is display:none\n forever \u2014 not merely invisible but absent from the layout, with nothing on\n screen hinting it exists. Where hover is unavailable the action stays\n visible; losing the tidiness beats losing the action. */\n @media (hover: hover) and (pointer: fine) {\n &:not(:hover) {\n .reqore-panel-action-hidden {\n display: none;\n }\n }\n }\n\n &.reqore-panel-floating-active {\n border-top-right-radius: 0;\n }\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n"], ["\n background-color: ", ";\n border-radius: ", "px;\n border: ", ";\n color: ", ";\n ", "\n overflow: ", ";\n display: flex;\n flex-flow: column;\n position: relative;\n backdrop-filter: ", ";\n width: ", ";\n max-width: 100%;\n flex: ", ";\n\n /* Hover-hiding applies ONLY where the pointer can hover. A touch device never\n fires :hover, so without this gate a \\`show: 'hover'\\` action is display:none\n forever \u2014 not merely invisible but absent from the layout, with nothing on\n screen hinting it exists. Where hover is unavailable the action stays\n visible; losing the tidiness beats losing the action. */\n @media (hover: hover) and (pointer: fine) {\n &:not(:hover) {\n .reqore-panel-action-hidden {\n display: none;\n }\n }\n }\n\n &.reqore-panel-floating-active {\n border-top-right-radius: 0;\n }\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n"])), function (_a) {
|
|
188
202
|
var theme = _a.theme, _b = _a.opacity, opacity = _b === void 0 ? 1 : _b;
|
|
189
203
|
return (0, polished_1.rgba)((0, colors_2.changeDarkness)((0, colors_2.getMainBackgroundColor)(theme), 0.03), opacity);
|
|
190
204
|
}, function (_a) {
|
|
@@ -219,10 +233,10 @@ exports.StyledPanel = (0, styled_components_1.default)(Effect_1.StyledEffect).wi
|
|
|
219
233
|
? Math.max(0, (0, sizes_1.resolveRadius)('normal', radiusSize) -
|
|
220
234
|
(hasPanelBorder({ flat: flat, intent: intent, accentPosition: accentPosition }) ? 1 : 0))
|
|
221
235
|
: 0;
|
|
222
|
-
return (0, styled_components_1.css)(
|
|
223
|
-
? (0, styled_components_1.css)(
|
|
236
|
+
return (0, styled_components_1.css)(templateObject_16 || (templateObject_16 = __makeTemplateObject(["\n position: relative;\n /* Reserve the strip's thickness so the title bar and content never sit\n under it \u2014 the same reservation ReqoreCallout makes. */\n padding-", ": ", "px;\n\n &::before {\n content: '';\n position: absolute;\n ", "\n ", "\n background-color: ", ";\n }\n "], ["\n position: relative;\n /* Reserve the strip's thickness so the title bar and content never sit\n under it \u2014 the same reservation ReqoreCallout makes. */\n padding-", ": ", "px;\n\n &::before {\n content: '';\n position: absolute;\n ", "\n ", "\n background-color: ", ";\n }\n "])), accentPosition === 'left' ? 'left' : 'top', $accentSize, accentPosition === 'left'
|
|
237
|
+
? (0, styled_components_1.css)(templateObject_12 || (templateObject_12 = __makeTemplateObject(["\n top: 0;\n bottom: 0;\n left: 0;\n width: ", "px;\n "], ["\n top: 0;\n bottom: 0;\n left: 0;\n width: ", "px;\n "])), $accentSize) : (0, styled_components_1.css)(templateObject_13 || (templateObject_13 = __makeTemplateObject(["\n top: 0;\n right: 0;\n left: 0;\n height: ", "px;\n "], ["\n top: 0;\n right: 0;\n left: 0;\n height: ", "px;\n "])), $accentSize), stripRadius
|
|
224
238
|
? accentPosition === 'left'
|
|
225
|
-
? (0, styled_components_1.css)(
|
|
239
|
+
? (0, styled_components_1.css)(templateObject_14 || (templateObject_14 = __makeTemplateObject(["\n border-top-left-radius: ", "px;\n border-bottom-left-radius: ", "px;\n "], ["\n border-top-left-radius: ", "px;\n border-bottom-left-radius: ", "px;\n "])), stripRadius, stripRadius) : (0, styled_components_1.css)(templateObject_15 || (templateObject_15 = __makeTemplateObject(["\n border-top-left-radius: ", "px;\n border-top-right-radius: ", "px;\n "], ["\n border-top-left-radius: ", "px;\n border-top-right-radius: ", "px;\n "])), stripRadius, stripRadius)
|
|
226
240
|
: undefined, intent
|
|
227
241
|
? theme.intents[intent]
|
|
228
242
|
: (0, colors_2.changeLightness)((0, colors_2.getMainBackgroundColor)(theme), 0.22));
|
|
@@ -241,25 +255,34 @@ exports.StyledPanel = (0, styled_components_1.default)(Effect_1.StyledEffect).wi
|
|
|
241
255
|
}, function (_a) {
|
|
242
256
|
var interactive = _a.interactive, theme = _a.theme, _b = _a.opacity, opacity = _b === void 0 ? 1 : _b, flat = _a.flat, intent = _a.intent, accentPosition = _a.accentPosition;
|
|
243
257
|
return interactive
|
|
244
|
-
? (0, styled_components_1.css)(
|
|
258
|
+
? (0, styled_components_1.css)(templateObject_18 || (templateObject_18 = __makeTemplateObject(["\n cursor: pointer;\n\n &:hover {\n ", " ", " .reqore-panel-title-icon {\n transform: scale(", ");\n }\n\n background-color: ", ";\n\n border-color: ", ";\n\n ", "\n }\n "], ["\n cursor: pointer;\n\n &:hover {\n ", " ", " .reqore-panel-title-icon {\n transform: scale(", ");\n }\n\n background-color: ", ";\n\n border-color: ", ";\n\n ", "\n }\n "])), exports.StyledPanelTitle, exports.StyledPanelTitleHeaderContent, styles_1.ACTIVE_ICON_SCALE, opacity === 0 && flat
|
|
245
259
|
? undefined
|
|
246
260
|
: (0, polished_1.rgba)((0, polished_1.darken)(0.025, (0, polished_1.rgba)((0, colors_2.changeDarkness)((0, colors_2.getMainBackgroundColor)(theme), 0.03), opacity)), opacity), hasPanelBorder({ flat: flat, intent: intent, accentPosition: accentPosition })
|
|
247
261
|
? (0, colors_2.changeLightness)(getPanelBorderBaseColor(theme, { intent: intent, accentPosition: accentPosition }), 0.25)
|
|
248
|
-
: undefined, opacity !== 0 && (0, styled_components_1.css)(
|
|
262
|
+
: undefined, opacity !== 0 && (0, styled_components_1.css)(templateObject_17 || (templateObject_17 = __makeTemplateObject(["\n ", ":after {\n background: linear-gradient(\n to top,\n ", "\n 0%,\n transparent 100%\n );\n }\n "], ["\n ", ":after {\n background: linear-gradient(\n to top,\n ", "\n 0%,\n transparent 100%\n );\n }\n "])), item_1.StyledCollectionItemContent, (0, polished_1.rgba)((0, polished_1.darken)(0.025, (0, polished_1.rgba)((0, colors_2.changeDarkness)((0, colors_2.getMainBackgroundColor)(theme), 0.03), opacity)), opacity))) : undefined;
|
|
249
263
|
}, function (_a) {
|
|
250
264
|
var raised = _a.raised, flat = _a.flat, intent = _a.intent, accentPosition = _a.accentPosition;
|
|
251
265
|
return raised && !hasPanelBorder({ flat: flat, intent: intent, accentPosition: accentPosition }) && styles_1.RaisedElement;
|
|
252
266
|
}, function (_a) {
|
|
253
267
|
var fill = _a.fill, isCollapsed = _a.isCollapsed;
|
|
254
268
|
return !isCollapsed && fill
|
|
255
|
-
? (0, styled_components_1.css)(
|
|
269
|
+
? (0, styled_components_1.css)(templateObject_19 || (templateObject_19 = __makeTemplateObject(["\n height: 100%;\n flex: 1;\n "], ["\n height: 100%;\n flex: 1;\n "]))) : undefined;
|
|
256
270
|
}, function (_a) {
|
|
257
271
|
var disabled = _a.disabled;
|
|
258
272
|
return disabled && styles_1.DisabledElement;
|
|
259
273
|
});
|
|
260
|
-
exports.StyledPanelTitle = styled_components_1.default.div(
|
|
261
|
-
var
|
|
262
|
-
return (
|
|
274
|
+
exports.StyledPanelTitle = styled_components_1.default.div(templateObject_25 || (templateObject_25 = __makeTemplateObject(["\n display: flex;\n /* Always a row. The title bar used to flip to a column when narrow; it now ellipsizes its\n label and lets the responsive action group collapse instead, which is what the \"hidden when\n small\" actions are for and what the stack was quietly defeating (a column made the group\n fluid, and a full-width group had room not to collapse). */\n flex-flow: ", ";\n\n ", "\n\n ", "\n\n ", "\n\n background-color: ", ";\n justify-content: space-between;\n\n padding: ", ";\n\n align-items: center;\n border-bottom: ", ";\n transition: background-color 0.2s ease-out;\n overflow: hidden;\n flex: 0 0 auto;\n gap: ", "px;\n\n ", " .reqore-panel-title-icon {\n transform: scale(", ");\n }\n\n ", "\n"], ["\n display: flex;\n /* Always a row. The title bar used to flip to a column when narrow; it now ellipsizes its\n label and lets the responsive action group collapse instead, which is what the \"hidden when\n small\" actions are for and what the stack was quietly defeating (a column made the group\n fluid, and a full-width group had room not to collapse). */\n flex-flow: ", ";\n\n ", "\n\n ", "\n\n ", "\n\n background-color: ", ";\n justify-content: space-between;\n\n padding: ", ";\n\n align-items: center;\n border-bottom: ", ";\n transition: background-color 0.2s ease-out;\n overflow: hidden;\n flex: 0 0 auto;\n gap: ", "px;\n\n ", " .reqore-panel-title-icon {\n transform: scale(", ");\n }\n\n ", "\n"])), function (_a) {
|
|
275
|
+
var $descriptionBelow = _a.$descriptionBelow;
|
|
276
|
+
return ($descriptionBelow ? 'row wrap' : 'row');
|
|
277
|
+
}, function (_a) {
|
|
278
|
+
var $descriptionFontPx = _a.$descriptionFontPx;
|
|
279
|
+
return !!$descriptionFontPx && (0, styled_components_1.css)(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n /* The description is a fixed px from `TEXT_FROM_SIZE` and knows nothing about the title\n having shrunk, so a fitted title crosses under it: at the 12px floor the support text\n renders at 15px and outranks the heading it supports. Scaling it by the SAME factor the\n title took keeps the two in their original proportion instead of giving the description\n a fit of its own \u2014 which would size it against its own box and let the pair drift apart\n again, in the other direction. */\n .reqore-panel-title-description {\n font-size: ", "px;\n }\n "], ["\n /* The description is a fixed px from \\`TEXT_FROM_SIZE\\` and knows nothing about the title\n having shrunk, so a fitted title crosses under it: at the 12px floor the support text\n renders at 15px and outranks the heading it supports. Scaling it by the SAME factor the\n title took keeps the two in their original proportion instead of giving the description\n a fit of its own \u2014 which would size it against its own box and let the pair drift apart\n again, in the other direction. */\n .reqore-panel-title-description {\n font-size: ", "px;\n }\n "])), $descriptionFontPx);
|
|
280
|
+
}, function (_a) {
|
|
281
|
+
var $descriptionBelow = _a.$descriptionBelow;
|
|
282
|
+
return $descriptionBelow && (0, styled_components_1.css)(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n /* Only on a wrapping bar. The header claims the row so the action group beside it gets\n squeezed and folds \u2014 that is what the base rule is for \u2014 but in a WRAPPING row a\n full-width claim takes the whole line and pushes the actions onto their own, which is\n not what \"description below\" asked for. Here the header grows from 0 into whatever the\n actions leave, on line one, and the description takes line two. */\n > .reqore-panel-title-header {\n width: auto;\n flex: 1 1 0%;\n min-width: 0;\n }\n "], ["\n /* Only on a wrapping bar. The header claims the row so the action group beside it gets\n squeezed and folds \u2014 that is what the base rule is for \u2014 but in a WRAPPING row a\n full-width claim takes the whole line and pushes the actions onto their own, which is\n not what \"description below\" asked for. Here the header grows from 0 into whatever the\n actions leave, on line one, and the description takes line two. */\n > .reqore-panel-title-header {\n width: auto;\n flex: 1 1 0%;\n min-width: 0;\n }\n "])));
|
|
283
|
+
}, function (_a) {
|
|
284
|
+
var $descriptionMaxLines = _a.$descriptionMaxLines;
|
|
285
|
+
return !!$descriptionMaxLines && (0, styled_components_1.css)(templateObject_23 || (templateObject_23 = __makeTemplateObject(["\n .reqore-panel-title-description {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: ", ";\n overflow: hidden;\n white-space: normal;\n overflow-wrap: anywhere;\n }\n "], ["\n .reqore-panel-title-description {\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: ", ";\n overflow: hidden;\n white-space: normal;\n overflow-wrap: anywhere;\n }\n "])), $descriptionMaxLines);
|
|
263
286
|
}, function (_a) {
|
|
264
287
|
var theme = _a.theme, _b = _a.opacity, opacity = _b === void 0 ? 1 : _b;
|
|
265
288
|
return (0, polished_1.rgba)((0, colors_2.changeLightness)((0, colors_2.getMainBackgroundColor)(theme), 0.03), opacity);
|
|
@@ -273,12 +296,12 @@ exports.StyledPanelTitle = styled_components_1.default.div(templateObject_20 ||
|
|
|
273
296
|
: null;
|
|
274
297
|
}, sizes_1.GAP_FROM_SIZE.normal, exports.StyledPanelTitleHeaderContent, styles_1.INACTIVE_ICON_SCALE, function (_a) {
|
|
275
298
|
var collapsible = _a.collapsible;
|
|
276
|
-
return collapsible && (0, styled_components_1.css)(
|
|
299
|
+
return collapsible && (0, styled_components_1.css)(templateObject_24 || (templateObject_24 = __makeTemplateObject(["\n cursor: pointer;\n &:hover {\n ", " .reqore-panel-title-icon {\n transform: scale(", ");\n }\n\n background-color: ", ";\n }\n "], ["\n cursor: pointer;\n &:hover {\n ", " .reqore-panel-title-icon {\n transform: scale(", ");\n }\n\n background-color: ", ";\n }\n "])), exports.StyledPanelTitleHeaderContent, styles_1.ACTIVE_ICON_SCALE, function (_a) {
|
|
277
300
|
var theme = _a.theme, _b = _a.opacity, opacity = _b === void 0 ? 1 : _b;
|
|
278
301
|
return (0, polished_1.rgba)((0, colors_2.changeLightness)((0, colors_2.getMainBackgroundColor)(theme), 0.05), opacity);
|
|
279
302
|
});
|
|
280
303
|
});
|
|
281
|
-
exports.StyledPanelTopBar = (0, styled_components_1.default)(exports.StyledPanelTitle)(
|
|
304
|
+
exports.StyledPanelTopBar = (0, styled_components_1.default)(exports.StyledPanelTitle)(templateObject_27 || (templateObject_27 = __makeTemplateObject(["\n padding-bottom: ", ";\n padding-top: ", ";\n position: ", ";\n /* `top: 0` must mean \"flush with the visible top edge of whatever scrolls\",\n which is what every call site assumes. Sticky resolves against the scroll\n container's CONTENT box, so on a padded scrollport \u2014 which every default\n panel/drawer/modal body is, since StyledPanelContent puts padding and\n overflow on one element \u2014 an uncompensated 0 parks the header below the\n padding and lets content scroll through the gap. `stickyHeaderInset` is\n that padding, measured from the real scroll ancestor at runtime;\n `stickyHeaderOffset` stays a deliberate caller offset on top of a now\n correct zero. */\n top: ", ";\n z-index: ", ";\n // A sticky header forces the panel wrapper to overflow visible (so the\n // header can stick), which stops the wrapper from clipping the header's top\n // corners \u2014 so without this the panel reads as square-topped even at rest.\n // AT REST, round the header's own top corners to the panel's inner radius so\n // the panel keeps its radius (inset 1px past a visible border to match the\n // wrapper's inner curve; flat border-less panels need no inset). ONCE STUCK\n // (pinned to the scroll container, detected at runtime via isStuck), drop the\n // radius to 0 so the pinned header reads as a full-width bar and only loses\n // its corners while it is actually moving with the scroll.\n border-top-left-radius: ", ";\n border-top-right-radius: ", ";\n background: ", ";\n // When the header is sticky AND the panel is minimal / transparent (opacity === 0), the\n // header has no surface of its own \u2014 scrolling content slides straight under it and the\n // label / actions become illegible. Apply a backdrop blur so the underlying content stays\n // visible but is softened enough for the header text to read clearly. Idle (no overflow,\n // nothing behind) the blur is a no-op so the static appearance is unchanged.\n ", "\n"], ["\n padding-bottom: ", ";\n padding-top: ", ";\n position: ", ";\n /* \\`top: 0\\` must mean \"flush with the visible top edge of whatever scrolls\",\n which is what every call site assumes. Sticky resolves against the scroll\n container's CONTENT box, so on a padded scrollport \u2014 which every default\n panel/drawer/modal body is, since StyledPanelContent puts padding and\n overflow on one element \u2014 an uncompensated 0 parks the header below the\n padding and lets content scroll through the gap. \\`stickyHeaderInset\\` is\n that padding, measured from the real scroll ancestor at runtime;\n \\`stickyHeaderOffset\\` stays a deliberate caller offset on top of a now\n correct zero. */\n top: ", ";\n z-index: ", ";\n // A sticky header forces the panel wrapper to overflow visible (so the\n // header can stick), which stops the wrapper from clipping the header's top\n // corners \u2014 so without this the panel reads as square-topped even at rest.\n // AT REST, round the header's own top corners to the panel's inner radius so\n // the panel keeps its radius (inset 1px past a visible border to match the\n // wrapper's inner curve; flat border-less panels need no inset). ONCE STUCK\n // (pinned to the scroll container, detected at runtime via isStuck), drop the\n // radius to 0 so the pinned header reads as a full-width bar and only loses\n // its corners while it is actually moving with the scroll.\n border-top-left-radius: ", ";\n border-top-right-radius: ", ";\n background: ", ";\n // When the header is sticky AND the panel is minimal / transparent (opacity === 0), the\n // header has no surface of its own \u2014 scrolling content slides straight under it and the\n // label / actions become illegible. Apply a backdrop blur so the underlying content stays\n // visible but is softened enough for the header text to read clearly. Idle (no overflow,\n // nothing behind) the blur is a no-op so the static appearance is unchanged.\n ", "\n"])), function (_a) {
|
|
282
305
|
var padded = _a.padded, size = _a.size, isCollapsed = _a.isCollapsed, minimal = _a.minimal;
|
|
283
306
|
return !padded || isCollapsed || !minimal
|
|
284
307
|
? "".concat(getPaddingSize(padded, size), "px")
|
|
@@ -323,9 +346,9 @@ exports.StyledPanelTopBar = (0, styled_components_1.default)(exports.StyledPanel
|
|
|
323
346
|
}, function (_a) {
|
|
324
347
|
var stickyHeader = _a.stickyHeader, _b = _a.opacity, opacity = _b === void 0 ? 1 : _b;
|
|
325
348
|
return stickyHeader &&
|
|
326
|
-
opacity === 0 && (0, styled_components_1.css)(
|
|
349
|
+
opacity === 0 && (0, styled_components_1.css)(templateObject_26 || (templateObject_26 = __makeTemplateObject(["\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n "], ["\n backdrop-filter: blur(30px);\n -webkit-backdrop-filter: blur(30px);\n "])));
|
|
327
350
|
});
|
|
328
|
-
exports.StyledPanelBottomActions = (0, styled_components_1.default)(exports.StyledPanelTitle)(
|
|
351
|
+
exports.StyledPanelBottomActions = (0, styled_components_1.default)(exports.StyledPanelTitle)(templateObject_28 || (templateObject_28 = __makeTemplateObject(["\n padding-top: ", ";\n padding-bottom: ", ";\n border-bottom: 0;\n border-top: ", ";\n"], ["\n padding-top: ", ";\n padding-bottom: ", ";\n border-bottom: 0;\n border-top: ", ";\n"])), function (_a) {
|
|
329
352
|
var padded = _a.padded, size = _a.size, minimal = _a.minimal;
|
|
330
353
|
return !padded || !minimal
|
|
331
354
|
? "".concat(getPaddingSize(padded, size), "px")
|
|
@@ -345,7 +368,7 @@ exports.StyledPanelBottomActions = (0, styled_components_1.default)(exports.Styl
|
|
|
345
368
|
? "1px solid ".concat((0, polished_1.rgba)((0, colors_2.changeLightness)((0, colors_2.getMainBackgroundColor)(theme), 0.08), opacity))
|
|
346
369
|
: null;
|
|
347
370
|
});
|
|
348
|
-
exports.StyledPanelContent = styled_components_1.default.div(
|
|
371
|
+
exports.StyledPanelContent = styled_components_1.default.div(templateObject_29 || (templateObject_29 = __makeTemplateObject(["\n display: ", ";\n padding: ", ";\n flex: 1;\n /* A flex child's min-height defaults to its content size, so without this the\n scrollable content can't shrink: a panel/drawer body taller than the panel\n pushes the (flex: 0 0 auto) bottom-actions footer past the panel's clipped\n edge and strands it, instead of scrolling. */\n min-height: 0;\n overflow: auto;\n overflow-wrap: anywhere;\n font-size: ", "px;\n"], ["\n display: ", ";\n padding: ", ";\n flex: 1;\n /* A flex child's min-height defaults to its content size, so without this the\n scrollable content can't shrink: a panel/drawer body taller than the panel\n pushes the (flex: 0 0 auto) bottom-actions footer past the panel's clipped\n edge and strands it, instead of scrolling. */\n min-height: 0;\n overflow: auto;\n overflow-wrap: anywhere;\n font-size: ", "px;\n"])), function (_a) {
|
|
349
372
|
var isCollapsed = _a.isCollapsed;
|
|
350
373
|
return (isCollapsed ? 'none !important' : undefined);
|
|
351
374
|
}, function (_a) {
|
|
@@ -359,7 +382,7 @@ exports.StyledPanelContent = styled_components_1.default.div(templateObject_24 |
|
|
|
359
382
|
var size = _a.size;
|
|
360
383
|
return sizes_1.TEXT_FROM_SIZE[size];
|
|
361
384
|
});
|
|
362
|
-
exports.StyledFloatingActions = styled_components_1.default.div(
|
|
385
|
+
exports.StyledFloatingActions = styled_components_1.default.div(templateObject_30 || (templateObject_30 = __makeTemplateObject(["\n position: fixed;\n z-index: 999999;\n display: flex;\n padding: ", "px;\n background-color: ", ";\n border: ", ";\n border-bottom: none;\n border-radius: ", "px\n ", "px 0 0;\n gap: ", "px;\n pointer-events: auto;\n"], ["\n position: fixed;\n z-index: 999999;\n display: flex;\n padding: ", "px;\n background-color: ", ";\n border: ", ";\n border-bottom: none;\n border-radius: ", "px\n ", "px 0 0;\n gap: ", "px;\n pointer-events: auto;\n"])), function (_a) {
|
|
363
386
|
var size = _a.size;
|
|
364
387
|
return sizes_1.PADDING_FROM_SIZE[size];
|
|
365
388
|
}, function (_a) {
|
|
@@ -387,11 +410,12 @@ exports.ReqorePanelSkeleton = (0, react_2.memo)(function (_a) {
|
|
|
387
410
|
(children ? (children) : ((0, jsx_runtime_1.jsx)(ControlGroup_1.default, { vertical: true, children: (0, jsx_runtime_1.jsx)(Skeleton_1.ReqoreSkeleton, { lines: 5, width: '100%', size: 'tiny' }) })))] }));
|
|
388
411
|
});
|
|
389
412
|
exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
390
|
-
var
|
|
413
|
+
var _b, _c;
|
|
414
|
+
var children = _a.children, label = _a.label, description = _a.description, _d = _a.collapseButtonProps, collapseButtonProps = _d === void 0 ? {} : _d, collapsible = _a.collapsible, onClose = _a.onClose, _e = _a.closeButtonProps, closeButtonProps = _e === void 0 ? {} : _e, _f = _a.rounded, rounded = _f === void 0 ? true : _f, _g = _a.actions, actions = _g === void 0 ? [] : _g, _h = _a.bottomActions, bottomActions = _h === void 0 ? [] : _h, isCollapsed = _a.isCollapsed, customTheme = _a.customTheme, inheritCustomTheme = _a.inheritCustomTheme, icon = _a.icon, iconImage = _a.iconImage, _j = _a.iconWithLabel, iconWithLabel = _j === void 0 ? false : _j, _k = _a.iconVerticalAlign, iconVerticalAlign = _k === void 0 ? 'center' : _k, intent = _a.intent, className = _a.className, flat = _a.flat, _l = _a.unMountContentOnCollapse, unMountContentOnCollapse = _l === void 0 ? true : _l, onCollapseChange = _a.onCollapseChange, _m = _a.padded, padded = _m === void 0 ? true : _m, _o = _a.wrapperPadding, wrapperPadding = _o === void 0 ? 'both' : _o, contentStyle = _a.contentStyle, contentEffect = _a.contentEffect, _p = _a.labelEffect, labelEffect = _p === void 0 ? {} : _p, _q = _a.descriptionEffect, descriptionEffect = _q === void 0 ? {} : _q, descriptionIntent = _a.descriptionIntent, labelSize = _a.labelSize, contentSize = _a.contentSize, minimal = _a.minimal, badge = _a.badge, iconColor = _a.iconColor, _r = _a.iconProps, iconProps = _r === void 0 ? {} : _r, fluid = _a.fluid, _s = _a.responsiveActions, responsiveActions = _s === void 0 ? true : _s, _t = _a.responsiveTitle, responsiveTitle = _t === void 0 ? true : _t, _u = _a.compactTitle, compactTitle = _u === void 0 ? false : _u, _v = _a.fitLabel, fitLabel = _v === void 0 ? true : _v, _w = _a.labelMaxLines, labelMaxLines = _w === void 0 ? 2 : _w, _x = _a.descriptionPosition, descriptionPosition = _x === void 0 ? 'inline' : _x, _y = _a.descriptionMaxLines, descriptionMaxLines = _y === void 0 ? 2 : _y, labelMinTextSize = _a.labelMinTextSize, _z = _a.size, panelSize = _z === void 0 ? 'normal' : _z, getContentRef = _a.getContentRef, _0 = _a.labelProps, labelProps = _0 === void 0 ? {} : _0, disabled = _a.disabled, breadcrumbs = _a.breadcrumbs, _1 = _a.showActionsWhenCollapsed, showActionsWhenCollapsed = _1 === void 0 ? true : _1, showLabelTooltip = _a.showLabelTooltip, customLabelTooltip = _a.customLabelTooltip, resizable = _a.resizable, onLabelEdit = _a.onLabelEdit, responsiveActionsWrapperProps = _a.responsiveActionsWrapperProps, loading = _a.loading, loadingIconType = _a.loadingIconType, skeleton = _a.skeleton, errorBoundaryOptions = _a.errorBoundaryOptions, floatingActions = _a.floatingActions, _2 = _a.collapseTooltip, collapseTooltip = _2 === void 0 ? 'Collapse' : _2, _3 = _a.expandTooltip, expandTooltip = _3 === void 0 ? 'Expand' : _3, _4 = _a.closeTooltip, closeTooltip = _4 === void 0 ? 'Close' : _4, accentPosition = _a.accentPosition, accentSize = _a.accentSize, rest = __rest(_a, ["children", "label", "description", "collapseButtonProps", "collapsible", "onClose", "closeButtonProps", "rounded", "actions", "bottomActions", "isCollapsed", "customTheme", "inheritCustomTheme", "icon", "iconImage", "iconWithLabel", "iconVerticalAlign", "intent", "className", "flat", "unMountContentOnCollapse", "onCollapseChange", "padded", "wrapperPadding", "contentStyle", "contentEffect", "labelEffect", "descriptionEffect", "descriptionIntent", "labelSize", "contentSize", "minimal", "badge", "iconColor", "iconProps", "fluid", "responsiveActions", "responsiveTitle", "compactTitle", "fitLabel", "labelMaxLines", "descriptionPosition", "descriptionMaxLines", "labelMinTextSize", "size", "getContentRef", "labelProps", "disabled", "breadcrumbs", "showActionsWhenCollapsed", "showLabelTooltip", "customLabelTooltip", "resizable", "onLabelEdit", "responsiveActionsWrapperProps", "loading", "loadingIconType", "skeleton", "errorBoundaryOptions", "floatingActions", "collapseTooltip", "expandTooltip", "closeTooltip", "accentPosition", "accentSize"]);
|
|
391
415
|
// Resolved ONCE, here — the accent styles interpolate px and reserve padding,
|
|
392
416
|
// so they must only ever see a number. Shared with ReqoreCallout.
|
|
393
417
|
var accentSizePx = (0, react_2.useMemo)(function () { return (0, utils_1.resolveAccentSize)(accentSize); }, [accentSize]);
|
|
394
|
-
var
|
|
418
|
+
var _5 = (0, react_2.useState)(isCollapsed || false), _isCollapsed = _5[0], setIsCollapsed = _5[1];
|
|
395
419
|
var primaryContentGradient = (0, Effect_1.getPrimaryGradient)(contentEffect === null || contentEffect === void 0 ? void 0 : contentEffect.gradient);
|
|
396
420
|
var primaryContentColors = primaryContentGradient && typeof primaryContentGradient.colors === 'object'
|
|
397
421
|
? primaryContentGradient.colors
|
|
@@ -409,8 +433,8 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
409
433
|
}, []);
|
|
410
434
|
var isMobile = (0, useReqoreContext_1.useReqoreProperty)('isMobile');
|
|
411
435
|
var targetRef = (0, useCombinedRefs_1.useCombinedRefs)(ref).targetRef;
|
|
412
|
-
var
|
|
413
|
-
var
|
|
436
|
+
var _6 = (0, react_use_1.useMeasure)(), measureRef = _6[0], width = _6[1].width;
|
|
437
|
+
var _7 = (0, react_2.useState)(false), _isHovered = _7[0], setIsHovered = _7[1];
|
|
414
438
|
var floatingActionsRef = (0, react_2.useRef)(null);
|
|
415
439
|
var panelRef = (0, react_2.useRef)(null);
|
|
416
440
|
var hoverTimerRef = (0, react_2.useRef)(null);
|
|
@@ -428,8 +452,8 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
428
452
|
// triggers it. Only wired when `stickyHeader` is on, so ordinary panels pay
|
|
429
453
|
// nothing.
|
|
430
454
|
var stickySentinelRef = (0, react_2.useRef)(null);
|
|
431
|
-
var
|
|
432
|
-
var
|
|
455
|
+
var _8 = (0, react_2.useState)(false), isHeaderStuck = _8[0], setIsHeaderStuck = _8[1];
|
|
456
|
+
var _9 = (0, react_2.useState)(0), stickyInset = _9[0], setStickyInset = _9[1];
|
|
433
457
|
(0, react_2.useEffect)(function () {
|
|
434
458
|
var _a;
|
|
435
459
|
if (!rest.stickyHeader) {
|
|
@@ -578,7 +602,49 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
578
602
|
}, [label, collapsible, onClose, nonFloatingActions, badge, icon]);
|
|
579
603
|
// Return true if the card has a title bar, otherwise return false.
|
|
580
604
|
var hasTitleHeader = (0, react_2.useMemo)(function () { return !!label || !!badge || !!icon || !!breadcrumbs; }, [label, icon, badge, breadcrumbs]);
|
|
581
|
-
|
|
605
|
+
/**
|
|
606
|
+
* `width` comes from `useMeasure`, which reports 0 until the element is actually measured —
|
|
607
|
+
* and in jsdom it stays 0 forever. `0 < 480` is true, so an unmeasured panel used to claim it
|
|
608
|
+
* was narrow; the guard against that was `NODE_ENV !== 'test'`, added in 4eb8ac1 ("Test
|
|
609
|
+
* fixes") back when the suite was jsdom-only.
|
|
610
|
+
*
|
|
611
|
+
* That proxy stopped holding when snapshots moved to a real browser under vitest: same
|
|
612
|
+
* NODE_ENV, real widths, and the narrow layout switched off in the one place it needed to be
|
|
613
|
+
* on. No snapshot has ever shown a stacked title bar, which is why the stack going three rows
|
|
614
|
+
* deep on a drawer went unnoticed for so long (#664).
|
|
615
|
+
*
|
|
616
|
+
* Asking whether the width was MEASURED says what the guard always meant. jsdom keeps its 0
|
|
617
|
+
* and stays wide, so the unit suite is unaffected; a browser measures and behaves.
|
|
618
|
+
*/
|
|
619
|
+
var isSmall = (0, react_2.useMemo)(function () { return responsiveTitle && width > 0 && width < 480; }, [width, responsiveTitle]);
|
|
620
|
+
/**
|
|
621
|
+
* Narrow, from either trigger: the panel measuring under 480px, or the provider's
|
|
622
|
+
* viewport-level `isMobile`.
|
|
623
|
+
*
|
|
624
|
+
* A narrow title bar STAYS ON ONE ROW. The label ellipsizes (it already carries `noWrap`) and
|
|
625
|
+
* the responsive action group collapses into its overflow, which is what the "hidden when
|
|
626
|
+
* small" actions exist for. It used to stack instead — title on one row, actions on another,
|
|
627
|
+
* close/collapse on a third — and that cost more room than the title ever took: measured on a
|
|
628
|
+
* drawer at 375px, a 93px header for a title using 204px of the width, with a 359px action
|
|
629
|
+
* group holding a 106px button and 261px of nothing beside it.
|
|
630
|
+
*
|
|
631
|
+
* Stacking also broke the collapse it was supposed to help. Going to a column made the action
|
|
632
|
+
* group `fluid`, the group got a full-width row, and with that much space its own measurement
|
|
633
|
+
* decided fewer actions needed collapsing — so an action labelled "hidden when small" rendered
|
|
634
|
+
* in full on a small panel.
|
|
635
|
+
*/
|
|
636
|
+
var isNarrow = isSmall || isMobile;
|
|
637
|
+
/**
|
|
638
|
+
* The tightest fallback, still opt-in: drop the title TEXT and leave the icon in its place.
|
|
639
|
+
* For a bar too narrow even to ellipsize into — a `[icon] [actions] [×]` header. Nothing
|
|
640
|
+
* changes without an icon to fall back to, and the label survives as that icon's tooltip.
|
|
641
|
+
*/
|
|
642
|
+
/**
|
|
643
|
+
* The title gives up its space entirely and the icon stands in. Opt-in only: the automatic
|
|
644
|
+
* end of the cascade is the ellipsis, and dropping the title is a decision the caller makes,
|
|
645
|
+
* not something a width should take on their behalf. Needs an icon to fall back to.
|
|
646
|
+
*/
|
|
647
|
+
var hideTitleForIcon = isNarrow && compactTitle;
|
|
582
648
|
// If collapsible is true, toggle the isCollapsed state
|
|
583
649
|
// If the isCollapsed state is true, the component is expanded
|
|
584
650
|
// If the isCollapsed state is false, the component is collapsed
|
|
@@ -607,10 +673,23 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
607
673
|
return function (action, index) {
|
|
608
674
|
return renderActions(action, index, true, align);
|
|
609
675
|
};
|
|
610
|
-
},
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
676
|
+
},
|
|
677
|
+
// `isNarrow` belongs here even though this callback does not name it: it wraps
|
|
678
|
+
// `renderActions`, which does. Without it the wrapper keeps whichever `renderActions`
|
|
679
|
+
// existed on the first render — when `useMeasure` still reported 0 and the bar did not
|
|
680
|
+
// yet know it was narrow — so a width-dependent decision inside it could never take
|
|
681
|
+
// effect. That is what silently defeated dropping the action labels: the flag flipped and
|
|
682
|
+
// the closure did not. (`renderActions` itself cannot go here: it is declared below.)
|
|
683
|
+
[isNarrow, actions, showActionsWhenCollapsed, _isCollapsed]);
|
|
684
|
+
var hasNonResponsiveActions = (0, react_2.useCallback)(
|
|
685
|
+
// `show: false` has to be honoured on BOTH paths. The `responsiveActions: false` arm used
|
|
686
|
+
// to ask only whether the array had entries, so a panel whose every action is hidden still
|
|
687
|
+
// reported having some and rendered an empty control group. It went unnoticed while the
|
|
688
|
+
// prop defaulted to `true` and that arm was mostly dead.
|
|
689
|
+
function (data) {
|
|
690
|
+
return data.some(function (action) {
|
|
691
|
+
return (!responsiveActions || action.responsive === false) && action.show !== false;
|
|
692
|
+
});
|
|
614
693
|
}, [actions, bottomActions, responsiveActions, showActionsWhenCollapsed, _isCollapsed]);
|
|
615
694
|
var hasResponsiveActions = (0, react_2.useCallback)(function (data) {
|
|
616
695
|
return responsiveActions &&
|
|
@@ -621,7 +700,14 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
621
700
|
return function (action, index) {
|
|
622
701
|
return renderActions(action, index, false, align);
|
|
623
702
|
};
|
|
624
|
-
}, [
|
|
703
|
+
}, [
|
|
704
|
+
isNarrow,
|
|
705
|
+
actions,
|
|
706
|
+
bottomActions,
|
|
707
|
+
responsiveActions,
|
|
708
|
+
showActionsWhenCollapsed,
|
|
709
|
+
_isCollapsed,
|
|
710
|
+
]);
|
|
625
711
|
var renderActions = (0, react_2.useCallback)(function (action, index, includeResponsive, align) {
|
|
626
712
|
if (align === void 0) { align = 'flex-end'; }
|
|
627
713
|
if (action.show === false ||
|
|
@@ -651,14 +737,23 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
651
737
|
}
|
|
652
738
|
: undefined })));
|
|
653
739
|
}
|
|
654
|
-
|
|
740
|
+
// FIRST thing to go when the bar is short of room: the action's LABEL, not the
|
|
741
|
+
// panel's title. An action is a verb the icon already carries, and the label moves
|
|
742
|
+
// to the tooltip rather than being lost; the title is the only thing naming what
|
|
743
|
+
// this panel IS. Needs an icon to fall back to — an unlabelled, iconless button is
|
|
744
|
+
// a blank box — and a caller can pin the label with `responsive: false`.
|
|
745
|
+
// `label` on an action is typed `string | number`; a tooltip is not, so the numeric
|
|
746
|
+
// case is stringified rather than cast away.
|
|
747
|
+
var actionLabelTooltip = typeof label === 'number' ? String(label) : label;
|
|
748
|
+
var dropActionLabel = isNarrow && !!rest.icon && !!label;
|
|
749
|
+
return ((0, react_1.createElement)(Button_1.default, __assign({ fixed: true }, rest, { id: id, key: index, className: className, customTheme: rest.customTheme || theme, intent: intent, tooltip: dropActionLabel ? rest.tooltip || actionLabelTooltip : rest.tooltip, onClick: rest.onClick
|
|
655
750
|
? function (e) {
|
|
656
751
|
var _a;
|
|
657
752
|
e.stopPropagation();
|
|
658
753
|
(_a = rest.onClick) === null || _a === void 0 ? void 0 : _a.call(rest);
|
|
659
754
|
}
|
|
660
|
-
: undefined }), label));
|
|
661
|
-
}, [actions, theme, showActionsWhenCollapsed, _isCollapsed]);
|
|
755
|
+
: undefined }), dropActionLabel ? undefined : label));
|
|
756
|
+
}, [actions, theme, showActionsWhenCollapsed, _isCollapsed, isNarrow]);
|
|
662
757
|
var interactive = !!(rest.onClick ||
|
|
663
758
|
rest.onMouseOver ||
|
|
664
759
|
rest.onMouseEnter ||
|
|
@@ -679,9 +774,10 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
679
774
|
var showNonResponsiveGroup = (0, react_2.useCallback)(function () {
|
|
680
775
|
var show = false;
|
|
681
776
|
// SHOULD THIS GROUP SHOW CONTROL BUTTONS?
|
|
682
|
-
//
|
|
683
|
-
//
|
|
684
|
-
|
|
777
|
+
// Always, now that a narrow bar stays on one row: there is no separate control row for them
|
|
778
|
+
// to move to. This used to read `!isSmall`, which withheld them here because a small panel
|
|
779
|
+
// rendered its own row below — and that row is what the one-row treatment removed.
|
|
780
|
+
if (onClose || collapsible) {
|
|
685
781
|
show = true;
|
|
686
782
|
}
|
|
687
783
|
// OTHERWISE, ARE THERE ANY NON RESPONSIVE ACTIONS TO BE SHOWN?
|
|
@@ -691,7 +787,139 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
691
787
|
show = true;
|
|
692
788
|
}
|
|
693
789
|
return show;
|
|
694
|
-
}, [
|
|
790
|
+
}, [collapsible, onClose, nonFloatingActions, hasNonResponsiveActions]);
|
|
791
|
+
/**
|
|
792
|
+
* The title's natural size in px, from the heading level it renders at — the same
|
|
793
|
+
* `labelSize || HEADER_SIZE_TO_NUMBER[panelSize]` the icon is sized from.
|
|
794
|
+
*/
|
|
795
|
+
var labelNaturalPx = (_b = sizes_1.HEADER_LEVEL_TO_PX[labelSize || sizes_1.HEADER_SIZE_TO_NUMBER[panelSize]]) !== null && _b !== void 0 ? _b : sizes_1.HEADER_LEVEL_TO_PX[3];
|
|
796
|
+
/**
|
|
797
|
+
* SECOND thing to give: the title's size. Once the actions are down to icons and the
|
|
798
|
+
* row is still short, the title shrinks toward a floor rather than dropping characters
|
|
799
|
+
* — the end of a name is often the part that distinguishes it. Only at the floor does
|
|
800
|
+
* the existing `noWrap` ellipsis take over.
|
|
801
|
+
*
|
|
802
|
+
* Off when the caller pins `labelEffect.textSize`: they have said what size they want.
|
|
803
|
+
*/
|
|
804
|
+
/**
|
|
805
|
+
* The width the layout left for the title, observed on the box that claims the leftover
|
|
806
|
+
* space. Kept as state rather than read during render so the fit is calculated from a width
|
|
807
|
+
* that has actually been laid out.
|
|
808
|
+
*/
|
|
809
|
+
/** Whole lines, at least one — a fractional or zero `labelMaxLines` is a caller slip, not
|
|
810
|
+
* a request for half a line of text. */
|
|
811
|
+
var clampLines = Math.max(1, Math.floor(labelMaxLines) || 1);
|
|
812
|
+
/** `compactTitle` drops the description with the title it belongs to, so a bar that has
|
|
813
|
+
* given up its title never grows a row to carry one. */
|
|
814
|
+
var descriptionBelow = descriptionPosition === 'below' && !!description && !(hideTitleForIcon && !!icon);
|
|
815
|
+
var descriptionClamp = Math.max(0, Math.floor(descriptionMaxLines || 0));
|
|
816
|
+
/**
|
|
817
|
+
* A clamped description opens on click so the whole of it can be read — on a phone there is
|
|
818
|
+
* no hover to reveal it with, and two lines of a long sentence are an invitation to tap.
|
|
819
|
+
*
|
|
820
|
+
* Interactive only while it is actually cut, or already open: a description that fits is
|
|
821
|
+
* left alone, so a click on it still reaches the bar and collapses a collapsible panel the
|
|
822
|
+
* way it always has. When it IS cut, that same click must not reach the bar — opening the
|
|
823
|
+
* text and folding the panel away in one gesture is the worst of both.
|
|
824
|
+
*/
|
|
825
|
+
var _10 = (0, react_2.useState)(false), isDescriptionExpanded = _10[0], setIsDescriptionExpanded = _10[1];
|
|
826
|
+
var _11 = (0, react_2.useState)(false), isDescriptionTruncated = _11[0], setIsDescriptionTruncated = _11[1];
|
|
827
|
+
var descriptionRef = (0, react_2.useRef)(null);
|
|
828
|
+
var descriptionIsClamped = descriptionClamp > 0 && !isDescriptionExpanded;
|
|
829
|
+
(0, react_2.useLayoutEffect)(function () {
|
|
830
|
+
var el = descriptionRef.current;
|
|
831
|
+
// `scrollHeight` is what the text wants, `clientHeight` what the clamp left it. Re-read
|
|
832
|
+
// whenever the bar's width moves, because that is what changes how many lines it takes.
|
|
833
|
+
setIsDescriptionTruncated(descriptionIsClamped && !!el && el.scrollHeight > el.clientHeight + 1);
|
|
834
|
+
}, [description, descriptionIsClamped, width]);
|
|
835
|
+
var descriptionIsInteractive = isDescriptionTruncated || isDescriptionExpanded;
|
|
836
|
+
var handleDescriptionClick = (0, react_2.useCallback)(function (event) {
|
|
837
|
+
if (!descriptionIsInteractive) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
event.stopPropagation();
|
|
841
|
+
setIsDescriptionExpanded(function (expanded) { return !expanded; });
|
|
842
|
+
}, [descriptionIsInteractive]);
|
|
843
|
+
/** Shared by both places the description can render — inline with the title, or on its
|
|
844
|
+
* own row below — so the two cannot drift apart. */
|
|
845
|
+
var descriptionProps = __assign({ ref: descriptionRef, className: 'reqore-panel-title-description', size: panelSize, effect: __assign({ opacity: 0.7 }, descriptionEffect), intent: descriptionIntent, onClick: handleDescriptionClick }, (descriptionIsInteractive
|
|
846
|
+
? {
|
|
847
|
+
role: 'button',
|
|
848
|
+
tabIndex: 0,
|
|
849
|
+
'aria-expanded': isDescriptionExpanded,
|
|
850
|
+
onKeyDown: function (event) {
|
|
851
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
852
|
+
event.preventDefault();
|
|
853
|
+
handleDescriptionClick(event);
|
|
854
|
+
}
|
|
855
|
+
},
|
|
856
|
+
style: { cursor: 'pointer' },
|
|
857
|
+
}
|
|
858
|
+
: {}));
|
|
859
|
+
var _12 = (0, react_2.useState)(undefined), labelAvailable = _12[0], setLabelAvailable = _12[1];
|
|
860
|
+
var _13 = (0, useFitTextSize_1.useFitTextSize)({
|
|
861
|
+
text: typeof label === 'string' ? label : '',
|
|
862
|
+
available: labelAvailable,
|
|
863
|
+
max: labelNaturalPx,
|
|
864
|
+
min: labelMinTextSize,
|
|
865
|
+
lines: clampLines,
|
|
866
|
+
enabled: fitLabel !== false && typeof label === 'string' && !(labelEffect === null || labelEffect === void 0 ? void 0 : labelEffect.textSize),
|
|
867
|
+
}), labelFitRef = _13[0], labelFitPx = _13[1];
|
|
868
|
+
/** Only while the title is actually below its natural size, and never over a caller who
|
|
869
|
+
* pinned the description's own size. */
|
|
870
|
+
var descriptionFontPx = fitLabel && !(descriptionEffect === null || descriptionEffect === void 0 ? void 0 : descriptionEffect.textSize) && labelFitPx < labelNaturalPx
|
|
871
|
+
? Math.max(useFitTextSize_1.FIT_TEXT_FLOOR_PX, Math.round(((_c = sizes_1.TEXT_FROM_SIZE[panelSize]) !== null && _c !== void 0 ? _c : sizes_1.TEXT_FROM_SIZE.normal) * (labelFitPx / labelNaturalPx)))
|
|
872
|
+
: 0;
|
|
873
|
+
/**
|
|
874
|
+
* How much room the title has, computed rather than measured off its own box.
|
|
875
|
+
*
|
|
876
|
+
* The box the title sits in is sized by its content, so measuring THAT is circular — the
|
|
877
|
+
* font shrinks, the box shrinks, and the size ratchets to the floor. Measuring the space it
|
|
878
|
+
* COULD have is not: take the bar, subtract everything competing with the title, and what
|
|
879
|
+
* is left does not move when the title's font does.
|
|
880
|
+
*
|
|
881
|
+
* Everything competing with it is text-independent: the action groups and control buttons
|
|
882
|
+
* (the bar's other children), and the icon and badge that share the title's row. The action
|
|
883
|
+
* group is `fluid` by default and would otherwise swallow the leftover, which is why this
|
|
884
|
+
* cannot be solved by giving the title column `flex-grow` — it competes with a group that
|
|
885
|
+
* is designed to take the rest, and loses.
|
|
886
|
+
*
|
|
887
|
+
* Re-run on `width`, which is the bar's own measured width: when the bar resizes, so does
|
|
888
|
+
* everything in it.
|
|
889
|
+
*/
|
|
890
|
+
/**
|
|
891
|
+
* The title's available width is its CONTAINING BLOCK minus whatever shares it — measured,
|
|
892
|
+
* not reconstructed.
|
|
893
|
+
*
|
|
894
|
+
* This used to subtract the action group, the gaps and the icon from the bar's width. That
|
|
895
|
+
* arithmetic held only for the one layout it was written against: give the panel a
|
|
896
|
+
* `description` and the icon moves into an outer grid, so the sum over-reported by 30-80px
|
|
897
|
+
* and the fit under-shrank. The symptom was the worst of both worlds — a title both smaller
|
|
898
|
+
* AND ellipsized, which is the one outcome the feature exists to avoid.
|
|
899
|
+
*
|
|
900
|
+
* Measuring the parent is safe precisely where it looks circular. While the text overflows
|
|
901
|
+
* — the only regime in which anything shrinks — the parent is pinned by the row, not by the
|
|
902
|
+
* text: at a 300px bar it measures 128px at 19px, at 16px, and wrapped to two lines. When
|
|
903
|
+
* the text does fit, the parent has slack and the fit returns the natural size, which is
|
|
904
|
+
* the right answer either way.
|
|
905
|
+
*/
|
|
906
|
+
(0, react_2.useLayoutEffect)(function () {
|
|
907
|
+
var node = labelFitRef.current;
|
|
908
|
+
var parent = node === null || node === void 0 ? void 0 : node.parentElement;
|
|
909
|
+
if (!fitLabel || !node || !parent) {
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
var style = getComputedStyle(parent);
|
|
913
|
+
var padding = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);
|
|
914
|
+
var gap = parseFloat(style.columnGap) || parseFloat(style.gap) || 0;
|
|
915
|
+
// A badge sits beside the title in the same box and takes real width.
|
|
916
|
+
var siblings = Array.from(parent.children).reduce(function (total, child) {
|
|
917
|
+
return child === node ? total : total + child.getBoundingClientRect().width;
|
|
918
|
+
}, 0);
|
|
919
|
+
var gaps = gap * Math.max(0, parent.children.length - 1);
|
|
920
|
+
var next = Math.max(0, Math.round(parent.clientWidth - padding - siblings - gaps));
|
|
921
|
+
setLabelAvailable(function (current) { return (current === next ? current : next); });
|
|
922
|
+
}, [fitLabel, label, width, badge, actions, panelSize, description, clampLines]);
|
|
695
923
|
var iconTooltip = (0, react_2.useMemo)(function () { return ({
|
|
696
924
|
content: label,
|
|
697
925
|
}); }, [label]);
|
|
@@ -710,8 +938,13 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
710
938
|
panelRef.current = node;
|
|
711
939
|
}, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [rest.stickyHeader ? ((0, jsx_runtime_1.jsx)("div", { ref: stickySentinelRef, "aria-hidden": 'true', style: { height: 0 } })) : null, _isHovered &&
|
|
712
940
|
(0, lodash_1.size)(floatingActionsList) > 0 &&
|
|
713
|
-
(0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(exports.StyledFloatingActions, { className: 'reqore-panel-floating-actions', theme: theme, size: panelSize, intent: intent, flat: flat, ref: floatingActionsRef, onMouseLeave: handleFloatingActionsMouseLeave, children: (0, jsx_runtime_1.jsx)(ControlGroup_1.default, { size: panelSize, gapSize: panelSize, children: floatingActionsList.map(function (action, index) { return renderActions(action, index, true); }) }) }), document.body), hasTitleBar && ((0, jsx_runtime_1.jsxs)(exports.StyledPanelTopBar, { flat: flat, isCollapsed: _isCollapsed, collapsible: collapsible, className: 'reqore-panel-title', onClick: handleCollapseClick, theme: theme, minimal: minimal || opacity === 0, size: contentSize || panelSize, opacity: minimal ? 0 : opacity !== null && opacity !== void 0 ? opacity : 1, noHorizontalPadding: noHorizontalPadding, responsive: responsiveTitle,
|
|
941
|
+
(0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(exports.StyledFloatingActions, { className: 'reqore-panel-floating-actions', theme: theme, size: panelSize, intent: intent, flat: flat, ref: floatingActionsRef, onMouseLeave: handleFloatingActionsMouseLeave, children: (0, jsx_runtime_1.jsx)(ControlGroup_1.default, { size: panelSize, gapSize: panelSize, children: floatingActionsList.map(function (action, index) { return renderActions(action, index, true); }) }) }), document.body), hasTitleBar && ((0, jsx_runtime_1.jsxs)(exports.StyledPanelTopBar, { flat: flat, isCollapsed: _isCollapsed, collapsible: collapsible, className: 'reqore-panel-title', onClick: handleCollapseClick, theme: theme, minimal: minimal || opacity === 0, size: contentSize || panelSize, opacity: minimal ? 0 : opacity !== null && opacity !== void 0 ? opacity : 1, noHorizontalPadding: noHorizontalPadding, responsive: responsiveTitle, "$descriptionBelow": descriptionBelow, "$descriptionMaxLines": descriptionIsClamped ? descriptionClamp : 0, "$descriptionFontPx": descriptionFontPx, "data-narrow": isNarrow ? 'true' : 'false', ref: measureRef, padded: padded, wrapperPadding: wrapperPadding, intent: intent, rounded: rounded, radiusSize: rest.radiusSize, stickyHeader: rest.stickyHeader, stickyHeaderOffset: rest.stickyHeaderOffset, stickyHeaderInset: stickyInset, isStuck: isHeaderStuck, children: [hasTitleHeader && ((0, jsx_runtime_1.jsxs)(exports.StyledPanelTitleHeader, { className: 'reqore-panel-title-header', children: [breadcrumbs ? ((0, jsx_runtime_1.jsx)(Breadcrumbs_1.default, __assign({}, breadcrumbs, { padded: false, margin: 'none', flat: true, responsive: true }))) : icon || iconImage || label || badge ? ((function () {
|
|
714
942
|
var hasPanelIcon = !!icon || !!iconImage || loading;
|
|
943
|
+
// The icon takes the label's place, so there has to BE an icon. Without one
|
|
944
|
+
// the label is the only thing identifying the panel and it stays put — a
|
|
945
|
+
// header with neither is not a compact header, it is an empty one. The label
|
|
946
|
+
// is not lost either way: it is already this icon's tooltip.
|
|
947
|
+
var hideTitleText = hideTitleForIcon && hasPanelIcon;
|
|
715
948
|
// Layout decision:
|
|
716
949
|
// - iconWithLabel=true → render the icon INSIDE the
|
|
717
950
|
// label-and-badge row (no outer icon column). The
|
|
@@ -727,7 +960,7 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
727
960
|
// the icon in row 1 (label), row 2 (description), or
|
|
728
961
|
// spans both rows (center). The description always
|
|
729
962
|
// indents past the icon column.
|
|
730
|
-
var inlineWithLabel = hasPanelIcon && (iconWithLabel || !description);
|
|
963
|
+
var inlineWithLabel = hasPanelIcon && (iconWithLabel || !description || hideTitleText);
|
|
731
964
|
var useOuterGrid = hasPanelIcon && !inlineWithLabel;
|
|
732
965
|
// Outer grid → grid column-gap handles icon→label
|
|
733
966
|
// spacing, so the icon itself takes no margin.
|
|
@@ -737,11 +970,28 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
737
970
|
var panelIcon = hasPanelIcon ? ((0, jsx_runtime_1.jsx)(Icon_1.default, __assign({ size: "".concat(sizes_1.ICON_FROM_HEADER_SIZE[labelSize || sizes_1.HEADER_SIZE_TO_NUMBER[panelSize]], "px"), image: loading ? undefined : iconImage, margin: iconMargin, color: iconColor, tooltip: iconTooltip, effect: {
|
|
738
971
|
opacity: colors_1.CONTROL_ICON_OPACITY,
|
|
739
972
|
} }, iconProps, { animation: loading ? 'spin' : iconProps === null || iconProps === void 0 ? void 0 : iconProps.animation, icon: loading ? "Loader".concat(loadingIconType || '', "Line") : icon || (iconProps === null || iconProps === void 0 ? void 0 : iconProps.icon), className: "reqore-panel-title-icon ".concat((iconProps === null || iconProps === void 0 ? void 0 : iconProps.className) || '').trim() }))) : null;
|
|
740
|
-
var labelRow = ((0, jsx_runtime_1.jsxs)(exports.StyledPanelTitleHeaderLabelAndBadge, { className: 'reqore-panel-title-label-row', children: [inlineWithLabel && panelIcon, typeof label === 'string' ? (
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
973
|
+
var labelRow = ((0, jsx_runtime_1.jsxs)(exports.StyledPanelTitleHeaderLabelAndBadge, { className: 'reqore-panel-title-label-row', children: [inlineWithLabel && panelIcon, hideTitleText ? null : typeof label === 'string' ? (
|
|
974
|
+
// The measured box is this wrapper, not the heading: as a
|
|
975
|
+
// `min-width: 0` flex child it reports the width the row actually
|
|
976
|
+
// left for the title, where the heading would report what the text
|
|
977
|
+
// wants. `overflow: hidden` is what makes it shrinkable at all.
|
|
978
|
+
// `display: flex` keeps the wrapper from opening a line box around
|
|
979
|
+
// the inline-flex heading: a block wrapper adds the row's leading on
|
|
980
|
+
// top of the heading's own box, which made a `tiny` panel 3px taller
|
|
981
|
+
// than it was before this wrapper existed.
|
|
982
|
+
(0, jsx_runtime_1.jsx)(StyledPanelTitleLabelBox, { ref: labelFitRef, className: 'reqore-panel-title-label-box', "$clampLines": clampLines, children: (0, jsx_runtime_1.jsx)(LabelEditor_1.LabelEditor, { size: labelSize || panelSize, customTheme: theme, effect: __assign({
|
|
983
|
+
// `noWrap` pins the heading to one line; a clamped title is
|
|
984
|
+
// allowed to wrap, and the clamp brings its own ellipsis.
|
|
985
|
+
noWrap: clampLines === 1 }, labelEffect), style: __assign(__assign(__assign({}, (clampLines > 1
|
|
986
|
+
? {}
|
|
987
|
+
: { display: 'inline-flex', alignItems: 'center' })), { minWidth: 0,
|
|
988
|
+
// Capped to the measured wrapper so the heading's own
|
|
989
|
+
// `text-overflow: ellipsis` (from `noWrap`) has a box to overflow.
|
|
990
|
+
// An `inline-flex` heading otherwise sizes to its text, and the
|
|
991
|
+
// wrapper clips it mid-word with no ellipsis at all.
|
|
992
|
+
maxWidth: '100%' }), (fitLabel !== false && !(labelEffect === null || labelEffect === void 0 ? void 0 : labelEffect.textSize)
|
|
993
|
+
? { fontSize: "".concat(labelFitPx, "px") }
|
|
994
|
+
: {})), label: label, onSubmit: onLabelEdit, tooltip: showLabelTooltip ? customLabelTooltip || label : undefined }) })) : (label), badge || badge === 0 ? ((0, jsx_runtime_1.jsx)(Button_1.ButtonBadge, { size: (0, utils_1.getOneHigherSize)(panelSize), content: badge, wrapGroup: isSmall, margin: label ? 'left' : 'none' })) : null] }));
|
|
745
995
|
// Description size is driven by the panel size only —
|
|
746
996
|
// explicitly NOT by `labelSize`. `NUMBER_TO_SIZE` maps
|
|
747
997
|
// 1..6 → micro..huge, which means bumping `labelSize`
|
|
@@ -750,9 +1000,55 @@ exports.ReqorePanel = (0, react_2.forwardRef)(function (_a, ref) {
|
|
|
750
1000
|
// pairing: a bigger label should not make supporting
|
|
751
1001
|
// text smaller. Consumers that want to size the
|
|
752
1002
|
// description explicitly pass `descriptionEffect.textSize`.
|
|
753
|
-
var descriptionRow = description ? ((0, jsx_runtime_1.jsx)(Span_1.ReqoreSpan,
|
|
754
|
-
return ((0, jsx_runtime_1.jsx)(exports.StyledPanelTitleHeaderContent, __assign({ size: panelSize }, labelProps, { hasLabel: !!label, hasIcon: useOuterGrid, iconSize: sizes_1.ICON_FROM_HEADER_SIZE[labelSize || sizes_1.HEADER_SIZE_TO_NUMBER[panelSize]], "$hasOuterIcon": useOuterGrid, "$iconVerticalAlign": iconVerticalAlign, "$hasDescription": !!description, children: useOuterGrid ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [panelIcon, labelRow, descriptionRow] })) : ((0, jsx_runtime_1.jsxs)(exports.StyledPanelTitleHeaderLabelAndDescription, { children: [labelRow, descriptionRow] })) })));
|
|
755
|
-
})()) : null, breadcrumbs && (badge || badge === 0) ? ((0, jsx_runtime_1.jsx)(Button_1.ButtonBadge, { size: (0, utils_1.getOneHigherSize)(panelSize), content: badge, wrapGroup: isSmall, margin: label ? 'left' : 'none' })) : null, (0, jsx_runtime_1.jsx)(NonResponsiveActions_1.ReqorePanelNonResponsiveActions
|
|
1003
|
+
var descriptionRow = description && !hideTitleText && !descriptionBelow ? ((0, jsx_runtime_1.jsx)(Span_1.ReqoreSpan, __assign({}, descriptionProps, { children: description }))) : null;
|
|
1004
|
+
return ((0, jsx_runtime_1.jsx)(exports.StyledPanelTitleHeaderContent, __assign({ size: panelSize }, labelProps, { hasLabel: !!label && !hideTitleText, hasIcon: useOuterGrid, iconSize: sizes_1.ICON_FROM_HEADER_SIZE[labelSize || sizes_1.HEADER_SIZE_TO_NUMBER[panelSize]], "$hasOuterIcon": useOuterGrid, "$iconVerticalAlign": iconVerticalAlign, "$hasDescription": !!description && !hideTitleText, children: useOuterGrid ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [panelIcon, labelRow, descriptionRow] })) : ((0, jsx_runtime_1.jsxs)(exports.StyledPanelTitleHeaderLabelAndDescription, { children: [labelRow, descriptionRow] })) })));
|
|
1005
|
+
})()) : null, breadcrumbs && (badge || badge === 0) ? ((0, jsx_runtime_1.jsx)(Button_1.ButtonBadge, { size: (0, utils_1.getOneHigherSize)(panelSize), content: badge, wrapGroup: isSmall, margin: label ? 'left' : 'none' })) : null, (0, jsx_runtime_1.jsx)(NonResponsiveActions_1.ReqorePanelNonResponsiveActions
|
|
1006
|
+
// The narrow bar keeps its controls in the trailing group, so this row —
|
|
1007
|
+
// which existed only for the stacked layout — never shows.
|
|
1008
|
+
, {
|
|
1009
|
+
// The narrow bar keeps its controls in the trailing group, so this row —
|
|
1010
|
+
// which existed only for the stacked layout — never shows.
|
|
1011
|
+
show: false, isSmall: false, showControlButtons: true, size: panelSize, hasResponsiveActions: hasResponsiveActions(nonFloatingActions), customTheme: theme, isCollapsed: _isCollapsed, onCollapseClick: collapsible ? handleCollapseClick : undefined, onCloseClick: onClose, closeButtonProps: closeButtonProps, collapseButtonProps: collapseButtonProps, collapseTooltip: collapseTooltip, expandTooltip: expandTooltip, closeTooltip: closeTooltip, fluid: false, style: { marginLeft: 'auto' } })] })), hasResponsiveActions(nonFloatingActions) && ((0, jsx_runtime_1.jsx)(ControlGroup_1.default, __assign({ responsive: responsiveActions,
|
|
1012
|
+
// Not fluid by default. `fluid` emits `width: 100%`, so the group's flex basis
|
|
1013
|
+
// becomes the whole bar and the title — the only shrinkable thing on the other
|
|
1014
|
+
// side — collapses to nothing: measured at 0px of title on a 400px panel, and
|
|
1015
|
+
// 142px of a 518px bar where the buttons needed 90.
|
|
1016
|
+
//
|
|
1017
|
+
// A caller whose actions include something with no useful width of its own —
|
|
1018
|
+
// Collection puts a search input in here — opts back in through
|
|
1019
|
+
// `responsiveActionsWrapperProps`, because `fluid` is also what ControlGroup
|
|
1020
|
+
// propagates to its children, and that input has nothing to fill without it.
|
|
1021
|
+
fluid: false, horizontalAlign: 'flex-end', customTheme: theme, size: panelSize }, responsiveActionsWrapperProps, {
|
|
1022
|
+
// The cap is the whole fix. Half the bar guarantees the title the other half,
|
|
1023
|
+
// and the moment the buttons need more than their share the group overflows —
|
|
1024
|
+
// which is what `responsive` collapse watches (`scrollWidth > clientWidth`), so
|
|
1025
|
+
// the fold into the `…` menu still fires. Floored at 40px because shrinking to
|
|
1026
|
+
// nothing clips the buttons rather than folding them, and ControlGroup ignores
|
|
1027
|
+
// its own overflow below that width, which would strand them clipped.
|
|
1028
|
+
style: __assign({
|
|
1029
|
+
// Pushed to the trailing edge. A `fluid` group used to span the bar and its
|
|
1030
|
+
// own `horizontalAlign` put the buttons on the right; a content-sized one is
|
|
1031
|
+
// only as wide as its buttons, so with no title header beside it — Tree has
|
|
1032
|
+
// no label — it would sit at the LEFT of an otherwise empty bar. `auto`
|
|
1033
|
+
// margin restores the edge without giving the group any width back.
|
|
1034
|
+
marginLeft: 'auto',
|
|
1035
|
+
// Content basis that may still shrink. `fluid={false}` alone compiles to
|
|
1036
|
+
// `flex: 0 0 auto`, which pins the group at its content width so it can never
|
|
1037
|
+
// overflow — and `responsive` collapse watches `scrollWidth > clientWidth`,
|
|
1038
|
+
// so the fold into the `…` menu would simply stop happening.
|
|
1039
|
+
flex: '0 1 auto',
|
|
1040
|
+
// Floored, because shrinking to nothing clips the buttons instead of folding
|
|
1041
|
+
// them, and ControlGroup ignores its own overflow below 40px.
|
|
1042
|
+
minWidth: 40,
|
|
1043
|
+
// Capped, so a group that IS opted back into growing cannot take the row —
|
|
1044
|
+
// but only while there is a title header to take it FROM. With no label,
|
|
1045
|
+
// badge, icon or breadcrumbs the bar is the group's alone, and holding a
|
|
1046
|
+
// Collection's search input to half of an empty bar guards nothing.
|
|
1047
|
+
maxWidth: hasTitleHeader ? '50%' : undefined }, responsiveActionsWrapperProps === null || responsiveActionsWrapperProps === void 0 ? void 0 : responsiveActionsWrapperProps.style), children: nonFloatingActions.map(renderResponsiveActions()) }))), (0, jsx_runtime_1.jsx)(NonResponsiveActions_1.ReqorePanelNonResponsiveActions, { show: showNonResponsiveGroup(), isSmall: false, showControlButtons: true, size: panelSize, hasResponsiveActions: hasResponsiveActions(nonFloatingActions), customTheme: theme, isCollapsed: _isCollapsed, onCollapseClick: collapsible ? handleCollapseClick : undefined, onCloseClick: onClose, closeButtonProps: closeButtonProps, collapseButtonProps: collapseButtonProps, collapseTooltip: collapseTooltip, expandTooltip: expandTooltip, closeTooltip: closeTooltip, fluid: !hasTitleHeader, children: nonFloatingActions.map(renderNonResponsiveActions()) }), descriptionBelow ? (
|
|
1048
|
+
// `flex-basis: 100%` is what puts it on its own line — the bar is a wrapping
|
|
1049
|
+
// flex row, so a full-width item cannot share one with anything before it.
|
|
1050
|
+
// `min-width: 0` so a long sentence wraps inside the bar instead of widening it.
|
|
1051
|
+
(0, jsx_runtime_1.jsx)("div", { className: 'reqore-panel-title-description-row', style: { flex: '0 0 100%', minWidth: 0 }, children: (0, jsx_runtime_1.jsx)(Span_1.ReqoreSpan, __assign({}, descriptionProps, { children: description })) })) : null] })), !_isCollapsed || (_isCollapsed && !unMountContentOnCollapse) ? ((0, jsx_runtime_1.jsx)(exports.StyledPanelContent, { as: 'div', className: 'reqore-panel-content', hasLabel: !!hasTitleBar, hasBottomActions: hasBottomActions, isCollapsed: _isCollapsed, style: contentStyle, padded: padded, minimal: minimal || opacity === 0, size: contentSize || panelSize, ref: getContentRef, noHorizontalPadding: noHorizontalPadding, children: children })) : null, hasBottomActions && !_isCollapsed ? ((0, jsx_runtime_1.jsxs)(exports.StyledPanelBottomActions, { flat: flat, className: 'reqore-panel-bottom-actions', theme: theme, padded: padded, intent: intent, minimal: minimal || opacity === 0, opacity: minimal ? 0 : opacity !== null && opacity !== void 0 ? opacity : 1, size: contentSize || panelSize, noHorizontalPadding: noHorizontalPadding, children: [hasNonResponsiveActions(leftBottomActions) ? ((0, jsx_runtime_1.jsx)(ControlGroup_1.default, { size: panelSize, style: { marginRight: 'auto' }, children: leftBottomActions.map(renderNonResponsiveActions('flex-start')) })) : null, hasResponsiveActions(leftBottomActions) && ((0, jsx_runtime_1.jsx)(ControlGroup_1.default, { fluid: responsiveActions, responsive: responsiveActions, customTheme: theme, size: panelSize, style: { marginRight: 'auto' }, children: leftBottomActions.map(renderResponsiveActions('flex-start')) })), hasResponsiveActions(rightBottomActions) && ((0, jsx_runtime_1.jsx)(ControlGroup_1.default, { fluid: responsiveActions, horizontalAlign: 'flex-end', responsive: responsiveActions, customTheme: theme, style: { marginLeft: 'auto' }, size: panelSize, children: rightBottomActions.map(renderResponsiveActions()) })), hasNonResponsiveActions(rightBottomActions) ? ((0, jsx_runtime_1.jsx)(ControlGroup_1.default, { horizontalAlign: 'flex-end', size: panelSize, style: { marginLeft: 'auto' }, children: rightBottomActions.map(renderNonResponsiveActions()) })) : null] })) : null] })) })));
|
|
756
1052
|
});
|
|
757
|
-
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22, templateObject_23, templateObject_24, templateObject_25;
|
|
1053
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22, templateObject_23, templateObject_24, templateObject_25, templateObject_26, templateObject_27, templateObject_28, templateObject_29, templateObject_30;
|
|
758
1054
|
//# sourceMappingURL=index.js.map
|