@box/blueprint-web 12.1.3 → 12.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib-esm/accordion/accordion.js +1 -12
- package/dist/lib-esm/accordion/accordion.module.js +1 -1
- package/dist/lib-esm/accordion/types.d.ts +5 -19
- package/dist/lib-esm/combobox/combobox.js +23 -3
- package/dist/lib-esm/combobox/types.d.ts +7 -0
- package/dist/lib-esm/index.css +23 -26
- package/package.json +1 -1
|
@@ -67,16 +67,12 @@ const Item = props => {
|
|
|
67
67
|
// TODO: [DSYS-549] Refactor - spread props in a single place
|
|
68
68
|
const {
|
|
69
69
|
status,
|
|
70
|
-
statusIcon,
|
|
71
|
-
statusIconAriaLabel,
|
|
72
70
|
title,
|
|
73
71
|
disabled,
|
|
74
72
|
error,
|
|
75
73
|
errorIconAriaLabel,
|
|
76
74
|
...itemRest
|
|
77
75
|
} = props;
|
|
78
|
-
const hasStatusLabel = isDefined(status) && !isDefined(statusIcon);
|
|
79
|
-
const hasStatusIcon = !isDefined(status) && isDefined(statusIcon);
|
|
80
76
|
return jsxs(RadixAccordion.Item, {
|
|
81
77
|
...itemRest,
|
|
82
78
|
className: accordionItemClasses,
|
|
@@ -91,17 +87,10 @@ const Item = props => {
|
|
|
91
87
|
children: title
|
|
92
88
|
}), jsxs("div", {
|
|
93
89
|
className: styles.accordionHeaderTrigger,
|
|
94
|
-
children: [
|
|
90
|
+
children: [isDefined(status) && jsx(Status, {
|
|
95
91
|
className: styles.accordionStatus,
|
|
96
92
|
color: error ? statusColors.error : statusColors.default,
|
|
97
93
|
text: `${status}`
|
|
98
|
-
}), hasStatusIcon && jsx(Status, {
|
|
99
|
-
"aria-label": statusIconAriaLabel,
|
|
100
|
-
className: styles.accordionIconStatus,
|
|
101
|
-
color: error ? statusColors.error : statusColors.default,
|
|
102
|
-
hideText: true,
|
|
103
|
-
icon: statusIcon,
|
|
104
|
-
text: statusIconAriaLabel ?? ''
|
|
105
94
|
}), jsx(PointerChevron, {
|
|
106
95
|
"aria-hidden": "true",
|
|
107
96
|
className: styles.accordionTriggerIcon
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '../index.css';
|
|
2
|
-
var styles = {"accordionContent":"bp_accordion_module_accordionContent--
|
|
2
|
+
var styles = {"accordionContent":"bp_accordion_module_accordionContent--eb917","slideDown":"bp_accordion_module_slideDown--eb917","slideUp":"bp_accordion_module_slideUp--eb917","accordionContentWrapper":"bp_accordion_module_accordionContentWrapper--eb917","accordionInlineErrorWrapper":"bp_accordion_module_accordionInlineErrorWrapper--eb917","accordionItem":"bp_accordion_module_accordionItem--eb917","accordionFixedContent":"bp_accordion_module_accordionFixedContent--eb917","accordionHeader":"bp_accordion_module_accordionHeader--eb917","accordionHeaderTrigger":"bp_accordion_module_accordionHeaderTrigger--eb917","accordionStatus":"bp_accordion_module_accordionStatus--eb917","accordionTrigger":"bp_accordion_module_accordionTrigger--eb917","accordionTriggerIcon":"bp_accordion_module_accordionTriggerIcon--eb917"};
|
|
3
3
|
|
|
4
4
|
export { styles as default };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type AccordionMultipleProps, type AccordionSingleProps, type AccordionItemProps as RadixAccordionItemProps } from '@radix-ui/react-accordion';
|
|
2
|
-
import { type FunctionComponent, type PropsWithChildren, type SVGProps } from 'react';
|
|
3
2
|
import { type RequireAllOrNone } from 'type-fest';
|
|
4
3
|
interface Loading {
|
|
5
4
|
/** Loading state of the section. Loading sections are displaying a placeholder. When this is true `loadingAriaLabel` must also be provided. */
|
|
@@ -17,23 +16,6 @@ interface Errorable {
|
|
|
17
16
|
*/
|
|
18
17
|
errorIconAriaLabel?: string;
|
|
19
18
|
}
|
|
20
|
-
interface StatusIconProps {
|
|
21
|
-
/**
|
|
22
|
-
* Icon displayed in a status pill next to the title
|
|
23
|
-
* */
|
|
24
|
-
statusIcon: FunctionComponent<PropsWithChildren<SVGProps<SVGSVGElement>>>;
|
|
25
|
-
/**
|
|
26
|
-
* Description of icon displayed in a status pill next to the title
|
|
27
|
-
* */
|
|
28
|
-
statusIconAriaLabel: string;
|
|
29
|
-
}
|
|
30
|
-
type StatusProps = {
|
|
31
|
-
status: number;
|
|
32
|
-
statusIcon?: never;
|
|
33
|
-
statusIconAriaLabel?: never;
|
|
34
|
-
} | ({
|
|
35
|
-
status?: never;
|
|
36
|
-
} & RequireAllOrNone<StatusIconProps, keyof StatusIconProps>);
|
|
37
19
|
export type AccordionBaseItem = {
|
|
38
20
|
/**
|
|
39
21
|
* Content of the accordion item that is displayed when the section is expanded
|
|
@@ -51,11 +33,15 @@ export type AccordionSectionItem = AccordionBaseItem & Omit<RadixAccordionItemPr
|
|
|
51
33
|
* Header text displayed
|
|
52
34
|
*/
|
|
53
35
|
title: string;
|
|
36
|
+
/**
|
|
37
|
+
* Number displayed in a status pill next to the title
|
|
38
|
+
* */
|
|
39
|
+
status?: number;
|
|
54
40
|
/**
|
|
55
41
|
* Disabled state of the section.
|
|
56
42
|
*/
|
|
57
43
|
disabled?: boolean;
|
|
58
|
-
}
|
|
44
|
+
};
|
|
59
45
|
export type AccordionItem = AccordionSectionItem | AccordionFixedItem;
|
|
60
46
|
export type AccordionItemProps = AccordionItem & React.ComponentPropsWithRef<'div'>;
|
|
61
47
|
export type AccordionProps = (AccordionSingleProps | AccordionMultipleProps) & React.ComponentPropsWithRef<'div'>;
|
|
@@ -79,6 +79,7 @@ const RootInner = ({
|
|
|
79
79
|
clearButtonAriaLabel,
|
|
80
80
|
endComboboxIcon,
|
|
81
81
|
idForLabel,
|
|
82
|
+
displaySingleSelectionAsChip = multiselect,
|
|
82
83
|
...comboboxProps
|
|
83
84
|
} = rest;
|
|
84
85
|
const isInput = useMemo(() => as === 'input', [as]);
|
|
@@ -152,6 +153,11 @@ const RootInner = ({
|
|
|
152
153
|
const {
|
|
153
154
|
setValue: setSelectedValue
|
|
154
155
|
} = selectStore;
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
if (inputValue.trim() === '' && !multiselect && selectedValue && !displaySingleSelectionAsChip && !clearOnBlur) {
|
|
158
|
+
setSelectedValue('');
|
|
159
|
+
}
|
|
160
|
+
}, [inputValue, multiselect, setSelectedValue, selectedValue, displaySingleSelectionAsChip, clearOnBlur]);
|
|
155
161
|
const resetSelectedValue = useCallback(() => {
|
|
156
162
|
setSelectedValue(multiselect ? [] : '');
|
|
157
163
|
}, [multiselect, setSelectedValue]);
|
|
@@ -165,15 +171,28 @@ const RootInner = ({
|
|
|
165
171
|
const focusInput = useCallback(() => {
|
|
166
172
|
inputRef.current?.focus();
|
|
167
173
|
}, []);
|
|
174
|
+
const onOptionClick = useCallback(displayedValue => {
|
|
175
|
+
// Check if inputValue is different from displayedValue,
|
|
176
|
+
// if so, update inputValue to displayedValue
|
|
177
|
+
// Othwerwise, clicking the option will do nothing.
|
|
178
|
+
if (inputValue.trim() !== displayedValue && !displaySingleSelectionAsChip) {
|
|
179
|
+
setInputValue(displayedValue);
|
|
180
|
+
}
|
|
181
|
+
}, [inputValue, setInputValue, displaySingleSelectionAsChip]);
|
|
182
|
+
const createClickHandler = useCallback(displayedValue => () => {
|
|
183
|
+
onOptionClick(displayedValue);
|
|
184
|
+
}, [onOptionClick]);
|
|
168
185
|
const renderSelectItemOption = useCallback(option => {
|
|
169
186
|
const value = getOptionValue(option);
|
|
187
|
+
const displayedValue = displayValue ? displayValue(option) : value;
|
|
170
188
|
return jsxs(OptionWithIndicator, {
|
|
171
189
|
...(typeof option === 'object' ? option : {}),
|
|
172
190
|
disabled: typeof option === 'object' && option.disabled,
|
|
191
|
+
onClick: createClickHandler(displayedValue),
|
|
173
192
|
value: value,
|
|
174
193
|
children: [jsx(Indicator, {}), displayValue ? displayValue(option) : value]
|
|
175
194
|
});
|
|
176
|
-
}, [displayValue]);
|
|
195
|
+
}, [displayValue, createClickHandler]);
|
|
177
196
|
const renderOptionFn = renderOption || renderSelectItemOption;
|
|
178
197
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
179
198
|
const selectedValueMemoized = useMemo(() => selectedValue, [JSON.stringify(selectedValue)]);
|
|
@@ -182,7 +201,8 @@ const RootInner = ({
|
|
|
182
201
|
if (Array.isArray(selectedValueMemoized) || showSingleSelectChip) {
|
|
183
202
|
setInputValue('');
|
|
184
203
|
} else if (selectedValueMemoized) {
|
|
185
|
-
|
|
204
|
+
const selectedDisplayValue = getDisplayValueFromOptionValue(selectedValueMemoized, options, displayValue);
|
|
205
|
+
setInputValue(selectedDisplayValue);
|
|
186
206
|
// Also focus input for single-select variant
|
|
187
207
|
focusInput();
|
|
188
208
|
}
|
|
@@ -259,7 +279,7 @@ const RootInner = ({
|
|
|
259
279
|
const reference = useForkRef(inputRef, ref);
|
|
260
280
|
const showChipsGroup = Array.isArray(selectedValue) && selectedValue.length > 0;
|
|
261
281
|
const showComboboxCancelButton = clearButtonAriaLabel && (inputValue.length > 0 || (Array.isArray(selectedValue) ? selectedValue.length > 0 : !!selectedValue));
|
|
262
|
-
const showSingleSelectChip =
|
|
282
|
+
const showSingleSelectChip = displaySingleSelectionAsChip && !Array.isArray(selectedValue) && !!selectedValue;
|
|
263
283
|
const Label = useLabelable(label, comboboxId);
|
|
264
284
|
const inlineErrorId = useUniqueId('inline-error-');
|
|
265
285
|
const ariaDescribedBy = clsx(rest['aria-describedby'], {
|
|
@@ -217,6 +217,13 @@ export interface ComboboxBaseProps<Multiple extends boolean, FreeInput extends b
|
|
|
217
217
|
* @default true
|
|
218
218
|
*/
|
|
219
219
|
hideOnEscape?: ComboboxPopoverProps['hideOnEscape'];
|
|
220
|
+
/**
|
|
221
|
+
* If `true`, displays the single selected value in the input field as a chip.
|
|
222
|
+
* This is independent of the clear button visibility.
|
|
223
|
+
*
|
|
224
|
+
* @default false
|
|
225
|
+
*/
|
|
226
|
+
displaySingleSelectionAsChip?: boolean;
|
|
220
227
|
}
|
|
221
228
|
export type ComboboxTextArea = Pick<TextAreaProps, 'maxRows' | 'minRows' | 'maxLength' | 'aria-describedby'> & {
|
|
222
229
|
as: 'textarea';
|
package/dist/lib-esm/index.css
CHANGED
|
@@ -612,19 +612,19 @@
|
|
|
612
612
|
.bp_status_module_colorSurfaceStatusSurfaceGreen--6c98f.bp_status_module_interactiveStatus--6c98f:focus-visible{
|
|
613
613
|
background-color:var(--surface-status-surface-green-focus);
|
|
614
614
|
}
|
|
615
|
-
.bp_accordion_module_accordionContent--
|
|
616
|
-
animation:bp_accordion_module_slideDown--
|
|
615
|
+
.bp_accordion_module_accordionContent--eb917[data-state=open]{
|
|
616
|
+
animation:bp_accordion_module_slideDown--eb917 .15s ease-out;
|
|
617
617
|
}
|
|
618
618
|
|
|
619
|
-
.bp_accordion_module_accordionContent--
|
|
620
|
-
animation:bp_accordion_module_slideUp--
|
|
619
|
+
.bp_accordion_module_accordionContent--eb917[data-state=closed]{
|
|
620
|
+
animation:bp_accordion_module_slideUp--eb917 .15s ease-out;
|
|
621
621
|
}
|
|
622
622
|
|
|
623
|
-
.bp_accordion_module_accordionContent--
|
|
623
|
+
.bp_accordion_module_accordionContent--eb917{
|
|
624
624
|
overflow:hidden;
|
|
625
625
|
}
|
|
626
626
|
|
|
627
|
-
@keyframes bp_accordion_module_slideDown--
|
|
627
|
+
@keyframes bp_accordion_module_slideDown--eb917{
|
|
628
628
|
from{
|
|
629
629
|
height:0;
|
|
630
630
|
}
|
|
@@ -632,7 +632,7 @@
|
|
|
632
632
|
height:var(--radix-accordion-content-height);
|
|
633
633
|
}
|
|
634
634
|
}
|
|
635
|
-
@keyframes bp_accordion_module_slideUp--
|
|
635
|
+
@keyframes bp_accordion_module_slideUp--eb917{
|
|
636
636
|
from{
|
|
637
637
|
height:var(--radix-accordion-content-height);
|
|
638
638
|
}
|
|
@@ -640,7 +640,7 @@
|
|
|
640
640
|
height:0;
|
|
641
641
|
}
|
|
642
642
|
}
|
|
643
|
-
.bp_accordion_module_accordionContentWrapper--
|
|
643
|
+
.bp_accordion_module_accordionContentWrapper--eb917{
|
|
644
644
|
display:flex;
|
|
645
645
|
flex-direction:column;
|
|
646
646
|
gap:var(--space-4);
|
|
@@ -649,20 +649,20 @@
|
|
|
649
649
|
padding-inline:var(--space-4);
|
|
650
650
|
}
|
|
651
651
|
|
|
652
|
-
.bp_accordion_module_accordionInlineErrorWrapper--
|
|
652
|
+
.bp_accordion_module_accordionInlineErrorWrapper--eb917{
|
|
653
653
|
padding-block-start:var(--space-4);
|
|
654
654
|
padding-inline:var(--space-4);
|
|
655
655
|
}
|
|
656
656
|
|
|
657
|
-
.bp_accordion_module_accordionItem--
|
|
657
|
+
.bp_accordion_module_accordionItem--eb917{
|
|
658
658
|
border-bottom:var(--border-1) solid var(--border-divider-border);
|
|
659
659
|
min-width:320px;
|
|
660
660
|
}
|
|
661
|
-
.bp_accordion_module_accordionItem--
|
|
661
|
+
.bp_accordion_module_accordionItem--eb917,.bp_accordion_module_accordionItem--eb917 > [data-state=open]{
|
|
662
662
|
background-color:var(--surface-accordion-surface);
|
|
663
663
|
}
|
|
664
664
|
|
|
665
|
-
.bp_accordion_module_accordionFixedContent--
|
|
665
|
+
.bp_accordion_module_accordionFixedContent--eb917{
|
|
666
666
|
background-color:var(--surface-surface);
|
|
667
667
|
display:flex;
|
|
668
668
|
flex-direction:column;
|
|
@@ -671,7 +671,7 @@
|
|
|
671
671
|
padding-inline:var(--space-4);
|
|
672
672
|
}
|
|
673
673
|
|
|
674
|
-
.bp_accordion_module_accordionHeader--
|
|
674
|
+
.bp_accordion_module_accordionHeader--eb917{
|
|
675
675
|
color:var(--text-text-on-light);
|
|
676
676
|
display:flex;
|
|
677
677
|
font-family:var(--title-small-font-family);
|
|
@@ -688,19 +688,16 @@
|
|
|
688
688
|
width:100%;
|
|
689
689
|
}
|
|
690
690
|
|
|
691
|
-
.bp_accordion_module_accordionHeaderTrigger--
|
|
691
|
+
.bp_accordion_module_accordionHeaderTrigger--eb917{
|
|
692
692
|
align-items:center;
|
|
693
693
|
display:flex;
|
|
694
694
|
}
|
|
695
695
|
|
|
696
|
-
.
|
|
696
|
+
.bp_accordion_module_accordionStatus--eb917{
|
|
697
697
|
margin-inline-start:var(--space-2);
|
|
698
698
|
}
|
|
699
|
-
.bp_accordion_module_accordionIconStatus--ae5da > span{
|
|
700
|
-
padding:0 var(--space-1);
|
|
701
|
-
}
|
|
702
699
|
|
|
703
|
-
.bp_accordion_module_accordionTrigger--
|
|
700
|
+
.bp_accordion_module_accordionTrigger--eb917{
|
|
704
701
|
align-items:center;
|
|
705
702
|
background-color:var(--surface-surface);
|
|
706
703
|
border:none;
|
|
@@ -711,31 +708,31 @@
|
|
|
711
708
|
text-transform:capitalize;
|
|
712
709
|
width:100%;
|
|
713
710
|
}
|
|
714
|
-
.bp_accordion_module_accordionTrigger--
|
|
711
|
+
.bp_accordion_module_accordionTrigger--eb917:active{
|
|
715
712
|
background-color:var(--surface-surface);
|
|
716
713
|
}
|
|
717
|
-
.bp_accordion_module_accordionTrigger--
|
|
714
|
+
.bp_accordion_module_accordionTrigger--eb917:hover{
|
|
718
715
|
background-color:var(--surface-accordion-surface-hover);
|
|
719
716
|
cursor:pointer;
|
|
720
717
|
}
|
|
721
|
-
.bp_accordion_module_accordionTrigger--
|
|
718
|
+
.bp_accordion_module_accordionTrigger--eb917:focus-visible{
|
|
722
719
|
background-color:var(--surface-surface-hover);
|
|
723
720
|
box-shadow:inset 0 0 0 var(--border-2) var(--outline-focus-on-light);
|
|
724
721
|
outline:none;
|
|
725
722
|
}
|
|
726
|
-
.bp_accordion_module_accordionTrigger--
|
|
723
|
+
.bp_accordion_module_accordionTrigger--eb917:disabled{
|
|
727
724
|
cursor:default;
|
|
728
725
|
opacity:.3;
|
|
729
726
|
}
|
|
730
|
-
.bp_accordion_module_accordionTrigger--
|
|
727
|
+
.bp_accordion_module_accordionTrigger--eb917:disabled:hover{
|
|
731
728
|
background-color:var(--gray-white);
|
|
732
729
|
}
|
|
733
|
-
.bp_accordion_module_accordionTrigger--
|
|
730
|
+
.bp_accordion_module_accordionTrigger--eb917 .bp_accordion_module_accordionTriggerIcon--eb917{
|
|
734
731
|
color:var(--gray-50);
|
|
735
732
|
flex-shrink:0;
|
|
736
733
|
margin-inline-start:var(--space-3);
|
|
737
734
|
}
|
|
738
|
-
.bp_accordion_module_accordionTrigger--
|
|
735
|
+
.bp_accordion_module_accordionTrigger--eb917[data-state=open] .bp_accordion_module_accordionTriggerIcon--eb917{
|
|
739
736
|
transform:rotate(180deg);
|
|
740
737
|
}
|
|
741
738
|
|