@sproutsocial/seeds-react-tabs 1.2.9 → 1.3.2

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.
@@ -3,19 +3,19 @@ $ tsup --dts
3
3
  CLI Building entry: src/index.ts
4
4
  CLI Using tsconfig: tsconfig.json
5
5
  CLI tsup v8.5.0
6
- CLI Using tsup config: /home/runner/work/seeds/seeds/seeds-react/seeds-react-tabs/tsup.config.ts
6
+ CLI Using tsup config: /home/runner/_work/seeds/seeds/seeds-react/seeds-react-tabs/tsup.config.ts
7
7
  CLI Target: es2022
8
8
  CLI Cleaning output folder
9
9
  CJS Build start
10
10
  ESM Build start
11
- ESM dist/esm/index.js 5.96 KB
12
- ESM dist/esm/index.js.map 12.58 KB
13
- ESM ⚡️ Build success in 193ms
14
- CJS dist/index.js 8.02 KB
15
- CJS dist/index.js.map 12.64 KB
16
- CJS ⚡️ Build success in 215ms
11
+ CJS dist/index.js 7.72 KB
12
+ CJS dist/index.js.map 12.13 KB
13
+ CJS ⚡️ Build success in 73ms
14
+ ESM dist/esm/index.js 5.75 KB
15
+ ESM dist/esm/index.js.map 12.06 KB
16
+ ESM ⚡️ Build success in 73ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 25408ms
18
+ DTS ⚡️ Build success in 2174ms
19
19
  DTS dist/index.d.ts 2.63 KB
20
20
  DTS dist/index.d.mts 2.63 KB
21
- Done in 33.62s.
21
+ Done in 3.65s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @sproutsocial/seeds-react-tabs
2
2
 
3
+ ## 1.3.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [7d54d67]
8
+ - @sproutsocial/seeds-react-button@1.4.0
9
+
10
+ ## 1.3.1
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [17d4f12]
15
+ - @sproutsocial/seeds-react-theme@3.6.0
16
+ - @sproutsocial/seeds-react-button@1.3.20
17
+
18
+ ## 1.3.0
19
+
20
+ ### Minor Changes
21
+
22
+ - 651fc1b: Update TabButton structure to correct aria descendents
23
+
24
+ ## 1.2.10
25
+
26
+ ### Patch Changes
27
+
28
+ - @sproutsocial/seeds-react-button@1.3.19
29
+
3
30
  ## 1.2.9
4
31
 
5
32
  ### Patch Changes
package/dist/esm/index.js CHANGED
@@ -20,8 +20,14 @@ var Container = styled.div`
20
20
 
21
21
  ${COMMON}
22
22
  `;
23
- var TabItem = styled.div`
23
+ var TabButton = styled(Button)`
24
24
  margin-bottom: -1px;
25
+ padding: ${(props) => `${props.theme.space[350]} 0`};
26
+ color: ${(props) => props.theme.colors.text.headline};
27
+ border-radius: 0;
28
+ border-width: 0 0 3px;
29
+ width: 100%;
30
+
25
31
  ${(props) => props.fullWidth && css`
26
32
  flex-grow: 1;
27
33
  `};
@@ -32,23 +38,10 @@ var TabItem = styled.div`
32
38
  `};
33
39
  }
34
40
 
35
- ${(props) => props.isSelected && css`
36
- box-shadow: ${(props2) => `inset 0 -3px 0 0 ${props2.theme.colors.button.primary.background.base}`};
37
- `};
38
-
39
- &:hover {
40
- ${(props) => props.isSelected && css`
41
- box-shadow: ${(props2) => `inset 0 -3px 0 0 ${props2.theme.colors.button.primary.background.hover}`};
42
- `};
43
- }
44
- `;
45
- var TabButton = styled(Button)`
46
- padding: ${(props) => `${props.theme.space[350]} 0`};
47
- color: ${(props) => props.theme.colors.text.headline};
48
- width: 100%;
49
-
50
41
  ${(props) => props.isSelected && css`
51
42
  color: ${(props2) => props2.theme.colors.link.base};
43
+ border-color: transparent transparent
44
+ ${(props2) => props2.theme.colors.button.primary.background.base};
52
45
  `};
