@sproutsocial/seeds-react-content-header 0.2.31 → 0.3.1

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
- CJS dist/index.js 6.36 KB
12
- CJS dist/index.js.map 7.61 KB
13
- CJS ⚡️ Build success in 114ms
14
- ESM dist/esm/index.js 4.02 KB
15
- ESM dist/esm/index.js.map 7.56 KB
16
- ESM ⚡️ Build success in 115ms
11
+ CJS dist/index.js 6.92 KB
12
+ CJS dist/index.js.map 8.42 KB
13
+ CJS ⚡️ Build success in 17ms
14
+ ESM dist/esm/index.js 4.53 KB
15
+ ESM dist/esm/index.js.map 8.37 KB
16
+ ESM ⚡️ Build success in 17ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 4182ms
19
- DTS dist/index.d.ts 1.84 KB
20
- DTS dist/index.d.mts 1.84 KB
21
- Done in 5.63s.
18
+ DTS ⚡️ Build success in 3231ms
19
+ DTS dist/index.d.ts 2.16 KB
20
+ DTS dist/index.d.mts 2.16 KB
21
+ Done in 4.81s.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @sproutsocial/seeds-react-content-header
2
2
 
3
+ ## 0.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - @sproutsocial/seeds-react-box@1.1.32
8
+ - @sproutsocial/seeds-react-icon@2.5.2
9
+ - @sproutsocial/seeds-react-mixins@4.3.16
10
+
11
+ ## 0.3.0
12
+
13
+ ### Minor Changes
14
+
15
+ - bb491e7: Adds an optional `rightTitleElement` prop to `ContentBlock`, `ContentHeader`, and
16
+ `CollapsibleContentHeader` to render an element inline after the title text (ex. a beta
17
+ badge) while keeping `title` a plain string.
18
+
19
+ Unlike the existing `rightSlot`, which sits at the far right of the title area,
20
+ `rightTitleElement` sits directly beside the title text. `rightSlot` behavior is
21
+ unchanged.
22
+
3
23
  ## 0.2.31
4
24
 
5
25
  ### Patch Changes
package/dist/esm/index.js CHANGED
@@ -61,15 +61,26 @@ var TitleArea = ({
61
61
  headingLevel = "h4",
62
62
  subtitleAs,
63
63
  leftSlot,
64
- rightSlot
65
- }) => /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", flex: 1, width: "100%", minWidth: 0, children: [
66
- leftSlot,
67
- /* @__PURE__ */ jsxs(Box, { flex: 1, children: [
68
- /* @__PURE__ */ jsx2(Text.Headline, { as: headingLevel, children: title }),
69
- subtitle && /* @__PURE__ */ jsx2(Text.Byline, { as: subtitleAs, children: subtitle })
70
- ] }),
71
- rightSlot
72
- ] });
64
+ rightSlot,
65
+ rightTitleElement
66
+ }) => {
67
+ const heading = /* @__PURE__ */ jsx2(Text.Headline, { as: headingLevel, children: title });
68
+ return /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", flex: 1, width: "100%", minWidth: 0, children: [
69
+ leftSlot,
70
+ /* @__PURE__ */ jsxs(Box, { flex: 1, minWidth: 0, children: [
71
+ rightTitleElement ? (
72
+ // Keep the element on the title's own line so it tracks the title
73
+ // text instead of being pushed to the edge of the title area.
74
+ /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", gap: 300, children: [
75
+ heading,
76
+ rightTitleElement
77
+ ] })
78
+ ) : heading,
79
+ subtitle && /* @__PURE__ */ jsx2(Text.Byline, { as: subtitleAs, children: subtitle })
80
+ ] }),
81
+ rightSlot
82
+ ] });
83
+ };
73
84
 
74
85
  // src/ContentHeader.tsx
