@sproutsocial/seeds-react-content-header 0.2.11 → 0.2.20

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.
@@ -8,14 +8,14 @@ $ tsup --dts
8
8
  CLI Cleaning output folder
9
9
  CJS Build start
10
10
  ESM Build start
11
- ESM dist/esm/index.js 4.03 KB
12
- ESM dist/esm/index.js.map 6.82 KB
13
- ESM ⚡️ Build success in 71ms
14
- CJS dist/index.js 6.42 KB
15
- CJS dist/index.js.map 6.85 KB
16
- CJS ⚡️ Build success in 71ms
11
+ CJS dist/index.js 6.38 KB
12
+ CJS dist/index.js.map 7.69 KB
13
+ CJS ⚡️ Build success in 69ms
14
+ ESM dist/esm/index.js 4.04 KB
15
+ ESM dist/esm/index.js.map 7.63 KB
16
+ ESM ⚡️ Build success in 70ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 2777ms
18
+ DTS ⚡️ Build success in 2716ms
19
19
  DTS dist/index.d.ts 1.84 KB
20
20
  DTS dist/index.d.mts 1.84 KB
21
- Done in 4.03s.
21
+ Done in 4.32s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # @sproutsocial/seeds-react-content-header
2
2
 
3
+ ## 0.2.20
4
+
5
+ ### Patch Changes
6
+
7
+ - @sproutsocial/seeds-react-box@1.1.22
8
+ - @sproutsocial/seeds-react-icon@2.4.1
9
+ - @sproutsocial/seeds-react-mixins@4.3.8
10
+
11
+ ## 0.2.19
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [69c9d02]
16
+ - @sproutsocial/seeds-react-icon@2.4.0
17
+
18
+ ## 0.2.18
19
+
20
+ ### Patch Changes
21
+
22
+ - edc1819: Migrate link, text, banner, loader-button, and content-header to the Tailwind hybrid pattern (mirroring seeds-react-button). Each component gains a pure CSS-class `*Tailwind` implementation, a `*Hybrid` router that falls back to styled-components when system/styled props are present, and a component-scoped CSS file of `seeds-*` classes built on `var(--…)` tokens. Component CSS is wrapped in `@layer components` so consumer Tailwind utility overrides win the cascade, and the per-component CSS import is dropped from the `*Tailwind` files since the CSS is aggregated into `@sproutsocial/racine/css/components` at build time. Legacy `styles.ts` paths are unchanged.
23
+ - Updated dependencies [edc1819]
24
+ - @sproutsocial/seeds-react-text@1.4.3
25
+
26
+ ## 0.2.17
27
+
28
+ ### Patch Changes
29
+
30
+ - @sproutsocial/seeds-react-box@1.1.21
31
+ - @sproutsocial/seeds-react-icon@2.3.13
32
+ - @sproutsocial/seeds-react-text@1.4.2
33
+
34
+ ## 0.2.16
35
+
36
+ ### Patch Changes
37
+
38
+ - @sproutsocial/seeds-react-box@1.1.20
39
+ - @sproutsocial/seeds-react-icon@2.3.12
40
+ - @sproutsocial/seeds-react-mixins@4.3.7
41
+
42
+ ## 0.2.15
43
+
44
+ ### Patch Changes
45
+
46
+ - @sproutsocial/seeds-react-box@1.1.19
47
+ - @sproutsocial/seeds-react-icon@2.3.11
48
+ - @sproutsocial/seeds-react-mixins@4.3.6
49
+ - @sproutsocial/seeds-react-text@1.4.1
50
+
51
+ ## 0.2.14
52
+
53
+ ### Patch Changes
54
+
55
+ - @sproutsocial/seeds-react-icon@2.3.10
56
+
57
+ ## 0.2.13
58
+
59
+ ### Patch Changes
60
+
61
+ - @sproutsocial/seeds-react-box@1.1.18
62
+ - @sproutsocial/seeds-react-icon@2.3.9
63
+ - @sproutsocial/seeds-react-mixins@4.3.5
64
+
65
+ ## 0.2.12
66
+
67
+ ### Patch Changes
68
+
69
+ - @sproutsocial/seeds-react-box@1.1.17
70
+ - @sproutsocial/seeds-react-icon@2.3.8
71
+ - @sproutsocial/seeds-react-mixins@4.3.4
72
+
3
73
  ## 0.2.11
4
74
 
5
75
  ### Patch Changes
package/dist/esm/index.js CHANGED
@@ -2,55 +2,59 @@
2
2
  import "react";
3
3
  import { Box as Box2 } from "@sproutsocial/seeds-react-box";
4
4
 
5
- // src/styles.ts
6
- import styled from "styled-components";
7
- import { divider, focusRing } from "@sproutsocial/seeds-react-mixins";
8
- var HeaderContainer = styled.div`
9
- box-sizing: border-box;
10
- display: flex;
11
- justify-content: space-between;
12
- align-items: center;
13
- width: 100%;
14
- color: ${({ theme }) => theme.colors.text.headline};
15
- padding: ${({ theme }) => theme.space[400]};
16
-
17
- ${({ $bordered }) => $bordered && divider}
18
-
19
- /* Delay hiding the divider until the close animation finishes */
20
- &:has(button[data-state="closed"]) {
21
- transition: border-bottom-color 0s ease-in-out 0.3s;
22
- border-bottom-color: transparent;
23
- }
24
- `;
25
- var TriggerButton = styled.button`
26
- all: unset;
27
- display: flex;
28
- align-items: center;
29
- justify-content: space-between;
30
- flex: 1;
31
- width: 100%;
32
- cursor: pointer;
33
- min-width: 0;
34
-
35
- .triggerIcon {
36
- flex-shrink: 0;
37
- transition: transform 300ms ease-in-out;
5
+ // src/ContentHeaderTailwind.tsx
6
+ import React from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ function cn(...inputs) {
9
+ const classes = [];
10
+ for (const input of inputs) {
11
+ if (!input) continue;
12
+ if (typeof input === "string") {
13
+ classes.push(input);
14
+ } else if (typeof input === "object") {
15
+ for (const [key, value] of Object.entries(input)) {
16
+ if (value) {
17
+ classes.push(key);
18
+ }
19
+ }
20
+ }
38
21
  }
39
-
40
- &[data-state="open"] .triggerIcon {
41
- transform: rotate(-180deg);
22
+ return classes.join(" ");
23
+ }
24
+ var HeaderContainer = ({
25
+ bordered = false,
26
+ className,
27
+ children,
28
+ ...rest
29
+ }) => /* @__PURE__ */ jsx(
30
+ "div",
31
+ {
32
+ className: cn(
33
+ "seeds-content-header",
34
+ { "seeds-content-header-bordered": bordered },
35
+ className
36
+ ),
37
+ ...rest,
38
+ children
42
39
  }
43
-
44
- &:focus-visible {
45
- ${focusRing}
40
+ );
41
+ var TriggerButton = React.forwardRef(({ className, children, type = "button", ...rest }, ref) => /* @__PURE__ */ jsx(
42
+ "button",
43
+ {
44
+ ref,
45
+ type,
46
+ className: cn("seeds-content-header-trigger", className),
47
+ ...rest,
48
+ children
46
49
  }
47
- `;
50
+ ));
51
+ TriggerButton.displayName = "TriggerButton";
48
52
 