53
46
 
54
47
  &:hover {
@@ -57,6 +50,11 @@ var TabButton = styled(Button)`
57
50
  `};
58
51
  }
59
52
 
53
+ &:focus,
54
+ &:active {
55
+ box-shadow: none;
56
+ }
57
+
60
58
  &:active {
61
59
  transform: none;
62
60
  }
@@ -88,7 +86,7 @@ var TabItemButton = class extends React2.Component {
88
86
  const { children, id, ...rest } = this.props;
89
87
  const { selectedId, onActivate, fullWidth } = this.context;
90
88
  const isSelected = selectedId === id;
91
- return /* @__PURE__ */ jsx(TabItem, { fullWidth, isSelected, children: /* @__PURE__ */ jsx(
89
+ return /* @__PURE__ */ jsx(
92
90
  TabButton,
93
91
  {
94
92
  innerRef: this.buttonRef,
@@ -104,8 +102,9 @@ var TabItemButton = class extends React2.Component {
104
102
  "aria-controls": `${id}-panel`,
105
103
  ...rest,
106
104
  children
107
- }
108
- ) }, id);
105
+ },
106
+ id
107
+ );
109
108
  }
110
109
  };
111
110
  var TabPanel = ({ children, id, ...rest }) => {
@@ -1 +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 {\n TypeTabButtonsProps,\n TypeTabsProps,\n TypeTabPanelProps,\n} 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 aria-controls={`${id}-panel`}\n {...rest}\n >\n {children}\n </TabButton>\n </TabItem>\n );\n }\n}\n\nconst TabPanel: React.FC<TypeTabPanelProps> = ({ children, id, ...rest }) => {\n const panelId = `${id}-panel`;\n\n return (\n <div id={panelId} role=\"tabpanel\" aria-labelledby={id} {...rest}>\n {children}\n </div>\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 static Panel = TabPanel;\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<HTMLDivElement>) => {\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.div<TypeTabsProps>`\n display: ${(props) => (props.fullWidth ? \"flex\" : \"inline-flex\")};\n justify-content: space-between;\n margin: 0;\n padding: 0;\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.div<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 TypeTabPanelProps\n extends React.ComponentPropsWithoutRef<\"div\"> {\n children: React.ReactNode;\n\n /** Should match the corresponding tab button id */\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":";AAAA,YAAYA,YAAW;;;ACAvB,OAAO,UAAU,WAAW;AAC5B,SAAS,cAAc;AACvB,SAAS,cAAc;;;ACFvB,OAAuB;;;ADWvB,IAAM,YAAY,OAAO;AAAA,aACZ,CAAC,UAAW,MAAM,YAAY,SAAS,aAAc;AAAA;AAAA;AAAA;AAAA,mBAI/C,CAAC,UAAU,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,MAChD,CAAC,UAAU,MAAM,MAAM,OAAO,UAAU,OAAO,IAAI;AAAA;AAAA,IAErD,MAAM;AAAA;AAGH,IAAM,UAAU,OAAO;AAAA;AAAA,IAE1B,CAAC,UACD,MAAM,aACN;AAAA;AAAA,KAEC;AAAA;AAAA;AAAA,MAGC,CAAC,UACD,CAAC,MAAM,aACP;AAAA,wBACkB,CAACC,WAAUA,OAAM,MAAM,MAAM,GAAG,CAAC;AAAA,OAClD;AAAA;AAAA;AAAA,IAGH,CAAC,UACD,MAAM,cACN;AAAA,oBACgB,CAACA,WACb,oBAAoBA,OAAM,MAAM,OAAO,OAAO,QAAQ,WAAW,IAAI,EAAE;AAAA,KAC1E;AAAA;AAAA;AAAA,MAGC,CAAC,UACD,MAAM,cACN;AAAA,sBACgB,CAACA,WACb,oBAAoBA,OAAM,MAAM,OAAO,OAAO,QAAQ,WAAW,KAAK,EAAE;AAAA,OAC3E;AAAA;AAAA;AAIA,IAAM,YAAY,OAAO,MAAM;AAAA,aACzB,CAAC,UAAU,GAAG,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI;AAAA,WAC1C,CAAC,UAAU,MAAM,MAAM,OAAO,KAAK,QAAQ;AAAA;AAAA;AAAA,IAGlD,CAAC,UACD,MAAM,cACN;AAAA,eACW,CAACA,WAAUA,OAAM,MAAM,OAAO,KAAK,IAAI;AAAA,KACjD;AAAA;AAAA;AAAA,MAGC,CAAC,UACD,MAAM,cACN;AAAA,iBACW,CAACA,WAAUA,OAAM,MAAM,OAAO,KAAK,KAAK;AAAA,OAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOP,IAAO,iBAAQ;;;AD1BP;AAhCR,IAAM,mBAAyB,qBAA6C,CAAC,CAAC;AAE9E,IAAM,gBAAN,cAAkC,iBAA+B;AAAA,EAC/D,OAAgB,cAAc;AAAA;AAAA;AAAA;AAAA,EAI9B;AAAA,EAEA,YAAoC,iBAAsC;AAAA,EAEjE,oBAAoB;AAC3B,SAAK,QAAQ,aAAa,KAAK,MAAM,IAAI,KAAK,SAAS;AAAA,EACzD;AAAA,EAES,mBAAmB,WAAgC;AAC1D,QAAI,UAAU,OAAO,KAAK,MAAM,IAAI;AAClC,WAAK,QAAQ,cAAc,UAAU,IAAI,KAAK,MAAM,EAAE;AAAA,IACxD;AAAA,EACF;AAAA,EAES,uBAAuB;AAC9B,SAAK,QAAQ,eAAe,KAAK,MAAM,EAAE;AAAA,EAC3C;AAAA,EAES,SAAS;AAChB,UAAM,EAAE,UAAU,IAAI,GAAG,KAAK,IAAI,KAAK;AACvC,UAAM,EAAE,YAAY,YAAY,UAAU,IAAI,KAAK;AACnD,UAAM,aAAa,eAAe;AAElC,WACE,oBAAC,WAAiB,WAAsB,YACtC;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,KAAK;AAAA,QACf;AAAA,QACA,SAAS,MAAM,aAAa,EAAE;AAAA,QAC9B;AAAA,QACA,UAAU,aAAa,IAAI;AAAA,QAC3B;AAAA,QACA,sBAAoB;AAAA,QACpB,4BAA0B;AAAA,QAC1B,iBAAe;AAAA,QACf,MAAK;AAAA,QACL,iBAAe,GAAG,EAAE;AAAA,QACnB,GAAG;AAAA,QAEH;AAAA;AAAA,IACH,KAhBY,EAiBd;AAAA,EAEJ;AACF;AAEA,IAAM,WAAwC,CAAC,EAAE,UAAU,IAAI,GAAG,KAAK,MAAM;AAC3E,QAAM,UAAU,GAAG,EAAE;AAErB,SACE,oBAAC,SAAI,IAAI,SAAS,MAAK,YAAW,mBAAiB,IAAK,GAAG,MACxD,UACH;AAEJ;AAKA,IAAM,OAAN,cAAyB,iBAAyB;AAAA,EAChD,OAAO,SAAS;AAAA,EAChB,OAAO,QAAQ;AAAA,EACf,aAAkE,CAAC;AAAA,EACnE,UAAoB,CAAC;AAAA,EAErB,gBAAgB,MAAM,KAAK,MAAM;AAAA,EACjC,aAAa,CAAC,OAAe,KAAK,MAAM,SAAS,EAAE;AAAA,EACnD,aAAa,CAAC,IAAY,QAA0B;AAClD,QAAI,CAAC,KAAK,QAAQ,SAAS,EAAE,GAAG;AAC9B,WAAK,QAAQ,KAAK,EAAE;AACpB,WAAK,WAAW,EAAE,IAAI;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,cAAc,CAAC,YAAoB,UAAkB;AACnD,QAAI,KAAK,QAAQ,SAAS,UAAU,GAAG;AACrC,WAAK,UAAU,KAAK,QAAQ,IAAI,CAAC,OAAQ,OAAO,aAAa,QAAQ,EAAG;AACxE,WAAK,WAAW,KAAK,IAAI,KAAK,WAAW,UAAU;AACnD,WAAK,WAAW,UAAU,IAAI;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,eAAe,CAAC,OAAe;AAC7B,QAAI,KAAK,QAAQ,SAAS,EAAE,GAAG;AAC7B,WAAK,UAAU,KAAK,QAAQ,OAAO,CAAC,cAAc,cAAc,EAAE;AAClE,WAAK,WAAW,EAAE,IAAI;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,gBAAgB,CAAC,OAAe;AAC9B,UAAM,YAAY,KAAK,WAAW,EAAE;AACpC,SAAK,MAAM,SAAS,EAAE;AACtB,iBACE,UAAU,WACV,UAAU,QAAQ,SAClB,UAAU,QAAQ,MAAM;AAAA,EAC5B;AAAA,EAEA,aAAa,CAAC,EAAE,QAAQ,MAA2C;AACjE,YAAQ,SAAS;AAAA;AAAA,MAEf,KAAK;AACH,aAAK,QAAQ,QAAQ,CAAC,IAAI,UAAU;AAClC,cAAI,OAAO,KAAK,cAAc,GAAG;AAC/B,kBAAM,QAAQ,KAAK,QAAQ;AAC3B,kBAAM,YAAY,QAAQ,KAAK,IAAI,QAAQ,IAAI,QAAQ;AACvD,kBAAM,SAAS,KAAK,QAAQ,SAAS;AACrC,iBAAK,cAAc,SAAS,SAAS,EAAE;AAAA,UACzC;AAAA,QACF,CAAC;AACD;AAAA;AAAA,MAGF,KAAK;AACH,aAAK,QAAQ,QAAQ,CAAC,IAAI,UAAU;AAClC,cAAI,OAAO,KAAK,cAAc,GAAG;AAC/B,kBAAM,QAAQ,KAAK,QAAQ;AAC3B,kBAAM,YAAY,QAAQ,IAAI,QAAQ,QAAQ,IAAI;AAClD,kBAAM,SAAS,KAAK,QAAQ,SAAS;AACrC,iBAAK,cAAc,SAAS,SAAS,EAAE;AAAA,UACzC;AAAA,QACF,CAAC;AACD;AAAA,MAEF;AACE;AAAA,IACJ;AAAA,EACF;AAAA,EAES,SAAS;AAChB,UAAM,EAAE,UAAU,IAAI,UAAU,GAAG,KAAK,IAAI,KAAK;AACjD,WACE;AAAA,MAAC;AAAA;AAAA,QACC,gBAAa;AAAA,QACb,SAAS,KAAK;AAAA,QACd;AAAA,QACA,MAAK;AAAA,QACJ,GAAG;AAAA,QACH,GAAG;AAAA,QAEJ;AAAA,UAAC,iBAAiB;AAAA,UAAjB;AAAA,YACC,OAAO;AAAA,cACL,YAAY,KAAK,cAAc;AAAA,cAC/B,WAAW,KAAK,MAAM;AAAA,cACtB,YAAY,KAAK;AAAA,cACjB,YAAY,KAAK;AAAA,cACjB,aAAa,KAAK;AAAA,cAClB,cAAc,KAAK;AAAA,YACrB;AAAA,YAEC;AAAA;AAAA,QACH;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,IAAO,eAAQ;;;AGtLf,IAAO,gBAAQ;","names":["React","props"]}
1
+ {"version":3,"sources":["../../src/Tabs.tsx","../../src/styles.ts","../../src/TabsTypes.ts","../../src/index.ts"],"sourcesContent":["import * as React from \"react\";\nimport Container, { TabButton } from \"./styles\";\nimport type {\n TypeTabButtonsProps,\n TypeTabsProps,\n TypeTabPanelProps,\n} 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 <TabButton\n key={id}\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 aria-controls={`${id}-panel`}\n {...rest}\n >\n {children}\n </TabButton>\n );\n }\n}\n\nconst TabPanel: React.FC<TypeTabPanelProps> = ({ children, id, ...rest }) => {\n const panelId = `${id}-panel`;\n\n return (\n <div id={panelId} role=\"tabpanel\" aria-labelledby={id} {...rest}>\n {children}\n </div>\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 static Panel = TabPanel;\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<HTMLDivElement>) => {\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.div<TypeTabsProps>`\n display: ${(props) => (props.fullWidth ? \"flex\" : \"inline-flex\")};\n justify-content: space-between;\n margin: 0;\n padding: 0;\n border-bottom: ${(props) => props.theme.borders[500]}\n ${(props) => props.theme.colors.container.border.base};\n\n ${COMMON}\n`;\n\nexport const TabButton = styled(Button)<TypeStyleProps>`\n margin-bottom: -1px;\n padding: ${(props) => `${props.theme.space[350]} 0`};\n color: ${(props) => props.theme.colors.text.headline};\n border-radius: 0;\n border-width: 0 0 3px;\n width: 100%;\n\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 color: ${(props) => props.theme.colors.link.base};\n border-color: transparent transparent\n ${(props) => props.theme.colors.button.primary.background.base};\n `};\n\n &:hover {\n ${(props) =>\n props.isSelected &&\n css`\n color: ${(props) => props.theme.colors.link.hover};\n `};\n }\n\n &:focus,\n &:active {\n box-shadow: none;\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 TypeTabPanelProps\n extends React.ComponentPropsWithoutRef<\"div\"> {\n children: React.ReactNode;\n\n /** Should match the corresponding tab button id */\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"]}
package/dist/index.js CHANGED
@@ -57,8 +57,14 @@ var Container = import_styled_components.default.div`
57
57
 
58
58
  ${import_seeds_react_system_props.COMMON}
59
59
  `;
60
- var TabItem = import_styled_components.default.div`
60
+ var TabButton = (0, import_styled_components.default)(import_seeds_react_button.Button)`
61
61
  margin-bottom: -1px;
62
+ padding: ${(props) => `${props.theme.space[350]} 0`};
63
+ color: ${(props) => props.theme.colors.text.headline};
64
+ border-radius: 0;
65
+ border-width: 0 0 3px;
66
+ width: 100%;
67
+
62
68
  ${(props) => props.fullWidth && import_styled_components.css`
63
69
  flex-grow: 1;
64
70
  `};
@@ -69,23 +75,10 @@ var TabItem = import_styled_components.default.div`
69
75
  `};
