react-miui 0.23.6 → 0.23.7-beta.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.
Files changed (163) hide show
  1. package/.storybook/preview.tsx +1 -0
  2. package/CHANGELOG.md +8 -0
  3. package/dist/components/icons/Icon.d.ts +1 -0
  4. package/dist/components/icons/Icon.d.ts.map +1 -1
  5. package/dist/components/layout/header/Header.d.ts +1 -1
  6. package/dist/components/layout/header/Header.d.ts.map +1 -1
  7. package/dist/components/layout/header/Header.js +7 -14
  8. package/dist/components/layout/header/Header.js.map +1 -1
  9. package/dist/components/layout/header/Header.stories.d.ts +11 -0
  10. package/dist/components/layout/header/Header.stories.d.ts.map +1 -0
  11. package/dist/components/layout/header/Header.stories.js +65 -0
  12. package/dist/components/layout/header/Header.stories.js.map +1 -0
  13. package/dist/components/layout/header/Header.styled.d.ts +326 -0
  14. package/dist/components/layout/header/Header.styled.d.ts.map +1 -0
  15. package/dist/components/layout/header/Header.styled.js +98 -0
  16. package/dist/components/layout/header/Header.styled.js.map +1 -0
  17. package/dist/components/layout/header/HeaderIconAction.d.ts +1 -2
  18. package/dist/components/layout/header/HeaderIconAction.d.ts.map +1 -1
  19. package/dist/components/layout/header/HeaderIconAction.js +6 -11
  20. package/dist/components/layout/header/HeaderIconAction.js.map +1 -1
  21. package/dist/components/layout/header/HeaderIconAction.stories.d.ts +9 -0
  22. package/dist/components/layout/header/HeaderIconAction.stories.d.ts.map +1 -0
  23. package/dist/components/layout/header/HeaderIconAction.stories.js +43 -0
  24. package/dist/components/layout/header/HeaderIconAction.stories.js.map +1 -0
  25. package/dist/components/layout/header/HeaderIconAction.styled.d.ts +243 -0
  26. package/dist/components/layout/header/HeaderIconAction.styled.d.ts.map +1 -0
  27. package/dist/components/layout/header/HeaderIconAction.styled.js +35 -0
  28. package/dist/components/layout/header/HeaderIconAction.styled.js.map +1 -0
  29. package/dist/components/layout/header/StickyHeader.d.ts +2 -2
  30. package/dist/components/layout/header/StickyHeader.d.ts.map +1 -1
  31. package/dist/components/layout/header/StickyHeader.js +17 -8
  32. package/dist/components/layout/header/StickyHeader.js.map +1 -1
  33. package/dist/components/layout/header/StickyHeader.stories.d.ts +8 -0
  34. package/dist/components/layout/header/StickyHeader.stories.d.ts.map +1 -0
  35. package/dist/components/layout/header/StickyHeader.stories.js +30 -0
  36. package/dist/components/layout/header/StickyHeader.stories.js.map +1 -0
  37. package/dist/components/layout/header/StickyHeader.styled.d.ts +166 -0
  38. package/dist/components/layout/header/StickyHeader.styled.d.ts.map +1 -0
  39. package/dist/components/layout/header/StickyHeader.styled.js +40 -0
  40. package/dist/components/layout/header/StickyHeader.styled.js.map +1 -0
  41. package/docs/assets/search.js +1 -1
  42. package/docs/classes/Drawer.html +14 -14
  43. package/docs/classes/Pop.html +14 -14
  44. package/docs/classes/ToasterProvider.html +10 -10
  45. package/docs/enums/ICON.html +14 -14
  46. package/docs/functions/Action.html +5 -4
  47. package/docs/functions/Button.html +5 -4
  48. package/docs/functions/Card.html +5 -4
  49. package/docs/functions/Checkbox.html +5 -4
  50. package/docs/functions/Choice.html +6 -5
  51. package/docs/functions/CoveringLoader.html +5 -4
  52. package/docs/functions/DirectionPad.html +5 -4
  53. package/docs/functions/EqualActions.html +5 -4
  54. package/docs/functions/FullLoader.html +5 -4
  55. package/docs/functions/HandleEsc.html +5 -4
  56. package/docs/functions/Header.html +5 -4
  57. package/docs/functions/HeaderIconAction.html +8 -4
  58. package/docs/functions/Icon-1.html +7 -6
  59. package/docs/functions/If.html +5 -4
  60. package/docs/functions/Input.html +6 -5
  61. package/docs/functions/KeyValue.html +5 -4
  62. package/docs/functions/Label.html +5 -4
  63. package/docs/functions/List-1.html +5 -4
  64. package/docs/functions/Loader.html +5 -4
  65. package/docs/functions/Loading.html +5 -4
  66. package/docs/functions/Message.html +5 -4
  67. package/docs/functions/Modal-1.html +5 -4
  68. package/docs/functions/ModalButtons.html +5 -4
  69. package/docs/functions/PopLoader.html +5 -4
  70. package/docs/functions/PopOption.html +5 -4
  71. package/docs/functions/SearchContainer.html +5 -4
  72. package/docs/functions/Section.html +5 -4
  73. package/docs/functions/Select.html +5 -4
  74. package/docs/functions/Selector.html +6 -5
  75. package/docs/functions/Spacer.html +5 -4
  76. package/docs/functions/Stats.html +5 -4
  77. package/docs/functions/StickyHeader-1.html +5 -4
  78. package/docs/functions/StickyHeader.Content.html +5 -5
  79. package/docs/functions/Table.html +5 -4
  80. package/docs/functions/TextArea.html +5 -4
  81. package/docs/functions/Toggle.html +5 -4
  82. package/docs/functions/getCssText.html +5 -4
  83. package/docs/functions/styled.html +5 -4
  84. package/docs/functions/useToaster.html +6 -5
  85. package/docs/index.html +5 -4
  86. package/docs/interfaces/ActionProps.html +13 -13
  87. package/docs/interfaces/ChoiceProps.html +11 -11
  88. package/docs/interfaces/IconProps.html +79 -0
  89. package/docs/interfaces/InputCustomProps.html +10 -10
  90. package/docs/modules/List.html +7 -7
  91. package/docs/modules/Modal.html +6 -6
  92. package/docs/modules/StickyHeader.html +6 -6
  93. package/docs/modules.html +6 -4
  94. package/docs/pages/tutorials/Test.html +5 -4
  95. package/docs/types/InputProps.html +6 -5
  96. package/docs/types/ThemeCSS.html +6 -5
  97. package/docs/variables/List.Header.html +5 -5
  98. package/docs/variables/List.Item.html +5 -5
  99. package/docs/variables/Modal.RemovePadding.html +5 -5
  100. package/docs/variables/cssReset.html +6 -5
  101. package/docs/variables/miuiScrollbars.html +6 -5
  102. package/esm/components/icons/Icon.d.ts +1 -0
  103. package/esm/components/icons/Icon.d.ts.map +1 -1
  104. package/esm/components/layout/header/Header.d.ts +1 -1
  105. package/esm/components/layout/header/Header.d.ts.map +1 -1
  106. package/esm/components/layout/header/Header.js +7 -14
  107. package/esm/components/layout/header/Header.js.map +1 -1
  108. package/esm/components/layout/header/Header.stories.d.ts +11 -0
  109. package/esm/components/layout/header/Header.stories.d.ts.map +1 -0
  110. package/esm/components/layout/header/Header.stories.js +56 -0
  111. package/esm/components/layout/header/Header.stories.js.map +1 -0
  112. package/esm/components/layout/header/Header.styled.d.ts +326 -0
  113. package/esm/components/layout/header/Header.styled.d.ts.map +1 -0
  114. package/esm/components/layout/header/Header.styled.js +112 -0
  115. package/esm/components/layout/header/Header.styled.js.map +1 -0
  116. package/esm/components/layout/header/HeaderIconAction.d.ts +1 -2
  117. package/esm/components/layout/header/HeaderIconAction.d.ts.map +1 -1
  118. package/esm/components/layout/header/HeaderIconAction.js +6 -11
  119. package/esm/components/layout/header/HeaderIconAction.js.map +1 -1
  120. package/esm/components/layout/header/HeaderIconAction.stories.d.ts +9 -0
  121. package/esm/components/layout/header/HeaderIconAction.stories.d.ts.map +1 -0
  122. package/esm/components/layout/header/HeaderIconAction.stories.js +24 -0
  123. package/esm/components/layout/header/HeaderIconAction.stories.js.map +1 -0
  124. package/esm/components/layout/header/HeaderIconAction.styled.d.ts +243 -0
  125. package/esm/components/layout/header/HeaderIconAction.styled.d.ts.map +1 -0
  126. package/esm/components/layout/header/HeaderIconAction.styled.js +30 -0
  127. package/esm/components/layout/header/HeaderIconAction.styled.js.map +1 -0
  128. package/esm/components/layout/header/StickyHeader.d.ts +2 -2
  129. package/esm/components/layout/header/StickyHeader.d.ts.map +1 -1
  130. package/esm/components/layout/header/StickyHeader.js +6 -8
  131. package/esm/components/layout/header/StickyHeader.js.map +1 -1
  132. package/esm/components/layout/header/StickyHeader.stories.d.ts +8 -0
  133. package/esm/components/layout/header/StickyHeader.stories.d.ts.map +1 -0
  134. package/esm/components/layout/header/StickyHeader.stories.js +24 -0
  135. package/esm/components/layout/header/StickyHeader.stories.js.map +1 -0
  136. package/esm/components/layout/header/StickyHeader.styled.d.ts +166 -0
  137. package/esm/components/layout/header/StickyHeader.styled.d.ts.map +1 -0
  138. package/esm/components/layout/header/StickyHeader.styled.js +36 -0
  139. package/esm/components/layout/header/StickyHeader.styled.js.map +1 -0
  140. package/package.json +3 -3
  141. package/src/components/icons/Icon.tsx +4 -0
  142. package/src/components/layout/header/Header.stories.tsx +86 -0
  143. package/src/components/layout/header/Header.styled.ts +134 -0
  144. package/src/components/layout/header/Header.tsx +22 -19
  145. package/src/components/layout/header/HeaderIconAction.stories.tsx +47 -0
  146. package/src/components/layout/header/HeaderIconAction.styled.ts +40 -0
  147. package/src/components/layout/header/HeaderIconAction.tsx +30 -16
  148. package/src/components/layout/header/StickyHeader.stories.tsx +34 -0
  149. package/src/components/layout/header/StickyHeader.styled.ts +43 -0
  150. package/src/components/layout/header/StickyHeader.tsx +10 -19
  151. package/src/demo/componentsMap.ts +1 -67
  152. package/dist/components/layout/header/Header.module.scss +0 -108
  153. package/dist/components/layout/header/HeaderIconAction.module.scss +0 -26
  154. package/dist/components/layout/header/StickyHeader.module.scss +0 -18
  155. package/esm/components/layout/header/Header.module.scss +0 -108
  156. package/esm/components/layout/header/HeaderIconAction.module.scss +0 -26
  157. package/esm/components/layout/header/StickyHeader.module.scss +0 -18
  158. package/src/components/layout/header/Header.module.scss +0 -108
  159. package/src/components/layout/header/HeaderIconAction.module.scss +0 -26
  160. package/src/components/layout/header/StickyHeader.module.scss +0 -18
  161. package/src/demo/components/layout/header/Header.tsx +0 -118
  162. package/src/demo/components/layout/header/StickyHeader.module.scss +0 -14
  163. package/src/demo/components/layout/header/StickyHeader.tsx +0 -112
