@lattice-ui/accordion 0.3.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/README.md +18 -0
- package/out/Accordion/AccordionContent.d.ts +3 -0
- package/out/Accordion/AccordionContent.luau +31 -0
- package/out/Accordion/AccordionHeader.d.ts +3 -0
- package/out/Accordion/AccordionHeader.luau +22 -0
- package/out/Accordion/AccordionItem.d.ts +3 -0
- package/out/Accordion/AccordionItem.luau +41 -0
- package/out/Accordion/AccordionRoot.d.ts +4 -0
- package/out/Accordion/AccordionRoot.luau +68 -0
- package/out/Accordion/AccordionTrigger.d.ts +3 -0
- package/out/Accordion/AccordionTrigger.luau +70 -0
- package/out/Accordion/context.d.ts +4 -0
- package/out/Accordion/context.luau +15 -0
- package/out/Accordion/state.d.ts +3 -0
- package/out/Accordion/state.luau +65 -0
- package/out/Accordion/types.d.ts +41 -0
- package/out/Accordion/types.luau +2 -0
- package/out/index.d.ts +15 -0
- package/out/init.luau +20 -0
- package/package.json +24 -0
- package/src/Accordion/AccordionContent.tsx +32 -0
- package/src/Accordion/AccordionHeader.tsx +19 -0
- package/src/Accordion/AccordionItem.tsx +39 -0
- package/src/Accordion/AccordionRoot.tsx +54 -0
- package/src/Accordion/AccordionTrigger.tsx +76 -0
- package/src/Accordion/context.ts +8 -0
- package/src/Accordion/state.ts +58 -0
- package/src/Accordion/types.ts +48 -0
- package/src/index.ts +25 -0
- package/tsconfig.json +16 -0
- package/tsconfig.typecheck.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @lattice-ui/accordion
|
|
2
|
+
|
|
3
|
+
Headless accordion primitives for Roblox UI with single and multiple disclosure modes.
|
|
4
|
+
|
|
5
|
+
## Exports
|
|
6
|
+
|
|
7
|
+
- `Accordion`
|
|
8
|
+
- `Accordion.Root`
|
|
9
|
+
- `Accordion.Item`
|
|
10
|
+
- `Accordion.Header`
|
|
11
|
+
- `Accordion.Trigger`
|
|
12
|
+
- `Accordion.Content`
|
|
13
|
+
|
|
14
|
+
## Notes
|
|
15
|
+
|
|
16
|
+
- Supports `type="single" | "multiple"`.
|
|
17
|
+
- Supports controlled/uncontrolled `value`.
|
|
18
|
+
- Keyboard navigation is integrated with roving focus.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local Slot = _core.Slot
|
|
6
|
+
local useAccordionItemContext = TS.import(script, script.Parent, "context").useAccordionItemContext
|
|
7
|
+
local function AccordionContent(props)
|
|
8
|
+
local itemContext = useAccordionItemContext()
|
|
9
|
+
local forceMount = props.forceMount == true
|
|
10
|
+
if not itemContext.open and not forceMount then
|
|
11
|
+
return nil
|
|
12
|
+
end
|
|
13
|
+
if props.asChild then
|
|
14
|
+
local child = props.children
|
|
15
|
+
if not React.isValidElement(child) then
|
|
16
|
+
error("[AccordionContent] `asChild` requires a child element.")
|
|
17
|
+
end
|
|
18
|
+
return React.createElement(Slot, {
|
|
19
|
+
Visible = itemContext.open,
|
|
20
|
+
}, child)
|
|
21
|
+
end
|
|
22
|
+
return React.createElement("frame", {
|
|
23
|
+
BackgroundColor3 = Color3.fromRGB(35, 41, 54),
|
|
24
|
+
BorderSizePixel = 0,
|
|
25
|
+
Size = UDim2.fromOffset(260, 44),
|
|
26
|
+
Visible = itemContext.open,
|
|
27
|
+
}, props.children)
|
|
28
|
+
end
|
|
29
|
+
return {
|
|
30
|
+
AccordionContent = AccordionContent,
|
|
31
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local Slot = _core.Slot
|
|
6
|
+
local function AccordionHeader(props)
|
|
7
|
+
if props.asChild then
|
|
8
|
+
local child = props.children
|
|
9
|
+
if not child then
|
|
10
|
+
error("[AccordionHeader] `asChild` requires a child element.")
|
|
11
|
+
end
|
|
12
|
+
return React.createElement(Slot, nil, child)
|
|
13
|
+
end
|
|
14
|
+
return React.createElement("frame", {
|
|
15
|
+
BackgroundTransparency = 1,
|
|
16
|
+
BorderSizePixel = 0,
|
|
17
|
+
Size = UDim2.fromOffset(260, 34),
|
|
18
|
+
}, props.children)
|
|
19
|
+
end
|
|
20
|
+
return {
|
|
21
|
+
AccordionHeader = AccordionHeader,
|
|
22
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local Slot = _core.Slot
|
|
6
|
+
local _context = TS.import(script, script.Parent, "context")
|
|
7
|
+
local AccordionItemContextProvider = _context.AccordionItemContextProvider
|
|
8
|
+
local useAccordionContext = _context.useAccordionContext
|
|
9
|
+
local function AccordionItem(props)
|
|
10
|
+
local accordionContext = useAccordionContext()
|
|
11
|
+
local _openValues = accordionContext.openValues
|
|
12
|
+
local _value = props.value
|
|
13
|
+
local open = table.find(_openValues, _value) ~= nil
|
|
14
|
+
local disabled = props.disabled == true
|
|
15
|
+
local contextValue = React.useMemo(function()
|
|
16
|
+
return {
|
|
17
|
+
value = props.value,
|
|
18
|
+
open = open,
|
|
19
|
+
disabled = disabled,
|
|
20
|
+
}
|
|
21
|
+
end, { disabled, open, props.value })
|
|
22
|
+
if props.asChild then
|
|
23
|
+
local child = props.children
|
|
24
|
+
if not React.isValidElement(child) then
|
|
25
|
+
error("[AccordionItem] `asChild` requires a child element.")
|
|
26
|
+
end
|
|
27
|
+
return React.createElement(AccordionItemContextProvider, {
|
|
28
|
+
value = contextValue,
|
|
29
|
+
}, React.createElement(Slot, nil, child))
|
|
30
|
+
end
|
|
31
|
+
return React.createElement(AccordionItemContextProvider, {
|
|
32
|
+
value = contextValue,
|
|
33
|
+
}, React.createElement("frame", {
|
|
34
|
+
BackgroundTransparency = 1,
|
|
35
|
+
BorderSizePixel = 0,
|
|
36
|
+
Size = UDim2.fromOffset(260, 80),
|
|
37
|
+
}, props.children))
|
|
38
|
+
end
|
|
39
|
+
return {
|
|
40
|
+
AccordionItem = AccordionItem,
|
|
41
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local useControllableState = _core.useControllableState
|
|
6
|
+
local RovingFocusGroup = TS.import(script, TS.getModule(script, "@lattice-ui", "focus").out).RovingFocusGroup
|
|
7
|
+
local AccordionContextProvider = TS.import(script, script.Parent, "context").AccordionContextProvider
|
|
8
|
+
local _state = TS.import(script, script.Parent, "state")
|
|
9
|
+
local nextAccordionValues = _state.nextAccordionValues
|
|
10
|
+
local normalizeAccordionValue = _state.normalizeAccordionValue
|
|
11
|
+
local function AccordionRoot(props)
|
|
12
|
+
local accordionType = props.type or "single"
|
|
13
|
+
local _condition = props.loop
|
|
14
|
+
if _condition == nil then
|
|
15
|
+
_condition = true
|
|
16
|
+
end
|
|
17
|
+
local loop = _condition
|
|
18
|
+
local _condition_1 = props.collapsible
|
|
19
|
+
if _condition_1 == nil then
|
|
20
|
+
_condition_1 = false
|
|
21
|
+
end
|
|
22
|
+
local collapsible = _condition_1
|
|
23
|
+
local _condition_2 = props.defaultValue
|
|
24
|
+
if _condition_2 == nil then
|
|
25
|
+
_condition_2 = (if accordionType == "single" then "" else {})
|
|
26
|
+
end
|
|
27
|
+
local defaultValue = _condition_2
|
|
28
|
+
local _binding = useControllableState({
|
|
29
|
+
value = props.value,
|
|
30
|
+
defaultValue = defaultValue,
|
|
31
|
+
onChange = props.onValueChange,
|
|
32
|
+
})
|
|
33
|
+
local rawValue = _binding[1]
|
|
34
|
+
local setRawValue = _binding[2]
|
|
35
|
+
local openValues = normalizeAccordionValue(accordionType, rawValue)
|
|
36
|
+
local toggleItem = React.useCallback(function(candidateValue)
|
|
37
|
+
local nextValues = nextAccordionValues(accordionType, openValues, candidateValue, collapsible)
|
|
38
|
+
if accordionType == "single" then
|
|
39
|
+
local _condition_3 = nextValues[1]
|
|
40
|
+
if _condition_3 == nil then
|
|
41
|
+
_condition_3 = ""
|
|
42
|
+
end
|
|
43
|
+
setRawValue(_condition_3)
|
|
44
|
+
return nil
|
|
45
|
+
end
|
|
46
|
+
setRawValue(nextValues)
|
|
47
|
+
end, { accordionType, collapsible, openValues, setRawValue })
|
|
48
|
+
local contextValue = React.useMemo(function()
|
|
49
|
+
return {
|
|
50
|
+
type = accordionType,
|
|
51
|
+
openValues = openValues,
|
|
52
|
+
loop = loop,
|
|
53
|
+
toggleItem = toggleItem,
|
|
54
|
+
}
|
|
55
|
+
end, { accordionType, loop, openValues, toggleItem })
|
|
56
|
+
return React.createElement(AccordionContextProvider, {
|
|
57
|
+
value = contextValue,
|
|
58
|
+
}, React.createElement(RovingFocusGroup, {
|
|
59
|
+
active = true,
|
|
60
|
+
autoFocus = "none",
|
|
61
|
+
loop = loop,
|
|
62
|
+
orientation = "vertical",
|
|
63
|
+
}, props.children))
|
|
64
|
+
end
|
|
65
|
+
return {
|
|
66
|
+
AccordionRoot = AccordionRoot,
|
|
67
|
+
Accordion = AccordionRoot,
|
|
68
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _core = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out)
|
|
4
|
+
local React = _core.React
|
|
5
|
+
local Slot = _core.Slot
|
|
6
|
+
local RovingFocusItem = TS.import(script, TS.getModule(script, "@lattice-ui", "focus").out).RovingFocusItem
|
|
7
|
+
local _context = TS.import(script, script.Parent, "context")
|
|
8
|
+
local useAccordionContext = _context.useAccordionContext
|
|
9
|
+
local useAccordionItemContext = _context.useAccordionItemContext
|
|
10
|
+
local function AccordionTrigger(props)
|
|
11
|
+
local accordionContext = useAccordionContext()
|
|
12
|
+
local itemContext = useAccordionItemContext()
|
|
13
|
+
local disabled = itemContext.disabled
|
|
14
|
+
local handleActivated = React.useCallback(function()
|
|
15
|
+
if disabled then
|
|
16
|
+
return nil
|
|
17
|
+
end
|
|
18
|
+
accordionContext.toggleItem(itemContext.value)
|
|
19
|
+
end, { accordionContext, disabled, itemContext.value })
|
|
20
|
+
local handleInputBegan = React.useCallback(function(_rbx, inputObject)
|
|
21
|
+
if disabled then
|
|
22
|
+
return nil
|
|
23
|
+
end
|
|
24
|
+
local keyCode = inputObject.KeyCode
|
|
25
|
+
if keyCode == Enum.KeyCode.Return or keyCode == Enum.KeyCode.Space then
|
|
26
|
+
accordionContext.toggleItem(itemContext.value)
|
|
27
|
+
end
|
|
28
|
+
end, { accordionContext, disabled, itemContext.value })
|
|
29
|
+
local eventHandlers = React.useMemo(function()
|
|
30
|
+
return {
|
|
31
|
+
Activated = handleActivated,
|
|
32
|
+
InputBegan = handleInputBegan,
|
|
33
|
+
}
|
|
34
|
+
end, { handleActivated, handleInputBegan })
|
|
35
|
+
if props.asChild then
|
|
36
|
+
local child = props.children
|
|
37
|
+
if not child then
|
|
38
|
+
error("[AccordionTrigger] `asChild` requires a child element.")
|
|
39
|
+
end
|
|
40
|
+
return React.createElement(RovingFocusItem, {
|
|
41
|
+
asChild = true,
|
|
42
|
+
disabled = disabled,
|
|
43
|
+
}, React.createElement(Slot, {
|
|
44
|
+
Active = not disabled,
|
|
45
|
+
Event = eventHandlers,
|
|
46
|
+
Selectable = not disabled,
|
|
47
|
+
}, child))
|
|
48
|
+
end
|
|
49
|
+
return React.createElement(RovingFocusItem, {
|
|
50
|
+
asChild = true,
|
|
51
|
+
disabled = disabled,
|
|
52
|
+
}, React.createElement("textbutton", {
|
|
53
|
+
Active = not disabled,
|
|
54
|
+
AutoButtonColor = false,
|
|
55
|
+
BackgroundColor3 = Color3.fromRGB(41, 48, 63),
|
|
56
|
+
BorderSizePixel = 0,
|
|
57
|
+
Event = eventHandlers,
|
|
58
|
+
Selectable = not disabled,
|
|
59
|
+
Size = UDim2.fromOffset(260, 34),
|
|
60
|
+
Text = if itemContext.open then "Collapse" else "Expand",
|
|
61
|
+
TextColor3 = if disabled then Color3.fromRGB(143, 150, 165) else Color3.fromRGB(236, 241, 249),
|
|
62
|
+
TextSize = 14,
|
|
63
|
+
TextXAlignment = Enum.TextXAlignment.Left,
|
|
64
|
+
}, React.createElement("uipadding", {
|
|
65
|
+
PaddingLeft = UDim.new(0, 10),
|
|
66
|
+
}), props.children))
|
|
67
|
+
end
|
|
68
|
+
return {
|
|
69
|
+
AccordionTrigger = AccordionTrigger,
|
|
70
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AccordionContextValue, AccordionItemContextValue } from "./types";
|
|
2
|
+
declare const AccordionContextProvider: import("@rbxts/react").Provider<AccordionContextValue | undefined>, useAccordionContext: () => AccordionContextValue;
|
|
3
|
+
declare const AccordionItemContextProvider: import("@rbxts/react").Provider<AccordionItemContextValue | undefined>, useAccordionItemContext: () => AccordionItemContextValue;
|
|
4
|
+
export { AccordionContextProvider, AccordionItemContextProvider, useAccordionContext, useAccordionItemContext };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local createStrictContext = TS.import(script, TS.getModule(script, "@lattice-ui", "core").out).createStrictContext
|
|
4
|
+
local _binding = createStrictContext("Accordion")
|
|
5
|
+
local AccordionContextProvider = _binding[1]
|
|
6
|
+
local useAccordionContext = _binding[2]
|
|
7
|
+
local _binding_1 = createStrictContext("AccordionItem")
|
|
8
|
+
local AccordionItemContextProvider = _binding_1[1]
|
|
9
|
+
local useAccordionItemContext = _binding_1[2]
|
|
10
|
+
return {
|
|
11
|
+
AccordionContextProvider = AccordionContextProvider,
|
|
12
|
+
AccordionItemContextProvider = AccordionItemContextProvider,
|
|
13
|
+
useAccordionContext = useAccordionContext,
|
|
14
|
+
useAccordionItemContext = useAccordionItemContext,
|
|
15
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type AccordionType = "single" | "multiple";
|
|
2
|
+
export declare function normalizeAccordionValue(accordionType: AccordionType, value: string | Array<string> | undefined): Array<string>;
|
|
3
|
+
export declare function nextAccordionValues(accordionType: AccordionType, currentValues: Array<string>, candidateValue: string, collapsible: boolean): Array<string>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local function normalizeAccordionValue(accordionType, value)
|
|
3
|
+
if accordionType == "single" then
|
|
4
|
+
if value == nil then
|
|
5
|
+
return {}
|
|
6
|
+
end
|
|
7
|
+
local _value = value
|
|
8
|
+
if type(_value) == "string" then
|
|
9
|
+
return if #value > 0 then { value } else {}
|
|
10
|
+
end
|
|
11
|
+
return if value[1] ~= nil then { value[1] } else {}
|
|
12
|
+
end
|
|
13
|
+
if value == nil then
|
|
14
|
+
return {}
|
|
15
|
+
end
|
|
16
|
+
local _value = value
|
|
17
|
+
if type(_value) == "string" then
|
|
18
|
+
return if #value > 0 then { value } else {}
|
|
19
|
+
end
|
|
20
|
+
local deduped = {}
|
|
21
|
+
for _, item in value do
|
|
22
|
+
if not (table.find(deduped, item) ~= nil) then
|
|
23
|
+
table.insert(deduped, item)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
return deduped
|
|
27
|
+
end
|
|
28
|
+
local function nextAccordionValues(accordionType, currentValues, candidateValue, collapsible)
|
|
29
|
+
local _currentValues = currentValues
|
|
30
|
+
local _candidateValue = candidateValue
|
|
31
|
+
local isOpen = table.find(_currentValues, _candidateValue) ~= nil
|
|
32
|
+
if accordionType == "single" then
|
|
33
|
+
if isOpen then
|
|
34
|
+
return if collapsible then {} else { candidateValue }
|
|
35
|
+
end
|
|
36
|
+
return { candidateValue }
|
|
37
|
+
end
|
|
38
|
+
if isOpen then
|
|
39
|
+
-- ▼ ReadonlyArray.filter ▼
|
|
40
|
+
local _newValue = {}
|
|
41
|
+
local _callback = function(value)
|
|
42
|
+
return value ~= candidateValue
|
|
43
|
+
end
|
|
44
|
+
local _length = 0
|
|
45
|
+
for _k, _v in currentValues do
|
|
46
|
+
if _callback(_v, _k - 1, currentValues) == true then
|
|
47
|
+
_length += 1
|
|
48
|
+
_newValue[_length] = _v
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
-- ▲ ReadonlyArray.filter ▲
|
|
52
|
+
return _newValue
|
|
53
|
+
end
|
|
54
|
+
local _array = {}
|
|
55
|
+
local _length = #_array
|
|
56
|
+
local _currentValuesLength = #currentValues
|
|
57
|
+
table.move(currentValues, 1, _currentValuesLength, _length + 1, _array)
|
|
58
|
+
_length += _currentValuesLength
|
|
59
|
+
_array[_length + 1] = candidateValue
|
|
60
|
+
return _array
|
|
61
|
+
end
|
|
62
|
+
return {
|
|
63
|
+
normalizeAccordionValue = normalizeAccordionValue,
|
|
64
|
+
nextAccordionValues = nextAccordionValues,
|
|
65
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type React from "@rbxts/react";
|
|
2
|
+
import type { AccordionType } from "./state";
|
|
3
|
+
export type AccordionContextValue = {
|
|
4
|
+
type: AccordionType;
|
|
5
|
+
openValues: Array<string>;
|
|
6
|
+
loop: boolean;
|
|
7
|
+
toggleItem: (value: string) => void;
|
|
8
|
+
};
|
|
9
|
+
export type AccordionItemContextValue = {
|
|
10
|
+
value: string;
|
|
11
|
+
open: boolean;
|
|
12
|
+
disabled: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type AccordionProps = {
|
|
15
|
+
type?: AccordionType;
|
|
16
|
+
value?: string | Array<string>;
|
|
17
|
+
defaultValue?: string | Array<string>;
|
|
18
|
+
onValueChange?: (value: string | Array<string>) => void;
|
|
19
|
+
collapsible?: boolean;
|
|
20
|
+
loop?: boolean;
|
|
21
|
+
children?: React.ReactNode;
|
|
22
|
+
};
|
|
23
|
+
export type AccordionItemProps = {
|
|
24
|
+
value: string;
|
|
25
|
+
asChild?: boolean;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
};
|
|
29
|
+
export type AccordionHeaderProps = {
|
|
30
|
+
asChild?: boolean;
|
|
31
|
+
children?: React.ReactElement;
|
|
32
|
+
};
|
|
33
|
+
export type AccordionTriggerProps = {
|
|
34
|
+
asChild?: boolean;
|
|
35
|
+
children?: React.ReactElement;
|
|
36
|
+
};
|
|
37
|
+
export type AccordionContentProps = {
|
|
38
|
+
asChild?: boolean;
|
|
39
|
+
forceMount?: boolean;
|
|
40
|
+
children?: React.ReactNode;
|
|
41
|
+
};
|
package/out/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AccordionContent } from "./Accordion/AccordionContent";
|
|
2
|
+
import { AccordionHeader } from "./Accordion/AccordionHeader";
|
|
3
|
+
import { AccordionItem } from "./Accordion/AccordionItem";
|
|
4
|
+
import { AccordionRoot } from "./Accordion/AccordionRoot";
|
|
5
|
+
import { AccordionTrigger } from "./Accordion/AccordionTrigger";
|
|
6
|
+
export declare const Accordion: {
|
|
7
|
+
readonly Root: typeof AccordionRoot;
|
|
8
|
+
readonly Item: typeof AccordionItem;
|
|
9
|
+
readonly Header: typeof AccordionHeader;
|
|
10
|
+
readonly Trigger: typeof AccordionTrigger;
|
|
11
|
+
readonly Content: typeof AccordionContent;
|
|
12
|
+
};
|
|
13
|
+
export type { AccordionType } from "./Accordion/state";
|
|
14
|
+
export { nextAccordionValues, normalizeAccordionValue } from "./Accordion/state";
|
|
15
|
+
export type { AccordionContentProps, AccordionContextValue, AccordionHeaderProps, AccordionItemContextValue, AccordionItemProps, AccordionProps, AccordionTriggerProps, } from "./Accordion/types";
|
package/out/init.luau
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local exports = {}
|
|
4
|
+
local AccordionContent = TS.import(script, script, "Accordion", "AccordionContent").AccordionContent
|
|
5
|
+
local AccordionHeader = TS.import(script, script, "Accordion", "AccordionHeader").AccordionHeader
|
|
6
|
+
local AccordionItem = TS.import(script, script, "Accordion", "AccordionItem").AccordionItem
|
|
7
|
+
local AccordionRoot = TS.import(script, script, "Accordion", "AccordionRoot").AccordionRoot
|
|
8
|
+
local AccordionTrigger = TS.import(script, script, "Accordion", "AccordionTrigger").AccordionTrigger
|
|
9
|
+
local Accordion = {
|
|
10
|
+
Root = AccordionRoot,
|
|
11
|
+
Item = AccordionItem,
|
|
12
|
+
Header = AccordionHeader,
|
|
13
|
+
Trigger = AccordionTrigger,
|
|
14
|
+
Content = AccordionContent,
|
|
15
|
+
}
|
|
16
|
+
local _state = TS.import(script, script, "Accordion", "state")
|
|
17
|
+
exports.nextAccordionValues = _state.nextAccordionValues
|
|
18
|
+
exports.normalizeAccordionValue = _state.normalizeAccordionValue
|
|
19
|
+
exports.Accordion = Accordion
|
|
20
|
+
return exports
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lattice-ui/accordion",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"main": "out/init.luau",
|
|
6
|
+
"types": "out/index.d.ts",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@lattice-ui/core": "0.3.0",
|
|
9
|
+
"@lattice-ui/focus": "0.3.0"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@rbxts/react": "17.3.7-ts.1",
|
|
13
|
+
"@rbxts/react-roblox": "17.3.7-ts.1"
|
|
14
|
+
},
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"@rbxts/react": "^17",
|
|
17
|
+
"@rbxts/react-roblox": "^17"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "rbxtsc -p tsconfig.json",
|
|
21
|
+
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
22
|
+
"watch": "rbxtsc -p tsconfig.json -w"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { React, Slot } from "@lattice-ui/core";
|
|
2
|
+
import { useAccordionItemContext } from "./context";
|
|
3
|
+
import type { AccordionContentProps } from "./types";
|
|
4
|
+
|
|
5
|
+
export function AccordionContent(props: AccordionContentProps) {
|
|
6
|
+
const itemContext = useAccordionItemContext();
|
|
7
|
+
const forceMount = props.forceMount === true;
|
|
8
|
+
|
|
9
|
+
if (!itemContext.open && !forceMount) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (props.asChild) {
|
|
14
|
+
const child = props.children;
|
|
15
|
+
if (!React.isValidElement(child)) {
|
|
16
|
+
error("[AccordionContent] `asChild` requires a child element.");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return <Slot Visible={itemContext.open}>{child}</Slot>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<frame
|
|
24
|
+
BackgroundColor3={Color3.fromRGB(35, 41, 54)}
|
|
25
|
+
BorderSizePixel={0}
|
|
26
|
+
Size={UDim2.fromOffset(260, 44)}
|
|
27
|
+
Visible={itemContext.open}
|
|
28
|
+
>
|
|
29
|
+
{props.children}
|
|
30
|
+
</frame>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { React, Slot } from "@lattice-ui/core";
|
|
2
|
+
import type { AccordionHeaderProps } from "./types";
|
|
3
|
+
|
|
4
|
+
export function AccordionHeader(props: AccordionHeaderProps) {
|
|
5
|
+
if (props.asChild) {
|
|
6
|
+
const child = props.children;
|
|
7
|
+
if (!child) {
|
|
8
|
+
error("[AccordionHeader] `asChild` requires a child element.");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return <Slot>{child}</Slot>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<frame BackgroundTransparency={1} BorderSizePixel={0} Size={UDim2.fromOffset(260, 34)}>
|
|
16
|
+
{props.children}
|
|
17
|
+
</frame>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { React, Slot } from "@lattice-ui/core";
|
|
2
|
+
import { AccordionItemContextProvider, useAccordionContext } from "./context";
|
|
3
|
+
import type { AccordionItemProps } from "./types";
|
|
4
|
+
|
|
5
|
+
export function AccordionItem(props: AccordionItemProps) {
|
|
6
|
+
const accordionContext = useAccordionContext();
|
|
7
|
+
const open = accordionContext.openValues.includes(props.value);
|
|
8
|
+
const disabled = props.disabled === true;
|
|
9
|
+
|
|
10
|
+
const contextValue = React.useMemo(
|
|
11
|
+
() => ({
|
|
12
|
+
value: props.value,
|
|
13
|
+
open,
|
|
14
|
+
disabled,
|
|
15
|
+
}),
|
|
16
|
+
[disabled, open, props.value],
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
if (props.asChild) {
|
|
20
|
+
const child = props.children;
|
|
21
|
+
if (!React.isValidElement(child)) {
|
|
22
|
+
error("[AccordionItem] `asChild` requires a child element.");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<AccordionItemContextProvider value={contextValue}>
|
|
27
|
+
<Slot>{child}</Slot>
|
|
28
|
+
</AccordionItemContextProvider>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<AccordionItemContextProvider value={contextValue}>
|
|
34
|
+
<frame BackgroundTransparency={1} BorderSizePixel={0} Size={UDim2.fromOffset(260, 80)}>
|
|
35
|
+
{props.children}
|
|
36
|
+
</frame>
|
|
37
|
+
</AccordionItemContextProvider>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { React, useControllableState } from "@lattice-ui/core";
|
|
2
|
+
import { RovingFocusGroup } from "@lattice-ui/focus";
|
|
3
|
+
import { AccordionContextProvider } from "./context";
|
|
4
|
+
import { nextAccordionValues, normalizeAccordionValue } from "./state";
|
|
5
|
+
import type { AccordionProps } from "./types";
|
|
6
|
+
|
|
7
|
+
export function AccordionRoot(props: AccordionProps) {
|
|
8
|
+
const accordionType = props.type ?? "single";
|
|
9
|
+
const loop = props.loop ?? true;
|
|
10
|
+
const collapsible = props.collapsible ?? false;
|
|
11
|
+
|
|
12
|
+
const defaultValue = props.defaultValue ?? (accordionType === "single" ? "" : []);
|
|
13
|
+
|
|
14
|
+
const [rawValue, setRawValue] = useControllableState<string | Array<string>>({
|
|
15
|
+
value: props.value,
|
|
16
|
+
defaultValue,
|
|
17
|
+
onChange: props.onValueChange,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const openValues = normalizeAccordionValue(accordionType, rawValue);
|
|
21
|
+
|
|
22
|
+
const toggleItem = React.useCallback(
|
|
23
|
+
(candidateValue: string) => {
|
|
24
|
+
const nextValues = nextAccordionValues(accordionType, openValues, candidateValue, collapsible);
|
|
25
|
+
if (accordionType === "single") {
|
|
26
|
+
setRawValue(nextValues[0] ?? "");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setRawValue(nextValues);
|
|
31
|
+
},
|
|
32
|
+
[accordionType, collapsible, openValues, setRawValue],
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const contextValue = React.useMemo(
|
|
36
|
+
() => ({
|
|
37
|
+
type: accordionType,
|
|
38
|
+
openValues,
|
|
39
|
+
loop,
|
|
40
|
+
toggleItem,
|
|
41
|
+
}),
|
|
42
|
+
[accordionType, loop, openValues, toggleItem],
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<AccordionContextProvider value={contextValue}>
|
|
47
|
+
<RovingFocusGroup active autoFocus="none" loop={loop} orientation="vertical">
|
|
48
|
+
{props.children}
|
|
49
|
+
</RovingFocusGroup>
|
|
50
|
+
</AccordionContextProvider>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { AccordionRoot as Accordion };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { React, Slot } from "@lattice-ui/core";
|
|
2
|
+
import { RovingFocusItem } from "@lattice-ui/focus";
|
|
3
|
+
import { useAccordionContext, useAccordionItemContext } from "./context";
|
|
4
|
+
import type { AccordionTriggerProps } from "./types";
|
|
5
|
+
|
|
6
|
+
export function AccordionTrigger(props: AccordionTriggerProps) {
|
|
7
|
+
const accordionContext = useAccordionContext();
|
|
8
|
+
const itemContext = useAccordionItemContext();
|
|
9
|
+
const disabled = itemContext.disabled;
|
|
10
|
+
|
|
11
|
+
const handleActivated = React.useCallback(() => {
|
|
12
|
+
if (disabled) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
accordionContext.toggleItem(itemContext.value);
|
|
17
|
+
}, [accordionContext, disabled, itemContext.value]);
|
|
18
|
+
|
|
19
|
+
const handleInputBegan = React.useCallback(
|
|
20
|
+
(_rbx: GuiObject, inputObject: InputObject) => {
|
|
21
|
+
if (disabled) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const keyCode = inputObject.KeyCode;
|
|
26
|
+
if (keyCode === Enum.KeyCode.Return || keyCode === Enum.KeyCode.Space) {
|
|
27
|
+
accordionContext.toggleItem(itemContext.value);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
[accordionContext, disabled, itemContext.value],
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const eventHandlers = React.useMemo(
|
|
34
|
+
() => ({
|
|
35
|
+
Activated: handleActivated,
|
|
36
|
+
InputBegan: handleInputBegan,
|
|
37
|
+
}),
|
|
38
|
+
[handleActivated, handleInputBegan],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
if (props.asChild) {
|
|
42
|
+
const child = props.children;
|
|
43
|
+
if (!child) {
|
|
44
|
+
error("[AccordionTrigger] `asChild` requires a child element.");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<RovingFocusItem asChild disabled={disabled}>
|
|
49
|
+
<Slot Active={!disabled} Event={eventHandlers} Selectable={!disabled}>
|
|
50
|
+
{child}
|
|
51
|
+
</Slot>
|
|
52
|
+
</RovingFocusItem>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<RovingFocusItem asChild disabled={disabled}>
|
|
58
|
+
<textbutton
|
|
59
|
+
Active={!disabled}
|
|
60
|
+
AutoButtonColor={false}
|
|
61
|
+
BackgroundColor3={Color3.fromRGB(41, 48, 63)}
|
|
62
|
+
BorderSizePixel={0}
|
|
63
|
+
Event={eventHandlers}
|
|
64
|
+
Selectable={!disabled}
|
|
65
|
+
Size={UDim2.fromOffset(260, 34)}
|
|
66
|
+
Text={itemContext.open ? "Collapse" : "Expand"}
|
|
67
|
+
TextColor3={disabled ? Color3.fromRGB(143, 150, 165) : Color3.fromRGB(236, 241, 249)}
|
|
68
|
+
TextSize={14}
|
|
69
|
+
TextXAlignment={Enum.TextXAlignment.Left}
|
|
70
|
+
>
|
|
71
|
+
<uipadding PaddingLeft={new UDim(0, 10)} />
|
|
72
|
+
{props.children}
|
|
73
|
+
</textbutton>
|
|
74
|
+
</RovingFocusItem>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createStrictContext } from "@lattice-ui/core";
|
|
2
|
+
import type { AccordionContextValue, AccordionItemContextValue } from "./types";
|
|
3
|
+
|
|
4
|
+
const [AccordionContextProvider, useAccordionContext] = createStrictContext<AccordionContextValue>("Accordion");
|
|
5
|
+
const [AccordionItemContextProvider, useAccordionItemContext] =
|
|
6
|
+
createStrictContext<AccordionItemContextValue>("AccordionItem");
|
|
7
|
+
|
|
8
|
+
export { AccordionContextProvider, AccordionItemContextProvider, useAccordionContext, useAccordionItemContext };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export type AccordionType = "single" | "multiple";
|
|
2
|
+
|
|
3
|
+
export function normalizeAccordionValue(
|
|
4
|
+
accordionType: AccordionType,
|
|
5
|
+
value: string | Array<string> | undefined,
|
|
6
|
+
): Array<string> {
|
|
7
|
+
if (accordionType === "single") {
|
|
8
|
+
if (value === undefined) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (typeIs(value, "string")) {
|
|
13
|
+
return value.size() > 0 ? [value] : [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return value[0] !== undefined ? [value[0]] : [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (value === undefined) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (typeIs(value, "string")) {
|
|
24
|
+
return value.size() > 0 ? [value] : [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const deduped: Array<string> = [];
|
|
28
|
+
for (const item of value) {
|
|
29
|
+
if (!deduped.includes(item)) {
|
|
30
|
+
deduped.push(item);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return deduped;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function nextAccordionValues(
|
|
38
|
+
accordionType: AccordionType,
|
|
39
|
+
currentValues: Array<string>,
|
|
40
|
+
candidateValue: string,
|
|
41
|
+
collapsible: boolean,
|
|
42
|
+
): Array<string> {
|
|
43
|
+
const isOpen = currentValues.includes(candidateValue);
|
|
44
|
+
|
|
45
|
+
if (accordionType === "single") {
|
|
46
|
+
if (isOpen) {
|
|
47
|
+
return collapsible ? [] : [candidateValue];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return [candidateValue];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (isOpen) {
|
|
54
|
+
return currentValues.filter((value) => value !== candidateValue);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return [...currentValues, candidateValue];
|
|
58
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type React from "@rbxts/react";
|
|
2
|
+
import type { AccordionType } from "./state";
|
|
3
|
+
|
|
4
|
+
export type AccordionContextValue = {
|
|
5
|
+
type: AccordionType;
|
|
6
|
+
openValues: Array<string>;
|
|
7
|
+
loop: boolean;
|
|
8
|
+
toggleItem: (value: string) => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type AccordionItemContextValue = {
|
|
12
|
+
value: string;
|
|
13
|
+
open: boolean;
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type AccordionProps = {
|
|
18
|
+
type?: AccordionType;
|
|
19
|
+
value?: string | Array<string>;
|
|
20
|
+
defaultValue?: string | Array<string>;
|
|
21
|
+
onValueChange?: (value: string | Array<string>) => void;
|
|
22
|
+
collapsible?: boolean;
|
|
23
|
+
loop?: boolean;
|
|
24
|
+
children?: React.ReactNode;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type AccordionItemProps = {
|
|
28
|
+
value: string;
|
|
29
|
+
asChild?: boolean;
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
children?: React.ReactNode;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type AccordionHeaderProps = {
|
|
35
|
+
asChild?: boolean;
|
|
36
|
+
children?: React.ReactElement;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type AccordionTriggerProps = {
|
|
40
|
+
asChild?: boolean;
|
|
41
|
+
children?: React.ReactElement;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type AccordionContentProps = {
|
|
45
|
+
asChild?: boolean;
|
|
46
|
+
forceMount?: boolean;
|
|
47
|
+
children?: React.ReactNode;
|
|
48
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AccordionContent } from "./Accordion/AccordionContent";
|
|
2
|
+
import { AccordionHeader } from "./Accordion/AccordionHeader";
|
|
3
|
+
import { AccordionItem } from "./Accordion/AccordionItem";
|
|
4
|
+
import { AccordionRoot } from "./Accordion/AccordionRoot";
|
|
5
|
+
import { AccordionTrigger } from "./Accordion/AccordionTrigger";
|
|
6
|
+
|
|
7
|
+
export const Accordion = {
|
|
8
|
+
Root: AccordionRoot,
|
|
9
|
+
Item: AccordionItem,
|
|
10
|
+
Header: AccordionHeader,
|
|
11
|
+
Trigger: AccordionTrigger,
|
|
12
|
+
Content: AccordionContent,
|
|
13
|
+
} as const;
|
|
14
|
+
|
|
15
|
+
export type { AccordionType } from "./Accordion/state";
|
|
16
|
+
export { nextAccordionValues, normalizeAccordionValue } from "./Accordion/state";
|
|
17
|
+
export type {
|
|
18
|
+
AccordionContentProps,
|
|
19
|
+
AccordionContextValue,
|
|
20
|
+
AccordionHeaderProps,
|
|
21
|
+
AccordionItemContextValue,
|
|
22
|
+
AccordionItemProps,
|
|
23
|
+
AccordionProps,
|
|
24
|
+
AccordionTriggerProps,
|
|
25
|
+
} from "./Accordion/types";
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": "src",
|
|
5
|
+
"outDir": "out",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"typeRoots": [
|
|
8
|
+
"./node_modules/@rbxts",
|
|
9
|
+
"../../node_modules/@rbxts",
|
|
10
|
+
"./node_modules/@lattice-ui",
|
|
11
|
+
"../../node_modules/@lattice-ui"
|
|
12
|
+
],
|
|
13
|
+
"types": ["types", "compiler-types"]
|
|
14
|
+
},
|
|
15
|
+
"include": ["src"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"noEmit": true,
|
|
5
|
+
"baseUrl": "..",
|
|
6
|
+
"rootDir": "..",
|
|
7
|
+
"paths": {
|
|
8
|
+
"@lattice-ui/accordion": ["accordion/src/index.ts"],
|
|
9
|
+
"@lattice-ui/avatar": ["avatar/src/index.ts"],
|
|
10
|
+
"@lattice-ui/checkbox": ["checkbox/src/index.ts"],
|
|
11
|
+
"@lattice-ui/combobox": ["combobox/src/index.ts"],
|
|
12
|
+
"@lattice-ui/core": ["core/src/index.ts"],
|
|
13
|
+
"@lattice-ui/dialog": ["dialog/src/index.ts"],
|
|
14
|
+
"@lattice-ui/focus": ["focus/src/index.ts"],
|
|
15
|
+
"@lattice-ui/layer": ["layer/src/index.ts"],
|
|
16
|
+
"@lattice-ui/menu": ["menu/src/index.ts"],
|
|
17
|
+
"@lattice-ui/popover": ["popover/src/index.ts"],
|
|
18
|
+
"@lattice-ui/popper": ["popper/src/index.ts"],
|
|
19
|
+
"@lattice-ui/progress": ["progress/src/index.ts"],
|
|
20
|
+
"@lattice-ui/radio-group": ["radio-group/src/index.ts"],
|
|
21
|
+
"@lattice-ui/scroll-area": ["scroll-area/src/index.ts"],
|
|
22
|
+
"@lattice-ui/select": ["select/src/index.ts"],
|
|
23
|
+
"@lattice-ui/slider": ["slider/src/index.ts"],
|
|
24
|
+
"@lattice-ui/style": ["style/src/index.ts"],
|
|
25
|
+
"@lattice-ui/switch": ["switch/src/index.ts"],
|
|
26
|
+
"@lattice-ui/system": ["system/src/index.ts"],
|
|
27
|
+
"@lattice-ui/tabs": ["tabs/src/index.ts"],
|
|
28
|
+
"@lattice-ui/text-field": ["text-field/src/index.ts"],
|
|
29
|
+
"@lattice-ui/textarea": ["textarea/src/index.ts"],
|
|
30
|
+
"@lattice-ui/toast": ["toast/src/index.ts"],
|
|
31
|
+
"@lattice-ui/toggle-group": ["toggle-group/src/index.ts"],
|
|
32
|
+
"@lattice-ui/tooltip": ["tooltip/src/index.ts"]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|