@sproutsocial/seeds-react-tabs 1.0.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/.eslintignore ADDED
@@ -0,0 +1,6 @@
1
+ # Node modules
2
+ node_modules/
3
+
4
+ # Build output
5
+ dist/
6
+ coverage/
package/.eslintrc.js ADDED
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: ["eslint-config-seeds/racine"],
4
+ };
@@ -0,0 +1,21 @@
1
+ yarn run v1.22.22
2
+ $ tsup --dts
3
+ CLI Building entry: src/index.ts
4
+ CLI Using tsconfig: tsconfig.json
5
+ CLI tsup v8.0.2
6
+ CLI Using tsup config: /home/runner/work/seeds/seeds/seeds-react/seeds-react-tabs/tsup.config.ts
7
+ CLI Target: es2022
8
+ CLI Cleaning output folder
9
+ CJS Build start
10
+ ESM Build start
11
+ CJS dist/index.js 7.71 KB
12
+ CJS dist/index.js.map 12.04 KB
13
+ CJS ⚡️ Build success in 159ms
14
+ ESM dist/esm/index.js 5.67 KB
15
+ ESM dist/esm/index.js.map 11.98 KB
16
+ ESM ⚡️ Build success in 160ms
17
+ DTS Build start
18
+ DTS ⚡️ Build success in 41689ms
19
+ DTS dist/index.d.ts 2.39 KB
20
+ DTS dist/index.d.mts 2.39 KB
21
+ Done in 49.01s.
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @sproutsocial/seeds-react-tabs
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - bd8d03d: Migrate tabs from Racine to seeds-react-tabs
@@ -0,0 +1,204 @@
1
+ // src/Tabs.tsx
2
+ import * as React2 from "react";
3
+
4
+ // src/styles.ts
5
+ import styled, { css } from "styled-components";
6
+ import { COMMON } from "@sproutsocial/seeds-react-system-props";
7
+ import { Button } from "@sproutsocial/seeds-react-button";
8
+
9
+ // src/TabsTypes.ts
10
+ import "react";
11
+
12
+ // src/styles.ts
13
+ var Container = styled.ul`
14
+ display: ${(props) => props.fullWidth ? "flex" : "inline-flex"};
15
+ justify-content: space-between;
16
+ margin: 0;
17
+ padding: 0;
18
+ list-style: none;
19
+ border-bottom: ${(props) => props.theme.borders[500]}
20
+ ${(props) => props.theme.colors.container.border.base};
21
+
22
+ ${COMMON}
23
+ `;
24
+ var TabItem = styled.li`
25
+ margin-bottom: -1px;
26
+ ${(props) => props.fullWidth && css`
27
+ flex-grow: 1;
28
+ `};
29
+
30
+ &:not(:last-child) {
31
+ ${(props) => !props.fullWidth && css`
32
+ margin-right: ${(props2) => props2.theme.space[350]};
33
+ `};
34
+ }
35
+
36
+ ${(props) => props.isSelected && css`
37
+ box-shadow: ${(props2) => `inset 0 -3px 0 0 ${props2.theme.colors.button.primary.background.base}`};
38
+ `};
39
+
40
+ &:hover {
41
+ ${(props) => props.isSelected && css`
42
+ box-shadow: ${(props2) => `inset 0 -3px 0 0 ${props2.theme.colors.button.primary.background.hover}`};
43
+ `};
44
+ }
45
+ `;
46
+ var TabButton = styled(Button)`
47
+ padding: ${(props) => `${props.theme.space[350]} 0`};
48
+ color: ${(props) => props.theme.colors.text.headline};
49
+ width: 100%;
50
+
51
+ ${(props) => props.isSelected && css`
52
+ color: ${(props2) => props2.theme.colors.link.base};
53
+ `};
54
+
55
+ &:hover {
56
+ ${(props) => props.isSelected && css`
57
+ color: ${(props2) => props2.theme.colors.link.hover};
58
+ `};
59
+ }
60
+
61
+ &:active {
62
+ transform: none;
63
+ }
64
+ `;
65
+ var styles_default = Container;
66
+
67
+ // src/Tabs.tsx
68
+ import { jsx } from "react/jsx-runtime";
69
+ var TabButtonContext = React2.createContext({});
70
+ var TabItemButton = class extends React2.Component {
71
+ static contextType = TabButtonContext;
72
+ // @ts-notes - using the legacy syntax here because `declare` does not play well with babel
73
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
74
+ //@ts-ignore
75
+ context;
76
+ buttonRef = React2.createRef();
77
+ componentDidMount() {
78
+ this.context.onTabMount?.(this.props.id, this.buttonRef);
79
+ }
80
+ componentDidUpdate(prevProps) {
81
+ if (prevProps.id !== this.props.id) {
82
+ this.context.onTabUpdate?.(prevProps.id, this.props.id);
83
+ }
84
+ }
85
+ componentWillUnmount() {
86
+ this.context.onTabUnmount?.(this.props.id);
87
+ }
88
+ render() {
89
+ const { children, id, ...rest } = this.props;
90
+ const { selectedId, onActivate, fullWidth } = this.context;
91
+ const isSelected = selectedId === id;
92
+ return /* @__PURE__ */ jsx(TabItem, { fullWidth, isSelected, children: /* @__PURE__ */ jsx(
93
+ TabButton,
94
+ {
95
+ innerRef: this.buttonRef,
96
+ id,
97
+ onClick: () => onActivate?.(id),
98
+ isSelected,
99
+ tabIndex: isSelected ? 0 : -1,
100
+ fullWidth,
101
+ "data-qa-tab-button": id,
102
+ "data-qa-tab-button-state": isSelected,
103
+ "aria-selected": isSelected,
104
+ role: "tab",
105
+ ...rest,
106
+ children
107
+ }
108
+ ) }, id);
109
+ }
110
+ };
111
+ var Tabs = class extends React2.Component {
112
+ static Button = TabItemButton;
113
+ buttonRefs = {};
114
+ tabList = [];
115
+ getSelectedId = () => this.props.selectedId;
116
+ onActivate = (id) => this.props.onSelect(id);
117
+ onTabMount = (id, ref) => {
118
+ if (!this.tabList.includes(id)) {
119
+ this.tabList.push(id);
120
+ this.buttonRefs[id] = ref;
121
+ }
122
+ };
123
+ onTabUpdate = (previousId, newId) => {
124
+ if (this.tabList.includes(previousId)) {
125
+ this.tabList = this.tabList.map((id) => id === previousId ? newId : id);
126
+ this.buttonRefs[newId] = this.buttonRefs[previousId];
127
+ this.buttonRefs[previousId] = void 0;
128
+ }
129
+ };
130
+ onTabUnmount = (id) => {
131
+ if (this.tabList.includes(id)) {
132
+ this.tabList = this.tabList.filter((currentId) => currentId !== id);
133
+ this.buttonRefs[id] = void 0;
134
+ }
135
+ };
136
+ selectNextTab = (id) => {
137
+ const buttonRef = this.buttonRefs[id];
138
+ this.props.onSelect(id);
139
+ buttonRef && buttonRef.current && buttonRef.current.focus && buttonRef.current.focus();
140
+ };
141
+ keyHandler = ({ keyCode }) => {
142
+ switch (keyCode) {
143
+ case 37:
144
+ this.tabList.forEach((id, index) => {
145
+ if (id === this.getSelectedId()) {
146
+ const count = this.tabList.length;
147
+ const nextIndex = index - 1 >= 0 ? index - 1 : count - 1;
148
+ const nextId = this.tabList[nextIndex];
149
+ this.selectNextTab(nextId ? nextId : "");
150
+ }
151
+ });
152
+ break;
153
+ case 39:
154
+ this.tabList.forEach((id, index) => {
155
+ if (id === this.getSelectedId()) {
156
+ const count = this.tabList.length;
157
+ const nextIndex = index + 1 < count ? index + 1 : 0;
158
+ const nextId = this.tabList[nextIndex];
159
+ this.selectNextTab(nextId ? nextId : "");
160
+ }
161
+ });
162
+ break;
163
+ default:
164
+ break;
165
+ }
166
+ };
167
+ render() {
168
+ const { children, qa, onSelect, ...rest } = this.props;
169
+ return /* @__PURE__ */ jsx(
170
+ styles_default,
171
+ {
172
+ "data-qa-tabs": "",
173
+ onKeyUp: this.keyHandler,
174
+ onSelect,
175
+ role: "tablist",
176
+ ...qa,
177
+ ...rest,
178
+ children: /* @__PURE__ */ jsx(
179
+ TabButtonContext.Provider,
180
+ {
181
+ value: {
182
+ selectedId: this.getSelectedId(),
183
+ fullWidth: this.props.fullWidth,
184
+ onActivate: this.onActivate,
185
+ onTabMount: this.onTabMount,
186
+ onTabUpdate: this.onTabUpdate,
187
+ onTabUnmount: this.onTabUnmount
188
+ },
189
+ children
190
+ }
191
+ )
192
+ }
193
+ );
194
+ }
195
+ };
196
+ var Tabs_default = Tabs;
197
+
198
+ // src/index.ts
199
+ var src_default = Tabs_default;
200
+ export {
201
+ Tabs_default as Tabs,
202
+ src_default as default
203
+ };
204
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/Tabs.tsx","../../src/styles.ts","../../src/TabsTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport Container, { TabItem, TabButton } from \"./styles\";\nimport type { TypeTabButtonsProps, TypeTabsProps } from \"./TabsTypes\";\n\ninterface TypeTabButtonRef {\n current: null | React.ElementRef<\"button\">;\n}\ninterface TypeTabButtonContext {\n onActivate: (arg0: string) => void;\n onTabMount: (id: string, ref: TypeTabButtonRef) => void;\n onTabUpdate: (previousId: string, nextId: string) => void;\n onTabUnmount: (id: string) => void;\n selectedId: string;\n fullWidth?: boolean;\n}\n\nconst TabButtonContext = React.createContext<Partial<TypeTabButtonContext>>({});\n\nclass TabItemButton extends React.Component<TypeTabButtonsProps> {\n static override contextType = TabButtonContext;\n // @ts-notes - using the legacy syntax here because `declare` does not play well with babel\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n context!: React.ContextType<typeof TabButtonContext>;\n\n buttonRef: TypeTabButtonRef = React.createRef<React.ElementRef<\"button\">>();\n\n override componentDidMount() {\n this.context.onTabMount?.(this.props.id, this.buttonRef);\n }\n\n override componentDidUpdate(prevProps: TypeTabButtonsProps) {\n if (prevProps.id !== this.props.id) {\n this.context.onTabUpdate?.(prevProps.id, this.props.id);\n }\n }\n\n override componentWillUnmount() {\n this.context.onTabUnmount?.(this.props.id);\n }\n\n override render() {\n const { children, id, ...rest } = this.props;\n const { selectedId, onActivate, fullWidth } = this.context;\n const isSelected = selectedId === id;\n\n return (\n <TabItem key={id} fullWidth={fullWidth} isSelected={isSelected}>\n <TabButton\n innerRef={this.buttonRef}\n id={id}\n onClick={() => onActivate?.(id)}\n isSelected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n fullWidth={fullWidth}\n data-qa-tab-button={id}\n data-qa-tab-button-state={isSelected}\n aria-selected={isSelected}\n role=\"tab\"\n // TODO: Add a TabPanel subcomponent for use with tabs\n // aria-controls={tabPanelId}\n {...rest}\n >\n {children}\n </TabButton>\n </TabItem>\n );\n }\n}\n\n/**\n * Render a group of buttons in a tab-heading style\n */\nclass Tabs extends React.Component<TypeTabsProps> {\n static Button = TabItemButton;\n buttonRefs: Record<string, TypeTabButtonRef | null | undefined> = {};\n tabList: string[] = [];\n\n getSelectedId = () => this.props.selectedId;\n onActivate = (id: string) => this.props.onSelect(id);\n onTabMount = (id: string, ref: TypeTabButtonRef) => {\n if (!this.tabList.includes(id)) {\n this.tabList.push(id);\n this.buttonRefs[id] = ref;\n }\n };\n\n onTabUpdate = (previousId: string, newId: string) => {\n if (this.tabList.includes(previousId)) {\n this.tabList = this.tabList.map((id) => (id === previousId ? newId : id));\n this.buttonRefs[newId] = this.buttonRefs[previousId];\n this.buttonRefs[previousId] = undefined;\n }\n };\n\n onTabUnmount = (id: string) => {\n if (this.tabList.includes(id)) {\n this.tabList = this.tabList.filter((currentId) => currentId !== id);\n this.buttonRefs[id] = undefined;\n }\n };\n\n selectNextTab = (id: string) => {\n const buttonRef = this.buttonRefs[id];\n this.props.onSelect(id);\n buttonRef &&\n buttonRef.current &&\n buttonRef.current.focus &&\n buttonRef.current.focus();\n };\n\n keyHandler = ({ keyCode }: React.KeyboardEvent<HTMLUListElement>) => {\n switch (keyCode) {\n // left arrow\n case 37:\n this.tabList.forEach((id, index) => {\n if (id === this.getSelectedId()) {\n const count = this.tabList.length;\n const nextIndex = index - 1 >= 0 ? index - 1 : count - 1;\n const nextId = this.tabList[nextIndex];\n this.selectNextTab(nextId ? nextId : \"\");\n }\n });\n break;\n\n // right arrow\n case 39:\n this.tabList.forEach((id, index) => {\n if (id === this.getSelectedId()) {\n const count = this.tabList.length;\n const nextIndex = index + 1 < count ? index + 1 : 0;\n const nextId = this.tabList[nextIndex];\n this.selectNextTab(nextId ? nextId : \"\");\n }\n });\n break;\n\n default:\n break;\n }\n };\n\n override render() {\n const { children, qa, onSelect, ...rest } = this.props;\n return (\n <Container\n data-qa-tabs=\"\"\n onKeyUp={this.keyHandler}\n onSelect={onSelect}\n role=\"tablist\"\n {...qa}\n {...rest}\n >\n <TabButtonContext.Provider\n value={{\n selectedId: this.getSelectedId(),\n fullWidth: this.props.fullWidth,\n onActivate: this.onActivate,\n onTabMount: this.onTabMount,\n onTabUpdate: this.onTabUpdate,\n onTabUnmount: this.onTabUnmount,\n }}\n >\n {children}\n </TabButtonContext.Provider>\n </Container>\n );\n }\n}\n\nexport default Tabs;\n","import styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport { Button } from \"@sproutsocial/seeds-react-button\";\nimport { type TypeTabsProps } from \"./TabsTypes\";\n\ninterface TypeTabState {\n isSelected: boolean;\n}\ntype TypeFullWidth = Pick<TypeTabsProps, \"fullWidth\">;\ninterface TypeStyleProps extends TypeFullWidth, TypeTabState {}\n\nconst Container = styled.ul<TypeTabsProps>`\n display: ${(props) => (props.fullWidth ? \"flex\" : \"inline-flex\")};\n justify-content: space-between;\n margin: 0;\n padding: 0;\n list-style: none;\n border-bottom: ${(props) => props.theme.borders[500]}\n ${(props) => props.theme.colors.container.border.base};\n\n ${COMMON}\n`;\n\nexport const TabItem = styled.li<TypeStyleProps>`\n margin-bottom: -1px;\n ${(props) =>\n props.fullWidth &&\n css`\n flex-grow: 1;\n `};\n\n &:not(:last-child) {\n ${(props) =>\n !props.fullWidth &&\n css`\n margin-right: ${(props) => props.theme.space[350]};\n `};\n }\n\n ${(props) =>\n props.isSelected &&\n css`\n box-shadow: ${(props) =>\n `inset 0 -3px 0 0 ${props.theme.colors.button.primary.background.base}`};\n `};\n\n &:hover {\n ${(props) =>\n props.isSelected &&\n css`\n box-shadow: ${(props) =>\n `inset 0 -3px 0 0 ${props.theme.colors.button.primary.background.hover}`};\n `};\n }\n`;\n\nexport const TabButton = styled(Button)<TypeStyleProps>`\n padding: ${(props) => `${props.theme.space[350]} 0`};\n color: ${(props) => props.theme.colors.text.headline};\n width: 100%;\n\n ${(props) =>\n props.isSelected &&\n css`\n color: ${(props) => props.theme.colors.link.base};\n `};\n\n &:hover {\n ${(props) =>\n props.isSelected &&\n css`\n color: ${(props) => props.theme.colors.link.hover};\n `};\n }\n\n &:active {\n transform: none;\n }\n`;\nexport default Container;\n","import * as React from \"react\";\nimport type {\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\n\nexport interface TypeTabButtonsProps extends TypeButtonProps {\n children: React.ReactNode;\n\n /** Should be unique among sibling elements */\n id: string;\n}\n\nexport interface TypeTabsProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<\n React.ComponentPropsWithoutRef<\"ul\">,\n keyof TypeSystemCommonProps | \"onSelect\"\n > {\n children: React.ReactNode;\n onSelect: (arg0: string) => void;\n\n /** Whether or not the tabs should stretch to fill the width of their container */\n fullWidth?: boolean;\n qa?: object;\n\n /** ID of the selected tab */\n selectedId: string;\n}\n","import Tabs from \"./Tabs\";\n\nexport default Tabs;\nexport { Tabs };\nexport * from \"./TabsTypes\";\n"],"mappings":"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","names":["React","props"]}
@@ -0,0 +1,59 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { TypeStyledComponentsCommonProps, TypeSystemCommonProps } from '@sproutsocial/seeds-react-system-props';
4
+ import { TypeButtonProps } from '@sproutsocial/seeds-react-button';
5
+
6
+ interface TypeTabButtonsProps extends TypeButtonProps {
7
+ children: React.ReactNode;
8
+ /** Should be unique among sibling elements */
9
+ id: string;
10
+ }
11
+ interface TypeTabsProps extends TypeStyledComponentsCommonProps, TypeSystemCommonProps, Omit<React.ComponentPropsWithoutRef<"ul">, keyof TypeSystemCommonProps | "onSelect"> {
12
+ children: React.ReactNode;
13
+ onSelect: (arg0: string) => void;
14
+ /** Whether or not the tabs should stretch to fill the width of their container */
15
+ fullWidth?: boolean;
16
+ qa?: object;
17
+ /** ID of the selected tab */
18
+ selectedId: string;
19
+ }
20
+
21
+ interface TypeTabButtonRef {
22
+ current: null | React.ElementRef<"button">;
23
+ }
24
+ interface TypeTabButtonContext {
25
+ onActivate: (arg0: string) => void;
26
+ onTabMount: (id: string, ref: TypeTabButtonRef) => void;
27
+ onTabUpdate: (previousId: string, nextId: string) => void;
28
+ onTabUnmount: (id: string) => void;
29
+ selectedId: string;
30
+ fullWidth?: boolean;
31
+ }
32
+ declare const TabButtonContext: React.Context<Partial<TypeTabButtonContext>>;
33
+ declare class TabItemButton extends React.Component<TypeTabButtonsProps> {
34
+ static contextType: React.Context<Partial<TypeTabButtonContext>>;
35
+ context: React.ContextType<typeof TabButtonContext>;
36
+ buttonRef: TypeTabButtonRef;
37
+ componentDidMount(): void;
38
+ componentDidUpdate(prevProps: TypeTabButtonsProps): void;
39
+ componentWillUnmount(): void;
40
+ render(): react_jsx_runtime.JSX.Element;
41
+ }
42
+ /**
43
+ * Render a group of buttons in a tab-heading style
44
+ */
45
+ declare class Tabs extends React.Component<TypeTabsProps> {
46
+ static Button: typeof TabItemButton;
47
+ buttonRefs: Record<string, TypeTabButtonRef | null | undefined>;
48
+ tabList: string[];
49
+ getSelectedId: () => string;
50
+ onActivate: (id: string) => void;
51
+ onTabMount: (id: string, ref: TypeTabButtonRef) => void;
52
+ onTabUpdate: (previousId: string, newId: string) => void;
53
+ onTabUnmount: (id: string) => void;
54
+ selectNextTab: (id: string) => void;
55
+ keyHandler: ({ keyCode }: React.KeyboardEvent<HTMLUListElement>) => void;
56
+ render(): react_jsx_runtime.JSX.Element;
57
+ }
58
+
59
+ export { Tabs, type TypeTabButtonsProps, type TypeTabsProps, Tabs as default };
@@ -0,0 +1,59 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { TypeStyledComponentsCommonProps, TypeSystemCommonProps } from '@sproutsocial/seeds-react-system-props';
4
+ import { TypeButtonProps } from '@sproutsocial/seeds-react-button';
5
+
6
+ interface TypeTabButtonsProps extends TypeButtonProps {
7
+ children: React.ReactNode;
8
+ /** Should be unique among sibling elements */
9
+ id: string;
10
+ }
11
+ interface TypeTabsProps extends TypeStyledComponentsCommonProps, TypeSystemCommonProps, Omit<React.ComponentPropsWithoutRef<"ul">, keyof TypeSystemCommonProps | "onSelect"> {
12
+ children: React.ReactNode;
13
+ onSelect: (arg0: string) => void;
14
+ /** Whether or not the tabs should stretch to fill the width of their container */
15
+ fullWidth?: boolean;
16
+ qa?: object;
17
+ /** ID of the selected tab */
18
+ selectedId: string;
19
+ }
20
+
21
+ interface TypeTabButtonRef {
22
+ current: null | React.ElementRef<"button">;
23
+ }
24
+ interface TypeTabButtonContext {
25
+ onActivate: (arg0: string) => void;
26
+ onTabMount: (id: string, ref: TypeTabButtonRef) => void;
27
+ onTabUpdate: (previousId: string, nextId: string) => void;
28
+ onTabUnmount: (id: string) => void;
29
+ selectedId: string;
30
+ fullWidth?: boolean;
31
+ }
32
+ declare const TabButtonContext: React.Context<Partial<TypeTabButtonContext>>;
33
+ declare class TabItemButton extends React.Component<TypeTabButtonsProps> {
34
+ static contextType: React.Context<Partial<TypeTabButtonContext>>;
35
+ context: React.ContextType<typeof TabButtonContext>;
36
+ buttonRef: TypeTabButtonRef;
37
+ componentDidMount(): void;
38
+ componentDidUpdate(prevProps: TypeTabButtonsProps): void;
39
+ componentWillUnmount(): void;
40
+ render(): react_jsx_runtime.JSX.Element;
41
+ }
42
+ /**
43
+ * Render a group of buttons in a tab-heading style
44
+ */
45
+ declare class Tabs extends React.Component<TypeTabsProps> {
46
+ static Button: typeof TabItemButton;
47
+ buttonRefs: Record<string, TypeTabButtonRef | null | undefined>;
48
+ tabList: string[];
49
+ getSelectedId: () => string;
50
+ onActivate: (id: string) => void;
51
+ onTabMount: (id: string, ref: TypeTabButtonRef) => void;
52
+ onTabUpdate: (previousId: string, newId: string) => void;
53
+ onTabUnmount: (id: string) => void;
54
+ selectNextTab: (id: string) => void;
55
+ keyHandler: ({ keyCode }: React.KeyboardEvent<HTMLUListElement>) => void;
56
+ render(): react_jsx_runtime.JSX.Element;
57
+ }
58
+
59
+ export { Tabs, type TypeTabButtonsProps, type TypeTabsProps, Tabs as default };
package/dist/index.js ADDED
@@ -0,0 +1,241 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ Tabs: () => Tabs_default,
34
+ default: () => src_default
35
+ });
36
+ module.exports = __toCommonJS(src_exports);
37
+
38
+ // src/Tabs.tsx
39
+ var React2 = __toESM(require("react"));
40
+
41
+ // src/styles.ts
42
+ var import_styled_components = __toESM(require("styled-components"));
43
+ var import_seeds_react_system_props = require("@sproutsocial/seeds-react-system-props");
44
+ var import_seeds_react_button = require("@sproutsocial/seeds-react-button");
45
+
46
+ // src/TabsTypes.ts
47
+ var React = require("react");
48
+
49
+ // src/styles.ts
50
+ var Container = import_styled_components.default.ul`
51
+ display: ${(props) => props.fullWidth ? "flex" : "inline-flex"};
52
+ justify-content: space-between;
53
+ margin: 0;
54
+ padding: 0;
55
+ list-style: none;
56
+ border-bottom: ${(props) => props.theme.borders[500]}
57
+ ${(props) => props.theme.colors.container.border.base};
58
+
59
+ ${import_seeds_react_system_props.COMMON}
60
+ `;
61
+ var TabItem = import_styled_components.default.li`
62
+ margin-bottom: -1px;
63
+ ${(props) => props.fullWidth && import_styled_components.css`
64
+ flex-grow: 1;
65
+ `};
66
+
67
+ &:not(:last-child) {
68
+ ${(props) => !props.fullWidth && import_styled_components.css`
69
+ margin-right: ${(props2) => props2.theme.space[350]};
70
+ `};
71
+ }
72
+
73
+ ${(props) => props.isSelected && import_styled_components.css`
74
+ box-shadow: ${(props2) => `inset 0 -3px 0 0 ${props2.theme.colors.button.primary.background.base}`};
75
+ `};
76
+
77
+ &:hover {
78
+ ${(props) => props.isSelected && import_styled_components.css`
79
+ box-shadow: ${(props2) => `inset 0 -3px 0 0 ${props2.theme.colors.button.primary.background.hover}`};
80
+ `};
81
+ }
82
+ `;
83
+ var TabButton = (0, import_styled_components.default)(import_seeds_react_button.Button)`
84
+ padding: ${(props) => `${props.theme.space[350]} 0`};
85
+ color: ${(props) => props.theme.colors.text.headline};
86
+ width: 100%;
87
+
88
+ ${(props) => props.isSelected && import_styled_components.css`
89
+ color: ${(props2) => props2.theme.colors.link.base};
90
+ `};
91
+
92
+ &:hover {
93
+ ${(props) => props.isSelected && import_styled_components.css`
94
+ color: ${(props2) => props2.theme.colors.link.hover};
95
+ `};
96
+ }
97
+
98
+ &:active {
99
+ transform: none;
100
+ }
101
+ `;
102
+ var styles_default = Container;
103
+
104
+ // src/Tabs.tsx
105
+ var import_jsx_runtime = require("react/jsx-runtime");
106
+ var TabButtonContext = React2.createContext({});
107
+ var TabItemButton = class extends React2.Component {
108
+ static contextType = TabButtonContext;
109
+ // @ts-notes - using the legacy syntax here because `declare` does not play well with babel
110
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
111
+ //@ts-ignore
112
+ context;
113
+ buttonRef = React2.createRef();
114
+ componentDidMount() {
115
+ this.context.onTabMount?.(this.props.id, this.buttonRef);
116
+ }
117
+ componentDidUpdate(prevProps) {
118
+ if (prevProps.id !== this.props.id) {
119
+ this.context.onTabUpdate?.(prevProps.id, this.props.id);
120
+ }
121
+ }
122
+ componentWillUnmount() {
123
+ this.context.onTabUnmount?.(this.props.id);
124
+ }
125
+ render() {
126
+ const { children, id, ...rest } = this.props;
127
+ const { selectedId, onActivate, fullWidth } = this.context;
128
+ const isSelected = selectedId === id;
129
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabItem, { fullWidth, isSelected, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
130
+ TabButton,
131
+ {
132
+ innerRef: this.buttonRef,
133
+ id,
134
+ onClick: () => onActivate?.(id),
135
+ isSelected,
136
+ tabIndex: isSelected ? 0 : -1,
137
+ fullWidth,
138
+ "data-qa-tab-button": id,
139
+ "data-qa-tab-button-state": isSelected,
140
+ "aria-selected": isSelected,
141
+ role: "tab",
142
+ ...rest,
143
+ children
144
+ }
145
+ ) }, id);
146
+ }
147
+ };
148
+ var Tabs = class extends React2.Component {
149
+ static Button = TabItemButton;
150
+ buttonRefs = {};
151
+ tabList = [];
152
+ getSelectedId = () => this.props.selectedId;
153
+ onActivate = (id) => this.props.onSelect(id);
154
+ onTabMount = (id, ref) => {
155
+ if (!this.tabList.includes(id)) {
156
+ this.tabList.push(id);
157
+ this.buttonRefs[id] = ref;
158
+ }
159
+ };
160
+ onTabUpdate = (previousId, newId) => {
161
+ if (this.tabList.includes(previousId)) {
162
+ this.tabList = this.tabList.map((id) => id === previousId ? newId : id);
163
+ this.buttonRefs[newId] = this.buttonRefs[previousId];
164
+ this.buttonRefs[previousId] = void 0;
165
+ }
166
+ };
167
+ onTabUnmount = (id) => {
168
+ if (this.tabList.includes(id)) {
169
+ this.tabList = this.tabList.filter((currentId) => currentId !== id);
170
+ this.buttonRefs[id] = void 0;
171
+ }
172
+ };
173
+ selectNextTab = (id) => {
174
+ const buttonRef = this.buttonRefs[id];
175
+ this.props.onSelect(id);
176
+ buttonRef && buttonRef.current && buttonRef.current.focus && buttonRef.current.focus();
177
+ };
178
+ keyHandler = ({ keyCode }) => {
179
+ switch (keyCode) {
180
+ case 37:
181
+ this.tabList.forEach((id, index) => {
182
+ if (id === this.getSelectedId()) {
183
+ const count = this.tabList.length;
184
+ const nextIndex = index - 1 >= 0 ? index - 1 : count - 1;
185
+ const nextId = this.tabList[nextIndex];
186
+ this.selectNextTab(nextId ? nextId : "");
187
+ }
188
+ });
189
+ break;
190
+ case 39:
191
+ this.tabList.forEach((id, index) => {
192
+ if (id === this.getSelectedId()) {
193
+ const count = this.tabList.length;
194
+ const nextIndex = index + 1 < count ? index + 1 : 0;
195
+ const nextId = this.tabList[nextIndex];
196
+ this.selectNextTab(nextId ? nextId : "");
197
+ }
198
+ });
199
+ break;
200
+ default:
201
+ break;
202
+ }
203
+ };
204
+ render() {
205
+ const { children, qa, onSelect, ...rest } = this.props;
206
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
207
+ styles_default,
208
+ {
209
+ "data-qa-tabs": "",
210
+ onKeyUp: this.keyHandler,
211
+ onSelect,
212
+ role: "tablist",
213
+ ...qa,
214
+ ...rest,
215
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
216
+ TabButtonContext.Provider,
217
+ {
218
+ value: {
219
+ selectedId: this.getSelectedId(),
220
+ fullWidth: this.props.fullWidth,
221
+ onActivate: this.onActivate,
222
+ onTabMount: this.onTabMount,
223
+ onTabUpdate: this.onTabUpdate,
224
+ onTabUnmount: this.onTabUnmount
225
+ },
226
+ children
227
+ }
228
+ )
229
+ }
230
+ );
231
+ }
232
+ };
233
+ var Tabs_default = Tabs;
234
+
235
+ // src/index.ts
236
+ var src_default = Tabs_default;
237
+ // Annotate the CommonJS export names for ESM import in node:
238
+ 0 && (module.exports = {
239
+ Tabs
240
+ });
241
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/Tabs.tsx","../src/styles.ts","../src/TabsTypes.ts"],"sourcesContent":["import Tabs from \"./Tabs\";\n\nexport default Tabs;\nexport { Tabs };\nexport * from \"./TabsTypes\";\n","import * as React from \"react\";\nimport Container, { TabItem, TabButton } from \"./styles\";\nimport type { TypeTabButtonsProps, TypeTabsProps } from \"./TabsTypes\";\n\ninterface TypeTabButtonRef {\n current: null | React.ElementRef<\"button\">;\n}\ninterface TypeTabButtonContext {\n onActivate: (arg0: string) => void;\n onTabMount: (id: string, ref: TypeTabButtonRef) => void;\n onTabUpdate: (previousId: string, nextId: string) => void;\n onTabUnmount: (id: string) => void;\n selectedId: string;\n fullWidth?: boolean;\n}\n\nconst TabButtonContext = React.createContext<Partial<TypeTabButtonContext>>({});\n\nclass TabItemButton extends React.Component<TypeTabButtonsProps> {\n static override contextType = TabButtonContext;\n // @ts-notes - using the legacy syntax here because `declare` does not play well with babel\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n context!: React.ContextType<typeof TabButtonContext>;\n\n buttonRef: TypeTabButtonRef = React.createRef<React.ElementRef<\"button\">>();\n\n override componentDidMount() {\n this.context.onTabMount?.(this.props.id, this.buttonRef);\n }\n\n override componentDidUpdate(prevProps: TypeTabButtonsProps) {\n if (prevProps.id !== this.props.id) {\n this.context.onTabUpdate?.(prevProps.id, this.props.id);\n }\n }\n\n override componentWillUnmount() {\n this.context.onTabUnmount?.(this.props.id);\n }\n\n override render() {\n const { children, id, ...rest } = this.props;\n const { selectedId, onActivate, fullWidth } = this.context;\n const isSelected = selectedId === id;\n\n return (\n <TabItem key={id} fullWidth={fullWidth} isSelected={isSelected}>\n <TabButton\n innerRef={this.buttonRef}\n id={id}\n onClick={() => onActivate?.(id)}\n isSelected={isSelected}\n tabIndex={isSelected ? 0 : -1}\n fullWidth={fullWidth}\n data-qa-tab-button={id}\n data-qa-tab-button-state={isSelected}\n aria-selected={isSelected}\n role=\"tab\"\n // TODO: Add a TabPanel subcomponent for use with tabs\n // aria-controls={tabPanelId}\n {...rest}\n >\n {children}\n </TabButton>\n </TabItem>\n );\n }\n}\n\n/**\n * Render a group of buttons in a tab-heading style\n */\nclass Tabs extends React.Component<TypeTabsProps> {\n static Button = TabItemButton;\n buttonRefs: Record<string, TypeTabButtonRef | null | undefined> = {};\n tabList: string[] = [];\n\n getSelectedId = () => this.props.selectedId;\n onActivate = (id: string) => this.props.onSelect(id);\n onTabMount = (id: string, ref: TypeTabButtonRef) => {\n if (!this.tabList.includes(id)) {\n this.tabList.push(id);\n this.buttonRefs[id] = ref;\n }\n };\n\n onTabUpdate = (previousId: string, newId: string) => {\n if (this.tabList.includes(previousId)) {\n this.tabList = this.tabList.map((id) => (id === previousId ? newId : id));\n this.buttonRefs[newId] = this.buttonRefs[previousId];\n this.buttonRefs[previousId] = undefined;\n }\n };\n\n onTabUnmount = (id: string) => {\n if (this.tabList.includes(id)) {\n this.tabList = this.tabList.filter((currentId) => currentId !== id);\n this.buttonRefs[id] = undefined;\n }\n };\n\n selectNextTab = (id: string) => {\n const buttonRef = this.buttonRefs[id];\n this.props.onSelect(id);\n buttonRef &&\n buttonRef.current &&\n buttonRef.current.focus &&\n buttonRef.current.focus();\n };\n\n keyHandler = ({ keyCode }: React.KeyboardEvent<HTMLUListElement>) => {\n switch (keyCode) {\n // left arrow\n case 37:\n this.tabList.forEach((id, index) => {\n if (id === this.getSelectedId()) {\n const count = this.tabList.length;\n const nextIndex = index - 1 >= 0 ? index - 1 : count - 1;\n const nextId = this.tabList[nextIndex];\n this.selectNextTab(nextId ? nextId : \"\");\n }\n });\n break;\n\n // right arrow\n case 39:\n this.tabList.forEach((id, index) => {\n if (id === this.getSelectedId()) {\n const count = this.tabList.length;\n const nextIndex = index + 1 < count ? index + 1 : 0;\n const nextId = this.tabList[nextIndex];\n this.selectNextTab(nextId ? nextId : \"\");\n }\n });\n break;\n\n default:\n break;\n }\n };\n\n override render() {\n const { children, qa, onSelect, ...rest } = this.props;\n return (\n <Container\n data-qa-tabs=\"\"\n onKeyUp={this.keyHandler}\n onSelect={onSelect}\n role=\"tablist\"\n {...qa}\n {...rest}\n >\n <TabButtonContext.Provider\n value={{\n selectedId: this.getSelectedId(),\n fullWidth: this.props.fullWidth,\n onActivate: this.onActivate,\n onTabMount: this.onTabMount,\n onTabUpdate: this.onTabUpdate,\n onTabUnmount: this.onTabUnmount,\n }}\n >\n {children}\n </TabButtonContext.Provider>\n </Container>\n );\n }\n}\n\nexport default Tabs;\n","import styled, { css } from \"styled-components\";\nimport { COMMON } from \"@sproutsocial/seeds-react-system-props\";\nimport { Button } from \"@sproutsocial/seeds-react-button\";\nimport { type TypeTabsProps } from \"./TabsTypes\";\n\ninterface TypeTabState {\n isSelected: boolean;\n}\ntype TypeFullWidth = Pick<TypeTabsProps, \"fullWidth\">;\ninterface TypeStyleProps extends TypeFullWidth, TypeTabState {}\n\nconst Container = styled.ul<TypeTabsProps>`\n display: ${(props) => (props.fullWidth ? \"flex\" : \"inline-flex\")};\n justify-content: space-between;\n margin: 0;\n padding: 0;\n list-style: none;\n border-bottom: ${(props) => props.theme.borders[500]}\n ${(props) => props.theme.colors.container.border.base};\n\n ${COMMON}\n`;\n\nexport const TabItem = styled.li<TypeStyleProps>`\n margin-bottom: -1px;\n ${(props) =>\n props.fullWidth &&\n css`\n flex-grow: 1;\n `};\n\n &:not(:last-child) {\n ${(props) =>\n !props.fullWidth &&\n css`\n margin-right: ${(props) => props.theme.space[350]};\n `};\n }\n\n ${(props) =>\n props.isSelected &&\n css`\n box-shadow: ${(props) =>\n `inset 0 -3px 0 0 ${props.theme.colors.button.primary.background.base}`};\n `};\n\n &:hover {\n ${(props) =>\n props.isSelected &&\n css`\n box-shadow: ${(props) =>\n `inset 0 -3px 0 0 ${props.theme.colors.button.primary.background.hover}`};\n `};\n }\n`;\n\nexport const TabButton = styled(Button)<TypeStyleProps>`\n padding: ${(props) => `${props.theme.space[350]} 0`};\n color: ${(props) => props.theme.colors.text.headline};\n width: 100%;\n\n ${(props) =>\n props.isSelected &&\n css`\n color: ${(props) => props.theme.colors.link.base};\n `};\n\n &:hover {\n ${(props) =>\n props.isSelected &&\n css`\n color: ${(props) => props.theme.colors.link.hover};\n `};\n }\n\n &:active {\n transform: none;\n }\n`;\nexport default Container;\n","import * as React from \"react\";\nimport type {\n TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n} from \"@sproutsocial/seeds-react-system-props\";\nimport type { TypeButtonProps } from \"@sproutsocial/seeds-react-button\";\n\nexport interface TypeTabButtonsProps extends TypeButtonProps {\n children: React.ReactNode;\n\n /** Should be unique among sibling elements */\n id: string;\n}\n\nexport interface TypeTabsProps\n extends TypeStyledComponentsCommonProps,\n TypeSystemCommonProps,\n Omit<\n React.ComponentPropsWithoutRef<\"ul\">,\n keyof TypeSystemCommonProps | \"onSelect\"\n > {\n children: React.ReactNode;\n onSelect: (arg0: string) => void;\n\n /** Whether or not the tabs should stretch to fill the width of their container */\n fullWidth?: boolean;\n qa?: object;\n\n /** ID of the selected tab */\n selectedId: string;\n}\n"],"mappings":"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","names":["React","styled","props"]}
package/jest.config.js ADDED
@@ -0,0 +1,9 @@
1
+ const baseConfig = require("@sproutsocial/seeds-testing");
2
+
3
+ /** * @type {import('jest').Config} */
4
+ const config = {
5
+ ...baseConfig,
6
+ displayName: "seeds-react-tabs",
7
+ };
8
+
9
+ module.exports = config;