@sproutsocial/racine 7.6.0 → 7.7.0-beta-collapsible.0

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/CHANGELOG.md CHANGED
@@ -1,11 +1,5 @@
1
1
  # Change Log
2
2
 
3
- ## 7.6.0
4
-
5
- ### Minor Changes
6
-
7
- - b69f92a: fix(token) hover styling for invalid tokens
8
-
9
3
  ## 7.5.0
10
4
 
11
5
  ### Minor Changes
@@ -32,15 +32,15 @@ export type TypeContainerProps = $ReadOnly<{|
32
32
 
33
33
  type TypeBoxContainer = StyledComponent<TypeContainerProps, TypeTheme, *>;
34
34
  const Container: TypeBoxContainer = styled.div`
35
- box-sizing: border-box;
36
- font-family: ${({ theme }) => theme.fontFamily};
35
+ box-sizing: border-box;
36
+ font-family: ${({ theme }) => theme.fontFamily};
37
37
 
38
- ${COMMON}
39
- ${BORDER}
38
+ ${COMMON}
39
+ ${BORDER}
40
40
  ${LAYOUT}
41
41
  ${POSITION}
42
42
  ${FLEXBOX}
43
43
  ${GRID}
44
- `;
44
+ `;
45
45
 
46
46
  export default Container;
@@ -25,13 +25,13 @@ const Container: StyledComponent<any, TypeTheme, *> = styled.div`
25
25
  ${(props) =>
26
26
  props.inline &&
27
27
  css`
28
- display: flex;
29
- justify-content: center;
28
+ display: flex;
29
+ justify-content: center;
30
30
 
31
- ${Label} + ${Label} {
32
- margin-left: ${(props) => props.theme.space[450]};
33
- }
34
- `}
31
+ ${Label} + ${Label} {
32
+ margin-left: ${(props) => props.theme.space[450]};
33
+ }
34
+ `}
35
35
 
36
36
  ${COMMON}
37
37
  ${LAYOUT}
@@ -11,6 +11,8 @@ type TypeCollapsibleContext = $Shape<{
11
11
  isOpen: boolean,
12
12
  id: string,
13
13
  offset: number,
14
+ openHeight: number,
15
+ collapsedHeight: number,
14
16
  }>;
15
17
 
16
18
  const CollapsibleContext = React.createContext<TypeCollapsibleContext>({});
@@ -20,13 +22,23 @@ type TypeProps = {
20
22
  children: React.Node,
21
23
  /** If the children of the collapsible panel have a top or bottom margin, it will throw off the calculations for the height of the content. The total amount of vertical margin (in pixels) can be supplied to this prop to correct this. */
22
24
  offset?: number,
25
+ collapsedHeight?: number,
26
+ openHeight?: number,
23
27
  };
24
28
 
25
- const Collapsible = ({ children, isOpen = false, offset = 0 }: TypeProps) => {
29
+ const Collapsible = ({
30
+ children,
31
+ isOpen = false,
32
+ offset = 0,
33
+ collapsedHeight = 0,
34
+ openHeight,
35
+ }: TypeProps) => {
26
36
  const [id] = useState(`Racine-collapsible-${idCounter++}`);
27
37
 
28
38
  return (
29
- <CollapsibleContext.Provider value={{ isOpen, id, offset }}>
39
+ <CollapsibleContext.Provider
40
+ value={{ isOpen, id, offset, collapsedHeight, openHeight }}
41
+ >
30
42
  {children}
31
43
  </CollapsibleContext.Provider>
32
44
  );
@@ -47,7 +59,9 @@ const Trigger = ({ children, ...rest }) => {
47
59
  };
48
60
 
49
61
  const Panel = ({ children, ...rest }) => {
50
- const { isOpen, id, offset } = useContext(CollapsibleContext);
62
+ const { isOpen, id, offset, collapsedHeight, openHeight } = useContext(
63
+ CollapsibleContext
64
+ );
51
65
  const ref = useRef();
52
66
  const measurement = useMeasure(ref);
53
67
  const [isHidden, setIsHidden] = useState(undefined);
@@ -57,7 +71,9 @@ const Panel = ({ children, ...rest }) => {
57
71
  // This prevents an initial expansion animation if a component starts out open
58
72
  // There is no animation because css is not changing the maxHeight property after mount
59
73
  const maxHeight =
60
- isHidden === undefined ? undefined : measurement.height + offset;
74
+ typeof openHeight !== "undefined"
75
+ ? openHeight
76
+ : measurement.height + offset;
61
77
 
62
78
  /* We use the "hidden" attribute to remove the contents of the panel from the tab order of the page, but it fucks with the animation. This logic sets a slight timeout on setting the prop so that the animation has time to complete before the attribute is set. */
63
79
  useEffect(() => {
@@ -76,14 +92,16 @@ const Panel = ({ children, ...rest }) => {
76
92
 
77
93
  return (
78
94
  <CollapsingBox
79
- maxHeight={isOpen ? maxHeight : "0"}
95
+ scrollable={isOpen}
96
+ maxHeight={isOpen ? maxHeight : collapsedHeight}
97
+ minHeight={collapsedHeight}
80
98
  data-qa-collapsible={""}
81
99
  data-qa-collapsible-isopen={isOpen === true}
82
100
  {...rest}
83
101
  >
84
102
  <Box
85
103
  width="100%"
86
- hidden={isHidden}
104
+ hidden={isHidden && collapsedHeight === 0}
87
105
  aria-hidden={!isOpen}
88
106
  id={id}
89
107
  ref={ref}
@@ -83,3 +83,80 @@ export const withTallContent = () => (
83
83
  withTallContent.story = {
84
84
  name: "With tall content",
85
85
  };
86
+
87
+ const StatefulCollapseWithMinHeight = ({
88
+ children,
89
+ offset = 0,
90
+ collapsedHeight = 0,
91
+ openHeight,
92
+ }) => {
93
+ const [open, setOpen] = useState(false);
94
+ const toggle = () => setOpen(!open);
95
+
96
+ return (
97
+ <Collapsible
98
+ id="test-id-1"
99
+ isOpen={open}
100
+ offset={offset}
101
+ openHeight={openHeight}
102
+ collapsedHeight={collapsedHeight}
103
+ >
104
+ <Collapsible.Panel>{children}</Collapsible.Panel>
105
+ <Collapsible.Trigger>
106
+ <Button onClick={toggle}>{open ? "Show Less" : "Show More"}</Button>
107
+ </Collapsible.Trigger>
108
+ </Collapsible>
109
+ );
110
+ };
111
+
112
+ export const withCollapsedHeight = () => {
113
+ return (
114
+ <StatefulCollapseWithMinHeight collapsedHeight={100} openHeight={300}>
115
+ <Box width="500px" p={400}>
116
+ Threepio! Come in, Threepio! Threepio! Get to the top! I can’t Where
117
+ could he be? Threepio! Threepio, will you come in? They aren’t here!
118
+ Something must have happened to them. See if they’ve been captured.
119
+ Hurry! One thing’s for sure. We’re all going to be a lot thinner! Get on
120
+ top of it! I’m trying! Thank goodness, they haven’t found them! Where
121
+ could they be? Use the comlink? Oh, my! I forgot I turned it off! Are
122
+ you there, sir? Threepio! We’ve had some problems… Will you shut up and
123
+ listen to me? Shut down all garbage mashers on the detention level, will
124
+ you? Do you copy? Shut down all the garbage mashers on the detention
125
+ level. Shut down all the garbage mashers on the detention level. No.
126
+ Shut them all down! Hurry! Listen to them! They’re dying, Artoo! Curse
127
+ my metal body! I wasn’t fast enough. It’s all my fault! My poor master!
128
+ Threepio, we’re all right! We’re all right. You did great. Threepio!
129
+ Come in, Threepio! Threepio! Get to the top! I can’t Where could he be?
130
+ Threepio! Threepio, will you come in? They aren’t here! Something must
131
+ have happened to them. See if they’ve been captured. Hurry! One thing’s
132
+ for sure. We’re all going to be a lot thinner! Get on top of it! I’m
133
+ trying! Thank goodness, they haven’t found them! Where could they be?
134
+ Use the comlink? Oh, my! I forgot I turned it off! Are you there, sir?
135
+ Threepio! We’ve had some problems… Will you shut up and listen to me?
136
+ Shut down all garbage mashers on the detention level, will you? Do you
137
+ copy? Shut down all the garbage mashers on the detention level. Shut
138
+ down all the garbage mashers on the detention level. No. Shut them all
139
+ down! Hurry! Listen to them! They’re dying, Artoo! Curse my metal body!
140
+ I wasn’t fast enough. It’s all my fault! My poor master! Threepio, we’re
141
+ all right! We’re all right. You did great. Threepio! Come in, Threepio!
142
+ Threepio! Get to the top! I can’t Where could he be? Threepio! Threepio,
143
+ will you come in? They aren’t here! Something must have happened to
144
+ them. See if they’ve been captured. Hurry! One thing’s for sure. We’re
145
+ all going to be a lot thinner! Get on top of it! I’m trying! Thank
146
+ goodness, they haven’t found them! Where could they be? Use the comlink?
147
+ Oh, my! I forgot I turned it off! Are you there, sir? Threepio! We’ve
148
+ had some problems… Will you shut up and listen to me? Shut down all
149
+ garbage mashers on the detention level, will you? Do you copy? Shut down
150
+ all the garbage mashers on the detention level. Shut down all the
151
+ garbage mashers on the detention level. No. Shut them all down! Hurry!
152
+ Listen to them! They’re dying, Artoo! Curse my metal body! I wasn’t fast
153
+ enough. It’s all my fault! My poor master! Threepio, we’re all right!
154
+ We’re all right. You did great.
155
+ </Box>
156
+ </StatefulCollapseWithMinHeight>
157
+ );
158
+ };
159
+
160
+ withCollapsedHeight.story = {
161
+ name: "With collapsedHeight",
162
+ };
@@ -4,9 +4,35 @@ import Box from "../Box";
4
4
 
5
5
  import type { TypeTheme } from "../types/theme.flow";
6
6
 
7
- export const CollapsingBox = styled<typeof Box, TypeTheme>(Box)`
7
+ export const CollapsingBox = styled<typeof Box, TypeTheme, *>(Box)`
8
8
  transition: max-height ${(p) => p.theme.duration.medium}
9
9
  ${(p) => p.theme.easing.ease_inout};
10
10
  will-change: max-height;
11
- overflow: hidden;
11
+ position: relative;
12
+ overflow: auto;
13
+ background: /* Shadow covers */ linear-gradient(
14
+ ${(p) => p.theme.colors.neutral[100]} 30%,
15
+ rgba(255, 255, 255, 0)
16
+ ),
17
+ linear-gradient(
18
+ rgba(255, 255, 255, 0),
19
+ ${(p) => p.theme.colors.neutral[100]} 70%
20
+ )
21
+ 0 100%,
22
+ /* Shadows */
23
+ radial-gradient(
24
+ farthest-side at 50% 0,
25
+ rgb(39 51 51 / 5%),
26
+ rgba(0, 0, 0, 0)
27
+ ),
28
+ radial-gradient(
29
+ farthest-side at 50% 100%,
30
+ rgb(39 51 51 / 5%),
31
+ rgba(0, 0, 0, 0)
32
+ )
33
+ 0 100%;
34
+ background-repeat: no-repeat;
35
+ background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
36
+ background-attachment: local, local, scroll, scroll;
37
+ ${({ scrollable }) => (scrollable ? `overflow: auto` : `overflow: hidden`)};
12
38
  `;
@@ -57,8 +57,6 @@ const Container: StyledComponent<any, TypeTheme, *> = styled.button`
57
57
 
58
58
  &:hover {
59
59
  color: ${(props) => props.theme.colors.text.inverse};
60
- border-color: ${(props) => props.theme.colors.red[900]};
61
- background: ${(props) => props.theme.colors.red[900]};
62
60
  }
63
61
  `}
