xmlui 0.10.15 → 0.10.18
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/{index-axjeT2uJ.mjs → index-Cy6Emsex.mjs} +3452 -1954
- package/dist/lib/index.css +1 -1
- package/dist/lib/{initMock-BoTWMs19.mjs → initMock-B-rmnC-t.mjs} +1 -1
- package/dist/lib/xmlui-parser.d.ts +1 -1
- package/dist/lib/xmlui.d.ts +4 -6
- package/dist/lib/xmlui.mjs +1 -1
- package/dist/metadata/{collectedComponentMetadata-CQywuPDB.mjs → collectedComponentMetadata-CB63ngkU.mjs} +3845 -2357
- package/dist/metadata/{initMock-Bi5kF5Af.mjs → initMock-D0wDKF_I.mjs} +1 -1
- package/dist/metadata/style.css +1 -1
- package/dist/metadata/xmlui-metadata.mjs +1 -1
- package/dist/metadata/xmlui-metadata.umd.js +3 -3
- package/dist/scripts/package.json +1 -1
- package/dist/scripts/src/components/Accordion/Accordion.spec.js +1 -1
- package/dist/scripts/src/components/Accordion/AccordionItemNative.js +1 -1
- package/dist/scripts/src/components/Animation/AnimationNative.js +5 -1
- package/dist/scripts/src/components/AutoComplete/AutoComplete.js +1 -5
- package/dist/scripts/src/components/AutoComplete/AutoComplete.spec.js +29 -0
- package/dist/scripts/src/components/AutoComplete/AutoCompleteContext.js +2 -0
- package/dist/scripts/src/components/AutoComplete/AutoCompleteNative.js +262 -62
- package/dist/scripts/src/components/Checkbox/Checkbox.js +1 -5
- package/dist/scripts/src/components/ColorPicker/ColorPicker.js +2 -6
- package/dist/scripts/src/components/ColorPicker/ColorPicker.spec.js +29 -0
- package/dist/scripts/src/components/ColorPicker/ColorPickerNative.js +12 -9
- package/dist/scripts/src/components/ComponentProvider.js +2 -0
- package/dist/scripts/src/components/DateInput/DateInput.js +1 -5
- package/dist/scripts/src/components/DateInput/DateInput.spec.js +29 -0
- package/dist/scripts/src/components/DateInput/DateInputNative.js +12 -16
- package/dist/scripts/src/components/DatePicker/DatePicker.js +1 -5
- package/dist/scripts/src/components/DatePicker/DatePicker.spec.js +29 -0
- package/dist/scripts/src/components/DatePicker/DatePickerNative.js +12 -13
- package/dist/scripts/src/components/FileInput/FileInput.js +1 -5
- package/dist/scripts/src/components/FileInput/FileInput.spec.js +29 -0
- package/dist/scripts/src/components/FileInput/FileInputNative.js +14 -15
- package/dist/scripts/src/components/Form/Form.spec.js +11 -9
- package/dist/scripts/src/components/Form/FormNative.js +41 -27
- package/dist/scripts/src/components/FormItem/FormItem.spec.js +179 -30
- package/dist/scripts/src/components/FormItem/FormItemNative.js +20 -22
- package/dist/scripts/src/components/FormItem/ItemWithLabel.js +8 -17
- package/dist/scripts/src/components/FormItem/Validations.js +25 -6
- package/dist/scripts/src/components/Icon/IconNative.js +18 -15
- package/dist/scripts/src/components/Input/PartialInput.js +2 -2
- package/dist/scripts/src/components/NestedApp/AppWithCodeViewNative.js +1 -1
- package/dist/scripts/src/components/NumberBox/NumberBox.js +5 -9
- package/dist/scripts/src/components/NumberBox/NumberBox.spec.js +142 -430
- package/dist/scripts/src/components/NumberBox/NumberBoxNative.js +33 -21
- package/dist/scripts/src/components/Option/Option.js +3 -1
- package/dist/scripts/src/components/RadioGroup/RadioGroup.js +1 -5
- package/dist/scripts/src/components/RadioGroup/RadioGroupNative.js +4 -5
- package/dist/scripts/src/components/RadioGroup/RadioItem.js +28 -0
- package/dist/scripts/src/components/Select/HiddenOption.js +1 -1
- package/dist/scripts/src/components/Select/Select.js +1 -5
- package/dist/scripts/src/components/Select/Select.spec.js +31 -3
- package/dist/scripts/src/components/Select/SelectNative.js +26 -32
- package/dist/scripts/src/components/Slider/Slider.js +1 -5
- package/dist/scripts/src/components/Slider/Slider.spec.js +75 -13
- package/dist/scripts/src/components/Slider/SliderNative.js +33 -24
- package/dist/scripts/src/components/Switch/Switch.js +1 -5
- package/dist/scripts/src/components/TextArea/TextArea.js +1 -5
- package/dist/scripts/src/components/TextArea/TextArea.spec.js +29 -0
- package/dist/scripts/src/components/TextArea/TextAreaNative.js +8 -29
- package/dist/scripts/src/components/TextBox/TextBox.spec.js +38 -7
- package/dist/scripts/src/components/TextBox/TextBoxNative.js +2 -2
- package/dist/scripts/src/components/TimeInput/TimeInput.spec.js +31 -0
- package/dist/scripts/src/components/Timer/Timer.spec.js +66 -96
- package/dist/scripts/src/components/Toggle/Toggle.js +28 -25
- package/dist/scripts/src/components/Tree/Tree-dynamic.spec.js +2894 -0
- package/dist/scripts/src/components/Tree/Tree-icons.spec.js +206 -0
- package/dist/scripts/src/components/Tree/Tree.spec.js +2839 -0
- package/dist/scripts/src/components/Tree/TreeComponent.js +303 -10
- package/dist/scripts/src/components/Tree/TreeNative.js +1090 -23
- package/dist/scripts/src/components/Tree/testData.js +296 -0
- package/dist/scripts/src/components-core/behaviors/Behavior.js +2 -0
- package/dist/scripts/src/components-core/behaviors/CoreBehaviors.js +8 -4
- package/dist/scripts/src/components-core/rendering/AppRoot.js +1 -2
- package/dist/scripts/src/components-core/rendering/ComponentAdapter.js +13 -15
- package/dist/scripts/src/components-core/utils/treeUtils.js +190 -12
- package/dist/scripts/src/testing/ComponentDrivers.js +79 -7
- package/dist/scripts/src/testing/drivers/NumberBoxDriver.js +2 -2
- package/dist/scripts/src/testing/drivers/TreeDriver.js +13 -0
- package/dist/scripts/src/testing/fixtures.js +7 -2
- package/dist/standalone/xmlui-standalone.es.d.ts +4 -6
- package/dist/standalone/xmlui-standalone.umd.js +36 -36
- package/package.json +1 -1
- package/dist/scripts/src/components/Animation/Animation.js +0 -50
- package/dist/scripts/src/components-core/behaviors/BehaviorContext.js +0 -54
- package/dist/scripts/src/testing/drivers/SliderDriver.js +0 -20
|
@@ -58,7 +58,6 @@ const numberbox_abstractions_1 = require("./numberbox-abstractions");
|
|
|
58
58
|
const IconNative_1 = require("../Icon/IconNative");
|
|
59
59
|
const InputAdornment_1 = require("../Input/InputAdornment");
|
|
60
60
|
const ButtonNative_1 = require("../Button/ButtonNative");
|
|
61
|
-
const ItemWithLabel_1 = require("../FormItem/ItemWithLabel");
|
|
62
61
|
const parts_1 = require("../../components-core/parts");
|
|
63
62
|
const PART_SPINNER_UP = "spinnerUp";
|
|
64
63
|
const PART_SPINNER_DOWN = "spinnerDown";
|
|
@@ -79,13 +78,15 @@ exports.defaultProps = {
|
|
|
79
78
|
};
|
|
80
79
|
exports.NumberBox = (0, react_1.forwardRef)(function NumberBox(_a, forwardedRef) {
|
|
81
80
|
var _b;
|
|
82
|
-
var { id, value, initialValue, style, className, enabled = exports.defaultProps.enabled, placeholder, validationStatus = exports.defaultProps.validationStatus, hasSpinBox = exports.defaultProps.hasSpinBox, step = exports.defaultProps.step, integersOnly = exports.defaultProps.integersOnly, zeroOrPositive = exports.defaultProps.zeroOrPositive, min = zeroOrPositive ? 0 : exports.defaultProps.min, max = exports.defaultProps.max, maxLength, updateState = exports.defaultProps.updateState, onDidChange = exports.defaultProps.onDidChange, onFocus = exports.defaultProps.onFocus, onBlur = exports.defaultProps.onBlur, registerComponentApi, startText, startIcon, endText, endIcon, gap, spinnerUpIcon, spinnerDownIcon, autoFocus, readOnly, required,
|
|
81
|
+
var { id, value, initialValue, style, className, enabled = exports.defaultProps.enabled, placeholder, validationStatus = exports.defaultProps.validationStatus, hasSpinBox = exports.defaultProps.hasSpinBox, step = exports.defaultProps.step, integersOnly = exports.defaultProps.integersOnly, zeroOrPositive = exports.defaultProps.zeroOrPositive, min = zeroOrPositive ? 0 : exports.defaultProps.min, max = exports.defaultProps.max, maxLength, updateState = exports.defaultProps.updateState, onDidChange = exports.defaultProps.onDidChange, onFocus = exports.defaultProps.onFocus, onBlur = exports.defaultProps.onBlur, registerComponentApi, startText, startIcon, endText, endIcon, gap, spinnerUpIcon, spinnerDownIcon, autoFocus, readOnly, required, direction } = _a, rest = __rest(_a, ["id", "value", "initialValue", "style", "className", "enabled", "placeholder", "validationStatus", "hasSpinBox", "step", "integersOnly", "zeroOrPositive", "min", "max", "maxLength", "updateState", "onDidChange", "onFocus", "onBlur", "registerComponentApi", "startText", "startIcon", "endText", "endIcon", "gap", "spinnerUpIcon", "spinnerDownIcon", "autoFocus", "readOnly", "required", "direction"]);
|
|
83
82
|
const _id = (0, react_1.useId)();
|
|
84
83
|
id = id || _id;
|
|
85
84
|
// --- Ensure the provided value is a number or null
|
|
86
85
|
// Ensure the provided minimum is not smaller than the 0 if zeroOrPositive is set to true
|
|
87
86
|
min = Math.max(zeroOrPositive ? 0 : -numberbox_abstractions_1.NUMBERBOX_MAX_VALUE, min);
|
|
88
87
|
// Step must be an integer since floating point arithmetic needs a deeper dive.
|
|
88
|
+
// probably some way to integrate with https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
|
|
89
|
+
// since there are footguns, like 0.1 + 0.2 = 0.0000...04
|
|
89
90
|
const _step = (_b = (0, numberbox_abstractions_1.toUsableNumber)(step, true)) !== null && _b !== void 0 ? _b : numberbox_abstractions_1.DEFAULT_STEP;
|
|
90
91
|
const inputRef = (0, react_1.useRef)(null);
|
|
91
92
|
const upButton = (0, react_1.useRef)(null);
|
|
@@ -414,10 +415,22 @@ exports.NumberBox = (0, react_1.forwardRef)(function NumberBox(_a, forwardedRef)
|
|
|
414
415
|
if (!integersOnly && currentInputValue.endsWith(numberbox_abstractions_1.DECIMAL_SEPARATOR)) {
|
|
415
416
|
// --- Add trailing zero if the value ends with decimal separator
|
|
416
417
|
finalValue = currentInputValue + "0";
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
418
|
+
}
|
|
419
|
+
// --- Convert to number and clamp to min/max bounds
|
|
420
|
+
const numericValue = (0, numberbox_abstractions_1.toUsableNumber)(finalValue, integersOnly);
|
|
421
|
+
if (!(0, numberbox_abstractions_1.isEmptyLike)(numericValue)) {
|
|
422
|
+
const clampedValue = (0, numberbox_abstractions_1.clamp)(numericValue, min, max);
|
|
423
|
+
if (clampedValue !== numericValue) {
|
|
424
|
+
const clampedString = clampedValue.toString();
|
|
425
|
+
finalValue = clampedString;
|
|
426
|
+
// --- Update the input field immediately
|
|
427
|
+
if (inputRef.current) {
|
|
428
|
+
inputRef.current.value = clampedString;
|
|
429
|
+
}
|
|
420
430
|
}
|
|
431
|
+
}
|
|
432
|
+
// --- Update the state if the final value is different from current input
|
|
433
|
+
if (finalValue !== currentInputValue) {
|
|
421
434
|
updateValue(finalValue, finalValue);
|
|
422
435
|
}
|
|
423
436
|
else {
|
|
@@ -425,7 +438,7 @@ exports.NumberBox = (0, react_1.forwardRef)(function NumberBox(_a, forwardedRef)
|
|
|
425
438
|
setValueStrRep((0, numberbox_abstractions_1.mapToRepresentation)(value));
|
|
426
439
|
}
|
|
427
440
|
onBlur === null || onBlur === void 0 ? void 0 : onBlur();
|
|
428
|
-
}, [value, onBlur, integersOnly, updateValue]);
|
|
441
|
+
}, [value, onBlur, integersOnly, updateValue, min, max]);
|
|
429
442
|
const focus = (0, react_1.useCallback)(() => {
|
|
430
443
|
var _a;
|
|
431
444
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
@@ -439,21 +452,20 @@ exports.NumberBox = (0, react_1.forwardRef)(function NumberBox(_a, forwardedRef)
|
|
|
439
452
|
setValue,
|
|
440
453
|
});
|
|
441
454
|
}, [focus, registerComponentApi, setValue]);
|
|
442
|
-
return ((0, jsx_runtime_1.
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}), disabled: !enabled, value: valueStrRep, step: step, placeholder: placeholder, onChange: onInputChange, onFocus: handleOnFocus, onBlur: handleOnBlur, onBeforeInput: handleOnBeforeInput, onPaste: handleOnPaste, onKeyDown: handleOnKey, readOnly: readOnly, ref: inputRef, autoFocus: autoFocus, maxLength: maxLength, required: required }), (0, jsx_runtime_1.jsx)(InputAdornment_1.Adornment, { "data-part-id": parts_1.PART_END_ADORNMENT, text: endText, iconName: endIcon, className: (0, classnames_1.default)(NumberBox_module_scss_1.default.adornment) }), hasSpinBox && ((0, jsx_runtime_1.jsxs)("div", { className: NumberBox_module_scss_1.default.spinnerBox, children: [(0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-part-id": PART_SPINNER_UP, "data-spinner": "up", type: "button", role: "spinbutton", variant: "ghost", themeColor: "secondary", tabIndex: -1, className: NumberBox_module_scss_1.default.spinnerButton, disabled: !enabled || readOnly, ref: upButton, children: (0, jsx_runtime_1.jsx)(IconNative_1.Icon, { name: spinnerUpIcon || "spinnerUp:NumberBox", fallback: "chevronup", size: "sm" }) }), (0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-part-id": PART_SPINNER_DOWN, "data-spinner": "down", type: "button", role: "spinbutton", tabIndex: -1, variant: "ghost", themeColor: "secondary", className: NumberBox_module_scss_1.default.spinnerButton, disabled: !enabled || readOnly, ref: downButton, children: (0, jsx_runtime_1.jsx)(IconNative_1.Icon, { name: spinnerDownIcon || "spinnerDown:NumberBox", fallback: "chevrondown", size: "sm" }) })] }))] }) })));
|
|
455
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({}, rest, { className: (0, classnames_1.default)(className, NumberBox_module_scss_1.default.inputRoot, {
|
|
456
|
+
[NumberBox_module_scss_1.default.readOnly]: readOnly,
|
|
457
|
+
[NumberBox_module_scss_1.default.disabled]: !enabled,
|
|
458
|
+
[NumberBox_module_scss_1.default.noSpinBox]: !hasSpinBox,
|
|
459
|
+
[NumberBox_module_scss_1.default.error]: validationStatus === "error",
|
|
460
|
+
[NumberBox_module_scss_1.default.warning]: validationStatus === "warning",
|
|
461
|
+
[NumberBox_module_scss_1.default.valid]: validationStatus === "valid",
|
|
462
|
+
[NumberBox_module_scss_1.default.rtl]: direction === "rtl",
|
|
463
|
+
}), id: id, ref: forwardedRef, tabIndex: -1, onFocus: () => {
|
|
464
|
+
var _a;
|
|
465
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
466
|
+
}, style: Object.assign(Object.assign({}, style), { gap }), children: [(0, jsx_runtime_1.jsx)(InputAdornment_1.Adornment, { "data-part-id": parts_1.PART_START_ADORNMENT, text: startText, iconName: startIcon, className: (0, classnames_1.default)(NumberBox_module_scss_1.default.adornment) }), (0, jsx_runtime_1.jsx)("input", { id: id, "data-part-id": parts_1.PART_INPUT, type: "text", inputMode: "numeric", className: (0, classnames_1.default)(NumberBox_module_scss_1.default.input, {
|
|
467
|
+
[NumberBox_module_scss_1.default.readOnly]: readOnly,
|
|
468
|
+
}), disabled: !enabled, value: valueStrRep, step: step, placeholder: placeholder, onChange: onInputChange, onFocus: handleOnFocus, onBlur: handleOnBlur, onBeforeInput: handleOnBeforeInput, onPaste: handleOnPaste, onKeyDown: handleOnKey, readOnly: readOnly, ref: inputRef, autoFocus: autoFocus, maxLength: maxLength, required: required }), (0, jsx_runtime_1.jsx)(InputAdornment_1.Adornment, { "data-part-id": parts_1.PART_END_ADORNMENT, text: endText, iconName: endIcon, className: (0, classnames_1.default)(NumberBox_module_scss_1.default.adornment) }), hasSpinBox && ((0, jsx_runtime_1.jsxs)("div", { className: NumberBox_module_scss_1.default.spinnerBox, children: [(0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-part-id": PART_SPINNER_UP, "data-spinner": "up", type: "button", role: "spinbutton", variant: "ghost", themeColor: "secondary", tabIndex: -1, className: NumberBox_module_scss_1.default.spinnerButton, disabled: !enabled || readOnly, ref: upButton, children: (0, jsx_runtime_1.jsx)(IconNative_1.Icon, { name: spinnerUpIcon || "spinnerUp:NumberBox", fallback: "chevronup", size: "sm" }) }), (0, jsx_runtime_1.jsx)(ButtonNative_1.Button, { "data-part-id": PART_SPINNER_DOWN, "data-spinner": "down", type: "button", role: "spinbutton", tabIndex: -1, variant: "ghost", themeColor: "secondary", className: NumberBox_module_scss_1.default.spinnerButton, disabled: !enabled || readOnly, ref: downButton, children: (0, jsx_runtime_1.jsx)(IconNative_1.Icon, { name: spinnerDownIcon || "spinnerDown:NumberBox", fallback: "chevrondown", size: "sm" }) })] }))] })));
|
|
457
469
|
});
|
|
458
470
|
function applyStep(valueStrRep, step, min, max, integersOnly) {
|
|
459
471
|
const currentValue = (0, numberbox_abstractions_1.toUsableNumber)(valueStrRep, integersOnly);
|
|
@@ -25,6 +25,8 @@ exports.OptionMd = (0, metadata_helpers_1.createMetadata)({
|
|
|
25
25
|
valueType: "boolean",
|
|
26
26
|
defaultValue: OptionNative_1.defaultProps.enabled,
|
|
27
27
|
},
|
|
28
|
+
keywords: (0, metadata_helpers_1.d)("An array of keywords that can be used for searching and filtering the option. " +
|
|
29
|
+
"These keywords are not displayed but help users find the option through search."),
|
|
28
30
|
},
|
|
29
31
|
});
|
|
30
32
|
exports.optionComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP, exports.OptionMd, ({ node, extractValue, className, renderChild, layoutContext }) => {
|
|
@@ -36,7 +38,7 @@ exports.optionComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP,
|
|
|
36
38
|
}
|
|
37
39
|
const hasTextNodeChild = ((_a = node.children) === null || _a === void 0 ? void 0 : _a.length) === 1 && (node.children[0].type === "TextNode" || node.children[0].type === "TextNodeCData");
|
|
38
40
|
const textNodeChild = hasTextNodeChild ? renderChild(node.children) : undefined;
|
|
39
|
-
return ((0, jsx_runtime_1.jsx)(OptionNative_1.OptionNative, { label: label || textNodeChild, value: value !== undefined && value !== "" ? value : label, enabled: extractValue.asOptionalBoolean(node.props.enabled), className: className, optionRenderer: ((_b = node.children) === null || _b === void 0 ? void 0 : _b.length) > 0
|
|
41
|
+
return ((0, jsx_runtime_1.jsx)(OptionNative_1.OptionNative, { label: label || textNodeChild, value: value !== undefined && value !== "" ? value : label, enabled: extractValue.asOptionalBoolean(node.props.enabled), keywords: extractValue.asOptionalStringArray(node.props.keywords), className: className, optionRenderer: ((_b = node.children) === null || _b === void 0 ? void 0 : _b.length) > 0
|
|
40
42
|
? !hasTextNodeChild ? (contextVars) => ((0, jsx_runtime_1.jsx)(container_helpers_1.MemoizedItem, { node: node.children, renderChild: renderChild, contextVars: contextVars, layoutContext: layoutContext })) : undefined
|
|
41
43
|
: undefined, children: !hasTextNodeChild && renderChild(node.children) }));
|
|
42
44
|
});
|
|
@@ -31,10 +31,6 @@ exports.RadioGroupMd = (0, metadata_helpers_1.createMetadata)({
|
|
|
31
31
|
validationStatus: Object.assign(Object.assign({}, (0, metadata_helpers_1.dValidationStatus)()), { defaultValue: RadioGroupNative_1.defaultProps.validationStatus }),
|
|
32
32
|
orientation: (0, metadata_helpers_1.dInternal)(`(*** NOT IMPLEMENTED YET ***) This property sets the orientation of the ` +
|
|
33
33
|
`options within the radio group.`),
|
|
34
|
-
label: (0, metadata_helpers_1.dLabel)(),
|
|
35
|
-
labelPosition: (0, metadata_helpers_1.dLabelPosition)("top"),
|
|
36
|
-
labelWidth: (0, metadata_helpers_1.dLabelWidth)(COMP),
|
|
37
|
-
labelBreak: (0, metadata_helpers_1.dLabelBreak)(COMP),
|
|
38
34
|
},
|
|
39
35
|
events: {
|
|
40
36
|
gotFocus: (0, metadata_helpers_1.dGotFocus)(COMP),
|
|
@@ -61,5 +57,5 @@ exports.RadioGroupMd = (0, metadata_helpers_1.createMetadata)({
|
|
|
61
57
|
},
|
|
62
58
|
});
|
|
63
59
|
exports.radioGroupRenderer = (0, renderers_1.createComponentRenderer)(COMP, exports.RadioGroupMd, ({ node, extractValue, className, state, updateState, lookupEventHandler, renderChild, registerComponentApi, }) => {
|
|
64
|
-
return ((0, jsx_runtime_1.jsx)(RadioGroupNative_1.RadioGroup, { autofocus: extractValue.asOptionalBoolean(node.props.autoFocus), enabled: extractValue.asOptionalBoolean(node.props.enabled), className: className, initialValue: extractValue(node.props.initialValue), value: state === null || state === void 0 ? void 0 : state.value, updateState: updateState, validationStatus: extractValue(node.props.validationStatus), onDidChange: lookupEventHandler("didChange"), onFocus: lookupEventHandler("gotFocus"), onBlur: lookupEventHandler("lostFocus"), registerComponentApi: registerComponentApi,
|
|
60
|
+
return ((0, jsx_runtime_1.jsx)(RadioGroupNative_1.RadioGroup, { autofocus: extractValue.asOptionalBoolean(node.props.autoFocus), enabled: extractValue.asOptionalBoolean(node.props.enabled), className: className, initialValue: extractValue(node.props.initialValue), value: state === null || state === void 0 ? void 0 : state.value, updateState: updateState, validationStatus: extractValue(node.props.validationStatus), onDidChange: lookupEventHandler("didChange"), onFocus: lookupEventHandler("gotFocus"), onBlur: lookupEventHandler("lostFocus"), registerComponentApi: registerComponentApi, required: extractValue.asOptionalBoolean(node.props.required), readOnly: extractValue.asOptionalBoolean(node.props.readOnly), children: renderChild(node.children) }));
|
|
65
61
|
});
|
|
@@ -55,7 +55,6 @@ const classnames_1 = __importDefault(require("classnames"));
|
|
|
55
55
|
const RadioGroup_module_scss_1 = __importDefault(require("./RadioGroup.module.scss"));
|
|
56
56
|
const constants_1 = require("../../components-core/constants");
|
|
57
57
|
const misc_1 = require("../../components-core/utils/misc");
|
|
58
|
-
const ItemWithLabel_1 = require("../FormItem/ItemWithLabel");
|
|
59
58
|
const OptionTypeProvider_1 = __importDefault(require("../Option/OptionTypeProvider"));
|
|
60
59
|
const RadioItemNative_1 = require("./RadioItemNative");
|
|
61
60
|
const OptionNative_1 = require("../Option/OptionNative");
|
|
@@ -136,10 +135,10 @@ exports.RadioGroup = (0, react_1.forwardRef)(function RadioGroup(_a, forwardedRe
|
|
|
136
135
|
const contextValue = (0, react_1.useMemo)(() => {
|
|
137
136
|
return { value, setValue: updateValue, status: validationStatus, enabled };
|
|
138
137
|
}, [value, updateValue, validationStatus, enabled]);
|
|
139
|
-
return ((0, jsx_runtime_1.jsx)(OptionTypeProvider_1.default, { Component: exports.RadioGroupOption, children: (0, jsx_runtime_1.jsx)(RadioGroupStatusContext.Provider, { value: contextValue, children: (0, jsx_runtime_1.jsx)(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
return ((0, jsx_runtime_1.jsx)(OptionTypeProvider_1.default, { Component: exports.RadioGroupOption, children: (0, jsx_runtime_1.jsx)(RadioGroupStatusContext.Provider, { value: contextValue, children: (0, jsx_runtime_1.jsx)(InnerRadioGroup.Root, Object.assign({}, rest, { style: style, ref: radioGroupRef, id: id, onBlur: handleOnBlur, onFocus: handleOnFocus, onValueChange: onInputChange, value: value, disabled: !enabled, required: required, "aria-readonly": readOnly, className: (0, classnames_1.default)(className, RadioGroup_module_scss_1.default.radioGroupContainer, {
|
|
139
|
+
[RadioGroup_module_scss_1.default.focused]: focused,
|
|
140
|
+
[RadioGroup_module_scss_1.default.disabled]: !enabled,
|
|
141
|
+
}), children: children })) }) }));
|
|
143
142
|
});
|
|
144
143
|
const RadioGroupOption = ({ value, label, enabled = true, optionRenderer, style, className, }) => {
|
|
145
144
|
const id = (0, react_1.useId)();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.radioItemComponentRenderer = exports.RadioItemMd = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const renderers_1 = require("../../components-core/renderers");
|
|
6
|
+
const metadata_helpers_1 = require("../metadata-helpers");
|
|
7
|
+
const RadioItemNative_1 = require("./RadioItemNative");
|
|
8
|
+
const COMP = "RadioItem";
|
|
9
|
+
exports.RadioItemMd = (0, metadata_helpers_1.createMetadata)({
|
|
10
|
+
status: "experimental",
|
|
11
|
+
description: `The \`${COMP}\` component is a radio button that is part of a group of radio buttons.`,
|
|
12
|
+
props: {
|
|
13
|
+
checked: {
|
|
14
|
+
description: "This property specifies whether the radio button is checked.",
|
|
15
|
+
defaultValue: RadioItemNative_1.defaultProps.checked,
|
|
16
|
+
},
|
|
17
|
+
value: {
|
|
18
|
+
description: "This property specifies the value of the radio button.",
|
|
19
|
+
defaultValue: RadioItemNative_1.defaultProps.value,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
events: {
|
|
23
|
+
didChange: (0, metadata_helpers_1.dDidChange)(COMP),
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
exports.radioItemComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP, exports.RadioItemMd, ({ node, extractValue, lookupEventHandler }) => {
|
|
27
|
+
return ((0, jsx_runtime_1.jsx)(RadioItemNative_1.RadioItem, { checked: extractValue(node.props.checked), value: extractValue(node.props.value), onDidChange: lookupEventHandler("didChange") }));
|
|
28
|
+
});
|
|
@@ -10,7 +10,7 @@ function HiddenOption(option) {
|
|
|
10
10
|
const [node, setNode] = (0, react_1.useState)(null);
|
|
11
11
|
const opt = (0, react_1.useMemo)(() => {
|
|
12
12
|
var _a, _b;
|
|
13
|
-
return Object.assign(Object.assign({}, option), { label: (_a = label !== null && label !== void 0 ? label : node === null || node === void 0 ? void 0 : node.textContent) !== null && _a !== void 0 ? _a : "", keywords: [(_b = label !== null && label !== void 0 ? label : node === null || node === void 0 ? void 0 : node.textContent) !== null && _b !== void 0 ? _b : ""] });
|
|
13
|
+
return Object.assign(Object.assign({}, option), { label: (_a = label !== null && label !== void 0 ? label : node === null || node === void 0 ? void 0 : node.textContent) !== null && _a !== void 0 ? _a : "", keywords: option.keywords || [(_b = label !== null && label !== void 0 ? label : node === null || node === void 0 ? void 0 : node.textContent) !== null && _b !== void 0 ? _b : ""] });
|
|
14
14
|
}, [option, node, label]);
|
|
15
15
|
(0, react_1.useEffect)(() => {
|
|
16
16
|
onOptionAdd(opt);
|
|
@@ -31,10 +31,6 @@ exports.SelectMd = (0, metadata_helpers_1.createMetadata)({
|
|
|
31
31
|
readOnly: Object.assign(Object.assign({}, (0, metadata_helpers_1.dReadonly)()), { defaultValue: SelectNative_1.defaultProps.readOnly }),
|
|
32
32
|
enabled: Object.assign(Object.assign({}, (0, metadata_helpers_1.dEnabled)()), { defaultValue: SelectNative_1.defaultProps.enabled }),
|
|
33
33
|
validationStatus: Object.assign(Object.assign({}, (0, metadata_helpers_1.dValidationStatus)()), { defaultValue: SelectNative_1.defaultProps.validationStatus }),
|
|
34
|
-
label: (0, metadata_helpers_1.dLabel)(),
|
|
35
|
-
labelPosition: (0, metadata_helpers_1.dLabelPosition)("top"),
|
|
36
|
-
labelWidth: (0, metadata_helpers_1.dLabelWidth)(COMP),
|
|
37
|
-
labelBreak: Object.assign(Object.assign({}, (0, metadata_helpers_1.dLabelBreak)(COMP)), { defaultValue: SelectNative_1.defaultProps.labelBreak }),
|
|
38
34
|
optionLabelTemplate: (0, metadata_helpers_1.dComponent)(`This property allows replacing the default template to display an option in the dropdown list.`),
|
|
39
35
|
optionTemplate: (0, metadata_helpers_1.dComponent)(`This property allows replacing the default template to display an option in the dropdown list.`),
|
|
40
36
|
valueTemplate: (0, metadata_helpers_1.dComponent)(`This property allows replacing the default template to display a selected value when ` +
|
|
@@ -119,7 +115,7 @@ exports.selectComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP,
|
|
|
119
115
|
const multiSelect = extractValue.asOptionalBoolean(node.props.multiSelect);
|
|
120
116
|
const searchable = extractValue.asOptionalBoolean(node.props.searchable);
|
|
121
117
|
const isControlled = node.props.value !== undefined;
|
|
122
|
-
return ((0, jsx_runtime_1.jsx)(SelectNative_1.Select, { multiSelect: multiSelect, className: className, inProgress: extractValue.asOptionalBoolean(node.props.inProgress), inProgressNotificationMessage: extractValue.asOptionalString(node.props.inProgressNotificationMessage), readOnly: extractValue.asOptionalBoolean(node.props.readOnly), updateState: isControlled ? undefined : updateState, searchable: searchable, initialValue: extractValue(node.props.initialValue), value: isControlled ? extractValue(node.props.value) : state === null || state === void 0 ? void 0 : state.value, autoFocus: extractValue.asOptionalBoolean(node.props.autoFocus), enabled: extractValue.asOptionalBoolean(node.props.enabled), placeholder: extractValue.asOptionalString(node.props.placeholder), validationStatus: extractValue(node.props.validationStatus), onDidChange: lookupEventHandler("didChange"), onFocus: lookupEventHandler("gotFocus"), onBlur: lookupEventHandler("lostFocus"), registerComponentApi: registerComponentApi, emptyListTemplate: renderChild(node.props.emptyListTemplate), dropdownHeight: extractValue(node.props.dropdownHeight),
|
|
118
|
+
return ((0, jsx_runtime_1.jsx)(SelectNative_1.Select, { multiSelect: multiSelect, className: className, inProgress: extractValue.asOptionalBoolean(node.props.inProgress), inProgressNotificationMessage: extractValue.asOptionalString(node.props.inProgressNotificationMessage), readOnly: extractValue.asOptionalBoolean(node.props.readOnly), updateState: isControlled ? undefined : updateState, searchable: searchable, initialValue: extractValue(node.props.initialValue), value: isControlled ? extractValue(node.props.value) : state === null || state === void 0 ? void 0 : state.value, autoFocus: extractValue.asOptionalBoolean(node.props.autoFocus), enabled: extractValue.asOptionalBoolean(node.props.enabled), placeholder: extractValue.asOptionalString(node.props.placeholder), validationStatus: extractValue(node.props.validationStatus), onDidChange: lookupEventHandler("didChange"), onFocus: lookupEventHandler("gotFocus"), onBlur: lookupEventHandler("lostFocus"), registerComponentApi: registerComponentApi, emptyListTemplate: renderChild(node.props.emptyListTemplate), dropdownHeight: extractValue(node.props.dropdownHeight), required: extractValue.asOptionalBoolean(node.props.required), valueRenderer: node.props.valueTemplate
|
|
123
119
|
? (item, removeItem) => {
|
|
124
120
|
return ((0, jsx_runtime_1.jsx)(container_helpers_1.MemoizedItem, { contextVars: {
|
|
125
121
|
$itemContext: { removeItem },
|
|
@@ -242,7 +242,6 @@ const fixtures_1 = require("../../testing/fixtures");
|
|
|
242
242
|
yield initTestBed(`
|
|
243
243
|
<Select
|
|
244
244
|
label="Dignissimos esse quasi esse cupiditate qui qui. Ut provident ad voluptatem tenetur sit consequuntur. Aliquam nisi fugit ut temporibus itaque ducimus rerum. Dolorem reprehenderit qui adipisci. Ullam harum atque ipsa."
|
|
245
|
-
|
|
246
245
|
>
|
|
247
246
|
<Option value="1" label="One"/>
|
|
248
247
|
<Option value="2" label="Two"/>
|
|
@@ -251,7 +250,7 @@ const fixtures_1 = require("../../testing/fixtures");
|
|
|
251
250
|
const labelWidth = (yield page.getByText("Dignissimos esse quasi").boundingBox()).width;
|
|
252
251
|
const select = page.getByRole("button").or(page.getByRole("combobox")).first();
|
|
253
252
|
const { width: selectWidth } = yield select.boundingBox();
|
|
254
|
-
(0, fixtures_1.expect)(labelWidth).
|
|
253
|
+
(0, fixtures_1.expect)(labelWidth).toBe(selectWidth);
|
|
255
254
|
}));
|
|
256
255
|
(0, fixtures_1.test)("placeholder is shown", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createSelectDriver }) {
|
|
257
256
|
yield initTestBed(`
|
|
@@ -424,7 +423,7 @@ fixtures_1.test.describe("multiSelect", () => {
|
|
|
424
423
|
const labelWidth = (yield page.getByText("Dignissimos esse quasi").boundingBox()).width;
|
|
425
424
|
const select = page.getByRole("button").or(page.getByRole("combobox")).first();
|
|
426
425
|
const { width: selectWidth } = yield select.boundingBox();
|
|
427
|
-
(0, fixtures_1.expect)(labelWidth).
|
|
426
|
+
(0, fixtures_1.expect)(labelWidth).toBe(selectWidth);
|
|
428
427
|
}));
|
|
429
428
|
(0, fixtures_1.test)('labelPosition="start" is left in ltr language', (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, }) {
|
|
430
429
|
yield initTestBed(`
|
|
@@ -525,3 +524,32 @@ fixtures_1.test.describe("searchable multiselect", { tag: "@smoke" }, () => {
|
|
|
525
524
|
</Form>`);
|
|
526
525
|
yield (0, fixtures_1.expect)(page.getByTestId("text")).toHaveText("Selected value: opt3");
|
|
527
526
|
}));
|
|
527
|
+
// =============================================================================
|
|
528
|
+
// VISUAL STATE TESTS
|
|
529
|
+
// =============================================================================
|
|
530
|
+
(0, fixtures_1.test)("input has correct width in px", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed }) {
|
|
531
|
+
yield initTestBed(`<Select width="200px" testId="test"/>`, {});
|
|
532
|
+
const input = page.getByTestId("test");
|
|
533
|
+
const { width } = yield input.boundingBox();
|
|
534
|
+
(0, fixtures_1.expect)(width).toBe(200);
|
|
535
|
+
}));
|
|
536
|
+
(0, fixtures_1.test)("input with label has correct width in px", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed }) {
|
|
537
|
+
yield initTestBed(`<Select width="200px" label="test" testId="test"/>`, {});
|
|
538
|
+
const input = page.getByTestId("test");
|
|
539
|
+
const { width } = yield input.boundingBox();
|
|
540
|
+
(0, fixtures_1.expect)(width).toBe(200);
|
|
541
|
+
}));
|
|
542
|
+
(0, fixtures_1.test)("input has correct width in %", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed }) {
|
|
543
|
+
yield page.setViewportSize({ width: 400, height: 300 });
|
|
544
|
+
yield initTestBed(`<Select width="50%" testId="test"/>`, {});
|
|
545
|
+
const input = page.getByTestId("test");
|
|
546
|
+
const { width } = yield input.boundingBox();
|
|
547
|
+
(0, fixtures_1.expect)(width).toBe(200);
|
|
548
|
+
}));
|
|
549
|
+
(0, fixtures_1.test)("input with label has correct width in %", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed }) {
|
|
550
|
+
yield page.setViewportSize({ width: 400, height: 300 });
|
|
551
|
+
yield initTestBed(`<Select width="50%" label="test" testId="test"/>`, {});
|
|
552
|
+
const input = page.getByTestId("test");
|
|
553
|
+
const { width } = yield input.boundingBox();
|
|
554
|
+
(0, fixtures_1.expect)(width).toBe(200);
|
|
555
|
+
}));
|
|
@@ -65,7 +65,6 @@ const IconNative_1 = __importDefault(require("../Icon/IconNative"));
|
|
|
65
65
|
const SelectContext_1 = require("./SelectContext");
|
|
66
66
|
const OptionTypeProvider_1 = __importDefault(require("../Option/OptionTypeProvider"));
|
|
67
67
|
const OptionContext_1 = require("./OptionContext");
|
|
68
|
-
const ItemWithLabel_1 = require("../FormItem/ItemWithLabel");
|
|
69
68
|
const HiddenOption_1 = require("./HiddenOption");
|
|
70
69
|
const FormContext_1 = require("../Form/FormContext");
|
|
71
70
|
exports.defaultProps = {
|
|
@@ -84,9 +83,8 @@ exports.defaultProps = {
|
|
|
84
83
|
const SimpleSelect = (0, react_2.forwardRef)(function SimpleSelect(props, forwardedRef) {
|
|
85
84
|
const { root } = (0, ThemeContext_1.useTheme)();
|
|
86
85
|
const { enabled, onBlur, autoFocus, onValueChange, validationStatus, value, height, style, placeholder, id, triggerRef, onFocus, width, children, readOnly, emptyListNode, className } = props, rest = __rest(props, ["enabled", "onBlur", "autoFocus", "onValueChange", "validationStatus", "value", "height", "style", "placeholder", "id", "triggerRef", "onFocus", "width", "children", "readOnly", "emptyListNode", "className"]);
|
|
87
|
-
// Compose refs for proper forwarding
|
|
88
|
-
const ref = forwardedRef ? (0, react_compose_refs_1.composeRefs)(triggerRef, forwardedRef) : triggerRef;
|
|
89
86
|
const { options } = (0, SelectContext_1.useSelect)();
|
|
87
|
+
const composedRef = react_2.forwardRef ? (0, react_compose_refs_1.composeRefs)(triggerRef, forwardedRef) : triggerRef;
|
|
90
88
|
// Convert value to string for Radix UI compatibility
|
|
91
89
|
const stringValue = (0, react_2.useMemo)(() => {
|
|
92
90
|
return value != undefined ? String(value) : undefined;
|
|
@@ -101,7 +99,7 @@ const SimpleSelect = (0, react_2.forwardRef)(function SimpleSelect(props, forwar
|
|
|
101
99
|
const selectedOption = (0, react_2.useMemo)(() => {
|
|
102
100
|
return optionsArray.find((option) => String(option.value) === String(value));
|
|
103
101
|
}, [optionsArray, value]);
|
|
104
|
-
return ((0, jsx_runtime_1.jsxs)(react_select_1.Root, { value: stringValue, onValueChange: handleValueChange, children: [(0, jsx_runtime_1.jsxs)(react_select_1.Trigger, Object.assign({}, rest, { id: id, "aria-haspopup": "listbox", style: style, onFocus: onFocus, onBlur: onBlur, disabled: !enabled, className: (0, classnames_1.default)(className, Select_module_scss_1.default.selectTrigger, {
|
|
102
|
+
return ((0, jsx_runtime_1.jsxs)(react_select_1.Root, { value: stringValue, onValueChange: handleValueChange, children: [(0, jsx_runtime_1.jsxs)(react_select_1.Trigger, Object.assign({}, rest, { id: id, ref: composedRef, "aria-haspopup": "listbox", style: style, onFocus: onFocus, onBlur: onBlur, disabled: !enabled, className: (0, classnames_1.default)(className, Select_module_scss_1.default.selectTrigger, {
|
|
105
103
|
[Select_module_scss_1.default.error]: validationStatus === "error",
|
|
106
104
|
[Select_module_scss_1.default.warning]: validationStatus === "warning",
|
|
107
105
|
[Select_module_scss_1.default.valid]: validationStatus === "valid",
|
|
@@ -109,12 +107,12 @@ const SimpleSelect = (0, react_2.forwardRef)(function SimpleSelect(props, forwar
|
|
|
109
107
|
// Prevent event propagation to parent elements (e.g., DropdownMenu)
|
|
110
108
|
// This ensures that clicking the Select trigger doesn't close the containing DropdownMenu
|
|
111
109
|
event.stopPropagation();
|
|
112
|
-
},
|
|
110
|
+
}, autoFocus: autoFocus, children: [(0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)(Select_module_scss_1.default.selectValue, {
|
|
113
111
|
[Select_module_scss_1.default.selectValue]: value !== undefined,
|
|
114
112
|
[Select_module_scss_1.default.placeholder]: value === undefined,
|
|
115
113
|
}), children: selectedOption ? selectedOption.label : readOnly ? "" : placeholder }), (0, jsx_runtime_1.jsx)(react_select_1.Icon, { asChild: true, children: (0, jsx_runtime_1.jsx)(IconNative_1.default, { name: "chevrondown" }) })] })), (0, jsx_runtime_1.jsx)(react_select_1.Portal, { container: root, children: (0, jsx_runtime_1.jsxs)(react_select_1.Content, { className: Select_module_scss_1.default.selectContent, position: "popper", style: { maxHeight: height, minWidth: width }, children: [(0, jsx_runtime_1.jsx)(react_select_1.ScrollUpButton, { className: Select_module_scss_1.default.selectScrollUpButton, children: (0, jsx_runtime_1.jsx)(IconNative_1.default, { name: "chevronup" }) }), (0, jsx_runtime_1.jsxs)(react_select_1.SelectViewport, { className: Select_module_scss_1.default.selectViewport, role: "listbox", children: [children, optionsArray.length === 0 && emptyListNode] }), (0, jsx_runtime_1.jsx)(react_select_1.ScrollDownButton, { className: Select_module_scss_1.default.selectScrollDownButton, children: (0, jsx_runtime_1.jsx)(IconNative_1.default, { name: "chevrondown" }) })] }) })] }));
|
|
116
114
|
});
|
|
117
|
-
exports.Select = (0, react_2.forwardRef)(function Select(_a,
|
|
115
|
+
exports.Select = (0, react_2.forwardRef)(function Select(_a, forwardedRef) {
|
|
118
116
|
var _b;
|
|
119
117
|
var {
|
|
120
118
|
// Basic props
|
|
@@ -129,18 +127,14 @@ exports.Select = (0, react_2.forwardRef)(function Select(_a, ref) {
|
|
|
129
127
|
searchable = exports.defaultProps.searchable, multiSelect = exports.defaultProps.multiSelect, emptyListTemplate, valueRenderer, optionRenderer,
|
|
130
128
|
// Progress state
|
|
131
129
|
inProgress = exports.defaultProps.inProgress, inProgressNotificationMessage = exports.defaultProps.inProgressNotificationMessage,
|
|
132
|
-
// Label configuration
|
|
133
|
-
label, labelPosition, labelWidth, labelBreak = exports.defaultProps.labelBreak,
|
|
134
130
|
// Internal
|
|
135
|
-
updateState = constants_1.noop, registerComponentApi, children } = _a, rest = __rest(_a, ["id", "initialValue", "value", "enabled", "placeholder", "autoFocus", "readOnly", "required", "style", "className", "dropdownHeight", "validationStatus", "onDidChange", "onFocus", "onBlur", "searchable", "multiSelect", "emptyListTemplate", "valueRenderer", "optionRenderer", "inProgress", "inProgressNotificationMessage", "
|
|
131
|
+
updateState = constants_1.noop, registerComponentApi, children } = _a, rest = __rest(_a, ["id", "initialValue", "value", "enabled", "placeholder", "autoFocus", "readOnly", "required", "style", "className", "dropdownHeight", "validationStatus", "onDidChange", "onFocus", "onBlur", "searchable", "multiSelect", "emptyListTemplate", "valueRenderer", "optionRenderer", "inProgress", "inProgressNotificationMessage", "updateState", "registerComponentApi", "children"]);
|
|
136
132
|
const [referenceElement, setReferenceElement] = (0, react_2.useState)(null);
|
|
137
133
|
const [open, setOpen] = (0, react_2.useState)(false);
|
|
138
134
|
const [width, setWidth] = (0, react_2.useState)(0);
|
|
139
135
|
const observer = (0, react_2.useRef)();
|
|
140
136
|
const { root } = (0, ThemeContext_1.useTheme)();
|
|
141
137
|
const [options, setOptions] = (0, react_2.useState)(new Set());
|
|
142
|
-
const generatedId = (0, react_2.useId)();
|
|
143
|
-
const inputId = id || generatedId;
|
|
144
138
|
const isInForm = (0, FormContext_1.useIsInsideForm)();
|
|
145
139
|
// Set initial state based on the initialValue prop
|
|
146
140
|
(0, react_2.useEffect)(() => {
|
|
@@ -232,26 +226,26 @@ exports.Select = (0, react_2.forwardRef)(function Select(_a, ref) {
|
|
|
232
226
|
options,
|
|
233
227
|
optionRenderer,
|
|
234
228
|
}), [multiSelect, toggleOption, value, options]);
|
|
235
|
-
return ((0, jsx_runtime_1.jsx)(SelectContext_1.SelectContext.Provider, { value: selectContextValue, children: (0, jsx_runtime_1.jsx)(OptionContext_1.OptionContext.Provider, { value: optionContextValue, children: searchable || multiSelect ? ((0, jsx_runtime_1.jsxs)(OptionTypeProvider_1.default, { Component: HiddenOption_1.HiddenOption, children: [(0, jsx_runtime_1.jsxs)(react_popover_1.Popover, { open: open, onOpenChange: setOpen, modal: false, children: [(0, jsx_runtime_1.jsx)(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
229
|
+
return ((0, jsx_runtime_1.jsx)(SelectContext_1.SelectContext.Provider, { value: selectContextValue, children: (0, jsx_runtime_1.jsx)(OptionContext_1.OptionContext.Provider, { value: optionContextValue, children: searchable || multiSelect ? ((0, jsx_runtime_1.jsxs)(OptionTypeProvider_1.default, { Component: HiddenOption_1.HiddenOption, children: [(0, jsx_runtime_1.jsxs)(react_popover_1.Popover, { open: open, onOpenChange: setOpen, modal: false, children: [(0, jsx_runtime_1.jsx)(react_popover_1.PopoverTrigger, Object.assign({}, rest, { ref: (0, react_compose_refs_1.composeRefs)(setReferenceElement, forwardedRef), id: id, "aria-haspopup": "listbox", style: style, onFocus: onFocus, onBlur: onBlur, disabled: !enabled, "aria-expanded": open, onClick: (event) => {
|
|
230
|
+
// Prevent event propagation to parent elements (e.g., DropdownMenu)
|
|
231
|
+
// This ensures that clicking the Select trigger doesn't close the containing DropdownMenu
|
|
232
|
+
event.stopPropagation();
|
|
233
|
+
setOpen((prev) => !prev);
|
|
234
|
+
}, className: (0, classnames_1.default)(Select_module_scss_1.default.selectTrigger, Select_module_scss_1.default[validationStatus], {
|
|
235
|
+
[Select_module_scss_1.default.disabled]: !enabled,
|
|
236
|
+
[Select_module_scss_1.default.multi]: multiSelect,
|
|
237
|
+
}, className), autoFocus: autoFocus, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [multiSelect ? (Array.isArray(value) && value.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: Select_module_scss_1.default.badgeListContainer, children: (0, jsx_runtime_1.jsx)("div", { className: Select_module_scss_1.default.badgeList, children: value.map((v) => {
|
|
238
|
+
var _a;
|
|
239
|
+
return valueRenderer ? (valueRenderer(Array.from(options).find((o) => o.value === `${v}`), () => {
|
|
240
|
+
toggleOption(v);
|
|
241
|
+
})) : ((0, jsx_runtime_1.jsxs)("span", { className: Select_module_scss_1.default.badge, children: [(_a = Array.from(options).find((o) => o.value === `${v}`)) === null || _a === void 0 ? void 0 : _a.label, (0, jsx_runtime_1.jsx)(IconNative_1.default, { name: "close", size: "sm", onClick: (event) => {
|
|
242
|
+
event.stopPropagation();
|
|
243
|
+
toggleOption(v);
|
|
244
|
+
} })] }, v));
|
|
245
|
+
}) }) })) : ((0, jsx_runtime_1.jsx)("span", { placeholder: placeholder, className: Select_module_scss_1.default.placeholder, children: placeholder }))) : value !== undefined && value !== null ? ((0, jsx_runtime_1.jsx)("div", { children: (_b = Array.from(options).find((o) => o.value === value)) === null || _b === void 0 ? void 0 : _b.label })) : ((0, jsx_runtime_1.jsx)("span", { "aria-placeholder": placeholder, className: Select_module_scss_1.default.placeholder, children: placeholder || "" })), (0, jsx_runtime_1.jsxs)("div", { className: Select_module_scss_1.default.actions, children: [multiSelect && Array.isArray(value) && value.length > 0 && ((0, jsx_runtime_1.jsx)(IconNative_1.default, { name: "close", onClick: (event) => {
|
|
246
|
+
event.stopPropagation();
|
|
247
|
+
clearValue();
|
|
248
|
+
} })), (0, jsx_runtime_1.jsx)(IconNative_1.default, { name: "chevrondown" })] })] }) })), open && ((0, jsx_runtime_1.jsx)(react_popover_1.Portal, { container: root, children: (0, jsx_runtime_1.jsx)(react_focus_scope_1.FocusScope, { asChild: true, loop: true, trapped: true, children: (0, jsx_runtime_1.jsx)(react_popover_1.PopoverContent, { style: { minWidth: width, height: dropdownHeight }, className: Select_module_scss_1.default.selectContent, children: (0, jsx_runtime_1.jsxs)(cmdk_1.Command, { className: Select_module_scss_1.default.command, shouldFilter: searchable, filter: (_, search, keywords) => {
|
|
255
249
|
const lowSearch = search.toLowerCase();
|
|
256
250
|
for (const kw of keywords) {
|
|
257
251
|
if (kw.toLowerCase().includes(lowSearch))
|
|
@@ -260,7 +254,7 @@ exports.Select = (0, react_2.forwardRef)(function Select(_a, ref) {
|
|
|
260
254
|
return 0;
|
|
261
255
|
}, children: [searchable ? ((0, jsx_runtime_1.jsxs)("div", { className: Select_module_scss_1.default.commandInputContainer, children: [(0, jsx_runtime_1.jsx)(IconNative_1.default, { name: "search" }), (0, jsx_runtime_1.jsx)(cmdk_1.CommandInput, { className: (0, classnames_1.default)(Select_module_scss_1.default.commandInput), placeholder: "Search..." })] })) : (
|
|
262
256
|
// https://github.com/pacocoursey/cmdk/issues/322#issuecomment-2444703817
|
|
263
|
-
(0, jsx_runtime_1.jsx)("button", { autoFocus: true, "aria-hidden": "true", className: Select_module_scss_1.default.srOnly })), (0, jsx_runtime_1.jsxs)(cmdk_1.CommandList, { className: Select_module_scss_1.default.commandList, children: [inProgress && ((0, jsx_runtime_1.jsx)("div", { className: Select_module_scss_1.default.loading, children: inProgressNotificationMessage })), Array.from(options).map(({ value, label, enabled, keywords }) => ((0, jsx_runtime_1.jsx)(exports.ComboboxOption, { readOnly: readOnly, value: value, label: label, enabled: enabled, keywords: keywords }, value))), !inProgress && (0, jsx_runtime_1.jsx)(cmdk_1.CommandEmpty, { children: emptyListNode })] })] }) }) }) }))] }), children] })) : ((0, jsx_runtime_1.jsx)(OptionTypeProvider_1.default, { Component: SelectOption, children: (0,
|
|
257
|
+
(0, jsx_runtime_1.jsx)("button", { autoFocus: true, "aria-hidden": "true", className: Select_module_scss_1.default.srOnly })), (0, jsx_runtime_1.jsxs)(cmdk_1.CommandList, { className: Select_module_scss_1.default.commandList, children: [inProgress && ((0, jsx_runtime_1.jsx)("div", { className: Select_module_scss_1.default.loading, children: inProgressNotificationMessage })), Array.from(options).map(({ value, label, enabled, keywords }) => ((0, jsx_runtime_1.jsx)(exports.ComboboxOption, { readOnly: readOnly, value: value, label: label, enabled: enabled, keywords: keywords }, value))), !inProgress && (0, jsx_runtime_1.jsx)(cmdk_1.CommandEmpty, { children: emptyListNode })] })] }) }) }) }))] }), children] })) : ((0, jsx_runtime_1.jsx)(OptionTypeProvider_1.default, { Component: SelectOption, children: (0, react_1.createElement)(SimpleSelect, Object.assign({}, rest, { readOnly: !!readOnly, ref: forwardedRef, key: isInForm ? (value ? `status-${value}` : "status-initial") : undefined, value: value, onValueChange: toggleOption, id: id, style: style, className: className, onFocus: onFocus, onBlur: onBlur, enabled: enabled, validationStatus: validationStatus, triggerRef: setReferenceElement, autoFocus: autoFocus, placeholder: placeholder, height: dropdownHeight, width: width, emptyListNode: emptyListNode }), children) })) }) }));
|
|
264
258
|
});
|
|
265
259
|
exports.ComboboxOption = (0, react_2.forwardRef)(function Combobox(option, forwardedRef) {
|
|
266
260
|
const id = (0, react_2.useId)();
|
|
@@ -21,10 +21,6 @@ exports.SliderMd = (0, metadata_helpers_1.createMetadata)({
|
|
|
21
21
|
"Hover over the component to see the tooltip with the current value. On mobile, tap the thumb to see the tooltip.",
|
|
22
22
|
props: {
|
|
23
23
|
initialValue: (0, metadata_helpers_1.dInitialValue)(),
|
|
24
|
-
label: (0, metadata_helpers_1.dLabel)(),
|
|
25
|
-
labelPosition: (0, metadata_helpers_1.dLabelPosition)("top"),
|
|
26
|
-
labelWidth: (0, metadata_helpers_1.dLabelWidth)(COMP),
|
|
27
|
-
labelBreak: (0, metadata_helpers_1.dLabelBreak)(COMP),
|
|
28
24
|
minValue: {
|
|
29
25
|
description: `This property specifies the minimum value of the allowed input range.`,
|
|
30
26
|
valueType: "number",
|
|
@@ -115,5 +111,5 @@ exports.SliderMd = (0, metadata_helpers_1.createMetadata)({
|
|
|
115
111
|
});
|
|
116
112
|
exports.sliderComponentRenderer = (0, renderers_1.createComponentRenderer)(COMP, exports.SliderMd, ({ node, extractValue, lookupEventHandler, lookupSyncCallback, className, updateState, state, registerComponentApi, }) => {
|
|
117
113
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
118
|
-
return ((0, jsx_runtime_1.jsx)(SliderNative_1.Slider, { validationStatus: extractValue(node.props.validationStatus), minStepsBetweenThumbs: extractValue((_a = node.props) === null || _a === void 0 ? void 0 : _a.minStepsBetweenThumbs), value: state.value, initialValue: extractValue(node.props.initialValue), updateState: updateState, onDidChange: lookupEventHandler("didChange"), onFocus: lookupEventHandler("gotFocus"), onBlur: lookupEventHandler("lostFocus"), registerComponentApi: registerComponentApi, className: className, step: extractValue((_b = node.props) === null || _b === void 0 ? void 0 : _b.step), min: extractValue((_c = node.props) === null || _c === void 0 ? void 0 : _c.minValue), max: extractValue((_d = node.props) === null || _d === void 0 ? void 0 : _d.maxValue), enabled: extractValue.asOptionalBoolean((_e = node.props) === null || _e === void 0 ? void 0 : _e.enabled), autoFocus: extractValue.asOptionalBoolean(node.props.autoFocus), readOnly: extractValue.asOptionalBoolean(node.props.readOnly),
|
|
114
|
+
return ((0, jsx_runtime_1.jsx)(SliderNative_1.Slider, { validationStatus: extractValue(node.props.validationStatus), minStepsBetweenThumbs: extractValue((_a = node.props) === null || _a === void 0 ? void 0 : _a.minStepsBetweenThumbs), value: state.value, initialValue: extractValue(node.props.initialValue), updateState: updateState, onDidChange: lookupEventHandler("didChange"), onFocus: lookupEventHandler("gotFocus"), onBlur: lookupEventHandler("lostFocus"), registerComponentApi: registerComponentApi, className: className, step: extractValue((_b = node.props) === null || _b === void 0 ? void 0 : _b.step), min: extractValue((_c = node.props) === null || _c === void 0 ? void 0 : _c.minValue), max: extractValue((_d = node.props) === null || _d === void 0 ? void 0 : _d.maxValue), enabled: extractValue.asOptionalBoolean((_e = node.props) === null || _e === void 0 ? void 0 : _e.enabled), autoFocus: extractValue.asOptionalBoolean(node.props.autoFocus), readOnly: extractValue.asOptionalBoolean(node.props.readOnly), required: extractValue.asOptionalBoolean(node.props.required), rangeStyle: extractValue((_f = node.props) === null || _f === void 0 ? void 0 : _f.rangeStyle), thumbStyle: extractValue((_g = node.props) === null || _g === void 0 ? void 0 : _g.thumbStyle), showValues: extractValue.asOptionalBoolean((_h = node.props) === null || _h === void 0 ? void 0 : _h.showValues), valueFormat: lookupSyncCallback((_j = node.props) === null || _j === void 0 ? void 0 : _j.valueFormat) }));
|
|
119
115
|
});
|
|
@@ -141,29 +141,62 @@ fixtures_1.test.describe("Basic Functionality", () => {
|
|
|
141
141
|
yield slider.press("ArrowRight");
|
|
142
142
|
yield (0, fixtures_1.expect)(page.getByTestId("slider-value")).toHaveText("0.1");
|
|
143
143
|
}));
|
|
144
|
-
|
|
145
|
-
yield initTestBed(`<Slider initialValue="{[2,
|
|
146
|
-
|
|
147
|
-
yield (0, fixtures_1.expect)(
|
|
144
|
+
(0, fixtures_1.test)("component handles multiple thumbs", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
145
|
+
yield initTestBed(`<Slider initialValue="{[2, 4]}" />`);
|
|
146
|
+
const thumbs = page.getByRole("slider");
|
|
147
|
+
yield (0, fixtures_1.expect)(thumbs).toHaveCount(2);
|
|
148
|
+
}));
|
|
149
|
+
(0, fixtures_1.test)("all thumbs are interactable via mouse", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createSliderDriver, page, }) {
|
|
150
|
+
yield initTestBed(`
|
|
151
|
+
<Fragment>
|
|
152
|
+
<Slider id="slider" initialValue="{[2, 4]}" minValue="0" maxValue="10" />
|
|
153
|
+
<Text testId="sliderValue0">{slider.value[0]}</Text>
|
|
154
|
+
<Text testId="sliderValue1">{slider.value[1]}</Text>
|
|
155
|
+
</Fragment>
|
|
156
|
+
`);
|
|
157
|
+
const driver = yield createSliderDriver("slider");
|
|
158
|
+
yield driver.dragThumbByMouse("start", 0);
|
|
159
|
+
yield driver.dragThumbByMouse("end", 1);
|
|
160
|
+
yield (0, fixtures_1.expect)(page.getByTestId("sliderValue0")).toHaveText("0");
|
|
161
|
+
yield (0, fixtures_1.expect)(page.getByTestId("sliderValue1")).toHaveText("10");
|
|
162
|
+
}));
|
|
163
|
+
(0, fixtures_1.test)("all thumbs are interactable via keyboard", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createSliderDriver, page }) {
|
|
164
|
+
yield initTestBed(`
|
|
165
|
+
<Fragment>
|
|
166
|
+
<Slider id="slider" initialValue="{[2, 4]}" minValue="0" maxValue="10" />
|
|
167
|
+
<Text testId="sliderValue0">{slider.value[0]}</Text>
|
|
168
|
+
<Text testId="sliderValue1">{slider.value[1]}</Text>
|
|
169
|
+
</Fragment>
|
|
170
|
+
`);
|
|
171
|
+
const driver = yield createSliderDriver("slider");
|
|
172
|
+
yield driver.stepThumbByKeyboard("ArrowLeft", 0);
|
|
173
|
+
yield driver.stepThumbByKeyboard("ArrowRight", 1);
|
|
174
|
+
yield (0, fixtures_1.expect)(page.getByTestId("sliderValue0")).toHaveText("1");
|
|
175
|
+
yield (0, fixtures_1.expect)(page.getByTestId("sliderValue1")).toHaveText("5");
|
|
176
|
+
}));
|
|
177
|
+
(0, fixtures_1.test)("minStepsBetweenThumbs maintains thumb separation", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, createSliderDriver, page }) {
|
|
178
|
+
yield initTestBed(`
|
|
179
|
+
<Fragment>
|
|
180
|
+
<Slider id="slider" initialValue="{[0, 5]}" minStepsBetweenThumbs="3" minValue="0" maxValue="10" />
|
|
181
|
+
<Text testId="sliderValue1">{slider.value[1]}</Text>
|
|
182
|
+
</Fragment>
|
|
183
|
+
`);
|
|
184
|
+
const driver = yield createSliderDriver("slider");
|
|
185
|
+
yield driver.stepThumbByKeyboard("ArrowLeft", 1, 3); // Try to move left by 3 steps
|
|
186
|
+
yield (0, fixtures_1.expect)(page.getByTestId("sliderValue1")).toHaveText("3");
|
|
148
187
|
}));
|
|
149
188
|
(0, fixtures_1.test)("enabled=false disables control", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
150
189
|
yield initTestBed(`<Slider enabled="false" />`);
|
|
151
190
|
yield (0, fixtures_1.expect)(page.getByRole("slider")).toBeDisabled();
|
|
152
191
|
}));
|
|
153
|
-
(0, fixtures_1.test)("readOnly prevents interaction", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
192
|
+
(0, fixtures_1.test)("readOnly prevents interaction", (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page, createSliderDriver }) {
|
|
154
193
|
yield initTestBed(`
|
|
155
194
|
<Fragment>
|
|
156
195
|
<Slider id="mySlider" readOnly="true" />
|
|
157
196
|
<Text testId="slider-value" value="{mySlider.value}" />
|
|
158
197
|
</Fragment>`);
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
return el.getBoundingClientRect().width;
|
|
162
|
-
});
|
|
163
|
-
yield slider.hover();
|
|
164
|
-
yield page.mouse.down({ button: "left" });
|
|
165
|
-
yield page.mouse.move(sliderOffsetWidth, 0); // Attempt to drag to end
|
|
166
|
-
yield page.mouse.up();
|
|
198
|
+
const driver = yield createSliderDriver("mySlider");
|
|
199
|
+
yield driver.dragThumbByMouse("end");
|
|
167
200
|
yield (0, fixtures_1.expect)(page.getByTestId("slider-value")).toHaveText("0"); // Value should remain unchanged
|
|
168
201
|
}));
|
|
169
202
|
fixtures_1.test.fixme("autoFocus focuses slider on mount", component_test_helpers_1.SKIP_REASON.XMLUI_BUG("autoFocus does not seem to work with radix-ui, need to double-check"), (_a) => __awaiter(void 0, [_a], void 0, function* ({ initTestBed, page }) {
|
|
@@ -572,3 +605,32 @@ fixtures_1.test.describe("Edge Cases", () => {
|
|
|
572
605
|
yield (0, fixtures_1.expect)(sliders).toHaveCount(2);
|
|
573
606
|
}));
|
|
574
607
|
});
|
|
608
|
+
// =============================================================================
|
|
609
|
+
// VISUAL STATE TESTS
|
|
610
|
+
// =============================================================================
|
|
611
|
+
(0, fixtures_1.test)("input has correct width in px", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed }) {
|
|
612
|
+
yield initTestBed(`<Slider width="200px" testId="test"/>`, {});
|
|
613
|
+
const input = page.getByTestId("test");
|
|
614
|
+
const { width } = yield input.boundingBox();
|
|
615
|
+
(0, fixtures_1.expect)(width).toBe(200);
|
|
616
|
+
}));
|
|
617
|
+
(0, fixtures_1.test)("input with label has correct width in px", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed }) {
|
|
618
|
+
yield initTestBed(`<Slider width="200px" label="test" testId="test"/>`, {});
|
|
619
|
+
const input = page.getByTestId("test");
|
|
620
|
+
const { width } = yield input.boundingBox();
|
|
621
|
+
(0, fixtures_1.expect)(width).toBe(200);
|
|
622
|
+
}));
|
|
623
|
+
(0, fixtures_1.test)("input has correct width in %", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed }) {
|
|
624
|
+
yield page.setViewportSize({ width: 400, height: 300 });
|
|
625
|
+
yield initTestBed(`<Slider width="50%" testId="test"/>`, {});
|
|
626
|
+
const input = page.getByTestId("test");
|
|
627
|
+
const { width } = yield input.boundingBox();
|
|
628
|
+
(0, fixtures_1.expect)(width).toBe(200);
|
|
629
|
+
}));
|
|
630
|
+
(0, fixtures_1.test)("input with label has correct width in %", (_a) => __awaiter(void 0, [_a], void 0, function* ({ page, initTestBed }) {
|
|
631
|
+
yield page.setViewportSize({ width: 400, height: 300 });
|
|
632
|
+
yield initTestBed(`<Slider width="50%" label="test" testId="test"/>`, {});
|
|
633
|
+
const input = page.getByTestId("test");
|
|
634
|
+
const { width } = yield input.boundingBox();
|
|
635
|
+
(0, fixtures_1.expect)(width).toBe(200);
|
|
636
|
+
}));
|