@lunit/oui 3.0.0 → 3.0.1

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.
Files changed (41) hide show
  1. package/dist/components/Autocomplete/Autocomplete.js +22 -0
  2. package/dist/components/Autocomplete/Autocomplete.styled.js +36 -0
  3. package/dist/components/Autocomplete/Autocomplete.types.js +1 -0
  4. package/dist/components/Autocomplete/index.js +2 -0
  5. package/dist/components/Collapse/Collapse.js +6 -0
  6. package/dist/components/Collapse/Collapse.types.js +1 -0
  7. package/dist/components/Collapse/index.js +2 -0
  8. package/dist/components/DataTable/DataTable.js +6 -4
  9. package/dist/components/DataTable/DataTable.types.js +1 -0
  10. package/dist/components/Drawer/Drawer.js +6 -0
  11. package/dist/components/Drawer/Drawer.styled.js +29 -0
  12. package/dist/components/Drawer/Drawer.types.js +1 -0
  13. package/dist/components/Drawer/index.js +2 -0
  14. package/dist/components/EllipsisTypography/EllipsisTypography.js +51 -15
  15. package/dist/components/Popover/Popover.js +6 -0
  16. package/dist/components/Popover/Popover.styled.js +10 -0
  17. package/dist/components/Popover/Popover.types.js +1 -0
  18. package/dist/components/Popover/index.js +2 -0
  19. package/dist/components/index.js +4 -0
  20. package/dist/types/components/Autocomplete/Autocomplete.d.ts +3 -0
  21. package/dist/types/components/Autocomplete/Autocomplete.styled.d.ts +6 -0
  22. package/dist/types/components/Autocomplete/Autocomplete.types.d.ts +20 -0
  23. package/dist/types/components/Autocomplete/index.d.ts +4 -0
  24. package/dist/types/components/Collapse/Collapse.d.ts +3 -0
  25. package/dist/types/components/Collapse/Collapse.types.d.ts +4 -0
  26. package/dist/types/components/Collapse/index.d.ts +4 -0
  27. package/dist/types/components/DataTable/DataTable.d.ts +2 -2
  28. package/dist/types/components/DataTable/DataTable.types.d.ts +8 -0
  29. package/dist/types/components/DataTable/index.d.ts +1 -0
  30. package/dist/types/components/Drawer/Drawer.d.ts +3 -0
  31. package/dist/types/components/Drawer/Drawer.styled.d.ts +3 -0
  32. package/dist/types/components/Drawer/Drawer.types.d.ts +14 -0
  33. package/dist/types/components/Drawer/index.d.ts +4 -0
  34. package/dist/types/components/EllipsisTypography/EllipsisTypography.d.ts +2 -1
  35. package/dist/types/components/Popover/Popover.d.ts +3 -0
  36. package/dist/types/components/Popover/Popover.styled.d.ts +2 -0
  37. package/dist/types/components/Popover/Popover.types.d.ts +4 -0
  38. package/dist/types/components/Popover/index.d.ts +4 -0
  39. package/dist/types/components/index.d.ts +4 -0
  40. package/docs/COMPONENTS.md +42 -38
  41. package/package.json +5 -3
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Autocomplete as MuiAutocomplete, TextField, useTheme } from '@mui/material';
3
+ import { Chip } from '../Chip';
4
+ import { Button } from '../Button';
5
+ import { CircularProgress } from '../Progress';
6
+ import { CloseSmall } from '../../icons';
7
+ import { autocompleteSx, paperSx } from './Autocomplete.styled';
8
+ const LOADING_SPINNER_SIZE = 20;
9
+ function Autocomplete({ placeholder = '', error, helperText, loading = false, noOptionsText, onDelete, onClearButtonClick, disabled, inputValue, sx, ...otherProps }) {
10
+ const theme = useTheme();
11
+ return (_jsx(MuiAutocomplete, { multiple: true, freeSolo: true, disableClearable: true, disabled: disabled, loading: loading, loadingText: noOptionsText, inputValue: inputValue, sx: [autocompleteSx(theme, disabled), ...(Array.isArray(sx) ? sx : [sx])], slotProps: {
12
+ listbox: { style: { maxHeight: '180px', overflow: 'auto' } },
13
+ paper: { sx: paperSx(theme) },
14
+ }, renderValue: (values) => values.map((option) => (_jsx(Chip, { disabled: disabled, label: option, onDelete: onDelete ? () => onDelete(option) : undefined }, option))), renderInput: (params) => (_jsx(TextField, { ...params, variant: "outlined", placeholder: placeholder, error: error, helperText: helperText, slotProps: {
15
+ ...params.slotProps,
16
+ input: {
17
+ ...params.slotProps?.input,
18
+ endAdornment: (_jsxs(_Fragment, { children: [loading ? (_jsx(CircularProgress, { size: LOADING_SPINNER_SIZE, sx: { color: theme.palette.neutralGrey[45] } })) : null, onClearButtonClick ? (_jsx(Button, { icon: _jsx(CloseSmall, { style: { color: theme.palette.neutralGrey[45] } }), size: "small", variant: "ghost", onClick: onClearButtonClick })) : null] })),
19
+ },
20
+ } })), ...otherProps }));
21
+ }
22
+ export default Autocomplete;
@@ -0,0 +1,36 @@
1
+ const MIN_INPUT_HEIGHT = '44px';
2
+ /** Tokenized styling for the underlying MUI Autocomplete. */
3
+ export const autocompleteSx = (theme, disabled) => ({
4
+ '.MuiAutocomplete-inputRoot': {
5
+ padding: `${theme.spacing(1.5, 3.5)} !important`,
6
+ gap: theme.spacing(1),
7
+ '& .MuiInputBase-input::placeholder': {
8
+ opacity: disabled ? 0.42 : 1,
9
+ },
10
+ '& .MuiAutocomplete-input': {
11
+ height: '100%',
12
+ },
13
+ },
14
+ '.MuiOutlinedInput-root': {
15
+ minHeight: MIN_INPUT_HEIGHT,
16
+ },
17
+ '.MuiInputBase-root.Mui-disabled': {
18
+ border: `1px solid ${theme.palette.neutralGrey[70]}`,
19
+ color: theme.palette.neutralGrey[45],
20
+ backgroundColor: theme.palette.neutralGrey[75],
21
+ pointerEvents: 'none',
22
+ opacity: 0.8,
23
+ },
24
+ '.MuiFormHelperText-root.Mui-error': {
25
+ ...theme.typography.body5,
26
+ color: theme.palette.error.main,
27
+ margin: 0,
28
+ paddingLeft: theme.spacing(1),
29
+ },
30
+ });
31
+ /** Tokenized styling for the listbox paper. */
32
+ export const paperSx = (theme) => ({
33
+ backgroundColor: theme.palette.neutralGrey[70],
34
+ borderRadius: theme.spacing(2),
35
+ backgroundImage: 'none',
36
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import Autocomplete from './Autocomplete';
2
+ export { Autocomplete };
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Collapse as MuiCollapse } from '@mui/material';
3
+ function Collapse({ children, ...otherProps }) {
4
+ return _jsx(MuiCollapse, { ...otherProps, children: children });
5
+ }
6
+ export default Collapse;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import Collapse from './Collapse';
2
+ export { Collapse };
@@ -2,10 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { DataGridPro } from '@mui/x-data-grid-pro';
3
3
  import DataGridContainer from './DataTable.styled';
4
4
  import { Checkbox } from '../Checkbox';
5
- function DataTable({ rows, columns, ...otherProps }) {
6
- return (_jsx(DataGridContainer, { children: _jsx(DataGridPro, { rows: rows, columns: columns, columnHeaderHeight: 40, rowHeight: 40, showColumnVerticalBorder: true, showCellVerticalBorder: true, disableColumnMenu: true, hideFooter: true, slots: {
7
- noRowsOverlay: () => _jsx("div", {}),
5
+ const EmptyOverlay = () => _jsx("div", {});
6
+ function DataTable({ rows, columns, slots, ...otherProps }) {
7
+ return (_jsx(DataGridContainer, { children: _jsx(DataGridPro, { rows: rows, columns: columns, columnHeaderHeight: 40, rowHeight: 40, showColumnVerticalBorder: true, showCellVerticalBorder: true, disableColumnMenu: true, hideFooter: true, ...otherProps, slots: {
8
+ noRowsOverlay: EmptyOverlay,
8
9
  baseCheckbox: Checkbox,
9
- }, ...otherProps }) }));
10
+ ...slots,
11
+ } }) }));
10
12
  }
11
13
  export default DataTable;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import BaseDrawer from './Drawer.styled';
3
+ function Drawer({ children, open = true, wide, variant = 'permanent', ...otherProps }) {
4
+ return (_jsx(BaseDrawer, { variant: variant, open: open, wide: wide, ...otherProps, children: children }));
5
+ }
6
+ export default Drawer;
@@ -0,0 +1,29 @@
1
+ import { Drawer as MuiDrawer, paperClasses } from '@mui/material';
2
+ import { styled } from '@mui/material/styles';
3
+ const DEFAULT_CLOSED_WIDTH = '52px';
4
+ const DEFAULT_OPEN_WIDTH = '240px';
5
+ const DEFAULT_WIDE_WIDTH = '280px';
6
+ const WIDTH_TRANSITION = 'width 0.2s';
7
+ const FORWARDED_EXCLUDES = ['wide', 'closedWidth', 'openWidth', 'wideWidth'];
8
+ const BaseDrawer = styled(MuiDrawer, {
9
+ shouldForwardProp: (prop) => !FORWARDED_EXCLUDES.includes(prop.toString()),
10
+ })(({ theme, open, wide, closedWidth, openWidth, wideWidth }) => {
11
+ const resolvedClosed = closedWidth ?? DEFAULT_CLOSED_WIDTH;
12
+ const resolvedOpen = openWidth ?? DEFAULT_OPEN_WIDTH;
13
+ const resolvedWide = wideWidth ?? DEFAULT_WIDE_WIDTH;
14
+ const width = !open ? resolvedClosed : wide ? resolvedWide : resolvedOpen;
15
+ return {
16
+ width,
17
+ background: theme.palette.neutralGrey[90],
18
+ boxSizing: 'border-box',
19
+ transition: WIDTH_TRANSITION,
20
+ [`& .${paperClasses.root}`]: {
21
+ width,
22
+ background: theme.palette.neutralGrey[90],
23
+ boxSizing: 'border-box',
24
+ transition: WIDTH_TRANSITION,
25
+ overflowY: 'hidden',
26
+ },
27
+ };
28
+ });
29
+ export default BaseDrawer;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import Drawer from './Drawer';
2
+ export { Drawer };
@@ -1,33 +1,69 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useContext, useEffect, useRef, useState } from 'react';
2
+ import { forwardRef, useCallback, useContext, useEffect, useRef, useState } from 'react';
3
3
  import StyledTypography from './EllipsisTypography.styled';
4
4
  import { Tooltip } from '../Tooltip';
5
5
  import { ResizeObserverContext } from '../ResizeObserver/ResizeObserverContext';
6
- function EllipsisTypography({ children, heightThreshold: heightThresholdProp, tooltipPlacement = 'bottom', maxLines = 1, ...otherProps }) {
7
- const typographyRef = useRef(null);
6
+ const MAX_RETRY_COUNT = 10;
7
+ const RETRY_DELAY_MS = 50;
8
+ const DEFAULT_HEIGHT_THRESHOLD = 1;
9
+ const EllipsisTypography = forwardRef(({ children, heightThreshold: heightThresholdProp, tooltipPlacement = 'bottom', maxLines = 1, ...otherProps }, forwardedRef) => {
10
+ const internalRef = useRef(null);
11
+ const retryCountRef = useRef(0);
12
+ const timeoutRef = useRef(null);
8
13
  const direction = otherProps.direction || 'row';
9
- const heightThreshold = heightThresholdProp != null ? heightThresholdProp : 1;
14
+ const heightThreshold = heightThresholdProp ?? DEFAULT_HEIGHT_THRESHOLD;
10
15
  const [showTooltip, setShowTooltip] = useState(false);
11
16
  const { addResizeHandler, removeResizeHandler } = useContext(ResizeObserverContext);
17
+ const heightThresholdRef = useRef(heightThreshold);
18
+ heightThresholdRef.current = heightThreshold;
19
+ const checkOverflow = useCallback((target) => {
20
+ if (!target)
21
+ return;
22
+ const { scrollHeight, clientHeight, scrollWidth, clientWidth } = target;
23
+ // The element may not be laid out yet (all metrics 0); retry until it is.
24
+ if (scrollHeight === 0 && clientHeight === 0 && scrollWidth === 0 && clientWidth === 0) {
25
+ if (retryCountRef.current < MAX_RETRY_COUNT) {
26
+ retryCountRef.current += 1;
27
+ timeoutRef.current = setTimeout(() => checkOverflow(target), RETRY_DELAY_MS);
28
+ }
29
+ return;
30
+ }
31
+ retryCountRef.current = 0;
32
+ const threshold = heightThresholdRef.current;
33
+ // Single-line ellipsis truncates horizontally (scrollHeight === clientHeight), so width must
34
+ // also be compared. Multi-line clamp still overflows vertically.
35
+ const isOverflowing = scrollWidth > clientWidth + threshold || scrollHeight > clientHeight + threshold;
36
+ setShowTooltip(isOverflowing);
37
+ }, []);
38
+ const setRefs = useCallback((node) => {
39
+ internalRef.current = node;
40
+ if (typeof forwardedRef === 'function') {
41
+ forwardedRef(node);
42
+ }
43
+ else if (forwardedRef) {
44
+ forwardedRef.current = node;
45
+ }
46
+ }, [forwardedRef]);
12
47
  useEffect(() => {
13
- if (!typographyRef.current)
48
+ const target = internalRef.current;
49
+ if (!target)
14
50
  return;
15
- const target = typographyRef.current;
16
- const checkOverflow = () => {
17
- const isOverflowing = target.scrollHeight - target.clientHeight > heightThreshold;
18
- setShowTooltip(isOverflowing);
19
- };
51
+ const run = () => checkOverflow(target);
20
52
  if (addResizeHandler) {
21
- addResizeHandler(target, checkOverflow);
53
+ addResizeHandler(target, run);
22
54
  }
23
- checkOverflow();
55
+ run();
24
56
  return () => {
57
+ if (timeoutRef.current) {
58
+ clearTimeout(timeoutRef.current);
59
+ }
25
60
  if (removeResizeHandler) {
26
61
  removeResizeHandler(target);
27
62
  }
28
63
  };
29
- }, [heightThreshold, addResizeHandler, removeResizeHandler]);
30
- const TypographyComponent = (_jsx(StyledTypography, { ...otherProps, ref: typographyRef, direction: direction, maxLines: maxLines, children: children }));
64
+ }, [children, maxLines, checkOverflow, addResizeHandler, removeResizeHandler]);
65
+ const TypographyComponent = (_jsx(StyledTypography, { ...otherProps, ref: setRefs, direction: direction, maxLines: maxLines, children: children }));
31
66
  return showTooltip ? (_jsx(Tooltip, { title: children, placement: tooltipPlacement, size: "small", children: TypographyComponent })) : (TypographyComponent);
32
- }
67
+ });
68
+ EllipsisTypography.displayName = 'EllipsisTypography';
33
69
  export default EllipsisTypography;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import StyledPopover from './Popover.styled';