@@ -0,0 +1,86 @@
1
+ import React from "react";
2
+
3
+ import type { StoryObj, Meta } from "@storybook/react";
4
+
5
+ import { ICON } from "../../icons/Icon";
6
+
7
+ import { Header } from "./Header";
8
+ import { HeaderIconAction } from "./HeaderIconAction";
9
+
10
+ const meta: Meta = {
11
+ title: "Components/Layout/Header/Header",
12
+ component: Header,
13
+ tags: ["autodocs", "layout"],
14
+
15
+ argTypes: {
16
+ before: {
17
+ control: {
18
+ type: "text",
19
+ },
20
+ },
21
+ after: {
22
+ control: {
23
+ type: "text",
24
+ },
25
+ },
26
+ },
27
+ args: {
28
+ before: "Left side",
29
+ children: "Title",
30
+ after: "[Icons]",
31
+ },
32
+ };
33
+
34
+ type Story = StoryObj<typeof Header>;
35
+
36
+ const Primary: Story = {};
37
+ const LongContent: Story = {
38
+ render: (args) => {
39
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers,react/no-array-index-key
40
+ const longContent = new Array(1000).fill(null).map((_, key) => <div key={key}>content</div>);
41
+
42
+ return (
43
+ <>
44
+ <Header {...args} />
45
+ {longContent}
46
+
47
+ </>
48
+ );
49
+ },
50
+ };
51
+
52
+ const handleClick = () => { alert(1); };
53
+
54
+ const WithButtons: Story = {
55
+ args: {
56
+ before: (
57
+ <>
58
+ <HeaderIconAction icon={ICON.back} onClick={handleClick} />
59
+ <HeaderIconAction icon={ICON.checkmark} onClick={handleClick} />
60
+ </>
61
+ ),
62
+ },
63
+ };
64
+
65
+ const Vertical: Story = {
66
+ args: {
67
+ before: (
68
+ <>
69
+ <HeaderIconAction icon={ICON.back} onClick={handleClick} />
70
+ <HeaderIconAction icon={ICON.checkmark} onClick={handleClick} />
71
+ </>
72
+ ),
73
+ after: null,
74
+ position: "left",
75
+ children: "M",
76
+ },
77
+ };
78
+
79
+ export {
80
+ Primary,
81
+ LongContent,
82
+ WithButtons,
83
+ Vertical,
84
+ };
85
+
86
+ export default meta;
@@ -0,0 +1,134 @@
1
+ import type { ThemeCSS } from "../../../theme";
2
+
3
+ import { dimensionsPxToRem, pxToRem, styled } from "../../../theme";
4
+ import { EqualActions } from "../../ui/action/EqualActions";
5
+
6
+ const Contents = styled("div", {
7
+ flex: 1,
8
+ display: "flex",
9
+ });
10
+
11
+ const Before = styled("div", {
12
+ display: "flex",
13
+ });
14
+
15
+ const After = styled("div", {
16
+ display: "flex",
17
+ });
18
+
19
+ const topBottomBeforeAfter: ThemeCSS = {
20
+ height: "100%",
21
+ padding: "7px 0",
22
+ boxSizing: "border-box",
23
+ display: "flex",
24
+ alignItems: "center",
25
+ justifyContent: "center",
26
+ };
27
+
28
+ const leftRightBeforeAfter: ThemeCSS = {
29
+ width: "100%",
30
+ padding: "0 7px",
31
+ boxSizing: "border-box",
32
+ display: "flex",
33
+ alignItems: "center",
34
+ justifyContent: "center",
35
+ };
36
+
37
+ const topBottomShared: ThemeCSS = {
38
+ padding: "0 16.666px",
39
+ height: "44px",
40
+
41
+ [`& ${Before.toString()}`]: topBottomBeforeAfter,
42
+ [`& ${After.toString()}`]: topBottomBeforeAfter,
43
+
44
+ [`& ${EqualActions.toString()}`]: {
45
+ margin: `${dimensionsPxToRem(56)} 0`,
46
+ },
47
+ };
48
+
49
+ const leftRightShared: ThemeCSS = {
50
+ padding: "16.666px 0",
51
+ width: "44px",
52
+ flexDirection: "column",
53
+
54
+ [`& ${Contents.toString()}`]: {
55
+ flexDirection: "column",
56
+ alignItems: "center",
57
+ },
58
+
59
+ [`& ${Before.toString()}`]: {
60
+ flexDirection: "column",
61
+ ...leftRightBeforeAfter,
62
+ },
63
+
64
+ [`& ${After.toString()}`]: {
65
+ flexDirection: "column",
66
+ ...leftRightBeforeAfter,
67
+ },
68
+
69
+ [`& ${EqualActions.toString()}`]: {
70
+ margin: `0 ${dimensionsPxToRem(56)}`,
71
+ },
72
+ };
73
+
74
+ const StyledHeader = styled("div", {
75
+ "--border-color": "$colors$headerBorder",
76
+ "--background-color": "$colors$headerBg",
77
+ "backgroundClip": "padding-box",
78
+ "background": "var(--background-color)",
79
+ "display": "flex",
80
+ "alignItems": "center",
81
+ "fontSize": pxToRem(15),
82
+ "fontWeight": "bold",
83
+ "boxSizing": "border-box",
84
+ "color": "$headerText",
85
+ "gap": dimensionsPxToRem(50),
86
+
87
+ "variants": {
88
+ variant: {
89
+ toolbar: {
90
+ "--border-color": "$colors$toolbarBorder",
91
+ "--background-color": "$colors$toolbarBg",
92
+ },
93
+ colored: {
94
+ "--border-color": "var(--custom-header-color)",
95
+ "--background-color": "var(--custom-header-color)",
96
+ "color": "var(--custom-text-color)",
97
+ },
98
+ },
99
+ position: {
100
+ top: {
101
+ borderBottom: "0.37px solid var(--border-color)",
102
+ ...topBottomShared,
103
+ },
104
+ bottom: {
105
+ borderTop: "0.37px solid var(--border-color)",
106
+ order: 2,
107
+ ...topBottomShared,
108
+ },
109
+ left: {
110
+ borderRight: "0.37px solid var(--border-color)",
111
+ ...leftRightShared,
112
+ },
113
+ right: {
114
+ borderLeft: "0.37px solid var(--border-color)",
115
+ order: 2,
116
+ ...leftRightShared,
117
+ },
118
+ },
119
+ center: {
120
+ true: {
121
+ [`& ${Contents.toString()}`]: {
122
+ justifyContent: "center",
123
+ },
124
+ },
125
+ },
126
+ },
127
+ });
128
+
129
+ export {
130
+ StyledHeader,
131
+ Contents,
132
+ Before,
133
+ After,
134
+ };
@@ -1,32 +1,41 @@
1
1
  import React from "react";
