@allxsmith/bestax-bulma 5.26.4 → 5.26.5
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/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +224 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +224 -39
- package/dist/index.esm.js.map +1 -1
- package/dist/types/form/Autocomplete.d.ts +6 -1
- package/dist/types/form/DateInput.d.ts +8 -4
- package/dist/types/form/DateTimeInput.d.ts +8 -4
- package/dist/types/form/FormContext.d.ts +47 -0
- package/dist/types/form/Input.d.ts +4 -3
- package/dist/types/form/Numberinput.d.ts +3 -0
- package/dist/types/form/Select.d.ts +4 -3
- package/dist/types/form/TextArea.d.ts +4 -3
- package/dist/types/form/TimeInput.d.ts +8 -4
- package/dist/types-cjs/form/Autocomplete.d.ts +6 -1
- package/dist/types-cjs/form/DateInput.d.ts +8 -4
- package/dist/types-cjs/form/DateTimeInput.d.ts +8 -4
- package/dist/types-cjs/form/FormContext.d.ts +47 -0
- package/dist/types-cjs/form/Input.d.ts +4 -3
- package/dist/types-cjs/form/Numberinput.d.ts +3 -0
- package/dist/types-cjs/form/Select.d.ts +4 -3
- package/dist/types-cjs/form/TextArea.d.ts +4 -3
- package/dist/types-cjs/form/TimeInput.d.ts +8 -4
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +1 -1
- package/src/scss/form/_taginput.scss +8 -0
package/dist/index.esm.js
CHANGED
|
@@ -8819,6 +8819,58 @@ const rendersOwnField = (component, options) => {
|
|
|
8819
8819
|
(moved.length > 0 ? `, and set ${listOf(moved)} on that <Field>.` : '.'));
|
|
8820
8820
|
return true;
|
|
8821
8821
|
};
|
|
8822
|
+
// Each Control-level prop, with what takes its place on the `Control` the
|
|
8823
|
+
// caller wrapped around the wrapper. `bare-control.test.tsx` holds this to
|
|
8824
|
+
// what each wrapper hands its own `Control`, so a new Control-level prop
|
|
8825
|
+
// fails there until it is added here and passed to `rendersOwnControl`.
|
|
8826
|
+
const ON_CONTROL = {
|
|
8827
|
+
isLoading: 'isLoading',
|
|
8828
|
+
iconLeft: 'iconLeft',
|
|
8829
|
+
iconLeftName: 'iconLeftName',
|
|
8830
|
+
iconLeftSize: 'iconLeftSize',
|
|
8831
|
+
iconRight: 'iconRight',
|
|
8832
|
+
iconRightName: 'iconRightName',
|
|
8833
|
+
iconRightSize: 'iconRightSize',
|
|
8834
|
+
hasIconsLeft: 'hasIconsLeft',
|
|
8835
|
+
hasIconsRight: 'hasIconsRight',
|
|
8836
|
+
isExpanded: 'isExpanded',
|
|
8837
|
+
controlSize: 'size (for controlSize)',
|
|
8838
|
+
controlClassName: 'className (for controlClassName)',
|
|
8839
|
+
};
|
|
8840
|
+
/**
|
|
8841
|
+
* Whether a convenience form wrapper renders a `Control` of its own (#921):
|
|
8842
|
+
* only outside one. Inside a `Control` it renders none, so the props it
|
|
8843
|
+
* would have handed its own do nothing there, and it warns in development,
|
|
8844
|
+
* naming them and saying to set them on that `Control`. An `inline` picker
|
|
8845
|
+
* renders none in either place, so it drops them inside a `Control` or not,
|
|
8846
|
+
* and its warning says so without pointing at a `Control`. A wrapper passes
|
|
8847
|
+
* only the props it hands its own `Control`, as the caller gave them, so a
|
|
8848
|
+
* default the wrapper fills in itself never warns. A prop counts when it is
|
|
8849
|
+
* truthy, since a falsy one would change nothing on a `Control` either.
|
|
8850
|
+
* Internal; not part of the public API.
|
|
8851
|
+
*/
|
|
8852
|
+
const rendersOwnControl = (component, options) => {
|
|
8853
|
+
if (!options.inline && !options.insideControl)
|
|
8854
|
+
return true;
|
|
8855
|
+
const held = Object.keys(ON_CONTROL).filter(prop => options[prop]);
|
|
8856
|
+
if (held.length === 0)
|
|
8857
|
+
return false;
|
|
8858
|
+
const names = held.join(' ');
|
|
8859
|
+
const doNothing = held.length > 1 ? 'those props do' : 'that prop does';
|
|
8860
|
+
if (options.inline) {
|
|
8861
|
+
warnOnce(`${component}:Control-props-inline:${held.join('+')}`, `[bestax-bulma] <${component} inline ${names}> renders no <Control> ` +
|
|
8862
|
+
`in inline mode, inside a <Control> or not, so ${doNothing} ` +
|
|
8863
|
+
`nothing. Leave ${held.length > 1 ? 'them' : 'it'} out of an ` +
|
|
8864
|
+
`inline picker.`);
|
|
8865
|
+
}
|
|
8866
|
+
else {
|
|
8867
|
+
warnOnce(`${component}:Control-props-in-Control:${held.join('+')}`, `[bestax-bulma] <${component} ${names}> inside a <Control> renders ` +
|
|
8868
|
+
`no <Control> of its own, so ${doNothing} nothing there. Set ` +
|
|
8869
|
+
`${listOf(held.map(prop => ON_CONTROL[prop]))} on that <Control> ` +
|
|
8870
|
+
`instead.`);
|
|
8871
|
+
}
|
|
8872
|
+
return false;
|
|
8873
|
+
};
|
|
8822
8874
|
const FieldLabelIdContext = createContext(undefined);
|
|
8823
8875
|
/**
|
|
8824
8876
|
* The id a labeled Field wants its single composed control to adopt (#495).
|
|
@@ -8953,6 +9005,7 @@ Checkbox.displayName = 'Checkbox';
|
|
|
8953
9005
|
// picker bases read it so their right-side launcher gives way to that
|
|
8954
9006
|
// spinner, which sits at the same edge, whether the `Control` is the one a
|
|
8955
9007
|
// convenience input renders or one the caller wrapped around the input.
|
|
9008
|
+
// Autocomplete reads it for its clear button, which sits there too.
|
|
8956
9009
|
// Kept apart from `FormContext`, whose contexts only report whether a `Field`
|
|
8957
9010
|
// or `Control` is present. Internal; not part of the public API.
|
|
8958
9011
|
const ControlLoadingContext = createContext(false);
|
|
@@ -9282,7 +9335,7 @@ const CheckboxesComponent = ({ label, labelSize, labelProps, horizontal, message
|
|
|
9282
9335
|
}), [name, groupActive, currentValue, handleChange]);
|
|
9283
9336
|
const checkboxesElement = (jsx("div", { className: wrapperClass, role: "group", "aria-labelledby": ariaLabelledBy, ...rest, children: jsx(CheckboxesProvider, { value: ctx, children: children }) }));
|
|
9284
9337
|
let content = checkboxesElement;
|
|
9285
|
-
if (
|
|
9338
|
+
if (rendersOwnControl('Checkboxes', { insideControl })) {
|
|
9286
9339
|
content = jsx(Control, { children: content });
|
|
9287
9340
|
}
|
|
9288
9341
|
if (ownField) {
|
|
@@ -9522,7 +9575,7 @@ const RadiosComponent = ({ label, labelSize, labelProps, horizontal, message, me
|
|
|
9522
9575
|
}), [name, groupActive, currentValue, handleChange]);
|
|
9523
9576
|
const radiosElement = (jsx("div", { className: wrapperClass, role: "radiogroup", "aria-labelledby": ariaLabelledBy, ...rest, children: jsx(RadiosProvider, { value: ctx, children: children }) }));
|
|
9524
9577
|
let content = radiosElement;
|
|
9525
|
-
if (
|
|
9578
|
+
if (rendersOwnControl('Radios', { insideControl })) {
|
|
9526
9579
|
content = jsx(Control, { children: content });
|
|
9527
9580
|
}
|
|
9528
9581
|
if (ownField) {
|
|
@@ -10056,7 +10109,7 @@ const Slider = forwardRef((props, ref) => {
|
|
|
10056
10109
|
'--slider-output-arrow-offset': `calc(50% - ${nudgeXHigh}px)`,
|
|
10057
10110
|
}, children: formatValue(currentRange[1]) })), renderTicks()] }));
|
|
10058
10111
|
let content = sliderElement;
|
|
10059
|
-
if (
|
|
10112
|
+
if (rendersOwnControl('Slider', { insideControl })) {
|
|
10060
10113
|
content = jsx(Control, { children: content });
|
|
10061
10114
|
}
|
|
10062
10115
|
if (ownField) {
|
|
@@ -10500,7 +10553,7 @@ const Rate = forwardRef(({ label, labelSize, labelProps, horizontal, message, me
|
|
|
10500
10553
|
const rateCustomTextClass = usePrefixedClassNames('rate-custom-text');
|
|
10501
10554
|
const rateElement = (jsxs("div", { ref: ref, className: combinedClasses, role: "radiogroup", "aria-label": ariaLabelledBy ? undefined : 'Rating', "aria-labelledby": ariaLabelledBy, "aria-valuenow": currentValue, "aria-valuemin": 0, "aria-valuemax": max, "aria-valuetext": ariaValueText, tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown, ...rest, children: [jsx("div", { className: rateItemsClass, children: renderIcons() }), showScore && (jsx("span", { className: rateScoreClass, children: getScoreDisplay() })), text && jsx("span", { className: rateTextClass, children: text }), customText && (jsx("span", { className: rateCustomTextClass, children: customText })), name && (jsx("input", { type: "hidden", name: name, value: currentValue, form: form }))] }));
|
|
10502
10555
|
let content = rateElement;
|
|
10503
|
-
if (
|
|
10556
|
+
if (rendersOwnControl('Rate', { insideControl })) {
|
|
10504
10557
|
content = jsx(Control, { children: content });
|
|
10505
10558
|
}
|
|
10506
10559
|
if (ownField) {
|
|
@@ -10739,7 +10792,11 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
|
|
|
10739
10792
|
[`is-${messageColor}`]: !!messageColor,
|
|
10740
10793
|
});
|
|
10741
10794
|
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|
|
10742
|
-
|
|
10795
|
+
// The clear button gives way to a spinner at its spot: the `loading` one,
|
|
10796
|
+
// or that of a loading Control this sits in.
|
|
10797
|
+
const controlLoading = useControlLoading();
|
|
10798
|
+
const showClear = clearable && !!inputValue && !disabled && !loading && !controlLoading;
|
|
10799
|
+
const autocompleteElement = (jsxs("div", { ref: containerRef, className: combinedClasses, ...rest, children: [jsxs("div", { className: controlClasses, children: [jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: placeholder, disabled: disabled, name: name, form: form, required: required, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, role: "combobox", "aria-expanded": isActive, "aria-haspopup": "listbox", "aria-autocomplete": "list", autoComplete: "off" }), showClear && (jsx("button", { type: "button", className: iconRightClickableClass, onClick: handleClear, "aria-label": "Clear", children: jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", "aria-hidden": "true", children: [jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })), loading && (jsx("span", { className: iconRightClass, children: jsx("span", { className: loaderClass }) }))] }), isActive && (filteredData.length > 0 || empty) && (jsx("div", { className: dropdownMenuClasses, children: jsxs("div", { ref: dropdownRef, className: dropdownContentClass, style: { maxHeight: `${maxHeight}px`, overflowY: 'auto' }, role: "listbox", onScroll: handleDropdownScroll, children: [header && jsx("div", { className: dropdownHeaderClass, children: header }), filteredData.length > 0 ? (filteredData.map((item, index) => {
|
|
10743
10800
|
const isDisabled = typeof item !== 'string' && item.disabled;
|
|
10744
10801
|
const isHighlighted = index === highlightedIndex;
|
|
10745
10802
|
const itemClasses = prefixedClassNames(classPrefix, 'dropdown-item', {
|
|
@@ -11247,6 +11304,21 @@ fieldClassName, controlClassName,
|
|
|
11247
11304
|
horizontal,
|
|
11248
11305
|
fieldClassName,
|
|
11249
11306
|
});
|
|
11307
|
+
const ownControl = rendersOwnControl('Input', {
|
|
11308
|
+
insideControl,
|
|
11309
|
+
isLoading,
|
|
11310
|
+
iconLeft,
|
|
11311
|
+
iconLeftName,
|
|
11312
|
+
iconLeftSize,
|
|
11313
|
+
iconRight,
|
|
11314
|
+
iconRightName,
|
|
11315
|
+
iconRightSize,
|
|
11316
|
+
hasIconsLeft,
|
|
11317
|
+
hasIconsRight,
|
|
11318
|
+
isExpanded,
|
|
11319
|
+
controlSize,
|
|
11320
|
+
controlClassName,
|
|
11321
|
+
});
|
|
11250
11322
|
const { controlId, fieldLabelProps } = useAutoLabelId({
|
|
11251
11323
|
label,
|
|
11252
11324
|
id: inputProps.id,
|
|
@@ -11257,7 +11329,7 @@ fieldClassName, controlClassName,
|
|
|
11257
11329
|
[`is-${messageColor}`]: !!messageColor,
|
|
11258
11330
|
});
|
|
11259
11331
|
let content = jsx(InputBase, { ref: ref, id: controlId, ...inputProps });
|
|
11260
|
-
if (
|
|
11332
|
+
if (ownControl) {
|
|
11261
11333
|
content = (jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
|
|
11262
11334
|
}
|
|
11263
11335
|
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|
|
@@ -11305,6 +11377,17 @@ fieldClassName, controlClassName,
|
|
|
11305
11377
|
horizontal,
|
|
11306
11378
|
fieldClassName,
|
|
11307
11379
|
});
|
|
11380
|
+
// Not isLoading, which the select draws itself and so keeps in a Control.
|
|
11381
|
+
const ownControl = rendersOwnControl('Select', {
|
|
11382
|
+
insideControl,
|
|
11383
|
+
iconLeft,
|
|
11384
|
+
iconLeftName,
|
|
11385
|
+
iconLeftSize,
|
|
11386
|
+
hasIconsLeft,
|
|
11387
|
+
isExpanded,
|
|
11388
|
+
controlSize,
|
|
11389
|
+
controlClassName,
|
|
11390
|
+
});
|
|
11308
11391
|
const { controlId, fieldLabelProps } = useAutoLabelId({
|
|
11309
11392
|
label,
|
|
11310
11393
|
id: selectProps.id,
|
|
@@ -11315,7 +11398,7 @@ fieldClassName, controlClassName,
|
|
|
11315
11398
|
[`is-${messageColor}`]: !!messageColor,
|
|
11316
11399
|
});
|
|
11317
11400
|
let content = jsx(SelectBase, { ref: ref, id: controlId, ...selectProps });
|
|
11318
|
-
if (
|
|
11401
|
+
if (ownControl) {
|
|
11319
11402
|
content = (jsx(Control, { iconLeft: iconLeft, iconLeftName: iconLeftName, iconLeftSize: iconLeftSize, hasIconsLeft: hasIconsLeft, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
|
|
11320
11403
|
}
|
|
11321
11404
|
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|
|
@@ -11364,6 +11447,12 @@ fieldClassName, controlClassName,
|
|
|
11364
11447
|
horizontal,
|
|
11365
11448
|
fieldClassName,
|
|
11366
11449
|
});
|
|
11450
|
+
const ownControl = rendersOwnControl('TextArea', {
|
|
11451
|
+
insideControl,
|
|
11452
|
+
isLoading: controlIsLoading,
|
|
11453
|
+
controlSize,
|
|
11454
|
+
controlClassName,
|
|
11455
|
+
});
|
|
11367
11456
|
const { controlId, fieldLabelProps } = useAutoLabelId({
|
|
11368
11457
|
label,
|
|
11369
11458
|
id: textAreaProps.id,
|
|
@@ -11374,7 +11463,7 @@ fieldClassName, controlClassName,
|
|
|
11374
11463
|
[`is-${messageColor}`]: !!messageColor,
|
|
11375
11464
|
});
|
|
11376
11465
|
let content = jsx(TextAreaBase, { ref: ref, id: controlId, ...textAreaProps });
|
|
11377
|
-
if (
|
|
11466
|
+
if (ownControl) {
|
|
11378
11467
|
content = (jsx(Control, { isLoading: controlIsLoading, size: controlSize, className: controlClassName, children: content }));
|
|
11379
11468
|
}
|
|
11380
11469
|
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|
|
@@ -12006,10 +12095,11 @@ function nearestEnabled(i, disabled) {
|
|
|
12006
12095
|
return i;
|
|
12007
12096
|
}
|
|
12008
12097
|
/**
|
|
12009
|
-
* The year list's keyboard
|
|
12010
|
-
* year or a row, Home/End go to the list's ends. Returns the
|
|
12011
|
-
* from and the direction to search past disabled years, or
|
|
12012
|
-
* the list doesn't handle.
|
|
12098
|
+
* The year list's keyboard, as the selection surface and as navigation:
|
|
12099
|
+
* arrows move a year or a row, Home/End go to the list's ends. Returns the
|
|
12100
|
+
* year to start from and the direction to search past disabled years, or
|
|
12101
|
+
* `null` for a key the list doesn't handle. As navigation no year is
|
|
12102
|
+
* disabled, so only the year is used.
|
|
12013
12103
|
*/
|
|
12014
12104
|
function yearStep(key, focusedYear, years) {
|
|
12015
12105
|
switch (key) {
|
|
@@ -12270,8 +12360,8 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12270
12360
|
// year is disabled the stop moves to the nearest enabled year in the list,
|
|
12271
12361
|
// and focusing it makes it the focused year. As the selection surface a
|
|
12272
12362
|
// year outside a non-empty list starts from the end it fell past, so the
|
|
12273
|
-
// list keeps a stop. As navigation
|
|
12274
|
-
//
|
|
12363
|
+
// list keeps a stop. As navigation it marks the current year, so a year
|
|
12364
|
+
// outside the list marks no option, and the stop itself follows focus.
|
|
12275
12365
|
const tabStopYear = useMemo(() => {
|
|
12276
12366
|
let i = yearList.indexOf(focusedYear);
|
|
12277
12367
|
if (i < 0) {
|
|
@@ -12281,6 +12371,12 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12281
12371
|
}
|
|
12282
12372
|
return yearList[nearestEnabled(i, yearList.map(y => disabledYears.has(y)))];
|
|
12283
12373
|
}, [yearList, focusedYear, disabledYears, isYearGranularity]);
|
|
12374
|
+
// As navigation the keys move focus and leave the focused year alone, so
|
|
12375
|
+
// the tab stop goes to the year that last had focus while it is listed,
|
|
12376
|
+
// and Tab leaves the list rather than landing on the current year. It
|
|
12377
|
+
// starts over each time the list opens.
|
|
12378
|
+
const [navYear, setNavYear] = useState(null);
|
|
12379
|
+
const listTabStop = navYear !== null && yearList.includes(navYear) ? navYear : tabStopYear;
|
|
12284
12380
|
// Which of the focused year's months have no selectable day.
|
|
12285
12381
|
const disabledMonths = useMemo(() => granularity === 'month'
|
|
12286
12382
|
? Array.from({ length: 12 }, (_, m) => isMonthUnselectable(makeDate(focusedYear, m)))
|
|
@@ -12316,19 +12412,39 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12316
12412
|
}
|
|
12317
12413
|
}, [yearList, disabledYears, onFocusedDateChange, min, max]);
|
|
12318
12414
|
const handleYearListKeyDown = useCallback((e) => {
|
|
12319
|
-
if (
|
|
12320
|
-
|
|
12321
|
-
if (
|
|
12322
|
-
|
|
12323
|
-
|
|
12324
|
-
|
|
12415
|
+
if (isYearGranularity) {
|
|
12416
|
+
const step = yearStep(e.key, focusedYear, yearList);
|
|
12417
|
+
if (!step)
|
|
12418
|
+
return;
|
|
12419
|
+
e.preventDefault();
|
|
12420
|
+
moveYearFocus(step[0], step[1]);
|
|
12325
12421
|
return;
|
|
12326
12422
|
}
|
|
12327
|
-
|
|
12423
|
+
// As navigation, Escape returns to the grid the list was opened from.
|
|
12424
|
+
// It stops there, so a popover around the calendar stays open and only
|
|
12425
|
+
// a second Escape closes it.
|
|
12426
|
+
if (e.key === 'Escape') {
|
|
12427
|
+
e.preventDefault();
|
|
12428
|
+
e.stopPropagation();
|
|
12429
|
+
setView(baseView);
|
|
12430
|
+
return;
|
|
12431
|
+
}
|
|
12432
|
+
// The other keys move DOM focus from the year that has it and leave
|
|
12433
|
+
// the focused date alone. The list is centred on that date, so moving
|
|
12434
|
+
// it would reflow the list under the keyboard, and it would turn the
|
|
12435
|
+
// grid behind the list before anything is picked. Enter or Space
|
|
12436
|
+
// clicks the year with focus, which picks it.
|
|
12437
|
+
const options = Array.from(e.currentTarget.querySelectorAll('[role="option"]'));
|
|
12438
|
+
const from = options.indexOf(e.target);
|
|
12439
|
+
if (from < 0)
|
|
12440
|
+
return;
|
|
12441
|
+
const step = yearStep(e.key, yearList[from], yearList);
|
|
12328
12442
|
if (!step)
|
|
12329
12443
|
return;
|
|
12330
12444
|
e.preventDefault();
|
|
12331
|
-
|
|
12445
|
+
// The listed years run one apart, so a year's index is its distance
|
|
12446
|
+
// from the first. A step past either end finds no option.
|
|
12447
|
+
options[step[0] - yearList[0]]?.focus();
|
|
12332
12448
|
}, [isYearGranularity, baseView, focusedYear, yearList, moveYearFocus]);
|
|
12333
12449
|
// The day or month grid takes focus as the popover opens on it, or comes
|
|
12334
12450
|
// back to it from the year list.
|
|
@@ -12399,7 +12515,10 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12399
12515
|
list.querySelector('[data-focused-year="true"]')?.focus();
|
|
12400
12516
|
}, [isYearGranularity, focusedYear]);
|
|
12401
12517
|
const navArrow = (d) => (jsx("svg", { viewBox: "0 0 16 16", width: "14", height: "14", "aria-hidden": "true", children: jsx("path", { d: d, fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
12402
|
-
return (jsxs("div", { className: classNames(calendarClass, className), id: id, children: [jsxs("div", { className: headerClass, children: [isYearGranularity ? (jsx("span", { className: monthLabelClass, id: labelId, children: monthLabel })) : (jsxs("button", { type: "button", className: monthTriggerClass, "aria-haspopup": "listbox", "aria-expanded": view === 'years', onClick: () =>
|
|
12518
|
+
return (jsxs("div", { className: classNames(calendarClass, className), id: id, children: [jsxs("div", { className: headerClass, children: [isYearGranularity ? (jsx("span", { className: monthLabelClass, id: labelId, children: monthLabel })) : (jsxs("button", { type: "button", className: monthTriggerClass, "aria-haspopup": "listbox", "aria-expanded": view === 'years', onClick: () => {
|
|
12519
|
+
setNavYear(null);
|
|
12520
|
+
setView(v => (v === 'years' ? baseView : 'years'));
|
|
12521
|
+
}, children: [jsx("span", { className: monthLabelClass, id: labelId, "aria-live": "polite", children: monthLabel }), jsx("svg", { className: monthCaretClass, viewBox: "0 0 12 12", width: "10", height: "10", "aria-hidden": "true", children: jsx("path", { d: "M2 4l4 4 4-4", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) })] })), !isYearGranularity && (jsxs("div", { className: navGroupClass, children: [jsx("button", { type: "button", className: navPrevClass, "aria-label": isDayGranularity ? t.prevMonth : t.prevYear, disabled: prevDisabled || view !== baseView, onClick: () => onFocusedDateChange(prevAnchor), children: navArrow('M10 3l-5 5 5 5') }), jsx("button", { type: "button", className: navNextClass, "aria-label": isDayGranularity ? t.nextMonth : t.nextYear, disabled: nextDisabled || view !== baseView, onClick: () => onFocusedDateChange(nextAnchor), children: navArrow('M6 3l5 5-5 5') })] }))] }), view === 'days' && (jsxs(Fragment, { children: [jsx("div", { className: dayNamesRowClass, "aria-hidden": "true", children: computedDayNames.map((name, i) => (jsx("div", { className: dayNameClass, children: name }, i))) }), jsx("div", { ref: gridRef, role: "grid", "aria-labelledby": labelId, className: gridClass, onKeyDown: handleKeyDown, ...gridFocusHandlers, children: cells.map(cell => {
|
|
12403
12522
|
const disabled = isDateUnselectable(cell.date);
|
|
12404
12523
|
const isSelected = !!value && isSameDay(value, cell.date);
|
|
12405
12524
|
const isFocused = isSameDay(cell.date, tabStopDay);
|
|
@@ -12459,10 +12578,16 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min: minP
|
|
|
12459
12578
|
'is-today': isToday,
|
|
12460
12579
|
'is-disabled': disabled,
|
|
12461
12580
|
});
|
|
12462
|
-
return (jsx("button", { type: "button", role: "option", "aria-selected": isSelected, "aria-disabled": isYearGranularity ? disabled : undefined, "aria-current": isYearGranularity && isToday ? 'date' : undefined, "data-focused-year": isFocused ? 'true' : undefined, tabIndex:
|
|
12463
|
-
//
|
|
12464
|
-
//
|
|
12465
|
-
|
|
12581
|
+
return (jsx("button", { type: "button", role: "option", "aria-selected": isSelected, "aria-disabled": isYearGranularity ? disabled : undefined, "aria-current": isYearGranularity && isToday ? 'date' : undefined, "data-focused-year": isFocused ? 'true' : undefined, tabIndex: year === listTabStop ? 0 : -1, disabled: disabled, className: cellCls, onFocus: () => {
|
|
12582
|
+
// As navigation, focusing a year by key or pointer only
|
|
12583
|
+
// moves the tab stop: nothing is committed until a year is
|
|
12584
|
+
// picked. As the selection surface it is reached by Tab
|
|
12585
|
+
// while the focused year is disabled, or by pointer, and
|
|
12586
|
+
// keys move on from here.
|
|
12587
|
+
if (!isYearGranularity) {
|
|
12588
|
+
setNavYear(year);
|
|
12589
|
+
}
|
|
12590
|
+
else if (year !== focusedYear) {
|
|
12466
12591
|
onFocusedDateChange(clampDate(makeDate(year), min, max));
|
|
12467
12592
|
}
|
|
12468
12593
|
}, onClick: () => isYearGranularity
|
|
@@ -13608,7 +13733,8 @@ DateInputBase.displayName = 'DateInputBase';
|
|
|
13608
13733
|
* shouldDisableDate={d => d.getDay() === 0 || d.getDay() === 6}
|
|
13609
13734
|
* />
|
|
13610
13735
|
*/
|
|
13611
|
-
const DateInput = forwardRef((
|
|
13736
|
+
const DateInput = forwardRef((props, ref) => {
|
|
13737
|
+
const { label, labelSize, labelProps, horizontal, iconLeft, iconRight, iconLeftName = 'calendar', iconRightName, iconLeftSize, iconRightSize, hasIconsLeft, hasIconsRight, isLoading, isExpanded, controlSize, message, messageColor, fieldClassName, controlClassName, ...baseProps } = props;
|
|
13612
13738
|
const insideField = useInsideField();
|
|
13613
13739
|
const insideControl = useInsideControl();
|
|
13614
13740
|
const ownField = rendersOwnField('DateInput', {
|
|
@@ -13619,6 +13745,27 @@ const DateInput = forwardRef(({ label, labelSize, labelProps, horizontal, iconLe
|
|
|
13619
13745
|
horizontal,
|
|
13620
13746
|
fieldClassName,
|
|
13621
13747
|
});
|
|
13748
|
+
// Inline mode renders a bare calendar with no input, so the Control's
|
|
13749
|
+
// icon-left container has nothing to anchor to, and it renders no
|
|
13750
|
+
// Control inside one or out. The left icon is checked as the caller
|
|
13751
|
+
// passed it: the default glyph is this component's own choice, not a
|
|
13752
|
+
// prop the caller set.
|
|
13753
|
+
const ownControl = rendersOwnControl('DateInput', {
|
|
13754
|
+
insideControl,
|
|
13755
|
+
inline: baseProps.inline,
|
|
13756
|
+
isLoading,
|
|
13757
|
+
iconLeft,
|
|
13758
|
+
iconLeftName: props.iconLeftName,
|
|
13759
|
+
iconLeftSize,
|
|
13760
|
+
iconRight,
|
|
13761
|
+
iconRightName,
|
|
13762
|
+
iconRightSize,
|
|
13763
|
+
hasIconsLeft,
|
|
13764
|
+
hasIconsRight,
|
|
13765
|
+
isExpanded,
|
|
13766
|
+
controlSize,
|
|
13767
|
+
controlClassName,
|
|
13768
|
+
});
|
|
13622
13769
|
const { controlId, fieldLabelProps } = useAutoLabelId({
|
|
13623
13770
|
label,
|
|
13624
13771
|
id: baseProps.id,
|
|
@@ -13632,9 +13779,7 @@ const DateInput = forwardRef(({ label, labelSize, labelProps, horizontal, iconLe
|
|
|
13632
13779
|
// The base hides its launcher while the Control it sits in is loading,
|
|
13633
13780
|
// whether that is the one rendered below or an enclosing one.
|
|
13634
13781
|
let content = (jsx(DateInputBase, { ref: ref, id: controlId, ...baseProps }));
|
|
13635
|
-
|
|
13636
|
-
// icon-left container has nothing to anchor to. Skip the Control wrap.
|
|
13637
|
-
if (!insideControl && !baseProps.inline) {
|
|
13782
|
+
if (ownControl) {
|
|
13638
13783
|
content = (jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft || !!iconLeftName, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
|
|
13639
13784
|
}
|
|
13640
13785
|
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|
|
@@ -14716,7 +14861,8 @@ TimeInputBase.displayName = 'TimeInputBase';
|
|
|
14716
14861
|
* @example
|
|
14717
14862
|
* <TimeInput label="Slot" hourFormat="12" incrementMinutes={15} />
|
|
14718
14863
|
*/
|
|
14719
|
-
const TimeInput = forwardRef((
|
|
14864
|
+
const TimeInput = forwardRef((props, ref) => {
|
|
14865
|
+
const { label, labelSize, labelProps, horizontal, iconLeft, iconRight, iconLeftName = 'clock', iconRightName, iconLeftSize, iconRightSize, hasIconsLeft, hasIconsRight, isLoading, isExpanded, controlSize, message, messageColor, fieldClassName, controlClassName, ...baseProps } = props;
|
|
14720
14866
|
const insideField = useInsideField();
|
|
14721
14867
|
const insideControl = useInsideControl();
|
|
14722
14868
|
const ownField = rendersOwnField('TimeInput', {
|
|
@@ -14727,6 +14873,27 @@ const TimeInput = forwardRef(({ label, labelSize, labelProps, horizontal, iconLe
|
|
|
14727
14873
|
horizontal,
|
|
14728
14874
|
fieldClassName,
|
|
14729
14875
|
});
|
|
14876
|
+
// Inline mode renders a bare panel with no input, so the Control's
|
|
14877
|
+
// icon-left container has nothing to anchor to, and it renders no
|
|
14878
|
+
// Control inside one or out. The left icon is checked as the caller
|
|
14879
|
+
// passed it: the default glyph is this component's own choice, not a
|
|
14880
|
+
// prop the caller set.
|
|
14881
|
+
const ownControl = rendersOwnControl('TimeInput', {
|
|
14882
|
+
insideControl,
|
|
14883
|
+
inline: baseProps.inline,
|
|
14884
|
+
isLoading,
|
|
14885
|
+
iconLeft,
|
|
14886
|
+
iconLeftName: props.iconLeftName,
|
|
14887
|
+
iconLeftSize,
|
|
14888
|
+
iconRight,
|
|
14889
|
+
iconRightName,
|
|
14890
|
+
iconRightSize,
|
|
14891
|
+
hasIconsLeft,
|
|
14892
|
+
hasIconsRight,
|
|
14893
|
+
isExpanded,
|
|
14894
|
+
controlSize,
|
|
14895
|
+
controlClassName,
|
|
14896
|
+
});
|
|
14730
14897
|
const { controlId, fieldLabelProps } = useAutoLabelId({
|
|
14731
14898
|
label,
|
|
14732
14899
|
id: baseProps.id,
|
|
@@ -14740,9 +14907,7 @@ const TimeInput = forwardRef(({ label, labelSize, labelProps, horizontal, iconLe
|
|
|
14740
14907
|
// The base hides its launcher while the Control it sits in is loading,
|
|
14741
14908
|
// whether that is the one rendered below or an enclosing one.
|
|
14742
14909
|
let content = (jsx(TimeInputBase, { ref: ref, id: controlId, ...baseProps }));
|
|
14743
|
-
|
|
14744
|
-
// icon-left container has nothing to anchor to. Skip the Control wrap.
|
|
14745
|
-
if (!insideControl && !baseProps.inline) {
|
|
14910
|
+
if (ownControl) {
|
|
14746
14911
|
content = (jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft || !!iconLeftName, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
|
|
14747
14912
|
}
|
|
14748
14913
|
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|
|
@@ -15037,7 +15202,8 @@ DateTimeInputBase.displayName = 'DateTimeInputBase';
|
|
|
15037
15202
|
* shouldDisableDate={d => d.getDay() === 0 || d.getDay() === 6}
|
|
15038
15203
|
* />
|
|
15039
15204
|
*/
|
|
15040
|
-
const DateTimeInput = forwardRef((
|
|
15205
|
+
const DateTimeInput = forwardRef((props, ref) => {
|
|
15206
|
+
const { label, labelSize, labelProps, horizontal, iconLeft, iconRight, iconLeftName = 'calendar-alt', iconRightName, iconLeftSize, iconRightSize, hasIconsLeft, hasIconsRight, isLoading, isExpanded, controlSize, message, messageColor, fieldClassName, controlClassName, ...baseProps } = props;
|
|
15041
15207
|
const insideField = useInsideField();
|
|
15042
15208
|
const insideControl = useInsideControl();
|
|
15043
15209
|
const ownField = rendersOwnField('DateTimeInput', {
|
|
@@ -15048,6 +15214,27 @@ const DateTimeInput = forwardRef(({ label, labelSize, labelProps, horizontal, ic
|
|
|
15048
15214
|
horizontal,
|
|
15049
15215
|
fieldClassName,
|
|
15050
15216
|
});
|
|
15217
|
+
// Inline mode renders a bare picker with no input, so the Control's
|
|
15218
|
+
// icon-left container has nothing to anchor to, and it renders no
|
|
15219
|
+
// Control inside one or out. The left icon is checked as the caller
|
|
15220
|
+
// passed it: the default glyph is this component's own choice, not a
|
|
15221
|
+
// prop the caller set.
|
|
15222
|
+
const ownControl = rendersOwnControl('DateTimeInput', {
|
|
15223
|
+
insideControl,
|
|
15224
|
+
inline: baseProps.inline,
|
|
15225
|
+
isLoading,
|
|
15226
|
+
iconLeft,
|
|
15227
|
+
iconLeftName: props.iconLeftName,
|
|
15228
|
+
iconLeftSize,
|
|
15229
|
+
iconRight,
|
|
15230
|
+
iconRightName,
|
|
15231
|
+
iconRightSize,
|
|
15232
|
+
hasIconsLeft,
|
|
15233
|
+
hasIconsRight,
|
|
15234
|
+
isExpanded,
|
|
15235
|
+
controlSize,
|
|
15236
|
+
controlClassName,
|
|
15237
|
+
});
|
|
15051
15238
|
const { controlId, fieldLabelProps } = useAutoLabelId({
|
|
15052
15239
|
label,
|
|
15053
15240
|
id: baseProps.id,
|
|
@@ -15061,9 +15248,7 @@ const DateTimeInput = forwardRef(({ label, labelSize, labelProps, horizontal, ic
|
|
|
15061
15248
|
// The base hides its launcher while the Control it sits in is loading,
|
|
15062
15249
|
// whether that is the one rendered below or an enclosing one.
|
|
15063
15250
|
let content = (jsx(DateTimeInputBase, { ref: ref, id: controlId, ...baseProps }));
|
|
15064
|
-
|
|
15065
|
-
// icon-left container has nothing to anchor to. Skip the Control wrap.
|
|
15066
|
-
if (!insideControl && !baseProps.inline) {
|
|
15251
|
+
if (ownControl) {
|
|
15067
15252
|
content = (jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft || !!iconLeftName, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
|
|
15068
15253
|
}
|
|
15069
15254
|
const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
|