64
62
 
@@ -29,7 +29,10 @@ var Collapsible = function Collapsible(_ref) {
29
29
  _ref$isOpen = _ref.isOpen,
30
30
  isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen,
31
31
  _ref$offset = _ref.offset,
32
- offset = _ref$offset === void 0 ? 0 : _ref$offset;
32
+ offset = _ref$offset === void 0 ? 0 : _ref$offset,
33
+ _ref$collapsedHeight = _ref.collapsedHeight,
34
+ collapsedHeight = _ref$collapsedHeight === void 0 ? 0 : _ref$collapsedHeight,
35
+ openHeight = _ref.openHeight;
33
36
 
34
37
  var _useState = (0, React.useState)("Racine-collapsible-" + idCounter++),
35
38
  id = _useState[0];
@@ -38,7 +41,9 @@ var Collapsible = function Collapsible(_ref) {
38
41
  value: {
39
42
  isOpen: isOpen,
40
43
  id: id,
41
- offset: offset
44
+ offset: offset,
45
+ collapsedHeight: collapsedHeight,
46
+ openHeight: openHeight
42
47
  }
43
48
  }, children);
44
49
  };
@@ -64,7 +69,9 @@ var Panel = function Panel(_ref3) {
64
69
  var _useContext2 = (0, React.useContext)(CollapsibleContext),
65
70
  isOpen = _useContext2.isOpen,
66
71
  id = _useContext2.id,
67
- offset = _useContext2.offset;
72
+ offset = _useContext2.offset,
73
+ collapsedHeight = _useContext2.collapsedHeight,
74
+ openHeight = _useContext2.openHeight;
68
75
 
69
76
  var ref = (0, React.useRef)();
70
77
  var measurement = (0, _useMeasure.default)(ref);
@@ -77,7 +84,7 @@ var Panel = function Panel(_ref3) {
77
84
  // There is no animation because css is not changing the maxHeight property after mount
78
85
 
79
86
 
80
- var maxHeight = isHidden === undefined ? undefined : measurement.height + offset;
87
+ var maxHeight = typeof openHeight !== "undefined" ? openHeight : measurement.height + offset;
81
88
  /* We use the "hidden" attribute to remove the contents of the panel from the tab order of the page, but it fucks with the animation. This logic sets a slight timeout on setting the prop so that the animation has time to complete before the attribute is set. */
82
89
 
83
90
  (0, React.useEffect)(function () {
@@ -103,12 +110,14 @@ var Panel = function Panel(_ref3) {
103
110
  }
104
111
  }, [isOpen]);
105
112
  return /*#__PURE__*/React.createElement(_styles.CollapsingBox, _extends({
106
- maxHeight: isOpen ? maxHeight : "0",
113
+ scrollable: isOpen,
114
+ maxHeight: isOpen ? maxHeight : collapsedHeight,
115
+ minHeight: collapsedHeight,
107
116
  "data-qa-collapsible": "",
108
117
  "data-qa-collapsible-isopen": isOpen === true
109
118
  }, rest), /*#__PURE__*/React.createElement(_Box.default, {
110
119
  width: "100%",
111
- hidden: isHidden,
120
+ hidden: isHidden && collapsedHeight === 0,
112
121
  "aria-hidden": !isOpen,
113
122
  id: id,
114
123
  ref: ref
@@ -12,9 +12,16 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
12
12
  var CollapsingBox = (0, _styledComponents.default)(_Box.default).withConfig({
13
13
  displayName: "styles__CollapsingBox",
14
14
  componentId: "sc-1xvfbl7-0"
15
- })(["transition:max-height ", " ", ";will-change:max-height;overflow:hidden;"], function (p) {
15
+ })(["transition:max-height ", " ", ";will-change:max-height;position:relative;overflow:auto;background:linear-gradient( ", " 30%,rgba(255,255,255,0) ),linear-gradient( rgba(255,255,255,0),", " 70% ) 0 100%,radial-gradient( farthest-side at 50% 0,rgb(39 51 51 / 5%),rgba(0,0,0,0) ),radial-gradient( farthest-side at 50% 100%,rgb(39 51 51 / 5%),rgba(0,0,0,0) ) 0 100%;background-repeat:no-repeat;background-size:100% 40px,100% 40px,100% 14px,100% 14px;background-attachment:local,local,scroll,scroll;", ";"], function (p) {
16
16
  return p.theme.duration.medium;
17
17
  }, function (p) {
18
18
  return p.theme.easing.ease_inout;
19
+ }, function (p) {
20
+ return p.theme.colors.neutral[100];
21
+ }, function (p) {
22
+ return p.theme.colors.neutral[100];
23
+ }, function (_ref) {
24
+ var scrollable = _ref.scrollable;
25
+ return scrollable ? "overflow: auto" : "overflow: hidden";
19
26
  });
20
27
  exports.CollapsingBox = CollapsingBox;
@@ -49,7 +49,7 @@ var Container = _styledComponents.default.button.withConfig({
49
49
  }, function (props) {
50
50
  return props.disabled && (0, _styledComponents.css)(["opacity:0.4;cursor:not-allowed;"]);
51
51
  }, function (props) {
52
- return !props.valid && (0, _styledComponents.css)(["color:", ";border-color:", ";background:", ";&:hover{color:", ";border-color:", ";background:", ";}"], function (props) {
52
+ return !props.valid && (0, _styledComponents.css)(["color:", ";border-color:", ";background:", ";&:hover{color:", ";}"], function (props) {
53
53
  return props.theme.colors.text.inverse;
54
54
  }, function (props) {
55
55
  return props.theme.colors.error.color;
@@ -57,10 +57,6 @@ var Container = _styledComponents.default.button.withConfig({
57
57
  return props.theme.colors.error.color;
58
58
  }, function (props) {
59
59
  return props.theme.colors.text.inverse;
60
- }, function (props) {
61
- return props.theme.colors.red[900];
62
- }, function (props) {
63
- return props.theme.colors.red[900];
64
60
  });
65
61
  }, _systemProps.COMMON);
66
62
 
@@ -15,7 +15,10 @@ var Collapsible = function Collapsible(_ref) {
15
15
  _ref$isOpen = _ref.isOpen,
16
16
  isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen,
17
17
  _ref$offset = _ref.offset,
18
- offset = _ref$offset === void 0 ? 0 : _ref$offset;
18
+ offset = _ref$offset === void 0 ? 0 : _ref$offset,
19
+ _ref$collapsedHeight = _ref.collapsedHeight,
20
+ collapsedHeight = _ref$collapsedHeight === void 0 ? 0 : _ref$collapsedHeight,
21
+ openHeight = _ref.openHeight;
19
22
 
20
23
  var _useState = useState("Racine-collapsible-" + idCounter++),
21
24
  id = _useState[0];
@@ -24,7 +27,9 @@ var Collapsible = function Collapsible(_ref) {
24
27
  value: {
25
28
  isOpen: isOpen,
26
29
  id: id,
27
- offset: offset
30
+ offset: offset,
31
+ collapsedHeight: collapsedHeight,
32
+ openHeight: openHeight
28
33
  }
29
34
  }, children);
30
35
  };
@@ -50,7 +55,9 @@ var Panel = function Panel(_ref3) {
50
55
  var _useContext2 = useContext(CollapsibleContext),
51
56
  isOpen = _useContext2.isOpen,
52
57
  id = _useContext2.id,
53
- offset = _useContext2.offset;
58
+ offset = _useContext2.offset,
59
+ collapsedHeight = _useContext2.collapsedHeight,
60
+ openHeight = _useContext2.openHeight;
54
61
 
55
62
  var ref = useRef();
56
63
  var measurement = useMeasure(ref);
@@ -63,7 +70,7 @@ var Panel = function Panel(_ref3) {
63
70
  // There is no animation because css is not changing the maxHeight property after mount
64
71
 
65
72
 
66
- var maxHeight = isHidden === undefined ? undefined : measurement.height + offset;
73
+ var maxHeight = typeof openHeight !== "undefined" ? openHeight : measurement.height + offset;
67
74
  /* We use the "hidden" attribute to remove the contents of the panel from the tab order of the page, but it fucks with the animation. This logic sets a slight timeout on setting the prop so that the animation has time to complete before the attribute is set. */
68
75
 
69
76
  useEffect(function () {
@@ -89,12 +96,14 @@ var Panel = function Panel(_ref3) {
89
96
  }
90
97
  }, [isOpen]);
91
98
  return /*#__PURE__*/React.createElement(CollapsingBox, _extends({
92
- maxHeight: isOpen ? maxHeight : "0",
99
+ scrollable: isOpen,
100
+ maxHeight: isOpen ? maxHeight : collapsedHeight,
101
+ minHeight: collapsedHeight,
93
102
  "data-qa-collapsible": "",
94
103
  "data-qa-collapsible-isopen": isOpen === true
95
104
  }, rest), /*#__PURE__*/React.createElement(Box, {
96
105
  width: "100%",
97
- hidden: isHidden,
106
+ hidden: isHidden && collapsedHeight === 0,
98
107
  "aria-hidden": !isOpen,
99
108
  id: id,
100
109
  ref: ref
@@ -3,8 +3,15 @@ import Box from "../Box";
3
3
  export var CollapsingBox = styled(Box).withConfig({
4
4
  displayName: "styles__CollapsingBox",
5
5
  componentId: "sc-1xvfbl7-0"
6
- })(["transition:max-height ", " ", ";will-change:max-height;overflow:hidden;"], function (p) {
6
+ })(["transition:max-height ", " ", ";will-change:max-height;position:relative;overflow:auto;background:linear-gradient( ", " 30%,rgba(255,255,255,0) ),linear-gradient( rgba(255,255,255,0),", " 70% ) 0 100%,radial-gradient( farthest-side at 50% 0,rgb(39 51 51 / 5%),rgba(0,0,0,0) ),radial-gradient( farthest-side at 50% 100%,rgb(39 51 51 / 5%),rgba(0,0,0,0) ) 0 100%;background-repeat:no-repeat;background-size:100% 40px,100% 40px,100% 14px,100% 14px;background-attachment:local,local,scroll,scroll;", ";"], function (p) {
7
7
  return p.theme.duration.medium;
8
8
  }, function (p) {
9
9
  return p.theme.easing.ease_inout;
10
+ }, function (p) {
11
+ return p.theme.colors.neutral[100];
12
+ }, function (p) {
13
+ return p.theme.colors.neutral[100];
14
+ }, function (_ref) {
15
+ var scrollable = _ref.scrollable;
16
+ return scrollable ? "overflow: auto" : "overflow: hidden";
10
17
  });
@@ -37,7 +37,7 @@ var Container = styled.button.withConfig({
37
37
  }, function (props) {
38
38
  return props.disabled && css(["opacity:0.4;cursor:not-allowed;"]);
39
39
  }, function (props) {
40
- return !props.valid && css(["color:", ";border-color:", ";background:", ";&:hover{color:", ";border-color:", ";background:", ";}"], function (props) {
40
+ return !props.valid && css(["color:", ";border-color:", ";background:", ";&:hover{color:", ";}"], function (props) {
41
41
  return props.theme.colors.text.inverse;
42
42
  }, function (props) {
43
43
  return props.theme.colors.error.color;
@@ -45,10 +45,6 @@ var Container = styled.button.withConfig({
45
45
  return props.theme.colors.error.color;
46
46
  }, function (props) {
47
47
  return props.theme.colors.text.inverse;
48
- }, function (props) {
49
- return props.theme.colors.red[900];
50
- }, function (props) {
51
- return props.theme.colors.red[900];
52
48
  });
53
49
  }, COMMON);
54
50
  export default Container;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/racine",
3
- "version": "7.6.0",
3
+ "version": "7.7.0-beta-collapsible.0",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "__flow__",
@@ -43,7 +43,7 @@
43
43
  "new": "node ./bin/scaffold.js",
44
44
  "playground": "node ./bin/scaffold-playground.js && yarn start",
45
45
  "release": "yarn test && yarn changeset publish",
46
- "storybook": "start-storybook -c .storybook",
46
+ "storybook": "start-storybook -c .storybook -p 9999",
47
47
  "build-storybook": "build-storybook --quiet -c .storybook -o .storybook-dist",
48
48
  "icon-lint": "node bin/icon-lint/cli",
49
49
  "playroom:start": "playroom start",