2
2
  import type { ReactNode } from "react";
3
3
 
4
- import classnames from "classnames";
4
+ import type { Div } from "../../native";
5
5
 
6
6
  import { Action } from "../../ui/action/Action";
7
7
  import { EqualActions } from "../../ui/action/EqualActions";
8
- import { Div } from "../../native";
9
8
 
10
- import styles from "./Header.module.scss";
9
+ import { After, Before, Contents, StyledHeader } from "./Header.styled";
11
10
 
12
11
  interface Props {
12
+ /**
13
+ * Should the main content (children) be centered?
14
+ */
13
15
  center?: boolean;
16
+ /**
17
+ * Styling variant.
18
+ */
14
19
  variant?: "toolbar" | "colored";
15
20
  /**
16
21
  * This indicates just how the borders are drawn and how content is aligned, not the actual position on the screen.
17
22
  * To set up position on the screen, you need to properly style the parent element.
18
23
  */
19
24
  position?: "top" | "left" | "right" | "bottom"; // @TODO disallow left/right if not inside StickyHeader?
25
+ /**
26
+ * Content to be displayed before the main content.
27
+ */
20
28
  before?: ReactNode;
29
+ /**
30
+ * Content to be displayed after the main content.
31
+ */
21
32
  after?: ReactNode;
22
33
  }