49
53
  // src/TitleArea.tsx
50
54
  import "react";
51
55
  import { Box } from "@sproutsocial/seeds-react-box";
52
56
  import { Text } from "@sproutsocial/seeds-react-text";
53
- import { jsx, jsxs } from "react/jsx-runtime";
57
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
54
58
  var TitleArea = ({
55
59
  title,
56
60
  subtitle,
@@ -61,14 +65,14 @@ var TitleArea = ({
61
65
  }) => /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", flex: 1, width: "100%", minWidth: 0, children: [
62
66
  leftSlot,
63
67
  /* @__PURE__ */ jsxs(Box, { flex: 1, children: [
64
- /* @__PURE__ */ jsx(Text.Headline, { as: headingLevel, children: title }),
65
- subtitle && /* @__PURE__ */ jsx(Text.Byline, { as: subtitleAs, fontWeight: "normal", children: subtitle })
68
+ /* @__PURE__ */ jsx2(Text.Headline, { as: headingLevel, children: title }),
69
+ subtitle && /* @__PURE__ */ jsx2(Text.Byline, { as: subtitleAs, fontWeight: "normal", children: subtitle })
66
70
  ] }),
67
71
  rightSlot
68
72
  ] });
69
73
 
70
74
  // src/ContentHeader.tsx
