@basic-ui/material 1.0.0-alpha.23 → 1.0.0-alpha.25
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/build/cjs/index.js +134 -20
- package/build/cjs/index.js.map +1 -1
- package/build/esm/Badge/Badge.d.ts +2 -2
- package/build/esm/Badge/Badge.js +28 -2
- package/build/esm/Badge/Badge.js.map +1 -1
- package/build/esm/Chip/ButtonChip.d.ts +1 -1
- package/build/esm/NavRail/NavRailItem.d.ts +3 -3
- package/build/esm/NavRail/NavRailItem.js +0 -1
- package/build/esm/NavRail/NavRailItem.js.map +1 -1
- package/build/esm/NavRail/icons/test-icons.d.ts +4 -0
- package/build/esm/NavRail/icons/test-icons.js +42 -0
- package/build/esm/NavRail/icons/test-icons.js.map +1 -0
- package/build/esm/Tab/Tab.d.ts +1 -1
- package/build/esm/Tab/Tab.js +45 -9
- package/build/esm/Tab/Tab.js.map +1 -1
- package/build/esm/Tab/TabList.d.ts +2 -1
- package/build/esm/Tab/TabList.js +5 -2
- package/build/esm/Tab/TabList.js.map +1 -1
- package/build/esm/Tab/context.d.ts +1 -0
- package/build/esm/Tab/context.js +2 -1
- package/build/esm/Tab/context.js.map +1 -1
- package/build/esm/TabIndicator/TabIndicator.d.ts +4 -2
- package/build/esm/TabIndicator/TabIndicator.js +75 -9
- package/build/esm/TabIndicator/TabIndicator.js.map +1 -1
- package/build/esm/Table/TableHead.d.ts +1 -1
- package/build/esm/theme/theme.js +1 -1
- package/build/esm/theme/theme.js.map +1 -1
- package/build/tsconfig-build.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/Badge/Badge.story.tsx +68 -0
- package/src/Badge/Badge.tsx +33 -3
- package/src/NavRail/NavRail.story.tsx +1 -45
- package/src/NavRail/NavRailItem.tsx +0 -1
- package/src/NavRail/icons/test-icons.tsx +46 -0
- package/src/Tab/Tab.story.tsx +170 -14
- package/src/Tab/Tab.tsx +52 -10
- package/src/Tab/TabList.tsx +5 -1
- package/src/Tab/context.ts +2 -0
- package/src/TabIndicator/TabIndicator.tsx +83 -7
- package/src/theme/theme.ts +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
1
2
|
import { forwardRef, useEffect, useRef, useLayoutEffect } from 'react';
|
|
2
3
|
import { rem } from 'polished';
|
|
3
4
|
import { assignMultipleRefs } from '@basic-ui/core';
|
|
@@ -10,16 +11,29 @@ import { EASING_STANDARD } from '../motion';
|
|
|
10
11
|
export interface TabIndicatorProps extends BoxProps {
|
|
11
12
|
selected?: boolean;
|
|
12
13
|
color?: string;
|
|
14
|
+
variant: 'primary' | 'secondary';
|
|
15
|
+
labelRef: RefObject<HTMLParagraphElement | null>;
|
|
13
16
|
}
|
|
14
17
|
|
|
18
|
+
const WIDTH_PROPERTY_NAME = '--indicator-width';
|
|
19
|
+
const SCALE_PROPERTY_NAME = '--indicator-scale';
|
|
20
|
+
|
|
15
21
|
const useEnhancedEffect =
|
|
16
22
|
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
17
23
|
|
|
18
24
|
export const TabIndicator = forwardRef<HTMLDivElement, TabIndicatorProps>(
|
|
19
25
|
function TabIndicator(props, forwardedRef) {
|
|
20
|
-
const {
|
|
26
|
+
const {
|
|
27
|
+
as = 'span',
|
|
28
|
+
selected,
|
|
29
|
+
color = 'primary',
|
|
30
|
+
variant,
|
|
31
|
+
labelRef,
|
|
32
|
+
...otherProps
|
|
33
|
+
} = props;
|
|
21
34
|
const ref = useRef<HTMLSpanElement>(null);
|
|
22
35
|
const { currentIndicator } = useTabIndicatorContext();
|
|
36
|
+
const resizeObserverRef = useRef<ResizeObserver>();
|
|
23
37
|
|
|
24
38
|
useEnhancedEffect(() => {
|
|
25
39
|
if (selected && ref.current) {
|
|
@@ -28,13 +42,28 @@ export const TabIndicator = forwardRef<HTMLDivElement, TabIndicatorProps>(
|
|
|
28
42
|
const previousClientRect =
|
|
29
43
|
currentIndicator.current.getBoundingClientRect();
|
|
30
44
|
const currentClientRect = ref.current.getBoundingClientRect();
|
|
31
|
-
const widthDelta = previousClientRect.width / currentClientRect.width;
|
|
32
45
|
const xPosition = previousClientRect.left - currentClientRect.left;
|
|
33
46
|
|
|
34
47
|
const prevTransition = ref.current.style.transition;
|
|
35
48
|
const prevTransform = ref.current.style.transform;
|
|
36
49
|
ref.current.style.transition = 'none';
|
|
37
|
-
|
|
50
|
+
if (variant === 'primary') {
|
|
51
|
+
const prevWidth =
|
|
52
|
+
currentIndicator.current.style.getPropertyValue(
|
|
53
|
+
WIDTH_PROPERTY_NAME
|
|
54
|
+
);
|
|
55
|
+
const currentWidth =
|
|
56
|
+
ref.current.style.getPropertyValue(WIDTH_PROPERTY_NAME);
|
|
57
|
+
const widthDelta = String(
|
|
58
|
+
parseFloat(prevWidth) / parseFloat(currentWidth)
|
|
59
|
+
);
|
|
60
|
+
ref.current.style.setProperty(SCALE_PROPERTY_NAME, widthDelta);
|
|
61
|
+
ref.current.style.transform = `translateX(${xPosition}px)`;
|
|
62
|
+
} else {
|
|
63
|
+
const widthDelta =
|
|
64
|
+
previousClientRect.width / currentClientRect.width;
|
|
65
|
+
ref.current.style.transform = `translateX(${xPosition}px) scaleX(${widthDelta})`;
|
|
66
|
+
}
|
|
38
67
|
|
|
39
68
|
// Force repaint before updating classes and transform to ensure the transform properly takes effect
|
|
40
69
|
ref.current.getBoundingClientRect();
|
|
@@ -42,26 +71,73 @@ export const TabIndicator = forwardRef<HTMLDivElement, TabIndicatorProps>(
|
|
|
42
71
|
// Restore and let transition do it's magic
|
|
43
72
|
ref.current.style.transition = prevTransition;
|
|
44
73
|
ref.current.style.transform = prevTransform;
|
|
74
|
+
if (variant === 'primary') {
|
|
75
|
+
ref.current.style.setProperty(SCALE_PROPERTY_NAME, '1');
|
|
76
|
+
}
|
|
45
77
|
}
|
|
46
78
|
currentIndicator.current = ref.current;
|
|
47
79
|
}
|
|
48
|
-
}, [selected]);
|
|
80
|
+
}, [selected, variant]);
|
|
81
|
+
|
|
82
|
+
useEnhancedEffect(() => {
|
|
83
|
+
if (variant === 'secondary') {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (labelRef.current && ref.current) {
|
|
88
|
+
const width = labelRef.current.getBoundingClientRect().width;
|
|
89
|
+
ref.current.style.setProperty(WIDTH_PROPERTY_NAME, `${width}px`);
|
|
90
|
+
|
|
91
|
+
if (typeof ResizeObserver === 'function') {
|
|
92
|
+
resizeObserverRef.current ??= new ResizeObserver(([entry]) => {
|
|
93
|
+
if (ref.current) {
|
|
94
|
+
ref.current.style.setProperty(
|
|
95
|
+
WIDTH_PROPERTY_NAME,
|
|
96
|
+
`${entry.contentRect.width}px`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
resizeObserverRef.current?.observe(labelRef.current);
|
|
102
|
+
return () => resizeObserverRef.current?.disconnect();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}, [labelRef, variant]);
|
|
49
106
|
|
|
50
107
|
return (
|
|
51
108
|
<Box
|
|
52
109
|
as={as}
|
|
53
110
|
ref={assignMultipleRefs(ref, forwardedRef)}
|
|
54
|
-
width="100%"
|
|
55
|
-
height={rem(2)}
|
|
56
111
|
__css={{
|
|
57
112
|
bg: color,
|
|
58
113
|
position: 'absolute',
|
|
59
114
|
bottom: 0,
|
|
60
115
|
transform: `scale(1)`,
|
|
61
116
|
opacity: selected ? 1 : 0,
|
|
62
|
-
transformOrigin: 'left',
|
|
63
117
|
transition: `transform .25s ${EASING_STANDARD}`,
|
|
64
118
|
zIndex: 1,
|
|
119
|
+
...(variant === 'secondary'
|
|
120
|
+
? {
|
|
121
|
+
width: '100%',
|
|
122
|
+
height: rem(2),
|
|
123
|
+
}
|
|
124
|
+
: {
|
|
125
|
+
width: '100%',
|
|
126
|
+
'&::before': {
|
|
127
|
+
content: '""',
|
|
128
|
+
width: `var(${WIDTH_PROPERTY_NAME}, 0px)`,
|
|
129
|
+
height: rem(3),
|
|
130
|
+
borderTopLeftRadius: rem(3),
|
|
131
|
+
borderTopRightRadius: rem(3),
|
|
132
|
+
bg: color,
|
|
133
|
+
position: 'absolute',
|
|
134
|
+
transformOrigin: 'center',
|
|
135
|
+
bottom: 0,
|
|
136
|
+
left: '50%',
|
|
137
|
+
transition: `inherit`,
|
|
138
|
+
transform: `translateX(-50%) scaleX(var(${SCALE_PROPERTY_NAME}, 1))}`,
|
|
139
|
+
},
|
|
140
|
+
}),
|
|
65
141
|
}}
|
|
66
142
|
{...otherProps}
|
|
67
143
|
/>
|
package/src/theme/theme.ts
CHANGED
|
@@ -176,7 +176,7 @@ export const theme = {
|
|
|
176
176
|
'title-small': font('plain', 20, 14, 0.1, 500),
|
|
177
177
|
'label-large': font('plain', 20, 14, 0.1, 500),
|
|
178
178
|
'label-medium': font('plain', 16, 12, 0.5, 500),
|
|
179
|
-
'label-small': font('plain',
|
|
179
|
+
'label-small': font('plain', 15, 11, 0.5, 500),
|
|
180
180
|
'body-large': font('plain', 24, 16, 0.5, 400),
|
|
181
181
|
'body-medium': font('plain', 20, 14, 0.25, 400),
|
|
182
182
|
'body-small': font('plain', 16, 12, 0.4, 400),
|