@sqrzro/ui 4.0.0-alpha.21 → 4.0.0-alpha.24
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/components/collections/ListItem/index.js +3 -1
- package/dist/components/collections/TableRow/index.js +3 -1
- package/dist/components/collections/interfaces.d.ts +2 -2
- package/dist/components/utility/Action/index.d.ts +1 -1
- package/dist/components/utility/ActionList/index.js +2 -1
- package/dist/components/utility/Menu/index.d.ts +1 -1
- package/dist/components/utility/Menu/index.js +3 -1
- package/dist/components/utility/Page/index.d.ts +9 -8
- package/dist/components/utility/Page/index.js +7 -23
- package/dist/forms/components/CSVInput/index.d.ts +15 -0
- package/dist/forms/components/CSVInput/index.js +30 -0
- package/dist/forms/components/FormFields/index.d.ts +3 -0
- package/dist/forms/components/FormFields/index.js +6 -0
- package/dist/forms/index.d.ts +4 -2
- package/dist/forms/index.js +2 -1
- package/dist/forms/utility/format-file-size.d.ts +2 -0
- package/dist/forms/utility/format-file-size.js +11 -0
- package/dist/styles/classnames/config.d.ts +2 -0
- package/dist/utility/interfaces.d.ts +4 -0
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { filterNull } from '@sqrzro/utility';
|
|
2
3
|
import { getClassNames } from '../../../styles/classnames';
|
|
3
4
|
import tw from '../../../styles/classnames/tw';
|
|
4
5
|
import Link from '../../../components/utility/Link';
|
|
@@ -19,6 +20,7 @@ function ListItem({ $data, actions, classNames, classNameProps, description, hre
|
|
|
19
20
|
const hasPrimary = Boolean(title || description || meta);
|
|
20
21
|
const hasSecondary = Boolean(secondary);
|
|
21
22
|
const hasTertiary = Boolean(tertiary);
|
|
22
|
-
|
|
23
|
+
const filteredActions = filterNull(actions || []);
|
|
24
|
+
return (_jsx("li", { className: tw('@container relative grid', componentClassNames?.root, isLoading ? 'pointer-events-none animate-pulse' : null, filteredActions.length ? 'grid-cols-[1fr_auto] gap-4' : 'grid-cols-1'), children: _jsxs("article", { className: "contents", children: [_jsxs("div", { className: tw('grid gap-x-6 gap-y-4', getLayout([hasPrimary, hasSecondary, hasTertiary])), children: [_jsxs("div", { className: componentClassNames?.primary, children: [title ? (_jsx("h2", { className: componentClassNames?.title, children: href ? (_jsx(Link, { className: "hover:text-link", href: href, children: title })) : (title) })) : null, description ? (_jsx("div", { className: componentClassNames?.description, children: description })) : null, _jsx(ListItemMeta, { classNameProps: classNameProps, data: meta })] }), tertiary ? (_jsx("div", { className: componentClassNames?.tertiary, children: tertiary })) : null, _jsx(ListItemSecondary, { classNameProps: classNameProps, classNames: classNames, data: secondary?.data, variant: variant })] }), filteredActions.length ? (_jsx(ListItemMenu, { actions: filteredActions, data: $data })) : null] }) }));
|
|
23
25
|
}
|
|
24
26
|
export default ListItem;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { filterNull } from '@sqrzro/utility';
|
|
2
3
|
import Switch from '../../../forms/components/Switch';
|
|
3
4
|
import { getClassNames } from '../../../styles/classnames';
|
|
4
5
|
import ListItemMenu from '../ListItemMenu';
|
|
5
6
|
function TableRow({ classNameProps, classNames, columns, data, isSelected, onSelect, }) {
|
|
6
7
|
const componentClassNames = getClassNames('table', { props: classNameProps, states: { isSelected } }, classNames);
|
|
7
|
-
|
|
8
|
+
const filteredActions = filterNull(data.actions || []);
|
|
9
|
+
return (_jsxs("tr", { className: componentClassNames?.row, children: [data.isSelectable ? (_jsx("td", { children: _jsx(Switch, { name: data.id, onChange: onSelect, value: isSelected }) })) : null, columns.map((column) => (_jsx("td", { className: componentClassNames?.cell, children: data.row[column.id] }, column.id))), filteredActions.length ? (_jsx("td", { children: _jsx(ListItemMenu, { actions: filteredActions, data: data.$data }) })) : null] }));
|
|
8
10
|
}
|
|
9
11
|
export default TableRow;
|
|
@@ -7,7 +7,7 @@ export interface CollectionFunctionConfig<Filters = null> {
|
|
|
7
7
|
export type ListFunctionConfig<Filters = null> = CollectionFunctionConfig<Filters>;
|
|
8
8
|
export interface ListItemObject<Data extends object | null = null> {
|
|
9
9
|
$data?: Data;
|
|
10
|
-
actions?: ActionObject<Data>[];
|
|
10
|
+
actions?: (ActionObject<Data> | null)[];
|
|
11
11
|
description?: React.ReactNode;
|
|
12
12
|
href?: string;
|
|
13
13
|
id: string;
|
|
@@ -31,7 +31,7 @@ export interface ListItemObject<Data extends object | null = null> {
|
|
|
31
31
|
export type TableFunctionConfig<Filters = null> = CollectionFunctionConfig<Filters>;
|
|
32
32
|
export interface TableItemObject<Data extends object | null = null> {
|
|
33
33
|
$data?: Data;
|
|
34
|
-
actions?: ActionObject<Data>[];
|
|
34
|
+
actions?: (ActionObject<Data> | null)[];
|
|
35
35
|
id: string;
|
|
36
36
|
isSelectable?: boolean;
|
|
37
37
|
row: {
|
|
@@ -4,7 +4,7 @@ export interface ActionProps<Data extends object | null = null> extends Omit<Act
|
|
|
4
4
|
readonly label?: React.ReactNode;
|
|
5
5
|
readonly render: (props: ActionComponentProps<Data>) => React.ReactElement;
|
|
6
6
|
}
|
|
7
|
-
export interface ActionComponentProps<Data extends object | null = null> extends Pick<ActionProps<Data>, 'href' | 'icon' | 'isDisabled' | 'isLoading' | 'isSubmittable' | 'onClick' | 'searchParams' | 'variant'> {
|
|
7
|
+
export interface ActionComponentProps<Data extends object | null = null> extends Pick<ActionProps<Data>, 'action' | 'confirmable' | 'data' | 'href' | 'icon' | 'isDisabled' | 'isLoading' | 'isSubmittable' | 'onClick' | 'searchParams' | 'variant'> {
|
|
8
8
|
children: React.ReactNode;
|
|
9
9
|
}
|
|
10
10
|
declare function Action<Data extends object | null = null>(props: ActionProps<Data>): React.ReactElement;
|
|
@@ -4,6 +4,7 @@ import ActionButton from '../../../components/buttons/ActionButton';
|
|
|
4
4
|
import { getClassNames } from '../../../styles/classnames';
|
|
5
5
|
function ActionList({ actions, classNameProps, classNames, isLoading, }) {
|
|
6
6
|
const componentClassNames = getClassNames('actionList', { props: classNameProps }, classNames);
|
|
7
|
-
|
|
7
|
+
const filteredActions = filterNull(actions);
|
|
8
|
+
return (_jsx("ul", { className: componentClassNames?.root, children: filteredActions.map((action, index) => (_jsx("li", { className: componentClassNames?.item, children: _jsx(ActionButton, { ...action, isLoading: Boolean(isLoading || action.isLoading) }) }, index))) }));
|
|
8
9
|
}
|
|
9
10
|
export default ActionList;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ActionObject } from '../../../utility/interfaces';
|
|
2
2
|
import { PopoverProps } from '../Popover';
|
|
3
3
|
export interface MenuProps<Data extends object | null = null> {
|
|
4
|
-
actions: ActionObject<Data>[];
|
|
4
|
+
actions: (ActionObject<Data> | null)[];
|
|
5
5
|
align?: PopoverProps['align'];
|
|
6
6
|
data?: Data;
|
|
7
7
|
label: React.ReactNode;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { filterNull } from '@sqrzro/utility';
|
|
3
4
|
import Button from '../../../components/buttons/Button';
|
|
4
5
|
import useClickOutside from '../../../hooks/useClickOutside';
|
|
5
6
|
import Action from '../Action';
|
|
@@ -10,6 +11,7 @@ function Menu({ actions, align, data, label, vAlign, }) {
|
|
|
10
11
|
function toggleIsOpen() {
|
|
11
12
|
setIsOpen(!isOpen);
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
+
const filteredActions = filterNull(actions);
|
|
15
|
+
return (_jsxs("div", { className: "relative", ref: ref, children: [_jsx(Button, { onClick: toggleIsOpen, children: label }), _jsx(Popover, { align: align, isOpen: isOpen, vAlign: vAlign, children: _jsx("ul", { children: filteredActions.map((item, index) => (_jsx("li", { children: _jsx(Action, { ...item, data: data, render: MenuItem }) }, index))) }) })] }));
|
|
14
16
|
}
|
|
15
17
|
export default Menu;
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import type { NavigationObject } from '../../../navigation/interfaces';
|
|
3
2
|
import type { NextPageProps } from '../../../utility/interfaces';
|
|
3
|
+
type Fn = (...args: any[]) => Promise<any>;
|
|
4
|
+
type FnReturn<T extends Fn> = T extends (...args: any[]) => Promise<infer R> ? R : never;
|
|
4
5
|
interface PageTemplateProps {
|
|
5
6
|
children: React.ReactNode;
|
|
6
7
|
tabs: NavigationObject[] | null;
|
|
7
8
|
title: React.ReactNode;
|
|
8
9
|
}
|
|
9
|
-
export
|
|
10
|
-
readonly
|
|
11
|
-
readonly
|
|
10
|
+
export type PageProps<T extends Fn | undefined = undefined> = {
|
|
11
|
+
readonly fn?: T;
|
|
12
|
+
readonly children: React.ReactNode | ((data: T extends Fn ? FnReturn<T> : null, pageProps?: NextPageProps) => React.ReactNode);
|
|
12
13
|
readonly pageProps?: NextPageProps;
|
|
13
|
-
readonly tabs?: NavigationObject[] | ((data: T) => NavigationObject[] | null);
|
|
14
|
+
readonly tabs?: NavigationObject[] | ((data: T extends Fn ? FnReturn<T> : null, pageProps?: NextPageProps) => NavigationObject[] | null);
|
|
14
15
|
readonly template?: (props: PageTemplateProps) => React.ReactElement;
|
|
15
|
-
readonly title?: React.ReactNode | ((data: T) => React.ReactNode);
|
|
16
|
-
}
|
|
17
|
-
declare function Page<T>(props: PageProps<T>):
|
|
16
|
+
readonly title?: React.ReactNode | ((data: T extends Fn ? FnReturn<T> : null, pageProps?: NextPageProps) => React.ReactNode);
|
|
17
|
+
};
|
|
18
|
+
declare function Page<T extends Fn | undefined = undefined>(props: PageProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
18
19
|
export default Page;
|
|
@@ -1,30 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense } from 'react';
|
|
3
|
-
function getChildren(props, data) {
|
|
4
|
-
if (typeof props.children === 'function') {
|
|
5
|
-
return data ? props.children(data) : null;
|
|
6
|
-
}
|
|
7
|
-
return props.children;
|
|
8
|
-
}
|
|
9
|
-
function getTabs(props, data) {
|
|
10
|
-
if (typeof props.tabs === 'function') {
|
|
11
|
-
return data ? props.tabs(data) : null;
|
|
12
|
-
}
|
|
13
|
-
return props.tabs ?? null;
|
|
14
|
-
}
|
|
15
|
-
function getTitle(props, data) {
|
|
16
|
-
if (typeof props.title === 'function') {
|
|
17
|
-
return data ? props.title(data) : null;
|
|
18
|
-
}
|
|
19
|
-
return props.title;
|
|
20
|
-
}
|
|
21
3
|
async function PageComponent(props) {
|
|
22
|
-
const data = props.fn ? await props.fn(
|
|
23
|
-
const children =
|
|
24
|
-
|
|
25
|
-
|
|
4
|
+
const data = props.fn ? await props.fn() : null;
|
|
5
|
+
const children = typeof props.children === 'function'
|
|
6
|
+
? props.children(data, props.pageProps)
|
|
7
|
+
: props.children;
|
|
8
|
+
const tabs = typeof props.tabs === 'function' ? props.tabs(data, props.pageProps) : props.tabs;
|
|
9
|
+
const title = typeof props.title === 'function' ? props.title(data, props.pageProps) : props.title;
|
|
26
10
|
if (props.template) {
|
|
27
|
-
return props.template({ children, tabs, title });
|
|
11
|
+
return props.template({ children, tabs: tabs ?? null, title });
|
|
28
12
|
}
|
|
29
13
|
return children;
|
|
30
14
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { InputProps } from '../../../forms/interfaces';
|
|
2
|
+
import type { ClassNameProps } from '../../../styles/classnames/interfaces';
|
|
3
|
+
export interface CSVInputClassNames {
|
|
4
|
+
root: string;
|
|
5
|
+
icon: string;
|
|
6
|
+
title: string;
|
|
7
|
+
description: string;
|
|
8
|
+
}
|
|
9
|
+
export interface CSVInputComponentProps {
|
|
10
|
+
icon?: React.ReactNode;
|
|
11
|
+
iconSuccess?: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export type CSVInputProps = ClassNameProps<CSVInputClassNames> & InputProps<string> & CSVInputComponentProps;
|
|
14
|
+
declare function CSVInput({ classNames, classNameProps, icon, iconSuccess, id, isDisabled, name, onChange, value, }: Readonly<CSVInputProps>): React.ReactElement;
|
|
15
|
+
export default CSVInput;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { formatPlural } from '@sqrzro/utility';
|
|
5
|
+
import { getClassNames } from '../../../styles/classnames';
|
|
6
|
+
import tw from '../../../styles/classnames/tw';
|
|
7
|
+
import formatFileSize from '../../utility/format-file-size';
|
|
8
|
+
function CSVInput({ classNames, classNameProps, icon, iconSuccess, id, isDisabled, name, onChange, value, }) {
|
|
9
|
+
const componentClassNames = getClassNames('csvInput', { props: classNameProps }, classNames);
|
|
10
|
+
const [fileData, setFileData] = useState(null);
|
|
11
|
+
function handleChange(event) {
|
|
12
|
+
const { files } = event.target;
|
|
13
|
+
const reader = new FileReader();
|
|
14
|
+
reader.addEventListener('load', () => {
|
|
15
|
+
const text = reader.result?.toString() || '';
|
|
16
|
+
const lines = text.split('\n').filter((item) => item.trim() !== '').length;
|
|
17
|
+
setFileData({
|
|
18
|
+
lines,
|
|
19
|
+
name: files?.[0].name || '',
|
|
20
|
+
size: files?.[0].size || 0,
|
|
21
|
+
});
|
|
22
|
+
onChange?.({ target: { name, value: text } });
|
|
23
|
+
}, false);
|
|
24
|
+
if (files?.[0]) {
|
|
25
|
+
reader.readAsText(files[0]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return (_jsxs("div", { className: tw('relative flex items-center justify-center', componentClassNames?.root), children: [_jsx("input", { name: name, type: "hidden", value: value || '' }), _jsx("input", { accept: "text/csv", className: "absolute left-0 top-0 h-full w-full cursor-pointer opacity-0", disabled: isDisabled, id: id || name, name: name, onChange: handleChange, type: "file" }), fileData ? (_jsxs("div", { className: tw('text-center', isDisabled ? 'pointer-events-none opacity-20' : null), children: [_jsx("i", { className: componentClassNames?.icon, children: iconSuccess }), _jsx("p", { className: componentClassNames?.title, children: fileData.name }), _jsxs("p", { className: componentClassNames?.description, children: [formatFileSize(fileData.size), " \u2022", ' ', formatPlural('line', fileData.lines)] })] })) : (_jsxs("div", { className: "text-center", children: [_jsx("i", { className: componentClassNames?.icon, children: icon }), _jsx("p", { className: componentClassNames?.title, children: "Click to Upload" }), _jsx("p", { className: componentClassNames?.description, children: "(or drag a CSV file over this box)" })] }))] }));
|
|
29
|
+
}
|
|
30
|
+
export default CSVInput;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FormFieldComponentProps } from '../../interfaces';
|
|
2
2
|
import type { AutocompleteComponentProps } from '../Autocomplete';
|
|
3
|
+
import type { CSVInputComponentProps } from '../CSVInput';
|
|
3
4
|
import type { DropdownComponentProps } from '../Dropdown';
|
|
4
5
|
import type { PointsInputComponentProps } from '../PointsInput';
|
|
5
6
|
import type { NumberInputComponentProps } from '../NumberInput';
|
|
@@ -7,6 +8,8 @@ import type { PasswordInputComponentProps } from '../PasswordInput';
|
|
|
7
8
|
import type { TextInputComponentProps } from '../TextInput';
|
|
8
9
|
export type AutocompleteFormFieldProps<T> = FormFieldComponentProps<T | null> & AutocompleteComponentProps<T>;
|
|
9
10
|
export declare function AutocompleteFormField<T>(props: Readonly<AutocompleteFormFieldProps<T>>): React.ReactElement;
|
|
11
|
+
export type CSVFormFieldProps = FormFieldComponentProps<string> & CSVInputComponentProps;
|
|
12
|
+
export declare function CSVFormField(props: Readonly<CSVFormFieldProps>): React.ReactElement;
|
|
10
13
|
export type DropdownFormFieldProps<T> = FormFieldComponentProps<T | null> & DropdownComponentProps<T>;
|
|
11
14
|
export declare function DropdownFormField<T>(props: Readonly<DropdownFormFieldProps<T>>): React.ReactElement;
|
|
12
15
|
export type MoneyFormFieldProps = FormFieldComponentProps<number> & PointsInputComponentProps;
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
import extractInputProps from '../../utility/extract-input-props';
|
|
4
4
|
import Autocomplete from '../Autocomplete';
|
|
5
|
+
import CSVInput from '../CSVInput';
|
|
5
6
|
import Dropdown from '../Dropdown';
|
|
6
7
|
import FormField from '../FormField';
|
|
7
8
|
import PointsInput from '../PointsInput';
|
|
@@ -13,6 +14,11 @@ export function AutocompleteFormField(props) {
|
|
|
13
14
|
const renderInput = useCallback((renderProps) => (_jsx(Autocomplete, { ...renderProps, ...inputProps })), [inputProps]);
|
|
14
15
|
return _jsx(FormField, { ...fieldProps, render: renderInput });
|
|
15
16
|
}
|
|
17
|
+
export function CSVFormField(props) {
|
|
18
|
+
const { fieldProps, inputProps } = extractInputProps(props);
|
|
19
|
+
const renderInput = useCallback((renderProps) => (_jsx(CSVInput, { ...renderProps, ...inputProps })), [inputProps]);
|
|
20
|
+
return _jsx(FormField, { ...fieldProps, render: renderInput });
|
|
21
|
+
}
|
|
16
22
|
export function DropdownFormField(props) {
|
|
17
23
|
const { fieldProps, inputProps } = extractInputProps(props);
|
|
18
24
|
const renderInput = useCallback((renderProps) => (_jsx(Dropdown, { ...renderProps, ...inputProps })), [inputProps]);
|
package/dist/forms/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from './interfaces';
|
|
2
2
|
export type { AutocompleteProps } from './components/Autocomplete';
|
|
3
3
|
export { default as Autocomplete } from './components/Autocomplete';
|
|
4
|
+
export type { CSVInputClassNames, CSVInputProps } from './components/CSVInput';
|
|
5
|
+
export { default as CSVInput } from './components/CSVInput';
|
|
4
6
|
export type { DropdownClassNames, DropdownProps } from './components/Dropdown';
|
|
5
7
|
export { default as Dropdown } from './components/Dropdown';
|
|
6
8
|
export type { EditableFormClassNames, EditableFormProps } from './components/EditableForm';
|
|
@@ -29,8 +31,8 @@ export type { TextInputClassNames, TextInputProps } from './components/TextInput
|
|
|
29
31
|
export { default as TextInput } from './components/TextInput';
|
|
30
32
|
export type { EditableDropdownFormFieldProps, EditableTextFormFieldProps, } from './components/EditableFormFields';
|
|
31
33
|
export { EditableDropdownFormField, EditableTextFormField } from './components/EditableFormFields';
|
|
32
|
-
export type { AutocompleteFormFieldProps, DropdownFormFieldProps, MoneyFormFieldProps, NumberFormFieldProps, PasswordFormFieldProps, TextFormFieldProps, } from './components/FormFields';
|
|
33
|
-
export { AutocompleteFormField, DropdownFormField, MoneyFormField, NumberFormField, PasswordFormField, TextFormField, } from './components/FormFields';
|
|
34
|
+
export type { AutocompleteFormFieldProps, CSVFormFieldProps, DropdownFormFieldProps, MoneyFormFieldProps, NumberFormFieldProps, PasswordFormFieldProps, TextFormFieldProps, } from './components/FormFields';
|
|
35
|
+
export { AutocompleteFormField, CSVFormField, DropdownFormField, MoneyFormField, NumberFormField, PasswordFormField, TextFormField, } from './components/FormFields';
|
|
34
36
|
export type { UseAutocompleteArgs, UseAutocompleteReturn } from './hooks/useAutocomplete';
|
|
35
37
|
export { default as useAutocomplete } from './hooks/useAutocomplete';
|
|
36
38
|
export type { UseDropdownArgs, UseDropdownReturn } from './hooks/useDropdown';
|
package/dist/forms/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './interfaces';
|
|
2
2
|
export { default as Autocomplete } from './components/Autocomplete';
|
|
3
|
+
export { default as CSVInput } from './components/CSVInput';
|
|
3
4
|
export { default as Dropdown } from './components/Dropdown';
|
|
4
5
|
export { default as EditableForm } from './components/EditableForm';
|
|
5
6
|
export { default as EditableFormField } from './components/EditableFormField';
|
|
@@ -14,7 +15,7 @@ export { default as PointsInput } from './components/PointsInput';
|
|
|
14
15
|
export { default as StaticTextInput } from './components/StaticTextInput';
|
|
15
16
|
export { default as TextInput } from './components/TextInput';
|
|
16
17
|
export { EditableDropdownFormField, EditableTextFormField } from './components/EditableFormFields';
|
|
17
|
-
export { AutocompleteFormField, DropdownFormField, MoneyFormField, NumberFormField, PasswordFormField, TextFormField, } from './components/FormFields';
|
|
18
|
+
export { AutocompleteFormField, CSVFormField, DropdownFormField, MoneyFormField, NumberFormField, PasswordFormField, TextFormField, } from './components/FormFields';
|
|
18
19
|
export { default as useAutocomplete } from './hooks/useAutocomplete';
|
|
19
20
|
export { default as useDropdown } from './hooks/useDropdown';
|
|
20
21
|
export { default as useEditableForm } from './hooks/useEditableForm';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const BYTES_IN_KB = 1024;
|
|
2
|
+
const DECIMAL_PLACES = 3;
|
|
3
|
+
function formatFileSize(size) {
|
|
4
|
+
const units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
|
5
|
+
const exponent = Math.min(Math.floor(Math.log(size) / Math.log(BYTES_IN_KB)), units.length - 1);
|
|
6
|
+
const approx = size / BYTES_IN_KB ** exponent;
|
|
7
|
+
return exponent === 0
|
|
8
|
+
? `${size} bytes`
|
|
9
|
+
: `${approx.toFixed(DECIMAL_PLACES)} ${units[exponent]} (${size} bytes)`;
|
|
10
|
+
}
|
|
11
|
+
export default formatFileSize;
|
|
@@ -20,6 +20,7 @@ import type { ToastClassNames } from '../../components/utility/Toast';
|
|
|
20
20
|
import type { FilterBarClassNames } from '../../filters/components/FilterBar';
|
|
21
21
|
import type { FilterItemClassNames } from '../../filters/components/FilterItem';
|
|
22
22
|
import type { FilterPanelClassNames } from '../../filters/components/FilterPanel';
|
|
23
|
+
import type { CSVInputClassNames } from '../../forms/components/CSVInput';
|
|
23
24
|
import type { DropdownClassNames } from '../../forms/components/Dropdown';
|
|
24
25
|
import type { EditableFormClassNames } from '../../forms/components/EditableForm';
|
|
25
26
|
import type { EditableFormFieldClassNames } from '../../forms/components/EditableFormField';
|
|
@@ -38,6 +39,7 @@ export interface RegisteredClassNames {
|
|
|
38
39
|
appNavigation?: ComponentClassNames<AppNavigationClassNames>;
|
|
39
40
|
button?: ComponentClassNames<ButtonClassNames>;
|
|
40
41
|
container?: ComponentClassNames<ContainerClassNames>;
|
|
42
|
+
csvInput?: ComponentClassNames<CSVInputClassNames>;
|
|
41
43
|
dataTable?: ComponentClassNames<DataTableClassNames>;
|
|
42
44
|
dropdown?: ComponentClassNames<DropdownClassNames>;
|
|
43
45
|
editableForm?: ComponentClassNames<EditableFormClassNames>;
|
|
@@ -33,6 +33,10 @@ export interface NextLayoutProps {
|
|
|
33
33
|
children: React.ReactNode;
|
|
34
34
|
params?: Promise<Record<string, string>> | null;
|
|
35
35
|
}
|
|
36
|
+
export interface AwaitedNextPageProps {
|
|
37
|
+
params?: Record<string, string> | null;
|
|
38
|
+
searchParams?: Record<string, string> | null;
|
|
39
|
+
}
|
|
36
40
|
export interface NextPageProps {
|
|
37
41
|
params?: Promise<Record<string, string>> | null;
|
|
38
42
|
searchParams?: Promise<Record<string, string>> | null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqrzro/ui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.0.0-alpha.
|
|
4
|
+
"version": "4.0.0-alpha.24",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "ISC",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"react-dom": "^19.2.1",
|
|
49
49
|
"tailwind-merge": "^3.4.0",
|
|
50
50
|
"use-deep-compare-effect": "^1.8.1",
|
|
51
|
-
"@sqrzro/utility": "^4.0.0-alpha.
|
|
51
|
+
"@sqrzro/utility": "^4.0.0-alpha.9"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@storybook/addon-a11y": "^10.1.7",
|