@rovula/ui 0.1.42 → 0.1.44
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/cjs/bundle.css +6 -0
- package/dist/cjs/bundle.js +13 -4
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/AutoComplete/AutoComplete.d.ts +3 -1
- package/dist/cjs/types/components/AutoComplete/AutoComplete.stories.d.ts +2 -1
- package/dist/components/AutoComplete/AutoComplete.js +4 -4
- package/dist/components/Badge/Badge.styles.js +2 -2
- package/dist/components/DataTable/DataTable.editing.js +19 -3
- package/dist/components/Dropdown/Dropdown.js +4 -1
- package/dist/esm/bundle.css +6 -0
- package/dist/esm/bundle.js +16 -7
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/AutoComplete/AutoComplete.d.ts +3 -1
- package/dist/esm/types/components/AutoComplete/AutoComplete.stories.d.ts +2 -1
- package/dist/index.d.ts +3 -1
- package/dist/src/theme/global.css +17 -9
- package/package.json +2 -2
- package/src/components/AutoComplete/AutoComplete.tsx +7 -2
- package/src/components/Badge/Badge.styles.ts +2 -2
- package/src/components/DataTable/DataTable.editing.tsx +19 -2
- package/src/components/Dropdown/Dropdown.tsx +4 -1
- package/src/theme/themes/variable.css +8 -8
- package/src/theme/tokens/components/table.css +1 -1
|
@@ -61,13 +61,15 @@ export type AutoCompleteProps<T extends AutoCompleteOption = AutoCompleteOption>
|
|
|
61
61
|
listboxClassName?: string;
|
|
62
62
|
/** Extra inline styles applied to the options list container */
|
|
63
63
|
listboxStyle?: React.CSSProperties;
|
|
64
|
+
/** Extra inline styles applied to the Popover content wrapper (portal mode only) */
|
|
65
|
+
popoverStyle?: React.CSSProperties;
|
|
64
66
|
/** Extra className applied to each option item */
|
|
65
67
|
optionClassName?: string;
|
|
66
68
|
/** Extra inline styles applied to each option item */
|
|
67
69
|
optionStyle?: React.CSSProperties;
|
|
68
70
|
"data-testid"?: string;
|
|
69
71
|
} & Omit<InputProps, OmittedInputProps>;
|
|
70
|
-
declare function AutoCompleteInner<T extends AutoCompleteOption = AutoCompleteOption>({ options, value, onChange, onSelect, onBlur, onSearch, loading, noOptionsText, showNoOptions, renderOption, filterOptions, portal, listboxClassName, listboxStyle, optionClassName, optionStyle, "data-testid": testId, id, label, fullwidth, size, rounded, variant, disabled, ...rest }: AutoCompleteProps<T>, ref: React.ForwardedRef<HTMLInputElement>): import("react/jsx-runtime").JSX.Element;
|
|
72
|
+
declare function AutoCompleteInner<T extends AutoCompleteOption = AutoCompleteOption>({ options, value, onChange, onSelect, onBlur, onSearch, loading, noOptionsText, showNoOptions, renderOption, filterOptions, portal, listboxClassName, listboxStyle, popoverStyle, optionClassName, optionStyle, "data-testid": testId, id, label, fullwidth, size, rounded, variant, disabled, ...rest }: AutoCompleteProps<T>, ref: React.ForwardedRef<HTMLInputElement>): import("react/jsx-runtime").JSX.Element;
|
|
71
73
|
declare const AutoComplete: <T extends AutoCompleteOption = AutoCompleteOption>(props: AutoCompleteProps<T> & {
|
|
72
74
|
ref?: React.ForwardedRef<HTMLInputElement>;
|
|
73
75
|
}) => ReturnType<typeof AutoCompleteInner>;
|
|
@@ -5,7 +5,7 @@ declare const meta: {
|
|
|
5
5
|
title: string;
|
|
6
6
|
component: <T extends AutoCompleteOption = AutoCompleteOption>(props: import("./AutoComplete").AutoCompleteProps<T> & {
|
|
7
7
|
ref?: React.ForwardedRef<HTMLInputElement>;
|
|
8
|
-
}) => ReturnType<(<T_1 extends AutoCompleteOption = AutoCompleteOption>({ options, value, onChange, onSelect, onBlur, onSearch, loading, noOptionsText, showNoOptions, renderOption, filterOptions, portal, listboxClassName, listboxStyle, optionClassName, optionStyle, "data-testid": testId, id, label, fullwidth, size, rounded, variant, disabled, ...rest }: import("./AutoComplete").AutoCompleteProps<T_1>, ref: React.ForwardedRef<HTMLInputElement>) => import("react/jsx-runtime").JSX.Element)>;
|
|
8
|
+
}) => ReturnType<(<T_1 extends AutoCompleteOption = AutoCompleteOption>({ options, value, onChange, onSelect, onBlur, onSearch, loading, noOptionsText, showNoOptions, renderOption, filterOptions, portal, listboxClassName, listboxStyle, popoverStyle, optionClassName, optionStyle, "data-testid": testId, id, label, fullwidth, size, rounded, variant, disabled, ...rest }: import("./AutoComplete").AutoCompleteProps<T_1>, ref: React.ForwardedRef<HTMLInputElement>) => import("react/jsx-runtime").JSX.Element)>;
|
|
9
9
|
tags: string[];
|
|
10
10
|
parameters: {
|
|
11
11
|
layout: string;
|
|
@@ -25,6 +25,7 @@ declare const meta: {
|
|
|
25
25
|
portal?: boolean | undefined;
|
|
26
26
|
listboxClassName?: string | undefined;
|
|
27
27
|
listboxStyle?: React.CSSProperties | undefined;
|
|
28
|
+
popoverStyle?: React.CSSProperties | undefined;
|
|
28
29
|
optionClassName?: string | undefined;
|
|
29
30
|
optionStyle?: React.CSSProperties | undefined;
|
|
30
31
|
"data-testid"?: string | undefined;
|
|
@@ -26,9 +26,9 @@ function AutoCompleteInner(_a, ref) {
|
|
|
26
26
|
var _b;
|
|
27
27
|
var {
|
|
28
28
|
// AutoComplete-specific props
|
|
29
|
-
options, value = "", onChange, onSelect, onBlur, onSearch, loading = false, noOptionsText = "No results", showNoOptions = false, renderOption, filterOptions = (x) => x, portal = true, listboxClassName, listboxStyle, optionClassName, optionStyle, "data-testid": testId,
|
|
29
|
+
options, value = "", onChange, onSelect, onBlur, onSearch, loading = false, noOptionsText = "No results", showNoOptions = false, renderOption, filterOptions = (x) => x, portal = true, listboxClassName, listboxStyle, popoverStyle, optionClassName, optionStyle, "data-testid": testId,
|
|
30
30
|
// InputProps with explicit defaults (rest passes everything else through)
|
|
31
|
-
id, label, fullwidth = true, size = "md", rounded = "normal", variant = "outline", disabled } = _a, rest = __rest(_a, ["options", "value", "onChange", "onSelect", "onBlur", "onSearch", "loading", "noOptionsText", "showNoOptions", "renderOption", "filterOptions", "portal", "listboxClassName", "listboxStyle", "optionClassName", "optionStyle", "data-testid", "id", "label", "fullwidth", "size", "rounded", "variant", "disabled"]);
|
|
31
|
+
id, label, fullwidth = true, size = "md", rounded = "normal", variant = "outline", disabled } = _a, rest = __rest(_a, ["options", "value", "onChange", "onSelect", "onBlur", "onSearch", "loading", "noOptionsText", "showNoOptions", "renderOption", "filterOptions", "portal", "listboxClassName", "listboxStyle", "popoverStyle", "optionClassName", "optionStyle", "data-testid", "id", "label", "fullwidth", "size", "rounded", "variant", "disabled"]);
|
|
32
32
|
const [open, setOpen] = useState(false);
|
|
33
33
|
const [activeIndex, setActiveIndex] = useState(-1);
|
|
34
34
|
const inputRef = useRef(null);
|
|
@@ -85,7 +85,7 @@ function AutoCompleteInner(_a, ref) {
|
|
|
85
85
|
setActiveIndex(-1);
|
|
86
86
|
}
|
|
87
87
|
}, [open, activeIndex, filteredOptions, commitSelection]);
|
|
88
|
-
const listContent = (_jsx("div", { role: "listbox", style: Object.assign({ boxShadow: "var(--dropdown-menu-shadow)" }, listboxStyle), className: cn("rounded-md border border-bg-stroke3
|
|
88
|
+
const listContent = (_jsx("div", { role: "listbox", style: Object.assign({ boxShadow: "var(--dropdown-menu-shadow)" }, listboxStyle), className: cn("max-h-60 overflow-y-auto", "rounded-md border border-bg-stroke3", "bg-modal-dropdown-surface text-text-g-contrast-high", !portal && "absolute top-full left-0 w-full -mt-3 z-[51]", portal && "z-[51]", listboxClassName), "data-testid": testId ? `${testId}-listbox` : undefined, children: loading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Loading, { size: 20 }) })) : filteredOptions.length === 0 ? (_jsx("div", { className: "px-4 py-6 text-center", children: _jsx(Text, { variant: "small1", className: "text-[var(--dropdown-menu-default-text)]", children: noOptionsText }) })) : (filteredOptions.map((option, index) => {
|
|
89
89
|
const isSelected = option.value === value;
|
|
90
90
|
const isActive = index === activeIndex;
|
|
91
91
|
return (_jsxs("button", { id: `autocomplete-option-${option.value}`, type: "button", role: "option", "aria-selected": isSelected, style: optionStyle, className: cn(menuItemBaseStyles, "w-full", isSelected &&
|
|
@@ -95,7 +95,7 @@ function AutoCompleteInner(_a, ref) {
|
|
|
95
95
|
})) }));
|
|
96
96
|
return (_jsxs(PopoverPrimitive.Root, { open: showPopover, children: [_jsx(PopoverPrimitive.Anchor, { asChild: true, children: _jsxs("div", { className: cn("relative", fullwidth && "w-full"), children: [_jsx(TextInput, Object.assign({}, rest, { ref: ref !== null && ref !== void 0 ? ref : inputRef, id: id, label: label, value: value, size: size, rounded: rounded, variant: variant, disabled: disabled, fullwidth: fullwidth, autoComplete: "off", role: "combobox", "aria-expanded": showPopover, "aria-autocomplete": "list", "aria-activedescendant": activeIndex >= 0
|
|
97
97
|
? `autocomplete-option-${(_b = filteredOptions[activeIndex]) === null || _b === void 0 ? void 0 : _b.value}`
|
|
98
|
-
: undefined, hasClearIcon: true, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, "data-testid": testId })), showPopover && !portal && listContent] }) }), portal && (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { onOpenAutoFocus: (e) => e.preventDefault(), onInteractOutside: (e) => e.preventDefault(), onFocusOutside: (e) => e.preventDefault(), side: "bottom", align: "start", sideOffset: -12, style: { width: "var(--radix-popover-trigger-width)" }, children: listContent }) }))] }));
|
|
98
|
+
: undefined, hasClearIcon: true, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, "data-testid": testId })), showPopover && !portal && listContent] }) }), portal && (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { onOpenAutoFocus: (e) => e.preventDefault(), onInteractOutside: (e) => e.preventDefault(), onFocusOutside: (e) => e.preventDefault(), side: "bottom", align: "start", sideOffset: -12, style: Object.assign({ width: "var(--radix-popover-trigger-width)", zIndex: 51 }, popoverStyle), children: listContent }) }))] }));
|
|
99
99
|
}
|
|
100
100
|
// forwardRef with generics requires a manual cast
|
|
101
101
|
const AutoComplete = forwardRef(AutoCompleteInner);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
export const badgeVariants = cva([
|
|
3
|
-
"inline-flex items-center justify-center rounded-
|
|
3
|
+
"inline-flex items-center justify-center rounded-[6px] px-3 py-1",
|
|
4
4
|
"typography-body3",
|
|
5
5
|
], {
|
|
6
6
|
variants: {
|
|
@@ -44,7 +44,7 @@ export const badgeVariants = cva([
|
|
|
44
44
|
},
|
|
45
45
|
});
|
|
46
46
|
export const severityBadgeVariants = cva([
|
|
47
|
-
"inline-flex items-center justify-center rounded px-1 py-0.5",
|
|
47
|
+
"inline-flex items-center justify-center rounded-[4px] px-1 py-0.5",
|
|
48
48
|
"typography-small6 text-[var(--badge-severity-text)]",
|
|
49
49
|
], {
|
|
50
50
|
variants: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import TextInput from "@/components/TextInput/TextInput";
|
|
4
4
|
import NumberInput from "@/components/NumberInput";
|
|
5
5
|
import { Checkbox } from "@/components/Checkbox/Checkbox";
|
|
@@ -295,6 +295,22 @@ function EditCellText({ columnId, row, placeholder, autoFocus, errorMessage, onB
|
|
|
295
295
|
}
|
|
296
296
|
function EditCellSelect({ row, columnId, col, autoFocus, onCommit, onBlurField, onKeyDown, keepOpenAfterSelect, errorMessage, }) {
|
|
297
297
|
var _a, _b, _c, _d, _e;
|
|
298
|
+
const selectRef = useRef(null);
|
|
299
|
+
// Cell mode: React's `autoFocus` fires el.focus() during the commit phase,
|
|
300
|
+
// which causes Headless UI's flushSync-inside-microTask to run while React
|
|
301
|
+
// is still committing → silent failure in concurrent mode. Delay focus to a
|
|
302
|
+
// rAF (same approach as row-mode Tab navigation) so it fires safely after
|
|
303
|
+
// the commit. Cancel on cleanup so StrictMode's double-mount is safe.
|
|
304
|
+
useEffect(() => {
|
|
305
|
+
if (!autoFocus)
|
|
306
|
+
return;
|
|
307
|
+
const el = selectRef.current;
|
|
308
|
+
if (!el)
|
|
309
|
+
return;
|
|
310
|
+
const rafId = requestAnimationFrame(() => el.focus());
|
|
311
|
+
return () => cancelAnimationFrame(rafId);
|
|
312
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
313
|
+
}, []);
|
|
298
314
|
const displayValue = String((_a = row.original[columnId]) !== null && _a !== void 0 ? _a : "");
|
|
299
315
|
const rawOptions = typeof ((_b = col.editSelectProps) === null || _b === void 0 ? void 0 : _b.options) === "function"
|
|
300
316
|
? col.editSelectProps.options(row)
|
|
@@ -311,11 +327,11 @@ function EditCellSelect({ row, columnId, col, autoFocus, onCommit, onBlurField,
|
|
|
311
327
|
return options[0];
|
|
312
328
|
return (_a = options.find((o) => o.label === cur)) !== null && _a !== void 0 ? _a : options[0];
|
|
313
329
|
}, [displayValue, options]);
|
|
314
|
-
return (_jsx("div", { children: _jsx(Dropdown, { id: `edit-dd-${columnId}-${row.id}`, options: options, value: selected, onSelect: (opt) => {
|
|
330
|
+
return (_jsx("div", { children: _jsx(Dropdown, { id: `edit-dd-${columnId}-${row.id}`, ref: selectRef, options: options, value: selected, onSelect: (opt) => {
|
|
315
331
|
if (isPlaceholderOption(opt))
|
|
316
332
|
return;
|
|
317
333
|
onCommit(opt.label);
|
|
318
|
-
}, size: "sm", variant: "outline", rounded: "normal", fullwidth: true, required: false, isFloatingLabel: false, label: "", keepFooterSpace: false, segmentedInput: true, autoFocus:
|
|
334
|
+
}, size: "sm", variant: "outline", rounded: "normal", fullwidth: true, required: false, isFloatingLabel: false, label: "", keepFooterSpace: false, segmentedInput: true, autoFocus: false, onBlur: onBlurField, onKeyDown: onKeyDown, keepOpenAfterSelect: keepOpenAfterSelect, portal: true, error: !!errorMessage, errorMessage: errorMessage, className: cn("rounded-md", customInputVariant({ size: "sm" }), displayValue.trim().length > 0 && "font-medium") }) }));
|
|
319
335
|
}
|
|
320
336
|
// ---------------------------------------------------------------------------
|
|
321
337
|
// EditCellNumber — inline number editor
|
|
@@ -84,7 +84,10 @@ const Dropdown = forwardRef((_a, ref) => {
|
|
|
84
84
|
});
|
|
85
85
|
};
|
|
86
86
|
return (_jsx(Combobox, { value: selectedOption, onChange: handleSelect, immediate: true, by: "value", disabled: disabled, children: ({ open }) => (_jsxs("div", { className: cn("relative", fullwidth && "w-full"), children: [_jsx(ComboboxInput, Object.assign({ as: TextInput, ref: inputRef, hasClearIcon: false, endIcon: _jsx(ChevronDownIcon, { className: dropdownIconVariant({ isFocus: open }) }), label: label, autoComplete: "off", rounded: rounded, variant: variant, helperText: helperText, errorMessage: errorMessage, fullwidth: fullwidth, error: error, required: required, id: _id, disabled: disabled, size: size, className: segmentedInput ? customInputVariant({ size }) : undefined, displayValue: (opt) => { var _a; return (_a = opt === null || opt === void 0 ? void 0 : opt.label) !== null && _a !== void 0 ? _a : ""; }, readOnly: !filterMode, onChange: handleInputChange }, props)), _jsx(ComboboxOptions, Object.assign({}, (portal
|
|
87
|
-
? {
|
|
87
|
+
? {
|
|
88
|
+
portal: true,
|
|
89
|
+
anchor: { to: "bottom start", gap: 4 },
|
|
90
|
+
}
|
|
88
91
|
: {}), { className: cn(!portal && "absolute top-full left-0 w-full -mt-3 z-[51]", portal && "z-[51] !max-h-60 w-[var(--input-width)]", "min-w-[154px] max-h-60 overflow-y-auto", "rounded-md bg-modal-dropdown-surface border border-bg-stroke3 text-text-g-contrast-high", optionContainerClassName), style: { boxShadow: "var(--dropdown-menu-shadow)" }, children: renderOptionList() }))] })) }));
|
|
89
92
|
});
|
|
90
93
|
Dropdown.displayName = "Dropdown";
|
package/dist/esm/bundle.css
CHANGED
|
@@ -1629,6 +1629,12 @@ input[type=number] {
|
|
|
1629
1629
|
.rounded-\[2px\]{
|
|
1630
1630
|
border-radius: 2px;
|
|
1631
1631
|
}
|
|
1632
|
+
.rounded-\[4px\]{
|
|
1633
|
+
border-radius: 4px;
|
|
1634
|
+
}
|
|
1635
|
+
.rounded-\[6px\]{
|
|
1636
|
+
border-radius: 6px;
|
|
1637
|
+
}
|
|
1632
1638
|
.rounded-\[8px\]{
|
|
1633
1639
|
border-radius: 8px;
|
|
1634
1640
|
}
|