@backstage/ui 0.15.0-next.1 → 0.15.0-next.3
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/CHANGELOG.md +53 -0
- package/dist/components/Accordion/Accordion.module.css.esm.js +2 -2
- package/dist/components/Box/Box.module.css.esm.js +2 -2
- package/dist/components/Card/Card.module.css.esm.js +2 -2
- package/dist/components/Combobox/Combobox.esm.js +72 -0
- package/dist/components/Combobox/Combobox.esm.js.map +1 -0
- package/dist/components/Combobox/Combobox.module.css.esm.js +8 -0
- package/dist/components/Combobox/Combobox.module.css.esm.js.map +1 -0
- package/dist/components/Combobox/ComboboxInput.esm.js +21 -0
- package/dist/components/Combobox/ComboboxInput.esm.js.map +1 -0
- package/dist/components/Combobox/ComboboxListBox.esm.js +46 -0
- package/dist/components/Combobox/ComboboxListBox.esm.js.map +1 -0
- package/dist/components/Combobox/definition.esm.js +74 -0
- package/dist/components/Combobox/definition.esm.js.map +1 -0
- package/dist/components/DatePicker/DatePicker.esm.js +60 -0
- package/dist/components/DatePicker/DatePicker.esm.js.map +1 -0
- package/dist/components/DatePicker/DatePicker.module.css.esm.js +8 -0
- package/dist/components/DatePicker/DatePicker.module.css.esm.js.map +1 -0
- package/dist/components/DatePicker/DatePickerCalendar.esm.js +24 -0
- package/dist/components/DatePicker/DatePickerCalendar.esm.js.map +1 -0
- package/dist/components/DatePicker/DatePickerGroup.esm.js +28 -0
- package/dist/components/DatePicker/DatePickerGroup.esm.js.map +1 -0
- package/dist/components/DatePicker/definition.esm.js +52 -0
- package/dist/components/DatePicker/definition.esm.js.map +1 -0
- package/dist/components/Flex/Flex.module.css.esm.js +2 -2
- package/dist/components/Grid/Grid.module.css.esm.js +2 -2
- package/dist/components/Header/Header.module.css.esm.js +2 -2
- package/dist/components/Link/Link.esm.js +4 -2
- package/dist/components/Link/Link.esm.js.map +1 -1
- package/dist/components/Link/Link.module.css.esm.js +2 -2
- package/dist/components/PluginHeader/PluginHeader.esm.js +8 -17
- package/dist/components/PluginHeader/PluginHeader.esm.js.map +1 -1
- package/dist/components/PluginHeader/PluginHeader.module.css.esm.js +2 -2
- package/dist/components/Table/Table.module.css.esm.js +2 -2
- package/dist/components/Table/hooks/useCompletePagination.esm.js +28 -11
- package/dist/components/Table/hooks/useCompletePagination.esm.js.map +1 -1
- package/dist/components/Table/hooks/useDebouncedValue.esm.js +16 -0
- package/dist/components/Table/hooks/useDebouncedValue.esm.js.map +1 -0
- package/dist/css/styles.css +34 -0
- package/dist/index.d.ts +286 -56
- package/dist/index.esm.js +4 -0
- package/dist/index.esm.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import 'react/jsx-runtime';
|
|
2
|
+
import 'clsx';
|
|
3
|
+
import '../../hooks/useBreakpoint.esm.js';
|
|
4
|
+
import '../../hooks/useBg.esm.js';
|
|
5
|
+
import '../../hooks/useDefinition/helpers.esm.js';
|
|
6
|
+
import '../../analytics/useAnalytics.esm.js';
|
|
7
|
+
import 'react-router-dom';
|
|
8
|
+
import { defineComponent } from '../../hooks/useDefinition/defineComponent.esm.js';
|
|
9
|
+
import styles from './DatePicker.module.css.esm.js';
|
|
10
|
+
|
|
11
|
+
const DatePickerDefinition = defineComponent()({
|
|
12
|
+
styles,
|
|
13
|
+
classNames: {
|
|
14
|
+
root: "bui-DatePicker"
|
|
15
|
+
},
|
|
16
|
+
propDefs: {
|
|
17
|
+
size: { dataAttribute: true, default: "small" },
|
|
18
|
+
className: {},
|
|
19
|
+
label: {},
|
|
20
|
+
description: {},
|
|
21
|
+
secondaryLabel: {}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
const DatePickerGroupDefinition = defineComponent()({
|
|
25
|
+
styles,
|
|
26
|
+
classNames: {
|
|
27
|
+
root: "bui-DatePickerGroup",
|
|
28
|
+
dateInput: "bui-DatePickerDateInput",
|
|
29
|
+
segment: "bui-DatePickerSegment",
|
|
30
|
+
button: "bui-DatePickerButton"
|
|
31
|
+
},
|
|
32
|
+
bg: "consumer",
|
|
33
|
+
propDefs: {}
|
|
34
|
+
});
|
|
35
|
+
const DatePickerCalendarDefinition = defineComponent()({
|
|
36
|
+
styles,
|
|
37
|
+
classNames: {
|
|
38
|
+
root: "bui-DatePickerCalendar",
|
|
39
|
+
header: "bui-DatePickerCalendarHeader",
|
|
40
|
+
heading: "bui-DatePickerCalendarHeading",
|
|
41
|
+
navButton: "bui-DatePickerCalendarNavButton",
|
|
42
|
+
grid: "bui-DatePickerCalendarGrid",
|
|
43
|
+
gridHeader: "bui-DatePickerCalendarGridHeader",
|
|
44
|
+
headerCell: "bui-DatePickerCalendarHeaderCell",
|
|
45
|
+
gridBody: "bui-DatePickerCalendarGridBody",
|
|
46
|
+
cell: "bui-DatePickerCalendarCell"
|
|
47
|
+
},
|
|
48
|
+
propDefs: {}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export { DatePickerCalendarDefinition, DatePickerDefinition, DatePickerGroupDefinition };
|
|
52
|
+
//# sourceMappingURL=definition.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition.esm.js","sources":["../../../src/components/DatePicker/definition.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { defineComponent } from '../../hooks/useDefinition';\nimport type { DatePickerOwnProps } from './types';\nimport styles from './DatePicker.module.css';\n\n/**\n * Component definition for DatePicker\n * @public\n */\nexport const DatePickerDefinition = defineComponent<DatePickerOwnProps>()({\n styles,\n classNames: {\n root: 'bui-DatePicker',\n },\n propDefs: {\n size: { dataAttribute: true, default: 'small' },\n className: {},\n label: {},\n description: {},\n secondaryLabel: {},\n },\n});\n\n/**\n * Component definition for DatePickerGroup\n * @public\n */\nexport const DatePickerGroupDefinition = defineComponent<\n Record<string, never>\n>()({\n styles,\n classNames: {\n root: 'bui-DatePickerGroup',\n dateInput: 'bui-DatePickerDateInput',\n segment: 'bui-DatePickerSegment',\n button: 'bui-DatePickerButton',\n },\n bg: 'consumer',\n propDefs: {},\n});\n\n/**\n * Component definition for DatePickerCalendar\n * @public\n */\nexport const DatePickerCalendarDefinition = defineComponent<\n Record<string, never>\n>()({\n styles,\n classNames: {\n root: 'bui-DatePickerCalendar',\n header: 'bui-DatePickerCalendarHeader',\n heading: 'bui-DatePickerCalendarHeading',\n navButton: 'bui-DatePickerCalendarNavButton',\n grid: 'bui-DatePickerCalendarGrid',\n gridHeader: 'bui-DatePickerCalendarGridHeader',\n headerCell: 'bui-DatePickerCalendarHeaderCell',\n gridBody: 'bui-DatePickerCalendarGridBody',\n cell: 'bui-DatePickerCalendarCell',\n },\n propDefs: {},\n});\n"],"names":[],"mappings":";;;;;;;;;;AAwBO,MAAM,oBAAA,GAAuB,iBAAoC,CAAE;AAAA,EACxE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,EAAE,aAAA,EAAe,IAAA,EAAM,SAAS,OAAA,EAAQ;AAAA,IAC9C,WAAW,EAAC;AAAA,IACZ,OAAO,EAAC;AAAA,IACR,aAAa,EAAC;AAAA,IACd,gBAAgB;AAAC;AAErB,CAAC;AAMM,MAAM,yBAAA,GAA4B,iBAEvC,CAAE;AAAA,EACF,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,qBAAA;AAAA,IACN,SAAA,EAAW,yBAAA;AAAA,IACX,OAAA,EAAS,uBAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,EAAA,EAAI,UAAA;AAAA,EACJ,UAAU;AACZ,CAAC;AAMM,MAAM,4BAAA,GAA+B,iBAE1C,CAAE;AAAA,EACF,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,wBAAA;AAAA,IACN,MAAA,EAAQ,8BAAA;AAAA,IACR,OAAA,EAAS,+BAAA;AAAA,IACT,SAAA,EAAW,iCAAA;AAAA,IACX,IAAA,EAAM,4BAAA;AAAA,IACN,UAAA,EAAY,kCAAA;AAAA,IACZ,UAAA,EAAY,kCAAA;AAAA,IACZ,QAAA,EAAU,gCAAA;AAAA,IACV,IAAA,EAAM;AAAA,GACR;AAAA,EACA,UAAU;AACZ,CAAC;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Flex_bui-
|
|
4
|
-
var styles = {"bui-Flex":"Flex_bui-
|
|
3
|
+
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Flex_bui-Flex__2bb9a18026 {\n display: flex;\n\n /* This helps when using `truncate` on text inside a flex container */\n min-width: 0;\n }\n}\n";
|
|
4
|
+
var styles = {"bui-Flex":"Flex_bui-Flex__2bb9a18026"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { styles as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Grid_bui-
|
|
4
|
-
var styles = {"bui-Grid":"Grid_bui-
|
|
3
|
+
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Grid_bui-Grid__b251778c91 {\n display: grid;\n }\n}\n";
|
|
4
|
+
var styles = {"bui-Grid":"Grid_bui-Grid__b251778c91"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { styles as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Header_bui-
|
|
4
|
-
var styles = {"bui-HeaderBottom":"Header_bui-
|
|
3
|
+
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Header_bui-HeaderBottom__88cf7f55e4 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-3);\n margin-bottom: var(--bui-space-5);\n }\n\n .Header_bui-HeaderTop__88cf7f55e4,\n .Header_bui-HeaderContent__88cf7f55e4,\n .Header_bui-HeaderBottom__88cf7f55e4 {\n width: 100%;\n padding-inline: var(--bui-space-5);\n box-sizing: border-box;\n }\n\n .Header_bui-HeaderStickySentinel__88cf7f55e4 {\n height: 1px;\n margin-bottom: -1px;\n pointer-events: none;\n }\n\n .Header_bui-HeaderContent__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n gap: var(--bui-space-3);\n padding-top: var(--bui-space-3);\n padding-bottom: var(--bui-space-3);\n }\n\n .Header_bui-HeaderContent__88cf7f55e4[data-has-tags] {\n padding-top: var(--bui-space-2);\n }\n\n .Header_bui-HeaderContent__88cf7f55e4[data-sticky] {\n position: sticky;\n top: 0;\n z-index: 10;\n background-color: var(--bui-bg-app);\n\n &[data-on-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-1);\n }\n\n &[data-on-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-on-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-3);\n }\n }\n\n .Header_bui-HeaderContent__88cf7f55e4[data-sticky]::after {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n content: '';\n background-color: var(--bui-border-1);\n opacity: 0;\n transition: opacity 200ms ease;\n }\n\n .Header_bui-HeaderContent__88cf7f55e4[data-stuck]::after {\n opacity: 1;\n }\n\n .Header_bui-HeaderTabsWrapper__88cf7f55e4 {\n margin-left: -8px;\n }\n\n .Header_bui-HeaderControls__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderTitleStack__88cf7f55e4 {\n position: relative;\n flex: 1 1 auto;\n height: 1lh;\n min-width: 0;\n font-size: var(--bui-font-size-6);\n line-height: 140%;\n overflow: hidden;\n }\n\n .Header_bui-HeaderBreadcrumbs__88cf7f55e4,\n .Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4 {\n position: absolute;\n inset-inline: 0;\n top: 50%;\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n min-width: 0;\n transform: translateY(-50%);\n }\n\n .Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4 {\n gap: var(--bui-space-1);\n }\n\n .Header_bui-HeaderBreadcrumbs__88cf7f55e4 .Header_bui-HeaderBreadcrumbLink__88cf7f55e4,\n .Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4 .Header_bui-HeaderBreadcrumbLinkSmall__88cf7f55e4 {\n max-width: 240px;\n overflow: hidden;\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-bold);\n line-height: inherit;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Header_bui-HeaderBreadcrumbs__88cf7f55e4 .Header_bui-HeaderBreadcrumbLink__88cf7f55e4 {\n font-size: inherit;\n }\n\n .Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4 .Header_bui-HeaderBreadcrumbLinkSmall__88cf7f55e4 {\n font-size: var(--bui-font-size-4);\n }\n\n .Header_bui-HeaderBreadcrumbSeparator__88cf7f55e4 {\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderTitle__88cf7f55e4,\n .Header_bui-HeaderTitleSmall__88cf7f55e4 {\n margin: 0;\n padding: 0;\n flex: 1 1 auto;\n min-width: 0;\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-bold);\n line-height: inherit;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Header_bui-HeaderTitle__88cf7f55e4 {\n font-size: inherit;\n }\n\n .Header_bui-HeaderTitleSmall__88cf7f55e4 {\n font-size: var(--bui-font-size-4);\n }\n\n .Header_bui-HeaderTags__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n flex-wrap: wrap;\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .Header_bui-HeaderTag__88cf7f55e4 {\n display: flex;\n align-items: center;\n gap: var(--bui-space-2);\n }\n\n .Header_bui-HeaderTag__88cf7f55e4 + .Header_bui-HeaderTag__88cf7f55e4::before {\n content: '';\n width: 3px;\n height: 3px;\n border-radius: 50%;\n background-color: var(--bui-fg-secondary);\n flex-shrink: 0;\n }\n\n .Header_bui-HeaderMetaRow__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-5);\n flex-wrap: wrap;\n margin: 0;\n }\n\n .Header_bui-HeaderMetaItem__88cf7f55e4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n\n dd {\n margin: 0;\n }\n }\n}\n";
|
|
4
|
+
var styles = {"bui-HeaderBottom":"Header_bui-HeaderBottom__88cf7f55e4","bui-HeaderTop":"Header_bui-HeaderTop__88cf7f55e4","bui-HeaderContent":"Header_bui-HeaderContent__88cf7f55e4","bui-HeaderStickySentinel":"Header_bui-HeaderStickySentinel__88cf7f55e4","bui-HeaderTabsWrapper":"Header_bui-HeaderTabsWrapper__88cf7f55e4","bui-HeaderControls":"Header_bui-HeaderControls__88cf7f55e4","bui-HeaderTitleStack":"Header_bui-HeaderTitleStack__88cf7f55e4","bui-HeaderBreadcrumbs":"Header_bui-HeaderBreadcrumbs__88cf7f55e4","bui-HeaderBreadcrumbsSmall":"Header_bui-HeaderBreadcrumbsSmall__88cf7f55e4","bui-HeaderBreadcrumbLink":"Header_bui-HeaderBreadcrumbLink__88cf7f55e4","bui-HeaderBreadcrumbLinkSmall":"Header_bui-HeaderBreadcrumbLinkSmall__88cf7f55e4","bui-HeaderBreadcrumbSeparator":"Header_bui-HeaderBreadcrumbSeparator__88cf7f55e4","bui-HeaderTitle":"Header_bui-HeaderTitle__88cf7f55e4","bui-HeaderTitleSmall":"Header_bui-HeaderTitleSmall__88cf7f55e4","bui-HeaderTags":"Header_bui-HeaderTags__88cf7f55e4","bui-HeaderTag":"Header_bui-HeaderTag__88cf7f55e4","bui-HeaderMetaRow":"Header_bui-HeaderMetaRow__88cf7f55e4","bui-HeaderMetaItem":"Header_bui-HeaderMetaItem__88cf7f55e4"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { styles as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { forwardRef, useRef } from 'react';
|
|
3
|
-
import { useLink } from 'react-aria';
|
|
3
|
+
import { useLink, useFocusRing, mergeProps } from 'react-aria';
|
|
4
4
|
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
5
5
|
import { useResolvedHref } from '../../hooks/useResolvedHref.esm.js';
|
|
6
6
|
import { LinkDefinition } from './definition.esm.js';
|
|
@@ -15,6 +15,7 @@ const LinkInternal = forwardRef((props, ref) => {
|
|
|
15
15
|
const internalRef = useRef(null);
|
|
16
16
|
const linkRef = ref || internalRef;
|
|
17
17
|
const { linkProps } = useLink(restProps, linkRef);
|
|
18
|
+
const { isFocusVisible, focusProps } = useFocusRing();
|
|
18
19
|
const resolvedHref = useResolvedHref(restProps.href);
|
|
19
20
|
const handleClick = (e) => {
|
|
20
21
|
linkProps.onClick?.(e);
|
|
@@ -26,13 +27,14 @@ const LinkInternal = forwardRef((props, ref) => {
|
|
|
26
27
|
return /* @__PURE__ */ jsx(
|
|
27
28
|
"a",
|
|
28
29
|
{
|
|
29
|
-
...linkProps,
|
|
30
|
+
...mergeProps(linkProps, focusProps),
|
|
30
31
|
...dataAttributes,
|
|
31
32
|
...restProps,
|
|
32
33
|
href: resolvedHref,
|
|
33
34
|
ref: linkRef,
|
|
34
35
|
title,
|
|
35
36
|
className: classes.root,
|
|
37
|
+
"data-focus-visible": isFocusVisible || void 0,
|
|
36
38
|
onClick: handleClick,
|
|
37
39
|
children
|
|
38
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.esm.js","sources":["../../../src/components/Link/Link.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { forwardRef, useRef } from 'react';\nimport { useLink } from 'react-aria';\nimport type { LinkProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { useResolvedHref } from '../../hooks/useResolvedHref';\nimport { LinkDefinition } from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\n\nconst LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n LinkDefinition,\n props,\n );\n const { classes, title, children } = ownProps;\n\n const internalRef = useRef<HTMLAnchorElement>(null);\n const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;\n\n const { linkProps } = useLink(restProps, linkRef);\n const resolvedHref = useResolvedHref(restProps.href);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n linkProps.onClick?.(e);\n const text =\n restProps['aria-label'] ??\n getNodeText(children) ??\n String(restProps.href ?? '');\n analytics.captureEvent('click', text, {\n attributes: { to: String(restProps.href ?? '') },\n });\n };\n\n return (\n <a\n {...linkProps}\n {...dataAttributes}\n {...(restProps as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n href={resolvedHref}\n ref={linkRef}\n title={title}\n className={classes.root}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n});\n\nLinkInternal.displayName = 'LinkInternal';\n\n/**\n * A styled anchor element that supports analytics event tracking on click.\n *\n * @public\n */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n return <LinkInternal {...props} ref={ref} />;\n});\n\nLink.displayName = 'Link';\n"],"names":[],"mappings":";;;;;;;;AAwBA,MAAM,YAAA,GAAe,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC5E,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAgB,WAAU,GAAI,aAAA;AAAA,IACzD,cAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,QAAA,EAAS,GAAI,QAAA;AAErC,EAAA,MAAM,WAAA,GAAc,OAA0B,IAAI,CAAA;AAClD,EAAA,MAAM,UAAW,GAAA,IAAO,WAAA;AAExB,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,OAAA,CAAQ,WAAW,OAAO,CAAA;AAChD,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,SAAA,CAAU,IAAI,CAAA;AAEnD,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAA2C;AAC9D,IAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACrB,IAAA,MAAM,IAAA,GACJ,SAAA,CAAU,YAAY,CAAA,IACtB,WAAA,CAAY,QAAQ,CAAA,IACpB,MAAA,CAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAC7B,IAAA,SAAA,CAAU,YAAA,CAAa,SAAS,IAAA,EAAM;AAAA,MACpC,YAAY,EAAE,EAAA,EAAI,OAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAAE,KAChD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"Link.esm.js","sources":["../../../src/components/Link/Link.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { forwardRef, useRef } from 'react';\nimport { mergeProps, useFocusRing, useLink } from 'react-aria';\nimport type { LinkProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { useResolvedHref } from '../../hooks/useResolvedHref';\nimport { LinkDefinition } from './definition';\nimport { getNodeText } from '../../analytics/getNodeText';\n\nconst LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n const { ownProps, restProps, dataAttributes, analytics } = useDefinition(\n LinkDefinition,\n props,\n );\n const { classes, title, children } = ownProps;\n\n const internalRef = useRef<HTMLAnchorElement>(null);\n const linkRef = (ref || internalRef) as React.RefObject<HTMLAnchorElement>;\n\n const { linkProps } = useLink(restProps, linkRef);\n const { isFocusVisible, focusProps } = useFocusRing();\n const resolvedHref = useResolvedHref(restProps.href);\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n linkProps.onClick?.(e);\n const text =\n restProps['aria-label'] ??\n getNodeText(children) ??\n String(restProps.href ?? '');\n analytics.captureEvent('click', text, {\n attributes: { to: String(restProps.href ?? '') },\n });\n };\n\n return (\n <a\n {...mergeProps(linkProps, focusProps)}\n {...dataAttributes}\n {...(restProps as React.AnchorHTMLAttributes<HTMLAnchorElement>)}\n href={resolvedHref}\n ref={linkRef}\n title={title}\n className={classes.root}\n data-focus-visible={isFocusVisible || undefined}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n});\n\nLinkInternal.displayName = 'LinkInternal';\n\n/**\n * A styled anchor element that supports analytics event tracking on click.\n *\n * @public\n */\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {\n return <LinkInternal {...props} ref={ref} />;\n});\n\nLink.displayName = 'Link';\n"],"names":[],"mappings":";;;;;;;;AAwBA,MAAM,YAAA,GAAe,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC5E,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAgB,WAAU,GAAI,aAAA;AAAA,IACzD,cAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,QAAA,EAAS,GAAI,QAAA;AAErC,EAAA,MAAM,WAAA,GAAc,OAA0B,IAAI,CAAA;AAClD,EAAA,MAAM,UAAW,GAAA,IAAO,WAAA;AAExB,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,OAAA,CAAQ,WAAW,OAAO,CAAA;AAChD,EAAA,MAAM,EAAE,cAAA,EAAgB,UAAA,EAAW,GAAI,YAAA,EAAa;AACpD,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,SAAA,CAAU,IAAI,CAAA;AAEnD,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAA2C;AAC9D,IAAA,SAAA,CAAU,UAAU,CAAC,CAAA;AACrB,IAAA,MAAM,IAAA,GACJ,SAAA,CAAU,YAAY,CAAA,IACtB,WAAA,CAAY,QAAQ,CAAA,IACpB,MAAA,CAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAC7B,IAAA,SAAA,CAAU,YAAA,CAAa,SAAS,IAAA,EAAM;AAAA,MACpC,YAAY,EAAE,EAAA,EAAI,OAAO,SAAA,CAAU,IAAA,IAAQ,EAAE,CAAA;AAAE,KAChD,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA,CAAW,SAAA,EAAW,UAAU,CAAA;AAAA,MACnC,GAAG,cAAA;AAAA,MACH,GAAI,SAAA;AAAA,MACL,IAAA,EAAM,YAAA;AAAA,MACN,GAAA,EAAK,OAAA;AAAA,MACL,KAAA;AAAA,MACA,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,sBAAoB,cAAA,IAAkB,MAAA;AAAA,MACtC,OAAA,EAAS,WAAA;AAAA,MAER;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AAED,YAAA,CAAa,WAAA,GAAc,cAAA;AAOpB,MAAM,IAAA,GAAO,UAAA,CAAyC,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC3E,EAAA,uBAAO,GAAA,CAAC,YAAA,EAAA,EAAc,GAAG,KAAA,EAAO,GAAA,EAAU,CAAA;AAC5C,CAAC;AAED,IAAA,CAAK,WAAA,GAAc,MAAA;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Link_bui-
|
|
4
|
-
var styles = {"bui-Link":"Link_bui-
|
|
3
|
+
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Link_bui-Link__b9cba1725b {\n font-family: var(--bui-font-regular);\n padding: 0;\n margin: 0;\n cursor: pointer;\n display: inline-block;\n\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n\n &:hover {\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n }\n\n &[data-focus-visible] {\n outline: 2px solid var(--bui-ring);\n outline-offset: 2px;\n }\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='title-large'] {\n font-size: var(--bui-font-size-8);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='title-medium'] {\n font-size: var(--bui-font-size-7);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='title-small'] {\n font-size: var(--bui-font-size-6);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='title-x-small'] {\n font-size: var(--bui-font-size-5);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='body-large'] {\n font-size: var(--bui-font-size-4);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='body-medium'] {\n font-size: var(--bui-font-size-3);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='body-small'] {\n font-size: var(--bui-font-size-2);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-variant='body-x-small'] {\n font-size: var(--bui-font-size-1);\n line-height: 140%;\n }\n\n .Link_bui-Link__b9cba1725b[data-weight='regular'] {\n font-weight: var(--bui-font-weight-regular);\n }\n\n .Link_bui-Link__b9cba1725b[data-weight='bold'] {\n font-weight: var(--bui-font-weight-bold);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='primary'] {\n color: var(--bui-fg-primary);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='secondary'] {\n color: var(--bui-fg-secondary);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='danger'] {\n color: var(--bui-fg-danger);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='warning'] {\n color: var(--bui-fg-warning);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='success'] {\n color: var(--bui-fg-success);\n }\n\n .Link_bui-Link__b9cba1725b[data-color='info'] {\n color: var(--bui-fg-info);\n }\n\n .Link_bui-Link__b9cba1725b[data-truncate] {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .Link_bui-Link__b9cba1725b[data-standalone] {\n text-decoration-line: none;\n\n &:hover {\n text-decoration-line: underline;\n text-decoration-style: solid;\n text-decoration-thickness: min(2px, max(1px, 0.05em));\n text-underline-offset: calc(0.025em + 2px);\n text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);\n }\n }\n}\n";
|
|
4
|
+
var styles = {"bui-Link":"Link_bui-Link__b9cba1725b"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { styles as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { Tabs, TabList, Tab } from '../Tabs/Tabs.esm.js';
|
|
3
3
|
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
4
4
|
import '../Tabs/Tabs.module.css.esm.js';
|
|
@@ -12,7 +12,6 @@ import '../Link/Link.module.css.esm.js';
|
|
|
12
12
|
import { RiShapesLine } from '@remixicon/react';
|
|
13
13
|
import { Text } from '../Text/Text.esm.js';
|
|
14
14
|
import '../Text/Text.module.css.esm.js';
|
|
15
|
-
import { BgReset } from '../../hooks/useBg.esm.js';
|
|
16
15
|
|
|
17
16
|
const PluginHeader = (props) => {
|
|
18
17
|
const { ownProps } = useDefinition(PluginHeaderDefinition, props);
|
|
@@ -26,14 +25,14 @@ const PluginHeader = (props) => {
|
|
|
26
25
|
onTabSelectionChange
|
|
27
26
|
} = ownProps;
|
|
28
27
|
const hasTabs = tabs && tabs.length > 0;
|
|
29
|
-
const
|
|
28
|
+
const rootRef = useRef(null);
|
|
30
29
|
const animationFrameRef = useRef(void 0);
|
|
31
30
|
const lastAppliedHeightRef = useRef(void 0);
|
|
32
31
|
const actionChildren = useMemo(() => {
|
|
33
32
|
return Children.toArray(customActions);
|
|
34
33
|
}, [customActions]);
|
|
35
34
|
useIsomorphicLayoutEffect(() => {
|
|
36
|
-
const el =
|
|
35
|
+
const el = rootRef.current;
|
|
37
36
|
if (!el) {
|
|
38
37
|
return void 0;
|
|
39
38
|
}
|
|
@@ -81,23 +80,15 @@ const PluginHeader = (props) => {
|
|
|
81
80
|
};
|
|
82
81
|
}, []);
|
|
83
82
|
const titleText = title || "Your plugin";
|
|
84
|
-
return /* @__PURE__ */
|
|
85
|
-
/* @__PURE__ */ jsxs(
|
|
83
|
+
return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: classes.root, children: [
|
|
84
|
+
/* @__PURE__ */ jsxs("div", { className: classes.toolbar, "data-has-tabs": hasTabs ? "" : void 0, children: [
|
|
86
85
|
/* @__PURE__ */ jsxs("div", { className: classes.toolbarContent, children: [
|
|
87
|
-
/* @__PURE__ */ jsx(
|
|
88
|
-
Box,
|
|
89
|
-
{
|
|
90
|
-
bg: "neutral",
|
|
91
|
-
className: classes.toolbarIcon,
|
|
92
|
-
"aria-hidden": "true",
|
|
93
|
-
children: icon || /* @__PURE__ */ jsx(RiShapesLine, {})
|
|
94
|
-
}
|
|
95
|
-
),
|
|
86
|
+
/* @__PURE__ */ jsx(Box, { bg: "neutral", className: classes.toolbarIcon, "aria-hidden": "true", children: icon || /* @__PURE__ */ jsx(RiShapesLine, {}) }),
|
|
96
87
|
/* @__PURE__ */ jsx("h1", { className: classes.toolbarName, children: titleLink ? /* @__PURE__ */ jsx(Link, { href: titleLink, standalone: true, variant: "body-medium", children: titleText }) : /* @__PURE__ */ jsx(Text, { as: "span", variant: "body-medium", children: titleText }) })
|
|
97
88
|
] }),
|
|
98
89
|
/* @__PURE__ */ jsx("div", { className: classes.toolbarControls, children: actionChildren })
|
|
99
90
|
] }),
|
|
100
|
-
|
|
91
|
+
hasTabs && /* @__PURE__ */ jsx("div", { className: classes.tabs, children: /* @__PURE__ */ jsx(Tabs, { onSelectionChange: onTabSelectionChange, children: /* @__PURE__ */ jsx(TabList, { children: tabs?.map((tab) => /* @__PURE__ */ jsx(
|
|
101
92
|
Tab,
|
|
102
93
|
{
|
|
103
94
|
id: tab.id,
|
|
@@ -107,7 +98,7 @@ const PluginHeader = (props) => {
|
|
|
107
98
|
},
|
|
108
99
|
tab.id
|
|
109
100
|
)) }) }) })
|
|
110
|
-
] })
|
|
101
|
+
] });
|
|
111
102
|
};
|
|
112
103
|
|
|
113
104
|
export { PluginHeader };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginHeader.esm.js","sources":["../../../src/components/PluginHeader/PluginHeader.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PluginHeaderProps } from './types';\nimport { Tabs, TabList, Tab } from '../Tabs';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { PluginHeaderDefinition } from './definition';\nimport { type NavigateOptions } from 'react-router-dom';\nimport { Children, useMemo, useRef } from 'react';\nimport { useIsomorphicLayoutEffect } from '../../hooks/useIsomorphicLayoutEffect';\nimport { Box } from '../Box';\nimport { Link } from '../Link';\nimport { RiShapesLine } from '@remixicon/react';\nimport { Text } from '../Text';\
|
|
1
|
+
{"version":3,"file":"PluginHeader.esm.js","sources":["../../../src/components/PluginHeader/PluginHeader.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { PluginHeaderProps } from './types';\nimport { Tabs, TabList, Tab } from '../Tabs';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { PluginHeaderDefinition } from './definition';\nimport { type NavigateOptions } from 'react-router-dom';\nimport { Children, useMemo, useRef } from 'react';\nimport { useIsomorphicLayoutEffect } from '../../hooks/useIsomorphicLayoutEffect';\nimport { Box } from '../Box';\nimport { Link } from '../Link';\nimport { RiShapesLine } from '@remixicon/react';\nimport { Text } from '../Text';\n\ndeclare module 'react-aria-components' {\n interface RouterConfig {\n routerOptions: NavigateOptions;\n }\n}\n\n/**\n * Renders a plugin header with icon, title, custom actions, and optional tabs.\n * Always participates in the background context system so descendants (e.g. buttons)\n * get the correct `data-on-bg` styling inside the toolbar and tabs.\n *\n * @public\n */\nexport const PluginHeader = (props: PluginHeaderProps) => {\n const { ownProps } = useDefinition(PluginHeaderDefinition, props);\n const {\n classes,\n tabs,\n icon,\n title,\n titleLink,\n customActions,\n onTabSelectionChange,\n } = ownProps;\n\n const hasTabs = tabs && tabs.length > 0;\n const rootRef = useRef<HTMLDivElement>(null);\n const animationFrameRef = useRef<number | undefined>(undefined);\n const lastAppliedHeightRef = useRef<number | undefined>(undefined);\n\n const actionChildren = useMemo(() => {\n return Children.toArray(customActions);\n }, [customActions]);\n\n useIsomorphicLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) {\n return undefined;\n }\n\n const cancelScheduledUpdate = () => {\n if (animationFrameRef.current === undefined) {\n return;\n }\n\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = undefined;\n };\n\n const applyHeight = (height: number) => {\n if (lastAppliedHeightRef.current === height) {\n return;\n }\n\n lastAppliedHeightRef.current = height;\n document.documentElement.style.setProperty(\n '--bui-header-height',\n `${height}px`,\n );\n };\n\n const scheduleHeightUpdate = () => {\n cancelScheduledUpdate();\n animationFrameRef.current = requestAnimationFrame(() => {\n animationFrameRef.current = undefined;\n applyHeight(el.offsetHeight);\n });\n };\n\n // Set height once immediately so the initial layout is correct.\n applyHeight(el.offsetHeight);\n\n // Observe for resize changes if ResizeObserver is available\n // (not present in Jest/jsdom by default)\n if (typeof ResizeObserver === 'undefined') {\n return () => {\n cancelScheduledUpdate();\n lastAppliedHeightRef.current = undefined;\n document.documentElement.style.removeProperty('--bui-header-height');\n };\n }\n\n const observer = new ResizeObserver(() => {\n scheduleHeightUpdate();\n });\n observer.observe(el);\n\n return () => {\n observer.disconnect();\n cancelScheduledUpdate();\n lastAppliedHeightRef.current = undefined;\n document.documentElement.style.removeProperty('--bui-header-height');\n };\n }, []);\n\n const titleText = title || 'Your plugin';\n\n return (\n <div ref={rootRef} className={classes.root}>\n <div className={classes.toolbar} data-has-tabs={hasTabs ? '' : undefined}>\n <div className={classes.toolbarContent}>\n <Box bg=\"neutral\" className={classes.toolbarIcon} aria-hidden=\"true\">\n {icon || <RiShapesLine />}\n </Box>\n <h1 className={classes.toolbarName}>\n {titleLink ? (\n <Link href={titleLink} standalone variant=\"body-medium\">\n {titleText}\n </Link>\n ) : (\n <Text as=\"span\" variant=\"body-medium\">\n {titleText}\n </Text>\n )}\n </h1>\n </div>\n <div className={classes.toolbarControls}>{actionChildren}</div>\n </div>\n {hasTabs && (\n <div className={classes.tabs}>\n <Tabs onSelectionChange={onTabSelectionChange}>\n <TabList>\n {tabs?.map(tab => (\n <Tab\n key={tab.id}\n id={tab.id}\n href={tab.href}\n matchStrategy={tab.matchStrategy}\n >\n {tab.label}\n </Tab>\n ))}\n </TabList>\n </Tabs>\n </div>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .PluginHeader_bui-
|
|
4
|
-
var styles = {"bui-
|
|
3
|
+
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .PluginHeader_bui-PluginHeader__1e9ee6c296 {\n --bui-plugin-header-margin-bottom: var(--bui-space-6);\n --bui-plugin-header-toolbar-border-bottom: solid 1px var(--bui-border-1);\n --bui-plugin-header-tabs-border-bottom: 1px solid var(--bui-border-1);\n --bui-plugin-header-toolbar-padding-bottom: var(--bui-space-4);\n --bui-plugin-header-toolbar-tabs-padding-bottom: var(--bui-space-1);\n --bui-plugin-header-background-color: transparent;\n --bui-plugin-header-padding-top: var(--bui-space-4);\n\n margin-bottom: var(--bui-plugin-header-margin-bottom);\n padding-inline: var(--bui-space-5);\n padding-top: var(--bui-plugin-header-padding-top);\n background-color: var(--bui-plugin-header-background-color);\n }\n\n .PluginHeader_bui-PluginHeader__1e9ee6c296:has(+ .PluginHeader_bui-HeaderTop__1e9ee6c296),\n .PluginHeader_bui-PluginHeader__1e9ee6c296:has(+ [data-backstage-core-header]),\n .PluginHeader_bui-PluginHeader__1e9ee6c296:has(\n + [data-backstage-core-page] [data-backstage-core-header]\n ) {\n --bui-plugin-header-margin-bottom: 0;\n --bui-plugin-header-toolbar-border-bottom: none;\n --bui-plugin-header-tabs-border-bottom: none;\n --bui-plugin-header-toolbar-padding-bottom: var(--bui-space-2);\n --bui-plugin-header-toolbar-tabs-padding-bottom: var(--bui-space-2);\n --bui-plugin-header-background-color: var(--bui-bg-neutral-1);\n --bui-plugin-header-padding-top: var(--bui-space-2);\n }\n\n .PluginHeader_bui-PluginHeader__1e9ee6c296:has(+ [data-backstage-core-header])\n .PluginHeader_bui-PluginHeaderToolbarIcon__1e9ee6c296,\n .PluginHeader_bui-PluginHeader__1e9ee6c296:has(\n + [data-backstage-core-page] [data-backstage-core-header]\n )\n .PluginHeader_bui-PluginHeaderToolbarIcon__1e9ee6c296 {\n background-color: var(--bui-bg-neutral-3);\n }\n\n .PluginHeader_bui-PluginHeaderToolbar__1e9ee6c296 {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n color: var(--bui-fg-primary);\n border-bottom: var(--bui-plugin-header-toolbar-border-bottom);\n padding-bottom: var(--bui-plugin-header-toolbar-padding-bottom);\n\n &[data-has-tabs] {\n border-bottom: none;\n padding-bottom: var(--bui-plugin-header-toolbar-tabs-padding-bottom);\n }\n }\n\n .PluginHeader_bui-PluginHeaderToolbarContent__1e9ee6c296 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n }\n\n .PluginHeader_bui-PluginHeaderToolbarName__1e9ee6c296 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n font-size: var(--bui-font-size-3);\n font-weight: var(--bui-font-weight-regular);\n flex-shrink: 0;\n }\n\n .PluginHeader_bui-PluginHeader__1e9ee6c296 .PluginHeader_bui-PluginHeaderToolbarIcon__1e9ee6c296 {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 2rem;\n height: 2rem;\n border-radius: var(--bui-radius-2);\n color: var(--bui-fg-primary);\n\n & svg {\n width: 1rem;\n height: 1rem;\n }\n }\n\n .PluginHeader_bui-PluginHeaderToolbarControls__1e9ee6c296 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n }\n\n .PluginHeader_bui-PluginHeaderTabsWrapper__1e9ee6c296 {\n border-bottom: var(--bui-plugin-header-tabs-border-bottom);\n }\n}\n";
|
|
4
|
+
var styles = {"bui-PluginHeader":"PluginHeader_bui-PluginHeader__1e9ee6c296","bui-HeaderTop":"PluginHeader_bui-HeaderTop__1e9ee6c296","bui-PluginHeaderToolbarIcon":"PluginHeader_bui-PluginHeaderToolbarIcon__1e9ee6c296","bui-PluginHeaderToolbar":"PluginHeader_bui-PluginHeaderToolbar__1e9ee6c296","bui-PluginHeaderToolbarContent":"PluginHeader_bui-PluginHeaderToolbarContent__1e9ee6c296","bui-PluginHeaderToolbarName":"PluginHeader_bui-PluginHeaderToolbarName__1e9ee6c296","bui-PluginHeaderToolbarControls":"PluginHeader_bui-PluginHeaderToolbarControls__1e9ee6c296","bui-PluginHeaderTabsWrapper":"PluginHeader_bui-PluginHeaderTabsWrapper__1e9ee6c296"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { styles as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Table_bui-
|
|
4
|
-
var styles = {"bui-TableWrapper":"Table_bui-
|
|
3
|
+
var css_248z = "/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Table_bui-TableWrapper__61510929c4 {\n display: flex;\n flex-direction: column;\n }\n\n .Table_bui-TableResizableContainer__61510929c4 {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n }\n\n .Table_bui-Table__61510929c4 {\n /* Establishes containing block for react-aria's absolutely positioned hidden checkbox inputs, preventing them from escaping to a distant ancestor and creating phantom scroll height. */\n position: relative;\n width: 100%;\n caption-side: bottom;\n border-collapse: collapse;\n table-layout: fixed;\n transition: opacity 0.2s ease-in-out;\n overflow: auto;\n flex: 1;\n min-height: 0;\n\n &[data-stale='true'],\n &[data-ispending='true'] {\n opacity: 0.6;\n }\n }\n\n .Table_bui-TableHeader__61510929c4 {\n border-bottom: 1px solid var(--bui-border-2);\n transition: color 0.2s ease-in-out;\n }\n\n .Table_bui-TableHead__61510929c4 {\n text-align: left;\n padding: var(--bui-space-3);\n font-size: var(--bui-font-size-3);\n color: var(--bui-fg-primary);\n }\n\n .Table_bui-TableHeadSelection__61510929c4 {\n width: 40px;\n }\n\n .Table_bui-TableHeadContent__61510929c4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-1);\n }\n\n .Table_bui-TableHeadLabel__61510929c4 {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n }\n\n .Table_bui-TableHeadSortButton__61510929c4 {\n cursor: pointer;\n user-select: none;\n display: inline-flex;\n align-items: center;\n gap: var(--bui-space-1);\n opacity: 0;\n transition: opacity 0.1s ease-in-out;\n color: var(--bui-fg-secondary);\n\n .Table_bui-TableHead__61510929c4:hover &,\n [data-sort-direction='ascending'] &,\n [data-sort-direction='descending'] & {\n opacity: 1;\n }\n\n & svg {\n transition: transform 0.1s ease-in-out;\n }\n [data-sort-direction='descending'] & svg {\n transform: rotate(180deg);\n }\n }\n\n .Table_bui-TableBody__61510929c4 {\n color: var(--bui-fg-primary);\n }\n\n .Table_bui-TableRow__61510929c4 {\n border-bottom: 1px solid var(--bui-border-2);\n transition: color 0.2s ease-in-out;\n cursor: default;\n\n &:hover {\n background-color: var(--bui-bg-neutral-1-hover);\n }\n\n &[data-selected] {\n background-color: var(--bui-bg-neutral-1-pressed);\n }\n\n &[data-pressed] {\n background-color: var(--bui-bg-neutral-1-pressed);\n }\n\n &[data-on-bg='neutral-1'] {\n &:hover {\n background-color: var(--bui-bg-neutral-2-hover);\n }\n\n &[data-selected] {\n background-color: var(--bui-bg-neutral-2-pressed);\n }\n\n &[data-pressed] {\n background-color: var(--bui-bg-neutral-2-pressed);\n }\n\n &[data-disabled] {\n background-color: var(--bui-bg-neutral-2-disabled);\n }\n }\n\n &[data-on-bg='neutral-2'] {\n &:hover {\n background-color: var(--bui-bg-neutral-3-hover);\n }\n\n &[data-selected] {\n background-color: var(--bui-bg-neutral-3-pressed);\n }\n\n &[data-pressed] {\n background-color: var(--bui-bg-neutral-3-pressed);\n }\n\n &[data-disabled] {\n background-color: var(--bui-bg-neutral-3-disabled);\n }\n }\n\n &[data-on-bg='neutral-3'] {\n &:hover {\n background-color: var(--bui-bg-neutral-4-hover);\n }\n\n &[data-selected] {\n background-color: var(--bui-bg-neutral-4-pressed);\n }\n\n &[data-pressed] {\n background-color: var(--bui-bg-neutral-4-pressed);\n }\n\n &[data-disabled] {\n background-color: var(--bui-bg-neutral-4-disabled);\n }\n }\n\n &[data-href],\n &[data-selection-mode],\n &[data-react-aria-pressable='true'] {\n cursor: pointer;\n }\n\n &[data-disabled] {\n background-color: var(--bui-bg-neutral-1-disabled);\n cursor: not-allowed;\n }\n }\n\n .Table_bui-TableCell__61510929c4 {\n padding: var(--bui-space-3);\n font-size: var(--bui-font-size-3);\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n min-width: 0;\n overflow: hidden;\n }\n\n .Table_bui-TableCellSelection__61510929c4 {\n width: 40px;\n }\n\n .Table_bui-TableCellContentWrapper__61510929c4 {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: var(--bui-space-2);\n min-width: 0;\n width: 100%;\n max-width: 100%;\n }\n\n .Table_bui-TableCellIcon__61510929c4,\n .Table_bui-TableCellIcon__61510929c4 svg {\n display: inline-flex;\n align-items: center;\n color: var(--bui-fg-primary);\n }\n\n .Table_bui-TableCellContent__61510929c4 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-0_5);\n min-width: 0;\n flex: 1;\n overflow: hidden;\n max-width: 100%;\n }\n\n .Table_bui-TableCellContent__61510929c4 > * {\n min-width: 0;\n max-width: 100%;\n }\n\n .Table_bui-TableCellProfile__61510929c4 {\n display: flex;\n flex-direction: row;\n gap: var(--bui-space-2);\n align-items: center;\n }\n}\n";
|
|
4
|
+
var styles = {"bui-TableWrapper":"Table_bui-TableWrapper__61510929c4","bui-TableResizableContainer":"Table_bui-TableResizableContainer__61510929c4","bui-Table":"Table_bui-Table__61510929c4","bui-TableHeader":"Table_bui-TableHeader__61510929c4","bui-TableHead":"Table_bui-TableHead__61510929c4","bui-TableHeadSelection":"Table_bui-TableHeadSelection__61510929c4","bui-TableHeadContent":"Table_bui-TableHeadContent__61510929c4","bui-TableHeadLabel":"Table_bui-TableHeadLabel__61510929c4","bui-TableHeadSortButton":"Table_bui-TableHeadSortButton__61510929c4","bui-TableBody":"Table_bui-TableBody__61510929c4","bui-TableRow":"Table_bui-TableRow__61510929c4","bui-TableCell":"Table_bui-TableCell__61510929c4","bui-TableCellSelection":"Table_bui-TableCellSelection__61510929c4","bui-TableCellContentWrapper":"Table_bui-TableCellContentWrapper__61510929c4","bui-TableCellIcon":"Table_bui-TableCellIcon__61510929c4","bui-TableCellContent":"Table_bui-TableCellContent__61510929c4","bui-TableCellProfile":"Table_bui-TableCellProfile__61510929c4"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { styles as default };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useState, useEffect,
|
|
1
|
+
import { useState, useEffect, useMemo, useRef, useCallback } from 'react';
|
|
2
2
|
import { useStableCallback } from './useStableCallback.esm.js';
|
|
3
|
+
import { useDebouncedValue } from './useDebouncedValue.esm.js';
|
|
3
4
|
import { getEffectivePageSize } from './getEffectivePageSize.esm.js';
|
|
4
5
|
|
|
5
6
|
function useCompletePagination(options, query) {
|
|
@@ -9,7 +10,9 @@ function useCompletePagination(options, query) {
|
|
|
9
10
|
paginationOptions = {},
|
|
10
11
|
sortFn,
|
|
11
12
|
filterFn,
|
|
12
|
-
searchFn
|
|
13
|
+
searchFn,
|
|
14
|
+
searchDebounceMs = 0,
|
|
15
|
+
filterDebounceMs = 0
|
|
13
16
|
} = options;
|
|
14
17
|
const hasGetData = "getData" in options;
|
|
15
18
|
const noPagination = paginationOptions.type === "none";
|
|
@@ -57,30 +60,44 @@ function useCompletePagination(options, query) {
|
|
|
57
60
|
cancelled = true;
|
|
58
61
|
};
|
|
59
62
|
}, [data, getData, hasGetData, loadCount]);
|
|
60
|
-
const
|
|
63
|
+
const debouncedSearch = useDebouncedValue(search, searchDebounceMs);
|
|
64
|
+
const debouncedFilter = useDebouncedValue(filter, filterDebounceMs);
|
|
65
|
+
const debouncedQuery = useMemo(
|
|
66
|
+
() => ({ sort, filter: debouncedFilter, search: debouncedSearch }),
|
|
67
|
+
[sort, debouncedFilter, debouncedSearch]
|
|
68
|
+
);
|
|
69
|
+
const prevDebouncedQueryRef = useRef(debouncedQuery);
|
|
61
70
|
useEffect(() => {
|
|
62
|
-
if (
|
|
63
|
-
|
|
71
|
+
if (prevDebouncedQueryRef.current !== debouncedQuery) {
|
|
72
|
+
prevDebouncedQueryRef.current = debouncedQuery;
|
|
64
73
|
setOffset(0);
|
|
65
74
|
}
|
|
66
|
-
}, [
|
|
75
|
+
}, [debouncedQuery]);
|
|
67
76
|
const resolvedItems = useMemo(() => data ?? items, [data, items]);
|
|
68
77
|
const processedData = useMemo(() => {
|
|
69
78
|
if (!resolvedItems) {
|
|
70
79
|
return void 0;
|
|
71
80
|
}
|
|
72
81
|
let result = [...resolvedItems];
|
|
73
|
-
if (
|
|
74
|
-
result = filterFn(result,
|
|
82
|
+
if (debouncedFilter !== void 0 && filterFn) {
|
|
83
|
+
result = filterFn(result, debouncedFilter);
|
|
75
84
|
}
|
|
76
|
-
if (
|
|
77
|
-
result = searchFn(result,
|
|
85
|
+
if (debouncedSearch && searchFn) {
|
|
86
|
+
result = searchFn(result, debouncedSearch);
|
|
78
87
|
}
|
|
79
88
|
if (sort && sortFn) {
|
|
80
89
|
result = sortFn(result, sort);
|
|
81
90
|
}
|
|
82
91
|
return result;
|
|
83
|
-
}, [
|
|
92
|
+
}, [
|
|
93
|
+
resolvedItems,
|
|
94
|
+
sort,
|
|
95
|
+
debouncedFilter,
|
|
96
|
+
debouncedSearch,
|
|
97
|
+
filterFn,
|
|
98
|
+
searchFn,
|
|
99
|
+
sortFn
|
|
100
|
+
]);
|
|
84
101
|
const totalCount = processedData?.length ?? 0;
|
|
85
102
|
const paginatedData = useMemo(
|
|
86
103
|
() => noPagination ? processedData : processedData?.slice(offset, offset + pageSize),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCompletePagination.esm.js","sources":["../../../../src/components/Table/hooks/useCompletePagination.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from 'react';\nimport type { TableItem } from '../types';\nimport type {\n PaginationResult,\n QueryState,\n UseTableCompleteOptions,\n} from './types';\nimport { useStableCallback } from './useStableCallback';\nimport { getEffectivePageSize } from './getEffectivePageSize';\n\n/** @internal */\nexport function useCompletePagination<T extends TableItem, TFilter>(\n options: UseTableCompleteOptions<T, TFilter>,\n query: QueryState<TFilter>,\n): PaginationResult<T> & { reload: () => void } {\n const {\n data,\n getData: getDataProp = () => [],\n paginationOptions = {},\n sortFn,\n filterFn,\n searchFn,\n } = options;\n const hasGetData = 'getData' in options;\n const noPagination = paginationOptions.type === 'none';\n const { initialOffset = 0 } = paginationOptions;\n const defaultPageSize = noPagination\n ? Infinity\n : getEffectivePageSize(paginationOptions);\n\n const getData = useStableCallback(getDataProp);\n const { sort, filter, search } = query;\n\n const [items, setItems] = useState<T[] | undefined>(undefined);\n const [isPending, setIsPending] = useState(!data);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [loadCount, setLoadCount] = useState(0);\n\n const [offset, setOffset] = useState(initialOffset);\n const [pageSize, setPageSize] = useState(defaultPageSize);\n\n // Sync pageSize when the caller changes paginationOptions.pageSize\n useEffect(() => {\n setPageSize(defaultPageSize);\n setOffset(0);\n }, [defaultPageSize]);\n\n // Load data on mount and when loadCount changes (reload trigger)\n useEffect(() => {\n if (data) {\n setIsPending(false);\n return;\n }\n\n if (!hasGetData) {\n return;\n }\n\n let cancelled = false;\n setIsPending(true);\n setError(undefined);\n\n (async () => {\n try {\n const result = getData();\n const resolvedData = result instanceof Promise ? await result : result;\n if (!cancelled) {\n setItems(resolvedData);\n setIsPending(false);\n }\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsPending(false);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [data, getData, hasGetData, loadCount]);\n\n // Reset offset when query changes (query object is memoized)\n const prevQueryRef = useRef(query);\n useEffect(() => {\n if (prevQueryRef.current !== query) {\n prevQueryRef.current = query;\n setOffset(0);\n }\n }, [query]);\n\n const resolvedItems = useMemo(() => data ?? items, [data, items]);\n\n // Process data client-side (filter, search, sort)\n const processedData = useMemo(() => {\n if (!resolvedItems) {\n return undefined;\n }\n let result = [...resolvedItems];\n if (filter !== undefined && filterFn) {\n result = filterFn(result, filter);\n }\n if (search && searchFn) {\n result = searchFn(result, search);\n }\n if (sort && sortFn) {\n result = sortFn(result, sort);\n }\n return result;\n }, [resolvedItems, sort, filter, search, filterFn, searchFn, sortFn]);\n\n const totalCount = processedData?.length ?? 0;\n\n // Paginate the processed data\n const paginatedData = useMemo(\n () =>\n noPagination\n ? processedData\n : processedData?.slice(offset, offset + pageSize),\n [processedData, offset, pageSize, noPagination],\n );\n\n const hasNextPage = !noPagination && offset + pageSize < totalCount;\n const hasPreviousPage = !noPagination && offset > 0;\n\n const onNextPage = useCallback(() => {\n if (offset + pageSize < totalCount) {\n setOffset(offset + pageSize);\n }\n }, [offset, pageSize, totalCount]);\n\n const onPreviousPage = useCallback(() => {\n if (offset > 0) {\n setOffset(Math.max(0, offset - pageSize));\n }\n }, [offset, pageSize]);\n\n const onPageSizeChange = useCallback((newSize: number) => {\n setPageSize(newSize);\n setOffset(0);\n }, []);\n\n const reload = useCallback(() => {\n setOffset(0);\n setLoadCount(c => c + 1);\n }, []);\n\n return {\n data: paginatedData,\n isPending: isPending,\n error,\n totalCount,\n offset,\n pageSize,\n hasNextPage,\n hasPreviousPage,\n onNextPage,\n onPreviousPage,\n onPageSizeChange,\n reload,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useCompletePagination.esm.js","sources":["../../../../src/components/Table/hooks/useCompletePagination.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from 'react';\nimport type { TableItem } from '../types';\nimport type {\n PaginationResult,\n QueryState,\n UseTableCompleteOptions,\n} from './types';\nimport { useStableCallback } from './useStableCallback';\nimport { useDebouncedValue } from './useDebouncedValue';\nimport { getEffectivePageSize } from './getEffectivePageSize';\n\n/** @internal */\nexport function useCompletePagination<T extends TableItem, TFilter>(\n options: UseTableCompleteOptions<T, TFilter>,\n query: QueryState<TFilter>,\n): PaginationResult<T> & { reload: () => void } {\n const {\n data,\n getData: getDataProp = () => [],\n paginationOptions = {},\n sortFn,\n filterFn,\n searchFn,\n searchDebounceMs = 0,\n filterDebounceMs = 0,\n } = options;\n const hasGetData = 'getData' in options;\n const noPagination = paginationOptions.type === 'none';\n const { initialOffset = 0 } = paginationOptions;\n const defaultPageSize = noPagination\n ? Infinity\n : getEffectivePageSize(paginationOptions);\n\n const getData = useStableCallback(getDataProp);\n const { sort, filter, search } = query;\n\n const [items, setItems] = useState<T[] | undefined>(undefined);\n const [isPending, setIsPending] = useState(!data);\n const [error, setError] = useState<Error | undefined>(undefined);\n const [loadCount, setLoadCount] = useState(0);\n\n const [offset, setOffset] = useState(initialOffset);\n const [pageSize, setPageSize] = useState(defaultPageSize);\n\n // Sync pageSize when the caller changes paginationOptions.pageSize\n useEffect(() => {\n setPageSize(defaultPageSize);\n setOffset(0);\n }, [defaultPageSize]);\n\n // Load data on mount and when loadCount changes (reload trigger)\n useEffect(() => {\n if (data) {\n setIsPending(false);\n return;\n }\n\n if (!hasGetData) {\n return;\n }\n\n let cancelled = false;\n setIsPending(true);\n setError(undefined);\n\n (async () => {\n try {\n const result = getData();\n const resolvedData = result instanceof Promise ? await result : result;\n if (!cancelled) {\n setItems(resolvedData);\n setIsPending(false);\n }\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsPending(false);\n }\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [data, getData, hasGetData, loadCount]);\n\n // Debounced surrogates of search and filter feed the processing pipeline.\n // At delayMs === 0 (the default) these are referentially equal to the live\n // values, so behavior is identical to before this refactor.\n const debouncedSearch = useDebouncedValue(search, searchDebounceMs);\n const debouncedFilter = useDebouncedValue(filter, filterDebounceMs);\n\n // Reset offset when the *debounced* query changes — keying on the live query\n // would briefly flash page 1 of unfiltered data while the debounce settles.\n const debouncedQuery = useMemo(\n () => ({ sort, filter: debouncedFilter, search: debouncedSearch }),\n [sort, debouncedFilter, debouncedSearch],\n );\n const prevDebouncedQueryRef = useRef(debouncedQuery);\n useEffect(() => {\n if (prevDebouncedQueryRef.current !== debouncedQuery) {\n prevDebouncedQueryRef.current = debouncedQuery;\n setOffset(0);\n }\n }, [debouncedQuery]);\n\n const resolvedItems = useMemo(() => data ?? items, [data, items]);\n\n // Process data client-side (filter, search, sort)\n const processedData = useMemo(() => {\n if (!resolvedItems) {\n return undefined;\n }\n let result = [...resolvedItems];\n if (debouncedFilter !== undefined && filterFn) {\n result = filterFn(result, debouncedFilter);\n }\n if (debouncedSearch && searchFn) {\n result = searchFn(result, debouncedSearch);\n }\n if (sort && sortFn) {\n result = sortFn(result, sort);\n }\n return result;\n }, [\n resolvedItems,\n sort,\n debouncedFilter,\n debouncedSearch,\n filterFn,\n searchFn,\n sortFn,\n ]);\n\n const totalCount = processedData?.length ?? 0;\n\n // Paginate the processed data\n const paginatedData = useMemo(\n () =>\n noPagination\n ? processedData\n : processedData?.slice(offset, offset + pageSize),\n [processedData, offset, pageSize, noPagination],\n );\n\n const hasNextPage = !noPagination && offset + pageSize < totalCount;\n const hasPreviousPage = !noPagination && offset > 0;\n\n const onNextPage = useCallback(() => {\n if (offset + pageSize < totalCount) {\n setOffset(offset + pageSize);\n }\n }, [offset, pageSize, totalCount]);\n\n const onPreviousPage = useCallback(() => {\n if (offset > 0) {\n setOffset(Math.max(0, offset - pageSize));\n }\n }, [offset, pageSize]);\n\n const onPageSizeChange = useCallback((newSize: number) => {\n setPageSize(newSize);\n setOffset(0);\n }, []);\n\n const reload = useCallback(() => {\n setOffset(0);\n setLoadCount(c => c + 1);\n }, []);\n\n return {\n data: paginatedData,\n isPending: isPending,\n error,\n totalCount,\n offset,\n pageSize,\n hasNextPage,\n hasPreviousPage,\n onNextPage,\n onPreviousPage,\n onPageSizeChange,\n reload,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useDebouncedValue(value, delayMs) {
|
|
4
|
+
const [debounced, setDebounced] = useState(value);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (delayMs <= 0) {
|
|
7
|
+
return void 0;
|
|
8
|
+
}
|
|
9
|
+
const timer = setTimeout(() => setDebounced(value), delayMs);
|
|
10
|
+
return () => clearTimeout(timer);
|
|
11
|
+
}, [value, delayMs]);
|
|
12
|
+
return delayMs <= 0 ? value : debounced;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { useDebouncedValue };
|
|
16
|
+
//# sourceMappingURL=useDebouncedValue.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDebouncedValue.esm.js","sources":["../../../../src/components/Table/hooks/useDebouncedValue.ts"],"sourcesContent":["/*\n * Copyright 2026 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useState } from 'react';\n\n/**\n * Returns a trailing-edge debounced surrogate of `value`.\n *\n * - When `delayMs <= 0`, the live `value` is returned directly without arming\n * a timer — a true bypass with no observable change relative to using\n * `value` itself.\n * - When `delayMs > 0`, the returned value lags behind `value` by `delayMs`\n * of stability. The timer is cleared on `value` change, `delayMs` change,\n * and on unmount.\n *\n * @internal\n */\nexport function useDebouncedValue<T>(value: T, delayMs: number): T {\n const [debounced, setDebounced] = useState<T>(value);\n\n useEffect(() => {\n if (delayMs <= 0) {\n return undefined;\n }\n const timer = setTimeout(() => setDebounced(value), delayMs);\n return () => clearTimeout(timer);\n }, [value, delayMs]);\n\n return delayMs <= 0 ? value : debounced;\n}\n"],"names":[],"mappings":";;AA8BO,SAAS,iBAAA,CAAqB,OAAU,OAAA,EAAoB;AACjE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAY,KAAK,CAAA;AAEnD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAW,CAAA,EAAG;AAChB,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,YAAA,CAAa,KAAK,GAAG,OAAO,CAAA;AAC3D,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,KAAA,EAAO,OAAO,CAAC,CAAA;AAEnB,EAAA,OAAO,OAAA,IAAW,IAAI,KAAA,GAAQ,SAAA;AAChC;;;;"}
|
package/dist/css/styles.css
CHANGED
|
@@ -491,6 +491,40 @@ Add the correct display in Chrome and Safari.
|
|
|
491
491
|
[data-theme-mode='light'] {
|
|
492
492
|
color-scheme: light;
|
|
493
493
|
}
|
|
494
|
+
|
|
495
|
+
:root {
|
|
496
|
+
--bui-bg-inherit: var(--bui-bg-app);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
[data-bg='neutral-1'] {
|
|
500
|
+
background-color: var(--bui-bg-neutral-1);
|
|
501
|
+
--bui-bg-inherit: var(--bui-bg-neutral-1);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
[data-bg='neutral-2'] {
|
|
505
|
+
background-color: var(--bui-bg-neutral-2);
|
|
506
|
+
--bui-bg-inherit: var(--bui-bg-neutral-2);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
[data-bg='neutral-3'] {
|
|
510
|
+
background-color: var(--bui-bg-neutral-3);
|
|
511
|
+
--bui-bg-inherit: var(--bui-bg-neutral-3);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
[data-bg='danger'] {
|
|
515
|
+
background-color: var(--bui-bg-danger);
|
|
516
|
+
--bui-bg-inherit: var(--bui-bg-danger);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
[data-bg='warning'] {
|
|
520
|
+
background-color: var(--bui-bg-warning);
|
|
521
|
+
--bui-bg-inherit: var(--bui-bg-warning);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
[data-bg='success'] {
|
|
525
|
+
background-color: var(--bui-bg-success);
|
|
526
|
+
--bui-bg-inherit: var(--bui-bg-success);
|
|
527
|
+
}
|
|
494
528
|
}
|
|
495
529
|
/* Utilities */
|
|
496
530
|
/* Padding */
|