@udixio/ui-react 2.5.2 → 2.7.0
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/CHANGELOG.md +41 -0
- package/dist/index.cjs +2 -2
- package/dist/index.js +2566 -2264
- package/dist/lib/components/Button.d.ts.map +1 -1
- package/dist/lib/components/Card.d.ts.map +1 -1
- package/dist/lib/components/Carousel.d.ts +0 -2
- package/dist/lib/components/Carousel.d.ts.map +1 -1
- package/dist/lib/components/Fab.d.ts +1 -1
- package/dist/lib/components/Fab.d.ts.map +1 -1
- package/dist/lib/components/FabMenu.d.ts +9 -0
- package/dist/lib/components/FabMenu.d.ts.map +1 -0
- package/dist/lib/components/IconButton.d.ts.map +1 -1
- package/dist/lib/components/NavigationRail.d.ts.map +1 -1
- package/dist/lib/components/NavigationRailItem.d.ts.map +1 -1
- package/dist/lib/components/Tab.d.ts.map +1 -1
- package/dist/lib/components/ToolTip.d.ts.map +1 -1
- package/dist/lib/components/index.d.ts +1 -0
- package/dist/lib/components/index.d.ts.map +1 -1
- package/dist/lib/effects/AnimateOnScroll.d.ts.map +1 -1
- package/dist/lib/effects/State.d.ts +26 -0
- package/dist/lib/effects/State.d.ts.map +1 -0
- package/dist/lib/effects/index.d.ts +1 -0
- package/dist/lib/effects/index.d.ts.map +1 -1
- package/dist/lib/effects/ripple/RippleEffect.d.ts.map +1 -1
- package/dist/lib/interfaces/button.interface.d.ts +4 -1
- package/dist/lib/interfaces/button.interface.d.ts.map +1 -1
- package/dist/lib/interfaces/fab-menu.interface.d.ts +12 -0
- package/dist/lib/interfaces/fab-menu.interface.d.ts.map +1 -0
- package/dist/lib/interfaces/fab.interface.d.ts +2 -2
- package/dist/lib/interfaces/fab.interface.d.ts.map +1 -1
- package/dist/lib/interfaces/index.d.ts +1 -0
- package/dist/lib/interfaces/index.d.ts.map +1 -1
- package/dist/lib/interfaces/side-sheet.interface.d.ts +1 -1
- package/dist/lib/interfaces/side-sheet.interface.d.ts.map +1 -1
- package/dist/lib/styles/button.style.d.ts +43 -3
- package/dist/lib/styles/button.style.d.ts.map +1 -1
- package/dist/lib/styles/card.style.d.ts +9 -1
- package/dist/lib/styles/card.style.d.ts.map +1 -1
- package/dist/lib/styles/carousel-item.style.d.ts +11 -1
- package/dist/lib/styles/carousel-item.style.d.ts.map +1 -1
- package/dist/lib/styles/carousel.style.d.ts +16 -1
- package/dist/lib/styles/carousel.style.d.ts.map +1 -1
- package/dist/lib/styles/divider.style.d.ts +8 -2
- package/dist/lib/styles/divider.style.d.ts.map +1 -1
- package/dist/lib/styles/fab-menu.style.d.ts +83 -0
- package/dist/lib/styles/fab-menu.style.d.ts.map +1 -0
- package/dist/lib/styles/fab.style.d.ts +29 -5
- package/dist/lib/styles/fab.style.d.ts.map +1 -1
- package/dist/lib/styles/icon-button.style.d.ts +37 -1
- package/dist/lib/styles/icon-button.style.d.ts.map +1 -1
- package/dist/lib/styles/index.d.ts +2 -0
- package/dist/lib/styles/index.d.ts.map +1 -1
- package/dist/lib/styles/navigation-rail-item.style.d.ts +11 -1
- package/dist/lib/styles/navigation-rail-item.style.d.ts.map +1 -1
- package/dist/lib/styles/navigation-rail.style.d.ts +31 -1
- package/dist/lib/styles/navigation-rail.style.d.ts.map +1 -1
- package/dist/lib/styles/progress-indicator.style.d.ts +12 -1
- package/dist/lib/styles/progress-indicator.style.d.ts.map +1 -1
- package/dist/lib/styles/side-sheet.style.d.ts +20 -3
- package/dist/lib/styles/side-sheet.style.d.ts.map +1 -1
- package/dist/lib/styles/slider.style.d.ts +21 -2
- package/dist/lib/styles/slider.style.d.ts.map +1 -1
- package/dist/lib/styles/snackbar.style.d.ts +14 -3
- package/dist/lib/styles/snackbar.style.d.ts.map +1 -1
- package/dist/lib/styles/switch.style.d.ts +14 -2
- package/dist/lib/styles/switch.style.d.ts.map +1 -1
- package/dist/lib/styles/tab.style.d.ts +12 -2
- package/dist/lib/styles/tab.style.d.ts.map +1 -1
- package/dist/lib/styles/tabs.style.d.ts +17 -2
- package/dist/lib/styles/tabs.style.d.ts.map +1 -1
- package/dist/lib/styles/text-field.style.d.ts +23 -2
- package/dist/lib/styles/text-field.style.d.ts.map +1 -1
- package/dist/lib/styles/tooltip.style.d.ts +20 -3
- package/dist/lib/styles/tooltip.style.d.ts.map +1 -1
- package/dist/lib/utils/styles/get-classname.d.ts +3 -0
- package/dist/lib/utils/styles/get-classname.d.ts.map +1 -1
- package/dist/lib/utils/styles/index.d.ts +1 -0
- package/dist/lib/utils/styles/index.d.ts.map +1 -1
- package/dist/lib/utils/styles/use-classnames.d.ts +6 -0
- package/dist/lib/utils/styles/use-classnames.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/lib/components/Button.tsx +54 -20
- package/src/lib/components/Card.tsx +11 -9
- package/src/lib/components/Carousel.tsx +70 -205
- package/src/lib/components/CarouselItem.tsx +2 -2
- package/src/lib/components/Divider.tsx +2 -2
- package/src/lib/components/Fab.tsx +22 -21
- package/src/lib/components/FabMenu.tsx +229 -0
- package/src/lib/components/IconButton.tsx +24 -30
- package/src/lib/components/NavigationRail.tsx +7 -4
- package/src/lib/components/NavigationRailItem.tsx +13 -4
- package/src/lib/components/ProgressIndicator.tsx +2 -2
- package/src/lib/components/SideSheet.tsx +2 -2
- package/src/lib/components/Slider.tsx +2 -2
- package/src/lib/components/Snackbar.tsx +2 -2
- package/src/lib/components/Switch.tsx +2 -2
- package/src/lib/components/Tab.tsx +11 -11
- package/src/lib/components/Tabs.tsx +2 -2
- package/src/lib/components/TextField.tsx +2 -2
- package/src/lib/components/ToolTip.tsx +9 -3
- package/src/lib/components/index.ts +1 -0
- package/src/lib/effects/AnimateOnScroll.ts +51 -18
- package/src/lib/effects/State.tsx +83 -0
- package/src/lib/effects/index.ts +1 -0
- package/src/lib/effects/ripple/RippleEffect.tsx +40 -27
- package/src/lib/interfaces/button.interface.ts +5 -1
- package/src/lib/interfaces/fab-menu.interface.ts +12 -0
- package/src/lib/interfaces/fab.interface.ts +8 -2
- package/src/lib/interfaces/index.ts +1 -0
- package/src/lib/interfaces/side-sheet.interface.tsx +1 -1
- package/src/lib/styles/button.style.ts +127 -136
- package/src/lib/styles/card.style.ts +22 -17
- package/src/lib/styles/carousel-item.style.ts +23 -9
- package/src/lib/styles/carousel.style.ts +17 -5
- package/src/lib/styles/divider.style.ts +27 -13
- package/src/lib/styles/fab-menu.style.ts +28 -0
- package/src/lib/styles/fab.style.ts +41 -43
- package/src/lib/styles/icon-button.style.ts +160 -149
- package/src/lib/styles/index.ts +2 -0
- package/src/lib/styles/navigation-rail-item.style.ts +49 -40
- package/src/lib/styles/navigation-rail.style.ts +31 -15
- package/src/lib/styles/progress-indicator.style.ts +49 -36
- package/src/lib/styles/side-sheet.style.ts +41 -27
- package/src/lib/styles/slider.style.ts +37 -23
- package/src/lib/styles/snackbar.style.ts +22 -10
- package/src/lib/styles/switch.style.ts +61 -45
- package/src/lib/styles/tab.style.ts +76 -66
- package/src/lib/styles/tabs.style.ts +19 -10
- package/src/lib/styles/text-field.style.ts +108 -97
- package/src/lib/styles/tooltip.style.ts +42 -33
- package/src/lib/utils/styles/get-classname.ts +23 -0
- package/src/lib/utils/styles/index.ts +1 -0
- package/src/lib/utils/styles/use-classnames.ts +25 -0
- package/src/tests/useClassNames.spec.tsx +82 -0
|
@@ -1,37 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
type ClassNameComponent,
|
|
3
|
+
classNames,
|
|
4
|
+
createUseClassNames,
|
|
5
|
+
defaultClassNames,
|
|
6
|
+
} from '../utils';
|
|
7
|
+
import { ToolTipInterface } from '../interfaces';
|
|
8
|
+
|
|
9
|
+
const toolTipConfig: ClassNameComponent<ToolTipInterface> = ({
|
|
10
|
+
position,
|
|
11
|
+
variant,
|
|
12
|
+
}) => ({
|
|
13
|
+
toolTip: classNames(
|
|
14
|
+
' pointer-events-auto w-max z-10 absolute m-1 w-max-content max-w-[312px]',
|
|
15
|
+
{
|
|
16
|
+
'bottom-full left-1/2 -translate-x-1/2': position == 'top',
|
|
17
|
+
'top-full left-1/2 -translate-x-1/2': position == 'bottom',
|
|
18
|
+
'right-full top-1/2 -translate-y-1/2': position == 'left',
|
|
19
|
+
'left-full top-1/2 -translate-y-1/2': position == 'right',
|
|
20
|
+
'bottom-full right-full': position == 'top-left',
|
|
21
|
+
'bottom-full left-full': position == 'top-right',
|
|
22
|
+
'top-full right-full': position == 'bottom-left',
|
|
23
|
+
'top-full left-full': position == 'bottom-right',
|
|
24
|
+
},
|
|
25
|
+
),
|
|
26
|
+
container: classNames(
|
|
27
|
+
'pb-2',
|
|
28
|
+
variant == 'rich' &&
|
|
29
|
+
'bg-surface-container rounded-2xl text-on-surface-container px-4 pt-3 shadow-2',
|
|
30
|
+
variant == 'plain' &&
|
|
31
|
+
'bg-inverse-surface rounded text-inverse-on-surface px-2 py-1',
|
|
32
|
+
),
|
|
33
|
+
actions: classNames('flex gap-10 px-1 mt-2', variant == 'plain' && 'hidden'),
|
|
34
|
+
subHead: classNames('text-title-small mb-1', variant == 'plain' && 'hidden'),
|
|
35
|
+
supportingText: classNames(''),
|
|
36
|
+
});
|
|
3
37
|
|
|
4
38
|
export const toolStyle = defaultClassNames<ToolTipInterface>(
|
|
5
39
|
'toolTip',
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'right-full top-1/2 -translate-y-1/2': position == 'left',
|
|
13
|
-
'left-full top-1/2 -translate-y-1/2': position == 'right',
|
|
14
|
-
'bottom-full right-full': position == 'top-left',
|
|
15
|
-
'bottom-full left-full': position == 'top-right',
|
|
16
|
-
'top-full right-full': position == 'bottom-left',
|
|
17
|
-
'top-full left-full': position == 'bottom-right',
|
|
18
|
-
}
|
|
19
|
-
),
|
|
20
|
-
container: classNames(
|
|
21
|
-
'pb-2',
|
|
22
|
-
variant == 'rich' &&
|
|
23
|
-
'bg-surface-container rounded-2xl text-on-surface-container px-4 pt-3 shadow-2',
|
|
24
|
-
variant == 'plain' &&
|
|
25
|
-
'bg-inverse-surface rounded text-inverse-on-surface px-2 py-1'
|
|
26
|
-
),
|
|
27
|
-
actions: classNames(
|
|
28
|
-
'flex gap-10 px-1 mt-2',
|
|
29
|
-
variant == 'plain' && 'hidden'
|
|
30
|
-
),
|
|
31
|
-
subHead: classNames(
|
|
32
|
-
'text-title-small mb-1',
|
|
33
|
-
variant == 'plain' && 'hidden'
|
|
34
|
-
),
|
|
35
|
-
supportingText: classNames(''),
|
|
36
|
-
})
|
|
40
|
+
toolTipConfig,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
export const useToolTipStyle = createUseClassNames<ToolTipInterface>(
|
|
44
|
+
'toolTip',
|
|
45
|
+
toolTipConfig,
|
|
37
46
|
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
1
2
|
import { ComponentInterface } from '../component';
|
|
2
3
|
import { convertToKebabCase } from '../string';
|
|
3
4
|
import { classnames } from './classnames';
|
|
@@ -71,3 +72,25 @@ export const defaultClassNames = <T extends ComponentInterface>(
|
|
|
71
72
|
states,
|
|
72
73
|
});
|
|
73
74
|
};
|
|
75
|
+
|
|
76
|
+
export const createUseClassNames = <T extends ComponentInterface>(
|
|
77
|
+
element: T['elements'][0],
|
|
78
|
+
defaultClassName: ClassNameComponent<T> | string,
|
|
79
|
+
) => {
|
|
80
|
+
return (
|
|
81
|
+
states: T['states'] & T['props'] & {
|
|
82
|
+
className?: string | ClassNameComponent<T>;
|
|
83
|
+
},
|
|
84
|
+
): Record<T['elements'][number], string> => {
|
|
85
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
86
|
+
return useMemo(
|
|
87
|
+
() =>
|
|
88
|
+
getClassNames<T>({
|
|
89
|
+
classNameList: [states.className, defaultClassName],
|
|
90
|
+
default: element,
|
|
91
|
+
states,
|
|
92
|
+
}),
|
|
93
|
+
[states],
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { ComponentInterface } from '../component';
|
|
3
|
+
import { ClassNameComponent, getClassNames } from './get-classname';
|
|
4
|
+
|
|
5
|
+
export function useClassNames<T extends ComponentInterface>(
|
|
6
|
+
element: T['elements'][0],
|
|
7
|
+
defaultClassName: ClassNameComponent<T> | string,
|
|
8
|
+
states: (T['states'] & T['props']) & { className?: string | ClassNameComponent<T> },
|
|
9
|
+
): Record<T['elements'][number], string> {
|
|
10
|
+
return useMemo(
|
|
11
|
+
() =>
|
|
12
|
+
getClassNames<T>({
|
|
13
|
+
classNameList: [states?.className, defaultClassName],
|
|
14
|
+
default: element,
|
|
15
|
+
states: states as any,
|
|
16
|
+
}),
|
|
17
|
+
[element, defaultClassName, states],
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Documentation note:
|
|
22
|
+
// - This hook centralizes class name merging logic (string or function),
|
|
23
|
+
// prefixes each element key with its kebab-case name, and adds `relative` on the root element by default.
|
|
24
|
+
// - It preserves current order/priority where consumer overrides take precedence over defaults.
|
|
25
|
+
// - Pass overrides via props.className (string or function) — see Button for example usage.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { renderHook } from '@testing-library/react';
|
|
4
|
+
import { useClassNames } from '../lib/utils/styles/use-classnames';
|
|
5
|
+
import type { ComponentInterface } from '../lib/utils/component';
|
|
6
|
+
import type { ClassNameComponent } from '../lib/utils/styles/get-classname';
|
|
7
|
+
|
|
8
|
+
// Minimal fake component interface for testing the hook
|
|
9
|
+
interface TestComp extends ComponentInterface {
|
|
10
|
+
type: 'div';
|
|
11
|
+
elements: ['root', 'label'];
|
|
12
|
+
props: { label?: string };
|
|
13
|
+
states: { active?: boolean };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const defaultConfig: ClassNameComponent<TestComp> = (s) => ({
|
|
17
|
+
root: 'bg-default',
|
|
18
|
+
label: s.active ? 'text-active' : 'text-inactive',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('useClassNames', () => {
|
|
22
|
+
it('merges string default with function override; override wins', () => {
|
|
23
|
+
const override: ClassNameComponent<TestComp> = () => ({
|
|
24
|
+
root: 'px-2 custom-override',
|
|
25
|
+
label: 'text-red-500',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const { result, rerender } = renderHook(
|
|
29
|
+
(props: any) =>
|
|
30
|
+
useClassNames<TestComp>('root', 'bg-default-root', {
|
|
31
|
+
...props,
|
|
32
|
+
className: override,
|
|
33
|
+
}),
|
|
34
|
+
{ initialProps: { active: false } },
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
expect(result.current.root).toContain('root'); // kebab-case prefix
|
|
38
|
+
expect(result.current.root).toContain('relative'); // default relative
|
|
39
|
+
// override precedence should keep both but allow override to win on conflicts; here no conflict
|
|
40
|
+
expect(result.current.root).toContain('custom-override');
|
|
41
|
+
|
|
42
|
+
// label from default function should be present and overridden by override
|
|
43
|
+
// default for inactive: text-inactive, but override sets text-red-500
|
|
44
|
+
// since we didn't include defaultConfig, this ensures hook handles function override w/ string default
|
|
45
|
+
|
|
46
|
+
rerender({ active: true });
|
|
47
|
+
// Memo invalidated due to states change; new value produced
|
|
48
|
+
expect(result.current.root).toContain('custom-override');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('merges function default with string override on default element', () => {
|
|
52
|
+
const { result } = renderHook(() =>
|
|
53
|
+
useClassNames<TestComp>('root', defaultConfig, {
|
|
54
|
+
active: true,
|
|
55
|
+
className: 'p-4',
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
expect(result.current.root).toContain('root');
|
|
59
|
+
expect(result.current.root).toContain('relative');
|
|
60
|
+
expect(result.current.root).toContain('p-4');
|
|
61
|
+
expect(result.current.label).toContain('label');
|
|
62
|
+
expect(result.current.label).toContain('text-active');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('memoizes: same inputs => stable reference', () => {
|
|
66
|
+
const states = { active: false, className: 'm-1' } as any;
|
|
67
|
+
const { result, rerender } = renderHook(
|
|
68
|
+
(p: any) => useClassNames<TestComp>('root', defaultConfig, p.states),
|
|
69
|
+
{ initialProps: { states } },
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const first = result.current;
|
|
73
|
+
rerender({ states }); // same reference
|
|
74
|
+
const second = result.current;
|
|
75
|
+
expect(second).toBe(first);
|
|
76
|
+
|
|
77
|
+
// change shallow reference -> new object allocated
|
|
78
|
+
rerender({ states: { ...states } });
|
|
79
|
+
const third = result.current;
|
|
80
|
+
expect(third).not.toBe(first);
|
|
81
|
+
});
|
|
82
|
+
});
|