75
86
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -80,6 +91,7 @@ var ContentHeader = ({
80
91
  subtitleAs,
81
92
  leftSlot,
82
93
  rightSlot,
94
+ rightTitleElement,
83
95
  headerActions,
84
96
  bordered = true
85
97
  }) => {
@@ -92,7 +104,8 @@ var ContentHeader = ({
92
104
  headingLevel,
93
105
  subtitleAs,
94
106
  leftSlot,
95
- rightSlot
107
+ rightSlot,
108
+ rightTitleElement
96
109
  }
97
110
  ),
98
111
  headerActions && /* @__PURE__ */ jsx3(Box2, { children: headerActions })
@@ -112,6 +125,7 @@ var CollapsibleContentHeader = ({
112
125
  subtitleAs,
113
126
  leftSlot,
114
127
  rightSlot,
128
+ rightTitleElement,
115
129
  headerActions,
116
130
  trigger: TriggerWrapper,
117
131
  triggerPosition = "right",
@@ -138,7 +152,8 @@ var CollapsibleContentHeader = ({
138
152
  headingLevel,
139
153
  subtitleAs,
140
154
  leftSlot,
141
- rightSlot
155
+ rightSlot,
156
+ rightTitleElement
142
157
  }
143
158
  ),
144
159
  triggerPosition === "right" && resolvedIcon
@@ -1 +1 @@
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 && <Text.Byline as={subtitleAs}>{subtitle}</Text.Byline>}\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"]}
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 rightTitleElement,\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 rightTitleElement={rightTitleElement}\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 rightTitleElement?: React.ReactNode;\n}\n\nexport const TitleArea = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n rightTitleElement,\n}: TypeTitleAreaProps) => {\n const heading = <Text.Headline as={headingLevel}>{title}</Text.Headline>;\n\n return (\n <Box display=\"flex\" alignItems=\"center\" flex={1} width=\"100%\" minWidth={0}>\n {leftSlot}\n <Box flex={1} minWidth={0}>\n {rightTitleElement ? (\n // Keep the element on the title's own line so it tracks the title\n // text instead of being pushed to the edge of the title area.\n <Box display=\"flex\" alignItems=\"center\" gap={300}>\n {heading}\n {rightTitleElement}\n </Box>\n ) : (\n heading\n )}\n {subtitle && <Text.Byline as={subtitleAs}>{subtitle}</Text.Byline>}\n </Box>\n {rightSlot}\n </Box>\n );\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 rightTitleElement,\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 rightTitleElement={rightTitleElement}\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.d.mts CHANGED
@@ -13,8 +13,14 @@ interface TypeContentHeaderProps {
13
13
  subtitleAs?: "h2" | "h3" | "h4" | "h5" | "p";
14
14
  /** Content rendered before the title */
15
15
  leftSlot?: React.ReactNode;
16
- /** Content rendered after the title */
16
+ /** Content rendered at the far right of the title area */
17
17
  rightSlot?: React.ReactNode;
18
+ /**
19
+ * Element rendered inline immediately after the title text, e.g. a badge or
20
+ * icon. Unlike `rightSlot`, this sits next to the title rather than being
21
+ * pushed to the right edge of the title area.
22
+ */
23
+ rightTitleElement?: React.ReactNode;
18
24
  /** Actions rendered to the right of the header */
19
25
  headerActions?: React.ReactNode;
20
26
  /** Adds a border-bottom divider. Defaults to true */
@@ -31,8 +37,8 @@ interface TypeCollapsibleContentHeaderProps extends TypeContentHeaderProps {
31
37
  triggerIcon?: React.ReactNode;
32
38
  }
33
39
 
34
- declare const ContentHeader: ({ title, subtitle, headingLevel, subtitleAs, leftSlot, rightSlot, headerActions, bordered, }: TypeContentHeaderProps) => react_jsx_runtime.JSX.Element;
40
+ declare const ContentHeader: ({ title, subtitle, headingLevel, subtitleAs, leftSlot, rightSlot, rightTitleElement, headerActions, bordered, }: TypeContentHeaderProps) => react_jsx_runtime.JSX.Element;
35
41
 
36
- declare const CollapsibleContentHeader: ({ title, subtitle, headingLevel, subtitleAs, leftSlot, rightSlot, headerActions, trigger: TriggerWrapper, triggerPosition, triggerIcon, bordered, }: TypeCollapsibleContentHeaderProps) => react_jsx_runtime.JSX.Element;
42
+ declare const CollapsibleContentHeader: ({ title, subtitle, headingLevel, subtitleAs, leftSlot, rightSlot, rightTitleElement, headerActions, trigger: TriggerWrapper, triggerPosition, triggerIcon, bordered, }: TypeCollapsibleContentHeaderProps) => react_jsx_runtime.JSX.Element;
37
43
 
38
44
  export { CollapsibleContentHeader, ContentHeader, type TypeCollapsibleContentHeaderProps, type TypeContentHeaderProps, type TypeHeadingLevel, ContentHeader as default };
package/dist/index.d.ts CHANGED
@@ -13,8 +13,14 @@ interface TypeContentHeaderProps {
13
13
  subtitleAs?: "h2" | "h3" | "h4" | "h5" | "p";
14
14
  /** Content rendered before the title */
15
15
  leftSlot?: React.ReactNode;
16
- /** Content rendered after the title */
16
+ /** Content rendered at the far right of the title area */
17
17
  rightSlot?: React.ReactNode;
18
+ /**
19
+ * Element rendered inline immediately after the title text, e.g. a badge or
20
+ * icon. Unlike `rightSlot`, this sits next to the title rather than being
21
+ * pushed to the right edge of the title area.
22
+ */
23
+ rightTitleElement?: React.ReactNode;
18
24
  /** Actions rendered to the right of the header */
19
25
  headerActions?: React.ReactNode;
20
26
  /** Adds a border-bottom divider. Defaults to true */
@@ -31,8 +37,8 @@ interface TypeCollapsibleContentHeaderProps extends TypeContentHeaderProps {
31
37
  triggerIcon?: React.ReactNode;
32
38
  }
33
39
 
34
- declare const ContentHeader: ({ title, subtitle, headingLevel, subtitleAs, leftSlot, rightSlot, headerActions, bordered, }: TypeContentHeaderProps) => react_jsx_runtime.JSX.Element;
40
+ declare const ContentHeader: ({ title, subtitle, headingLevel, subtitleAs, leftSlot, rightSlot, rightTitleElement, headerActions, bordered, }: TypeContentHeaderProps) => react_jsx_runtime.JSX.Element;
35
41
 
36
- declare const CollapsibleContentHeader: ({ title, subtitle, headingLevel, subtitleAs, leftSlot, rightSlot, headerActions, trigger: TriggerWrapper, triggerPosition, triggerIcon, bordered, }: TypeCollapsibleContentHeaderProps) => react_jsx_runtime.JSX.Element;
42
+ declare const CollapsibleContentHeader: ({ title, subtitle, headingLevel, subtitleAs, leftSlot, rightSlot, rightTitleElement, headerActions, trigger: TriggerWrapper, triggerPosition, triggerIcon, bordered, }: TypeCollapsibleContentHeaderProps) => react_jsx_runtime.JSX.Element;
37
43
 
38
44
  export { CollapsibleContentHeader, ContentHeader, type TypeCollapsibleContentHeaderProps, type TypeContentHeaderProps, type TypeHeadingLevel, ContentHeader as default };
package/dist/index.js CHANGED
@@ -99,15 +99,26 @@ var TitleArea = ({
99
99
  headingLevel = "h4",
100
100
  subtitleAs,
101
101
  leftSlot,
102
- rightSlot
103
- }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_seeds_react_box.Box, { display: "flex", alignItems: "center", flex: 1, width: "100%", minWidth: 0, children: [
104
- leftSlot,
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, children: subtitle })
108
- ] }),
109
- rightSlot
110
- ] });
102
+ rightSlot,
103
+ rightTitleElement
104
+ }) => {
105
+ const heading = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_text.Text.Headline, { as: headingLevel, children: title });
106
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_seeds_react_box.Box, { display: "flex", alignItems: "center", flex: 1, width: "100%", minWidth: 0, children: [
107
+ leftSlot,
108
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_seeds_react_box.Box, { flex: 1, minWidth: 0, children: [
109
+ rightTitleElement ? (
110
+ // Keep the element on the title's own line so it tracks the title
111
+ // text instead of being pushed to the edge of the title area.
112
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_seeds_react_box.Box, { display: "flex", alignItems: "center", gap: 300, children: [
113
+ heading,
114
+ rightTitleElement
115
+ ] })
116
+ ) : heading,
117
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_text.Text.Byline, { as: subtitleAs, children: subtitle })
118
+ ] }),
119
+ rightSlot
120
+ ] });
121
+ };
111
122
 