71
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
75
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
72
76
  var ContentHeader = ({
73
77
  title,
74
78
  subtitle,
@@ -79,8 +83,8 @@ var ContentHeader = ({
79
83
  headerActions,
80
84
  bordered = true
81
85
  }) => {
82
- return /* @__PURE__ */ jsxs2(HeaderContainer, { $bordered: bordered, children: [
83
- /* @__PURE__ */ jsx2(
86
+ return /* @__PURE__ */ jsxs2(HeaderContainer, { bordered, children: [
87
+ /* @__PURE__ */ jsx3(
84
88
  TitleArea,
85
89
  {
86
90
  title,
@@ -91,7 +95,7 @@ var ContentHeader = ({
91
95
  rightSlot
92
96
  }
93
97
  ),
94
- headerActions && /* @__PURE__ */ jsx2(Box2, { children: headerActions })
98
+ headerActions && /* @__PURE__ */ jsx3(Box2, { children: headerActions })
95
99
  ] });
96
100
  };
97
101
  var ContentHeader_default = ContentHeader;
@@ -100,7 +104,7 @@ var ContentHeader_default = ContentHeader;
100
104
  import "react";
101
105
  import { Box as Box3 } from "@sproutsocial/seeds-react-box";
102
106
  import { Icon } from "@sproutsocial/seeds-react-icon";
103
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
107
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
104
108
  var CollapsibleContentHeader = ({
105
109
  title,
106
110
  subtitle,
@@ -114,7 +118,7 @@ var CollapsibleContentHeader = ({
114
118
  triggerIcon,
115
119
  bordered = true
116
120
  }) => {
117
- const defaultIcon = /* @__PURE__ */ jsx3(
121
+ const defaultIcon = /* @__PURE__ */ jsx4(
118
122
  Icon,
119
123
  {
120
124
  name: "chevron-down-outline",
@@ -123,10 +127,10 @@ var CollapsibleContentHeader = ({
123
127
  }
124
128
  );
125
129
  const resolvedIcon = triggerIcon !== void 0 ? triggerIcon : defaultIcon;
126
- return /* @__PURE__ */ jsxs3(HeaderContainer, { $bordered: bordered, children: [
127
- /* @__PURE__ */ jsx3(TriggerWrapper, { children: /* @__PURE__ */ jsxs3(TriggerButton, { type: "button", children: [
128
- triggerPosition === "left" && /* @__PURE__ */ jsx3(Box3, { mr: 400, children: resolvedIcon }),
129
- /* @__PURE__ */ jsx3(
130
+ return /* @__PURE__ */ jsxs3(HeaderContainer, { bordered, children: [
131
+ /* @__PURE__ */ jsx4(TriggerWrapper, { children: /* @__PURE__ */ jsxs3(TriggerButton, { type: "button", children: [
132
+ triggerPosition === "left" && /* @__PURE__ */ jsx4(Box3, { mr: 400, children: resolvedIcon }),
133
+ /* @__PURE__ */ jsx4(
130
134
  TitleArea,
131
135
  {
132
136
  title,
@@ -139,7 +143,7 @@ var CollapsibleContentHeader = ({
139
143
  ),
140
144
  triggerPosition === "right" && resolvedIcon
141
145
  ] }) }),
142
- headerActions && /* @__PURE__ */ jsx3(Box3, { ml: 300, children: headerActions })
146
+ headerActions && /* @__PURE__ */ jsx4(Box3, { ml: 300, children: headerActions })
143
147
  ] });
144
148
  };
145
149
  var CollapsibleContentHeader_default = CollapsibleContentHeader;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ContentHeader.tsx","../../src/styles.ts","../../src/TitleArea.tsx","../../src/CollapsibleContentHeader.tsx","../../src/index.ts"],"sourcesContent":["import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { type TypeContentHeaderProps } from \"./ContentHeaderTypes\";\nimport { HeaderContainer } from \"./styles\";\nimport { TitleArea } from \"./TitleArea\";\n\nexport const ContentHeader = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n headerActions,\n bordered = true,\n}: TypeContentHeaderProps) => {\n return (\n <HeaderContainer $bordered={bordered}>\n <TitleArea\n title={title}\n subtitle={subtitle}\n headingLevel={headingLevel}\n subtitleAs={subtitleAs}\n leftSlot={leftSlot}\n rightSlot={rightSlot}\n />\n {headerActions && <Box>{headerActions}</Box>}\n </HeaderContainer>\n );\n};\n\nexport default ContentHeader;\n","import styled from \"styled-components\";\nimport { divider, focusRing } from \"@sproutsocial/seeds-react-mixins\";\n\nexport const HeaderContainer = styled.div<{ $bordered?: boolean }>`\n box-sizing: border-box;\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n color: ${({ theme }) => theme.colors.text.headline};\n padding: ${({ theme }) => theme.space[400]};\n\n ${({ $bordered }) => $bordered && divider}\n\n /* Delay hiding the divider until the close animation finishes */\n &:has(button[data-state=\"closed\"]) {\n transition: border-bottom-color 0s ease-in-out 0.3s;\n border-bottom-color: transparent;\n }\n`;\n\nexport const TriggerButton = styled.button`\n all: unset;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex: 1;\n width: 100%;\n cursor: pointer;\n min-width: 0;\n\n .triggerIcon {\n flex-shrink: 0;\n transition: transform 300ms ease-in-out;\n }\n\n &[data-state=\"open\"] .triggerIcon {\n transform: rotate(-180deg);\n }\n\n &:focus-visible {\n ${focusRing}\n }\n`;\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport { type TypeHeadingLevel } from \"./ContentHeaderTypes\";\n\ninterface TypeTitleAreaProps {\n title: string;\n subtitle?: string;\n headingLevel?: TypeHeadingLevel;\n subtitleAs?: \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"p\";\n leftSlot?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\n\nexport const TitleArea = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n}: TypeTitleAreaProps) => (\n <Box display=\"flex\" alignItems=\"center\" flex={1} width=\"100%\" minWidth={0}>\n {leftSlot}\n <Box flex={1}>\n <Text.Headline as={headingLevel}>{title}</Text.Headline>\n {subtitle && (\n <Text.Byline as={subtitleAs} fontWeight=\"normal\">\n {subtitle}\n </Text.Byline>\n )}\n </Box>\n {rightSlot}\n </Box>\n);\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { type TypeCollapsibleContentHeaderProps } from \"./ContentHeaderTypes\";\nimport { HeaderContainer, TriggerButton } from \"./styles\";\nimport { TitleArea } from \"./TitleArea\";\n\nexport const CollapsibleContentHeader = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n headerActions,\n trigger: TriggerWrapper,\n triggerPosition = \"right\",\n triggerIcon,\n bordered = true,\n}: TypeCollapsibleContentHeaderProps) => {\n const defaultIcon = (\n <Icon\n name=\"chevron-down-outline\"\n className=\"triggerIcon\"\n aria-hidden=\"true\"\n />\n );\n\n const resolvedIcon = triggerIcon !== undefined ? triggerIcon : defaultIcon;\n\n return (\n <HeaderContainer $bordered={bordered}>\n <TriggerWrapper>\n <TriggerButton type=\"button\">\n {triggerPosition === \"left\" && <Box mr={400}>{resolvedIcon}</Box>}\n <TitleArea\n title={title}\n subtitle={subtitle}\n headingLevel={headingLevel}\n subtitleAs={subtitleAs}\n leftSlot={leftSlot}\n rightSlot={rightSlot}\n />\n {triggerPosition === \"right\" && resolvedIcon}\n </TriggerButton>\n </TriggerWrapper>\n {headerActions && <Box ml={300}>{headerActions}</Box>}\n </HeaderContainer>\n );\n};\n\nexport default CollapsibleContentHeader;\n","import ContentHeader from \"./ContentHeader\";\nimport CollapsibleContentHeader from \"./CollapsibleContentHeader\";\n\nexport default ContentHeader;\nexport { ContentHeader };\nexport { CollapsibleContentHeader };\nexport * from \"./ContentHeaderTypes\";\n"],"mappings":"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","names":["Box","jsx","jsxs","Box","Box","jsx","jsxs","Box"]}
1
+ {"version":3,"sources":["../../src/ContentHeader.tsx","../../src/ContentHeaderTailwind.tsx","../../src/TitleArea.tsx","../../src/CollapsibleContentHeader.tsx","../../src/index.ts"],"sourcesContent":["import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { type TypeContentHeaderProps } from \"./ContentHeaderTypes\";\nimport { HeaderContainer } from \"./ContentHeaderHybrid\";\nimport { TitleArea } from \"./TitleArea\";\n\nexport const ContentHeader = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n headerActions,\n bordered = true,\n}: TypeContentHeaderProps) => {\n return (\n <HeaderContainer bordered={bordered}>\n <TitleArea\n title={title}\n subtitle={subtitle}\n headingLevel={headingLevel}\n subtitleAs={subtitleAs}\n leftSlot={leftSlot}\n rightSlot={rightSlot}\n />\n {headerActions && <Box>{headerActions}</Box>}\n </HeaderContainer>\n );\n};\n\nexport default ContentHeader;\n","/**\n * Tailwind CSS implementation of ContentHeader primitives\n * Uses Seeds content-header CSS classes from content-header.css\n */\n\nimport React from \"react\";\n\n// Utility for merging class names properly\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\ninterface TypeHeaderContainerProps\n extends React.HTMLAttributes<HTMLDivElement> {\n bordered?: boolean;\n}\n\nexport const HeaderContainer = ({\n bordered = false,\n className,\n children,\n ...rest\n}: TypeHeaderContainerProps) => (\n <div\n className={cn(\n \"seeds-content-header\",\n { \"seeds-content-header-bordered\": bordered },\n className\n )}\n {...rest}\n >\n {children}\n </div>\n);\n\nexport const TriggerButton = React.forwardRef<\n HTMLButtonElement,\n React.ButtonHTMLAttributes<HTMLButtonElement>\n>(({ className, children, type = \"button\", ...rest }, ref) => (\n <button\n ref={ref}\n type={type}\n className={cn(\"seeds-content-header-trigger\", className)}\n {...rest}\n >\n {children}\n </button>\n));\n\nTriggerButton.displayName = \"TriggerButton\";\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport { type TypeHeadingLevel } from \"./ContentHeaderTypes\";\n\ninterface TypeTitleAreaProps {\n title: string;\n subtitle?: string;\n headingLevel?: TypeHeadingLevel;\n subtitleAs?: \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"p\";\n leftSlot?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\n\nexport const TitleArea = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n}: TypeTitleAreaProps) => (\n <Box display=\"flex\" alignItems=\"center\" flex={1} width=\"100%\" minWidth={0}>\n {leftSlot}\n <Box flex={1}>\n <Text.Headline as={headingLevel}>{title}</Text.Headline>\n {subtitle && (\n <Text.Byline as={subtitleAs} fontWeight=\"normal\">\n {subtitle}\n </Text.Byline>\n )}\n </Box>\n {rightSlot}\n </Box>\n);\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { type TypeCollapsibleContentHeaderProps } from \"./ContentHeaderTypes\";\nimport { HeaderContainer, TriggerButton } from \"./ContentHeaderHybrid\";\nimport { TitleArea } from \"./TitleArea\";\n\nexport const CollapsibleContentHeader = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n headerActions,\n trigger: TriggerWrapper,\n triggerPosition = \"right\",\n triggerIcon,\n bordered = true,\n}: TypeCollapsibleContentHeaderProps) => {\n const defaultIcon = (\n <Icon\n name=\"chevron-down-outline\"\n className=\"triggerIcon\"\n aria-hidden=\"true\"\n />\n );\n\n const resolvedIcon = triggerIcon !== undefined ? triggerIcon : defaultIcon;\n\n return (\n <HeaderContainer bordered={bordered}>\n <TriggerWrapper>\n <TriggerButton type=\"button\">\n {triggerPosition === \"left\" && <Box mr={400}>{resolvedIcon}</Box>}\n <TitleArea\n title={title}\n subtitle={subtitle}\n headingLevel={headingLevel}\n subtitleAs={subtitleAs}\n leftSlot={leftSlot}\n rightSlot={rightSlot}\n />\n {triggerPosition === \"right\" && resolvedIcon}\n </TriggerButton>\n </TriggerWrapper>\n {headerActions && <Box ml={300}>{headerActions}</Box>}\n </HeaderContainer>\n );\n};\n\nexport default CollapsibleContentHeader;\n","import ContentHeader from \"./ContentHeader\";\nimport CollapsibleContentHeader from \"./CollapsibleContentHeader\";\n\nexport default ContentHeader;\nexport { ContentHeader };\nexport { CollapsibleContentHeader };\nexport * from \"./ContentHeaderTypes\";\n"],"mappings":"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","names":["Box","jsx","jsx","jsxs","Box","Box","jsx","jsxs","Box"]}
package/dist/index.js CHANGED
@@ -37,58 +37,62 @@ __export(index_exports, {
37
37
  module.exports = __toCommonJS(index_exports);
38
38
 
39
39
  // src/ContentHeader.tsx
40
- var import_react2 = require("react");
40
+ var import_react3 = require("react");
41
41
  var import_seeds_react_box2 = require("@sproutsocial/seeds-react-box");
42
42
 
43
- // src/styles.ts
44
- var import_styled_components = __toESM(require("styled-components"));
45
- var import_seeds_react_mixins = require("@sproutsocial/seeds-react-mixins");
46
- var HeaderContainer = import_styled_components.default.div`
47
- box-sizing: border-box;
48
- display: flex;
49
- justify-content: space-between;
50
- align-items: center;
51
- width: 100%;
52
- color: ${({ theme }) => theme.colors.text.headline};
53
- padding: ${({ theme }) => theme.space[400]};
54
-
55
- ${({ $bordered }) => $bordered && import_seeds_react_mixins.divider}
56
-
57
- /* Delay hiding the divider until the close animation finishes */
58
- &:has(button[data-state="closed"]) {
59
- transition: border-bottom-color 0s ease-in-out 0.3s;
60
- border-bottom-color: transparent;
61
- }
62
- `;
63
- var TriggerButton = import_styled_components.default.button`
64
- all: unset;
65
- display: flex;
66
- align-items: center;
67
- justify-content: space-between;
68
- flex: 1;
69
- width: 100%;
70
- cursor: pointer;
71
- min-width: 0;
72
-
73
- .triggerIcon {
74
- flex-shrink: 0;
75
- transition: transform 300ms ease-in-out;
43
+ // src/ContentHeaderTailwind.tsx
44
+ var import_react = __toESM(require("react"));
45
+ var import_jsx_runtime = require("react/jsx-runtime");
46
+ function cn(...inputs) {
47
+ const classes = [];
48
+ for (const input of inputs) {
49
+ if (!input) continue;
50
+ if (typeof input === "string") {
51
+ classes.push(input);
52
+ } else if (typeof input === "object") {
53
+ for (const [key, value] of Object.entries(input)) {
54
+ if (value) {
55
+ classes.push(key);
56
+ }
57
+ }
58
+ }
76
59
  }
77
-
78
- &[data-state="open"] .triggerIcon {
79
- transform: rotate(-180deg);
60
+ return classes.join(" ");
61
+ }
62
+ var HeaderContainer = ({
63
+ bordered = false,
64
+ className,
65
+ children,
66
+ ...rest
67
+ }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
68
+ "div",
69
+ {
70
+ className: cn(
71
+ "seeds-content-header",
72
+ { "seeds-content-header-bordered": bordered },
73
+ className
74
+ ),
75
+ ...rest,
76
+ children
80
77
  }
81
-
82
- &:focus-visible {
83
- ${import_seeds_react_mixins.focusRing}
78
+ );
79
+ var TriggerButton = import_react.default.forwardRef(({ className, children, type = "button", ...rest }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
80
+ "button",
81
+ {
82
+ ref,
83
+ type,
84
+ className: cn("seeds-content-header-trigger", className),
85
+ ...rest,
86
+ children
84
87
  }
85
- `;
88
+ ));
89
+ TriggerButton.displayName = "TriggerButton";
86
90
 
87
91
  // src/TitleArea.tsx
88
- var import_react = require("react");
92
+ var import_react2 = require("react");
89
93
  var import_seeds_react_box = require("@sproutsocial/seeds-react-box");
90
94
  var import_seeds_react_text = require("@sproutsocial/seeds-react-text");
91
- var import_jsx_runtime = require("react/jsx-runtime");
95
+ var import_jsx_runtime2 = require("react/jsx-runtime");
92
96
  var TitleArea = ({
93
97
  title,
94
98
  subtitle,
@@ -96,17 +100,17 @@ var TitleArea = ({
96
100
  subtitleAs,
97
101
  leftSlot,
98
102
  rightSlot
99
- }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_seeds_react_box.Box, { display: "flex", alignItems: "center", flex: 1, width: "100%", minWidth: 0, children: [
103
+ }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_seeds_react_box.Box, { display: "flex", alignItems: "center", flex: 1, width: "100%", minWidth: 0, children: [
100
104
  leftSlot,
101
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_seeds_react_box.Box, { flex: 1, children: [
102
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_text.Text.Headline, { as: headingLevel, children: title }),
103
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_text.Text.Byline, { as: subtitleAs, fontWeight: "normal", children: subtitle })
105
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_seeds_react_box.Box, { flex: 1, children: [
106
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_text.Text.Headline, { as: headingLevel, children: title }),
107
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_text.Text.Byline, { as: subtitleAs, fontWeight: "normal", children: subtitle })
104
108
  ] }),
105
109
  rightSlot
106
110
  ] });
107
111
 
108
112
  // src/ContentHeader.tsx
109
- var import_jsx_runtime2 = require("react/jsx-runtime");
113
+ var import_jsx_runtime3 = require("react/jsx-runtime");
110
114
  var ContentHeader = ({
111
115
  title,
112
116
  subtitle,
@@ -117,8 +121,8 @@ var ContentHeader = ({
117
121
  headerActions,
118
122
  bordered = true
119
123
  }) => {
120
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(HeaderContainer, { $bordered: bordered, children: [
121
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
124
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(HeaderContainer, { bordered, children: [
125
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
122
126
  TitleArea,
123
127
  {
124
128
  title,
@@ -129,16 +133,16 @@ var ContentHeader = ({
129
133
  rightSlot
130
134
  }
131
135
  ),
132
- headerActions && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_box2.Box, { children: headerActions })
136
+ headerActions && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_box2.Box, { children: headerActions })
133
137
  ] });
134
138
  };
135
139
  var ContentHeader_default = ContentHeader;
136
140
 
137
141
  // src/CollapsibleContentHeader.tsx
138
- var import_react3 = require("react");
142
+ var import_react4 = require("react");
139
143
  var import_seeds_react_box3 = require("@sproutsocial/seeds-react-box");
140
144
  var import_seeds_react_icon = require("@sproutsocial/seeds-react-icon");
141
- var import_jsx_runtime3 = require("react/jsx-runtime");
145
+ var import_jsx_runtime4 = require("react/jsx-runtime");
142
146
  var CollapsibleContentHeader = ({
143
147
  title,
144
148
  subtitle,
@@ -152,7 +156,7 @@ var CollapsibleContentHeader = ({
152
156
  triggerIcon,
153
157
  bordered = true
154
158
  }) => {
155
- const defaultIcon = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
159
+ const defaultIcon = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
156
160
  import_seeds_react_icon.Icon,
157
161
  {
158
162
  name: "chevron-down-outline",
@@ -161,10 +165,10 @@ var CollapsibleContentHeader = ({
161
165
  }
162
166
  );
163
167
  const resolvedIcon = triggerIcon !== void 0 ? triggerIcon : defaultIcon;
164
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(HeaderContainer, { $bordered: bordered, children: [
165
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TriggerWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(TriggerButton, { type: "button", children: [
166
- triggerPosition === "left" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_box3.Box, { mr: 400, children: resolvedIcon }),
167
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
168
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(HeaderContainer, { bordered, children: [
169
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(TriggerWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(TriggerButton, { type: "button", children: [
170
+ triggerPosition === "left" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_seeds_react_box3.Box, { mr: 400, children: resolvedIcon }),
171
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
168
172
  TitleArea,
169
173
  {
170
174
  title,
@@ -177,7 +181,7 @@ var CollapsibleContentHeader = ({
177
181
  ),
178
182
  triggerPosition === "right" && resolvedIcon
179
183
  ] }) }),
180
- headerActions && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_box3.Box, { ml: 300, children: headerActions })
184
+ headerActions && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_seeds_react_box3.Box, { ml: 300, children: headerActions })
181
185
  ] });
182
186
  };
183
187
  var CollapsibleContentHeader_default = CollapsibleContentHeader;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/ContentHeader.tsx","../src/styles.ts","../src/TitleArea.tsx","../src/CollapsibleContentHeader.tsx"],"sourcesContent":["import ContentHeader from \"./ContentHeader\";\nimport CollapsibleContentHeader from \"./CollapsibleContentHeader\";\n\nexport default ContentHeader;\nexport { ContentHeader };\nexport { CollapsibleContentHeader };\nexport * from \"./ContentHeaderTypes\";\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { type TypeContentHeaderProps } from \"./ContentHeaderTypes\";\nimport { HeaderContainer } from \"./styles\";\nimport { TitleArea } from \"./TitleArea\";\n\nexport const ContentHeader = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n headerActions,\n bordered = true,\n}: TypeContentHeaderProps) => {\n return (\n <HeaderContainer $bordered={bordered}>\n <TitleArea\n title={title}\n subtitle={subtitle}\n headingLevel={headingLevel}\n subtitleAs={subtitleAs}\n leftSlot={leftSlot}\n rightSlot={rightSlot}\n />\n {headerActions && <Box>{headerActions}</Box>}\n </HeaderContainer>\n );\n};\n\nexport default ContentHeader;\n","import styled from \"styled-components\";\nimport { divider, focusRing } from \"@sproutsocial/seeds-react-mixins\";\n\nexport const HeaderContainer = styled.div<{ $bordered?: boolean }>`\n box-sizing: border-box;\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%;\n color: ${({ theme }) => theme.colors.text.headline};\n padding: ${({ theme }) => theme.space[400]};\n\n ${({ $bordered }) => $bordered && divider}\n\n /* Delay hiding the divider until the close animation finishes */\n &:has(button[data-state=\"closed\"]) {\n transition: border-bottom-color 0s ease-in-out 0.3s;\n border-bottom-color: transparent;\n }\n`;\n\nexport const TriggerButton = styled.button`\n all: unset;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex: 1;\n width: 100%;\n cursor: pointer;\n min-width: 0;\n\n .triggerIcon {\n flex-shrink: 0;\n transition: transform 300ms ease-in-out;\n }\n\n &[data-state=\"open\"] .triggerIcon {\n transform: rotate(-180deg);\n }\n\n &:focus-visible {\n ${focusRing}\n }\n`;\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport { type TypeHeadingLevel } from \"./ContentHeaderTypes\";\n\ninterface TypeTitleAreaProps {\n title: string;\n subtitle?: string;\n headingLevel?: TypeHeadingLevel;\n subtitleAs?: \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"p\";\n leftSlot?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\n\nexport const TitleArea = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n}: TypeTitleAreaProps) => (\n <Box display=\"flex\" alignItems=\"center\" flex={1} width=\"100%\" minWidth={0}>\n {leftSlot}\n <Box flex={1}>\n <Text.Headline as={headingLevel}>{title}</Text.Headline>\n {subtitle && (\n <Text.Byline as={subtitleAs} fontWeight=\"normal\">\n {subtitle}\n </Text.Byline>\n )}\n </Box>\n {rightSlot}\n </Box>\n);\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { type TypeCollapsibleContentHeaderProps } from \"./ContentHeaderTypes\";\nimport { HeaderContainer, TriggerButton } from \"./styles\";\nimport { TitleArea } from \"./TitleArea\";\n\nexport const CollapsibleContentHeader = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n headerActions,\n trigger: TriggerWrapper,\n triggerPosition = \"right\",\n triggerIcon,\n bordered = true,\n}: TypeCollapsibleContentHeaderProps) => {\n const defaultIcon = (\n <Icon\n name=\"chevron-down-outline\"\n className=\"triggerIcon\"\n aria-hidden=\"true\"\n />\n );\n\n const resolvedIcon = triggerIcon !== undefined ? triggerIcon : defaultIcon;\n\n return (\n <HeaderContainer $bordered={bordered}>\n <TriggerWrapper>\n <TriggerButton type=\"button\">\n {triggerPosition === \"left\" && <Box mr={400}>{resolvedIcon}</Box>}\n <TitleArea\n title={title}\n subtitle={subtitle}\n headingLevel={headingLevel}\n subtitleAs={subtitleAs}\n leftSlot={leftSlot}\n rightSlot={rightSlot}\n />\n {triggerPosition === \"right\" && resolvedIcon}\n </TriggerButton>\n </TriggerWrapper>\n {headerActions && <Box ml={300}>{headerActions}</Box>}\n </HeaderContainer>\n );\n};\n\nexport default CollapsibleContentHeader;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAAkB;AAClB,IAAAC,0BAAoB;;;ACDpB,+BAAmB;AACnB,gCAAmC;AAE5B,IAAM,kBAAkB,yBAAAC,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAM3B,CAAC,EAAE,MAAM,MAAM,MAAM,OAAO,KAAK,QAAQ;AAAA,aACvC,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA,IAExC,CAAC,EAAE,UAAU,MAAM,aAAa,iCAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpC,IAAM,gBAAgB,yBAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAoB9B,mCAAS;AAAA;AAAA;;;ACzCf,mBAAkB;AAClB,6BAAoB;AACpB,8BAAqB;AAsBjB;AAVG,IAAM,YAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AACF,MACE,6CAAC,8BAAI,SAAQ,QAAO,YAAW,UAAS,MAAM,GAAG,OAAM,QAAO,UAAU,GACrE;AAAA;AAAA,EACD,6CAAC,8BAAI,MAAM,GACT;AAAA,gDAAC,6BAAK,UAAL,EAAc,IAAI,cAAe,iBAAM;AAAA,IACvC,YACC,4CAAC,6BAAK,QAAL,EAAY,IAAI,YAAY,YAAW,UACrC,oBACH;AAAA,KAEJ;AAAA,EACC;AAAA,GACH;;;AFhBE,IAAAC,sBAAA;AAXG,IAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AACb,MAA8B;AAC5B,SACE,8CAAC,mBAAgB,WAAW,UAC1B;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,IACC,iBAAiB,6CAAC,+BAAK,yBAAc;AAAA,KACxC;AAEJ;AAEA,IAAO,wBAAQ;;;AG/Bf,IAAAC,gBAAkB;AAClB,IAAAC,0BAAoB;AACpB,8BAAqB;AAmBjB,IAAAC,sBAAA;AAdG,IAAM,2BAA2B,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB;AAAA,EACA,WAAW;AACb,MAAyC;AACvC,QAAM,cACJ;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,eAAY;AAAA;AAAA,EACd;AAGF,QAAM,eAAe,gBAAgB,SAAY,cAAc;AAE/D,SACE,8CAAC,mBAAgB,WAAW,UAC1B;AAAA,iDAAC,kBACC,wDAAC,iBAAc,MAAK,UACjB;AAAA,0BAAoB,UAAU,6CAAC,+BAAI,IAAI,KAAM,wBAAa;AAAA,MAC3D;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,MACC,oBAAoB,WAAW;AAAA,OAClC,GACF;AAAA,IACC,iBAAiB,6CAAC,+BAAI,IAAI,KAAM,yBAAc;AAAA,KACjD;AAEJ;AAEA,IAAO,mCAAQ;;;AJhDf,IAAO,gBAAQ;","names":["import_react","import_seeds_react_box","styled","import_jsx_runtime","import_react","import_seeds_react_box","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/ContentHeader.tsx","../src/ContentHeaderTailwind.tsx","../src/TitleArea.tsx","../src/CollapsibleContentHeader.tsx"],"sourcesContent":["import ContentHeader from \"./ContentHeader\";\nimport CollapsibleContentHeader from \"./CollapsibleContentHeader\";\n\nexport default ContentHeader;\nexport { ContentHeader };\nexport { CollapsibleContentHeader };\nexport * from \"./ContentHeaderTypes\";\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { type TypeContentHeaderProps } from \"./ContentHeaderTypes\";\nimport { HeaderContainer } from \"./ContentHeaderHybrid\";\nimport { TitleArea } from \"./TitleArea\";\n\nexport const ContentHeader = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n headerActions,\n bordered = true,\n}: TypeContentHeaderProps) => {\n return (\n <HeaderContainer bordered={bordered}>\n <TitleArea\n title={title}\n subtitle={subtitle}\n headingLevel={headingLevel}\n subtitleAs={subtitleAs}\n leftSlot={leftSlot}\n rightSlot={rightSlot}\n />\n {headerActions && <Box>{headerActions}</Box>}\n </HeaderContainer>\n );\n};\n\nexport default ContentHeader;\n","/**\n * Tailwind CSS implementation of ContentHeader primitives\n * Uses Seeds content-header CSS classes from content-header.css\n */\n\nimport React from \"react\";\n\n// Utility for merging class names properly\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\ninterface TypeHeaderContainerProps\n extends React.HTMLAttributes<HTMLDivElement> {\n bordered?: boolean;\n}\n\nexport const HeaderContainer = ({\n bordered = false,\n className,\n children,\n ...rest\n}: TypeHeaderContainerProps) => (\n <div\n className={cn(\n \"seeds-content-header\",\n { \"seeds-content-header-bordered\": bordered },\n className\n )}\n {...rest}\n >\n {children}\n </div>\n);\n\nexport const TriggerButton = React.forwardRef<\n HTMLButtonElement,\n React.ButtonHTMLAttributes<HTMLButtonElement>\n>(({ className, children, type = \"button\", ...rest }, ref) => (\n <button\n ref={ref}\n type={type}\n className={cn(\"seeds-content-header-trigger\", className)}\n {...rest}\n >\n {children}\n </button>\n));\n\nTriggerButton.displayName = \"TriggerButton\";\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport { type TypeHeadingLevel } from \"./ContentHeaderTypes\";\n\ninterface TypeTitleAreaProps {\n title: string;\n subtitle?: string;\n headingLevel?: TypeHeadingLevel;\n subtitleAs?: \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"p\";\n leftSlot?: React.ReactNode;\n rightSlot?: React.ReactNode;\n}\n\nexport const TitleArea = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n}: TypeTitleAreaProps) => (\n <Box display=\"flex\" alignItems=\"center\" flex={1} width=\"100%\" minWidth={0}>\n {leftSlot}\n <Box flex={1}>\n <Text.Headline as={headingLevel}>{title}</Text.Headline>\n {subtitle && (\n <Text.Byline as={subtitleAs} fontWeight=\"normal\">\n {subtitle}\n </Text.Byline>\n )}\n </Box>\n {rightSlot}\n </Box>\n);\n","import React from \"react\";\nimport { Box } from \"@sproutsocial/seeds-react-box\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { type TypeCollapsibleContentHeaderProps } from \"./ContentHeaderTypes\";\nimport { HeaderContainer, TriggerButton } from \"./ContentHeaderHybrid\";\nimport { TitleArea } from \"./TitleArea\";\n\nexport const CollapsibleContentHeader = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n headerActions,\n trigger: TriggerWrapper,\n triggerPosition = \"right\",\n triggerIcon,\n bordered = true,\n}: TypeCollapsibleContentHeaderProps) => {\n const defaultIcon = (\n <Icon\n name=\"chevron-down-outline\"\n className=\"triggerIcon\"\n aria-hidden=\"true\"\n />\n );\n\n const resolvedIcon = triggerIcon !== undefined ? triggerIcon : defaultIcon;\n\n return (\n <HeaderContainer bordered={bordered}>\n <TriggerWrapper>\n <TriggerButton type=\"button\">\n {triggerPosition === \"left\" && <Box mr={400}>{resolvedIcon}</Box>}\n <TitleArea\n title={title}\n subtitle={subtitle}\n headingLevel={headingLevel}\n subtitleAs={subtitleAs}\n leftSlot={leftSlot}\n rightSlot={rightSlot}\n />\n {triggerPosition === \"right\" && resolvedIcon}\n </TriggerButton>\n </TriggerWrapper>\n {headerActions && <Box ml={300}>{headerActions}</Box>}\n </HeaderContainer>\n );\n};\n\nexport default CollapsibleContentHeader;\n"],"mappings":"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","names":["import_react","import_seeds_react_box","React","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_seeds_react_box","import_jsx_runtime"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-content-header",
3
- "version": "0.2.11",
3
+ "version": "0.2.20",
4
4
  "description": "Seeds React ContentHeader",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -18,10 +18,10 @@
18
18
  "test:watch": "jest --watch --coverage=false"
19
19
  },
20
20
  "dependencies": {
21
- "@sproutsocial/seeds-react-box": "^1.1.16",
22
- "@sproutsocial/seeds-react-icon": "^2.3.7",
23
- "@sproutsocial/seeds-react-mixins": "^4.3.3",
24
- "@sproutsocial/seeds-react-text": "^1.4.0"
21
+ "@sproutsocial/seeds-react-box": "^1.1.22",
22
+ "@sproutsocial/seeds-react-icon": "^2.4.1",
23
+ "@sproutsocial/seeds-react-mixins": "^4.3.8",
24
+ "@sproutsocial/seeds-react-text": "^1.4.3"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/react": "^18.0.0",
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import { Box } from "@sproutsocial/seeds-react-box";
3
3
  import { Icon } from "@sproutsocial/seeds-react-icon";
4
4
  import { type TypeCollapsibleContentHeaderProps } from "./ContentHeaderTypes";
5
- import { HeaderContainer, TriggerButton } from "./styles";
5
+ import { HeaderContainer, TriggerButton } from "./ContentHeaderHybrid";
6
6
  import { TitleArea } from "./TitleArea";
7
7
 
8
8
  export const CollapsibleContentHeader = ({
@@ -29,7 +29,7 @@ export const CollapsibleContentHeader = ({
29
29
  const resolvedIcon = triggerIcon !== undefined ? triggerIcon : defaultIcon;
30
30
 
31
31
  return (
32
- <HeaderContainer $bordered={bordered}>
32
+ <HeaderContainer bordered={bordered}>
33
33
  <TriggerWrapper>
34
34
  <TriggerButton type="button">
35
35
  {triggerPosition === "left" && <Box mr={400}>{resolvedIcon}</Box>}
@@ -0,0 +1,44 @@
1
+ import { ContentHeader } from "./";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+
4
+ const meta: Meta<typeof ContentHeader> = {
5
+ title: "Components/ContentHeader",
6
+ component: ContentHeader,
7
+ };
8
+ export default meta;
9
+
10
+ type Story = StoryObj<typeof ContentHeader>;
11
+
12
+ /**
13
+ * Default ContentHeader with a title and subtitle. The bottom divider is shown
14
+ * because `bordered` defaults to `true`.
15
+ */
16
+ export const Default: Story = {
17
+ args: {
18
+ title: "Section title",
19
+ subtitle: "A short supporting subtitle",
20
+ },
21
+ render: (args) => <ContentHeader {...args} />,
22
+ };
23
+
24
+ /**
25
+ * Title only — no subtitle is rendered when `subtitle` is omitted.
26
+ */
27
+ export const TitleOnly: Story = {
28
+ args: {
29
+ title: "Just a title",
30
+ },
31
+ render: (args) => <ContentHeader {...args} />,
32
+ };
33
+
34
+ /**
35
+ * With `bordered` set to `false` the bottom divider is removed.
36
+ */
37
+ export const WithoutBorder: Story = {
38
+ args: {
39
+ title: "No divider",
40
+ subtitle: "bordered is false",
41
+ bordered: false,
42
+ },
43
+ render: (args) => <ContentHeader {...args} />,
44
+ };
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { Box } from "@sproutsocial/seeds-react-box";
3
3
  import { type TypeContentHeaderProps } from "./ContentHeaderTypes";
4
- import { HeaderContainer } from "./styles";
4
+ import { HeaderContainer } from "./ContentHeaderHybrid";
5
5
  import { TitleArea } from "./TitleArea";
6
6
 
7
7
  export const ContentHeader = ({
@@ -15,7 +15,7 @@ export const ContentHeader = ({
15
15
  bordered = true,
16
16
  }: TypeContentHeaderProps) => {
17
17
  return (
18
- <HeaderContainer $bordered={bordered}>
18
+ <HeaderContainer bordered={bordered}>
19
19
  <TitleArea
20
20
  title={title}
21
21
  subtitle={subtitle}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hybrid ContentHeader primitives.
3
+ *
4
+ * ContentHeader exposes no system props / no `...rest` / no className passthrough,
5
+ * so there is nothing to route on — the hybrid is degenerate and always renders
6
+ * the Tailwind implementation. The styled-components version in `styles.ts` is
7
+ * retained as unreachable legacy for reference.
8
+ */
9
+
10
+ export { HeaderContainer, TriggerButton } from "./ContentHeaderTailwind";
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Tailwind CSS implementation of ContentHeader primitives
3
+ * Uses Seeds content-header CSS classes from content-header.css
4
+ */
5
+
6
+ import React from "react";
7
+
8
+ // Utility for merging class names properly
9
+ function cn(
10
+ ...inputs: (string | undefined | null | false | Record<string, boolean>)[]
11
+ ): string {
12
+ const classes: string[] = [];
13
+
14
+ for (const input of inputs) {
15
+ if (!input) continue;
16
+
17
+ if (typeof input === "string") {
18
+ classes.push(input);
19
+ } else if (typeof input === "object") {
20
+ for (const [key, value] of Object.entries(input)) {
21
+ if (value) {
22
+ classes.push(key);
23
+ }
24
+ }
25
+ }
26
+ }
27
+
28
+ return classes.join(" ");
29
+ }
30
+
31
+ interface TypeHeaderContainerProps
32
+ extends React.HTMLAttributes<HTMLDivElement> {
33
+ bordered?: boolean;
34
+ }
35
+
36
+ export const HeaderContainer = ({
37
+ bordered = false,
38
+ className,
39
+ children,
40
+ ...rest
41
+ }: TypeHeaderContainerProps) => (
42
+ <div
43
+ className={cn(
44
+ "seeds-content-header",
45
+ { "seeds-content-header-bordered": bordered },
46
+ className
47
+ )}
48
+ {...rest}
49
+ >
50
+ {children}
51
+ </div>
52
+ );
53
+
54
+ export const TriggerButton = React.forwardRef<
55
+ HTMLButtonElement,
56
+ React.ButtonHTMLAttributes<HTMLButtonElement>
57
+ >(({ className, children, type = "button", ...rest }, ref) => (
58
+ <button
59
+ ref={ref}
60
+ type={type}
61
+ className={cn("seeds-content-header-trigger", className)}
62
+ {...rest}
63
+ >
64
+ {children}
65
+ </button>
66
+ ));
67
+
68
+ TriggerButton.displayName = "TriggerButton";
@@ -0,0 +1,48 @@
1
+ import React from "react";
2
+ import {
3
+ render,
4
+ screen,
5
+ fireEvent,
6
+ } from "@sproutsocial/seeds-react-testing-library";
7
+ import { Collapsible } from "@sproutsocial/seeds-react-collapsible";
8
+ import { ContentHeader } from "../ContentHeader";
9
+ import { CollapsibleContentHeader } from "../CollapsibleContentHeader";
10
+
11
+ describe("ContentHeader Tailwind path", () => {
12
+ it("renders the container with the seeds-content-header class", () => {
13
+ const { container } = render(<ContentHeader title="Title" />);
14
+ const header = container.querySelector(".seeds-content-header");
15
+ expect(header).toBeInTheDocument();
16
+ });
17
+
18
+ it("applies the bordered class by default", () => {
19
+ const { container } = render(<ContentHeader title="Title" />);
20
+ expect(container.querySelector(".seeds-content-header")).toHaveClass(
21
+ "seeds-content-header-bordered"
22
+ );
23
+ });
24
+
25
+ it("omits the bordered class when bordered is false", () => {
26
+ const { container } = render(
27
+ <ContentHeader title="Title" bordered={false} />
28
+ );
29
+ expect(container.querySelector(".seeds-content-header")).not.toHaveClass(
30
+ "seeds-content-header-bordered"
31
+ );
32
+ });
33
+
34
+ it("renders the collapsible trigger with the trigger class and toggles", () => {
35
+ const onOpenChange = jest.fn();
36
+ render(
37
+ <Collapsible isOpen={true} onOpenChange={onOpenChange}>
38
+ <CollapsibleContentHeader title="Title" trigger={Collapsible.Trigger} />
39
+ <Collapsible.Panel>Content</Collapsible.Panel>
40
+ </Collapsible>
41
+ );
42
+
43
+ const trigger = screen.getByRole("button");
44
+ expect(trigger).toHaveClass("seeds-content-header-trigger");
45
+ fireEvent.click(trigger);
46
+ expect(onOpenChange).toHaveBeenCalledWith(false);
47
+ });
48
+ });
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Seeds ContentHeader component classes
3
+ * Use these instead of writing out individual Tailwind utility classes.
4
+ *
5
+ * Requires @sproutsocial/seeds-react-theme/dist/theme-all.css imported for
6
+ * CSS variable definitions and dark mode support.
7
+ *
8
+ * Rules live in the Tailwind `components` layer so consumer utility classes
9
+ * (e.g. mx-200, p-300, inline-flex) win the cascade over these defaults.
10
+ */
11
+
12
+ @layer components {
13
+ .seeds-content-header {
14
+ box-sizing: border-box;
15
+ display: flex;
16
+ justify-content: space-between;
17
+ align-items: center;
18
+ width: 100%;
19
+ color: var(--color-text-headline);
20
+ padding: var(--space-400);
21
+ }
22
+
23
+ .seeds-content-header-bordered {
24
+ border-bottom: 1px solid var(--color-container-border-base);
25
+ }
26
+
27
+ /* Delay hiding the divider until the close animation finishes */
28
+ .seeds-content-header:has(button[data-state="closed"]) {
29
+ transition: border-bottom-color 0s ease-in-out 0.3s;
30
+ border-bottom-color: transparent;
31
+ }
32
+
33
+ .seeds-content-header-trigger {
34
+ all: unset;
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: space-between;
38
+ flex: 1;
39
+ width: 100%;
40
+ cursor: pointer;
41
+ min-width: 0;
42
+ }
43
+
44
+ .seeds-content-header-trigger .triggerIcon {
45
+ flex-shrink: 0;
46
+ transition: transform 300ms ease-in-out;
47
+ }
48
+
49
+ .seeds-content-header-trigger[data-state="open"] .triggerIcon {
50
+ transform: rotate(-180deg);
51
+ }
52
+
53
+ .seeds-content-header-trigger:focus-visible {
54
+ outline: none;
55
+ box-shadow:
56
+ 0 0 0 1px var(--color-button-primary-bg-base),
57
+ 0 0 0 4px color-mix(in srgb, var(--color-button-primary-bg-base) 30%, transparent);
58
+ }
59
+ }