@wellingtonhlc/shared-ui 0.29.0 → 0.29.2
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/README.md +25 -10
- package/dist/cli/check-page-actions.d.ts +9 -0
- package/dist/cli/check-page-actions.d.ts.map +1 -0
- package/dist/cli/check-page-actions.js +108 -0
- package/dist/components/ActionBar.d.ts +26 -0
- package/dist/components/ActionBar.d.ts.map +1 -0
- package/dist/components/ActionBar.js +29 -0
- package/dist/components/ActionPrimitives.d.ts +31 -0
- package/dist/components/ActionPrimitives.d.ts.map +1 -0
- package/dist/components/ActionPrimitives.js +27 -0
- package/dist/components/AppShell.d.ts +65 -0
- package/dist/components/AppShell.d.ts.map +1 -0
- package/dist/components/AppShell.js +50 -0
- package/dist/components/AppShellActions.d.ts +24 -0
- package/dist/components/AppShellActions.d.ts.map +1 -0
- package/dist/components/AppShellActions.js +15 -0
- package/dist/components/Badge.d.ts +16 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +36 -0
- package/dist/components/Banner.d.ts +13 -0
- package/dist/components/Banner.d.ts.map +1 -0
- package/dist/components/Banner.js +29 -0
- package/dist/components/Button.d.ts +14 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +39 -0
- package/dist/components/Card.d.ts +36 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/Card.js +56 -0
- package/dist/components/ConfirmationDialog.d.ts +74 -0
- package/dist/components/ConfirmationDialog.d.ts.map +1 -0
- package/dist/components/ConfirmationDialog.js +234 -0
- package/dist/components/CopyableField.d.ts +10 -0
- package/dist/components/CopyableField.d.ts.map +1 -0
- package/dist/components/CopyableField.js +60 -0
- package/dist/components/DateField.d.ts +20 -0
- package/dist/components/DateField.d.ts.map +1 -0
- package/dist/components/DateField.js +172 -0
- package/dist/components/DecimalField.d.ts +21 -0
- package/dist/components/DecimalField.d.ts.map +1 -0
- package/dist/components/DecimalField.js +137 -0
- package/dist/components/DismissiblePopover.d.ts +14 -0
- package/dist/components/DismissiblePopover.d.ts.map +1 -0
- package/dist/components/DismissiblePopover.js +51 -0
- package/dist/components/EmptyState.d.ts +15 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +32 -0
- package/dist/components/FieldControl.d.ts +20 -0
- package/dist/components/FieldControl.d.ts.map +1 -0
- package/dist/components/FieldControl.js +73 -0
- package/dist/components/FieldGroup.d.ts +11 -0
- package/dist/components/FieldGroup.d.ts.map +1 -0
- package/dist/components/FieldGroup.js +11 -0
- package/dist/components/FieldSkeleton.d.ts +14 -0
- package/dist/components/FieldSkeleton.d.ts.map +1 -0
- package/dist/components/FieldSkeleton.js +23 -0
- package/dist/components/FieldValidationError.d.ts +8 -0
- package/dist/components/FieldValidationError.d.ts.map +1 -0
- package/dist/components/FieldValidationError.js +7 -0
- package/dist/components/Filter.d.ts +51 -0
- package/dist/components/Filter.d.ts.map +1 -0
- package/dist/components/Filter.js +68 -0
- package/dist/components/Loading.d.ts +17 -0
- package/dist/components/Loading.d.ts.map +1 -0
- package/dist/components/Loading.js +15 -0
- package/dist/components/LoadingOverlay.d.ts +11 -0
- package/dist/components/LoadingOverlay.d.ts.map +1 -0
- package/dist/components/LoadingOverlay.js +8 -0
- package/dist/components/Modal.d.ts +49 -0
- package/dist/components/Modal.d.ts.map +1 -0
- package/dist/components/Modal.js +108 -0
- package/dist/components/MultiSelectField.d.ts +22 -0
- package/dist/components/MultiSelectField.d.ts.map +1 -0
- package/dist/components/MultiSelectField.js +84 -0
- package/dist/components/NavCard.d.ts +15 -0
- package/dist/components/NavCard.d.ts.map +1 -0
- package/dist/components/NavCard.js +13 -0
- package/dist/components/Page.d.ts +89 -0
- package/dist/components/Page.d.ts.map +1 -0
- package/dist/components/Page.js +347 -0
- package/dist/components/PageMessage.d.ts +12 -0
- package/dist/components/PageMessage.d.ts.map +1 -0
- package/dist/components/PageMessage.js +36 -0
- package/dist/components/Pagination.d.ts +15 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +57 -0
- package/dist/components/PasswordInput.d.ts +8 -0
- package/dist/components/PasswordInput.d.ts.map +1 -0
- package/dist/components/PasswordInput.js +17 -0
- package/dist/components/RadioGroup.d.ts +32 -0
- package/dist/components/RadioGroup.d.ts.map +1 -0
- package/dist/components/RadioGroup.js +86 -0
- package/dist/components/RenderCase.d.ts +20 -0
- package/dist/components/RenderCase.d.ts.map +1 -0
- package/dist/components/RenderCase.js +31 -0
- package/dist/components/RenderIf.d.ts +10 -0
- package/dist/components/RenderIf.d.ts.map +1 -0
- package/dist/components/RenderIf.js +9 -0
- package/dist/components/SearchField.d.ts +22 -0
- package/dist/components/SearchField.d.ts.map +1 -0
- package/dist/components/SearchField.js +43 -0
- package/dist/components/SelectField.d.ts +31 -0
- package/dist/components/SelectField.d.ts.map +1 -0
- package/dist/components/SelectField.js +26 -0
- package/dist/components/SelectionField.d.ts +39 -0
- package/dist/components/SelectionField.d.ts.map +1 -0
- package/dist/components/SelectionField.js +105 -0
- package/dist/components/Sidebar.d.ts +104 -0
- package/dist/components/Sidebar.d.ts.map +1 -0
- package/dist/components/Sidebar.js +146 -0
- package/dist/components/StatCard.d.ts +16 -0
- package/dist/components/StatCard.d.ts.map +1 -0
- package/dist/components/StatCard.js +62 -0
- package/dist/components/Switch.d.ts +20 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Switch.js +63 -0
- package/dist/components/Table.d.ts +65 -0
- package/dist/components/Table.d.ts.map +1 -0
- package/dist/components/Table.js +118 -0
- package/dist/components/TabsUnderlined.d.ts +23 -0
- package/dist/components/TabsUnderlined.d.ts.map +1 -0
- package/dist/components/TabsUnderlined.js +29 -0
- package/dist/components/TextField.d.ts +25 -0
- package/dist/components/TextField.d.ts.map +1 -0
- package/dist/components/TextField.js +71 -0
- package/dist/components/TextareaField.d.ts +14 -0
- package/dist/components/TextareaField.d.ts.map +1 -0
- package/dist/components/TextareaField.js +34 -0
- package/dist/components/ThemePreferencesSelector.d.ts +29 -0
- package/dist/components/ThemePreferencesSelector.d.ts.map +1 -0
- package/dist/components/ThemePreferencesSelector.js +37 -0
- package/dist/components/Tooltip.d.ts +13 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip.js +40 -0
- package/dist/components/Workspace.d.ts +22 -0
- package/dist/components/Workspace.d.ts.map +1 -0
- package/dist/components/Workspace.js +33 -0
- package/dist/components/WorkspaceContext.d.ts +2 -0
- package/dist/components/WorkspaceContext.d.ts.map +1 -0
- package/dist/components/WorkspaceContext.js +2 -0
- package/dist/components/form-control-helpers.d.ts +24 -0
- package/dist/components/form-control-helpers.d.ts.map +1 -0
- package/dist/components/form-control-helpers.js +20 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/styles.css +26 -43
- package/dist/tailwind-preset.d.ts +23 -0
- package/dist/tailwind-preset.d.ts.map +1 -0
- package/dist/tailwind-preset.js +22 -0
- package/dist/utils/cn.d.ts +2 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/dist/utils/cn.js +33 -0
- package/package.json +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useController, } from 'react-hook-form';
|
|
4
|
+
import { cn } from '../utils/cn';
|
|
5
|
+
import { FieldControl } from './FieldControl';
|
|
6
|
+
import { FieldValidationError } from './FieldValidationError';
|
|
7
|
+
import { fieldWrapper } from './form-control-helpers';
|
|
8
|
+
const RadioGroupContext = React.createContext({
|
|
9
|
+
size: 'sm',
|
|
10
|
+
onChange: () => { },
|
|
11
|
+
});
|
|
12
|
+
const sizeStyles = {
|
|
13
|
+
xs: { outer: 'h-3.5 w-3.5', dot: 'h-1.5 w-1.5', text: 'text-xs' },
|
|
14
|
+
sm: { outer: 'h-4 w-4', dot: 'h-2 w-2', text: 'text-sm' },
|
|
15
|
+
md: { outer: 'h-5 w-5', dot: 'h-2.5 w-2.5', text: 'text-sm' },
|
|
16
|
+
lg: { outer: 'h-6 w-6', dot: 'h-3 w-3', text: 'text-base' },
|
|
17
|
+
};
|
|
18
|
+
const groupHeightStyles = {
|
|
19
|
+
xs: 'h-7',
|
|
20
|
+
sm: 'h-9',
|
|
21
|
+
md: 'h-12',
|
|
22
|
+
lg: 'h-14',
|
|
23
|
+
};
|
|
24
|
+
const groupMinHeightStyles = {
|
|
25
|
+
xs: 'min-h-7',
|
|
26
|
+
sm: 'min-h-9',
|
|
27
|
+
md: 'min-h-12',
|
|
28
|
+
lg: 'min-h-14',
|
|
29
|
+
};
|
|
30
|
+
const groupPaddingStyles = {
|
|
31
|
+
xs: 'px-2',
|
|
32
|
+
sm: 'px-3',
|
|
33
|
+
md: 'px-4',
|
|
34
|
+
lg: 'px-6',
|
|
35
|
+
};
|
|
36
|
+
const boxedFieldsetHeightStyles = {
|
|
37
|
+
xs: 'min-h-12',
|
|
38
|
+
sm: 'min-h-14',
|
|
39
|
+
md: 'min-h-[4.25rem]',
|
|
40
|
+
lg: 'min-h-[4.75rem]',
|
|
41
|
+
};
|
|
42
|
+
function RadioGroupBase({ children, direction = 'row', disabled = false, errorMessage, inputDisabled, inputName, inputOnBlur, inputValue, label, labelClassName = '', name, onChange, onValueChange, size = 'sm', value, variant = 'boxed', wrapperClassName, }) {
|
|
43
|
+
const generatedId = React.useId().replace(/:/g, '');
|
|
44
|
+
const resolvedValue = inputValue ?? value;
|
|
45
|
+
const resolvedName = inputName ?? name;
|
|
46
|
+
const resolvedDisabled = inputDisabled ?? disabled;
|
|
47
|
+
const legendId = `rg-${generatedId}-legend`;
|
|
48
|
+
const errorId = `rg-${generatedId}-error`;
|
|
49
|
+
const describedBy = errorMessage ? errorId : undefined;
|
|
50
|
+
function handleChange(nextValue) {
|
|
51
|
+
onValueChange?.(nextValue);
|
|
52
|
+
onChange?.(nextValue);
|
|
53
|
+
}
|
|
54
|
+
const groupClassName = cn('flex gap-3', direction === 'column' ? groupMinHeightStyles[size] : groupHeightStyles[size], direction === 'column' ? 'flex-col items-start justify-center' : 'flex-row flex-wrap items-center');
|
|
55
|
+
const boxedGroupClassName = cn(groupClassName, direction === 'row' && 'justify-around', groupPaddingStyles[size]);
|
|
56
|
+
if (variant === 'plain') {
|
|
57
|
+
return (_jsx(RadioGroupContext.Provider, { value: { name: resolvedName, value: resolvedValue, disabled: resolvedDisabled, size, onChange: handleChange }, children: _jsx(FieldControl, { label: label, wrapperClassName: wrapperClassName, labelClassName: labelClassName, errorMessage: errorMessage, size: size, disabled: resolvedDisabled, children: () => (_jsx("div", { role: "radiogroup", "aria-label": label, "aria-describedby": describedBy, onBlur: inputOnBlur, className: groupClassName, children: children })) }) }));
|
|
58
|
+
}
|
|
59
|
+
return (_jsx(RadioGroupContext.Provider, { value: { name: resolvedName, value: resolvedValue, disabled: resolvedDisabled, size, onChange: handleChange }, children: _jsxs("div", { className: cn(fieldWrapper, wrapperClassName), "data-disabled": resolvedDisabled || undefined, "data-invalid": !!errorMessage || undefined, children: [_jsxs("fieldset", { className: cn('border-app-border flex h-full flex-1 flex-col justify-center rounded-xl border px-3 pb-2 pt-0 transition-[background-color,border-color,box-shadow,color] duration-[var(--duration-normal)]', boxedFieldsetHeightStyles[size], resolvedDisabled && 'cursor-not-allowed opacity-60', errorMessage && 'border-red-500 dark:border-red-400'), children: [label ? (_jsx("legend", { id: legendId, className: cn('text-foreground-muted px-2 text-xs font-medium transition-colors', resolvedDisabled && 'cursor-not-allowed opacity-70', errorMessage && 'text-red-600 dark:text-red-400', labelClassName), children: label })) : null, _jsx("div", { role: "radiogroup", "aria-label": label ? undefined : resolvedName, "aria-labelledby": label ? legendId : undefined, "aria-describedby": describedBy, onBlur: inputOnBlur, className: boxedGroupClassName, children: children })] }), _jsx(FieldValidationError, { id: errorId, message: errorMessage })] }) }));
|
|
60
|
+
}
|
|
61
|
+
function Item({ className, disabled: itemDisabled, label, value }) {
|
|
62
|
+
const { value: groupValue, disabled: groupDisabled, size, onChange } = React.useContext(RadioGroupContext);
|
|
63
|
+
const isChecked = groupValue === value;
|
|
64
|
+
const isDisabled = itemDisabled ?? groupDisabled ?? false;
|
|
65
|
+
const s = sizeStyles[size];
|
|
66
|
+
function handleClick() {
|
|
67
|
+
onChange(value);
|
|
68
|
+
}
|
|
69
|
+
return (_jsxs("button", { type: "button", role: "radio", "aria-checked": isChecked, "aria-label": label, disabled: isDisabled, onClick: handleClick, className: cn('flex items-center gap-2 transition-colors focus:outline-none', isDisabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer', className), children: [_jsx("span", { "data-checked": isChecked, className: cn('app-radio flex shrink-0 items-center justify-center rounded-full border-2 transition-colors duration-[var(--duration-normal)]', s.outer), children: isChecked ? _jsx("span", { className: cn('app-radio__dot rounded-full', s.dot) }) : null }), _jsx("span", { className: cn('leading-none transition-colors duration-[var(--duration-normal)]', s.text, isChecked ? 'text-foreground' : 'text-foreground-muted'), children: label })] }));
|
|
70
|
+
}
|
|
71
|
+
function HookFormRadioGroup(props) {
|
|
72
|
+
const { control, name, rules, ...rest } = props;
|
|
73
|
+
const { field } = useController({
|
|
74
|
+
control: control,
|
|
75
|
+
name: name,
|
|
76
|
+
rules: rules,
|
|
77
|
+
});
|
|
78
|
+
return _jsx(RadioGroupBase, { ...rest, name: name, inputName: field.name, inputValue: field.value, inputDisabled: field.disabled, inputOnBlur: () => field.onBlur(), onValueChange: (nextValue) => field.onChange(nextValue) });
|
|
79
|
+
}
|
|
80
|
+
function RadioGroupRoot(props) {
|
|
81
|
+
if (props.control && props.name) {
|
|
82
|
+
return _jsx(HookFormRadioGroup, { ...props });
|
|
83
|
+
}
|
|
84
|
+
return _jsx(RadioGroupBase, { ...props });
|
|
85
|
+
}
|
|
86
|
+
export const RadioGroup = Object.assign(RadioGroupRoot, { Item });
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface RenderCaseChildProps {
|
|
3
|
+
when?: boolean;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export interface RenderCaseRootProps {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
declare function Root({ children }: RenderCaseRootProps): React.JSX.Element | null;
|
|
10
|
+
declare function If({ children }: RenderCaseChildProps): React.JSX.Element;
|
|
11
|
+
declare function ElseIf({ children }: RenderCaseChildProps): React.JSX.Element;
|
|
12
|
+
declare function Else({ children }: Omit<RenderCaseChildProps, 'when'>): React.JSX.Element;
|
|
13
|
+
export declare const RenderCase: {
|
|
14
|
+
Root: typeof Root;
|
|
15
|
+
If: typeof If;
|
|
16
|
+
ElseIf: typeof ElseIf;
|
|
17
|
+
Else: typeof Else;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=RenderCase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenderCase.d.ts","sourceRoot":"","sources":["../../src/components/RenderCase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,mBAAmB,4BAgB9C;AAED,iBAAS,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,oBAAoB,qBAE7C;AAED,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,oBAAoB,qBAEjD;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,qBAE7D;AAED,eAAO,MAAM,UAAU;;;;;CAKtB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
function Root({ children }) {
|
|
4
|
+
const items = React.Children.toArray(children);
|
|
5
|
+
for (const item of items) {
|
|
6
|
+
if (!React.isValidElement(item))
|
|
7
|
+
continue;
|
|
8
|
+
if (item.type === Else) {
|
|
9
|
+
return _jsx(_Fragment, { children: item.props.children });
|
|
10
|
+
}
|
|
11
|
+
if (item.props.when) {
|
|
12
|
+
return _jsx(_Fragment, { children: item.props.children });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
function If({ children }) {
|
|
18
|
+
return _jsx(_Fragment, { children: children });
|
|
19
|
+
}
|
|
20
|
+
function ElseIf({ children }) {
|
|
21
|
+
return _jsx(_Fragment, { children: children });
|
|
22
|
+
}
|
|
23
|
+
function Else({ children }) {
|
|
24
|
+
return _jsx(_Fragment, { children: children });
|
|
25
|
+
}
|
|
26
|
+
export const RenderCase = {
|
|
27
|
+
Root,
|
|
28
|
+
If,
|
|
29
|
+
ElseIf,
|
|
30
|
+
Else,
|
|
31
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface RenderIfProps {
|
|
3
|
+
when: boolean;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
fallback?: React.ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
as?: React.ElementType;
|
|
8
|
+
}
|
|
9
|
+
export declare function RenderIf({ as: Component, children, className, fallback, when }: RenderIfProps): React.JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=RenderIf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenderIf.d.ts","sourceRoot":"","sources":["../../src/components/RenderIf.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;CACxB;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,EAAE,SAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAe,EAAE,IAAI,EAAE,EAAE,aAAa,4BAO5G"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
export function RenderIf({ as: Component = 'div', children, className, fallback = null, when }) {
|
|
3
|
+
if (className) {
|
|
4
|
+
if (!when && fallback === null)
|
|
5
|
+
return null;
|
|
6
|
+
return _jsx(Component, { className: className, children: when ? children : fallback });
|
|
7
|
+
}
|
|
8
|
+
return _jsx(_Fragment, { children: when ? children : fallback });
|
|
9
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ChangeEvent, ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
type RegisterLike<T extends Record<string, unknown>> = (name: keyof T & string) => ComponentPropsWithoutRef<'input'>;
|
|
3
|
+
export type SearchFieldProps<T extends Record<string, unknown>> = Omit<ComponentPropsWithoutRef<'input'>, 'children' | 'className' | 'errorMessage' | 'name' | 'onChange' | 'size' | 'value' | 'wrapperClassName'> & {
|
|
4
|
+
name?: keyof T & string;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
roundedFull?: boolean;
|
|
7
|
+
errorMessage?: string;
|
|
8
|
+
onSearch: (data: T) => void;
|
|
9
|
+
wrapperClassName?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
labelClassName?: string;
|
|
13
|
+
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
14
|
+
labelPosition?: 'top' | 'right' | 'bottom' | 'left';
|
|
15
|
+
register?: RegisterLike<T>;
|
|
16
|
+
isSubmitting?: boolean;
|
|
17
|
+
value?: string;
|
|
18
|
+
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
19
|
+
};
|
|
20
|
+
export declare function SearchField<T extends Record<string, unknown>>({ name, placeholder, errorMessage, roundedFull, onSearch, wrapperClassName, className, label, labelClassName, size, labelPosition, register, isSubmitting, value, disabled, id, onChange, ...props }: SearchFieldProps<T>): import("react").JSX.Element;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=SearchField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchField.d.ts","sourceRoot":"","sources":["../../src/components/SearchField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAa,MAAM,OAAO,CAAC;AAS9E,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CACrD,IAAI,EAAE,MAAM,CAAC,GAAG,MAAM,KACnB,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAEvC,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,CACpE,wBAAwB,CAAC,OAAO,CAAC,EAC/B,UAAU,GACV,WAAW,GACX,cAAc,GACd,MAAM,GACN,UAAU,GACV,MAAM,GACN,OAAO,GACP,kBAAkB,CACrB,GAAG;IACF,IAAI,CAAC,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpD,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;CAC3D,CAAC;AAEF,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC7D,IAAmC,EACnC,WAAgB,EAChB,YAAiB,EACjB,WAAkB,EAClB,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,KAAK,EACL,cAAc,EACd,IAAW,EACX,aAAqB,EACrB,QAAQ,EACR,YAAoB,EACpB,KAAK,EACL,QAAgB,EAChB,EAAE,EACF,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BAuFrB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SearchIcon } from 'lucide-react';
|
|
3
|
+
import { cn } from '../utils/cn';
|
|
4
|
+
import { Button } from './Button';
|
|
5
|
+
import { controlClasses } from './form-control-helpers';
|
|
6
|
+
import { FieldControl } from './FieldControl';
|
|
7
|
+
export function SearchField({ name = 'search', placeholder = '', errorMessage = '', roundedFull = true, onSearch, wrapperClassName, className, label, labelClassName, size = 'md', labelPosition = 'top', register, isSubmitting = false, value, disabled = false, id, onChange, ...props }) {
|
|
8
|
+
function handleSubmit(event) {
|
|
9
|
+
event.preventDefault();
|
|
10
|
+
event.stopPropagation();
|
|
11
|
+
const input = event.currentTarget.elements.namedItem(name);
|
|
12
|
+
onSearch({ [name]: input.value });
|
|
13
|
+
}
|
|
14
|
+
const inputProps = register ? register(name) : { value, onChange };
|
|
15
|
+
const sizeMap = {
|
|
16
|
+
xs: 'h-7 text-xs px-2.5',
|
|
17
|
+
sm: 'h-9 text-sm px-3',
|
|
18
|
+
md: 'h-12 text-md px-4',
|
|
19
|
+
lg: 'h-14 text-base px-6',
|
|
20
|
+
};
|
|
21
|
+
const buttonSizeMap = {
|
|
22
|
+
xs: 'size-7',
|
|
23
|
+
sm: 'size-9',
|
|
24
|
+
md: 'size-12',
|
|
25
|
+
lg: 'size-14',
|
|
26
|
+
};
|
|
27
|
+
const buttonPixelSizeMap = {
|
|
28
|
+
xs: 28,
|
|
29
|
+
sm: 36,
|
|
30
|
+
md: 48,
|
|
31
|
+
lg: 56,
|
|
32
|
+
};
|
|
33
|
+
return (_jsx(FieldControl, { label: label, id: id, labelClassName: labelClassName, labelPosition: labelPosition, wrapperClassName: wrapperClassName, errorMessage: errorMessage, roundedFull: roundedFull, size: size, disabled: disabled, children: ({ controlId, describedBy, errorMessage: controlError, disabled: controlDisabled }) => (_jsxs("form", { role: "search", onSubmit: handleSubmit, className: "flex w-full items-center gap-2", children: [_jsx("input", { id: controlId, name: name, placeholder: placeholder, disabled: controlDisabled, "aria-invalid": !!controlError, "aria-describedby": describedBy, type: "search", ...inputProps, ...props, className: controlClasses({
|
|
34
|
+
errorMessage: controlError,
|
|
35
|
+
disabled: controlDisabled,
|
|
36
|
+
extra: cn('border-app-border bg-surface text-foreground placeholder:text-foreground-muted truncate border shadow-none', 'focus:border-brand focus:ring-brand/20 focus:ring-2', roundedFull && 'rounded-full', sizeMap[size], className),
|
|
37
|
+
}) }), _jsx(Button, { "aria-label": "Buscar", className: cn('min-h-0 min-w-0 shrink-0 rounded-full p-0', buttonSizeMap[size]), isSubmitting: isSubmitting, type: "submit", disabled: controlDisabled, style: {
|
|
38
|
+
width: buttonPixelSizeMap[size],
|
|
39
|
+
height: buttonPixelSizeMap[size],
|
|
40
|
+
minWidth: buttonPixelSizeMap[size],
|
|
41
|
+
minHeight: buttonPixelSizeMap[size],
|
|
42
|
+
}, children: _jsx(SearchIcon, { className: "size-4 shrink-0" }) })] })) }));
|
|
43
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface ValidValues {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string | number | null | undefined;
|
|
5
|
+
}
|
|
6
|
+
export interface SelectFieldAction {
|
|
7
|
+
onClick: React.MouseEventHandler<HTMLButtonElement>;
|
|
8
|
+
icon: React.ReactNode;
|
|
9
|
+
ariaLabel: string;
|
|
10
|
+
tooltip?: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface SelectFieldProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'> {
|
|
14
|
+
isLoading?: boolean;
|
|
15
|
+
wrapperClassName?: string;
|
|
16
|
+
labelClassName?: string;
|
|
17
|
+
labelAction?: React.ReactNode;
|
|
18
|
+
action?: SelectFieldAction;
|
|
19
|
+
label?: string;
|
|
20
|
+
errorMessage?: string;
|
|
21
|
+
error?: string;
|
|
22
|
+
options?: ValidValues[];
|
|
23
|
+
hasValidation?: boolean;
|
|
24
|
+
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
25
|
+
labelPosition?: 'top' | 'right' | 'bottom' | 'left';
|
|
26
|
+
roundedFull?: boolean;
|
|
27
|
+
defaultValue?: number | string;
|
|
28
|
+
hideEmptyOption?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare const SelectField: React.ForwardRefExoticComponent<SelectFieldProps & React.RefAttributes<HTMLSelectElement>>;
|
|
31
|
+
//# sourceMappingURL=SelectField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectField.d.ts","sourceRoot":"","sources":["../../src/components/SelectField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACpD,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACnG,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,aAAa,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,WAAW,4FAuGvB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { cn } from '../utils/cn';
|
|
4
|
+
import { FieldSkeleton } from './FieldSkeleton';
|
|
5
|
+
import { controlClasses } from './form-control-helpers';
|
|
6
|
+
import { FieldControl } from './FieldControl';
|
|
7
|
+
import { Button } from './Button';
|
|
8
|
+
export const SelectField = React.forwardRef(({ isLoading, label, errorMessage, error, id, className, wrapperClassName = '', labelClassName = '', labelAction, action, labelPosition = 'top', options: validValues, roundedFull = false, size = 'sm', defaultValue, hideEmptyOption = false, disabled = false, children, ...props }, ref) => {
|
|
9
|
+
const componentId = id || props.name;
|
|
10
|
+
const resolvedError = errorMessage ?? error;
|
|
11
|
+
const sizeMap = {
|
|
12
|
+
xs: 'h-7 text-xs px-2',
|
|
13
|
+
sm: 'h-9 text-sm px-3',
|
|
14
|
+
md: 'h-12 text-sm px-4',
|
|
15
|
+
lg: 'h-14 text-base px-6',
|
|
16
|
+
};
|
|
17
|
+
const roundedClass = roundedFull ? 'rounded-full' : size === 'lg' ? 'rounded-lg' : 'rounded-md';
|
|
18
|
+
const sizeClass = `${sizeMap[size ?? 'sm']} ${roundedClass}`;
|
|
19
|
+
const resolvedLabelAction = action ? (_jsx(Button, { type: "button", variant: "ghost", size: "xs", className: "!h-4 !min-h-4 !w-4 !min-w-4 !p-0", onClick: action.onClick, "aria-label": action.ariaLabel, tooltip: action.tooltip, disabled: action.disabled, children: action.icon })) : labelAction;
|
|
20
|
+
return (_jsx(FieldSkeleton, { className: wrapperClassName, isLoading: isLoading ?? false, hasLabel: !!label, labelPosition: labelPosition, size: size, children: _jsx(FieldControl, { label: label, id: componentId, labelClassName: labelClassName, labelAction: resolvedLabelAction, labelPosition: labelPosition, wrapperClassName: wrapperClassName, errorMessage: resolvedError, roundedFull: roundedFull, size: size, disabled: disabled, children: ({ controlId, describedBy, errorMessage: controlError, disabled: controlDisabled }) => (_jsxs("div", { className: cn('relative text-foreground-muted', controlDisabled && 'opacity-60'), children: [_jsxs("select", { ref: ref, ...props, id: controlId, disabled: controlDisabled, "aria-invalid": !!controlError, "aria-describedby": describedBy, className: controlClasses({
|
|
21
|
+
errorMessage: controlError,
|
|
22
|
+
disabled: controlDisabled,
|
|
23
|
+
extra: cn('field-select', className, 'appearance-none pr-10', roundedFull && 'min-h-[2rem] px-4 py-1.5', sizeClass),
|
|
24
|
+
}), defaultValue: defaultValue, children: [!hideEmptyOption && !children && (_jsx("option", { value: "", children: "Selecione..." }, "")), children, validValues?.map((opt) => (_jsx("option", { value: opt.value ?? '', children: opt.label }, opt.value ?? '')))] }), _jsx("div", { className: "pointer-events-none absolute top-1/2 right-3 -translate-y-1/2 text-current", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": true, focusable: "false", className: "block size-4", children: _jsx("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })) }) }));
|
|
25
|
+
});
|
|
26
|
+
SelectField.displayName = 'SelectField';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type FormControlSize, type FormControlVariant } from './form-control-helpers';
|
|
3
|
+
export interface SelectionDisplayValue {
|
|
4
|
+
title: string;
|
|
5
|
+
subtitle?: string | null;
|
|
6
|
+
meta?: string | null;
|
|
7
|
+
}
|
|
8
|
+
export type SelectionFieldSize = FormControlSize;
|
|
9
|
+
export type SelectionFieldVariant = FormControlVariant;
|
|
10
|
+
type SelectionTriggerProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
11
|
+
tooltip?: string;
|
|
12
|
+
};
|
|
13
|
+
export interface SelectionFieldProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'className' | 'disabled' | 'required' | 'value'> {
|
|
14
|
+
label?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
value?: SelectionDisplayValue | null;
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
icon?: React.ReactNode;
|
|
19
|
+
emptyIcon?: React.ReactNode;
|
|
20
|
+
triggerSlot?: React.ReactElement<SelectionTriggerProps>;
|
|
21
|
+
clearable?: boolean;
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
loading?: boolean;
|
|
24
|
+
required?: boolean;
|
|
25
|
+
errorMessage?: string;
|
|
26
|
+
size?: SelectionFieldSize;
|
|
27
|
+
variant?: SelectionFieldVariant;
|
|
28
|
+
shortcutHint?: string;
|
|
29
|
+
selectTooltip?: string;
|
|
30
|
+
clearTooltip?: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
controlClassName?: string;
|
|
33
|
+
labelClassName?: string;
|
|
34
|
+
labelPosition?: 'top' | 'right' | 'bottom' | 'left';
|
|
35
|
+
onClear?: () => void;
|
|
36
|
+
}
|
|
37
|
+
export declare function SelectionField({ label, description, value, placeholder, icon, emptyIcon, triggerSlot, clearable, disabled, loading, required, errorMessage, size, variant, shortcutHint, selectTooltip, clearTooltip, className, controlClassName, labelClassName, labelPosition, onClear, onClick, title: triggerTitle, type, ...triggerButtonProps }: SelectionFieldProps): React.JSX.Element;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=SelectionField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectionField.d.ts","sourceRoot":"","sources":["../../src/components/SelectionField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAkB,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAIvG,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,eAAe,CAAC;AACjD,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAEvD,KAAK,qBAAqB,GAAG,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,GAAG;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,WAAW,mBACf,SAAQ,IAAI,CACV,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAC7C,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAC7D;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAuDD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,WAAW,EACX,KAAK,EACL,WAAqC,EACrC,IAAI,EACJ,SAAS,EACT,WAAW,EACX,SAAiB,EACjB,QAAgB,EAChB,OAAe,EACf,QAAgB,EAChB,YAAY,EACZ,IAAW,EACX,OAAmB,EACnB,YAAY,EACZ,aAA4B,EAC5B,YAA+B,EAC/B,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,aAAqB,EACrB,OAAO,EACP,OAAO,EACP,KAAK,EAAE,YAAY,EACnB,IAAe,EACf,GAAG,kBAAkB,EACtB,EAAE,mBAAmB,qBAiMrB"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { cn } from '../utils/cn';
|
|
4
|
+
import { controlClasses } from './form-control-helpers';
|
|
5
|
+
import { FieldControl } from './FieldControl';
|
|
6
|
+
import { Search, X } from 'lucide-react';
|
|
7
|
+
const controlSizeClass = {
|
|
8
|
+
xs: '!h-7 !pr-0.5 !py-0 text-xs',
|
|
9
|
+
sm: '!h-9 !pr-1 !py-0 text-sm',
|
|
10
|
+
md: '!h-12 !pr-1.5 !py-0 text-md',
|
|
11
|
+
lg: '!h-14 !pr-2 !py-0 text-base',
|
|
12
|
+
};
|
|
13
|
+
const controlLeadingPaddingClass = {
|
|
14
|
+
xs: '!pl-2',
|
|
15
|
+
sm: '!pl-3',
|
|
16
|
+
md: '!pl-4',
|
|
17
|
+
lg: '!pl-6',
|
|
18
|
+
};
|
|
19
|
+
const controlIconPaddingClass = {
|
|
20
|
+
xs: '!pl-0.5',
|
|
21
|
+
sm: '!pl-1',
|
|
22
|
+
md: '!pl-1.5',
|
|
23
|
+
lg: '!pl-2',
|
|
24
|
+
};
|
|
25
|
+
const controlGapClass = {
|
|
26
|
+
xs: 'gap-0.5',
|
|
27
|
+
sm: 'gap-1',
|
|
28
|
+
md: 'gap-1.5',
|
|
29
|
+
lg: 'gap-2',
|
|
30
|
+
};
|
|
31
|
+
const iconSizeClass = {
|
|
32
|
+
xs: '[&>svg]:size-3.5',
|
|
33
|
+
sm: '[&>svg]:size-4',
|
|
34
|
+
md: '[&>svg]:size-[1.125rem]',
|
|
35
|
+
lg: '[&>svg]:size-5',
|
|
36
|
+
};
|
|
37
|
+
const actionSizeClass = {
|
|
38
|
+
xs: '!size-6 !min-h-6 !min-w-6 !p-0 [&>svg]:size-3.5',
|
|
39
|
+
sm: '!size-7 !min-h-7 !min-w-7 !p-0 [&>svg]:size-4',
|
|
40
|
+
md: '!size-9 !min-h-9 !min-w-9 !p-0 [&>svg]:size-[1.125rem]',
|
|
41
|
+
lg: '!size-10 !min-h-10 !min-w-10 !p-0 [&>svg]:size-5',
|
|
42
|
+
};
|
|
43
|
+
const textGapClass = {
|
|
44
|
+
xs: 'gap-0',
|
|
45
|
+
sm: 'gap-0',
|
|
46
|
+
md: 'gap-1',
|
|
47
|
+
lg: 'gap-1',
|
|
48
|
+
};
|
|
49
|
+
function stopPropagation(event) {
|
|
50
|
+
event.stopPropagation();
|
|
51
|
+
}
|
|
52
|
+
export function SelectionField({ label, description, value, placeholder = 'Selecione um registro', icon, emptyIcon, triggerSlot, clearable = false, disabled = false, loading = false, required = false, errorMessage, size = 'sm', variant = 'default', shortcutHint, selectTooltip = 'Selecionar', clearTooltip = 'Limpar selecao', className, controlClassName, labelClassName, labelPosition = 'top', onClear, onClick, title: triggerTitle, type = 'button', ...triggerButtonProps }) {
|
|
53
|
+
const hasValue = !!value;
|
|
54
|
+
const resolvedIcon = hasValue ? icon : emptyIcon ?? icon;
|
|
55
|
+
const title = value?.title ?? placeholder;
|
|
56
|
+
const subtitle = value?.subtitle;
|
|
57
|
+
const meta = value?.meta;
|
|
58
|
+
const generatedDescriptionId = React.useId().replace(/:/g, '');
|
|
59
|
+
const describedById = description ? `${generatedDescriptionId}-description` : undefined;
|
|
60
|
+
const showClear = clearable && hasValue && !disabled && !loading && !!onClear;
|
|
61
|
+
const [isClearHover, setIsClearHover] = React.useState(false);
|
|
62
|
+
function handleClear(event) {
|
|
63
|
+
event.stopPropagation();
|
|
64
|
+
onClear?.();
|
|
65
|
+
}
|
|
66
|
+
function handleClearMouseEnter() {
|
|
67
|
+
setIsClearHover(true);
|
|
68
|
+
}
|
|
69
|
+
function handleClearMouseLeave() {
|
|
70
|
+
setIsClearHover(false);
|
|
71
|
+
}
|
|
72
|
+
function handleOpen(event) {
|
|
73
|
+
if (disabled || loading || event.defaultPrevented) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (onClick) {
|
|
77
|
+
onClick(event);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
triggerSlot?.props.onClick?.(event);
|
|
81
|
+
}
|
|
82
|
+
const triggerClassName = cn('inline-flex cursor-pointer shrink-0 items-center justify-center rounded-md border border-transparent bg-transparent text-foreground-muted transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand/30 disabled:pointer-events-none disabled:opacity-50', actionSizeClass[size]);
|
|
83
|
+
const selectionTrigger = triggerSlot
|
|
84
|
+
? React.cloneElement(triggerSlot, {
|
|
85
|
+
'aria-label': triggerSlot.props['aria-label'] ?? selectTooltip,
|
|
86
|
+
className: cn(triggerClassName, triggerSlot.props.className),
|
|
87
|
+
disabled: disabled || loading || triggerSlot.props.disabled,
|
|
88
|
+
title: triggerSlot.props.title ?? triggerSlot.props.tooltip ?? selectTooltip,
|
|
89
|
+
type: triggerSlot.props.type ?? 'button',
|
|
90
|
+
onClick: triggerSlot.props.onClick,
|
|
91
|
+
})
|
|
92
|
+
: (_jsx("button", { ...triggerButtonProps, type: type, "aria-label": triggerButtonProps['aria-label'] ?? selectTooltip, className: triggerClassName, disabled: disabled || loading, title: triggerTitle ?? selectTooltip, onClick: onClick, children: _jsx(Search, { "aria-hidden": "true" }) }));
|
|
93
|
+
return (_jsx(FieldControl, { label: label, labelClassName: labelClassName, labelPosition: labelPosition, wrapperClassName: className, errorMessage: errorMessage, hasValidation: !!description, size: size, disabled: disabled || loading, children: ({ controlId, describedBy, errorMessage: controlError }) => {
|
|
94
|
+
const ariaDescribedBy = cn(describedBy, describedById);
|
|
95
|
+
return (_jsxs("div", { children: [_jsxs("div", { id: controlId, "aria-describedby": ariaDescribedBy || undefined, "aria-disabled": disabled || loading || undefined, "aria-invalid": !!controlError || undefined, className: controlClasses({
|
|
96
|
+
errorMessage: controlError,
|
|
97
|
+
disabled: disabled || loading,
|
|
98
|
+
variant,
|
|
99
|
+
extra: cn('group flex items-center overflow-hidden border-dashed', !hasValue && 'bg-[color-mix(in_srgb,var(--brand)_5%,var(--surface))]', hasValue && 'bg-surface', disabled || loading
|
|
100
|
+
? 'cursor-not-allowed'
|
|
101
|
+
: cn('cursor-pointer', !isClearHover &&
|
|
102
|
+
'hover:border-[color-mix(in_srgb,var(--brand)_58%,var(--app-border))] hover:bg-[color-mix(in_srgb,var(--brand)_8%,var(--surface))]'), size === 'lg' ? 'rounded-lg' : 'rounded-md', controlSizeClass[size], controlGapClass[size], resolvedIcon ? controlIconPaddingClass[size] : controlLeadingPaddingClass[size], controlClassName),
|
|
103
|
+
}), "data-empty": !hasValue || undefined, "data-loading": loading || undefined, onClick: handleOpen, children: [resolvedIcon ? (_jsx("span", { className: cn('inline-flex shrink-0 items-center justify-center rounded-md text-foreground-muted', !hasValue && 'text-[color-mix(in_srgb,var(--brand)_72%,var(--foreground-muted))]', actionSizeClass[size], iconSizeClass[size]), "aria-hidden": "true", children: resolvedIcon })) : null, _jsxs("div", { className: cn('min-w-0 flex-1 text-left', textGapClass[size]), children: [_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsxs("span", { className: cn('min-w-0 truncate font-semibold', hasValue ? 'text-foreground' : 'text-foreground-muted'), children: [title, required && !hasValue ? _jsx("span", { "aria-hidden": "true", children: " *" }) : null] }), meta ? (_jsx("span", { className: "border-app-border bg-background text-foreground-muted shrink-0 rounded border px-1.5 py-0.5 font-mono text-[length:var(--font-size-2xs)] leading-none", children: meta })) : null] }), subtitle ? (_jsx("p", { className: cn('text-foreground-muted truncate text-xs font-medium', (size === 'xs' || size === 'sm') && 'sr-only'), children: subtitle })) : null] }), shortcutHint ? (_jsx("kbd", { className: "border-app-border bg-background text-foreground-muted hidden shrink-0 rounded border px-1.5 py-1 font-mono text-[length:var(--font-size-2xs)] leading-none sm:inline-flex", children: shortcutHint })) : null, showClear ? (_jsx("button", { type: "button", "aria-label": clearTooltip, className: cn('inline-flex cursor-pointer shrink-0 items-center justify-center rounded-md border border-transparent bg-transparent text-foreground-muted transition-colors', 'hover:bg-[color-mix(in_srgb,var(--destructive)_10%,transparent)] hover:text-[var(--destructive)]', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--destructive)]/25', actionSizeClass[size]), title: clearTooltip, onClick: handleClear, onMouseEnter: handleClearMouseEnter, onMouseLeave: handleClearMouseLeave, children: _jsx(X, { "aria-hidden": "true" }) })) : null, disabled ? null : _jsx("span", { onClick: stopPropagation, children: selectionTrigger })] }), description ? (_jsx("p", { id: describedById, className: "mt-1 text-xs font-medium text-foreground-muted", children: description })) : null] }));
|
|
104
|
+
} }));
|
|
105
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { type ButtonHTMLAttributes, type MouseEvent, type ReactNode } from 'react';
|
|
2
|
+
type SidebarItemSize = 'default' | 'compact';
|
|
3
|
+
type SidebarActionTone = 'nav' | 'subtle';
|
|
4
|
+
export interface SidebarRootProps {
|
|
5
|
+
ariaLabel?: string;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
className?: string;
|
|
8
|
+
desktopWidthClass?: string;
|
|
9
|
+
isOpen: boolean;
|
|
10
|
+
mobileWidthClass?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SidebarContentProps {
|
|
13
|
+
ariaLabel?: string;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
declare function Content({ ariaLabel, children, className }: SidebarContentProps): import("react").JSX.Element;
|
|
18
|
+
declare function Header({ children, className }: {
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
className?: string;
|
|
21
|
+
}): import("react").JSX.Element;
|
|
22
|
+
export interface SidebarListProps {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
className?: string;
|
|
25
|
+
isOpen: boolean;
|
|
26
|
+
}
|
|
27
|
+
declare function List({ children, className, isOpen }: SidebarListProps): import("react").JSX.Element;
|
|
28
|
+
export interface SidebarFooterProps {
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
className?: string;
|
|
31
|
+
}
|
|
32
|
+
declare function Footer({ children, className }: SidebarFooterProps): import("react").JSX.Element;
|
|
33
|
+
export interface SidebarSeparatorProps {
|
|
34
|
+
className?: string;
|
|
35
|
+
flush?: boolean;
|
|
36
|
+
}
|
|
37
|
+
declare function Separator({ className, flush }: SidebarSeparatorProps): import("react").JSX.Element;
|
|
38
|
+
export interface SidebarToggleButtonProps {
|
|
39
|
+
className?: string;
|
|
40
|
+
closedLabel?: string;
|
|
41
|
+
icon: ReactNode;
|
|
42
|
+
isOpen: boolean;
|
|
43
|
+
onToggle: () => void;
|
|
44
|
+
openLabel?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface SidebarActionButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
|
47
|
+
active?: boolean;
|
|
48
|
+
expanded?: boolean;
|
|
49
|
+
icon?: ReactNode;
|
|
50
|
+
isOpen: boolean;
|
|
51
|
+
label: ReactNode;
|
|
52
|
+
labelClassName?: string;
|
|
53
|
+
showChevron?: boolean;
|
|
54
|
+
size?: SidebarItemSize;
|
|
55
|
+
tone?: SidebarActionTone;
|
|
56
|
+
}
|
|
57
|
+
export interface SidebarSubActionButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
|
58
|
+
active?: boolean;
|
|
59
|
+
isOpen: boolean;
|
|
60
|
+
label: ReactNode;
|
|
61
|
+
size?: SidebarItemSize;
|
|
62
|
+
}
|
|
63
|
+
export interface SidebarNavItem {
|
|
64
|
+
active?: boolean;
|
|
65
|
+
icon?: ReactNode;
|
|
66
|
+
key: string;
|
|
67
|
+
label: ReactNode;
|
|
68
|
+
onSelect?: (event: MouseEvent<HTMLButtonElement>) => void;
|
|
69
|
+
title?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface SidebarNavGroupProps {
|
|
72
|
+
active?: boolean;
|
|
73
|
+
className?: string;
|
|
74
|
+
collapsible?: boolean;
|
|
75
|
+
defaultExpanded?: boolean;
|
|
76
|
+
icon: ReactNode;
|
|
77
|
+
isOpen: boolean;
|
|
78
|
+
items: SidebarNavItem[];
|
|
79
|
+
subItemSize?: SidebarItemSize;
|
|
80
|
+
title: ReactNode;
|
|
81
|
+
}
|
|
82
|
+
declare function NavGroup({ active, className, collapsible, defaultExpanded, icon, isOpen, items, subItemSize, title, }: SidebarNavGroupProps): import("react").JSX.Element;
|
|
83
|
+
export interface SidebarFlyoutProps {
|
|
84
|
+
items: SidebarNavItem[];
|
|
85
|
+
onItemSelect: (event: MouseEvent<HTMLButtonElement>) => void;
|
|
86
|
+
open: boolean;
|
|
87
|
+
title: ReactNode;
|
|
88
|
+
}
|
|
89
|
+
declare function Flyout({ items, onItemSelect, open, title }: SidebarFlyoutProps): import("react").JSX.Element;
|
|
90
|
+
export declare const Sidebar: {
|
|
91
|
+
Root: import("react").ForwardRefExoticComponent<SidebarRootProps & import("react").RefAttributes<HTMLElement>>;
|
|
92
|
+
Content: typeof Content;
|
|
93
|
+
Header: typeof Header;
|
|
94
|
+
List: typeof List;
|
|
95
|
+
Footer: typeof Footer;
|
|
96
|
+
Separator: typeof Separator;
|
|
97
|
+
ToggleButton: import("react").ForwardRefExoticComponent<SidebarToggleButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
98
|
+
ActionButton: import("react").ForwardRefExoticComponent<SidebarActionButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
99
|
+
SubActionButton: import("react").ForwardRefExoticComponent<SidebarSubActionButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
100
|
+
NavGroup: typeof NavGroup;
|
|
101
|
+
Flyout: typeof Flyout;
|
|
102
|
+
};
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=Sidebar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../src/components/Sidebar.tsx"],"names":[],"mappings":"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"}
|