@lattice-ui/accordion 0.5.0-next.2 → 0.5.0-next.3
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.
|
@@ -8,60 +8,104 @@ local _motion = TS.import(script, TS.getModule(script, "@lattice-ui", "motion").
|
|
|
8
8
|
local createSurfaceRevealRecipe = _motion.createSurfaceRevealRecipe
|
|
9
9
|
local usePresenceMotionController = _motion.usePresenceMotionController
|
|
10
10
|
local useAccordionItemContext = TS.import(script, script.Parent, "context").useAccordionItemContext
|
|
11
|
+
local function getImplRestProps(props)
|
|
12
|
+
local restProps = {}
|
|
13
|
+
for rawKey, value in pairs(props) do
|
|
14
|
+
if not (type(rawKey) == "string") then
|
|
15
|
+
continue
|
|
16
|
+
end
|
|
17
|
+
if rawKey == "present" or rawKey == "forceMount" or rawKey == "transition" or rawKey == "onExitComplete" or rawKey == "asChild" or rawKey == "children" then
|
|
18
|
+
continue
|
|
19
|
+
end
|
|
20
|
+
restProps[rawKey] = value
|
|
21
|
+
end
|
|
22
|
+
return restProps
|
|
23
|
+
end
|
|
24
|
+
local function getContentRestProps(props)
|
|
25
|
+
local restProps = {}
|
|
26
|
+
for rawKey, value in pairs(props) do
|
|
27
|
+
if not (type(rawKey) == "string") then
|
|
28
|
+
continue
|
|
29
|
+
end
|
|
30
|
+
if rawKey == "asChild" or rawKey == "forceMount" or rawKey == "transition" or rawKey == "children" then
|
|
31
|
+
continue
|
|
32
|
+
end
|
|
33
|
+
restProps[rawKey] = value
|
|
34
|
+
end
|
|
35
|
+
return restProps
|
|
36
|
+
end
|
|
11
37
|
local function AccordionContentImpl(props)
|
|
38
|
+
local present = props.present
|
|
39
|
+
local forceMount = props.forceMount
|
|
40
|
+
local transition = props.transition
|
|
41
|
+
local onExitComplete = props.onExitComplete
|
|
42
|
+
local asChild = props.asChild
|
|
43
|
+
local children = props.children
|
|
44
|
+
local restProps = getImplRestProps(props)
|
|
12
45
|
local defaultTransition = React.useMemo(function()
|
|
13
46
|
return createSurfaceRevealRecipe()
|
|
14
47
|
end, {})
|
|
15
|
-
local config =
|
|
48
|
+
local config = transition or defaultTransition
|
|
16
49
|
local motion = usePresenceMotionController({
|
|
17
|
-
present =
|
|
18
|
-
forceMount =
|
|
50
|
+
present = present,
|
|
51
|
+
forceMount = forceMount,
|
|
19
52
|
config = config,
|
|
20
|
-
onExitComplete =
|
|
53
|
+
onExitComplete = onExitComplete,
|
|
21
54
|
})
|
|
22
55
|
local mounted = motion.mounted
|
|
23
56
|
local visible = mounted and (motion.present or motion.phase ~= "exited")
|
|
24
57
|
if not mounted then
|
|
25
58
|
return nil
|
|
26
59
|
end
|
|
27
|
-
if
|
|
28
|
-
local child =
|
|
29
|
-
if not React.isValidElement(child) then
|
|
30
|
-
error("[AccordionContent] `asChild` requires a child element.")
|
|
60
|
+
if asChild then
|
|
61
|
+
local child = children
|
|
62
|
+
if React.Children.count(children) ~= 1 or not React.isValidElement(child) then
|
|
63
|
+
error("[AccordionContent] `asChild` requires a single child element.")
|
|
31
64
|
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
65
|
+
local _attributes = table.clone(restProps)
|
|
66
|
+
setmetatable(_attributes, nil)
|
|
67
|
+
_attributes.Visible = visible
|
|
68
|
+
_attributes.ref = motion.ref
|
|
69
|
+
return React.createElement(Slot, _attributes, child)
|
|
36
70
|
end
|
|
37
|
-
|
|
71
|
+
local _attributes = {
|
|
38
72
|
BackgroundColor3 = Color3.fromRGB(35, 41, 54),
|
|
39
73
|
BorderSizePixel = 0,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
74
|
+
}
|
|
75
|
+
for _k, _v in restProps do
|
|
76
|
+
_attributes[_k] = _v
|
|
77
|
+
end
|
|
78
|
+
_attributes.Visible = visible
|
|
79
|
+
_attributes.ref = motion.ref
|
|
80
|
+
return React.createElement("frame", _attributes, children)
|
|
44
81
|
end
|
|
45
82
|
local function AccordionContent(props)
|
|
46
83
|
local itemContext = useAccordionItemContext()
|
|
47
|
-
local
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
84
|
+
local asChild = props.asChild
|
|
85
|
+
local forceMount = props.forceMount
|
|
86
|
+
local transition = props.transition
|
|
87
|
+
local children = props.children
|
|
88
|
+
local restProps = getContentRestProps(props)
|
|
89
|
+
local shouldForceMount = forceMount == true
|
|
90
|
+
if shouldForceMount then
|
|
91
|
+
local _attributes = table.clone(restProps)
|
|
92
|
+
setmetatable(_attributes, nil)
|
|
93
|
+
_attributes.asChild = asChild
|
|
94
|
+
_attributes.forceMount = true
|
|
95
|
+
_attributes.present = itemContext.open
|
|
96
|
+
_attributes.transition = transition
|
|
97
|
+
return React.createElement(AccordionContentImpl, _attributes, children)
|
|
55
98
|
end
|
|
56
99
|
return React.createElement(Presence, {
|
|
57
100
|
present = itemContext.open,
|
|
58
101
|
render = function(state)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
102
|
+
local _attributes = table.clone(restProps)
|
|
103
|
+
setmetatable(_attributes, nil)
|
|
104
|
+
_attributes.asChild = asChild
|
|
105
|
+
_attributes.onExitComplete = state.onExitComplete
|
|
106
|
+
_attributes.present = state.isPresent
|
|
107
|
+
_attributes.transition = transition
|
|
108
|
+
return React.createElement(AccordionContentImpl, _attributes, children)
|
|
65
109
|
end,
|
|
66
110
|
})
|
|
67
111
|
end
|
package/out/Accordion/types.d.ts
CHANGED
|
@@ -33,9 +33,11 @@ export type AccordionTriggerProps = {
|
|
|
33
33
|
asChild?: boolean;
|
|
34
34
|
children?: React.ReactElement;
|
|
35
35
|
};
|
|
36
|
+
type AccordionContentGuiProps = React.Attributes & Record<string, unknown>;
|
|
36
37
|
export type AccordionContentProps = {
|
|
37
38
|
asChild?: boolean;
|
|
38
39
|
forceMount?: boolean;
|
|
39
40
|
transition?: PresenceMotionConfig;
|
|
40
41
|
children?: React.ReactNode;
|
|
41
|
-
};
|
|
42
|
+
} & AccordionContentGuiProps;
|
|
43
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lattice-ui/accordion",
|
|
3
|
-
"version": "0.5.0-next.
|
|
3
|
+
"version": "0.5.0-next.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "out/init.luau",
|
|
6
6
|
"types": "out/index.d.ts",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"url": "https://github.com/astra-void/lattice-ui.git"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@lattice-ui/core": "0.5.0-next.
|
|
20
|
-
"@lattice-ui/
|
|
21
|
-
"@lattice-ui/
|
|
19
|
+
"@lattice-ui/core": "0.5.0-next.3",
|
|
20
|
+
"@lattice-ui/layer": "0.5.0-next.3",
|
|
21
|
+
"@lattice-ui/motion": "0.5.0-next.3"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@rbxts/react": "17.3.7-ts.1",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "rbxtsc -p tsconfig.json",
|
|
33
|
-
"lint": "
|
|
34
|
-
"lint:fix": "
|
|
33
|
+
"lint": "biome check src",
|
|
34
|
+
"lint:fix": "biome check src --write --unsafe",
|
|
35
35
|
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
36
36
|
"watch": "rbxtsc -p tsconfig.json -w"
|
|
37
37
|
}
|
|
@@ -1,25 +1,76 @@
|
|
|
1
1
|
import { React, Slot } from "@lattice-ui/core";
|
|
2
2
|
import { Presence } from "@lattice-ui/layer";
|
|
3
|
-
import { createSurfaceRevealRecipe,
|
|
3
|
+
import { createSurfaceRevealRecipe, usePresenceMotionController } from "@lattice-ui/motion";
|
|
4
4
|
import { useAccordionItemContext } from "./context";
|
|
5
5
|
import type { AccordionContentProps } from "./types";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
type GuiPropBag = React.Attributes & Record<string, unknown>;
|
|
8
|
+
|
|
9
|
+
type AccordionContentImplProps = AccordionContentProps & {
|
|
8
10
|
present: boolean;
|
|
9
|
-
forceMount?: boolean;
|
|
10
|
-
transition?: PresenceMotionConfig;
|
|
11
11
|
onExitComplete?: () => void;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function getImplRestProps(props: AccordionContentImplProps): GuiPropBag {
|
|
15
|
+
const restProps: GuiPropBag = {};
|
|
16
|
+
|
|
17
|
+
for (const [rawKey, value] of pairs(props as Record<string, unknown>)) {
|
|
18
|
+
if (!typeIs(rawKey, "string")) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (
|
|
23
|
+
rawKey === "present" ||
|
|
24
|
+
rawKey === "forceMount" ||
|
|
25
|
+
rawKey === "transition" ||
|
|
26
|
+
rawKey === "onExitComplete" ||
|
|
27
|
+
rawKey === "asChild" ||
|
|
28
|
+
rawKey === "children"
|
|
29
|
+
) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
restProps[rawKey] = value;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return restProps;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getContentRestProps(props: AccordionContentProps): GuiPropBag {
|
|
40
|
+
const restProps: GuiPropBag = {};
|
|
41
|
+
|
|
42
|
+
for (const [rawKey, value] of pairs(props as Record<string, unknown>)) {
|
|
43
|
+
if (!typeIs(rawKey, "string")) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (rawKey === "asChild" || rawKey === "forceMount" || rawKey === "transition" || rawKey === "children") {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
restProps[rawKey] = value;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return restProps;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function AccordionContentImpl(props: AccordionContentImplProps) {
|
|
58
|
+
const present = props.present;
|
|
59
|
+
const forceMount = props.forceMount;
|
|
60
|
+
const transition = props.transition;
|
|
61
|
+
const onExitComplete = props.onExitComplete;
|
|
62
|
+
const asChild = props.asChild;
|
|
63
|
+
const children = props.children;
|
|
64
|
+
const restProps = getImplRestProps(props);
|
|
65
|
+
|
|
15
66
|
const defaultTransition = React.useMemo(() => createSurfaceRevealRecipe(), []);
|
|
16
|
-
const config =
|
|
67
|
+
const config = transition ?? defaultTransition;
|
|
17
68
|
|
|
18
69
|
const motion = usePresenceMotionController<Frame>({
|
|
19
|
-
present
|
|
20
|
-
forceMount
|
|
70
|
+
present,
|
|
71
|
+
forceMount,
|
|
21
72
|
config,
|
|
22
|
-
onExitComplete
|
|
73
|
+
onExitComplete,
|
|
23
74
|
});
|
|
24
75
|
|
|
25
76
|
const mounted = motion.mounted;
|
|
@@ -29,14 +80,14 @@ function AccordionContentImpl(props: {
|
|
|
29
80
|
return undefined;
|
|
30
81
|
}
|
|
31
82
|
|
|
32
|
-
if (
|
|
33
|
-
const child =
|
|
34
|
-
if (!React.isValidElement(child)) {
|
|
35
|
-
error("[AccordionContent] `asChild` requires a child element.");
|
|
83
|
+
if (asChild) {
|
|
84
|
+
const child = children;
|
|
85
|
+
if (React.Children.count(children) !== 1 || !React.isValidElement(child)) {
|
|
86
|
+
error("[AccordionContent] `asChild` requires a single child element.");
|
|
36
87
|
}
|
|
37
88
|
|
|
38
89
|
return (
|
|
39
|
-
<Slot Visible={visible} ref={motion.ref}>
|
|
90
|
+
<Slot {...restProps} Visible={visible} ref={motion.ref}>
|
|
40
91
|
{child}
|
|
41
92
|
</Slot>
|
|
42
93
|
);
|
|
@@ -46,28 +97,35 @@ function AccordionContentImpl(props: {
|
|
|
46
97
|
<frame
|
|
47
98
|
BackgroundColor3={Color3.fromRGB(35, 41, 54)}
|
|
48
99
|
BorderSizePixel={0}
|
|
49
|
-
|
|
100
|
+
{...restProps}
|
|
50
101
|
Visible={visible}
|
|
51
102
|
ref={motion.ref}
|
|
52
103
|
>
|
|
53
|
-
{
|
|
104
|
+
{children}
|
|
54
105
|
</frame>
|
|
55
106
|
);
|
|
56
107
|
}
|
|
57
108
|
|
|
58
109
|
export function AccordionContent(props: AccordionContentProps) {
|
|
59
110
|
const itemContext = useAccordionItemContext();
|
|
60
|
-
const
|
|
111
|
+
const asChild = props.asChild;
|
|
112
|
+
const forceMount = props.forceMount;
|
|
113
|
+
const transition = props.transition;
|
|
114
|
+
const children = props.children;
|
|
115
|
+
const restProps = getContentRestProps(props);
|
|
116
|
+
|
|
117
|
+
const shouldForceMount = forceMount === true;
|
|
61
118
|
|
|
62
|
-
if (
|
|
119
|
+
if (shouldForceMount) {
|
|
63
120
|
return (
|
|
64
121
|
<AccordionContentImpl
|
|
65
|
-
|
|
122
|
+
{...restProps}
|
|
123
|
+
asChild={asChild}
|
|
66
124
|
forceMount={true}
|
|
67
125
|
present={itemContext.open}
|
|
68
|
-
transition={
|
|
126
|
+
transition={transition}
|
|
69
127
|
>
|
|
70
|
-
{
|
|
128
|
+
{children}
|
|
71
129
|
</AccordionContentImpl>
|
|
72
130
|
);
|
|
73
131
|
}
|
|
@@ -77,12 +135,13 @@ export function AccordionContent(props: AccordionContentProps) {
|
|
|
77
135
|
present={itemContext.open}
|
|
78
136
|
render={(state) => (
|
|
79
137
|
<AccordionContentImpl
|
|
80
|
-
|
|
138
|
+
{...restProps}
|
|
139
|
+
asChild={asChild}
|
|
81
140
|
onExitComplete={state.onExitComplete}
|
|
82
141
|
present={state.isPresent}
|
|
83
|
-
transition={
|
|
142
|
+
transition={transition}
|
|
84
143
|
>
|
|
85
|
-
{
|
|
144
|
+
{children}
|
|
86
145
|
</AccordionContentImpl>
|
|
87
146
|
)}
|
|
88
147
|
/>
|
package/src/Accordion/types.ts
CHANGED
|
@@ -40,9 +40,11 @@ export type AccordionTriggerProps = {
|
|
|
40
40
|
children?: React.ReactElement;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
type AccordionContentGuiProps = React.Attributes & Record<string, unknown>;
|
|
44
|
+
|
|
43
45
|
export type AccordionContentProps = {
|
|
44
46
|
asChild?: boolean;
|
|
45
47
|
forceMount?: boolean;
|
|
46
48
|
transition?: PresenceMotionConfig;
|
|
47
49
|
children?: React.ReactNode;
|
|
48
|
-
};
|
|
50
|
+
} & AccordionContentGuiProps;
|