3
+ function Popover({ children, ...otherProps }) {
4
+ return _jsx(StyledPopover, { ...otherProps, children: children });
5
+ }
6
+ export default Popover;
@@ -0,0 +1,10 @@
1
+ import { Popover as MuiPopover } from '@mui/material';
2
+ import { styled } from '@mui/material/styles';
3
+ const StyledPopover = styled(MuiPopover)(({ theme }) => ({
4
+ '& .MuiPopover-paper': {
5
+ backgroundColor: theme.palette.neutralGrey[70],
6
+ borderRadius: theme.spacing(2),
7
+ backgroundImage: 'none',
8
+ },
9
+ }));
10
+ export default StyledPopover;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import Popover from './Popover';
2
+ export { Popover };
@@ -1,16 +1,20 @@
1
1
  export * from './Alert';
2
+ export * from './Autocomplete';
2
3
  export * from './Button';
3
4
  export * from './Card';
4
5
  export * from './Checkbox';
5
6
  export * from './Chip';
7
+ export * from './Collapse';
6
8
  export * from './DataTable';
7
9
  export * from './DatePicker';
8
10
  export * from './Dialog';
9
11
  export * from './Divider';
12
+ export * from './Drawer';
10
13
  export * from './Dropdown';
11
14
  export * from './EllipsisTypography';
