@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @backstage/ui
|
|
2
2
|
|
|
3
|
+
## 0.15.0-next.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4bb649d: Fixed Table with row selection creating phantom scroll height on ancestor elements by establishing a containing block for visually-hidden checkbox inputs.
|
|
8
|
+
|
|
9
|
+
**Affected components:** Table, TableRoot
|
|
10
|
+
|
|
11
|
+
- d726bcd: Added new `DatePicker` component — combines a date field and a calendar popover for selecting a date, built on React Aria with full keyboard and screen reader accessibility. Uses BUI design tokens throughout, including auto-incremented backgrounds via the bg consumer pattern.
|
|
12
|
+
|
|
13
|
+
**Affected components:** DatePicker
|
|
14
|
+
|
|
15
|
+
## 0.15.0-next.2
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 37535b2: Added a public `--bui-bg-inherit` CSS variable that resolves to the background
|
|
20
|
+
color of the nearest enclosing bg provider (`Box`, `Flex`, `Grid`, `Card`,
|
|
21
|
+
`Accordion`, or any element with a `data-bg` attribute), falling back to
|
|
22
|
+
`--bui-bg-app`. Use it from CSS for sticky or fixed elements that need to match
|
|
23
|
+
their surrounding surface without hardcoding a specific level.
|
|
24
|
+
|
|
25
|
+
```css
|
|
26
|
+
.searchBarContainer {
|
|
27
|
+
position: sticky;
|
|
28
|
+
top: 0;
|
|
29
|
+
background-color: var(--bui-bg-inherit);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
As part of this change, the `data-bg` painting rules previously duplicated in
|
|
34
|
+
`Box`, `Flex`, `Grid`, `Accordion`, and `Card` have been centralized into a
|
|
35
|
+
single source in `core.css`. Painting and component behavior are unchanged for
|
|
36
|
+
all existing usages, with one minor expansion: any element with a `data-bg`
|
|
37
|
+
attribute (including provider elements and any element that sets it directly)
|
|
38
|
+
is now painted, not only `Box`/`Flex`/`Grid`/`Card`/`Accordion` elements.
|
|
39
|
+
|
|
40
|
+
- 5b85902: Fix `Card href=...` not showing a focus indicator on keyboard navigation. `Link` now composes `useFocusRing`, emits `data-focus-visible`, and renders a `--bui-ring` outline when keyboard-focused. The Card's existing focus-ring CSS matches when the trigger is focused.
|
|
41
|
+
|
|
42
|
+
_Affected components_: Card, Link
|
|
43
|
+
|
|
44
|
+
- 38bb056: Adjusted PluginHeader spacing and borders so headers with and without tabs align more consistently with surrounding page content, including when paired with page headers.
|
|
45
|
+
|
|
46
|
+
**Affected components:** PluginHeader, Header
|
|
47
|
+
|
|
48
|
+
- 25909ba: Added `searchDebounceMs` and `filterDebounceMs` options to `useTable` in `complete` mode. Both default to `0` (no debounce, no observable change for existing consumers); set them to defer the client-side filter/search/sort pipeline on large datasets without reimplementing input-layer debouncing. The controlled `search` / `onSearchChange` and `filter` / `onFilterChange` callbacks continue to fire on every change.
|
|
49
|
+
|
|
50
|
+
**Affected components:** Table
|
|
51
|
+
|
|
52
|
+
- ddca41f: Added a new `Combobox` component. It pairs a text input with a filterable dropdown of options and supports single selection, sectioned options, icons, sizes, and custom typed values via `allowsCustomValue`.
|
|
53
|
+
|
|
54
|
+
**Affected components:** Combobox
|
|
55
|
+
|
|
3
56
|
## 0.15.0-next.1
|
|
4
57
|
|
|
5
58
|
### Minor Changes
|
|
@@ -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 .Accordion_bui-
|
|
4
|
-
var styles = {"bui-Accordion":"Accordion_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 .Accordion_bui-Accordion__c1521aeef0 {\n width: 100%;\n border-radius: var(--bui-radius-3);\n padding: var(--bui-space-3);\n }\n\n .Accordion_bui-Accordion__c1521aeef0[data-bg='danger'],\n .Accordion_bui-Accordion__c1521aeef0[data-bg='warning'],\n .Accordion_bui-Accordion__c1521aeef0[data-bg='success'] {\n background-color: transparent;\n }\n\n .Accordion_bui-AccordionTrigger__c1521aeef0 {\n all: unset;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .Accordion_bui-AccordionTriggerButton__c1521aeef0 {\n all: unset;\n width: 100%;\n color: var(--bui-fg-primary);\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n text-align: left;\n\n &[data-focus-visible] {\n outline: none;\n transition: none;\n box-shadow: inset 0 0 0 2px var(--bui-ring);\n }\n\n &[data-disabled='true'] {\n background-color: transparent;\n color: var(--bui-fg-disabled);\n cursor: not-allowed;\n }\n }\n\n .Accordion_bui-AccordionTriggerTitle__c1521aeef0 {\n font-size: var(--bui-font-size-4);\n font-weight: var(--bui-font-weight-bold);\n line-height: 140%;\n }\n\n .Accordion_bui-AccordionTriggerSubtitle__c1521aeef0 {\n font-size: var(--bui-font-size-2);\n line-height: 140%;\n color: var(--bui-fg-secondary);\n }\n\n .Accordion_bui-AccordionTriggerIcon__c1521aeef0 {\n transition: transform 150ms ease-out;\n flex-shrink: 0;\n width: 1rem;\n height: 1rem;\n\n .Accordion_bui-Accordion__c1521aeef0[data-expanded='true'] > .Accordion_bui-AccordionTrigger__c1521aeef0 & {\n transform: rotate(180deg);\n }\n }\n\n .Accordion_bui-AccordionPanel__c1521aeef0 {\n .Accordion_bui-Accordion__c1521aeef0[data-expanded='true'] > & {\n padding-top: var(--bui-space-1);\n }\n }\n\n .Accordion_bui-AccordionGroup__c1521aeef0 {\n display: flex;\n flex-direction: column;\n gap: var(--bui-space-3);\n width: 100%;\n }\n}\n";
|
|
4
|
+
var styles = {"bui-Accordion":"Accordion_bui-Accordion__c1521aeef0","bui-AccordionTrigger":"Accordion_bui-AccordionTrigger__c1521aeef0","bui-AccordionTriggerButton":"Accordion_bui-AccordionTriggerButton__c1521aeef0","bui-AccordionTriggerTitle":"Accordion_bui-AccordionTriggerTitle__c1521aeef0","bui-AccordionTriggerSubtitle":"Accordion_bui-AccordionTriggerSubtitle__c1521aeef0","bui-AccordionTriggerIcon":"Accordion_bui-AccordionTriggerIcon__c1521aeef0","bui-AccordionPanel":"Accordion_bui-AccordionPanel__c1521aeef0","bui-AccordionGroup":"Accordion_bui-AccordionGroup__c1521aeef0"};
|
|
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 .Box_bui-
|
|
4
|
-
var styles = {"bui-Box":"Box_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 .Box_bui-Box__ab80215ae2 {\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n color: var(--bui-fg-primary);\n }\n}\n";
|
|
4
|
+
var styles = {"bui-Box":"Box_bui-Box__ab80215ae2"};
|
|
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 .Card_bui-
|
|
4
|
-
var styles = {"bui-Card":"Card_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 .Card_bui-Card__d452bb14b2 {\n display: flex;\n flex-direction: column;\n border-radius: var(--bui-radius-3);\n color: var(--bui-fg-primary);\n overflow: auto;\n min-height: 0;\n width: 100%;\n position: relative;\n padding: var(--bui-space-3);\n }\n\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardHeader__d452bb14b2, .Card_bui-CardBody__d452bb14b2, .Card_bui-CardFooter__d452bb14b2) {\n padding: 0;\n }\n\n /*\n * Cursor and hover tint are applied at the card level so they cover the\n * entire surface.\n */\n .Card_bui-Card__d452bb14b2[data-interactive] {\n cursor: pointer;\n\n &::after {\n content: '';\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, currentColor 5%, transparent);\n border-radius: inherit;\n pointer-events: none;\n z-index: 3;\n opacity: 0;\n transition: opacity 200ms ease-in-out;\n }\n\n &:hover::after {\n opacity: 1;\n }\n }\n\n .Card_bui-Card__d452bb14b2[data-interactive]:has(.Card_bui-CardTrigger__d452bb14b2[data-focus-visible]) {\n outline: 2px solid var(--bui-ring);\n outline-offset: -2px;\n }\n\n .Card_bui-CardTrigger__d452bb14b2 {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(100%);\n white-space: nowrap;\n border: 0;\n }\n\n .Card_bui-CardHeader__d452bb14b2 {\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n\n .Card_bui-CardBody__d452bb14b2 {\n flex: 1;\n min-height: var(--bui-space-6);\n overflow: auto;\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n\n @keyframes Card_bui-card-body-shadow__d452bb14b2 {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardHeader__d452bb14b2) .Card_bui-CardBody__d452bb14b2 {\n padding-block-start: 0;\n }\n\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardFooter__d452bb14b2) .Card_bui-CardBody__d452bb14b2 {\n padding-block-end: 0;\n }\n\n @supports (animation-timeline: scroll()) {\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardHeader__d452bb14b2) .Card_bui-CardBody__d452bb14b2::before {\n content: '';\n position: sticky;\n top: 0;\n display: block;\n height: 1.5rem;\n margin-bottom: -1.5rem;\n background: linear-gradient(\n to bottom,\n var(--bui-bg-inherit),\n rgb(from var(--bui-bg-inherit) r g b / 0)\n );\n pointer-events: none;\n opacity: 0;\n animation: Card_bui-card-body-shadow__d452bb14b2 linear both;\n animation-timeline: scroll();\n animation-range: 0px 2.5rem;\n }\n\n .Card_bui-Card__d452bb14b2:has(.Card_bui-CardFooter__d452bb14b2) .Card_bui-CardBody__d452bb14b2::after {\n content: '';\n position: sticky;\n bottom: 0;\n display: block;\n height: 1.5rem;\n margin-top: -1.5rem;\n background: linear-gradient(\n to top,\n var(--bui-bg-inherit),\n rgb(from var(--bui-bg-inherit) r g b / 0)\n );\n pointer-events: none;\n opacity: 0;\n animation: Card_bui-card-body-shadow__d452bb14b2 linear forwards,\n Card_bui-card-body-shadow__d452bb14b2 linear forwards reverse;\n animation-timeline: scroll(), scroll();\n animation-range: 0px 1px, calc(100% - 2.5rem) 100%;\n }\n }\n\n .Card_bui-CardFooter__d452bb14b2 {\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-3);\n }\n}\n";
|
|
4
|
+
var styles = {"bui-Card":"Card_bui-Card__d452bb14b2","bui-CardHeader":"Card_bui-CardHeader__d452bb14b2","bui-CardBody":"Card_bui-CardBody__d452bb14b2","bui-CardFooter":"Card_bui-CardFooter__d452bb14b2","bui-CardTrigger":"Card_bui-CardTrigger__d452bb14b2","bui-card-body-shadow":"Card_bui-card-body-shadow__d452bb14b2"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { styles as default };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef, useEffect } from 'react';
|
|
3
|
+
import { ComboBox } from 'react-aria-components';
|
|
4
|
+
import { useFilter } from 'react-aria';
|
|
5
|
+
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
6
|
+
import { ComboboxDefinition } from './definition.esm.js';
|
|
7
|
+
import { Popover } from '../Popover/Popover.esm.js';
|
|
8
|
+
import '../Popover/Popover.module.css.esm.js';
|
|
9
|
+
import { FieldLabel } from '../FieldLabel/FieldLabel.esm.js';
|
|
10
|
+
import '../FieldLabel/FieldLabel.module.css.esm.js';
|
|
11
|
+
import { FieldError } from '../FieldError/FieldError.esm.js';
|
|
12
|
+
import '../FieldError/FieldError.module.css.esm.js';
|
|
13
|
+
import { ComboboxInput } from './ComboboxInput.esm.js';
|
|
14
|
+
import { ComboboxListBox } from './ComboboxListBox.esm.js';
|
|
15
|
+
|
|
16
|
+
const Combobox = forwardRef(
|
|
17
|
+
(props, ref) => {
|
|
18
|
+
const { contains } = useFilter({ sensitivity: "base" });
|
|
19
|
+
const { ownProps, restProps, dataAttributes } = useDefinition(
|
|
20
|
+
ComboboxDefinition,
|
|
21
|
+
props
|
|
22
|
+
);
|
|
23
|
+
const {
|
|
24
|
+
classes,
|
|
25
|
+
label,
|
|
26
|
+
description,
|
|
27
|
+
options,
|
|
28
|
+
icon,
|
|
29
|
+
placeholder,
|
|
30
|
+
isRequired,
|
|
31
|
+
secondaryLabel
|
|
32
|
+
} = ownProps;
|
|
33
|
+
const ariaLabel = restProps["aria-label"];
|
|
34
|
+
const ariaLabelledBy = restProps["aria-labelledby"];
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (!label && !ariaLabel && !ariaLabelledBy) {
|
|
37
|
+
console.warn(
|
|
38
|
+
"Combobox requires either a visible label, aria-label, or aria-labelledby for accessibility"
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}, [label, ariaLabel, ariaLabelledBy]);
|
|
42
|
+
const secondaryLabelText = secondaryLabel || (isRequired ? "Required" : null);
|
|
43
|
+
return /* @__PURE__ */ jsxs(
|
|
44
|
+
ComboBox,
|
|
45
|
+
{
|
|
46
|
+
className: classes.root,
|
|
47
|
+
defaultFilter: contains,
|
|
48
|
+
...dataAttributes,
|
|
49
|
+
ref,
|
|
50
|
+
...restProps,
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
FieldLabel,
|
|
54
|
+
{
|
|
55
|
+
label,
|
|
56
|
+
secondaryLabel: secondaryLabelText,
|
|
57
|
+
description,
|
|
58
|
+
descriptionSlot: "description"
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
/* @__PURE__ */ jsx(ComboboxInput, { icon, placeholder }),
|
|
62
|
+
/* @__PURE__ */ jsx(FieldError, {}),
|
|
63
|
+
/* @__PURE__ */ jsx(Popover, { className: classes.popover, hideArrow: true, ...dataAttributes, children: /* @__PURE__ */ jsx(ComboboxListBox, { options }) })
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
Combobox.displayName = "Combobox";
|
|
70
|
+
|
|
71
|
+
export { Combobox };
|
|
72
|
+
//# sourceMappingURL=Combobox.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Combobox.esm.js","sources":["../../../src/components/Combobox/Combobox.tsx"],"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 { forwardRef, useEffect } from 'react';\nimport { ComboBox as AriaComboBox } from 'react-aria-components';\nimport { useFilter } from 'react-aria';\nimport { ComboboxProps } from './types';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { ComboboxDefinition } from './definition';\nimport { Popover } from '../Popover';\nimport { FieldLabel } from '../FieldLabel';\nimport { FieldError } from '../FieldError';\nimport { ComboboxInput } from './ComboboxInput';\nimport { ComboboxListBox } from './ComboboxListBox';\n\n/**\n * A text input combined with a dropdown list of options. The user can type to filter\n * suggestions, navigate with the keyboard, and pick a value. With `allowsCustomValue`\n * the typed text can be committed even if no option matches.\n *\n * @public\n */\nexport const Combobox = forwardRef<HTMLDivElement, ComboboxProps>(\n (props, ref) => {\n const { contains } = useFilter({ sensitivity: 'base' });\n const { ownProps, restProps, dataAttributes } = useDefinition(\n ComboboxDefinition,\n props,\n );\n const {\n classes,\n label,\n description,\n options,\n icon,\n placeholder,\n isRequired,\n secondaryLabel,\n } = ownProps;\n\n const ariaLabel = restProps['aria-label'];\n const ariaLabelledBy = restProps['aria-labelledby'];\n\n useEffect(() => {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n 'Combobox requires either a visible label, aria-label, or aria-labelledby for accessibility',\n );\n }\n }, [label, ariaLabel, ariaLabelledBy]);\n\n const secondaryLabelText =\n secondaryLabel || (isRequired ? 'Required' : null);\n\n return (\n <AriaComboBox\n className={classes.root}\n defaultFilter={contains}\n {...dataAttributes}\n ref={ref}\n {...restProps}\n >\n <FieldLabel\n label={label}\n secondaryLabel={secondaryLabelText}\n description={description}\n descriptionSlot=\"description\"\n />\n <ComboboxInput icon={icon} placeholder={placeholder} />\n <FieldError />\n <Popover className={classes.popover} hideArrow {...dataAttributes}>\n <ComboboxListBox options={options} />\n </Popover>\n </AriaComboBox>\n );\n },\n);\n\nCombobox.displayName = 'Combobox';\n"],"names":["AriaComboBox"],"mappings":";;;;;;;;;;;;;;;AAmCO,MAAM,QAAA,GAAW,UAAA;AAAA,EACtB,CAAC,OAAO,GAAA,KAAQ;AACd,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,UAAU,EAAE,WAAA,EAAa,QAAQ,CAAA;AACtD,IAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAe,GAAI,aAAA;AAAA,MAC9C,kBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM;AAAA,MACJ,OAAA;AAAA,MACA,KAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,WAAA;AAAA,MACA,UAAA;AAAA,MACA;AAAA,KACF,GAAI,QAAA;AAEJ,IAAA,MAAM,SAAA,GAAY,UAAU,YAAY,CAAA;AACxC,IAAA,MAAM,cAAA,GAAiB,UAAU,iBAAiB,CAAA;AAElD,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,KAAA,IAAS,CAAC,SAAA,IAAa,CAAC,cAAA,EAAgB;AAC3C,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,EAAG,CAAC,KAAA,EAAO,SAAA,EAAW,cAAc,CAAC,CAAA;AAErC,IAAA,MAAM,kBAAA,GACJ,cAAA,KAAmB,UAAA,GAAa,UAAA,GAAa,IAAA,CAAA;AAE/C,IAAA,uBACE,IAAA;AAAA,MAACA,QAAA;AAAA,MAAA;AAAA,QACC,WAAW,OAAA,CAAQ,IAAA;AAAA,QACnB,aAAA,EAAe,QAAA;AAAA,QACd,GAAG,cAAA;AAAA,QACJ,GAAA;AAAA,QACC,GAAG,SAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,KAAA;AAAA,cACA,cAAA,EAAgB,kBAAA;AAAA,cAChB,WAAA;AAAA,cACA,eAAA,EAAgB;AAAA;AAAA,WAClB;AAAA,0BACA,GAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAY,WAAA,EAA0B,CAAA;AAAA,8BACpD,UAAA,EAAA,EAAW,CAAA;AAAA,0BACZ,GAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,OAAA,EAAS,SAAA,EAAS,IAAA,EAAE,GAAG,cAAA,EACjD,QAAA,kBAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,OAAA,EAAkB,CAAA,EACrC;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
|
+
|
|
3
|
+
var css_248z = "/*\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\n@layer tokens, base, components, utilities;\n\n@layer components {\n .Combobox_bui-Combobox__90f6359000,\n .Combobox_bui-ComboboxPopover__90f6359000 {\n &[data-size='small'] {\n --combobox-item-height: 2rem;\n }\n\n &[data-size='medium'] {\n --combobox-item-height: 2.5rem;\n }\n }\n\n .Combobox_bui-ComboboxPopover__90f6359000 {\n min-width: var(--trigger-width);\n\n .bui-PopoverContent {\n padding: 0;\n }\n }\n\n .Combobox_bui-ComboboxInput__90f6359000 {\n box-sizing: border-box;\n border-radius: var(--bui-radius-3);\n border: none;\n outline: none;\n background-color: var(--bui-bg-neutral-1);\n transition: box-shadow 0.2s ease-in-out;\n\n &[data-on-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-on-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-3);\n }\n\n &[data-on-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-4);\n }\n\n .Combobox_bui-Combobox__90f6359000[data-focus-within] & {\n box-shadow: inset 0 0 0 1px var(--bui-ring);\n }\n\n .Combobox_bui-Combobox__90f6359000[data-invalid] & {\n box-shadow: inset 0 0 0 1px var(--bui-border-danger);\n }\n\n display: flex;\n align-items: center;\n gap: var(--bui-space-2);\n width: 100%;\n height: var(--combobox-item-height);\n\n .Combobox_bui-Combobox__90f6359000[data-size='small'] & {\n padding-inline: var(--bui-space-3) 0;\n }\n\n .Combobox_bui-Combobox__90f6359000[data-size='medium'] & {\n padding-inline: var(--bui-space-4) 0;\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n }\n }\n\n .Combobox_bui-ComboboxInputIcon__90f6359000 {\n display: grid;\n place-content: center;\n flex-shrink: 0;\n color: var(--bui-fg-secondary);\n pointer-events: none;\n\n .Combobox_bui-Combobox__90f6359000[data-size='small'] & svg {\n width: 1rem;\n height: 1rem;\n }\n\n .Combobox_bui-Combobox__90f6359000[data-size='medium'] & svg {\n width: 1.25rem;\n height: 1.25rem;\n }\n }\n\n .Combobox_bui-ComboboxInputField__90f6359000 {\n flex: 1;\n min-width: 0;\n width: 100%;\n border: none;\n outline: none;\n background-color: transparent;\n padding: 0;\n color: var(--bui-fg-primary);\n font-size: var(--bui-font-size-3);\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n line-height: var(--combobox-item-height);\n height: 100%;\n text-overflow: ellipsis;\n\n &::placeholder {\n color: var(--bui-fg-secondary);\n }\n\n &[disabled] {\n cursor: not-allowed;\n color: var(--bui-fg-disabled);\n }\n }\n\n .Combobox_bui-ComboboxInputChevron__90f6359000 {\n flex-shrink: 0;\n flex-grow: 0;\n display: grid;\n place-content: center;\n width: var(--combobox-item-height);\n height: var(--combobox-item-height);\n background-color: transparent;\n border: none;\n padding: 0;\n margin: 0;\n cursor: pointer;\n color: var(--bui-fg-secondary);\n outline: none;\n transition: color 0.2s ease-in-out;\n\n &:hover {\n color: var(--bui-fg-primary);\n }\n\n & svg {\n .Combobox_bui-Combobox__90f6359000[data-size='small'] & {\n width: 1rem;\n height: 1rem;\n }\n\n .Combobox_bui-Combobox__90f6359000[data-size='medium'] & {\n width: 1.25rem;\n height: 1.25rem;\n }\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n color: var(--bui-fg-disabled);\n }\n }\n\n .Combobox_bui-ComboboxList__90f6359000 {\n overflow: auto;\n min-height: 0;\n padding-block: var(--bui-space-1);\n padding-inline: var(--bui-space-1);\n\n &[data-focus-visible] {\n outline: none;\n }\n }\n\n .Combobox_bui-ComboboxItem__90f6359000 {\n box-sizing: border-box;\n position: relative;\n display: grid;\n grid-template-areas: 'icon text';\n grid-template-columns: 1rem 1fr;\n align-items: center;\n min-height: var(--combobox-item-height);\n padding-block: var(--bui-space-1);\n padding-left: var(--bui-space-3);\n padding-right: var(--bui-space-4);\n color: var(--bui-fg-primary);\n cursor: pointer;\n user-select: none;\n font-size: var(--bui-font-size-3);\n gap: var(--bui-space-2);\n outline: none;\n border-radius: var(--bui-radius-2);\n\n &[data-focused] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n color: var(--bui-fg-disabled);\n }\n\n &[data-selected] .Combobox_bui-ComboboxItemIndicator__90f6359000 {\n opacity: 1;\n }\n }\n\n .Combobox_bui-ComboboxItemIndicator__90f6359000 {\n grid-area: icon;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s ease-in-out;\n }\n\n .Combobox_bui-ComboboxItemLabel__90f6359000 {\n flex: 1;\n grid-area: text;\n }\n\n .Combobox_bui-ComboboxSection__90f6359000 {\n &:first-child .Combobox_bui-ComboboxSectionHeader__90f6359000 {\n padding-top: 0;\n }\n }\n\n .Combobox_bui-ComboboxSectionHeader__90f6359000 {\n height: 2rem;\n display: flex;\n align-items: center;\n padding-top: var(--bui-space-3);\n padding-left: var(--bui-space-3);\n color: var(--bui-fg-primary);\n font-size: var(--bui-font-size-1);\n font-weight: bold;\n letter-spacing: 0.05rem;\n text-transform: uppercase;\n }\n\n .Combobox_bui-ComboboxNoResults__90f6359000 {\n padding-inline: var(--bui-space-3);\n padding-block: var(--bui-space-2);\n color: var(--bui-fg-secondary);\n font-size: var(--bui-font-size-3);\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n }\n}\n";
|
|
4
|
+
var styles = {"bui-Combobox":"Combobox_bui-Combobox__90f6359000","bui-ComboboxPopover":"Combobox_bui-ComboboxPopover__90f6359000","bui-ComboboxInput":"Combobox_bui-ComboboxInput__90f6359000","bui-ComboboxInputIcon":"Combobox_bui-ComboboxInputIcon__90f6359000","bui-ComboboxInputField":"Combobox_bui-ComboboxInputField__90f6359000","bui-ComboboxInputChevron":"Combobox_bui-ComboboxInputChevron__90f6359000","bui-ComboboxList":"Combobox_bui-ComboboxList__90f6359000","bui-ComboboxItem":"Combobox_bui-ComboboxItem__90f6359000","bui-ComboboxItemIndicator":"Combobox_bui-ComboboxItemIndicator__90f6359000","bui-ComboboxItemLabel":"Combobox_bui-ComboboxItemLabel__90f6359000","bui-ComboboxSection":"Combobox_bui-ComboboxSection__90f6359000","bui-ComboboxSectionHeader":"Combobox_bui-ComboboxSectionHeader__90f6359000","bui-ComboboxNoResults":"Combobox_bui-ComboboxNoResults__90f6359000"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { styles as default };
|
|
8
|
+
//# sourceMappingURL=Combobox.module.css.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Combobox.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Group, Input, Button } from 'react-aria-components';
|
|
3
|
+
import { RiArrowDownSLine } from '@remixicon/react';
|
|
4
|
+
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
5
|
+
import { ComboboxInputDefinition } from './definition.esm.js';
|
|
6
|
+
|
|
7
|
+
function ComboboxInput(props) {
|
|
8
|
+
const { ownProps, dataAttributes } = useDefinition(
|
|
9
|
+
ComboboxInputDefinition,
|
|
10
|
+
props
|
|
11
|
+
);
|
|
12
|
+
const { classes, icon, placeholder } = ownProps;
|
|
13
|
+
return /* @__PURE__ */ jsxs(Group, { className: classes.root, ...dataAttributes, children: [
|
|
14
|
+
icon ? /* @__PURE__ */ jsx("div", { className: classes.icon, "aria-hidden": "true", children: icon }) : null,
|
|
15
|
+
/* @__PURE__ */ jsx(Input, { className: classes.input, placeholder }),
|
|
16
|
+
/* @__PURE__ */ jsx(Button, { className: classes.chevron, children: /* @__PURE__ */ jsx(RiArrowDownSLine, { "aria-hidden": "true" }) })
|
|
17
|
+
] });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { ComboboxInput };
|
|
21
|
+
//# sourceMappingURL=ComboboxInput.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComboboxInput.esm.js","sources":["../../../src/components/Combobox/ComboboxInput.tsx"],"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 { Button, Group, Input } from 'react-aria-components';\nimport { RiArrowDownSLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { ComboboxInputDefinition } from './definition';\nimport type { ComboboxInputOwnProps } from './types';\n\nexport function ComboboxInput(props: ComboboxInputOwnProps) {\n const { ownProps, dataAttributes } = useDefinition(\n ComboboxInputDefinition,\n props,\n );\n const { classes, icon, placeholder } = ownProps;\n\n return (\n <Group className={classes.root} {...dataAttributes}>\n {icon ? (\n <div className={classes.icon} aria-hidden=\"true\">\n {icon}\n </div>\n ) : null}\n <Input className={classes.input} placeholder={placeholder} />\n <Button className={classes.chevron}>\n <RiArrowDownSLine aria-hidden=\"true\" />\n </Button>\n </Group>\n );\n}\n"],"names":[],"mappings":";;;;;;AAsBO,SAAS,cAAc,KAAA,EAA8B;AAC1D,EAAA,MAAM,EAAE,QAAA,EAAU,cAAA,EAAe,GAAI,aAAA;AAAA,IACnC,uBAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAM,WAAA,EAAY,GAAI,QAAA;AAEvC,EAAA,4BACG,KAAA,EAAA,EAAM,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAO,GAAG,cAAA,EACjC,QAAA,EAAA;AAAA,IAAA,IAAA,mBACC,GAAA,CAAC,SAAI,SAAA,EAAW,OAAA,CAAQ,MAAM,aAAA,EAAY,MAAA,EACvC,gBACH,CAAA,GACE,IAAA;AAAA,oBACJ,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAW,OAAA,CAAQ,OAAO,WAAA,EAA0B,CAAA;AAAA,oBAC3D,GAAA,CAAC,UAAO,SAAA,EAAW,OAAA,CAAQ,SACzB,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,aAAA,EAAY,MAAA,EAAO,CAAA,EACvC;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { ListBox, ListBoxSection, Header, ListBoxItem, Text } from 'react-aria-components';
|
|
3
|
+
import { RiCheckLine } from '@remixicon/react';
|
|
4
|
+
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
5
|
+
import { ComboboxListBoxDefinition, ComboboxSectionDefinition, ComboboxListBoxItemDefinition } from './definition.esm.js';
|
|
6
|
+
|
|
7
|
+
const NoResults = () => {
|
|
8
|
+
const { ownProps } = useDefinition(ComboboxListBoxDefinition, {});
|
|
9
|
+
const { classes } = ownProps;
|
|
10
|
+
return /* @__PURE__ */ jsx("div", { className: classes.noResults, children: "No results found." });
|
|
11
|
+
};
|
|
12
|
+
function ComboboxItem({ option }) {
|
|
13
|
+
const { ownProps } = useDefinition(ComboboxListBoxItemDefinition, {});
|
|
14
|
+
const { classes } = ownProps;
|
|
15
|
+
return /* @__PURE__ */ jsxs(
|
|
16
|
+
ListBoxItem,
|
|
17
|
+
{
|
|
18
|
+
id: option.value,
|
|
19
|
+
textValue: option.label,
|
|
20
|
+
className: classes.root,
|
|
21
|
+
isDisabled: option.disabled,
|
|
22
|
+
children: [
|
|
23
|
+
/* @__PURE__ */ jsx("div", { className: classes.indicator, children: /* @__PURE__ */ jsx(RiCheckLine, { "aria-hidden": "true" }) }),
|
|
24
|
+
/* @__PURE__ */ jsx(Text, { slot: "label", className: classes.label, children: option.label })
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
function ComboboxSectionItems({ section }) {
|
|
30
|
+
const { ownProps } = useDefinition(ComboboxSectionDefinition, {});
|
|
31
|
+
const { classes } = ownProps;
|
|
32
|
+
return /* @__PURE__ */ jsxs(ListBoxSection, { className: classes.root, children: [
|
|
33
|
+
/* @__PURE__ */ jsx(Header, { className: classes.header, children: section.title }),
|
|
34
|
+
section.options.map((option) => /* @__PURE__ */ jsx(ComboboxItem, { option }, option.value))
|
|
35
|
+
] });
|
|
36
|
+
}
|
|
37
|
+
function ComboboxListBox(props) {
|
|
38
|
+
const { ownProps } = useDefinition(ComboboxListBoxDefinition, props);
|
|
39
|
+
const { classes, options } = ownProps;
|
|
40
|
+
return /* @__PURE__ */ jsx(ListBox, { className: classes.root, renderEmptyState: () => /* @__PURE__ */ jsx(NoResults, {}), children: options?.map(
|
|
41
|
+
(item) => "options" in item ? /* @__PURE__ */ jsx(ComboboxSectionItems, { section: item }, item.title) : /* @__PURE__ */ jsx(ComboboxItem, { option: item }, item.value)
|
|
42
|
+
) });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { ComboboxListBox };
|
|
46
|
+
//# sourceMappingURL=ComboboxListBox.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComboboxListBox.esm.js","sources":["../../../src/components/Combobox/ComboboxListBox.tsx"],"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 {\n ListBox,\n ListBoxItem,\n ListBoxSection,\n Header,\n Text,\n} from 'react-aria-components';\nimport { RiCheckLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport {\n ComboboxListBoxDefinition,\n ComboboxListBoxItemDefinition,\n ComboboxSectionDefinition,\n} from './definition';\nimport type { Option, OptionSection, ComboboxListBoxOwnProps } from './types';\n\nconst NoResults = () => {\n const { ownProps } = useDefinition(ComboboxListBoxDefinition, {});\n const { classes } = ownProps;\n\n return <div className={classes.noResults}>No results found.</div>;\n};\n\nfunction ComboboxItem({ option }: { option: Option }) {\n const { ownProps } = useDefinition(ComboboxListBoxItemDefinition, {});\n const { classes } = ownProps;\n\n return (\n <ListBoxItem\n id={option.value}\n textValue={option.label}\n className={classes.root}\n isDisabled={option.disabled}\n >\n <div className={classes.indicator}>\n <RiCheckLine aria-hidden=\"true\" />\n </div>\n <Text slot=\"label\" className={classes.label}>\n {option.label}\n </Text>\n </ListBoxItem>\n );\n}\n\nfunction ComboboxSectionItems({ section }: { section: OptionSection }) {\n const { ownProps } = useDefinition(ComboboxSectionDefinition, {});\n const { classes } = ownProps;\n\n return (\n <ListBoxSection className={classes.root}>\n <Header className={classes.header}>{section.title}</Header>\n {section.options.map(option => (\n <ComboboxItem key={option.value} option={option} />\n ))}\n </ListBoxSection>\n );\n}\n\nexport function ComboboxListBox(props: ComboboxListBoxOwnProps) {\n const { ownProps } = useDefinition(ComboboxListBoxDefinition, props);\n const { classes, options } = ownProps;\n\n return (\n <ListBox className={classes.root} renderEmptyState={() => <NoResults />}>\n {options?.map(item =>\n 'options' in item ? (\n <ComboboxSectionItems key={item.title} section={item} />\n ) : (\n <ComboboxItem key={item.value} option={item} />\n ),\n )}\n </ListBox>\n );\n}\n"],"names":[],"mappings":";;;;;;AAgCA,MAAM,YAAY,MAAM;AACtB,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,yBAAA,EAA2B,EAAE,CAAA;AAChE,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,WAAW,QAAA,EAAA,mBAAA,EAAiB,CAAA;AAC7D,CAAA;AAEA,SAAS,YAAA,CAAa,EAAE,MAAA,EAAO,EAAuB;AACpD,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,6BAAA,EAA+B,EAAE,CAAA;AACpE,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,uBACE,IAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,IAAI,MAAA,CAAO,KAAA;AAAA,MACX,WAAW,MAAA,CAAO,KAAA;AAAA,MAClB,WAAW,OAAA,CAAQ,IAAA;AAAA,MACnB,YAAY,MAAA,CAAO,QAAA;AAAA,MAEnB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,WAAW,OAAA,CAAQ,SAAA,EACtB,8BAAC,WAAA,EAAA,EAAY,aAAA,EAAY,QAAO,CAAA,EAClC,CAAA;AAAA,wBACA,GAAA,CAAC,QAAK,IAAA,EAAK,OAAA,EAAQ,WAAW,OAAA,CAAQ,KAAA,EACnC,iBAAO,KAAA,EACV;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,SAAS,oBAAA,CAAqB,EAAE,OAAA,EAAQ,EAA+B;AACrE,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,yBAAA,EAA2B,EAAE,CAAA;AAChE,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,uBACE,IAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAW,OAAA,CAAQ,IAAA,EACjC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,MAAA,EAAS,kBAAQ,KAAA,EAAM,CAAA;AAAA,IACjD,OAAA,CAAQ,QAAQ,GAAA,CAAI,CAAA,MAAA,yBAClB,YAAA,EAAA,EAAgC,MAAA,EAAA,EAAd,MAAA,CAAO,KAAuB,CAClD;AAAA,GAAA,EACH,CAAA;AAEJ;AAEO,SAAS,gBAAgB,KAAA,EAAgC;AAC9D,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,2BAA2B,KAAK,CAAA;AACnE,EAAA,MAAM,EAAE,OAAA,EAAS,OAAA,EAAQ,GAAI,QAAA;AAE7B,EAAA,uBACE,GAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAM,kBAAkB,sBAAM,GAAA,CAAC,SAAA,EAAA,EAAU,CAAA,EAClE,QAAA,EAAA,OAAA,EAAS,GAAA;AAAA,IAAI,CAAA,IAAA,KACZ,SAAA,IAAa,IAAA,mBACX,GAAA,CAAC,wBAAsC,OAAA,EAAS,IAAA,EAAA,EAArB,IAAA,CAAK,KAAsB,oBAEtD,GAAA,CAAC,YAAA,EAAA,EAA8B,MAAA,EAAQ,IAAA,EAAA,EAApB,KAAK,KAAqB;AAAA,GAEjD,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,74 @@
|
|
|
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 './Combobox.module.css.esm.js';
|
|
10
|
+
|
|
11
|
+
const ComboboxDefinition = defineComponent()({
|
|
12
|
+
styles,
|
|
13
|
+
classNames: {
|
|
14
|
+
root: "bui-Combobox",
|
|
15
|
+
popover: "bui-ComboboxPopover"
|
|
16
|
+
},
|
|
17
|
+
propDefs: {
|
|
18
|
+
icon: {},
|
|
19
|
+
size: { dataAttribute: true, default: "small" },
|
|
20
|
+
options: {},
|
|
21
|
+
placeholder: {},
|
|
22
|
+
label: {},
|
|
23
|
+
secondaryLabel: {},
|
|
24
|
+
description: {},
|
|
25
|
+
isRequired: {},
|
|
26
|
+
className: {}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
const ComboboxInputDefinition = defineComponent()(
|
|
30
|
+
{
|
|
31
|
+
styles,
|
|
32
|
+
classNames: {
|
|
33
|
+
root: "bui-ComboboxInput",
|
|
34
|
+
icon: "bui-ComboboxInputIcon",
|
|
35
|
+
input: "bui-ComboboxInputField",
|
|
36
|
+
chevron: "bui-ComboboxInputChevron"
|
|
37
|
+
},
|
|
38
|
+
bg: "consumer",
|
|
39
|
+
propDefs: {
|
|
40
|
+
icon: {},
|
|
41
|
+
placeholder: {}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
const ComboboxListBoxDefinition = defineComponent()({
|
|
46
|
+
styles,
|
|
47
|
+
classNames: {
|
|
48
|
+
root: "bui-ComboboxList",
|
|
49
|
+
noResults: "bui-ComboboxNoResults"
|
|
50
|
+
},
|
|
51
|
+
propDefs: {
|
|
52
|
+
options: {}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const ComboboxListBoxItemDefinition = defineComponent()({
|
|
56
|
+
styles,
|
|
57
|
+
classNames: {
|
|
58
|
+
root: "bui-ComboboxItem",
|
|
59
|
+
indicator: "bui-ComboboxItemIndicator",
|
|
60
|
+
label: "bui-ComboboxItemLabel"
|
|
61
|
+
},
|
|
62
|
+
propDefs: {}
|
|
63
|
+
});
|
|
64
|
+
const ComboboxSectionDefinition = defineComponent()({
|
|
65
|
+
styles,
|
|
66
|
+
classNames: {
|
|
67
|
+
root: "bui-ComboboxSection",
|
|
68
|
+
header: "bui-ComboboxSectionHeader"
|
|
69
|
+
},
|
|
70
|
+
propDefs: {}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
export { ComboboxDefinition, ComboboxInputDefinition, ComboboxListBoxDefinition, ComboboxListBoxItemDefinition, ComboboxSectionDefinition };
|
|
74
|
+
//# sourceMappingURL=definition.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definition.esm.js","sources":["../../../src/components/Combobox/definition.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 { defineComponent } from '../../hooks/useDefinition';\nimport type {\n ComboboxOwnProps,\n ComboboxInputOwnProps,\n ComboboxListBoxOwnProps,\n ComboboxListBoxItemOwnProps,\n ComboboxSectionOwnProps,\n} from './types';\nimport styles from './Combobox.module.css';\n\n/**\n * Component definition for Combobox\n * @public\n */\nexport const ComboboxDefinition = defineComponent<ComboboxOwnProps>()({\n styles,\n classNames: {\n root: 'bui-Combobox',\n popover: 'bui-ComboboxPopover',\n },\n propDefs: {\n icon: {},\n size: { dataAttribute: true, default: 'small' },\n options: {},\n placeholder: {},\n label: {},\n secondaryLabel: {},\n description: {},\n isRequired: {},\n className: {},\n },\n});\n\n/**\n * Component definition for ComboboxInput\n * @public\n */\nexport const ComboboxInputDefinition = defineComponent<ComboboxInputOwnProps>()(\n {\n styles,\n classNames: {\n root: 'bui-ComboboxInput',\n icon: 'bui-ComboboxInputIcon',\n input: 'bui-ComboboxInputField',\n chevron: 'bui-ComboboxInputChevron',\n },\n bg: 'consumer',\n propDefs: {\n icon: {},\n placeholder: {},\n },\n },\n);\n\n/**\n * Component definition for ComboboxListBox\n * @public\n */\nexport const ComboboxListBoxDefinition =\n defineComponent<ComboboxListBoxOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ComboboxList',\n noResults: 'bui-ComboboxNoResults',\n },\n propDefs: {\n options: {},\n },\n });\n\n/**\n * Component definition for ComboboxListBoxItem\n * @public\n */\nexport const ComboboxListBoxItemDefinition =\n defineComponent<ComboboxListBoxItemOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ComboboxItem',\n indicator: 'bui-ComboboxItemIndicator',\n label: 'bui-ComboboxItemLabel',\n },\n propDefs: {},\n });\n\n/**\n * Component definition for ComboboxSection\n * @public\n */\nexport const ComboboxSectionDefinition =\n defineComponent<ComboboxSectionOwnProps>()({\n styles,\n classNames: {\n root: 'bui-ComboboxSection',\n header: 'bui-ComboboxSectionHeader',\n },\n propDefs: {},\n });\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,kBAAA,GAAqB,iBAAkC,CAAE;AAAA,EACpE,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,cAAA;AAAA,IACN,OAAA,EAAS;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACR,MAAM,EAAC;AAAA,IACP,IAAA,EAAM,EAAE,aAAA,EAAe,IAAA,EAAM,SAAS,OAAA,EAAQ;AAAA,IAC9C,SAAS,EAAC;AAAA,IACV,aAAa,EAAC;AAAA,IACd,OAAO,EAAC;AAAA,IACR,gBAAgB,EAAC;AAAA,IACjB,aAAa,EAAC;AAAA,IACd,YAAY,EAAC;AAAA,IACb,WAAW;AAAC;AAEhB,CAAC;AAMM,MAAM,0BAA0B,eAAA,EAAuC;AAAA,EAC5E;AAAA,IACE,MAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,mBAAA;AAAA,MACN,IAAA,EAAM,uBAAA;AAAA,MACN,KAAA,EAAO,wBAAA;AAAA,MACP,OAAA,EAAS;AAAA,KACX;AAAA,IACA,EAAA,EAAI,UAAA;AAAA,IACJ,QAAA,EAAU;AAAA,MACR,MAAM,EAAC;AAAA,MACP,aAAa;AAAC;AAChB;AAEJ;AAMO,MAAM,yBAAA,GACX,iBAAyC,CAAE;AAAA,EACzC,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,kBAAA;AAAA,IACN,SAAA,EAAW;AAAA,GACb;AAAA,EACA,QAAA,EAAU;AAAA,IACR,SAAS;AAAC;AAEd,CAAC;AAMI,MAAM,6BAAA,GACX,iBAA6C,CAAE;AAAA,EAC7C,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,kBAAA;AAAA,IACN,SAAA,EAAW,2BAAA;AAAA,IACX,KAAA,EAAO;AAAA,GACT;AAAA,EACA,UAAU;AACZ,CAAC;AAMI,MAAM,yBAAA,GACX,iBAAyC,CAAE;AAAA,EACzC,MAAA;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,qBAAA;AAAA,IACN,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,UAAU;AACZ,CAAC;;;;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef, useEffect } from 'react';
|
|
3
|
+
import { DatePicker as DatePicker$1 } from 'react-aria-components';
|
|
4
|
+
import { FieldLabel } from '../FieldLabel/FieldLabel.esm.js';
|
|
5
|
+
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
6
|
+
import '../FieldLabel/FieldLabel.module.css.esm.js';
|
|
7
|
+
import { FieldError } from '../FieldError/FieldError.esm.js';
|
|
8
|
+
import '../FieldError/FieldError.module.css.esm.js';
|
|
9
|
+
import { Popover } from '../Popover/Popover.esm.js';
|
|
10
|
+
import '../Popover/Popover.module.css.esm.js';
|
|
11
|
+
import { DatePickerGroup } from './DatePickerGroup.esm.js';
|
|
12
|
+
import { DatePickerCalendar } from './DatePickerCalendar.esm.js';
|
|
13
|
+
import { DatePickerDefinition } from './definition.esm.js';
|
|
14
|
+
|
|
15
|
+
const DatePicker = forwardRef(
|
|
16
|
+
(props, ref) => {
|
|
17
|
+
const { ownProps, restProps, dataAttributes } = useDefinition(
|
|
18
|
+
DatePickerDefinition,
|
|
19
|
+
props
|
|
20
|
+
);
|
|
21
|
+
const { classes, label, description, secondaryLabel } = ownProps;
|
|
22
|
+
const ariaLabel = restProps["aria-label"];
|
|
23
|
+
const ariaLabelledBy = restProps["aria-labelledby"];
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!label && !ariaLabel && !ariaLabelledBy) {
|
|
26
|
+
console.warn(
|
|
27
|
+
"DatePicker requires either a visible label, aria-label, or aria-labelledby for accessibility"
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}, [label, ariaLabel, ariaLabelledBy]);
|
|
31
|
+
const secondaryLabelText = secondaryLabel || (restProps.isRequired ? "Required" : null);
|
|
32
|
+
return /* @__PURE__ */ jsxs(
|
|
33
|
+
DatePicker$1,
|
|
34
|
+
{
|
|
35
|
+
className: classes.root,
|
|
36
|
+
...dataAttributes,
|
|
37
|
+
...restProps,
|
|
38
|
+
ref,
|
|
39
|
+
children: [
|
|
40
|
+
/* @__PURE__ */ jsx(
|
|
41
|
+
FieldLabel,
|
|
42
|
+
{
|
|
43
|
+
label,
|
|
44
|
+
secondaryLabel: secondaryLabelText,
|
|
45
|
+
description,
|
|
46
|
+
descriptionSlot: "description"
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
/* @__PURE__ */ jsx(DatePickerGroup, { dataSize: dataAttributes["data-size"] }),
|
|
50
|
+
/* @__PURE__ */ jsx(FieldError, {}),
|
|
51
|
+
/* @__PURE__ */ jsx(Popover, { hideArrow: true, children: /* @__PURE__ */ jsx(DatePickerCalendar, {}) })
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
DatePicker.displayName = "DatePicker";
|
|
58
|
+
|
|
59
|
+
export { DatePicker };
|
|
60
|
+
//# sourceMappingURL=DatePicker.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.esm.js","sources":["../../../src/components/DatePicker/DatePicker.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 { forwardRef, useEffect } from 'react';\nimport { DatePicker as AriaDatePicker } from 'react-aria-components';\nimport { FieldLabel } from '../FieldLabel';\nimport { FieldError } from '../FieldError';\nimport { Popover } from '../Popover';\nimport { DatePickerGroup } from './DatePickerGroup';\nimport { DatePickerCalendar } from './DatePickerCalendar';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { DatePickerDefinition } from './definition';\nimport type { DatePickerProps } from './types';\n\n/**\n * A date picker that combines a date field and a calendar popover, allowing\n * users to enter or select a date with full keyboard and screen reader\n * accessibility.\n *\n * @public\n */\nexport const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(\n (props, ref) => {\n const { ownProps, restProps, dataAttributes } = useDefinition(\n DatePickerDefinition,\n props,\n );\n\n const { classes, label, description, secondaryLabel } = ownProps;\n\n const ariaLabel = restProps['aria-label'];\n const ariaLabelledBy = restProps['aria-labelledby'];\n\n useEffect(() => {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n 'DatePicker requires either a visible label, aria-label, or aria-labelledby for accessibility',\n );\n }\n }, [label, ariaLabel, ariaLabelledBy]);\n\n const secondaryLabelText =\n secondaryLabel || (restProps.isRequired ? 'Required' : null);\n\n return (\n <AriaDatePicker\n className={classes.root}\n {...dataAttributes}\n {...restProps}\n ref={ref}\n >\n <FieldLabel\n label={label}\n secondaryLabel={secondaryLabelText}\n description={description}\n descriptionSlot=\"description\"\n />\n <DatePickerGroup dataSize={dataAttributes['data-size']} />\n <FieldError />\n <Popover hideArrow>\n <DatePickerCalendar />\n </Popover>\n </AriaDatePicker>\n );\n },\n);\n\nDatePicker.displayName = 'DatePicker';\n"],"names":["AriaDatePicker"],"mappings":";;;;;;;;;;;;;;AAkCO,MAAM,UAAA,GAAa,UAAA;AAAA,EACxB,CAAC,OAAO,GAAA,KAAQ;AACd,IAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,cAAA,EAAe,GAAI,aAAA;AAAA,MAC9C,oBAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,WAAA,EAAa,gBAAe,GAAI,QAAA;AAExD,IAAA,MAAM,SAAA,GAAY,UAAU,YAAY,CAAA;AACxC,IAAA,MAAM,cAAA,GAAiB,UAAU,iBAAiB,CAAA;AAElD,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,KAAA,IAAS,CAAC,SAAA,IAAa,CAAC,cAAA,EAAgB;AAC3C,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN;AAAA,SACF;AAAA,MACF;AAAA,IACF,CAAA,EAAG,CAAC,KAAA,EAAO,SAAA,EAAW,cAAc,CAAC,CAAA;AAErC,IAAA,MAAM,kBAAA,GACJ,cAAA,KAAmB,SAAA,CAAU,UAAA,GAAa,UAAA,GAAa,IAAA,CAAA;AAEzD,IAAA,uBACE,IAAA;AAAA,MAACA,YAAA;AAAA,MAAA;AAAA,QACC,WAAW,OAAA,CAAQ,IAAA;AAAA,QAClB,GAAG,cAAA;AAAA,QACH,GAAG,SAAA;AAAA,QACJ,GAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,KAAA;AAAA,cACA,cAAA,EAAgB,kBAAA;AAAA,cAChB,WAAA;AAAA,cACA,eAAA,EAAgB;AAAA;AAAA,WAClB;AAAA,0BACA,GAAA,CAAC,eAAA,EAAA,EAAgB,QAAA,EAAU,cAAA,CAAe,WAAW,CAAA,EAAG,CAAA;AAAA,8BACvD,UAAA,EAAA,EAAW,CAAA;AAAA,8BACX,OAAA,EAAA,EAAQ,SAAA,EAAS,IAAA,EAChB,QAAA,kBAAA,GAAA,CAAC,sBAAmB,CAAA,EACtB;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AAEA,UAAA,CAAW,WAAA,GAAc,YAAA;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import styleInject from '../../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
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 /* ============================================================\n Root\n ============================================================ */\n\n .DatePicker_bui-DatePicker__5f91f82970 {\n display: flex;\n flex-direction: column;\n font-family: var(--bui-font-regular);\n width: 100%;\n flex-shrink: 0;\n }\n\n /* ============================================================\n Field group — custom container (not reusing any BUI field)\n ============================================================ */\n\n .DatePicker_bui-DatePickerGroup__5f91f82970 {\n display: flex;\n align-items: center;\n background-color: var(--bui-bg-neutral-1);\n border-radius: var(--bui-radius-2);\n padding: 0 var(--bui-space-1) 0 var(--bui-space-3);\n width: fit-content;\n min-width: 200px;\n max-width: 100%;\n overflow: clip;\n transition: box-shadow 0.2s ease-in-out;\n cursor: text;\n\n /* bg consumer — auto-increment background based on parent context */\n &[data-on-bg='neutral-1'] {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-on-bg='neutral-2'] {\n background-color: var(--bui-bg-neutral-3);\n }\n\n &[data-on-bg='neutral-3'] {\n background-color: var(--bui-bg-neutral-4);\n }\n\n &[data-focus-within] {\n outline: none;\n box-shadow: inset 0 0 0 1px var(--bui-ring);\n }\n\n &[data-invalid] {\n box-shadow: inset 0 0 0 1px var(--bui-border-danger);\n }\n\n &[data-disabled] {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Sizes */\n &[data-size='small'] {\n height: 2rem;\n padding-inline-start: var(--bui-space-2);\n }\n\n &[data-size='medium'] {\n height: 2.5rem;\n min-width: 210px;\n padding-inline-end: var(--bui-space-1);\n\n & .DatePicker_bui-DatePickerButton__5f91f82970 {\n width: 2rem;\n height: 2rem;\n }\n }\n }\n\n /* ============================================================\n Date input\n ============================================================ */\n\n .DatePicker_bui-DatePickerDateInput__5f91f82970 {\n flex: 1;\n display: inline-flex;\n align-items: center;\n width: unset;\n min-width: unset;\n padding: unset;\n border: unset;\n box-shadow: none;\n background: none;\n height: auto;\n overflow-x: auto;\n overflow-y: clip;\n scrollbar-width: none;\n }\n\n /* ============================================================\n Date segments (month, day, year literals and placeholders)\n ============================================================ */\n\n .DatePicker_bui-DatePickerSegment__5f91f82970 {\n display: inline-block;\n padding: var(--bui-space-0_5) var(--bui-space-1);\n border-radius: var(--bui-radius-1);\n font-size: var(--bui-font-size-3);\n font-family: var(--bui-font-regular);\n font-weight: var(--bui-font-weight-regular);\n color: var(--bui-fg-primary);\n caret-color: transparent;\n outline: none;\n font-variant-numeric: tabular-nums;\n\n &[data-placeholder] {\n color: var(--bui-fg-secondary);\n }\n\n &[data-type='literal'] {\n color: var(--bui-fg-secondary);\n padding: 0;\n }\n\n &[data-focused] {\n background-color: var(--bui-bg-solid);\n color: var(--bui-fg-solid);\n border-radius: var(--bui-radius-1);\n\n &[data-placeholder] {\n color: var(--bui-fg-solid);\n }\n }\n\n &[data-disabled] {\n color: var(--bui-fg-disabled);\n }\n }\n\n /* ============================================================\n Calendar trigger button\n ============================================================ */\n\n .DatePicker_bui-DatePickerButton__5f91f82970 {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: 1.5rem;\n height: 1.5rem;\n padding: 0;\n background: none;\n border: none;\n border-radius: var(--bui-radius-2);\n color: var(--bui-fg-secondary);\n cursor: pointer;\n margin-left: auto;\n transition: color 0.15s ease-in-out;\n outline: none;\n\n &[data-hovered] {\n color: var(--bui-fg-primary);\n }\n\n &[data-focus-visible] {\n box-shadow: inset 0 0 0 1px var(--bui-ring);\n }\n\n &[data-pressed] {\n color: var(--bui-fg-primary);\n }\n }\n\n /* ============================================================\n Calendar (inside Popover)\n ============================================================ */\n\n .DatePicker_bui-DatePickerCalendar__5f91f82970 {\n width: fit-content;\n outline: none;\n }\n\n .DatePicker_bui-DatePickerCalendarHeader__5f91f82970 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--bui-space-3);\n }\n\n .DatePicker_bui-DatePickerCalendarHeading__5f91f82970 {\n font-size: var(--bui-font-size-3);\n font-weight: var(--bui-font-weight-bold);\n font-family: var(--bui-font-regular);\n color: var(--bui-fg-primary);\n flex: 1;\n text-align: center;\n }\n\n .DatePicker_bui-DatePickerCalendarNavButton__5f91f82970 {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--bui-space-8);\n height: var(--bui-space-8);\n background: none;\n border: none;\n border-radius: var(--bui-radius-2);\n color: var(--bui-fg-secondary);\n cursor: pointer;\n transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;\n\n &[data-hovered] {\n background-color: var(--bui-bg-neutral-2);\n color: var(--bui-fg-primary);\n }\n\n &[data-focus-visible] {\n outline: 2px solid var(--bui-ring);\n outline-offset: 1px;\n }\n\n &[data-pressed] {\n background-color: var(--bui-bg-neutral-2);\n }\n }\n\n /* ============================================================\n Calendar grid\n ============================================================ */\n\n .DatePicker_bui-DatePickerCalendarGrid__5f91f82970 {\n width: 100%;\n border-collapse: separate;\n border-spacing: 0 2px;\n }\n\n .DatePicker_bui-DatePickerCalendarHeaderCell__5f91f82970 {\n font-size: var(--bui-font-size-2);\n font-weight: var(--bui-font-weight-regular);\n color: var(--bui-fg-secondary);\n text-align: center;\n padding-bottom: var(--bui-space-2);\n width: 40px;\n }\n\n /* ============================================================\n Calendar cells\n ============================================================ */\n\n .DatePicker_bui-DatePickerCalendarCell__5f91f82970 {\n position: relative;\n width: 40px;\n height: 40px;\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n outline: none;\n cursor: default;\n font-size: var(--bui-font-size-3);\n font-family: var(--bui-font-regular);\n color: var(--bui-fg-primary);\n border-radius: var(--bui-radius-full);\n\n &[data-outside-month] {\n color: var(--bui-fg-disabled);\n }\n\n &[data-disabled] {\n color: var(--bui-fg-disabled);\n cursor: not-allowed;\n }\n\n &[data-unavailable] {\n color: var(--bui-fg-disabled);\n cursor: not-allowed;\n text-decoration: line-through;\n }\n\n &[data-hovered]:not([data-disabled]):not([data-unavailable]):not(\n [data-selected]\n ) {\n background-color: var(--bui-bg-neutral-2);\n }\n\n &[data-focus-visible] {\n outline: 2px solid var(--bui-ring);\n outline-offset: -2px;\n }\n\n /* Today marker */\n &[data-today]:not([data-selected]) {\n font-weight: var(--bui-font-weight-bold);\n }\n\n /* Selected day */\n &[data-selected] {\n background-color: var(--bui-bg-solid);\n color: var(--bui-fg-solid);\n }\n }\n}\n";
|
|
4
|
+
var styles = {"bui-DatePicker":"DatePicker_bui-DatePicker__5f91f82970","bui-DatePickerGroup":"DatePicker_bui-DatePickerGroup__5f91f82970","bui-DatePickerButton":"DatePicker_bui-DatePickerButton__5f91f82970","bui-DatePickerDateInput":"DatePicker_bui-DatePickerDateInput__5f91f82970","bui-DatePickerSegment":"DatePicker_bui-DatePickerSegment__5f91f82970","bui-DatePickerCalendar":"DatePicker_bui-DatePickerCalendar__5f91f82970","bui-DatePickerCalendarHeader":"DatePicker_bui-DatePickerCalendarHeader__5f91f82970","bui-DatePickerCalendarHeading":"DatePicker_bui-DatePickerCalendarHeading__5f91f82970","bui-DatePickerCalendarNavButton":"DatePicker_bui-DatePickerCalendarNavButton__5f91f82970","bui-DatePickerCalendarGrid":"DatePicker_bui-DatePickerCalendarGrid__5f91f82970","bui-DatePickerCalendarHeaderCell":"DatePicker_bui-DatePickerCalendarHeaderCell__5f91f82970","bui-DatePickerCalendarCell":"DatePicker_bui-DatePickerCalendarCell__5f91f82970"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { styles as default };
|
|
8
|
+
//# sourceMappingURL=DatePicker.module.css.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.module.css.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Calendar, Button, Heading, CalendarGrid, CalendarGridHeader, CalendarHeaderCell, CalendarGridBody, CalendarCell } from 'react-aria-components';
|
|
3
|
+
import { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react';
|
|
4
|
+
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
5
|
+
import { DatePickerCalendarDefinition } from './definition.esm.js';
|
|
6
|
+
|
|
7
|
+
const DatePickerCalendar = () => {
|
|
8
|
+
const { ownProps } = useDefinition(DatePickerCalendarDefinition, {});
|
|
9
|
+
const { classes } = ownProps;
|
|
10
|
+
return /* @__PURE__ */ jsxs(Calendar, { className: classes.root, children: [
|
|
11
|
+
/* @__PURE__ */ jsxs("header", { className: classes.header, children: [
|
|
12
|
+
/* @__PURE__ */ jsx(Button, { slot: "previous", className: classes.navButton, children: /* @__PURE__ */ jsx(RiArrowLeftSLine, { size: 16, "aria-hidden": "true" }) }),
|
|
13
|
+
/* @__PURE__ */ jsx(Heading, { className: classes.heading }),
|
|
14
|
+
/* @__PURE__ */ jsx(Button, { slot: "next", className: classes.navButton, children: /* @__PURE__ */ jsx(RiArrowRightSLine, { size: 16, "aria-hidden": "true" }) })
|
|
15
|
+
] }),
|
|
16
|
+
/* @__PURE__ */ jsxs(CalendarGrid, { className: classes.grid, children: [
|
|
17
|
+
/* @__PURE__ */ jsx(CalendarGridHeader, { className: classes.gridHeader, children: (day) => /* @__PURE__ */ jsx(CalendarHeaderCell, { className: classes.headerCell, children: day }) }),
|
|
18
|
+
/* @__PURE__ */ jsx(CalendarGridBody, { className: classes.gridBody, children: (date) => /* @__PURE__ */ jsx(CalendarCell, { className: classes.cell, date }) })
|
|
19
|
+
] })
|
|
20
|
+
] });
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { DatePickerCalendar };
|
|
24
|
+
//# sourceMappingURL=DatePickerCalendar.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePickerCalendar.esm.js","sources":["../../../src/components/DatePicker/DatePickerCalendar.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 {\n Calendar,\n CalendarGrid,\n CalendarGridHeader,\n CalendarHeaderCell,\n CalendarGridBody,\n CalendarCell,\n Heading,\n Button,\n} from 'react-aria-components';\nimport { RiArrowLeftSLine, RiArrowRightSLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { DatePickerCalendarDefinition } from './definition';\n\n/**\n * Calendar popover content for DatePicker — renders the Calendar with\n * navigation and a full calendar grid.\n *\n * @internal\n */\nexport const DatePickerCalendar = () => {\n const { ownProps } = useDefinition(DatePickerCalendarDefinition, {});\n const { classes } = ownProps;\n\n return (\n <Calendar className={classes.root}>\n <header className={classes.header}>\n <Button slot=\"previous\" className={classes.navButton}>\n <RiArrowLeftSLine size={16} aria-hidden=\"true\" />\n </Button>\n <Heading className={classes.heading} />\n <Button slot=\"next\" className={classes.navButton}>\n <RiArrowRightSLine size={16} aria-hidden=\"true\" />\n </Button>\n </header>\n <CalendarGrid className={classes.grid}>\n <CalendarGridHeader className={classes.gridHeader}>\n {day => (\n <CalendarHeaderCell className={classes.headerCell}>\n {day}\n </CalendarHeaderCell>\n )}\n </CalendarGridHeader>\n <CalendarGridBody className={classes.gridBody}>\n {date => <CalendarCell className={classes.cell} date={date} />}\n </CalendarGridBody>\n </CalendarGrid>\n </Calendar>\n );\n};\n"],"names":[],"mappings":";;;;;;AAoCO,MAAM,qBAAqB,MAAM;AACtC,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,aAAA,CAAc,4BAAA,EAA8B,EAAE,CAAA;AACnE,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,uBACE,IAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAW,OAAA,CAAQ,IAAA,EAC3B,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,MAAA,EACzB,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAK,UAAA,EAAW,SAAA,EAAW,OAAA,CAAQ,SAAA,EACzC,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,EAAA,EAAI,aAAA,EAAY,MAAA,EAAO,CAAA,EACjD,CAAA;AAAA,sBACA,GAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,OAAA,EAAS,CAAA;AAAA,sBACrC,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAK,MAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,SAAA,EACrC,QAAA,kBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,IAAA,EAAM,EAAA,EAAI,aAAA,EAAY,QAAO,CAAA,EAClD;AAAA,KAAA,EACF,CAAA;AAAA,oBACA,IAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAW,OAAA,CAAQ,IAAA,EAC/B,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,SAAA,EAAW,OAAA,CAAQ,UAAA,EACpC,QAAA,EAAA,CAAA,GAAA,qBACC,GAAA,CAAC,kBAAA,EAAA,EAAmB,SAAA,EAAW,OAAA,CAAQ,UAAA,EACpC,QAAA,EAAA,GAAA,EACH,CAAA,EAEJ,CAAA;AAAA,sBACA,GAAA,CAAC,gBAAA,EAAA,EAAiB,SAAA,EAAW,OAAA,CAAQ,QAAA,EAClC,QAAA,EAAA,CAAA,IAAA,qBAAQ,GAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAW,OAAA,CAAQ,IAAA,EAAM,IAAA,EAAY,CAAA,EAC9D;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Group, DateInput, DateSegment, Button } from 'react-aria-components';
|
|
3
|
+
import { RiCalendarLine } from '@remixicon/react';
|
|
4
|
+
import { useDefinition } from '../../hooks/useDefinition/useDefinition.esm.js';
|
|
5
|
+
import { DatePickerGroupDefinition } from './definition.esm.js';
|
|
6
|
+
|
|
7
|
+
const DatePickerGroup = ({ dataSize }) => {
|
|
8
|
+
const { ownProps, dataAttributes } = useDefinition(
|
|
9
|
+
DatePickerGroupDefinition,
|
|
10
|
+
{}
|
|
11
|
+
);
|
|
12
|
+
const { classes } = ownProps;
|
|
13
|
+
return /* @__PURE__ */ jsxs(
|
|
14
|
+
Group,
|
|
15
|
+
{
|
|
16
|
+
className: classes.root,
|
|
17
|
+
...dataAttributes,
|
|
18
|
+
...dataSize ? { "data-size": dataSize } : {},
|
|
19
|
+
children: [
|
|
20
|
+
/* @__PURE__ */ jsx(DateInput, { className: classes.dateInput, children: (segment) => /* @__PURE__ */ jsx(DateSegment, { segment, className: classes.segment }) }),
|
|
21
|
+
/* @__PURE__ */ jsx(Button, { className: classes.button, "aria-label": "Open calendar", children: /* @__PURE__ */ jsx(RiCalendarLine, { size: 16, "aria-hidden": "true" }) })
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { DatePickerGroup };
|
|
28
|
+
//# sourceMappingURL=DatePickerGroup.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePickerGroup.esm.js","sources":["../../../src/components/DatePicker/DatePickerGroup.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 { Group, DateInput, DateSegment, Button } from 'react-aria-components';\nimport { RiCalendarLine } from '@remixicon/react';\nimport { useDefinition } from '../../hooks/useDefinition';\nimport { DatePickerGroupDefinition } from './definition';\n\n/**\n * Custom field group for DatePicker — renders a single DateInput field\n * and a calendar trigger button.\n *\n * @internal\n */\nexport const DatePickerGroup = ({ dataSize }: { dataSize?: string }) => {\n const { ownProps, dataAttributes } = useDefinition(\n DatePickerGroupDefinition,\n {},\n );\n const { classes } = ownProps;\n\n return (\n <Group\n className={classes.root}\n {...dataAttributes}\n {...(dataSize ? { 'data-size': dataSize } : {})}\n >\n <DateInput className={classes.dateInput}>\n {segment => (\n <DateSegment segment={segment} className={classes.segment} />\n )}\n </DateInput>\n <Button className={classes.button} aria-label=\"Open calendar\">\n <RiCalendarLine size={16} aria-hidden=\"true\" />\n </Button>\n </Group>\n );\n};\n"],"names":[],"mappings":";;;;;;AA2BO,MAAM,eAAA,GAAkB,CAAC,EAAE,QAAA,EAAS,KAA6B;AACtE,EAAA,MAAM,EAAE,QAAA,EAAU,cAAA,EAAe,GAAI,aAAA;AAAA,IACnC,yBAAA;AAAA,IACA;AAAC,GACH;AACA,EAAA,MAAM,EAAE,SAAQ,GAAI,QAAA;AAEpB,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAW,OAAA,CAAQ,IAAA;AAAA,MAClB,GAAG,cAAA;AAAA,MACH,GAAI,QAAA,GAAW,EAAE,WAAA,EAAa,QAAA,KAAa,EAAC;AAAA,MAE7C,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,SAAA,EAAW,OAAA,CAAQ,SAAA,EAC3B,QAAA,EAAA,CAAA,OAAA,qBACC,GAAA,CAAC,WAAA,EAAA,EAAY,OAAA,EAAkB,SAAA,EAAW,OAAA,CAAQ,OAAA,EAAS,CAAA,EAE/D,CAAA;AAAA,wBACA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,MAAA,EAAQ,YAAA,EAAW,eAAA,EAC5C,QAAA,kBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,IAAA,EAAM,EAAA,EAAI,aAAA,EAAY,QAAO,CAAA,EAC/C;AAAA;AAAA;AAAA,GACF;AAEJ;;;;"}
|