@neo4j-ndl/react 4.22.0 → 4.23.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/lib/cjs/_common/form-control/FormFieldLabel.js +52 -0
- package/lib/cjs/_common/form-control/FormFieldLabel.js.map +1 -0
- package/lib/cjs/_common/form-control/FormFieldMessage.js +72 -0
- package/lib/cjs/_common/form-control/FormFieldMessage.js.map +1 -0
- package/lib/cjs/_common/form-control/form-control-types.js +23 -0
- package/lib/cjs/_common/form-control/form-control-types.js.map +1 -0
- package/lib/cjs/_common/form-control/index.js +39 -0
- package/lib/cjs/_common/form-control/index.js.map +1 -0
- package/lib/cjs/_common/form-control/use-form-field.js +76 -0
- package/lib/cjs/_common/form-control/use-form-field.js.map +1 -0
- package/lib/cjs/_common/form-control/use-inline-field-label.js +76 -0
- package/lib/cjs/_common/form-control/use-inline-field-label.js.map +1 -0
- package/lib/cjs/checkbox/Checkbox.js +9 -21
- package/lib/cjs/checkbox/Checkbox.js.map +1 -1
- package/lib/cjs/combobox/Combobox.js +75 -53
- package/lib/cjs/combobox/Combobox.js.map +1 -1
- package/lib/cjs/combobox/combobox-types.js.map +1 -1
- package/lib/cjs/date-picker/DatePicker.js.map +1 -1
- package/lib/cjs/icons/generated/custom/FloppyDiskArrowTopRight.js +30 -0
- package/lib/cjs/icons/generated/custom/FloppyDiskArrowTopRight.js.map +1 -0
- package/lib/cjs/icons/generated/custom/OpenQueryTab.js +1 -0
- package/lib/cjs/icons/generated/custom/OpenQueryTab.js.map +1 -1
- package/lib/cjs/icons/generated/custom/index.js +5 -3
- package/lib/cjs/icons/generated/custom/index.js.map +1 -1
- package/lib/cjs/next/tree-view/TreeView.js +16 -1
- package/lib/cjs/next/tree-view/TreeView.js.map +1 -1
- package/lib/cjs/radio/Radio.js +12 -22
- package/lib/cjs/radio/Radio.js.map +1 -1
- package/lib/cjs/select/Select.js +14 -5
- package/lib/cjs/select/Select.js.map +1 -1
- package/lib/cjs/select/types.js.map +1 -1
- package/lib/cjs/switch/Switch.js +9 -21
- package/lib/cjs/switch/Switch.js.map +1 -1
- package/lib/cjs/text-area/TextArea.js +8 -21
- package/lib/cjs/text-area/TextArea.js.map +1 -1
- package/lib/cjs/text-input/TextInput.js +15 -38
- package/lib/cjs/text-input/TextInput.js.map +1 -1
- package/lib/cjs/text-input/stories/text-input-sizes.story.js +1 -1
- package/lib/cjs/text-input/stories/text-input-sizes.story.js.map +1 -1
- package/lib/cjs/time-picker/TimePicker.js +13 -7
- package/lib/cjs/time-picker/TimePicker.js.map +1 -1
- package/lib/cjs/timezone-picker/TimeZonePicker.js +13 -7
- package/lib/cjs/timezone-picker/TimeZonePicker.js.map +1 -1
- package/lib/esm/_common/form-control/FormFieldLabel.js +45 -0
- package/lib/esm/_common/form-control/FormFieldLabel.js.map +1 -0
- package/lib/esm/_common/form-control/FormFieldMessage.js +65 -0
- package/lib/esm/_common/form-control/FormFieldMessage.js.map +1 -0
- package/lib/esm/_common/form-control/form-control-types.js +22 -0
- package/lib/esm/_common/form-control/form-control-types.js.map +1 -0
- package/lib/esm/_common/form-control/index.js +32 -0
- package/lib/esm/_common/form-control/index.js.map +1 -0
- package/lib/esm/_common/form-control/use-form-field.js +72 -0
- package/lib/esm/_common/form-control/use-form-field.js.map +1 -0
- package/lib/esm/_common/form-control/use-inline-field-label.js +69 -0
- package/lib/esm/_common/form-control/use-inline-field-label.js.map +1 -0
- package/lib/esm/checkbox/Checkbox.js +10 -22
- package/lib/esm/checkbox/Checkbox.js.map +1 -1
- package/lib/esm/combobox/Combobox.js +76 -54
- package/lib/esm/combobox/Combobox.js.map +1 -1
- package/lib/esm/combobox/combobox-types.js.map +1 -1
- package/lib/esm/date-picker/DatePicker.js.map +1 -1
- package/lib/esm/icons/generated/custom/FloppyDiskArrowTopRight.js +28 -0
- package/lib/esm/icons/generated/custom/FloppyDiskArrowTopRight.js.map +1 -0
- package/lib/esm/icons/generated/custom/OpenQueryTab.js +1 -0
- package/lib/esm/icons/generated/custom/OpenQueryTab.js.map +1 -1
- package/lib/esm/icons/generated/custom/index.js +1 -0
- package/lib/esm/icons/generated/custom/index.js.map +1 -1
- package/lib/esm/next/tree-view/TreeView.js +16 -1
- package/lib/esm/next/tree-view/TreeView.js.map +1 -1
- package/lib/esm/radio/Radio.js +12 -22
- package/lib/esm/radio/Radio.js.map +1 -1
- package/lib/esm/select/Select.js +14 -5
- package/lib/esm/select/Select.js.map +1 -1
- package/lib/esm/select/types.js.map +1 -1
- package/lib/esm/switch/Switch.js +10 -22
- package/lib/esm/switch/Switch.js.map +1 -1
- package/lib/esm/text-area/TextArea.js +9 -22
- package/lib/esm/text-area/TextArea.js.map +1 -1
- package/lib/esm/text-input/TextInput.js +15 -38
- package/lib/esm/text-input/TextInput.js.map +1 -1
- package/lib/esm/text-input/stories/text-input-sizes.story.js +1 -1
- package/lib/esm/text-input/stories/text-input-sizes.story.js.map +1 -1
- package/lib/esm/time-picker/TimePicker.js +13 -7
- package/lib/esm/time-picker/TimePicker.js.map +1 -1
- package/lib/esm/timezone-picker/TimeZonePicker.js +13 -7
- package/lib/esm/timezone-picker/TimeZonePicker.js.map +1 -1
- package/lib/types/_common/form-control/FormFieldLabel.d.ts +58 -0
- package/lib/types/_common/form-control/FormFieldLabel.d.ts.map +1 -0
- package/lib/types/_common/form-control/FormFieldMessage.d.ts +46 -0
- package/lib/types/_common/form-control/FormFieldMessage.d.ts.map +1 -0
- package/lib/types/_common/form-control/form-control-types.d.ts +92 -0
- package/lib/types/_common/form-control/form-control-types.d.ts.map +1 -0
- package/lib/types/_common/form-control/index.d.ts +33 -0
- package/lib/types/_common/form-control/index.d.ts.map +1 -0
- package/lib/types/_common/form-control/use-form-field.d.ts +53 -0
- package/lib/types/_common/form-control/use-form-field.d.ts.map +1 -0
- package/lib/types/_common/form-control/use-inline-field-label.d.ts +69 -0
- package/lib/types/_common/form-control/use-inline-field-label.d.ts.map +1 -0
- package/lib/types/checkbox/Checkbox.d.ts.map +1 -1
- package/lib/types/combobox/Combobox.d.ts.map +1 -1
- package/lib/types/combobox/combobox-types.d.ts +6 -5
- package/lib/types/combobox/combobox-types.d.ts.map +1 -1
- package/lib/types/icons/generated/custom/FloppyDiskArrowTopRight.d.ts +29 -0
- package/lib/types/icons/generated/custom/FloppyDiskArrowTopRight.d.ts.map +1 -0
- package/lib/types/icons/generated/custom/OpenQueryTab.d.ts +1 -0
- package/lib/types/icons/generated/custom/OpenQueryTab.d.ts.map +1 -1
- package/lib/types/icons/generated/custom/index.d.ts +1 -0
- package/lib/types/icons/generated/custom/index.d.ts.map +1 -1
- package/lib/types/next/tree-view/TreeView.d.ts.map +1 -1
- package/lib/types/radio/Radio.d.ts.map +1 -1
- package/lib/types/select/Select.d.ts.map +1 -1
- package/lib/types/select/types.d.ts.map +1 -1
- package/lib/types/switch/Switch.d.ts.map +1 -1
- package/lib/types/text-area/TextArea.d.ts.map +1 -1
- package/lib/types/text-input/TextInput.d.ts.map +1 -1
- package/lib/types/text-input/stories/text-input-sizes.story.d.ts.map +1 -1
- package/lib/types/time-picker/TimePicker.d.ts +3 -1
- package/lib/types/time-picker/TimePicker.d.ts.map +1 -1
- package/lib/types/timezone-picker/TimeZonePicker.d.ts +4 -1
- package/lib/types/timezone-picker/TimeZonePicker.d.ts.map +1 -1
- package/package.json +3 -3
- package/skills/ndl-react/SKILL.md +7 -2
- package/skills/ndl-react/components/accordion.md +2 -0
- package/skills/ndl-react/components/ai/code-preview.md +4 -0
- package/skills/ndl-react/components/ai/file-tag.md +2 -0
- package/skills/ndl-react/components/ai/image-tag.md +2 -0
- package/skills/ndl-react/components/ai/more-files.md +2 -0
- package/skills/ndl-react/components/ai/presence.md +2 -0
- package/skills/ndl-react/components/ai/preview.md +2 -0
- package/skills/ndl-react/components/ai/prompt.md +2 -0
- package/skills/ndl-react/components/ai/reasoning.md +2 -0
- package/skills/ndl-react/components/ai/response.md +2 -0
- package/skills/ndl-react/components/ai/suggestion.md +2 -0
- package/skills/ndl-react/components/ai/thinking.md +2 -0
- package/skills/ndl-react/components/ai/tool-call.md +2 -0
- package/skills/ndl-react/components/ai/user-bubble.md +2 -0
- package/skills/ndl-react/components/avatar.md +2 -0
- package/skills/ndl-react/components/banner.md +2 -0
- package/skills/ndl-react/components/box.md +2 -0
- package/skills/ndl-react/components/breadcrumbs.md +2 -0
- package/skills/ndl-react/components/checkbox.md +2 -0
- package/skills/ndl-react/components/clean-icon-button.md +2 -0
- package/skills/ndl-react/components/clipboard-button.md +2 -0
- package/skills/ndl-react/components/code-block.md +2 -0
- package/skills/ndl-react/components/code.md +2 -0
- package/skills/ndl-react/components/color-picker.md +34 -32
- package/skills/ndl-react/components/combobox.md +5 -3
- package/skills/ndl-react/components/conditional-wrap.md +2 -0
- package/skills/ndl-react/components/data-grid.md +2 -0
- package/skills/ndl-react/components/date-picker.md +2 -0
- package/skills/ndl-react/components/dialog.md +2 -0
- package/skills/ndl-react/components/dismissible-tag.md +2 -0
- package/skills/ndl-react/components/divider.md +2 -0
- package/skills/ndl-react/components/drawer.md +2 -0
- package/skills/ndl-react/components/dropdown-button.md +2 -0
- package/skills/ndl-react/components/dropzone.md +7 -5
- package/skills/ndl-react/components/filled-button.md +2 -0
- package/skills/ndl-react/components/flex.md +2 -0
- package/skills/ndl-react/components/graph-label.md +2 -0
- package/skills/ndl-react/components/icon-button-array.md +2 -0
- package/skills/ndl-react/components/icon-button.md +2 -0
- package/skills/ndl-react/components/inline-edit.md +2 -0
- package/skills/ndl-react/components/kbd.md +2 -0
- package/skills/ndl-react/components/loading-bar.md +2 -0
- package/skills/ndl-react/components/loading-spinner.md +2 -0
- package/skills/ndl-react/components/logo.md +2 -0
- package/skills/ndl-react/components/menu.md +2 -0
- package/skills/ndl-react/components/modal.md +2 -0
- package/skills/ndl-react/components/next/tree-view.md +90 -2
- package/skills/ndl-react/components/outlined-button.md +2 -0
- package/skills/ndl-react/components/popover.md +2 -0
- package/skills/ndl-react/components/progress-bar.md +2 -0
- package/skills/ndl-react/components/radio.md +2 -0
- package/skills/ndl-react/components/read-only-tag.md +2 -0
- package/skills/ndl-react/components/segmented-control.md +2 -0
- package/skills/ndl-react/components/select-icon-button.md +2 -0
- package/skills/ndl-react/components/select.md +4 -0
- package/skills/ndl-react/components/selectable-tag.md +2 -0
- package/skills/ndl-react/components/side-navigation.md +2 -0
- package/skills/ndl-react/components/skeleton.md +2 -0
- package/skills/ndl-react/components/slider.md +2 -0
- package/skills/ndl-react/components/spotlight.md +2 -0
- package/skills/ndl-react/components/status-indicator.md +2 -0
- package/skills/ndl-react/components/status-label.md +2 -0
- package/skills/ndl-react/components/switch.md +2 -0
- package/skills/ndl-react/components/tabs.md +2 -0
- package/skills/ndl-react/components/tag.md +4 -0
- package/skills/ndl-react/components/text-area.md +2 -0
- package/skills/ndl-react/components/text-button.md +2 -0
- package/skills/ndl-react/components/text-input.md +8 -0
- package/skills/ndl-react/components/text-link.md +2 -0
- package/skills/ndl-react/components/time-picker.md +3 -0
- package/skills/ndl-react/components/timezone-picker.md +3 -0
- package/skills/ndl-react/components/tooltip.md +2 -0
- package/skills/ndl-react/components/tree-view.md +2 -0
- package/skills/ndl-react/components/typography.md +2 -0
- package/skills/ndl-react/components/wizard.md +2 -0
|
@@ -40,6 +40,7 @@ const react_1 = require("@floating-ui/react");
|
|
|
40
40
|
const react_virtual_1 = require("@tanstack/react-virtual");
|
|
41
41
|
const classnames_1 = __importDefault(require("classnames"));
|
|
42
42
|
const react_2 = require("react");
|
|
43
|
+
const form_control_1 = require("../_common/form-control");
|
|
43
44
|
const use_semi_controlled_state_1 = require("../_common/use-semi-controlled-state");
|
|
44
45
|
const utils_1 = require("../_common/utils");
|
|
45
46
|
const checkbox_1 = require("../checkbox");
|
|
@@ -108,9 +109,6 @@ const Combobox = ({ label, name, formId, autoComplete, triggerRef, hasVisuallyHi
|
|
|
108
109
|
const listboxId = `${baseId}-listbox`;
|
|
109
110
|
const panelId = `${baseId}-panel`;
|
|
110
111
|
const triggerId = `${baseId}-trigger`;
|
|
111
|
-
const labelId = `${baseId}-label`;
|
|
112
|
-
const helpTextId = `${baseId}-help-text`;
|
|
113
|
-
const errorTextId = `${baseId}-error-text`;
|
|
114
112
|
const initialValue = (0, combobox_utils_1.getInitialValue)(value, defaultValue, isMulti);
|
|
115
113
|
const [selectedValue, setSelectedValue, resetSelectedValue] = (0, use_semi_controlled_state_1.useSemicontrolledState)({
|
|
116
114
|
isControlled: value !== undefined,
|
|
@@ -144,7 +142,6 @@ const Combobox = ({ label, name, formId, autoComplete, triggerRef, hasVisuallyHi
|
|
|
144
142
|
isPortaled,
|
|
145
143
|
onOpenChange: setIsPanelOpen,
|
|
146
144
|
});
|
|
147
|
-
const hasCustomTrigger = renderTrigger !== undefined;
|
|
148
145
|
const builtInTriggerRef = (0, react_1.useMergeRefs)([internalTriggerRef, triggerRef]);
|
|
149
146
|
const customTriggerRef = (0, react_1.useMergeRefs)([
|
|
150
147
|
refs.setReference,
|
|
@@ -468,13 +465,22 @@ const Combobox = ({ label, name, formId, autoComplete, triggerRef, hasVisuallyHi
|
|
|
468
465
|
? actionRows.map((row) => getOptionId(row)).join(' ')
|
|
469
466
|
: undefined;
|
|
470
467
|
const isDialogPanel = isSearchable;
|
|
471
|
-
//
|
|
472
|
-
//
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
468
|
+
// The shared form field resolves the ids and which message is displayed -
|
|
469
|
+
// an error always replaces the help text. A native validation failure
|
|
470
|
+
// reported by the hidden form control acts as the error while no errorText
|
|
471
|
+
// is set.
|
|
472
|
+
const { field: formField, controlProps: fieldControlProps } = (0, form_control_1.useFormField)({
|
|
473
|
+
baseId,
|
|
474
|
+
controlId: triggerId,
|
|
475
|
+
errorText: errorText !== null && errorText !== void 0 ? errorText : nativeValidationMessage,
|
|
476
|
+
hasRequiredIndicator,
|
|
477
|
+
hasVisuallyHiddenLabel,
|
|
478
|
+
helpText,
|
|
479
|
+
isRequired,
|
|
480
|
+
label,
|
|
481
|
+
});
|
|
482
|
+
const hasError = formField.hasError;
|
|
483
|
+
const labelId = formField.labelId;
|
|
478
484
|
const triggerAria = {
|
|
479
485
|
'aria-activedescendant': isPanelOpen && !isSearchable ? activeOptionId : undefined,
|
|
480
486
|
'aria-controls': getTriggerControlsId({
|
|
@@ -484,11 +490,11 @@ const Combobox = ({ label, name, formId, autoComplete, triggerRef, hasVisuallyHi
|
|
|
484
490
|
listboxId,
|
|
485
491
|
panelId,
|
|
486
492
|
}),
|
|
487
|
-
'aria-describedby':
|
|
493
|
+
'aria-describedby': fieldControlProps['aria-describedby'],
|
|
488
494
|
'aria-disabled': isDisabled ? true : undefined,
|
|
489
495
|
'aria-expanded': isPanelOpen,
|
|
490
496
|
'aria-haspopup': isDialogPanel ? 'dialog' : 'listbox',
|
|
491
|
-
'aria-invalid':
|
|
497
|
+
'aria-invalid': fieldControlProps['aria-invalid'],
|
|
492
498
|
'aria-required': isRequired ? true : undefined,
|
|
493
499
|
// The label points at the trigger through `htmlFor`, so clicking it moves
|
|
494
500
|
// focus to the trigger.
|
|
@@ -508,13 +514,13 @@ const Combobox = ({ label, name, formId, autoComplete, triggerRef, hasVisuallyHi
|
|
|
508
514
|
// is referenced, keeping "Optional" out of the accessible name.
|
|
509
515
|
'aria-labelledby': labelId, ref: builtInTriggerRef });
|
|
510
516
|
const field = {
|
|
511
|
-
errorText:
|
|
512
|
-
errorTextId,
|
|
517
|
+
errorText: formField.errorText,
|
|
518
|
+
errorTextId: formField.errorTextId,
|
|
513
519
|
hasError,
|
|
514
520
|
hasRequiredIndicator,
|
|
515
521
|
hasVisuallyHiddenLabel,
|
|
516
522
|
helpText,
|
|
517
|
-
helpTextId,
|
|
523
|
+
helpTextId: formField.helpTextId,
|
|
518
524
|
isRequired,
|
|
519
525
|
label,
|
|
520
526
|
labelId,
|
|
@@ -569,20 +575,27 @@ const Combobox = ({ label, name, formId, autoComplete, triggerRef, hasVisuallyHi
|
|
|
569
575
|
id: listboxId,
|
|
570
576
|
role: 'listbox',
|
|
571
577
|
}), { className: "ndl-combobox-actions", children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, { className: "ndl-combobox-action-divider", htmlAttributes: { 'aria-hidden': true } }), actionRows.map((row, index) => ((0, jsx_runtime_1.jsxs)(react_2.Fragment, { children: [index > 0 && (0, combobox_utils_1.getAction)(row).hasDivider === true && ((0, jsx_runtime_1.jsx)(divider_1.Divider, { className: "ndl-combobox-action-divider", htmlAttributes: { 'aria-hidden': true } })), renderAction(row)] }, row.value)))] })))] })));
|
|
572
|
-
|
|
578
|
+
const formControl = name !== undefined && ((0, jsx_runtime_1.jsx)(ComboboxFormControl, { ref: internalTriggerRef, name: name, form: formId, autoComplete: autoComplete, options: formOptions, selectedOptions: selectedOptions, resetSelectedOptions: resetSelectedOptions, isMulti: isMulti, isDisabled: isDisabled, isRequired: isRequired, isSelectionControlled: value !== undefined, onValueChange: setSelectedValue, onInvalid: setNativeValidationMessage, onReset: resetFromForm }));
|
|
579
|
+
const floatingPanel = context.open && ((0, jsx_runtime_1.jsx)(conditional_wrap_1.ConditionalWrap, { shouldWrap: isPanelPortaled, wrap: (wrapChildren) => ((0, jsx_runtime_1.jsx)(react_1.FloatingPortal, { root: portalTarget, children: wrapChildren })), children: (0, jsx_runtime_1.jsx)(react_1.FloatingFocusManager, { context: context, modal: false,
|
|
580
|
+
// A select-only combobox keeps DOM focus on the trigger and speaks
|
|
581
|
+
// through aria-activedescendant, so nothing inside is focused.
|
|
582
|
+
initialFocus: isSearchable ? searchInputRef : -1, returnFocus: internalTriggerRef, children: panel }) }));
|
|
583
|
+
// No root element around a custom trigger, so the trigger is a real child of
|
|
584
|
+
// whatever holds the combobox and sibling-based selectors there match it.
|
|
585
|
+
// The form control goes after the trigger to keep it out of leading
|
|
586
|
+
// positional slots.
|
|
587
|
+
if (renderTrigger !== undefined) {
|
|
588
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [renderTrigger(triggerProps, triggerState), formControl, floatingPanel] }));
|
|
589
|
+
}
|
|
590
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ ref: ref, style: style, className: (0, classnames_1.default)('ndl-combobox ndl-combobox-field', {
|
|
573
591
|
'ndl-clean': isClean,
|
|
574
|
-
'ndl-combobox-custom-trigger': hasCustomTrigger,
|
|
575
|
-
'ndl-combobox-field': !hasCustomTrigger,
|
|
576
592
|
'ndl-disabled': isDisabled,
|
|
577
593
|
'ndl-fluid': isFluid,
|
|
578
594
|
'ndl-has-error': hasError,
|
|
579
595
|
'ndl-large': size === 'large',
|
|
580
596
|
'ndl-medium': size === 'medium',
|
|
581
597
|
'ndl-small': size === 'small',
|
|
582
|
-
}, className) }, htmlAttributes, { children: [
|
|
583
|
-
// A select-only combobox keeps DOM focus on the trigger and speaks
|
|
584
|
-
// through aria-activedescendant, so nothing inside is focused.
|
|
585
|
-
initialFocus: isSearchable ? searchInputRef : -1, returnFocus: internalTriggerRef, children: panel }) }))] })));
|
|
598
|
+
}, className) }, htmlAttributes, { children: [formControl, (0, jsx_runtime_1.jsx)(Control, { triggerProps: builtInTriggerProps, state: triggerState, field: field, placeholder: placeholder, isClearable: isClearable, isClean: isClean, size: size, maxRows: isMulti ? maxRows : undefined, components: components, referenceProps: getReferenceProps(), referenceRef: refs.setReference }), floatingPanel] })));
|
|
586
599
|
};
|
|
587
600
|
exports.Combobox = Combobox;
|
|
588
601
|
const getTriggerControlsId = ({ isPanelOpen, isDialogPanel, hasRows, panelId, listboxId, }) => {
|
|
@@ -602,6 +615,42 @@ const getSelectedOptions = (value) => {
|
|
|
602
615
|
}
|
|
603
616
|
return value === null ? [] : [value];
|
|
604
617
|
};
|
|
618
|
+
/**
|
|
619
|
+
* The public `ComboboxFieldState` keeps its own shape - a custom trigger
|
|
620
|
+
* renders from it - so the built-in field parts map it onto the shared form
|
|
621
|
+
* field state (`_common/form-control`) instead of taking it directly.
|
|
622
|
+
*/
|
|
623
|
+
const toFormFieldState = (field) => {
|
|
624
|
+
const hasHelpText = Boolean(field.helpText) && !field.hasError;
|
|
625
|
+
return {
|
|
626
|
+
controlId: field.triggerId,
|
|
627
|
+
errorText: field.errorText,
|
|
628
|
+
errorTextId: field.errorTextId,
|
|
629
|
+
hasError: field.hasError,
|
|
630
|
+
hasRequiredIndicator: field.hasRequiredIndicator,
|
|
631
|
+
hasVisuallyHiddenLabel: field.hasVisuallyHiddenLabel,
|
|
632
|
+
helpText: field.helpText,
|
|
633
|
+
helpTextId: field.helpTextId,
|
|
634
|
+
isRequired: field.isRequired,
|
|
635
|
+
label: field.label,
|
|
636
|
+
labelId: field.labelId,
|
|
637
|
+
message: field.hasError
|
|
638
|
+
? field.errorText
|
|
639
|
+
: hasHelpText
|
|
640
|
+
? field.helpText
|
|
641
|
+
: undefined,
|
|
642
|
+
messageId: field.hasError
|
|
643
|
+
? field.errorTextId
|
|
644
|
+
: hasHelpText
|
|
645
|
+
? field.helpTextId
|
|
646
|
+
: undefined,
|
|
647
|
+
messageSeverity: field.hasError
|
|
648
|
+
? 'error'
|
|
649
|
+
: hasHelpText
|
|
650
|
+
? 'help'
|
|
651
|
+
: undefined,
|
|
652
|
+
};
|
|
653
|
+
};
|
|
605
654
|
/**
|
|
606
655
|
* A native select mirrors the custom control for submission, autofill,
|
|
607
656
|
* constraint validation, and reset. It is hidden from assistive technology
|
|
@@ -698,6 +747,7 @@ const Control = ({ triggerProps, state, field, placeholder, isClearable, isClean
|
|
|
698
747
|
const { isOpen, isMulti, isDisabled, selectedOptions, clear, remove } = state;
|
|
699
748
|
const { MultiValue, SingleValue } = components;
|
|
700
749
|
const { ref: triggerRef } = triggerProps, triggerAria = __rest(triggerProps, ["ref"]);
|
|
750
|
+
const sharedField = toFormFieldState(field);
|
|
701
751
|
const hasValue = selectedOptions.length > 0;
|
|
702
752
|
const singleValueOption = isMulti ? undefined : selectedOptions[0];
|
|
703
753
|
// Selected values are shown as tags, so the trigger renders nothing and is
|
|
@@ -807,7 +857,7 @@ const Control = ({ triggerProps, state, field, placeholder, isClearable, isClean
|
|
|
807
857
|
return (
|
|
808
858
|
// A fragment, so the label, the control, and the message are rows of the
|
|
809
859
|
// combobox itself. A custom trigger replaces all three.
|
|
810
|
-
(0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(
|
|
860
|
+
(0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(form_control_1.FormFieldLabel, { field: sharedField, size: size, onLabelClick: handleLabelClick }), (0, jsx_runtime_1.jsxs)("div", Object.assign({ ref: referenceRef, className: (0, classnames_1.default)('ndl-combobox-control', {
|
|
811
861
|
'ndl-clean': isClean,
|
|
812
862
|
'ndl-disabled': isDisabled,
|
|
813
863
|
'ndl-has-error': field.hasError,
|
|
@@ -853,35 +903,7 @@ const Control = ({ triggerProps, state, field, placeholder, isClearable, isClean
|
|
|
853
903
|
// Select.
|
|
854
904
|
(0, jsx_runtime_1.jsxs)("div", { className: "ndl-combobox-clear", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: "ndl-combobox-clear-button", "aria-label": "Clear selection", onKeyDown: handleAuxiliaryActionKeyDown, onClick: handleClear, children: (0, jsx_runtime_1.jsx)(heroIcons_1.XMarkIconOutline, {}) }), (0, jsx_runtime_1.jsx)("div", { className: "ndl-combobox-divider" })] })), (0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('ndl-combobox-dropdown-indicator', {
|
|
855
905
|
'ndl-open': isOpen,
|
|
856
|
-
}), children: (0, jsx_runtime_1.jsx)(heroIcons_1.ChevronDownIconOutline, { "aria-hidden": "true", className: "ndl-combobox-icon" }) })] })] })), (0, jsx_runtime_1.jsx)(
|
|
857
|
-
};
|
|
858
|
-
/**
|
|
859
|
-
* The trigger is a button with `role="combobox"`, which takes its accessible
|
|
860
|
-
* name from the author rather than from its content, so the label is referenced
|
|
861
|
-
* through `aria-labelledby` instead of wrapping the control in a `<label>`.
|
|
862
|
-
* The label is still a `<label>` associated through `htmlFor`, and clicking it
|
|
863
|
-
* moves focus to the trigger, as with a native select. It deliberately does
|
|
864
|
-
* not open the panel, which is also what a native select label leaves alone.
|
|
865
|
-
*/
|
|
866
|
-
const FieldLabel = ({ field, size, onLabelClick }) => {
|
|
867
|
-
const { label, labelId, triggerId, hasVisuallyHiddenLabel, hasRequiredIndicator, isRequired, } = field;
|
|
868
|
-
const variant = size === 'large' ? 'body-large' : 'body-medium';
|
|
869
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('ndl-combobox-label-row', {
|
|
870
|
-
'ndl-visually-hidden': hasVisuallyHiddenLabel,
|
|
871
|
-
}), children: [(0, jsx_runtime_1.jsx)(typography_1.Typography, { as: "label", variant: variant, className: "ndl-combobox-label", htmlAttributes: {
|
|
872
|
-
htmlFor: triggerId,
|
|
873
|
-
id: labelId,
|
|
874
|
-
onClick: onLabelClick,
|
|
875
|
-
}, children: label }), hasRequiredIndicator && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { variant: variant, className: "ndl-combobox-label-indicator", children: isRequired ? 'Required' : 'Optional' }))] }));
|
|
876
|
-
};
|
|
877
|
-
/**
|
|
878
|
-
* Rendered whether or not there is a message, so the live region is in the
|
|
879
|
-
* document before the text arrives and a validation error is announced.
|
|
880
|
-
*/
|
|
881
|
-
const FieldMessage = ({ field, size }) => {
|
|
882
|
-
const { errorText, hasError, helpText, helpTextId, errorTextId } = field;
|
|
883
|
-
const variant = size === 'large' ? 'body-medium' : 'body-small';
|
|
884
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "ndl-combobox-message", "aria-live": "polite", children: [hasError && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "ndl-error-icon", children: (0, jsx_runtime_1.jsx)(heroIcons_1.ExclamationCircleIconSolid, {}) }), (0, jsx_runtime_1.jsx)(typography_1.Typography, { variant: variant, className: "ndl-error-text", htmlAttributes: { id: errorTextId }, children: errorText })] })), !hasError && Boolean(helpText) && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { variant: variant, htmlAttributes: { id: helpTextId }, children: helpText }))] }));
|
|
906
|
+
}), children: (0, jsx_runtime_1.jsx)(heroIcons_1.ChevronDownIconOutline, { "aria-hidden": "true", className: "ndl-combobox-icon" }) })] })] })), (0, jsx_runtime_1.jsx)(form_control_1.FormFieldMessage, { field: sharedField, size: size })] }));
|
|
885
907
|
};
|
|
886
908
|
const Panel = (_a) => {
|
|
887
909
|
var { children, ref, id, ariaLabel, isDialog, className, style } = _a, restProps = __rest(_a, ["children", "ref", "id", "ariaLabel", "isDialog", "className", "style"]);
|