70
76
  }
71
77
 
72
- ${(props) => props.isSelected && import_styled_components.css`
73
- box-shadow: ${(props2) => `inset 0 -3px 0 0 ${props2.theme.colors.button.primary.background.base}`};
74
- `};
75
-
76
- &:hover {
77
- ${(props) => props.isSelected && import_styled_components.css`
78
- box-shadow: ${(props2) => `inset 0 -3px 0 0 ${props2.theme.colors.button.primary.background.hover}`};
79
- `};
80
- }
81
- `;
82
- var TabButton = (0, import_styled_components.default)(import_seeds_react_button.Button)`
83
- padding: ${(props) => `${props.theme.space[350]} 0`};
84
- color: ${(props) => props.theme.colors.text.headline};
85
- width: 100%;
86
-
87
78
  ${(props) => props.isSelected && import_styled_components.css`
88
79
  color: ${(props2) => props2.theme.colors.link.base};
80
+ border-color: transparent transparent
81
+ ${(props2) => props2.theme.colors.button.primary.background.base};
89
82
  `};
90
83
 
91
84
  &:hover {
@@ -94,6 +87,11 @@ var TabButton = (0, import_styled_components.default)(import_seeds_react_button.
94
87
  `};
95
88
  }
96
89
 
90
+ &:focus,
91
+ &:active {
92
+ box-shadow: none;
93
+ }
94
+
97
95
  &:active {
98
96
  transform: none;
99
97
  }
@@ -125,7 +123,7 @@ var TabItemButton = class extends React2.Component {
125
123
  const { children, id, ...rest } = this.props;
126
124
  const { selectedId, onActivate, fullWidth } = this.context;
127
125
  const isSelected = selectedId === id;
128
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabItem, { fullWidth, isSelected, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
126
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
129
127
  TabButton,
130
128
  {
131
129
  innerRef: this.buttonRef,
@@ -141,8 +139,9 @@ var TabItemButton = class extends React2.Component {
141
139
  "aria-controls": `${id}-panel`,
142
140
  ...rest,
143
141
  children
144
- }
145
- ) }, id);
142
+ },
143
+ id
144
+ );
146
145
  }
147
146
  };
148
147
  var TabPanel = ({ children, id, ...rest }) => {
package/dist/index.js.map CHANGED
@@ -1 +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 {\n TypeTabButtonsProps,\n TypeTabsProps,\n TypeTabPanelProps,\n} 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 aria-controls={`${id}-panel`}\n {...rest}\n >\n {children}\n </TabButton>\n </TabItem>\n );\n }\n}\n\nconst TabPanel: React.FC<TypeTabPanelProps> = ({ children, id, ...rest }) => {\n const panelId = `${id}-panel`;\n\n return (\n <div id={panelId} role=\"tabpanel\" aria-labelledby={id} {...rest}>\n {children}\n </div>\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 static Panel = TabPanel;\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<HTMLDivElement>) => {\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.div<TypeTabsProps>`\n display: ${(props) => (props.fullWidth ? \"flex\" : \"inline-flex\")};\n justify-content: space-between;\n margin: 0;\n padding: 0;\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.div<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 TypeTabPanelProps\n extends React.ComponentPropsWithoutRef<\"div\"> {\n children: React.ReactNode;\n\n /** Should match the corresponding tab button id */\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"]}
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, { TabButton } from \"./styles\";\nimport type {\n TypeTabButtonsProps,\n TypeTabsProps,\n TypeTabPanelProps,\n} 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 <TabButton\n key={id}\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 aria-controls={`${id}-panel`}\n {...rest}\n >\n {children}\n </TabButton>\n );\n }\n}\n\nconst TabPanel: React.FC<TypeTabPanelProps> = ({ children, id, ...rest }) => {\n const panelId = `${id}-panel`;\n\n return (\n <div id={panelId} role=\"tabpanel\" aria-labelledby={id} {...rest}>\n {children}\n </div>\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 static Panel = TabPanel;\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<HTMLDivElement>) => {\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.div<TypeTabsProps>`\n display: ${(props) => (props.fullWidth ? \"flex\" : \"inline-flex\")};\n justify-content: space-between;\n margin: 0;\n padding: 0;\n border-bottom: ${(props) => props.theme.borders[500]}\n ${(props) => props.theme.colors.container.border.base};\n\n ${COMMON}\n`;\n\nexport const TabButton = styled(Button)<TypeStyleProps>`\n margin-bottom: -1px;\n padding: ${(props) => `${props.theme.space[350]} 0`};\n color: ${(props) => props.theme.colors.text.headline};\n border-radius: 0;\n border-width: 0 0 3px;\n width: 100%;\n\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 color: ${(props) => props.theme.colors.link.base};\n border-color: transparent transparent\n ${(props) => props.theme.colors.button.primary.background.base};\n `};\n\n &:hover {\n ${(props) =>\n props.isSelected &&\n css`\n color: ${(props) => props.theme.colors.link.hover};\n `};\n }\n\n &:focus,\n &:active {\n box-shadow: none;\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 TypeTabPanelProps\n extends React.ComponentPropsWithoutRef<\"div\"> {\n children: React.ReactNode;\n\n /** Should match the corresponding tab button id */\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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-tabs",
3
- "version": "1.2.9",
3
+ "version": "1.3.2",
4
4
  "description": "Seeds React Tabs",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -18,9 +18,9 @@
18
18
  "test:watch": "jest --watch --coverage=false"
19
19
  },
20
20
  "dependencies": {
21
- "@sproutsocial/seeds-react-theme": "^3.5.1",
21
+ "@sproutsocial/seeds-react-theme": "^3.6.0",
22
22
  "@sproutsocial/seeds-react-system-props": "^3.0.1",
23
- "@sproutsocial/seeds-react-button": "^1.3.18"
23
+ "@sproutsocial/seeds-react-button": "^1.4.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/react": "^18.0.0",
@@ -4,6 +4,7 @@ import { Icon, type TypeIconName } from "@sproutsocial/seeds-react-icon";
4
4
  import { Tabs } from "./";
5
5
  import { Text } from "@sproutsocial/seeds-react-text";
6
6
  import type { Meta, StoryObj } from "@storybook/react";
7
+ import Box from "@sproutsocial/seeds-react-box";
7
8
 
8
9
  interface TypeTabData {
9
10
  id: string;
@@ -77,6 +78,55 @@ export const Default: Story = {
77
78
  name: "Default",
78
79
  };
79
80
 
81
+ export const FullWidth: Story = {
82
+ render: (args) => {
83
+ const [selectedId, setSelectedId] = useState("notifications");
84
+
85
+ return (
86
+ <Box width="100%" display="flex" flexDirection="column">
87
+ <Tabs
88
+ selectedId={selectedId}
89
+ onSelect={(selected) => setSelectedId(selected)}
90
+ fullWidth
91
+ >
92
+ <Tabs.Button id="notifications">
93
+ <Icon name="bell-outline" mr="12px" aria-hidden />
94
+ <Text size="300" fontWeight="600">
95
+ Notifications
96
+ </Text>
97
+ </Tabs.Button>
98
+ <Tabs.Button id="issues">
99
+ <Icon name="triangle-exclamation-outline" mr="12px" aria-hidden />
100
+ <Text size="300" fontWeight="600">
101
+ Issues
102
+ </Text>
103
+ </Tabs.Button>
104
+ </Tabs>
105
+
106
+ {selectedId === "notifications" && (
107
+ <Tabs.Panel id="notifications">
108
+ <Text mt="24px">
109
+ Notifications panel content goes here. This panel is properly
110
+ connected to the "Notifications" tab via ARIA attributes for
111
+ accessibility.
112
+ </Text>
113
+ </Tabs.Panel>
114
+ )}
115
+
116
+ {selectedId === "issues" && (
117
+ <Tabs.Panel id="issues">
118
+ <Text mt="24px">
119
+ Issues panel content goes here. Screen readers will announce the
120
+ relationship between tabs and panels.
121
+ </Text>
122
+ </Tabs.Panel>
123
+ )}
124
+ </Box>
125
+ );
126
+ },
127
+ name: "Full width",
128
+ };
129
+
80
130
  export const RemoveATab: Story = {
81
131
  render: (args) => {
82
132
  const [state, setState] = useState<TypeTabsStoryState>({
package/src/Tabs.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import Container, { TabItem, TabButton } from "./styles";
2
+ import Container, { TabButton } from "./styles";
3
3
  import type {
4
4
  TypeTabButtonsProps,
5
5
  TypeTabsProps,
@@ -49,24 +49,23 @@ class TabItemButton extends React.Component<TypeTabButtonsProps> {
49
49
  const isSelected = selectedId === id;
50
50
 
51
51
  return (
52
- <TabItem key={id} fullWidth={fullWidth} isSelected={isSelected}>
53
- <TabButton
54
- innerRef={this.buttonRef}
55
- id={id}
56
- onClick={() => onActivate?.(id)}
57
- isSelected={isSelected}
58
- tabIndex={isSelected ? 0 : -1}
59
- fullWidth={fullWidth}
60
- data-qa-tab-button={id}
61
- data-qa-tab-button-state={isSelected}
62
- aria-selected={isSelected}
63
- role="tab"
64
- aria-controls={`${id}-panel`}
65
- {...rest}
66
- >
67
- {children}
68
- </TabButton>
69
- </TabItem>
52
+ <TabButton
53
+ key={id}
54
+ innerRef={this.buttonRef}
55
+ id={id}
56
+ onClick={() => onActivate?.(id)}
57
+ isSelected={isSelected}
58
+ tabIndex={isSelected ? 0 : -1}
59
+ fullWidth={fullWidth}
60
+ data-qa-tab-button={id}
61
+ data-qa-tab-button-state={isSelected}
62
+ aria-selected={isSelected}
63
+ role="tab"
64
+ aria-controls={`${id}-panel`}
65
+ {...rest}
66
+ >
67
+ {children}
68
+ </TabButton>
70
69
  );
71
70
  }
72
71
  }
package/src/styles.ts CHANGED
@@ -20,8 +20,14 @@ const Container = styled.div<TypeTabsProps>`
20
20
  ${COMMON}
21
21
  `;
22
22
 
23
- export const TabItem = styled.div<TypeStyleProps>`
23
+ export const TabButton = styled(Button)<TypeStyleProps>`
24
24
  margin-bottom: -1px;
25
+ padding: ${(props) => `${props.theme.space[350]} 0`};
26
+ color: ${(props) => props.theme.colors.text.headline};
27
+ border-radius: 0;
28
+ border-width: 0 0 3px;
29
+ width: 100%;
30
+
25
31
  ${(props) =>
26
32
  props.fullWidth &&
27
33
  css`
@@ -36,32 +42,12 @@ export const TabItem = styled.div<TypeStyleProps>`
36
42
  `};
37
43
  }
38
44
 
39
- ${(props) =>
40
- props.isSelected &&
41
- css`
42
- box-shadow: ${(props) =>
43
- `inset 0 -3px 0 0 ${props.theme.colors.button.primary.background.base}`};
44
- `};
45
-
46
- &:hover {
47
- ${(props) =>
48
- props.isSelected &&
49
- css`
50
- box-shadow: ${(props) =>
51
- `inset 0 -3px 0 0 ${props.theme.colors.button.primary.background.hover}`};
52
- `};
53
- }
54
- `;
55
-
56
- export const TabButton = styled(Button)<TypeStyleProps>`
57
- padding: ${(props) => `${props.theme.space[350]} 0`};
58
- color: ${(props) => props.theme.colors.text.headline};
59
- width: 100%;
60
-
61
45
  ${(props) =>
62
46
  props.isSelected &&
63
47
  css`
64
48
  color: ${(props) => props.theme.colors.link.base};
49
+ border-color: transparent transparent
50
+ ${(props) => props.theme.colors.button.primary.background.base};
65
51
  `};
66
52
 
67
53
  &:hover {
@@ -72,6 +58,11 @@ export const TabButton = styled(Button)<TypeStyleProps>`
72
58
  `};
73
59
  }
74
60
 
61
+ &:focus,
62
+ &:active {
63
+ box-shadow: none;
64
+ }
65
+
75
66
  &:active {
76
67
  transform: none;
77
68
  }