@carrier-dpx/air-react-library 0.7.36 → 0.7.38
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 +1 -1
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +0 -1
- package/src/components/Tabs/Tab.horizontal.figma.tsx +185 -0
- package/src/components/Tabs/Tab.tsx +65 -0
- package/src/components/Tabs/Tab.vertical.figma.tsx +171 -0
- package/src/components/Tabs/TabContext.tsx +15 -0
- package/src/components/Tabs/TabList.tsx +66 -0
- package/src/components/Tabs/TabPanel.tsx +35 -0
- package/src/components/Tabs/TabScrollButton.tsx +23 -0
- package/src/components/Tabs/Tabs.horizontal.figma.tsx +86 -0
- package/src/components/Tabs/Tabs.tsx +160 -0
- package/src/components/Tabs/Tabs.vertical.figma.tsx +88 -0
- package/src/components/Tabs/index.ts +19 -0
- package/src/components/Tabs/styles.ts +9 -0
- package/src/components/Tag/Tag.figma.tsx +1 -0
- package/src/index.ts +9 -0
- package/src/components/Icon/ArrowLeftIcon.figma.tsx +0 -33
- package/src/components/Icon/ArrowRightIcon.figma.tsx +0 -33
- package/src/components/Icon/CheckIcon.figma.tsx +0 -33
- package/src/components/Icon/CloseIcon.figma.tsx +0 -33
- package/src/components/Icon/HomeIcon.figma.tsx +0 -33
- package/src/components/Icon/InfoIcon.figma.tsx +0 -33
- package/src/components/Icon/MenuIcon.figma.tsx +0 -33
- package/src/components/Icon/SearchIcon.figma.tsx +0 -33
- package/src/components/Icon/SettingsIcon.figma.tsx +0 -61
- package/src/components/Icon/UserIcon.figma.tsx +0 -33
package/package.json
CHANGED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Code Connect Configuration for Tab Component (Horizontal)
|
|
3
|
+
*
|
|
4
|
+
* Figma URL: https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=23369-17683
|
|
5
|
+
*
|
|
6
|
+
* Figma Properties:
|
|
7
|
+
* - selected (true, false)
|
|
8
|
+
* - indicatorWidth (content, full)
|
|
9
|
+
* - invertIndicator (true, false)
|
|
10
|
+
* - disabled (true, false)
|
|
11
|
+
* - state (enabled, hover, focus) - visual state, not a prop
|
|
12
|
+
* - label (true, false) - boolean hide/show
|
|
13
|
+
* - startAdornment (true, false) - boolean hide/show
|
|
14
|
+
* - endAdornment (true, false) - boolean hide/show
|
|
15
|
+
*
|
|
16
|
+
* Note: indicatorWidth and invertIndicator are Tabs-level props, but are included
|
|
17
|
+
* here as they may be visually represented in Figma's Tab component.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import figma from "@figma/code-connect";
|
|
21
|
+
import Tab from "./Tab";
|
|
22
|
+
|
|
23
|
+
figma.connect(
|
|
24
|
+
Tab,
|
|
25
|
+
"https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=23369-17683",
|
|
26
|
+
{
|
|
27
|
+
props: {
|
|
28
|
+
/**
|
|
29
|
+
* SELECTED STATE
|
|
30
|
+
* Maps Figma's "selected" boolean to React's "selected" prop
|
|
31
|
+
*/
|
|
32
|
+
selected: figma.boolean("selected"),
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* INDICATOR WIDTH
|
|
36
|
+
* Maps Figma's "indicatorWidth" property
|
|
37
|
+
* Note: This is typically a Tabs-level prop, but may be visually represented in Figma
|
|
38
|
+
*/
|
|
39
|
+
indicatorWidth: figma.enum("indicatorWidth", {
|
|
40
|
+
content: "content",
|
|
41
|
+
full: "full",
|
|
42
|
+
}),
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* INVERT INDICATOR
|
|
46
|
+
* Maps Figma's "invertIndicator" boolean
|
|
47
|
+
* Note: This is typically a Tabs-level prop, but may be visually represented in Figma
|
|
48
|
+
*/
|
|
49
|
+
invertIndicator: figma.boolean("invertIndicator"),
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* DISABLED STATE
|
|
53
|
+
* Maps Figma's "disabled" boolean to React's "disabled" prop
|
|
54
|
+
*/
|
|
55
|
+
disabled: figma.boolean("disabled"),
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* LABEL VISIBILITY
|
|
59
|
+
* Maps Figma's "label" boolean - controls visibility of label text
|
|
60
|
+
*/
|
|
61
|
+
showLabel: figma.boolean("label"),
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* LABEL TEXT CONTENT
|
|
65
|
+
* Maps text content from nested "Label" Typography component
|
|
66
|
+
*/
|
|
67
|
+
labelText: figma.nestedProps("Label", {
|
|
68
|
+
children: figma.children("Label"),
|
|
69
|
+
}),
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* START ADORNMENT VISIBILITY
|
|
73
|
+
* Maps Figma's "startAdornment" boolean - controls visibility of start icon
|
|
74
|
+
*/
|
|
75
|
+
showStartAdornment: figma.boolean("startAdornment"),
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* START ADORNMENT ICON INSTANCE
|
|
79
|
+
* Maps nested Icon component instance when startAdornment is visible
|
|
80
|
+
* Uses figma.instance() to get the Icon component instance
|
|
81
|
+
*/
|
|
82
|
+
startIcon: figma.instance("startAdornment"),
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* END ADORNMENT VISIBILITY
|
|
86
|
+
* Maps Figma's "endAdornment" boolean - controls visibility of end icon
|
|
87
|
+
*/
|
|
88
|
+
showEndAdornment: figma.boolean("endAdornment"),
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* END ADORNMENT ICON INSTANCE
|
|
92
|
+
* Maps nested Icon component instance when endAdornment is visible
|
|
93
|
+
* Uses figma.instance() to get the Icon component instance
|
|
94
|
+
*/
|
|
95
|
+
endIcon: figma.instance("endAdornment"),
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* EXAMPLE CODE TEMPLATE
|
|
100
|
+
* Horizontal Tab - handles label, startAdornment, and endAdornment visibility
|
|
101
|
+
*/
|
|
102
|
+
example: ({ selected, disabled, showLabel, labelText, showStartAdornment, startIcon, showEndAdornment, endIcon }) => {
|
|
103
|
+
// Handle case with label and both adornments
|
|
104
|
+
// Note: MUI Tab only supports one icon, so we prioritize startAdornment
|
|
105
|
+
if (showLabel && labelText && labelText.children && showStartAdornment && startIcon && showEndAdornment && endIcon) {
|
|
106
|
+
return (
|
|
107
|
+
<Tab
|
|
108
|
+
selected={selected}
|
|
109
|
+
disabled={disabled}
|
|
110
|
+
label={labelText.children}
|
|
111
|
+
icon={startIcon}
|
|
112
|
+
iconPosition="start"
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Handle case with label and startAdornment only
|
|
118
|
+
if (showLabel && labelText && labelText.children && showStartAdornment && startIcon) {
|
|
119
|
+
return (
|
|
120
|
+
<Tab
|
|
121
|
+
selected={selected}
|
|
122
|
+
disabled={disabled}
|
|
123
|
+
label={labelText.children}
|
|
124
|
+
icon={startIcon}
|
|
125
|
+
iconPosition="start"
|
|
126
|
+
/>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Handle case with label and endAdornment only
|
|
131
|
+
if (showLabel && labelText && labelText.children && showEndAdornment && endIcon) {
|
|
132
|
+
return (
|
|
133
|
+
<Tab
|
|
134
|
+
selected={selected}
|
|
135
|
+
disabled={disabled}
|
|
136
|
+
label={labelText.children}
|
|
137
|
+
icon={endIcon}
|
|
138
|
+
iconPosition="end"
|
|
139
|
+
/>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Handle case with label only
|
|
144
|
+
if (showLabel && labelText && labelText.children) {
|
|
145
|
+
return (
|
|
146
|
+
<Tab
|
|
147
|
+
selected={selected}
|
|
148
|
+
disabled={disabled}
|
|
149
|
+
label={labelText.children}
|
|
150
|
+
/>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Handle case with startAdornment only (no label)
|
|
155
|
+
if (showStartAdornment && startIcon) {
|
|
156
|
+
return (
|
|
157
|
+
<Tab
|
|
158
|
+
selected={selected}
|
|
159
|
+
disabled={disabled}
|
|
160
|
+
icon={startIcon}
|
|
161
|
+
/>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Handle case with endAdornment only (no label)
|
|
166
|
+
if (showEndAdornment && endIcon) {
|
|
167
|
+
return (
|
|
168
|
+
<Tab
|
|
169
|
+
selected={selected}
|
|
170
|
+
disabled={disabled}
|
|
171
|
+
icon={endIcon}
|
|
172
|
+
/>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Default case - no label, no adornments
|
|
177
|
+
return (
|
|
178
|
+
<Tab
|
|
179
|
+
selected={selected}
|
|
180
|
+
disabled={disabled}
|
|
181
|
+
/>
|
|
182
|
+
);
|
|
183
|
+
},
|
|
184
|
+
}
|
|
185
|
+
);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { forwardRef, Ref } from "react";
|
|
2
|
+
|
|
3
|
+
import MuiTab, { TabProps as MuiTabProps } from "@mui/material/Tab";
|
|
4
|
+
import { TouchRippleActions } from "@mui/material/ButtonBase/TouchRipple";
|
|
5
|
+
import { CSSObject, Theme } from "@mui/material/styles";
|
|
6
|
+
import { getSxStyles } from "../utils/styles";
|
|
7
|
+
|
|
8
|
+
export interface TabProps extends MuiTabProps {
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* A ref that points to the TouchRipple element.
|
|
12
|
+
*/
|
|
13
|
+
touchRippleRef?: Ref<TouchRippleActions>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Tab
|
|
17
|
+
*
|
|
18
|
+
* `import Tab from '@carrier-io/air-react/Tab'`
|
|
19
|
+
*/
|
|
20
|
+
const Tab = forwardRef<HTMLDivElement, TabProps>(({ sx, ...rest }, ref) => {
|
|
21
|
+
return (
|
|
22
|
+
<MuiTab
|
|
23
|
+
sx={(theme: Theme) =>
|
|
24
|
+
({
|
|
25
|
+
...getSxStyles(theme, sx),
|
|
26
|
+
...theme.typography.body2Semibold,
|
|
27
|
+
textTransform: "capitalize",
|
|
28
|
+
// Default/unselected: label and icon use base.state.active
|
|
29
|
+
color: theme.palette.base?.state.active,
|
|
30
|
+
"& .MuiTab-iconWrapper": {
|
|
31
|
+
color: theme.palette.base?.state.active,
|
|
32
|
+
},
|
|
33
|
+
// Hover state: label and icon use base.text.primary
|
|
34
|
+
"&:hover": {
|
|
35
|
+
color: theme.palette.base?.text.primary,
|
|
36
|
+
"& .MuiTab-iconWrapper": {
|
|
37
|
+
color: theme.palette.base?.text.primary,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
// Selected tab: label and icon use base.text.primary
|
|
41
|
+
"&.Mui-selected": {
|
|
42
|
+
color: theme.palette.base?.text.primary,
|
|
43
|
+
"& .MuiTab-iconWrapper": {
|
|
44
|
+
color: theme.palette.base?.text.primary,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
// Disabled tab: label and icon use base.text.disabled
|
|
48
|
+
"&.Mui-disabled": {
|
|
49
|
+
color: theme.palette.base?.text.disabled,
|
|
50
|
+
"& .MuiTab-iconWrapper": {
|
|
51
|
+
color: theme.palette.base?.state.disabledContent,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
} as CSSObject)
|
|
55
|
+
}
|
|
56
|
+
{...rest}
|
|
57
|
+
ref={ref}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
Tab.displayName = "Tab";
|
|
63
|
+
|
|
64
|
+
export default Tab;
|
|
65
|
+
export type { TabProps };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Code Connect Configuration for Tab Component (Vertical)
|
|
3
|
+
*
|
|
4
|
+
* Figma URL: https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=23626-42929
|
|
5
|
+
*
|
|
6
|
+
* Figma Properties:
|
|
7
|
+
* - selected (true, false)
|
|
8
|
+
* - invertIndicator (true, false)
|
|
9
|
+
* - disabled (true, false)
|
|
10
|
+
* - state (enabled, hover, focus) - visual state, not a prop
|
|
11
|
+
* - label (true, false) - boolean hide/show
|
|
12
|
+
* - startAdornment (true, false) - boolean hide/show
|
|
13
|
+
* - endAdornment (true, false) - boolean hide/show
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import figma from "@figma/code-connect";
|
|
17
|
+
import Tab from "./Tab";
|
|
18
|
+
|
|
19
|
+
figma.connect(
|
|
20
|
+
Tab,
|
|
21
|
+
"https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=23626-42929",
|
|
22
|
+
{
|
|
23
|
+
props: {
|
|
24
|
+
/**
|
|
25
|
+
* SELECTED STATE
|
|
26
|
+
* Maps Figma's "selected" boolean to React's "selected" prop
|
|
27
|
+
*/
|
|
28
|
+
selected: figma.boolean("selected"),
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* INVERT INDICATOR
|
|
32
|
+
* Maps Figma's "invertIndicator" boolean
|
|
33
|
+
* Note: This is typically a Tabs-level prop, but may be visually represented in Figma
|
|
34
|
+
*/
|
|
35
|
+
invertIndicator: figma.boolean("invertIndicator"),
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* DISABLED STATE
|
|
39
|
+
* Maps Figma's "disabled" boolean to React's "disabled" prop
|
|
40
|
+
*/
|
|
41
|
+
disabled: figma.boolean("disabled"),
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* LABEL VISIBILITY
|
|
45
|
+
* Maps Figma's "label" boolean - controls visibility of label text
|
|
46
|
+
*/
|
|
47
|
+
showLabel: figma.boolean("label"),
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* LABEL TEXT CONTENT
|
|
51
|
+
* Maps text content from nested "Label" Typography component
|
|
52
|
+
*/
|
|
53
|
+
labelText: figma.nestedProps("Label", {
|
|
54
|
+
children: figma.children("Label"),
|
|
55
|
+
}),
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* START ADORNMENT VISIBILITY
|
|
59
|
+
* Maps Figma's "startAdornment" boolean - controls visibility of start icon
|
|
60
|
+
*/
|
|
61
|
+
showStartAdornment: figma.boolean("startAdornment"),
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* START ADORNMENT ICON INSTANCE
|
|
65
|
+
* Maps nested Icon component instance when startAdornment is visible
|
|
66
|
+
* Uses figma.instance() to get the Icon component instance
|
|
67
|
+
*/
|
|
68
|
+
startIcon: figma.instance("startAdornment"),
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* END ADORNMENT VISIBILITY
|
|
72
|
+
* Maps Figma's "endAdornment" boolean - controls visibility of end icon
|
|
73
|
+
*/
|
|
74
|
+
showEndAdornment: figma.boolean("endAdornment"),
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* END ADORNMENT ICON INSTANCE
|
|
78
|
+
* Maps nested Icon component instance when endAdornment is visible
|
|
79
|
+
* Uses figma.instance() to get the Icon component instance
|
|
80
|
+
*/
|
|
81
|
+
endIcon: figma.instance("endAdornment"),
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* EXAMPLE CODE TEMPLATE
|
|
86
|
+
* Vertical Tab - handles label, startAdornment, and endAdornment visibility
|
|
87
|
+
*/
|
|
88
|
+
example: ({ selected, disabled, showLabel, labelText, showStartAdornment, startIcon, showEndAdornment, endIcon }) => {
|
|
89
|
+
// Handle case with label and both adornments
|
|
90
|
+
// Note: MUI Tab only supports one icon, so we prioritize startAdornment
|
|
91
|
+
if (showLabel && labelText && labelText.children && showStartAdornment && startIcon && showEndAdornment && endIcon) {
|
|
92
|
+
return (
|
|
93
|
+
<Tab
|
|
94
|
+
selected={selected}
|
|
95
|
+
disabled={disabled}
|
|
96
|
+
label={labelText.children}
|
|
97
|
+
icon={startIcon}
|
|
98
|
+
iconPosition="start"
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Handle case with label and startAdornment only
|
|
104
|
+
if (showLabel && labelText && labelText.children && showStartAdornment && startIcon) {
|
|
105
|
+
return (
|
|
106
|
+
<Tab
|
|
107
|
+
selected={selected}
|
|
108
|
+
disabled={disabled}
|
|
109
|
+
label={labelText.children}
|
|
110
|
+
icon={startIcon}
|
|
111
|
+
iconPosition="start"
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Handle case with label and endAdornment only
|
|
117
|
+
if (showLabel && labelText && labelText.children && showEndAdornment && endIcon) {
|
|
118
|
+
return (
|
|
119
|
+
<Tab
|
|
120
|
+
selected={selected}
|
|
121
|
+
disabled={disabled}
|
|
122
|
+
label={labelText.children}
|
|
123
|
+
icon={endIcon}
|
|
124
|
+
iconPosition="end"
|
|
125
|
+
/>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Handle case with label only
|
|
130
|
+
if (showLabel && labelText && labelText.children) {
|
|
131
|
+
return (
|
|
132
|
+
<Tab
|
|
133
|
+
selected={selected}
|
|
134
|
+
disabled={disabled}
|
|
135
|
+
label={labelText.children}
|
|
136
|
+
/>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Handle case with startAdornment only (no label)
|
|
141
|
+
if (showStartAdornment && startIcon) {
|
|
142
|
+
return (
|
|
143
|
+
<Tab
|
|
144
|
+
selected={selected}
|
|
145
|
+
disabled={disabled}
|
|
146
|
+
icon={startIcon}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Handle case with endAdornment only (no label)
|
|
152
|
+
if (showEndAdornment && endIcon) {
|
|
153
|
+
return (
|
|
154
|
+
<Tab
|
|
155
|
+
selected={selected}
|
|
156
|
+
disabled={disabled}
|
|
157
|
+
icon={endIcon}
|
|
158
|
+
/>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Default case - no label, no adornments
|
|
163
|
+
return (
|
|
164
|
+
<Tab
|
|
165
|
+
selected={selected}
|
|
166
|
+
disabled={disabled}
|
|
167
|
+
/>
|
|
168
|
+
);
|
|
169
|
+
},
|
|
170
|
+
}
|
|
171
|
+
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import MuiTabContext, {
|
|
2
|
+
TabContextProps as MuiTabContextProps,
|
|
3
|
+
} from "@mui/lab/TabContext";
|
|
4
|
+
|
|
5
|
+
export interface TabContextProps extends MuiTabContextProps {}
|
|
6
|
+
|
|
7
|
+
/** TabContext
|
|
8
|
+
*
|
|
9
|
+
* `import { TabContext } from '@carrier-io/air-react'`
|
|
10
|
+
*/
|
|
11
|
+
export default function TabContext(props: TabContextProps) {
|
|
12
|
+
return <MuiTabContext {...props} />;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type { TabContextProps };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import MuiTabList, { TabListProps as MuiTabListProps } from "@mui/lab/TabList";
|
|
4
|
+
|
|
5
|
+
export interface TabListProps extends MuiTabListProps {
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* Invert the indicator on the tab. Default set to bottom for "horizontal" orientation and right for "vertical" orientation.
|
|
9
|
+
*/
|
|
10
|
+
invertIndicator?: boolean;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* indicator variant
|
|
14
|
+
* @default "line"
|
|
15
|
+
*/
|
|
16
|
+
indicatorVariant?: "line" | "standard";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* indicator width
|
|
20
|
+
*/
|
|
21
|
+
indicatorWidth?: "content" | "full";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** TabList
|
|
25
|
+
*
|
|
26
|
+
* `import { TabList } from '@carrier-io/air-react'`
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const indicatorInvertStyle = {
|
|
30
|
+
right: "unset",
|
|
31
|
+
borderBottomRightRadius: 4,
|
|
32
|
+
borderBottomLeftRadius: 0,
|
|
33
|
+
borderTopLeftRadius: 0,
|
|
34
|
+
borderTopRightRadius: 4,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const TabList = forwardRef<HTMLButtonElement, TabListProps>(
|
|
38
|
+
({ invertIndicator, indicatorVariant, indicatorWidth, ...props }, ref) => {
|
|
39
|
+
const rootClassNames = `${
|
|
40
|
+
indicatorWidth === "full"
|
|
41
|
+
? "MuiTab-indicator__full"
|
|
42
|
+
: "MuiTab-indicator__content"
|
|
43
|
+
}`;
|
|
44
|
+
const indicatorClassNames = `${
|
|
45
|
+
indicatorVariant === "line"
|
|
46
|
+
? "MuiTab-indicator__line"
|
|
47
|
+
: "MuiTab-indicator__standard"
|
|
48
|
+
}`;
|
|
49
|
+
return (
|
|
50
|
+
<MuiTabList
|
|
51
|
+
{...props}
|
|
52
|
+
ref={ref}
|
|
53
|
+
TabIndicatorProps={{
|
|
54
|
+
...(invertIndicator ? { style: indicatorInvertStyle } : undefined),
|
|
55
|
+
...props.TabIndicatorProps,
|
|
56
|
+
}}
|
|
57
|
+
className={[rootClassNames, indicatorClassNames].join(" ")}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
TabList.displayName = "TabList";
|
|
64
|
+
|
|
65
|
+
export default TabList;
|
|
66
|
+
export type { TabListProps };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import MuiTabPanel, {
|
|
4
|
+
TabPanelProps as MuiTabPanelProps,
|
|
5
|
+
} from "@mui/lab/TabPanel";
|
|
6
|
+
import { Theme } from "@mui/material/styles";
|
|
7
|
+
import { getSxStyles } from "../utils/styles";
|
|
8
|
+
|
|
9
|
+
export interface TabPanelProps extends MuiTabPanelProps {}
|
|
10
|
+
|
|
11
|
+
/** TabPanel
|
|
12
|
+
*
|
|
13
|
+
* `import { TabPanel } from '@carrier-io/air-react'`
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const TabPanel = forwardRef<unknown, TabPanelProps>(({ sx, ...props }, ref) => {
|
|
17
|
+
return (
|
|
18
|
+
<MuiTabPanel
|
|
19
|
+
sx={
|
|
20
|
+
((theme: Theme) => ({
|
|
21
|
+
...getSxStyles(theme, sx),
|
|
22
|
+
// Apply base.text.primary color to panel content for dark theme support
|
|
23
|
+
color: theme.palette.base?.text.primary || theme.palette.text.primary,
|
|
24
|
+
})) as any
|
|
25
|
+
}
|
|
26
|
+
{...props}
|
|
27
|
+
ref={ref}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
TabPanel.displayName = "TabPanel";
|
|
33
|
+
|
|
34
|
+
export default TabPanel;
|
|
35
|
+
export type { TabPanelProps };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
|
|
3
|
+
import MuiTabScrollButton, {
|
|
4
|
+
TabScrollButtonProps as MuiTabScrollButtonProps,
|
|
5
|
+
} from "@mui/material/TabScrollButton";
|
|
6
|
+
|
|
7
|
+
export interface TabScrollButtonProps extends MuiTabScrollButtonProps {}
|
|
8
|
+
|
|
9
|
+
/** TabScrollButton
|
|
10
|
+
*
|
|
11
|
+
* `import { TabScrollButton } from '@carrier-io/air-react'`
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const TabScrollButton = forwardRef<HTMLDivElement, TabScrollButtonProps>(
|
|
15
|
+
(props, ref) => {
|
|
16
|
+
return <MuiTabScrollButton {...props} ref={ref} />;
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
TabScrollButton.displayName = "TabScrollButton";
|
|
21
|
+
|
|
22
|
+
export default TabScrollButton;
|
|
23
|
+
export type { TabScrollButtonProps };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Code Connect Configuration for Tabs Component (Horizontal)
|
|
3
|
+
*
|
|
4
|
+
* Figma URL: https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=17801-86244
|
|
5
|
+
*
|
|
6
|
+
* Figma Properties:
|
|
7
|
+
* - variant (group-left, group-center, group-right, full-width, scrollable)
|
|
8
|
+
* - disabled (true, false)
|
|
9
|
+
* - divider (true, false)
|
|
10
|
+
*
|
|
11
|
+
* Structure:
|
|
12
|
+
* - Tab 1-8: Multiple Tab instances with numbered layer names
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import figma from "@figma/code-connect";
|
|
16
|
+
import Tabs from "./Tabs";
|
|
17
|
+
import Tab from "./Tab";
|
|
18
|
+
|
|
19
|
+
figma.connect(
|
|
20
|
+
Tabs,
|
|
21
|
+
"https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=17801-86244",
|
|
22
|
+
{
|
|
23
|
+
props: {
|
|
24
|
+
/**
|
|
25
|
+
* VARIANT MAPPING
|
|
26
|
+
* Maps Figma's "variant" property to React's "variant" prop
|
|
27
|
+
*/
|
|
28
|
+
variant: figma.enum("variant", {
|
|
29
|
+
"group-left": "group-left",
|
|
30
|
+
"group-center": "group-center",
|
|
31
|
+
"group-right": "group-right",
|
|
32
|
+
"full-width": "full-width",
|
|
33
|
+
scrollable: "scrollable",
|
|
34
|
+
}),
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* DISABLED STATE
|
|
38
|
+
* Maps Figma's "disabled" boolean to React's "disabled" prop
|
|
39
|
+
*/
|
|
40
|
+
disabled: figma.boolean("disabled"),
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* DIVIDER VISIBILITY
|
|
44
|
+
* Maps Figma's "divider" boolean - controls divider visibility
|
|
45
|
+
*/
|
|
46
|
+
divider: figma.boolean("divider"),
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* TAB CHILDREN
|
|
50
|
+
* Maps nested Tab instances from Figma
|
|
51
|
+
* Each "Tab X" is an instance of the Tab component
|
|
52
|
+
*/
|
|
53
|
+
tab1: figma.children("Tab 1"),
|
|
54
|
+
tab2: figma.children("Tab 2"),
|
|
55
|
+
tab3: figma.children("Tab 3"),
|
|
56
|
+
tab4: figma.children("Tab 4"),
|
|
57
|
+
tab5: figma.children("Tab 5"),
|
|
58
|
+
tab6: figma.children("Tab 6"),
|
|
59
|
+
tab7: figma.children("Tab 7"),
|
|
60
|
+
tab8: figma.children("Tab 8"),
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* EXAMPLE CODE TEMPLATE
|
|
65
|
+
* Horizontal Tabs - sets orientation="horizontal"
|
|
66
|
+
*/
|
|
67
|
+
example: ({ variant, disabled, tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8 }) => (
|
|
68
|
+
<Tabs
|
|
69
|
+
orientation="horizontal"
|
|
70
|
+
variant={variant}
|
|
71
|
+
disabled={disabled}
|
|
72
|
+
value={0}
|
|
73
|
+
onChange={() => {}}
|
|
74
|
+
>
|
|
75
|
+
{tab1}
|
|
76
|
+
{tab2}
|
|
77
|
+
{tab3}
|
|
78
|
+
{tab4}
|
|
79
|
+
{tab5}
|
|
80
|
+
{tab6}
|
|
81
|
+
{tab7}
|
|
82
|
+
{tab8}
|
|
83
|
+
</Tabs>
|
|
84
|
+
),
|
|
85
|
+
}
|
|
86
|
+
);
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { forwardRef, Ref } from "react";
|
|
2
|
+
|
|
3
|
+
import MuiTabs, { TabsProps as MuiTabsProps } from "@mui/material/Tabs";
|
|
4
|
+
import { TouchRippleActions } from "@mui/material/ButtonBase/TouchRipple";
|
|
5
|
+
import { baseTabsSx } from "./styles";
|
|
6
|
+
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
|
|
7
|
+
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
|
8
|
+
import TabScrollButton, {
|
|
9
|
+
TabScrollButtonProps,
|
|
10
|
+
} from "@mui/material/TabScrollButton";
|
|
11
|
+
|
|
12
|
+
export interface TabsProps extends Omit<MuiTabsProps, "centered" | "variant"> {
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* A ref that points to the TouchRipple element.
|
|
16
|
+
*/
|
|
17
|
+
touchRippleRef?: Ref<TouchRippleActions>;
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* Invert the indicator on the tab. Default set to bottom for "horizontal" orientation and right for "vertical" orientation.
|
|
21
|
+
*/
|
|
22
|
+
invertIndicator?: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* indicator variant
|
|
26
|
+
* @default "line"
|
|
27
|
+
*/
|
|
28
|
+
indicatorVariant?: "line" | "standard";
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* indicator width
|
|
32
|
+
*/
|
|
33
|
+
indicatorWidth?: "content" | "full";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Determines additional display behavior of the tabs:
|
|
37
|
+
*
|
|
38
|
+
* - `scrollable` will invoke scrolling properties and allow for horizontally
|
|
39
|
+
* scrolling (or swiping) of the tab bar.
|
|
40
|
+
* - `fullWidth` will make the tabs grow to use all the available space,
|
|
41
|
+
* which should be used for small views, like on mobile.
|
|
42
|
+
* - `group-left` will align the tabs to the left within the available space.
|
|
43
|
+
* - `group-center` will center-align the tabs within the available space.
|
|
44
|
+
* - `group-right` will align the tabs to the right within the available space.
|
|
45
|
+
* @default 'group-left'
|
|
46
|
+
*/
|
|
47
|
+
variant?:
|
|
48
|
+
| "scrollable"
|
|
49
|
+
| "full-width"
|
|
50
|
+
| "group-left"
|
|
51
|
+
| "group-center"
|
|
52
|
+
| "group-right";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const indicatorInvertStyle = {
|
|
56
|
+
bottom: "unset",
|
|
57
|
+
top: 0,
|
|
58
|
+
borderBottomRightRadius: 4,
|
|
59
|
+
borderBottomLeftRadius: 4,
|
|
60
|
+
borderTopLeftRadius: 0,
|
|
61
|
+
borderTopRightRadius: 0,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const ScrollButton = ({
|
|
65
|
+
direction,
|
|
66
|
+
onClick,
|
|
67
|
+
orientation = "horizontal",
|
|
68
|
+
...props
|
|
69
|
+
}: TabScrollButtonProps) => {
|
|
70
|
+
return (
|
|
71
|
+
<TabScrollButton
|
|
72
|
+
orientation={orientation}
|
|
73
|
+
{...props}
|
|
74
|
+
direction={direction}
|
|
75
|
+
onClick={onClick}
|
|
76
|
+
>
|
|
77
|
+
{direction === "left" ? (
|
|
78
|
+
<ChevronLeftIcon fontSize="small" />
|
|
79
|
+
) : (
|
|
80
|
+
<ChevronRightIcon fontSize="small" />
|
|
81
|
+
)}
|
|
82
|
+
</TabScrollButton>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/** The Tabs component is useful for organizing views of related content and allowing users to switch between them.
|
|
87
|
+
*
|
|
88
|
+
* `import { Tabs, Tab, TabContext, TabList, TabPanel, TabScrollButton } from '@carrier-io/air-react'`
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
const Tabs = forwardRef<HTMLButtonElement, TabsProps>(
|
|
92
|
+
(
|
|
93
|
+
{
|
|
94
|
+
invertIndicator,
|
|
95
|
+
indicatorVariant = "line",
|
|
96
|
+
indicatorWidth = "content",
|
|
97
|
+
variant = "group-left",
|
|
98
|
+
visibleScrollbar = false,
|
|
99
|
+
...props
|
|
100
|
+
},
|
|
101
|
+
ref
|
|
102
|
+
) => {
|
|
103
|
+
const rootClassNames = `${
|
|
104
|
+
indicatorWidth === "full"
|
|
105
|
+
? "MuiTab-indicator__full"
|
|
106
|
+
: "MuiTab-indicator__content"
|
|
107
|
+
}`;
|
|
108
|
+
const indicatorClassNames = `${
|
|
109
|
+
indicatorVariant === "line"
|
|
110
|
+
? "MuiTab-indicator__line"
|
|
111
|
+
: "MuiTab-indicator__standard"
|
|
112
|
+
}`;
|
|
113
|
+
|
|
114
|
+
let justifyContentValue: "left" | "right" | "center" | undefined;
|
|
115
|
+
let componentVariant: "standard" | "scrollable" | "fullWidth" | undefined =
|
|
116
|
+
"standard";
|
|
117
|
+
|
|
118
|
+
switch (variant) {
|
|
119
|
+
case "group-center":
|
|
120
|
+
justifyContentValue = "center";
|
|
121
|
+
break;
|
|
122
|
+
case "group-left":
|
|
123
|
+
justifyContentValue = "left";
|
|
124
|
+
break;
|
|
125
|
+
case "group-right":
|
|
126
|
+
justifyContentValue = "right";
|
|
127
|
+
break;
|
|
128
|
+
case "full-width":
|
|
129
|
+
justifyContentValue = undefined;
|
|
130
|
+
componentVariant = "fullWidth";
|
|
131
|
+
break;
|
|
132
|
+
default:
|
|
133
|
+
justifyContentValue = undefined;
|
|
134
|
+
componentVariant = variant;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<MuiTabs
|
|
140
|
+
{...props}
|
|
141
|
+
ref={ref}
|
|
142
|
+
visibleScrollbar={visibleScrollbar}
|
|
143
|
+
ScrollButtonComponent={ScrollButton}
|
|
144
|
+
variant={componentVariant}
|
|
145
|
+
allowScrollButtonsMobile={props.allowScrollButtonsMobile || false}
|
|
146
|
+
sx={baseTabsSx(justifyContentValue)}
|
|
147
|
+
className={[rootClassNames, indicatorClassNames].join(" ")}
|
|
148
|
+
TabIndicatorProps={{
|
|
149
|
+
...(invertIndicator ? { style: indicatorInvertStyle } : undefined),
|
|
150
|
+
...props.TabIndicatorProps,
|
|
151
|
+
}}
|
|
152
|
+
/>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
Tabs.displayName = "Tabs";
|
|
158
|
+
|
|
159
|
+
export default Tabs;
|
|
160
|
+
export type { TabsProps };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma Code Connect Configuration for Tabs Component (Vertical)
|
|
3
|
+
*
|
|
4
|
+
* Figma URL: https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=23641-53725
|
|
5
|
+
*
|
|
6
|
+
* Figma Properties:
|
|
7
|
+
* - scrollable (true, false)
|
|
8
|
+
* - disabled (true, false)
|
|
9
|
+
* - divider (true, false)
|
|
10
|
+
*
|
|
11
|
+
* Structure:
|
|
12
|
+
* - Tab 1-8: Multiple Tab instances with numbered layer names
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import figma from "@figma/code-connect";
|
|
16
|
+
import Tabs from "./Tabs";
|
|
17
|
+
import Tab from "./Tab";
|
|
18
|
+
|
|
19
|
+
figma.connect(
|
|
20
|
+
Tabs,
|
|
21
|
+
"https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=23641-53725",
|
|
22
|
+
{
|
|
23
|
+
props: {
|
|
24
|
+
/**
|
|
25
|
+
* SCROLLABLE VARIANT
|
|
26
|
+
* Maps Figma's "scrollable" boolean to React's "variant" prop
|
|
27
|
+
* When true, variant="scrollable", otherwise variant="group-left" (default)
|
|
28
|
+
*/
|
|
29
|
+
scrollable: figma.boolean("scrollable"),
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* DISABLED STATE
|
|
33
|
+
* Maps Figma's "disabled" boolean to React's "disabled" prop
|
|
34
|
+
*/
|
|
35
|
+
disabled: figma.boolean("disabled"),
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* DIVIDER VISIBILITY
|
|
39
|
+
* Maps Figma's "divider" boolean - controls divider visibility
|
|
40
|
+
*/
|
|
41
|
+
divider: figma.boolean("divider"),
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* TAB CHILDREN
|
|
45
|
+
* Maps nested Tab instances from Figma
|
|
46
|
+
* Each "Tab X" is an instance of the Tab component
|
|
47
|
+
*/
|
|
48
|
+
tab1: figma.children("Tab 1"),
|
|
49
|
+
tab2: figma.children("Tab 2"),
|
|
50
|
+
tab3: figma.children("Tab 3"),
|
|
51
|
+
tab4: figma.children("Tab 4"),
|
|
52
|
+
tab5: figma.children("Tab 5"),
|
|
53
|
+
tab6: figma.children("Tab 6"),
|
|
54
|
+
tab7: figma.children("Tab 7"),
|
|
55
|
+
tab8: figma.children("Tab 8"),
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* EXAMPLE CODE TEMPLATE
|
|
60
|
+
* Vertical Tabs - sets orientation="vertical"
|
|
61
|
+
*/
|
|
62
|
+
example: ({ scrollable, disabled, tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8 }) => {
|
|
63
|
+
let variant: "scrollable" | "group-left" = "group-left";
|
|
64
|
+
if (scrollable) {
|
|
65
|
+
variant = "scrollable";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<Tabs
|
|
70
|
+
orientation="vertical"
|
|
71
|
+
variant={variant}
|
|
72
|
+
disabled={disabled}
|
|
73
|
+
value={0}
|
|
74
|
+
onChange={() => {}}
|
|
75
|
+
>
|
|
76
|
+
{tab1}
|
|
77
|
+
{tab2}
|
|
78
|
+
{tab3}
|
|
79
|
+
{tab4}
|
|
80
|
+
{tab5}
|
|
81
|
+
{tab6}
|
|
82
|
+
{tab7}
|
|
83
|
+
{tab8}
|
|
84
|
+
</Tabs>
|
|
85
|
+
);
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Tabs component family exports
|
|
2
|
+
export { default } from "./Tabs"; // For: import Tabs from "Tabs"
|
|
3
|
+
export { default as Tabs } from "./Tabs"; // For: import { Tabs } from "Tabs"
|
|
4
|
+
export * from "./Tabs"; // For: TabsProps, etc.
|
|
5
|
+
|
|
6
|
+
export { default as Tab } from "./Tab";
|
|
7
|
+
export * from "./Tab";
|
|
8
|
+
|
|
9
|
+
export { default as TabContext } from "./TabContext";
|
|
10
|
+
export * from "./TabContext";
|
|
11
|
+
|
|
12
|
+
export { default as TabList } from "./TabList";
|
|
13
|
+
export * from "./TabList";
|
|
14
|
+
|
|
15
|
+
export { default as TabPanel } from "./TabPanel";
|
|
16
|
+
export * from "./TabPanel";
|
|
17
|
+
|
|
18
|
+
export { default as TabScrollButton } from "./TabScrollButton";
|
|
19
|
+
export * from "./TabScrollButton";
|
package/src/index.ts
CHANGED
|
@@ -63,6 +63,15 @@ export { default as Tag } from "./components/Tag";
|
|
|
63
63
|
export type { TagProps } from "./components/Tag";
|
|
64
64
|
export { default as Breadcrumbs, BreadcrumbLink } from "./components/Breadcrumbs";
|
|
65
65
|
export type { BreadcrumbsProps, BreadcrumbLinkProps } from "./components/Breadcrumbs";
|
|
66
|
+
export * from "./components/Tabs";
|
|
67
|
+
export type {
|
|
68
|
+
TabsProps,
|
|
69
|
+
TabProps,
|
|
70
|
+
TabListProps,
|
|
71
|
+
TabPanelProps,
|
|
72
|
+
TabContextProps,
|
|
73
|
+
TabScrollButtonProps,
|
|
74
|
+
} from "./components/Tabs";
|
|
66
75
|
export * from "./components/theme";
|
|
67
76
|
|
|
68
77
|
// Demo Icons - exported from main index to avoid deep-path imports
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for ArrowLeft Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import ArrowLeftIcon from your actual icon library package.
|
|
5
|
-
* Example: import { ArrowLeftIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { ArrowLeftIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual ArrowLeftIcon import
|
|
14
|
-
const ArrowLeftIcon = ({ variant, ...props }: any) => <span {...props}>ArrowLeftIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// ArrowLeftIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=ARROW-LEFT-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <ArrowLeftIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for ArrowRight Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import ArrowRightIcon from your actual icon library package.
|
|
5
|
-
* Example: import { ArrowRightIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { ArrowRightIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual ArrowRightIcon import
|
|
14
|
-
const ArrowRightIcon = ({ variant, ...props }: any) => <span {...props}>ArrowRightIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// ArrowRightIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=ARROW-RIGHT-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <ArrowRightIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for Check Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import CheckIcon from your actual icon library package.
|
|
5
|
-
* Example: import { CheckIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { CheckIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual CheckIcon import
|
|
14
|
-
const CheckIcon = ({ variant, ...props }: any) => <span {...props}>CheckIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// CheckIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=CHECK-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <CheckIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for Close Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import CloseIcon from your actual icon library package.
|
|
5
|
-
* Example: import { CloseIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { CloseIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual CloseIcon import
|
|
14
|
-
const CloseIcon = ({ variant, ...props }: any) => <span {...props}>CloseIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// CloseIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=CLOSE-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <CloseIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for Home Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import HomeIcon from your actual icon library package.
|
|
5
|
-
* Example: import { HomeIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { HomeIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual HomeIcon import
|
|
14
|
-
const HomeIcon = ({ variant, ...props }: any) => <span {...props}>HomeIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// HomeIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=HOME-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <HomeIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for Info Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import InfoIcon from your actual icon library package.
|
|
5
|
-
* Example: import { InfoIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { InfoIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual InfoIcon import
|
|
14
|
-
const InfoIcon = ({ variant, ...props }: any) => <span {...props}>InfoIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// InfoIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=INFO-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <InfoIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for Menu Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import MenuIcon from your actual icon library package.
|
|
5
|
-
* Example: import { MenuIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { MenuIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual MenuIcon import
|
|
14
|
-
const MenuIcon = ({ variant, ...props }: any) => <span {...props}>MenuIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// MenuIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=MENU-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <MenuIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for Search Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import SearchIcon from your actual icon library package.
|
|
5
|
-
* Example: import { SearchIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { SearchIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual SearchIcon import
|
|
14
|
-
const SearchIcon = ({ variant, ...props }: any) => <span {...props}>SearchIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// SearchIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=SEARCH-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <SearchIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for Settings Icon
|
|
3
|
-
*
|
|
4
|
-
* This connects Figma's SettingsIcon component to the React SettingsIcon component.
|
|
5
|
-
* The icon component is wrapped in the Icon wrapper for fontSize control.
|
|
6
|
-
*
|
|
7
|
-
* Figma URL: https://www.figma.com/design/RT43n0bKuuIt7ylllD3DR0/Icon-Library?node-id=31-2
|
|
8
|
-
*
|
|
9
|
-
* NOTE: Import SettingsIcon from your actual icon library package.
|
|
10
|
-
* Example: import { SettingsIcon } from '@carrier-io/icons';
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import figma from "@figma/code-connect";
|
|
14
|
-
import Icon from "./Icon";
|
|
15
|
-
// TODO: Import from your actual icon library
|
|
16
|
-
// import { SettingsIcon } from '@carrier-io/icons';
|
|
17
|
-
|
|
18
|
-
// Placeholder - replace with actual SettingsIcon import
|
|
19
|
-
const SettingsIcon = ({ variant, ...props }: any) => <span {...props}>SettingsIcon</span>;
|
|
20
|
-
|
|
21
|
-
figma.connect(
|
|
22
|
-
SettingsIcon,
|
|
23
|
-
"https://www.figma.com/design/RT43n0bKuuIt7ylllD3DR0/Icon-Library?node-id=31-2",
|
|
24
|
-
{
|
|
25
|
-
props: {
|
|
26
|
-
/**
|
|
27
|
-
* STYLE MAPPING
|
|
28
|
-
* Maps Figma's "Style" property to the icon component's "variant" prop
|
|
29
|
-
* Figma uses "Style" with values "Outlined" and "Filled"
|
|
30
|
-
* React icon component expects "variant" with values "outlined" and "filled"
|
|
31
|
-
*/
|
|
32
|
-
variant: figma.enum("Style", {
|
|
33
|
-
Outlined: "outlined",
|
|
34
|
-
Filled: "filled",
|
|
35
|
-
}),
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* FONT SIZE MAPPING (optional)
|
|
39
|
-
* If your Figma icon component has a fontSize property, map it here
|
|
40
|
-
* Otherwise, fontSize is set on the Icon wrapper component
|
|
41
|
-
*/
|
|
42
|
-
// fontSize: figma.enum("fontSize", {
|
|
43
|
-
// "xsmall-12px": "xsmall",
|
|
44
|
-
// "small-16px": "small",
|
|
45
|
-
// "medium-24px": "medium",
|
|
46
|
-
// "large-32px": "large",
|
|
47
|
-
// }),
|
|
48
|
-
},
|
|
49
|
-
/**
|
|
50
|
-
* EXAMPLE CODE TEMPLATE
|
|
51
|
-
* Shows the icon component wrapped in Icon for fontSize control.
|
|
52
|
-
* The Icon wrapper handles fontSize (xsmall, small, medium, large).
|
|
53
|
-
* The icon component handles variant (outlined, filled).
|
|
54
|
-
*/
|
|
55
|
-
example: ({ variant }) => (
|
|
56
|
-
<Icon fontSize="medium">
|
|
57
|
-
<SettingsIcon variant={variant} />
|
|
58
|
-
</Icon>
|
|
59
|
-
),
|
|
60
|
-
}
|
|
61
|
-
);
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Figma Code Connect Configuration for User Icon
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Import UserIcon from your actual icon library package.
|
|
5
|
-
* Example: import { UserIcon } from '@carrier-io/icons';
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import figma from "@figma/code-connect";
|
|
9
|
-
import Icon from "./Icon";
|
|
10
|
-
// TODO: Import from your actual icon library
|
|
11
|
-
// import { UserIcon } from '@carrier-io/icons';
|
|
12
|
-
|
|
13
|
-
// Placeholder - replace with actual UserIcon import
|
|
14
|
-
const UserIcon = ({ variant, ...props }: any) => <span {...props}>UserIcon</span>;
|
|
15
|
-
|
|
16
|
-
// TODO: Uncomment and update with real Figma URL when ready
|
|
17
|
-
// figma.connect(
|
|
18
|
-
// UserIcon,
|
|
19
|
-
// "https://www.figma.com/design/vkoHdM6rchIhH9IWetZeP0/Air--Components?node-id=USER-ICON-NODE-ID",
|
|
20
|
-
// {
|
|
21
|
-
// props: {
|
|
22
|
-
// variant: figma.enum("variant", {
|
|
23
|
-
// outlined: "outlined",
|
|
24
|
-
// filled: "filled",
|
|
25
|
-
// }),
|
|
26
|
-
// },
|
|
27
|
-
// example: ({ variant }) => (
|
|
28
|
-
// <Icon fontSize="medium">
|
|
29
|
-
// <UserIcon variant={variant} />
|
|
30
|
-
// </Icon>
|
|
31
|
-
// ),
|
|
32
|
-
// }
|
|
33
|
-
// );
|