@pk-design/react-tailwind 1.4.2 → 1.4.4
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.
|
@@ -142,8 +142,8 @@ const loaderSizeMap = {
|
|
|
142
142
|
md: 'size-8',
|
|
143
143
|
lg: 'size-10',
|
|
144
144
|
};
|
|
145
|
-
const Loader = ({ className = '
|
|
146
|
-
return (jsxRuntime.jsx("svg", { className: buildClassName(loaderSizeMap[size], className, 'spinner'), viewBox: "0 0 50 50", ...props, children: jsxRuntime.jsx("circle", { className: "path", cx: "25", cy: "25", r: "20", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "5" }) }));
|
|
145
|
+
const Loader = ({ className = '', size = 'md', ...props }) => {
|
|
146
|
+
return (jsxRuntime.jsx("svg", { className: buildClassName('text-blue-600 dark:text-white', loaderSizeMap[size], className, 'spinner'), viewBox: "0 0 50 50", ...props, children: jsxRuntime.jsx("circle", { className: "path", cx: "25", cy: "25", r: "20", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "5" }) }));
|
|
147
147
|
};
|
|
148
148
|
|
|
149
149
|
const TextContent = React.forwardRef((props, ref) => {
|
|
@@ -176,6 +176,23 @@ const THEMED_BTN_CLASS = {
|
|
|
176
176
|
plain: 'text-gray-700 hover:bg-black/5 dark:text-gray-200 dark:hover:bg-gray-700 focus:outline-[var(--ui-focus-ring)] disabled:text-gray-400',
|
|
177
177
|
},
|
|
178
178
|
};
|
|
179
|
+
const LOADER_TEXT_CLASS = {
|
|
180
|
+
primary: {
|
|
181
|
+
default: 'text-white',
|
|
182
|
+
outlined: 'text-[var(--ui-primary-text)]',
|
|
183
|
+
plain: 'text-[var(--ui-primary-text)]',
|
|
184
|
+
},
|
|
185
|
+
danger: {
|
|
186
|
+
default: 'text-white',
|
|
187
|
+
outlined: 'text-[var(--ui-danger-text)]',
|
|
188
|
+
plain: 'text-[var(--ui-danger-text)]',
|
|
189
|
+
},
|
|
190
|
+
secondary: {
|
|
191
|
+
default: 'text-gray-700 dark:text-white',
|
|
192
|
+
outlined: 'text-gray-700 dark:text-gray-200',
|
|
193
|
+
plain: 'text-gray-700 dark:text-gray-200',
|
|
194
|
+
},
|
|
195
|
+
};
|
|
179
196
|
/**
|
|
180
197
|
* Generate size classes.
|
|
181
198
|
*/
|
|
@@ -225,7 +242,7 @@ const Button = React.forwardRef(({ as, type, ...props }, ref) => {
|
|
|
225
242
|
if (loading && iconOnly) {
|
|
226
243
|
return (jsxRuntime.jsx(Component, { ref: ref, className: classes, ...buttonSpecificProps, ...cleanRest, children: jsxRuntime.jsx(Loader, { "data-testid": "btn-loader-icon", size: "xs" }) }));
|
|
227
244
|
}
|
|
228
|
-
return (jsxRuntime.jsx(Component, { ref: ref, className: classes, ...buttonSpecificProps, ...cleanRest, children: loading ? (jsxRuntime.jsxs("span", { className: "flex items-center gap-2", "aria-live": "polite", children: [jsxRuntime.jsx(Loader, { "data-testid": "btn-loader-icon", size: "xs" }), loadingText && jsxRuntime.jsx(TextContent, { children: loadingText })] })) : (children) }));
|
|
245
|
+
return (jsxRuntime.jsx(Component, { ref: ref, className: classes, ...buttonSpecificProps, ...cleanRest, children: loading ? (jsxRuntime.jsxs("span", { className: "flex items-center gap-2", "aria-live": "polite", children: [jsxRuntime.jsx(Loader, { "data-testid": "btn-loader-icon", size: "xs", className: buildClassName(LOADER_TEXT_CLASS[theme][variant]) }), loadingText && (jsxRuntime.jsx(TextContent, { className: buildClassName(LOADER_TEXT_CLASS[theme][variant]), children: loadingText }))] })) : (children) }));
|
|
229
246
|
});
|
|
230
247
|
Button.displayName = 'Button';
|
|
231
248
|
|
|
@@ -805,11 +822,11 @@ function DataTable({ items, columns, sorting = {}, onSort, loading, pagination,
|
|
|
805
822
|
}
|
|
806
823
|
DataTable.displayName = 'DataTable';
|
|
807
824
|
|
|
808
|
-
const Title = ({ children, className }) => (jsxRuntime.jsx("h1", { className: buildClassName('text-3xl font-bold', className), children: children }));
|
|
809
|
-
const SubTitle = ({ children, className }) => (jsxRuntime.jsx("h2", { className: buildClassName('text-2xl font-semibold', className), children: children }));
|
|
810
|
-
const SubTitle2 = ({ children, className }) => (jsxRuntime.jsx("h3", { className: buildClassName('text-xl font-semibold', className), children: children }));
|
|
811
|
-
const SubTitle3 = ({ children, className }) => (jsxRuntime.jsx("h4", { className: buildClassName('text-lg font-medium', className), children: children }));
|
|
812
|
-
const SubTitle4 = ({ children, className }) => (jsxRuntime.jsx("h5", { className: buildClassName('text-base font-medium', className), children: children }));
|
|
825
|
+
const Title = ({ children, className }) => (jsxRuntime.jsx("h1", { className: buildClassName('text-3xl font-bold text-gray-900 dark:text-white', className), children: children }));
|
|
826
|
+
const SubTitle = ({ children, className }) => (jsxRuntime.jsx("h2", { className: buildClassName('text-2xl font-semibold text-gray-900 dark:text-white', className), children: children }));
|
|
827
|
+
const SubTitle2 = ({ children, className }) => (jsxRuntime.jsx("h3", { className: buildClassName('text-xl font-semibold text-gray-900 dark:text-white', className), children: children }));
|
|
828
|
+
const SubTitle3 = ({ children, className }) => (jsxRuntime.jsx("h4", { className: buildClassName('text-lg font-medium text-gray-900 dark:text-white', className), children: children }));
|
|
829
|
+
const SubTitle4 = ({ children, className }) => (jsxRuntime.jsx("h5", { className: buildClassName('text-base font-medium text-gray-900 dark:text-white', className), children: children }));
|
|
813
830
|
const HeadingText = {
|
|
814
831
|
Title,
|
|
815
832
|
SubTitle,
|
|
@@ -1205,7 +1222,7 @@ var SvgCirclePlus = function SvgCirclePlus(props) {
|
|
|
1205
1222
|
|
|
1206
1223
|
const constructInputClass = (disabled) => buildInputClass('', { disabled });
|
|
1207
1224
|
const SelectBox = React.forwardRef((props, forwardedRef) => {
|
|
1208
|
-
const { labelKey = 'label', valueKey = 'value', name, id = name, options, selected, label = null, labelWrapperClass = '', labelClass = '', labelHint = null, disabled = false, containerClass = '', onChange = () => { }, placeholder, dropdownContainerClass = 'z-20', multiple = false, maxSelection, immediate = true, showErrorMessage = true, error = null, async = false, searchable = true, required = false, allowAdd = false, addNewText = 'Create', onAdd = () => { }, allowClear = false, } = props;
|
|
1225
|
+
const { labelKey = 'label', valueKey = 'value', name, id = name, options, selected, label = null, labelWrapperClass = '', labelClass = '', labelHint = null, disabled = false, containerClass = '', onChange = () => { }, placeholder, dropdownContainerClass = 'z-20', multiple = false, maxSelection, immediate = true, showErrorMessage = true, error = null, async = false, searchable = true, required = false, allowAdd = false, addNewText = 'Create', onAdd = () => { }, allowClear = false, modalDropdown = false, } = props;
|
|
1209
1226
|
const hasError = Boolean(error);
|
|
1210
1227
|
const [query, setQuery] = React.useState('');
|
|
1211
1228
|
const debouncedQuery = useDebounce(query, 500);
|
|
@@ -1300,11 +1317,18 @@ const SelectBox = React.forwardRef((props, forwardedRef) => {
|
|
|
1300
1317
|
console.error('onAdd handler error', err);
|
|
1301
1318
|
}
|
|
1302
1319
|
}, [onAdd, handleOnChangeInternal]);
|
|
1320
|
+
// Kept in a ref so `handleSearch` stays referentially stable even when the
|
|
1321
|
+
// caller passes a non-memoized `onSearch` — otherwise the effect below would
|
|
1322
|
+
// re-fire (and re-search) on every render instead of only on query changes.
|
|
1323
|
+
const onSearchRef = React.useRef(props.onSearch);
|
|
1324
|
+
React.useEffect(() => {
|
|
1325
|
+
onSearchRef.current = props.onSearch;
|
|
1326
|
+
}, [props.onSearch]);
|
|
1303
1327
|
const handleSearch = React.useCallback(async (searchString) => {
|
|
1304
1328
|
var _a;
|
|
1305
1329
|
try {
|
|
1306
1330
|
setOptionsLoading(true);
|
|
1307
|
-
await ((_a =
|
|
1331
|
+
await ((_a = onSearchRef.current) === null || _a === void 0 ? void 0 : _a.call(onSearchRef, searchString));
|
|
1308
1332
|
}
|
|
1309
1333
|
catch (err) {
|
|
1310
1334
|
console.error('Error loading options:', err);
|
|
@@ -1312,7 +1336,7 @@ const SelectBox = React.forwardRef((props, forwardedRef) => {
|
|
|
1312
1336
|
finally {
|
|
1313
1337
|
setOptionsLoading(false);
|
|
1314
1338
|
}
|
|
1315
|
-
}, [
|
|
1339
|
+
}, []);
|
|
1316
1340
|
React.useEffect(() => {
|
|
1317
1341
|
if (async && debouncedQuery)
|
|
1318
1342
|
handleSearch(debouncedQuery);
|
|
@@ -1325,7 +1349,7 @@ const SelectBox = React.forwardRef((props, forwardedRef) => {
|
|
|
1325
1349
|
removeSelection(selected.length - 1);
|
|
1326
1350
|
}
|
|
1327
1351
|
}
|
|
1328
|
-
}, "data-testid": "combobox-input" }), jsxRuntime.jsx(react.ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5", "data-testid": "combobox-button", children: jsxRuntime.jsx(SvgChevronDown, { className: chevronIconClass }) })] })) : (jsxRuntime.jsxs("div", { className: "relative", ref: forwardedRef, children: [jsxRuntime.jsx(react.ComboboxInput, { "aria-label": name, displayValue: (option) => (option ? getDisplayValue(option) : null), autoComplete: "off", placeholder: placeholder, onChange: (event) => setQuery(event.target.value), className: inputClass, disabled: disabled, id: id, readOnly: !searchable, ref: inputRef, "data-testid": "combobox-input" }), allowClear && !isEmpty(selected) && (jsxRuntime.jsx(Button, { size: "xs", iconOnly: true, "aria-label": "Clear selection", theme: "secondary", variant: "plain", className: "group absolute inset-y-0 right-8 h-6 top-2", onClick: () => handleOnChangeInternal(multiple ? [] : null), disabled: disabled, "data-testid": "combobox-clear-button", noOutlineOnFocus: true, children: jsxRuntime.jsx(SvgX, { className: "size-4 stroke-gray-500" }) })), jsxRuntime.jsx(react.ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5", "data-testid": "combobox-button", children: jsxRuntime.jsx(SvgChevronDown, { className: chevronIconClass }) })] })), jsxRuntime.jsx(react.ComboboxOptions, { anchor: { to: 'bottom', gap: 5 }, as: "div", className: buildClassName('w-[var(--input-width)] rounded-lg border border-gray-200 dark:border-white/5 bg-white dark:bg-gray-800 p-1 [--anchor-gap:var(--spacing-1)]', '[--anchor-max-height:20rem]', 'origin-top border transition duration-200 ease-[cubic-bezier(0.4, 0.0, 0.2, 1)] data-[closed]:translate-y-[-15%] data-[closed]:opacity-0', dropdownContainerClass), transition: true, "data-testid": "combobox-options", children: optionsLoading ? (jsxRuntime.jsx(
|
|
1352
|
+
}, "data-testid": "combobox-input" }), jsxRuntime.jsx(react.ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5", "data-testid": "combobox-button", children: jsxRuntime.jsx(SvgChevronDown, { className: chevronIconClass }) })] })) : (jsxRuntime.jsxs("div", { className: "relative", ref: forwardedRef, children: [jsxRuntime.jsx(react.ComboboxInput, { "aria-label": name, displayValue: (option) => (option ? getDisplayValue(option) : null), autoComplete: "off", placeholder: placeholder, onChange: (event) => setQuery(event.target.value), className: inputClass, disabled: disabled, id: id, readOnly: !searchable, ref: inputRef, "data-testid": "combobox-input" }), allowClear && !isEmpty(selected) && (jsxRuntime.jsx(Button, { size: "xs", iconOnly: true, "aria-label": "Clear selection", theme: "secondary", variant: "plain", className: "group absolute inset-y-0 right-8 h-6 top-2", onClick: () => handleOnChangeInternal(multiple ? [] : null), disabled: disabled, "data-testid": "combobox-clear-button", noOutlineOnFocus: true, children: jsxRuntime.jsx(SvgX, { className: "size-4 stroke-gray-500 dark:stroke-gray-300" }) })), jsxRuntime.jsx(react.ComboboxButton, { className: "group absolute inset-y-0 right-0 px-2.5", "data-testid": "combobox-button", children: jsxRuntime.jsx(SvgChevronDown, { className: chevronIconClass }) })] })), jsxRuntime.jsx(react.ComboboxOptions, { anchor: { to: 'bottom', gap: 5 }, as: "div", modal: modalDropdown, className: buildClassName('w-[var(--input-width)] rounded-lg border border-gray-200 dark:border-white/5 bg-white dark:bg-gray-800 p-1 [--anchor-gap:var(--spacing-1)]', '[--anchor-max-height:20rem]', 'origin-top border transition duration-200 ease-[cubic-bezier(0.4, 0.0, 0.2, 1)] data-[closed]:translate-y-[-15%] data-[closed]:opacity-0', dropdownContainerClass), transition: true, "data-testid": "combobox-options", children: optionsLoading ? (jsxRuntime.jsx(BodyText, { "data-testid": "options-loading", className: "flex items-center justify-center py-2 px-3 select-none", children: jsxRuntime.jsx(Loader, { size: "sm" }) })) : shouldShowTypeToSearch ? (jsxRuntime.jsx(BodyText, { className: "flex items-center justify-between py-2 px-3 select-none", children: "Type to search..." })) : (jsxRuntime.jsxs("div", { children: [filteredOptions.map((option) => (jsxRuntime.jsx(react.ComboboxOption, { disabled: option.disabled, value: option, className: "group rounded-lg py-1.5 px-3 select-none data-[focus]:bg-black/3 dark:data-[focus]:bg-white/10 data-disabled:opacity-50 cursor-pointer data-disabled:pointer-events-none", children: jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 dark:text-white group-data-[selected]:text-blue-600", children: [jsxRuntime.jsx("span", { className: "text-sm/6", children: getDisplayValue(option) }), jsxRuntime.jsx(SvgCheck, { className: "invisible size-5 dark:stroke-gray-300 group-data-[selected]:visible" })] }) }, getValue(option)))), filteredOptions.length === 0 && query && !optionsLoading && (jsxRuntime.jsxs("div", { "data-testid": "no-result-found", className: "flex items-center gap-2 py-1.5 px-3 select-none text-gray-500 dark:text-gray-400", children: ["No results found for ", jsxRuntime.jsx("span", { className: "font-semibold", children: query })] })), allowAdd && (jsxRuntime.jsx(react.ComboboxOption, { value: query, className: "group rounded-lg py-1.5 px-3 cursor-pointer text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700", onClick: () => void handleAddAndSelect(query), children: jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsx(SvgCirclePlus, { className: "size-4.5" }), jsxRuntime.jsxs(TextContent, { children: [addNewText, " \"", query, "\""] })] }) }))] })) })] }), showErrorMessage && error && (jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx(TextContent, { error: true, small: true, children: error }) }))] }));
|
|
1329
1353
|
});
|
|
1330
1354
|
|
|
1331
1355
|
const Tabs = ({ tabs, defaultIndex = 0, selectedIndex, onChange, variant = 'underline', orientation = 'horizontal', stretch = false, className = '', listClass = '', panelsClass = '', }) => {
|