23
34
 
24
35
  const Header: React.FC<React.ComponentProps<typeof Div> & Props> = (props) => {
25
36
  const {
26
- center,
27
- variant,
28
37
  position = "top",
29
- className: _className, before: _before, after: _after,
38
+ before: _before, after: _after,
30
39
  children,
31
40
  ...rest
32
41
  } = props;
@@ -36,36 +45,30 @@ const Header: React.FC<React.ComponentProps<typeof Div> & Props> = (props) => {
36
45
  return c && typeof c === "object" && "type" in c && c.type === Action;
37
46
  });
38
47
 
39
- const cls = classnames(styles.header, {
40
- [styles["header--center"] as string]: center,
41
- [styles["header--toolbar"] as string]: variant === "toolbar",
42
- [styles["header--colored"] as string]: variant === "colored",
43
- }, styles[`header--${position}`], props.className);
44
-
45
48
  let contents = children;
46
49
  if (justActions) {
47
50
  const mode = position === "top" || position === "bottom" ? "horizontal" : "vertical";
48
- contents = <EqualActions className={styles.actions as string} mode={mode}>{contents}</EqualActions>;
51
+ contents = <EqualActions mode={mode}>{contents}</EqualActions>;
49
52
  }
50
53
 
51
54
  let before: ReactNode;