112
123
  // src/ContentHeader.tsx
113
124
  var import_jsx_runtime3 = require("react/jsx-runtime");
@@ -118,6 +129,7 @@ var ContentHeader = ({
118
129
  subtitleAs,
119
130
  leftSlot,
120
131
  rightSlot,
132
+ rightTitleElement,
121
133
  headerActions,
122
134
  bordered = true
123
135
  }) => {
@@ -130,7 +142,8 @@ var ContentHeader = ({
130
142
  headingLevel,
131
143
  subtitleAs,
132
144
  leftSlot,
133
- rightSlot
145
+ rightSlot,
146
+ rightTitleElement
134
147
  }
135
148
  ),
136
149
  headerActions && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_box2.Box, { children: headerActions })
@@ -150,6 +163,7 @@ var CollapsibleContentHeader = ({
150
163
  subtitleAs,
151
164
  leftSlot,
152
165
  rightSlot,
166
+ rightTitleElement,
153
167
  headerActions,
154
168
  trigger: TriggerWrapper,
155
169
  triggerPosition = "right",
@@ -176,7 +190,8 @@ var CollapsibleContentHeader = ({
176
190
  headingLevel,
177
191
  subtitleAs,
178
192
  leftSlot,
179
- rightSlot
193
+ rightSlot,
194
+ rightTitleElement
180
195
  }
181
196
  ),
182
197
  triggerPosition === "right" && resolvedIcon
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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 && <Text.Byline as={subtitleAs}>{subtitle}</Text.Byline>}\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"]}
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 rightTitleElement,\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 rightTitleElement={rightTitleElement}\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 rightTitleElement?: React.ReactNode;\n}\n\nexport const TitleArea = ({\n title,\n subtitle,\n headingLevel = \"h4\",\n subtitleAs,\n leftSlot,\n rightSlot,\n rightTitleElement,\n}: TypeTitleAreaProps) => {\n const heading = <Text.Headline as={headingLevel}>{title}</Text.Headline>;\n\n return (\n <Box display=\"flex\" alignItems=\"center\" flex={1} width=\"100%\" minWidth={0}>\n {leftSlot}\n <Box flex={1} minWidth={0}>\n {rightTitleElement ? (\n // Keep the element on the title's own line so it tracks the title\n // text instead of being pushed to the edge of the title area.\n <Box display=\"flex\" alignItems=\"center\" gap={300}>\n {heading}\n {rightTitleElement}\n </Box>\n ) : (\n heading\n )}\n {subtitle && <Text.Byline as={subtitleAs}>{subtitle}</Text.Byline>}\n </Box>\n {rightSlot}\n </Box>\n );\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 rightTitleElement,\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 rightTitleElement={rightTitleElement}\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.31",
3
+ "version": "0.3.1",
4
4
  "description": "Seeds React ContentHeader",
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-box": "^1.1.31",
22
- "@sproutsocial/seeds-react-icon": "^2.5.1",
23
- "@sproutsocial/seeds-react-mixins": "^4.3.15",
21
+ "@sproutsocial/seeds-react-box": "^1.1.32",
22
+ "@sproutsocial/seeds-react-icon": "^2.5.2",
23
+ "@sproutsocial/seeds-react-mixins": "^4.3.16",
24
24
  "@sproutsocial/seeds-react-text": "^1.5.5"
25
25
  },
26
26
  "devDependencies": {
@@ -12,6 +12,7 @@ export const CollapsibleContentHeader = ({
12
12
  subtitleAs,
13
13
  leftSlot,
14
14
  rightSlot,
15
+ rightTitleElement,
15
16
  headerActions,
16
17
  trigger: TriggerWrapper,
17
18
  triggerPosition = "right",
@@ -40,6 +41,7 @@ export const CollapsibleContentHeader = ({
40
41
  subtitleAs={subtitleAs}
41
42
  leftSlot={leftSlot}
42
43
  rightSlot={rightSlot}
44
+ rightTitleElement={rightTitleElement}
43
45
  />
44
46
  {triggerPosition === "right" && resolvedIcon}
45
47
  </TriggerButton>
@@ -11,6 +11,7 @@ export const ContentHeader = ({
11
11
  subtitleAs,
12
12
  leftSlot,
13
13
  rightSlot,
14
+ rightTitleElement,
14
15
  headerActions,
15
16
  bordered = true,
16
17
  }: TypeContentHeaderProps) => {
@@ -23,6 +24,7 @@ export const ContentHeader = ({
23
24
  subtitleAs={subtitleAs}
24
25
  leftSlot={leftSlot}
25
26
  rightSlot={rightSlot}
27
+ rightTitleElement={rightTitleElement}
26
28
  />
27
29
  {headerActions && <Box>{headerActions}</Box>}
28
30
  </HeaderContainer>
@@ -13,8 +13,14 @@ export interface TypeContentHeaderProps {
13
13
  subtitleAs?: "h2" | "h3" | "h4" | "h5" | "p";
14
14
  /** Content rendered before the title */
15
15
  leftSlot?: React.ReactNode;
16
- /** Content rendered after the title */
16
+ /** Content rendered at the far right of the title area */
17
17
  rightSlot?: React.ReactNode;
18
+ /**
19
+ * Element rendered inline immediately after the title text, e.g. a badge or
20
+ * icon. Unlike `rightSlot`, this sits next to the title rather than being
21
+ * pushed to the right edge of the title area.
22
+ */
23
+ rightTitleElement?: React.ReactNode;
18
24
  /** Actions rendered to the right of the header */
19
25
  headerActions?: React.ReactNode;
20
26
  /** Adds a border-bottom divider. Defaults to true */
package/src/TitleArea.tsx CHANGED
@@ -10,6 +10,7 @@ interface TypeTitleAreaProps {
10
10
  subtitleAs?: "h2" | "h3" | "h4" | "h5" | "p";
11
11
  leftSlot?: React.ReactNode;
12
12
  rightSlot?: React.ReactNode;
13
+ rightTitleElement?: React.ReactNode;
13
14
  }
14
15
 
15
16
  export const TitleArea = ({
@@ -19,13 +20,27 @@ export const TitleArea = ({
19
20
  subtitleAs,
20
21
  leftSlot,
21
22
  rightSlot,
22
- }: TypeTitleAreaProps) => (
23
- <Box display="flex" alignItems="center" flex={1} width="100%" minWidth={0}>
24
- {leftSlot}
25
- <Box flex={1}>
26
- <Text.Headline as={headingLevel}>{title}</Text.Headline>
27
- {subtitle && <Text.Byline as={subtitleAs}>{subtitle}</Text.Byline>}
23
+ rightTitleElement,
24
+ }: TypeTitleAreaProps) => {
25
+ const heading = <Text.Headline as={headingLevel}>{title}</Text.Headline>;
26
+
27
+ return (
28
+ <Box display="flex" alignItems="center" flex={1} width="100%" minWidth={0}>
29
+ {leftSlot}
30
+ <Box flex={1} minWidth={0}>
31
+ {rightTitleElement ? (
32
+ // Keep the element on the title's own line so it tracks the title
33
+ // text instead of being pushed to the edge of the title area.
34
+ <Box display="flex" alignItems="center" gap={300}>
35
+ {heading}
36
+ {rightTitleElement}
37
+ </Box>
38
+ ) : (
39
+ heading
40
+ )}
41
+ {subtitle && <Text.Byline as={subtitleAs}>{subtitle}</Text.Byline>}
42
+ </Box>
43
+ {rightSlot}
28
44
  </Box>
29
- {rightSlot}
30
- </Box>
31
- );
45
+ );
46
+ };
@@ -60,6 +60,40 @@ describe("ContentHeader", () => {
60
60
  expect(screen.getByText("Left")).toBeInTheDocument();
61
61
  expect(screen.getByText("Right")).toBeInTheDocument();
62
62
  });
63
+
64
+ test("renders rightTitleElement inline with the title", () => {
65
+ render(
66
+ <ContentHeader title="Title" rightTitleElement={<span>Beta</span>} />
67
+ );
68
+
69
+ // Sharing a parent with the heading is what keeps the element next to the
70
+ // title text instead of at the edge of the title area.
71
+ expect(screen.getByText("Beta").parentElement).toBe(
72
+ screen.getByText("Title").parentElement
73
+ );
74
+ });
75
+
76
+ test("does not render rightSlot inline with the title", () => {
77
+ render(<ContentHeader title="Title" rightSlot={<span>Right</span>} />);
78
+
79
+ expect(screen.getByText("Right").parentElement).not.toBe(
80
+ screen.getByText("Title").parentElement
81
+ );
82
+ });
83
+
84
+ test("keeps the subtitle below the title row when rightTitleElement is set", () => {
85
+ render(
86
+ <ContentHeader
87
+ title="Title"
88
+ subtitle="Subtitle"
89
+ rightTitleElement={<span>Beta</span>}
90
+ />
91
+ );
92
+
93
+ expect(screen.getByText("Beta").parentElement).not.toContainElement(
94
+ screen.getByText("Subtitle")
95
+ );
96
+ });
63
97
  });
64
98
 
65
99
  describe("CollapsibleContentHeader", () => {
@@ -141,6 +175,23 @@ describe("CollapsibleContentHeader", () => {
141
175
  expect(screen.getByText("Right")).toBeInTheDocument();
142
176
  });
143
177
 
178
+ test("renders rightTitleElement inline with the title", () => {
179
+ render(
180
+ <Collapsible isOpen={true} onOpenChange={() => {}}>
181
+ <CollapsibleContentHeader
182
+ title="Title"
183
+ trigger={Collapsible.Trigger}
184
+ rightTitleElement={<span>Beta</span>}
185
+ />
186
+ <Collapsible.Panel>Content</Collapsible.Panel>
187
+ </Collapsible>
188
+ );
189
+
190
+ expect(screen.getByText("Beta").parentElement).toBe(
191
+ screen.getByText("Title").parentElement
192
+ );
193
+ });
194
+
144
195
  test("renders custom triggerIcon", () => {
145
196
  render(
146
197
  <Collapsible isOpen={true} onOpenChange={() => {}}>