@sproutsocial/seeds-react-content-header 0.2.10 → 0.2.19
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 +8 -8
- package/CHANGELOG.md +68 -0
- package/dist/esm/index.js +58 -54
- package/dist/esm/index.js.map +1 -1
- package/dist/index.js +63 -59
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/CollapsibleContentHeader.tsx +2 -2
- package/src/ContentHeader.stories.tsx +44 -0
- package/src/ContentHeader.tsx +2 -2
- package/src/ContentHeaderHybrid.tsx +10 -0
- package/src/ContentHeaderTailwind.tsx +68 -0
- package/src/__tests__/tailwind.test.tsx +48 -0
- package/src/content-header.css +59 -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.38 KB[39m
|
|
12
|
+
[32mCJS[39m [1mdist/index.js.map [22m[32m7.69 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 63ms
|
|
14
|
+
[32mESM[39m [1mdist/esm/index.js [22m[32m4.04 KB[39m
|
|
15
|
+
[32mESM[39m [1mdist/esm/index.js.map [22m[32m7.63 KB[39m
|
|
16
|
+
[32mESM[39m ⚡️ Build success in 64ms
|
|
17
17
|
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in
|
|
18
|
+
[32mDTS[39m ⚡️ Build success in 3307ms
|
|
19
19
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m1.84 KB[39m
|
|
20
20
|
[32mDTS[39m [1mdist/index.d.mts [22m[32m1.84 KB[39m
|
|
21
|
-
Done in 4.
|
|
21
|
+
Done in 4.63s.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
1
|
# @sproutsocial/seeds-react-content-header
|
|
2
2
|
|
|
3
|
+
## 0.2.19
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [69c9d02]
|
|
8
|
+
- @sproutsocial/seeds-react-icon@2.4.0
|
|
9
|
+
|
|
10
|
+
## 0.2.18
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 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.
|
|
15
|
+
- Updated dependencies [edc1819]
|
|
16
|
+
- @sproutsocial/seeds-react-text@1.4.3
|
|
17
|
+
|
|
18
|
+
## 0.2.17
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- @sproutsocial/seeds-react-box@1.1.21
|
|
23
|
+
- @sproutsocial/seeds-react-icon@2.3.13
|
|
24
|
+
- @sproutsocial/seeds-react-text@1.4.2
|
|
25
|
+
|
|
26
|
+
## 0.2.16
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- @sproutsocial/seeds-react-box@1.1.20
|
|
31
|
+
- @sproutsocial/seeds-react-icon@2.3.12
|
|
32
|
+
- @sproutsocial/seeds-react-mixins@4.3.7
|
|
33
|
+
|
|
34
|
+
## 0.2.15
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- @sproutsocial/seeds-react-box@1.1.19
|
|
39
|
+
- @sproutsocial/seeds-react-icon@2.3.11
|
|
40
|
+
- @sproutsocial/seeds-react-mixins@4.3.6
|
|
41
|
+
- @sproutsocial/seeds-react-text@1.4.1
|
|
42
|
+
|
|
43
|
+
## 0.2.14
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- @sproutsocial/seeds-react-icon@2.3.10
|
|
48
|
+
|
|
49
|
+
## 0.2.13
|
|
50
|
+
|
|
51
|
+
### Patch Changes
|
|
52
|
+
|
|
53
|
+
- @sproutsocial/seeds-react-box@1.1.18
|
|
54
|
+
- @sproutsocial/seeds-react-icon@2.3.9
|
|
55
|
+
- @sproutsocial/seeds-react-mixins@4.3.5
|
|
56
|
+
|
|
57
|
+
## 0.2.12
|
|
58
|
+
|
|
59
|
+
### Patch Changes
|
|
60
|
+
|
|
61
|
+
- @sproutsocial/seeds-react-box@1.1.17
|
|
62
|
+
- @sproutsocial/seeds-react-icon@2.3.8
|
|
63
|
+
- @sproutsocial/seeds-react-mixins@4.3.4
|
|
64
|
+
|
|
65
|
+
## 0.2.11
|
|
66
|
+
|
|
67
|
+
### Patch Changes
|
|
68
|
+
|
|
69
|
+
- @sproutsocial/seeds-react-icon@2.3.7
|
|
70
|
+
|
|
3
71
|
## 0.2.10
|
|
4
72
|
|
|
5
73
|
### 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/
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
45
|
-
|
|
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__ */
|
|
65
|
-
subtitle && /* @__PURE__ */
|
|
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
|
|
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, {
|
|
83
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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, {
|
|
127
|
-
/* @__PURE__ */
|
|
128
|
-
triggerPosition === "left" && /* @__PURE__ */
|
|
129
|
-
/* @__PURE__ */
|
|
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__ */
|
|
146
|
+
headerActions && /* @__PURE__ */ jsx4(Box3, { ml: 300, children: headerActions })
|
|
143
147
|
] });
|
|
144
148
|
};
|
|
145
149
|
var CollapsibleContentHeader_default = CollapsibleContentHeader;
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ContentHeader.tsx","../../src/
|
|
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
|
|
40
|
+
var import_react3 = require("react");
|
|
41
41
|
var import_seeds_react_box2 = require("@sproutsocial/seeds-react-box");
|
|
42
42
|
|
|
43
|
-
// src/
|
|
44
|
-
var
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
79
|
-
|
|
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
|
-
|
|
83
|
-
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
102
|
-
/* @__PURE__ */ (0,
|
|
103
|
-
subtitle && /* @__PURE__ */ (0,
|
|
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
|
|
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,
|
|
121
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
165
|
-
/* @__PURE__ */ (0,
|
|
166
|
-
triggerPosition === "left" && /* @__PURE__ */ (0,
|
|
167
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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/
|
|
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.
|
|
3
|
+
"version": "0.2.19",
|
|
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.
|
|
22
|
-
"@sproutsocial/seeds-react-icon": "^2.
|
|
23
|
-
"@sproutsocial/seeds-react-mixins": "^4.3.
|
|
24
|
-
"@sproutsocial/seeds-react-text": "^1.4.
|
|
21
|
+
"@sproutsocial/seeds-react-box": "^1.1.21",
|
|
22
|
+
"@sproutsocial/seeds-react-icon": "^2.4.0",
|
|
23
|
+
"@sproutsocial/seeds-react-mixins": "^4.3.7",
|
|
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 "./
|
|
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
|
|
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
|
+
};
|
package/src/ContentHeader.tsx
CHANGED
|
@@ -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 "./
|
|
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
|
|
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(
|
|
21
|
+
container.querySelector(".seeds-content-header")
|
|
22
|
+
).toHaveClass("seeds-content-header-bordered");
|
|
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(
|
|
30
|
+
container.querySelector(".seeds-content-header")
|
|
31
|
+
).not.toHaveClass("seeds-content-header-bordered");
|
|
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
|
+
}
|