52
55
  if (props.before != null) {
53
- before = <div className={styles.before}>{props.before}</div>;
56
+ before = <Before>{props.before}</Before>;
54
57
  }
55
58
 
56
59
  let after: ReactNode;
57
60
  if (props.after != null) {
58
- after = <div className={styles.after}>{props.after}</div>;
61
+ after = <After>{props.after}</After>;
59
62
  }
60
63
 
61
64
  return (
62
- <Div className={cls} {...rest}>
65
+ <StyledHeader {...rest} position={position} data-header-position={position}>
63
66
  {before}
64
- <div className={styles.contents}>
67
+ <Contents>
65
68
  {contents}
66
- </div>
69
+ </Contents>
67
70
  {after}
68
- </Div>
71
+ </StyledHeader>
69
72
  );
70
73
  };
71
74
 
@@ -0,0 +1,47 @@
1
+ import React from "react";
2
+
3
+ import type { StoryObj, Meta } from "@storybook/react";
4
+
5
+ import { Header } from "./Header";
6
+ import { HeaderIconAction } from "./HeaderIconAction";
7
+
8
+ const meta: Meta = {
9
+ title: "Components/Layout/Header/HeaderIconAction",
10
+ component: HeaderIconAction,
11
+ tags: ["autodocs", "layout"],
12
+ render: (args) => {
13
+ return (
14
+ <Header before={<HeaderIconAction {...args} icon={<>i</>} />}>
15
+ On the left you can see the icon
16
+ </Header>
17
+ );
18
+ },
19
+ };
20
+
21
+ type Story = StoryObj<typeof Header>;
22
+
23
+ const Primary: Story = {};
24
+
25
+ const MultipleIcons: Story = {
26
+ render: ({ onClick: _onClick, ...args }) => {
27
+ const after = (
28
+ <>
29
+ <div>some text</div>
30
+ <HeaderIconAction {...args} icon={<>i</>} />
31
+ <HeaderIconAction {...args} icon={<>i</>} />
32
+ </>
33
+ );
34
+ return (
35
+ <Header after={after}>
36
+ On the left you can see the icon
37
+ </Header>
38
+ );
39
+ },
40
+ };
41
+
42
+ export {
43
+ Primary,
44
+ MultipleIcons,
45
+ };
46
+
47
+ export default meta;
@@ -0,0 +1,40 @@
1
+ import type { ThemeCSS } from "../../../theme";
2
+
3
+ import { styled } from "../../../theme";
4
+ import { Icon } from "../../icons/Icon";
5
+
6
+ const sharedStyles: ThemeCSS = {
7
+ "blockSize": "100%",
8
+ "aspectRatio": "1",
9
+ "background": "none",
10
+ "borderRadius": "666px",
11
+ "display": "inline-flex",
12
+ "alignItems": "center",
13
+ "justifyContent": "center",
14
+ "border": "calc(2px / var(--ratio-border)) solid transparent",
15
+ "color": "currentColor",
16
+
17
+ "&:hover": {
18
+ background: "#00000022",
19
+ },
20
+ "&:active": {
21
+ background: "#00000011",
22
+ color: "currentColor",
23
+ },
24
+ };
25
+
26
+ const Btn = styled("button", sharedStyles);
27
+ const A = styled("a", sharedStyles);
28
+
29
+ const StyledIcon = styled(Icon, {
30
+ width: "16px",
31
+ height: "16px",
32
+ display: "block",
33
+ fill: "currentColor",
34
+ });
35
+
36
+ export {
37
+ Btn,
38
+ A,
39
+ StyledIcon,
40
+ };
@@ -1,13 +1,9 @@
1
1
  import React from "react";
