@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.
- package/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +20 -0
- package/dist/esm/index.js +26 -11
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +26 -11
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/CollapsibleContentHeader.tsx +2 -0
- package/src/ContentHeader.tsx +2 -0
- package/src/ContentHeaderTypes.ts +7 -1
- package/src/TitleArea.tsx +24 -9
- package/src/__tests__/content-header.test.tsx +51 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -8,14 +8,14 @@ $ tsup --dts
|
|
|
8
8
|
[34mCLI[39m Cleaning output folder
|
|
9
9
|
[34mCJS[39m Build start
|
|
10
10
|
[34mESM[39m Build start
|
|
11
|
-
[32mCJS[39m [1mdist/index.js [22m[32m6.
|
|
12
|
-
[32mCJS[39m [1mdist/index.js.map [22m[
|
|
13
|
-
[32mCJS[39m ⚡️ Build success in
|
|
14
|
-
[32mESM[39m [1mdist/esm/index.js [22m[32m4.
|
|
15
|
-
[32mESM[39m [1mdist/esm/index.js.map [22m[
|
|
16
|
-
[32mESM[39m ⚡️ Build success in
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m6.92 KB[39m
|
|
12
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m8.42 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 17ms
|
|
14
|
+
[32mESM[39m [1mdist/esm/index.js [22m[32m4.53 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/esm/index.js.map [22m[32m8.37 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 17ms
|
|
17
17
|
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in
|
|
19
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
20
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[
|
|
21
|
-
Done in
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 3231ms
|
|
19
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m2.16 KB[39m
|
|
20
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m2.16 KB[39m
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
/* @__PURE__ */
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
package/dist/esm/index.js.map
CHANGED
|
@@ -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) =>
|
|
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":";AAAA,OAAkB;AAClB,SAAS,OAAAA,YAAW;;;ACIpB,OAAO,WAAW;AAoChB;AAjCF,SAAS,MACJ,QACK;AACR,QAAM,UAAoB,CAAC;AAE3B,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,MAAO;AAEZ,QAAI,OAAO,UAAU,UAAU;AAC7B,cAAQ,KAAK,KAAK;AAAA,IACpB,WAAW,OAAO,UAAU,UAAU;AACpC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,YAAI,OAAO;AACT,kBAAQ,KAAK,GAAG;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ,KAAK,GAAG;AACzB;AAOO,IAAM,kBAAkB,CAAC;AAAA,EAC9B,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE;AAAA,EAAC;AAAA;AAAA,IACC,WAAW;AAAA,MACT;AAAA,MACA,EAAE,iCAAiC,SAAS;AAAA,MAC5C;AAAA,IACF;AAAA,IACC,GAAG;AAAA,IAEH;AAAA;AACH;AAGK,IAAM,gBAAgB,MAAM,WAGjC,CAAC,EAAE,WAAW,UAAU,OAAO,UAAU,GAAG,KAAK,GAAG,QACpD;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA;AAAA,IACA,WAAW,GAAG,gCAAgC,SAAS;AAAA,IACtD,GAAG;AAAA,IAEH;AAAA;AACH,CACD;AAED,cAAc,cAAc;;;ACnE5B,OAAkB;AAClB,SAAS,WAAW;AACpB,SAAS,YAAY;AAsBH,gBAAAC,MASR,YATQ;AATX,IAAM,YAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA0B;AACxB,QAAM,UAAU,gBAAAA,KAAC,KAAK,UAAL,EAAc,IAAI,cAAe,iBAAM;AAExD,SACE,qBAAC,OAAI,SAAQ,QAAO,YAAW,UAAS,MAAM,GAAG,OAAM,QAAO,UAAU,GACrE;AAAA;AAAA,IACD,qBAAC,OAAI,MAAM,GAAG,UAAU,GACrB;AAAA;AAAA;AAAA;AAAA,QAGC,qBAAC,OAAI,SAAQ,QAAO,YAAW,UAAS,KAAK,KAC1C;AAAA;AAAA,UACA;AAAA,WACH;AAAA,UAEA;AAAA,MAED,YAAY,gBAAAA,KAAC,KAAK,QAAL,EAAY,IAAI,YAAa,oBAAS;AAAA,OACtD;AAAA,IACC;AAAA,KACH;AAEJ;;;AF3BI,SACE,OAAAC,MADF,QAAAC,aAAA;AAZG,IAAM,gBAAgB,CAAC;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AACb,MAA8B;AAC5B,SACE,gBAAAA,MAAC,mBAAgB,UACf;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,IACC,iBAAiB,gBAAAA,KAACE,MAAA,EAAK,yBAAc;AAAA,KACxC;AAEJ;AAEA,IAAO,wBAAQ;;;AGjCf,OAAkB;AAClB,SAAS,OAAAC,YAAW;AACpB,SAAS,YAAY;AAoBjB,gBAAAC,MAYI,QAAAC,aAZJ;AAfG,IAAM,2BAA2B,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB;AAAA,EACA,WAAW;AACb,MAAyC;AACvC,QAAM,cACJ,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,eAAY;AAAA;AAAA,EACd;AAGF,QAAM,eAAe,gBAAgB,SAAY,cAAc;AAE/D,SACE,gBAAAC,MAAC,mBAAgB,UACf;AAAA,oBAAAD,KAAC,kBACC,0BAAAC,MAAC,iBAAc,MAAK,UACjB;AAAA,0BAAoB,UAAU,gBAAAD,KAACE,MAAA,EAAI,IAAI,KAAM,wBAAa;AAAA,MAC3D,gBAAAF;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,MACC,oBAAoB,WAAW;AAAA,OAClC,GACF;AAAA,IACC,iBAAiB,gBAAAA,KAACE,MAAA,EAAI,IAAI,KAAM,yBAAc;AAAA,KACjD;AAEJ;AAEA,IAAO,mCAAQ;;;AClDf,IAAO,gBAAQ;","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
|
|
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
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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) =>
|
|
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.
|
|
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.
|
|
22
|
-
"@sproutsocial/seeds-react-icon": "^2.5.
|
|
23
|
-
"@sproutsocial/seeds-react-mixins": "^4.3.
|
|
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>
|
package/src/ContentHeader.tsx
CHANGED
|
@@ -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
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
30
|
-
|
|
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={() => {}}>
|