12
15
  export * from './FileDnDZone';
13
16
  export * from './List';
17
+ export * from './Popover';
14
18
  export * from './LoadingIndicator';
15
19
  export * from './Menu';
16
20
  export * from './Pagination';
@@ -0,0 +1,3 @@
1
+ import type { AutocompleteProps } from './Autocomplete.types';
2
+ declare function Autocomplete({ placeholder, error, helperText, loading, noOptionsText, onDelete, onClearButtonClick, disabled, inputValue, sx, ...otherProps }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;
3
+ export default Autocomplete;
@@ -0,0 +1,6 @@
1
+ import type { Theme } from '@mui/material/styles';
2
+ import type { SxProps } from '@mui/system';
3
+ /** Tokenized styling for the underlying MUI Autocomplete. */
4
+ export declare const autocompleteSx: (theme: Theme, disabled?: boolean) => SxProps<Theme>;
5
+ /** Tokenized styling for the listbox paper. */
6
+ export declare const paperSx: (theme: Theme) => SxProps<Theme>;
@@ -0,0 +1,20 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { AutocompleteProps as MuiAutocompleteProps } from '@mui/material';
3
+ type MuiBase = MuiAutocompleteProps<string, true, true, true>;
4
+ export interface AutocompleteProps extends Omit<MuiBase, 'renderInput' | 'renderValue' | 'renderTags' | 'multiple' | 'freeSolo' | 'disableClearable'> {
5
+ /** Placeholder shown in the text input. */
6
+ placeholder?: string;
7
+ /** Whether the field is in an error state. */
8
+ error?: boolean;
9
+ /** Helper / error message shown below the input. */
10
+ helperText?: string;
11
+ /** Shows a loading indicator and `noOptionsText` while fetching options. */
12
+ loading?: boolean;
13
+ /** Message shown when there are no matching options. */
14
+ noOptionsText?: ReactNode;
15
+ /** Called when a selected chip's delete icon is clicked. */
16
+ onDelete?: (value: string) => void;
17
+ /** When provided, renders a clear button in the input adornment. */
18
+ onClearButtonClick?: () => void;
19
+ }
20
+ export {};
@@ -0,0 +1,4 @@
1
+ import Autocomplete from './Autocomplete';
2
+ import type { AutocompleteProps } from './Autocomplete.types';
3
+ export { Autocomplete };
4
+ export type { AutocompleteProps };
@@ -0,0 +1,3 @@
1
+ import type { CollapseProps } from './Collapse.types';
2
+ declare function Collapse({ children, ...otherProps }: CollapseProps): import("react/jsx-runtime").JSX.Element;
3
+ export default Collapse;
@@ -0,0 +1,4 @@
1
+ import type { CollapseProps as MuiCollapseProps } from '@mui/material';
2
+ /** Props for Collapse. Re-exports MUI Collapse props for expand/collapse transitions. */
3
+ export interface CollapseProps extends MuiCollapseProps {
4
+ }
@@ -0,0 +1,4 @@
1
+ import Collapse from './Collapse';
2
+ import type { CollapseProps } from './Collapse.types';
3
+ export { Collapse };
4
+ export type { CollapseProps };
@@ -1,3 +1,3 @@
1
- import { type DataGridProProps } from '@mui/x-data-grid-pro';
2
- declare function DataTable({ rows, columns, ...otherProps }: DataGridProProps): import("react/jsx-runtime").JSX.Element;
1
+ import type { DataTableProps } from './DataTable.types';
2
+ declare function DataTable({ rows, columns, slots, ...otherProps }: DataTableProps): import("react/jsx-runtime").JSX.Element;
3
3
  export default DataTable;
@@ -0,0 +1,8 @@
1
+ import type { DataGridProProps } from '@mui/x-data-grid-pro';
2
+ /**
3
+ * Props for the DataTable component. Extends MUI X DataGridPro props; OUI sets
4
+ * sensible defaults (header/row height, borders, base checkbox, empty overlay)
5
+ * that consumers can still override, including per-key `slots` merging.
6
+ */
7
+ export interface DataTableProps extends DataGridProProps {
8
+ }
@@ -1 +1,2 @@
1
1
  export { default as DataTable } from './DataTable';
2
+ export type { DataTableProps } from './DataTable.types';
@@ -0,0 +1,3 @@
1
+ import type { DrawerProps } from './Drawer.types';
2
+ declare function Drawer({ children, open, wide, variant, ...otherProps }: DrawerProps): import("react/jsx-runtime").JSX.Element;
3
+ export default Drawer;
@@ -0,0 +1,3 @@
1
+ import type { BaseDrawerProps } from './Drawer.types';
2
+ declare const BaseDrawer: import("@emotion/styled").StyledComponent<import("@mui/material").DrawerProps & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & BaseDrawerProps, {}, {}>;
3
+ export default BaseDrawer;
@@ -0,0 +1,14 @@
1
+ import type { DrawerProps as MuiDrawerProps } from '@mui/material';
2
+ export interface BaseDrawerProps extends MuiDrawerProps {
3
+ /** Whether the drawer is expanded. When false, collapses to `closedWidth`. */
4
+ open?: boolean;
5
+ /** Whether to use the wider expanded width (`wideWidth`) instead of `openWidth`. */
6
+ wide?: boolean;
7
+ /** Width when collapsed (`open=false`). Defaults to 52px. */
8
+ closedWidth?: number | string;
9
+ /** Width when expanded. Defaults to 240px. */
10
+ openWidth?: number | string;
11
+ /** Width when expanded and `wide` is set. Defaults to 280px. */
12
+ wideWidth?: number | string;
13
+ }
14
+ export type DrawerProps = BaseDrawerProps;
@@ -0,0 +1,4 @@
1
+ import Drawer from './Drawer';
2
+ import type { BaseDrawerProps, DrawerProps } from './Drawer.types';
3
+ export { Drawer };
4
+ export type { BaseDrawerProps, DrawerProps };
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import type { EllipsisTypographyProps } from './EllipsisTypography.types';
2
- declare function EllipsisTypography({ children, heightThreshold: heightThresholdProp, tooltipPlacement, maxLines, ...otherProps }: EllipsisTypographyProps): import("react/jsx-runtime").JSX.Element;
3
+ declare const EllipsisTypography: React.ForwardRefExoticComponent<Omit<EllipsisTypographyProps, "ref"> & React.RefAttributes<HTMLElement>>;
3
4
  export default EllipsisTypography;
@@ -0,0 +1,3 @@
1
+ import type { PopoverProps } from './Popover.types';
2
+ declare function Popover({ children, ...otherProps }: PopoverProps): import("react/jsx-runtime").JSX.Element;
3
+ export default Popover;
@@ -0,0 +1,2 @@
1
+ declare const StyledPopover: import("@emotion/styled").StyledComponent<import("@mui/material").PopoverProps & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, {}, {}>;
2
+ export default StyledPopover;
@@ -0,0 +1,4 @@
1
+ import type { PopoverProps as MuiPopoverProps } from '@mui/material';
2
+ /** Props for Popover. Extends MUI Popover with OUI's tokenized paper styling. */
3
+ export interface PopoverProps extends MuiPopoverProps {
4
+ }
@@ -0,0 +1,4 @@
1
+ import Popover from './Popover';
2
+ import type { PopoverProps } from './Popover.types';
3
+ export { Popover };
4
+ export type { PopoverProps };
@@ -1,16 +1,20 @@
1
1
  export * from './Alert';
2
+ export * from './Autocomplete';
2
3
  export * from './Button';
3
4
  export * from './Card';
4
5
  export * from './Checkbox';
5
6
  export * from './Chip';
7
+ export * from './Collapse';
6
8
  export * from './DataTable';
7
9
  export * from './DatePicker';
8
10
  export * from './Dialog';
9
11
  export * from './Divider';
12
+ export * from './Drawer';
10
13
  export * from './Dropdown';
11
14
  export * from './EllipsisTypography';
12
15
  export * from './FileDnDZone';
13
16
  export * from './List';
17
+ export * from './Popover';
14
18
  export * from './LoadingIndicator';
15
19
  export * from './Menu';
16
20
  export * from './Pagination';
@@ -18,14 +18,14 @@ import { theme } from '@lunit/oui';
18
18
  <ThemeProvider theme={theme}>
19
19
  <CssBaseline />
20
20
  <App />
21
- </ThemeProvider>
21
+ </ThemeProvider>;
22
22
  ```
23
23
 
24
24
  ## Import paths
25
25
 
26
26
  ```ts
27
27
  import { Button, Dialog, TextField } from '@lunit/oui'; // components
28
- import { ArrowDoubleDown } from '@lunit/oui/icons'; // icons
28
+ import { ArrowDoubleDown } from '@lunit/oui/icons'; // icons
29
29
  import { theme, palette, typography, spacing } from '@lunit/oui'; // theme & tokens
30
30
  ```
31
31
 
@@ -37,54 +37,58 @@ import { theme, palette, typography, spacing } from '@lunit/oui'; // theme & tok
37
37
 
38
38
  ### Input / Form
39
39
 
40
- | Component | Purpose | Key props |
41
- |---|---|---|
42
- | **Button** | Trigger actions. Supports label/icon buttons and loading | `variant: 'contained' \| 'ghost' \| 'outlined'`, `color: 'primary' \| 'secondary' \| 'error'`, `size: 'small' \| 'medium' \| 'large'`, `label`, `icon`, `loading` |
43
- | **TextField** / **BaseTextField** | Text input | extends MUI TextField |
44
- | **Checkbox** | Checkbox | — |
45
- | **Radio** | Radio button | — |
46
- | **Toggle** | on/off switch | — |
47
- | **Dropdown** | Selection dropdown | — |
48
- | **DatePicker** | Date selection (based on `@mui/x-date-pickers`) | |
49
- | **FileDnDZone** | File drag-and-drop area | — |
50
- | **UploadManager** | Upload progress/management UI | — |
40
+ | Component | Purpose | Key props |
41
+ | --------------------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
42
+ | **Button** | Trigger actions. Supports label/icon buttons and loading | `variant: 'contained' \| 'ghost' \| 'outlined'`, `color: 'primary' \| 'secondary' \| 'error'`, `size: 'small' \| 'medium' \| 'large'`, `label`, `icon`, `loading` |
43
+ | **TextField** / **BaseTextField** | Text input | extends MUI TextField |
44
+ | **Checkbox** | Checkbox | — |
45
+ | **Radio** | Radio button | — |
46
+ | **Toggle** | on/off switch | — |
47
+ | **Dropdown** | Selection dropdown | — |
48
+ | **Autocomplete** | Multi-select chip input with clear button + loading | `placeholder`, `error`, `helperText`, `loading`, `noOptionsText`, `onDelete`, `onClearButtonClick` |
49
+ | **DatePicker** | Date selection (based on `@mui/x-date-pickers`) | — |
50
+ | **FileDnDZone** | File drag-and-drop area | — |
51
+ | **UploadManager** | Upload progress/management UI | — |
51
52
 
52
53
  ### Display / Layout
53
54
 
54
- | Component | Purpose | Key props |
55
- |---|---|---|
56
- | **Card** | Content card container | `size: 'small' \| 'large'` |
57
- | **Divider** | Separator line | `orientation: 'horizontal' \| 'vertical'` |
58
- | **List** | List | `size: 'small' \| 'medium' \| 'large'` |
59
- | **DataTable** | Data table (based on `@mui/x-data-grid`) | — |
60
- | **EllipsisTypography** | Text with ellipsis (...) truncation | — |
61
- | **ProductLabel** | Product label badge | — |
62
- | **NoMatchContainer** | Empty state (e.g. no search results) | — |
55
+ | Component | Purpose | Key props |
56
+ | ---------------------- | ----------------------------------------------- | ------------------------------------------------------- |
57
+ | **Card** | Content card container | `size: 'small' \| 'large'` |
58
+ | **Divider** | Separator line | `orientation: 'horizontal' \| 'vertical'` |
59
+ | **Drawer** | Side drawer with collapsed/expanded/wide widths | `open`, `wide`, `closedWidth`, `openWidth`, `wideWidth` |
60
+ | **Collapse** | Expand/collapse transition wrapper | extends MUI Collapse (`in`, `orientation`, `timeout`) |
61
+ | **List** | List | `size: 'small' \| 'medium' \| 'large'` |
62
+ | **DataTable** | Data table (based on `@mui/x-data-grid`) | — |
63
+ | **EllipsisTypography** | Text with ellipsis (...) truncation | — |
64
+ | **ProductLabel** | Product label badge | — |
65
+ | **NoMatchContainer** | Empty state (e.g. no search results) | — |
63
66
 
64
67
  ### Feedback / Overlay
65
68
 
66
- | Component | Purpose | Key props |
67
- |---|---|---|
68
- | **Alert** | Inline notification (info/success/error/warning) | — |
69
- | **Dialog** | Modal dialog | — |
70
- | **Tooltip** | Tooltip | `size: 'small' \| 'large'`, `placement` |
71
- | **Progress** | Progress indicator (Circular/Linear) | `CircularProgress`: `size`, `circleColor` |
72
- | **LoadingIndicator** | Loading spinner | |
73
- | **Chip** | Chip/tag | `preset` (ChipsPreset) |
69
+ | Component | Purpose | Key props |
70
+ | -------------------- | ------------------------------------------------ | -------------------------------------------------------- |
71
+ | **Alert** | Inline notification (info/success/error/warning) | — |
72
+ | **Dialog** | Modal dialog | — |
73
+ | **Popover** | Anchored overlay with tokenized paper styling | extends MUI Popover (`open`, `anchorEl`, `anchorOrigin`) |
74
+ | **Tooltip** | Tooltip | `size: 'small' \| 'large'`, `placement` |
75
+ | **Progress** | Progress indicator (Circular/Linear) | `CircularProgress`: `size`, `circleColor` |
76
+ | **LoadingIndicator** | Loading spinner | |
77
+ | **Chip** | Chip/tag | `preset` (ChipsPreset) |
74
78
 
75
79
  ### Navigation / Structure
76
80
 
77
- | Component | Purpose | Key props |
78
- |---|---|---|
79
- | **Menu** | Menu | `size: 'small' \| 'medium'` |
80
- | **Pagination** | Pagination | `size: number` |
81
- | **Stepper** | Step progress indicator | — |
82
- | **TabbedPanel** | Tab panel | `size: 'small' \| 'medium'`, `variant: 'normal' \| 'toggle'` |
81
+ | Component | Purpose | Key props |
82
+ | --------------- | ----------------------- | ------------------------------------------------------------ |
83
+ | **Menu** | Menu | `size: 'small' \| 'medium'` |
84
+ | **Pagination** | Pagination | `size: number` |
85
+ | **Stepper** | Step progress indicator | — |
86
+ | **TabbedPanel** | Tab panel | `size: 'small' \| 'medium'`, `variant: 'normal' \| 'toggle'` |
83
87
 
84
88
  ### Utility
85
89
 
86
- | Component | Purpose |
87
- |---|---|
90
+ | Component | Purpose |
91
+ | ------------------ | ----------------------------- |
88
92
  | **ResizeObserver** | Size-change detection wrapper |
89
93
 
90
94
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunit/oui",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "validate-branch-name": {
5
5
  "pattern": "^(main|develop)|(feature|fix|release|hotfix|qe)/.+$",
6
6
  "errorMsg": "The branch name is not correct. Please check the pattern. (ex. feature/add-something)"
@@ -225,20 +225,22 @@
225
225
  ],
226
226
  "exports": {
227
227
  ".": {
228
+ "types": "./dist/types/index.d.ts",
228
229
  "import": "./dist/index.js",
229
230
  "module": "./dist/index.js",
230
231
  "default": "./dist/index.js"
231
232
  },
232
233
  "./*": {
234
+ "types": "./dist/types/components/*/index.d.ts",
233
235
  "import": "./dist/components/*/index.js",
234
236
  "module": "./dist/components/*/index.js",
235
237
  "default": "./dist/components/*/index.js"
236
238
  },
237
239
  "./icons": {
240
+ "types": "./dist/types/icons/index.d.ts",
238
241
  "import": "./dist/icons/index.js",
239
242
  "module": "./dist/icons/index.js",
240
- "default": "./dist/icons/index.js",
241
- "types": "./dist/types/icons/index.d.ts"
243
+ "default": "./dist/icons/index.js"
242
244
  }
243
245
  },
244
246
  "typesVersions": {