2
2
  import type { ReactNode } from "react";
3
3
 
4
- import classnames from "classnames";
5
-
6
4
  import type { ICON } from "../../icons/Icon";
7
5
 
8
- import { Icon } from "../../icons/Icon";
9
-
10
- import styles from "./HeaderIconAction.module.scss";
6
+ import { A, Btn, StyledIcon } from "./HeaderIconAction.styled";
11
7
 
12
8
  interface LinkProps { // @TODO extract? - same on list item
13
9
  href: string;
@@ -15,21 +11,42 @@ interface LinkProps { // @TODO extract? - same on list item
15
11
  }
16
12
 
17
13
  interface Props {
14
+ /**
15
+ * Icon to display. Can be a string (for build in icons) or a ReactNode (any icon component).
16
+ */
18
17
  icon?: ICON | Exclude<ReactNode, string>;
18
+ /**
19
+ * Function to call when the icon is clicked.
20
+ */
19
21
  onClick?: () => void;
22
+ /**
23
+ * If given it will make the icon a native link.
24
+ */
20
25
  href?: string;
26
+ /**
27
+ * If given it will make the icon a custom link. `to` will be passed to given `Link` component as `href`.
28
+ */
21
29
  to?: string;
30
+ /**
31
+ * Custom link component to use. Use with `to` prop.
32
+ */
22
33
  Link?: React.ComponentClass<LinkProps> | React.FC<LinkProps>;
23
- label?: ReactNode;
24
- className?: string;
34
+ /**
35
+ * Additional class name to apply.
36
+ */
37
+ className?: string | undefined;
25
38
  }
26
39
 
40
+ /**
41
+ * Use this component if you need a clickable icon that stylistically fits the header.
42
+ * It can be a simple link, a button or a custom link component.
43
+ */
27
44
  const HeaderIconAction: React.FC<Props> = (props) => {
28
- const { icon, label, href, to, Link, className, ...restProps } = props;
45
+ const { icon, href, to, Link, className, ...restProps } = props;
29
46
 
30
47
  let content: ReactNode = icon;
31
48
  if (typeof icon === "string") {
32
- content = <Icon className={styles.icon as string} name={icon as ICON} />;
49
+ content = <StyledIcon name={icon as ICON} />;
33
50
  }
34
51
 
35
52
  if (to) {
@@ -37,20 +54,17 @@ const HeaderIconAction: React.FC<Props> = (props) => {
37
54
  throw new TypeError("`to` prop given without `Link` component");
38
55
  }
39
56
 
40
- const aCls = classnames(props.className, styles.a);
41
- return <Link href={to} {...restProps}><a className={aCls}>{content}</a></Link>;
57
+ return <Link href={to} {...restProps}><A className={props.className}>{content}</A></Link>;
42
58
  }
43
59
 
44
60
  if (href) {
45
- const aCls = classnames(props.className, styles.a);
46
- return <a href={href} className={aCls} {...restProps}>{content}</a>;
61
+ return <A href={href} className={props.className} {...restProps}>{content}</A>;
47
62
  }
48
63
 
49
- const btnCls = classnames(props.className, styles.btn);
50
64
  return (
51
- <button className={btnCls} onClick={props.onClick}>
65
+ <Btn className={props.className} onClick={props.onClick}>
52
66
  {content}
53
- </button>
67
+ </Btn>
54
68
  );
55
69
  };
56
70
 
@@ -0,0 +1,34 @@
1
+ import React from "react";
2
+
3
+ import type { StoryObj, Meta } from "@storybook/react";
4
+
5
+ import { StickyHeader } from "./StickyHeader";
6
+ import { Header } from "./Header";
7
+
8
+ const meta: Meta = {
9
+ title: "Components/Layout/Header/StickyHeader",
10
+ component: StickyHeader,
11
+ tags: ["autodocs", "layout"],
12
+ };
13
+
14
+ type Story = StoryObj<typeof StickyHeader>;
15
+
16
+ const Primary: Story = {
17
+ render: (args) => {
18
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers,react/no-array-index-key
19
+ const longContent = new Array(1000).fill(null).map((_, key) => <div key={key}>content</div>);
20
+
21
+ return (
22
+ <StickyHeader {...args}>
23
+ <Header>x<br />x<br />x</Header>
24
+ <StickyHeader.Content>{longContent}</StickyHeader.Content>
25
+ </StickyHeader>
26
+ );
27
+ },
28
+ };
29
+
30
+ export {
31
+ Primary,
32
+ };
33
+
34
+ export default meta;
@@ -0,0 +1,43 @@
1
+ import { styled } from "../../../theme";
2
+
3
+ const StyledStickyHeader = styled("div", {
4
+ height: "100%",
5
+ display: "flex",
6
+ flexDirection: "column",
7
+
8
+ variants: {
9
+ position: {
10
+ top: {},
11
+ left: {
12
+ flexDirection: "row",
13
+ },
14
+ bottom: {},
15
+ right: {
16
+ flexDirection: "row",
17
+ },
18
+ },
19
+ },
20
+ });
21
+
22
+ const Content = styled("div", {
23
+ flex: 1,
24
+ overflow: "auto",
25
+
26
+ variants: {
27
+ position: {
28
+ top: {},
29
+ bottom: {
30
+ order: 1,
31
+ },
32
+ left: {},
33
+ right: {
34
+ order: 1,
35
+ },
36
+ },
37
+ },
38
+ });
39
+
40
+ export {
41
+ Content,
42
+ StyledStickyHeader,
43
+ };
@@ -1,14 +1,11 @@
1
1
  import React from "react";
2
2
 
3
- import classnames from "classnames";
4
-
5
3
  import { Header } from "./Header";
6
-
7
- import styles from "./StickyHeader.module.scss";
4
+ import { Content, StyledStickyHeader } from "./StickyHeader.styled";
8
5
 
9
6
  const err = new TypeError("StickyHeader needs two children - Header and StickyHeader.Content");
10
7
 
11
- interface Content {
8
+ interface ContentComponent {
12
9
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
13
10
  Content: React.FC<ContentProps>;
14
11
  }
@@ -24,10 +21,10 @@ interface Props {
24
21
  children: React.ReactNode;
25
22
  }
26
23
 
27
- const StickyHeader: React.FC<Props> & Content = (props) => {
28
- const position = props.position || "top";
24
+ const StickyHeader: React.FC<Props> & ContentComponent = (props) => {
25
+ const { children: _children, position = "top", ...rest } = props;
29
26
 
30
- const children = React.Children.toArray(props.children);
27
+ const children = React.Children.toArray(_children);
31
28
 
32
29
  // eslint-disable-next-line @typescript-eslint/no-magic-numbers
33
30
  if (children.length !== 2) {
@@ -44,21 +41,15 @@ const StickyHeader: React.FC<Props> & Content = (props) => {
44
41
  header = header as never; // @TODO find a better way to silence TS on cloneElement
45
42
  content = content as never;
46
43
 
47
- const cls = classnames(styles.stickyHeader, styles[`stickyHeader--${position}`], props.className);
48
-
49
- const contentCls = classnames(
50
- styles.stickyHeader__content,
51
- styles[`stickyHeader__content--${position}`],
52
- (content as { props: ContentProps }).props.className,
53
- );
44
+ const contentCls = (content as { props: ContentProps }).props.className;
54
45
 
55
46
  return (
56
- <div className={cls}>
47
+ <StyledStickyHeader {...rest} position={position}>
57
48
  {React.cloneElement(header, { position })}
58
- <div className={contentCls}>
49
+ <Content className={contentCls} position={position}>
59
50
  {content}
60
- </div>
61
- </div>
51
+ </Content>
52
+ </StyledStickyHeader>
62
53
  );
63
54
  };
64
55
  // eslint-disable-next-line react/no-multi-comp