@carrier-dpx/air-react-library 0.7.33 → 0.7.36
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/package.json +2 -2
- package/src/components/AccentIndicator/AccentIndicator.horizontal.figma.tsx +56 -0
- package/src/components/AccentIndicator/AccentIndicator.tsx +56 -0
- package/src/components/AccentIndicator/AccentIndicator.vertical.figma.tsx +56 -0
- package/src/components/AccentIndicator/index.ts +4 -0
- package/src/components/AccentIndicator/styles.ts +28 -0
- package/src/components/AccentIndicator/types.ts +39 -0
- package/src/components/AccentIndicator/utils.ts +14 -0
- package/src/components/Alert/Alert.figma.tsx +160 -0
- package/src/components/Alert/Alert.tsx +90 -0
- package/src/components/Alert/AlertTitle.tsx +34 -0
- package/src/components/Alert/index.ts +9 -0
- package/src/components/Alert/styles.ts +80 -0
- package/src/components/Alert/types.ts +5 -0
- package/src/components/Breadcrumbs/BreadcrumbLink.figma.tsx +137 -0
- package/src/components/Breadcrumbs/BreadcrumbLink.tsx +82 -0
- package/src/components/Breadcrumbs/Breadcrumbs.figma.tsx +117 -0
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +53 -0
- package/src/components/Breadcrumbs/index.ts +5 -0
- package/src/components/Breadcrumbs/styles.ts +20 -0
- package/src/components/List/List.figma.tsx +110 -0
- package/src/components/List/List.tsx +72 -0
- package/src/components/List/ListItem.figma.tsx +298 -0
- package/src/components/List/ListItem.tsx +58 -0
- package/src/components/List/ListItemAvatar.tsx +26 -0
- package/src/components/List/ListItemButton.tsx +42 -0
- package/src/components/List/ListItemIcon.tsx +41 -0
- package/src/components/List/ListItemSecondaryAction.tsx +28 -0
- package/src/components/List/ListItemText.tsx +46 -0
- package/src/components/List/ListSubheader.tsx +42 -0
- package/src/components/List/index.ts +25 -0
- package/src/components/Menu/Menu.figma.tsx +119 -0
- package/src/components/Menu/Menu.tsx +72 -0
- package/src/components/Menu/index.ts +3 -0
- package/src/components/Navbar/NavbarButtons/Item.figma.tsx +197 -16
- package/src/components/Tag/Tag.figma.tsx +129 -0
- package/src/components/Tag/Tag.tsx +40 -0
- package/src/components/Tag/index.ts +4 -0
- package/src/components/Tag/styles.ts +93 -0
- package/src/components/Tag/types.ts +39 -0
- package/src/components/types/common.ts +22 -0
- package/src/components/useMediaQuery/index.ts +3 -0
- package/src/components/useMediaQuery/useMediaQuery.ts +35 -0
- package/src/components/utils/getAccentColor.ts +31 -0
- package/src/index.ts +21 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Code Connect Configuration for Breadcrumb Link Component
|
|
3
|
+
*
|
|
4
|
+
* Figma URL: https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=20464-143034
|
|
5
|
+
*
|
|
6
|
+
* Figma Properties:
|
|
7
|
+
* - color (primary, main)
|
|
8
|
+
* - active (true, false)
|
|
9
|
+
* - state (enabled, hover) - visual state, not a prop
|
|
10
|
+
* - disabled (true, false)
|
|
11
|
+
* - Icon (true, false) - boolean hide/show
|
|
12
|
+
* - separator (true, false) - boolean hide/show
|
|
13
|
+
*
|
|
14
|
+
* Structure:
|
|
15
|
+
* - Icon: Nested Icon component instance (when Icon=true)
|
|
16
|
+
* - Link: Nested Link component instance with text content
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import figma from "@figma/code-connect";
|
|
20
|
+
import BreadcrumbLink from "./BreadcrumbLink";
|
|
21
|
+
import Link from "../Link";
|
|
22
|
+
import Icon from "../Icon";
|
|
23
|
+
|
|
24
|
+
figma.connect(
|
|
25
|
+
BreadcrumbLink,
|
|
26
|
+
"https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=20464-143034",
|
|
27
|
+
{
|
|
28
|
+
props: {
|
|
29
|
+
/**
|
|
30
|
+
* COLOR MAPPING
|
|
31
|
+
* Maps Figma's "color" property to React's "color" prop
|
|
32
|
+
* Figma: primary, main → React: primary, base
|
|
33
|
+
*/
|
|
34
|
+
color: figma.enum("color", {
|
|
35
|
+
primary: "primary",
|
|
36
|
+
main: "base",
|
|
37
|
+
}),
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* ACTIVE STATE
|
|
41
|
+
* Maps Figma's "active" boolean to React's "active" prop
|
|
42
|
+
*/
|
|
43
|
+
active: figma.boolean("active"),
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* DISABLED STATE
|
|
47
|
+
* Maps Figma's "disabled" boolean to React's "disabled" prop
|
|
48
|
+
*/
|
|
49
|
+
disabled: figma.boolean("disabled"),
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* ICON VISIBILITY
|
|
53
|
+
* Maps Figma's "Icon" boolean - controls visibility of nested Icon component
|
|
54
|
+
*/
|
|
55
|
+
showIcon: figma.boolean("Icon"),
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* SEPARATOR VISIBILITY
|
|
59
|
+
* Maps Figma's "separator" boolean - controls visibility of separator
|
|
60
|
+
* Note: Separator is typically handled by parent Breadcrumbs component
|
|
61
|
+
*/
|
|
62
|
+
showSeparator: figma.boolean("separator"),
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* ICON NESTED PROPERTIES
|
|
66
|
+
* Access Icon's fontSize and SVG through nested properties
|
|
67
|
+
* The Icon component is nested within BreadcrumbLink when Icon is visible
|
|
68
|
+
*/
|
|
69
|
+
icon: figma.nestedProps("Icon", {
|
|
70
|
+
fontSize: figma.enum("fontSize", {
|
|
71
|
+
large: "large",
|
|
72
|
+
medium: "medium",
|
|
73
|
+
small: "small",
|
|
74
|
+
xsmall: "xsmall",
|
|
75
|
+
}),
|
|
76
|
+
children: figma.instance("SVG"),
|
|
77
|
+
}),
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* LINK COMPONENT INSTANCE
|
|
81
|
+
* Maps nested Link component instance
|
|
82
|
+
* The Link component is nested within BreadcrumbLink
|
|
83
|
+
* Using figma.instance() to get the Link component instance
|
|
84
|
+
*/
|
|
85
|
+
link: figma.instance("Link"),
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* EXAMPLE CODE TEMPLATE
|
|
90
|
+
* Shows how BreadcrumbLink should be used with optional icon and link
|
|
91
|
+
*/
|
|
92
|
+
example: ({ color, active, disabled, showIcon, icon, link }) => {
|
|
93
|
+
// Handle case with icon
|
|
94
|
+
if (showIcon && icon && icon.fontSize && icon.children && link) {
|
|
95
|
+
return (
|
|
96
|
+
<BreadcrumbLink
|
|
97
|
+
color={color}
|
|
98
|
+
active={active}
|
|
99
|
+
disabled={disabled}
|
|
100
|
+
icon={
|
|
101
|
+
<Icon fontSize={icon.fontSize}>
|
|
102
|
+
{icon.children}
|
|
103
|
+
</Icon>
|
|
104
|
+
}
|
|
105
|
+
href="#"
|
|
106
|
+
>
|
|
107
|
+
{link}
|
|
108
|
+
</BreadcrumbLink>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Handle case without icon
|
|
113
|
+
if (link) {
|
|
114
|
+
return (
|
|
115
|
+
<BreadcrumbLink
|
|
116
|
+
color={color}
|
|
117
|
+
active={active}
|
|
118
|
+
disabled={disabled}
|
|
119
|
+
href="#"
|
|
120
|
+
>
|
|
121
|
+
{link}
|
|
122
|
+
</BreadcrumbLink>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Fallback
|
|
127
|
+
return (
|
|
128
|
+
<BreadcrumbLink
|
|
129
|
+
color={color}
|
|
130
|
+
active={active}
|
|
131
|
+
disabled={disabled}
|
|
132
|
+
href="#"
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import Link from "../Link";
|
|
3
|
+
import Icon from "../Icon";
|
|
4
|
+
import { styled } from "@mui/material/styles";
|
|
5
|
+
import { Theme } from "@mui/material";
|
|
6
|
+
|
|
7
|
+
export interface BreadcrumbLinkProps {
|
|
8
|
+
/**
|
|
9
|
+
* The color of the breadcrumb link
|
|
10
|
+
*/
|
|
11
|
+
color?: "primary" | "base";
|
|
12
|
+
/**
|
|
13
|
+
* Whether the breadcrumb link is active
|
|
14
|
+
*/
|
|
15
|
+
active?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the breadcrumb link is disabled
|
|
18
|
+
*/
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Icon element to display before the link text
|
|
22
|
+
*/
|
|
23
|
+
icon?: React.ReactElement;
|
|
24
|
+
/**
|
|
25
|
+
* Link content (text)
|
|
26
|
+
*/
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* href for the link
|
|
30
|
+
*/
|
|
31
|
+
href?: string;
|
|
32
|
+
/**
|
|
33
|
+
* onClick handler
|
|
34
|
+
*/
|
|
35
|
+
onClick?: () => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const StyledLink = styled(Link)<{ active?: boolean; disabled?: boolean }>(
|
|
39
|
+
({ theme, active, disabled }: { theme: Theme; active?: boolean; disabled?: boolean }) => ({
|
|
40
|
+
...(active && {
|
|
41
|
+
color: theme.palette.base?.text.primary,
|
|
42
|
+
fontWeight: 600,
|
|
43
|
+
}),
|
|
44
|
+
...(disabled && {
|
|
45
|
+
color: theme.palette.base?.text.disabled,
|
|
46
|
+
cursor: "not-allowed",
|
|
47
|
+
pointerEvents: "none",
|
|
48
|
+
}),
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
/** BreadcrumbLink component used within Breadcrumbs
|
|
53
|
+
*
|
|
54
|
+
* `import BreadcrumbLink from '@carrier-io/air-react/Breadcrumbs/BreadcrumbLink'`
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
const BreadcrumbLink = forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(
|
|
58
|
+
({ color, active, disabled, icon, children, href, onClick, ...rest }, ref) => {
|
|
59
|
+
// If children is a Link component instance, extract its content
|
|
60
|
+
const linkContent = children;
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<StyledLink
|
|
64
|
+
ref={ref}
|
|
65
|
+
href={href}
|
|
66
|
+
onClick={onClick}
|
|
67
|
+
active={active}
|
|
68
|
+
disabled={disabled}
|
|
69
|
+
color={color === "base" ? undefined : color}
|
|
70
|
+
{...rest}
|
|
71
|
+
>
|
|
72
|
+
{icon}
|
|
73
|
+
{linkContent}
|
|
74
|
+
</StyledLink>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
BreadcrumbLink.displayName = "BreadcrumbLink";
|
|
80
|
+
|
|
81
|
+
export default BreadcrumbLink;
|
|
82
|
+
export type { BreadcrumbLinkProps };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Code Connect Configuration for Breadcrumbs Component
|
|
3
|
+
*
|
|
4
|
+
* Figma URL: https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=20464-143181
|
|
5
|
+
*
|
|
6
|
+
* Figma Properties:
|
|
7
|
+
* - color (primary, main)
|
|
8
|
+
* - icon (true, false)
|
|
9
|
+
* - separator (slash, icon)
|
|
10
|
+
* - collapsed (true, false)
|
|
11
|
+
* - mobile (true, false)
|
|
12
|
+
*
|
|
13
|
+
* Structure:
|
|
14
|
+
* - Breadcrumb 01-06: Multiple Breadcrumb Link instances with numbered layer names
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import figma from "@figma/code-connect";
|
|
18
|
+
import Breadcrumbs from "./Breadcrumbs";
|
|
19
|
+
|
|
20
|
+
figma.connect(
|
|
21
|
+
Breadcrumbs,
|
|
22
|
+
"https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=20464-143181",
|
|
23
|
+
{
|
|
24
|
+
props: {
|
|
25
|
+
/**
|
|
26
|
+
* COLOR MAPPING
|
|
27
|
+
* Maps Figma's "color" property to React's "color" prop
|
|
28
|
+
* Figma: primary, main → React: primary, base
|
|
29
|
+
*/
|
|
30
|
+
color: figma.enum("color", {
|
|
31
|
+
primary: "primary",
|
|
32
|
+
main: "base",
|
|
33
|
+
}),
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* ICON VISIBILITY
|
|
37
|
+
* Maps Figma's "icon" boolean property
|
|
38
|
+
* Controls visibility of icons in breadcrumbs
|
|
39
|
+
*/
|
|
40
|
+
icon: figma.boolean("icon"),
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* SEPARATOR TYPE
|
|
44
|
+
* Maps Figma's "separator" property to React separator prop
|
|
45
|
+
* Figma: slash, icon → React: "/", icon component
|
|
46
|
+
*/
|
|
47
|
+
separator: figma.enum("separator", {
|
|
48
|
+
slash: "/",
|
|
49
|
+
icon: "icon",
|
|
50
|
+
}),
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* COLLAPSED STATE
|
|
54
|
+
* Maps Figma's "collapsed" boolean property
|
|
55
|
+
* Controls collapsed state of breadcrumbs
|
|
56
|
+
*/
|
|
57
|
+
collapsed: figma.boolean("collapsed"),
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* MOBILE STATE
|
|
61
|
+
* Maps Figma's "mobile" boolean property
|
|
62
|
+
* Controls mobile-specific behavior
|
|
63
|
+
*/
|
|
64
|
+
mobile: figma.boolean("mobile"),
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* BREADCRUMB LINK CHILDREN
|
|
68
|
+
* Maps nested Breadcrumb Link instances from Figma
|
|
69
|
+
* Each "Breadcrumb XX" is an instance of the Breadcrumb Link component
|
|
70
|
+
* We map each one individually using the exact layer names
|
|
71
|
+
*/
|
|
72
|
+
breadcrumb01: figma.children("Breadcrumb 01"),
|
|
73
|
+
breadcrumb02: figma.children("Breadcrumb 02"),
|
|
74
|
+
breadcrumb03: figma.children("Breadcrumb 03"),
|
|
75
|
+
breadcrumb04: figma.children("Breadcrumb 04"),
|
|
76
|
+
breadcrumb05: figma.children("Breadcrumb 05"),
|
|
77
|
+
breadcrumb06: figma.children("Breadcrumb 06"),
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* EXAMPLE CODE TEMPLATE
|
|
82
|
+
* Shows how Breadcrumbs should be used with Breadcrumb Link children
|
|
83
|
+
* Note: separator prop handling may need adjustment based on actual implementation
|
|
84
|
+
*/
|
|
85
|
+
example: ({ color, separator, breadcrumb01, breadcrumb02, breadcrumb03, breadcrumb04, breadcrumb05, breadcrumb06 }) => {
|
|
86
|
+
// Handle separator - if icon, use undefined (separator handled by parent), otherwise use the separator string
|
|
87
|
+
if (separator === "icon") {
|
|
88
|
+
return (
|
|
89
|
+
<Breadcrumbs
|
|
90
|
+
color={color}
|
|
91
|
+
>
|
|
92
|
+
{breadcrumb01}
|
|
93
|
+
{breadcrumb02}
|
|
94
|
+
{breadcrumb03}
|
|
95
|
+
{breadcrumb04}
|
|
96
|
+
{breadcrumb05}
|
|
97
|
+
{breadcrumb06}
|
|
98
|
+
</Breadcrumbs>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<Breadcrumbs
|
|
104
|
+
color={color}
|
|
105
|
+
separator={separator}
|
|
106
|
+
>
|
|
107
|
+
{breadcrumb01}
|
|
108
|
+
{breadcrumb02}
|
|
109
|
+
{breadcrumb03}
|
|
110
|
+
{breadcrumb04}
|
|
111
|
+
{breadcrumb05}
|
|
112
|
+
{breadcrumb06}
|
|
113
|
+
</Breadcrumbs>
|
|
114
|
+
);
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import MuiBreadcrumbs, {
|
|
4
|
+
BreadcrumbsProps as MuiBreadcrumbsProps,
|
|
5
|
+
} from "@mui/material/Breadcrumbs";
|
|
6
|
+
import { CSSObject, Theme } from "@mui/material/styles";
|
|
7
|
+
|
|
8
|
+
import { baseBreadcrumbsSx } from "./styles";
|
|
9
|
+
import { getSxStyles } from "../utils/styles";
|
|
10
|
+
import useMediaQuery from "../useMediaQuery/useMediaQuery";
|
|
11
|
+
|
|
12
|
+
export interface BreadcrumbsProps extends MuiBreadcrumbsProps {
|
|
13
|
+
color?: "primary" | "base";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The Breadcrumbs component is a set of links that help users navigate
|
|
17
|
+
* and visualize the current location within a hierarchical structure.
|
|
18
|
+
*
|
|
19
|
+
* // Default import
|
|
20
|
+
* import Breadcrumbs from '@carrier-io/air-react/Breadcrumbs'
|
|
21
|
+
*
|
|
22
|
+
* // Named import
|
|
23
|
+
* import { Breadcrumbs } from '@carrier-io/air-react'
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const Breadcrumbs = forwardRef<HTMLElement, BreadcrumbsProps>(
|
|
27
|
+
({ sx, color, ...rest }, ref) => {
|
|
28
|
+
const isMobile = useMediaQuery(`(max-width:599px)`);
|
|
29
|
+
|
|
30
|
+
const breadcrumbSX = (theme: Theme) => {
|
|
31
|
+
const baseStyles = getSxStyles(theme, sx);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
...baseStyles,
|
|
35
|
+
...baseBreadcrumbsSx(theme, color),
|
|
36
|
+
} as CSSObject;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<MuiBreadcrumbs
|
|
41
|
+
{...rest}
|
|
42
|
+
sx={breadcrumbSX}
|
|
43
|
+
ref={ref}
|
|
44
|
+
separator={isMobile ? "" : "/"}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
Breadcrumbs.displayName = "Breadcrumbs";
|
|
51
|
+
|
|
52
|
+
export default Breadcrumbs;
|
|
53
|
+
export type { BreadcrumbsProps };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CSSObject, Theme } from "@mui/material";
|
|
2
|
+
import { styleTokens } from "../theme/constants/styleTokens";
|
|
3
|
+
|
|
4
|
+
export const baseBreadcrumbsSx = (
|
|
5
|
+
theme: Theme,
|
|
6
|
+
color: "primary" | "base" | undefined
|
|
7
|
+
): CSSObject => ({
|
|
8
|
+
"& .MuiBreadcrumbs-separator": {
|
|
9
|
+
color: theme.palette.base?.filledInput.outlinedBorder,
|
|
10
|
+
marginRight: styleTokens.margin.medium,
|
|
11
|
+
marginLeft: styleTokens.margin.medium,
|
|
12
|
+
},
|
|
13
|
+
"& .MuiBreadcrumbs-li:last-child": {
|
|
14
|
+
color: theme.palette.base?.text.primary,
|
|
15
|
+
},
|
|
16
|
+
color:
|
|
17
|
+
color == "primary"
|
|
18
|
+
? theme.palette.primary.main
|
|
19
|
+
: theme.palette.base?.state.active,
|
|
20
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Code Connect Configuration for List Component
|
|
3
|
+
*
|
|
4
|
+
* Figma URL: https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=19353-120893
|
|
5
|
+
*
|
|
6
|
+
* Figma Properties:
|
|
7
|
+
* - subheader (true, false) - boolean hide/show
|
|
8
|
+
*
|
|
9
|
+
* Structure:
|
|
10
|
+
* - Container: Frame wrapping Subheader and ListItem components
|
|
11
|
+
* - Subheader: Nested component "ListItems/List Subheader" with layer name "Subheader"
|
|
12
|
+
* - Contains Typography component with layer name "↪ Subheader"
|
|
13
|
+
* - List Item 1-10: Multiple ListItem instances with numbered layer names
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import figma from "@figma/code-connect";
|
|
17
|
+
import List from "./List";
|
|
18
|
+
import ListSubheader from "./ListSubheader";
|
|
19
|
+
import ListItem from "./ListItem";
|
|
20
|
+
import Typography from "../Typography";
|
|
21
|
+
|
|
22
|
+
figma.connect(
|
|
23
|
+
List,
|
|
24
|
+
"https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=19353-120893",
|
|
25
|
+
{
|
|
26
|
+
props: {
|
|
27
|
+
/**
|
|
28
|
+
* SUBHEADER VISIBILITY
|
|
29
|
+
* Maps Figma's "subheader" boolean property
|
|
30
|
+
* When true, shows the nested "Subheader" component
|
|
31
|
+
*/
|
|
32
|
+
subheader: figma.boolean("subheader"),
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* SUBHEADER TEXT CONTENT
|
|
36
|
+
* Maps text content from nested Typography component with layer name "Subheader/↪ Subheader"
|
|
37
|
+
* Using full path to avoid nested nestedProps
|
|
38
|
+
*/
|
|
39
|
+
subheaderText: figma.nestedProps("Subheader/↪ Subheader", {
|
|
40
|
+
children: figma.children("Subheader/↪ Subheader"),
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* LIST ITEM CHILDREN
|
|
45
|
+
* Maps nested ListItem instances from Figma
|
|
46
|
+
* Each "List Item X" is an instance of the ListItem component
|
|
47
|
+
* We map each one individually using the exact layer names
|
|
48
|
+
*/
|
|
49
|
+
listItem1: figma.children("List Item 1"),
|
|
50
|
+
listItem2: figma.children("List Item 2"),
|
|
51
|
+
listItem3: figma.children("List Item 3"),
|
|
52
|
+
listItem4: figma.children("List Item 4"),
|
|
53
|
+
listItem5: figma.children("List Item 5"),
|
|
54
|
+
listItem6: figma.children("List Item 6"),
|
|
55
|
+
listItem7: figma.children("List Item 7"),
|
|
56
|
+
listItem8: figma.children("List Item 8"),
|
|
57
|
+
listItem9: figma.children("List Item 9"),
|
|
58
|
+
listItem10: figma.children("List Item 10"),
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* EXAMPLE CODE TEMPLATE
|
|
63
|
+
* Shows how List should be used with optional subheader and ListItem children
|
|
64
|
+
* Note: This example handles up to 10 list items. Adjust based on your design needs.
|
|
65
|
+
*/
|
|
66
|
+
example: ({ subheader, subheaderText, listItem1, listItem2, listItem3, listItem4, listItem5, listItem6, listItem7, listItem8, listItem9, listItem10 }) => {
|
|
67
|
+
// Handle case with subheader and multiple list items
|
|
68
|
+
if (subheader && subheaderText && subheaderText.children) {
|
|
69
|
+
return (
|
|
70
|
+
<List
|
|
71
|
+
subheader={
|
|
72
|
+
<ListSubheader>
|
|
73
|
+
<Typography variant="body2Semibold">
|
|
74
|
+
{subheaderText.children}
|
|
75
|
+
</Typography>
|
|
76
|
+
</ListSubheader>
|
|
77
|
+
}
|
|
78
|
+
>
|
|
79
|
+
{listItem1}
|
|
80
|
+
{listItem2}
|
|
81
|
+
{listItem3}
|
|
82
|
+
{listItem4}
|
|
83
|
+
{listItem5}
|
|
84
|
+
{listItem6}
|
|
85
|
+
{listItem7}
|
|
86
|
+
{listItem8}
|
|
87
|
+
{listItem9}
|
|
88
|
+
{listItem10}
|
|
89
|
+
</List>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Handle case without subheader
|
|
94
|
+
return (
|
|
95
|
+
<List>
|
|
96
|
+
{listItem1}
|
|
97
|
+
{listItem2}
|
|
98
|
+
{listItem3}
|
|
99
|
+
{listItem4}
|
|
100
|
+
{listItem5}
|
|
101
|
+
{listItem6}
|
|
102
|
+
{listItem7}
|
|
103
|
+
{listItem8}
|
|
104
|
+
{listItem9}
|
|
105
|
+
{listItem10}
|
|
106
|
+
</List>
|
|
107
|
+
);
|
|
108
|
+
},
|
|
109
|
+
}
|
|
110
|
+
);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
List as MuiList,
|
|
5
|
+
ListProps as MuiListProps,
|
|
6
|
+
CSSObject,
|
|
7
|
+
Theme,
|
|
8
|
+
} from "@mui/material";
|
|
9
|
+
import { styleTokens } from "../theme/constants/styleTokens";
|
|
10
|
+
import { getSxStyles } from "../utils/styles";
|
|
11
|
+
|
|
12
|
+
export interface ListProps extends MuiListProps {
|
|
13
|
+
maxHeight?: string;
|
|
14
|
+
// this may be updated later if Design needs any props to be removed
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The content of the subheader, normally `ListSubheader`.
|
|
18
|
+
*/
|
|
19
|
+
subheader?: React.ReactNode;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Toggles the display of the subheader. Set to `true` to show the subheader.
|
|
23
|
+
*/
|
|
24
|
+
showSubheader?: boolean;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Added padding between the list
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
padded?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The List component is useful for organizing related content or actions in a vertical format.
|
|
34
|
+
*
|
|
35
|
+
* `import List from '@carrier-io/air-react/List'`
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
const List = forwardRef<HTMLUListElement, ListProps>(
|
|
39
|
+
(
|
|
40
|
+
{ maxHeight, sx, subheader, showSubheader = true, padded = false, ...rest },
|
|
41
|
+
ref
|
|
42
|
+
) => {
|
|
43
|
+
return (
|
|
44
|
+
<MuiList
|
|
45
|
+
ref={ref}
|
|
46
|
+
{...rest}
|
|
47
|
+
sx={(theme: Theme) =>
|
|
48
|
+
({
|
|
49
|
+
backgroundColor: theme.palette.base?.background.paper,
|
|
50
|
+
maxHeight: maxHeight ?? "auto",
|
|
51
|
+
overflowY: maxHeight ? "auto" : "visible",
|
|
52
|
+
...(padded && {
|
|
53
|
+
".MuiListItem-root": {
|
|
54
|
+
padding: styleTokens.paddingItem,
|
|
55
|
+
},
|
|
56
|
+
".MuiListItemButton-root": {
|
|
57
|
+
padding: styleTokens.paddingItem,
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
...getSxStyles(theme, sx),
|
|
61
|
+
} as CSSObject)
|
|
62
|
+
}
|
|
63
|
+
subheader={showSubheader && subheader ? subheader : null}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
List.displayName = "List";
|
|
70
|
+
|
|
71
|
+
export default List;
|
|
72
|
+
export type { ListProps };
|