@mitodl/smoot-design 1.0.0 → 1.0.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.
Files changed (103) hide show
  1. package/dist/cjs/components/Button/ActionButton.stories.d.ts +18 -0
  2. package/dist/cjs/components/Button/ActionButton.stories.js +121 -0
  3. package/dist/cjs/components/Button/Button.d.ts +70 -0
  4. package/dist/cjs/components/Button/Button.js +311 -0
  5. package/dist/cjs/components/Button/Button.stories.d.ts +17 -0
  6. package/dist/cjs/components/Button/Button.stories.js +163 -0
  7. package/dist/cjs/components/Button/Button.test.d.ts +1 -0
  8. package/dist/cjs/components/Button/Button.test.js +43 -0
  9. package/dist/cjs/components/LinkAdapter/LinkAdapter.d.ts +23 -0
  10. package/dist/cjs/components/LinkAdapter/LinkAdapter.js +34 -0
  11. package/dist/cjs/components/ThemeProvider/ThemeProvider.d.ts +23 -0
  12. package/dist/cjs/components/ThemeProvider/ThemeProvider.js +106 -0
  13. package/dist/cjs/components/ThemeProvider/ThemeProvider.stories.d.ts +58 -0
  14. package/dist/cjs/components/ThemeProvider/ThemeProvider.stories.js +97 -0
  15. package/dist/cjs/components/ThemeProvider/Typography.stories.d.ts +37 -0
  16. package/dist/cjs/components/ThemeProvider/Typography.stories.js +63 -0
  17. package/dist/cjs/components/ThemeProvider/breakpoints.d.ts +4 -0
  18. package/dist/cjs/components/ThemeProvider/breakpoints.js +20 -0
  19. package/dist/cjs/components/ThemeProvider/buttons.d.ts +7 -0
  20. package/dist/cjs/components/ThemeProvider/buttons.js +20 -0
  21. package/dist/cjs/components/ThemeProvider/chips.d.ts +3 -0
  22. package/dist/cjs/components/ThemeProvider/chips.js +154 -0
  23. package/dist/cjs/components/ThemeProvider/colors.d.ts +32 -0
  24. package/dist/cjs/components/ThemeProvider/colors.js +35 -0
  25. package/dist/cjs/components/ThemeProvider/typography.d.ts +18 -0
  26. package/dist/cjs/components/ThemeProvider/typography.js +174 -0
  27. package/dist/cjs/index.d.ts +7 -0
  28. package/dist/cjs/index.js +19 -0
  29. package/dist/cjs/jest-setup.js +1 -0
  30. package/{src/story-utils/index.ts → dist/cjs/story-utils/index.d.ts} +3 -9
  31. package/dist/cjs/story-utils/index.js +30 -0
  32. package/dist/esm/components/Button/ActionButton.stories.d.ts +18 -0
  33. package/dist/esm/components/Button/ActionButton.stories.js +118 -0
  34. package/dist/esm/components/Button/Button.d.ts +70 -0
  35. package/dist/esm/components/Button/Button.js +304 -0
  36. package/dist/esm/components/Button/Button.stories.d.ts +17 -0
  37. package/dist/esm/components/Button/Button.stories.js +160 -0
  38. package/dist/esm/components/Button/Button.test.d.ts +1 -0
  39. package/dist/esm/components/Button/Button.test.js +41 -0
  40. package/dist/esm/components/LinkAdapter/LinkAdapter.d.ts +23 -0
  41. package/dist/esm/components/LinkAdapter/LinkAdapter.js +31 -0
  42. package/dist/esm/components/ThemeProvider/ThemeProvider.d.ts +23 -0
  43. package/dist/esm/components/ThemeProvider/ThemeProvider.js +102 -0
  44. package/dist/esm/components/ThemeProvider/ThemeProvider.stories.d.ts +58 -0
  45. package/dist/esm/components/ThemeProvider/ThemeProvider.stories.js +94 -0
  46. package/dist/esm/components/ThemeProvider/Typography.stories.d.ts +37 -0
  47. package/dist/esm/components/ThemeProvider/Typography.stories.js +60 -0
  48. package/dist/esm/components/ThemeProvider/breakpoints.d.ts +4 -0
  49. package/dist/esm/components/ThemeProvider/breakpoints.js +16 -0
  50. package/dist/esm/components/ThemeProvider/buttons.d.ts +7 -0
  51. package/dist/esm/components/ThemeProvider/buttons.js +17 -0
  52. package/dist/esm/components/ThemeProvider/chips.d.ts +3 -0
  53. package/dist/esm/components/ThemeProvider/chips.js +151 -0
  54. package/dist/esm/components/ThemeProvider/colors.d.ts +32 -0
  55. package/dist/esm/components/ThemeProvider/colors.js +32 -0
  56. package/dist/esm/components/ThemeProvider/typography.d.ts +18 -0
  57. package/dist/esm/components/ThemeProvider/typography.js +168 -0
  58. package/dist/esm/index.d.ts +7 -0
  59. package/dist/esm/index.js +6 -0
  60. package/dist/esm/jest-setup.d.ts +0 -0
  61. package/dist/esm/jest-setup.js +1 -0
  62. package/dist/esm/story-utils/index.d.ts +22 -0
  63. package/dist/esm/story-utils/index.js +26 -0
  64. package/dist/tsconfig.tsbuildinfo +1 -0
  65. package/dist/type-augmentation/TypescriptDocs.mdx +17 -0
  66. package/dist/type-augmentation/index.d.ts +2 -0
  67. package/{src/types → dist/type-augmentation}/theme.d.ts +1 -2
  68. package/package.json +13 -3
  69. package/.eslintrc.js +0 -142
  70. package/.github/workflows/ci.yml +0 -48
  71. package/.github/workflows/publish-pages.yml +0 -50
  72. package/.github/workflows/release.yml +0 -34
  73. package/.github/workflows/validate-pr.yml +0 -49
  74. package/.pre-commit-config.yaml +0 -90
  75. package/.prettierignore +0 -1
  76. package/.prettierrc.json +0 -4
  77. package/.releaserc.json +0 -40
  78. package/.secrets.baseline +0 -113
  79. package/.storybook/main.ts +0 -46
  80. package/.storybook/manager-head.html +0 -1
  81. package/.storybook/preview-head.html +0 -5
  82. package/.storybook/preview.tsx +0 -15
  83. package/.storybook/public/pexels-photo-1851188.webp +0 -0
  84. package/.yarn/releases/yarn-4.5.1.cjs +0 -934
  85. package/.yarnrc.yml +0 -23
  86. package/jest.config.ts +0 -22
  87. package/src/components/Button/ActionButton.stories.tsx +0 -186
  88. package/src/components/Button/Button.stories.tsx +0 -275
  89. package/src/components/Button/Button.test.tsx +0 -56
  90. package/src/components/Button/Button.tsx +0 -418
  91. package/src/components/LinkAdapter/LinkAdapter.tsx +0 -38
  92. package/src/components/ThemeProvider/ThemeProvider.stories.tsx +0 -94
  93. package/src/components/ThemeProvider/ThemeProvider.tsx +0 -127
  94. package/src/components/ThemeProvider/Typography.stories.tsx +0 -74
  95. package/src/components/ThemeProvider/breakpoints.ts +0 -20
  96. package/src/components/ThemeProvider/buttons.ts +0 -22
  97. package/src/components/ThemeProvider/chips.tsx +0 -167
  98. package/src/components/ThemeProvider/colors.ts +0 -33
  99. package/src/components/ThemeProvider/typography.ts +0 -174
  100. package/src/index.ts +0 -24
  101. package/tsconfig.json +0 -26
  102. /package/{src/jest-setup.ts → dist/cjs/jest-setup.d.ts} +0 -0
  103. /package/{src/types → dist/type-augmentation}/typography.d.ts +0 -0
@@ -0,0 +1,18 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { ActionButton } from "./Button";
3
+ /**
4
+ * A button that should contain a remixicon icon and nothing else.
5
+ */
6
+ declare const meta: Meta<typeof ActionButton>;
7
+ export default meta;
8
+ type Story = StoryObj<typeof ActionButton>;
9
+ export declare const VariantsAndEdge: Story;
10
+ export declare const Showcase: Story;
11
+ /**
12
+ * `ActionButtonLink` is styled as a `ActionButton` that renders an anchor tag.
13
+ *
14
+ * To use a custom link component (E.g. `Link` from `react-router` or `next/link`),
15
+ * pass it as the `Component` prop. Alternatively, customize the project-wide
16
+ * default link adapter via [Theme's LinkAdapter](../?path=/docs/smoot-design-themeprovider--docs)
17
+ */
18
+ export declare const Links: Story;
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Links = exports.Showcase = exports.VariantsAndEdge = void 0;
4
+ const React = require("react");
5
+ const Button_1 = require("./Button");
6
+ const Grid2_1 = require("@mui/material/Grid2");
7
+ const Stack_1 = require("@mui/material/Stack");
8
+ const react_1 = require("@remixicon/react");
9
+ const test_1 = require("@storybook/test");
10
+ const story_utils_1 = require("@/story-utils");
11
+ const ICONS = {
12
+ None: undefined,
13
+ ArrowBackIcon: React.createElement(react_1.RiArrowLeftLine, null),
14
+ DeleteIcon: React.createElement(react_1.RiDeleteBinLine, null),
15
+ TestTubeIcon: React.createElement(react_1.RiTestTubeLine, null),
16
+ };
17
+ const VARIANTS = (0, story_utils_1.enumValues)({
18
+ primary: true,
19
+ secondary: true,
20
+ tertiary: true,
21
+ text: true,
22
+ unstable_noBorder: true,
23
+ unstable_inverted: true,
24
+ unstable_success: true,
25
+ });
26
+ const STABLE_VARIANTS = VARIANTS.filter((v) => !v.startsWith("unstable"));
27
+ const SIZES = (0, story_utils_1.enumValues)({
28
+ small: true,
29
+ medium: true,
30
+ large: true,
31
+ });
32
+ const EDGES = (0, story_utils_1.enumValues)({
33
+ circular: true,
34
+ rounded: true,
35
+ none: true,
36
+ });
37
+ /**
38
+ * A button that should contain a remixicon icon and nothing else.
39
+ */
40
+ const meta = {
41
+ title: "smoot-design/ActionButton",
42
+ component: Button_1.ActionButton,
43
+ argTypes: {
44
+ variant: {
45
+ options: VARIANTS,
46
+ control: { type: "select" },
47
+ table: {
48
+ type: { summary: (0, story_utils_1.docsEnum)(VARIANTS) },
49
+ defaultValue: { summary: Button_1.DEFAULT_PROPS.variant },
50
+ },
51
+ },
52
+ size: {
53
+ options: SIZES,
54
+ control: { type: "select" },
55
+ table: {
56
+ type: { summary: (0, story_utils_1.docsEnum)(SIZES) },
57
+ defaultValue: { summary: Button_1.DEFAULT_PROPS.size },
58
+ },
59
+ },
60
+ edge: {
61
+ options: EDGES,
62
+ control: { type: "select" },
63
+ table: {
64
+ type: { summary: (0, story_utils_1.docsEnum)(EDGES) },
65
+ defaultValue: { summary: Button_1.DEFAULT_PROPS.edge },
66
+ },
67
+ },
68
+ },
69
+ args: {
70
+ onClick: (0, test_1.fn)(),
71
+ },
72
+ tags: ["autodocs"],
73
+ };
74
+ exports.default = meta;
75
+ exports.VariantsAndEdge = {
76
+ render: (args) => (React.createElement(React.Fragment, null,
77
+ React.createElement(Stack_1.default, { direction: "row", gap: 2, sx: { my: 2 } },
78
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "none", variant: "primary" }), ICONS.DeleteIcon),
79
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "none", variant: "secondary" }), ICONS.DeleteIcon),
80
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "none", variant: "tertiary" }), ICONS.DeleteIcon),
81
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "none", variant: "text" }), ICONS.DeleteIcon)),
82
+ React.createElement(Stack_1.default, { direction: "row", gap: 2, sx: { my: 2 } },
83
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "rounded", variant: "primary" }), ICONS.DeleteIcon),
84
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "rounded", variant: "secondary" }), ICONS.DeleteIcon),
85
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "rounded", variant: "tertiary" }), ICONS.DeleteIcon),
86
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "rounded", variant: "text" }), ICONS.DeleteIcon)),
87
+ React.createElement(Stack_1.default, { direction: "row", gap: 2, sx: { my: 2 } },
88
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "circular", variant: "primary" }), ICONS.DeleteIcon),
89
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "circular", variant: "secondary" }), ICONS.DeleteIcon),
90
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "circular", variant: "tertiary" }), ICONS.DeleteIcon),
91
+ React.createElement(Button_1.ActionButton, Object.assign({}, args, { edge: "circular", variant: "text" }), ICONS.DeleteIcon)))),
92
+ tags: ["main"],
93
+ };
94
+ exports.Showcase = {
95
+ render: (args) => (React.createElement(Grid2_1.default, { container: true, sx: { maxWidth: "750px" }, rowGap: 2 }, STABLE_VARIANTS.flatMap((variant) => EDGES.flatMap((edge) => (React.createElement(React.Fragment, { key: `${variant}-${edge}` },
96
+ React.createElement(Grid2_1.default, { size: { xs: 12, sm: 3 }, alignItems: "center" },
97
+ React.createElement("code", null,
98
+ "variant=",
99
+ variant,
100
+ React.createElement("br", null),
101
+ "edge=",
102
+ edge)),
103
+ SIZES.flatMap((size) => Object.entries(ICONS)
104
+ .filter(([_key, icon]) => icon)
105
+ .map(([iconKey, icon]) => (React.createElement(Grid2_1.default, { size: { xs: 4, sm: 1 }, key: `${size}-${iconKey}` },
106
+ React.createElement(Button_1.ActionButton, Object.assign({ variant: variant, edge: edge, size: size }, args), icon))))))))))),
107
+ };
108
+ /**
109
+ * `ActionButtonLink` is styled as a `ActionButton` that renders an anchor tag.
110
+ *
111
+ * To use a custom link component (E.g. `Link` from `react-router` or `next/link`),
112
+ * pass it as the `Component` prop. Alternatively, customize the project-wide
113
+ * default link adapter via [Theme's LinkAdapter](../?path=/docs/smoot-design-themeprovider--docs)
114
+ */
115
+ exports.Links = {
116
+ render: () => (React.createElement(Stack_1.default, { direction: "row", gap: 2, sx: { my: 2 } },
117
+ React.createElement(Button_1.ActionButtonLink, { href: "#fake", variant: "primary" }, ICONS.DeleteIcon),
118
+ React.createElement(Button_1.ActionButtonLink, { href: "#fake", variant: "secondary" }, ICONS.DeleteIcon),
119
+ React.createElement(Button_1.ActionButtonLink, { href: "#fake", variant: "tertiary" }, ICONS.DeleteIcon),
120
+ React.createElement(Button_1.ActionButtonLink, { href: "#fake", variant: "text" }, ICONS.DeleteIcon))),
121
+ };
@@ -0,0 +1,70 @@
1
+ import * as React from "react";
2
+ import { LinkAdapterPropsOverrides } from "../LinkAdapter/LinkAdapter";
3
+ type ButtonVariant = "primary" | "secondary" | "tertiary" | "text" | "unstable_noBorder" | "unstable_inverted" | "unstable_success";
4
+ type ButtonSize = "small" | "medium" | "large";
5
+ type ButtonEdge = "circular" | "rounded" | "none";
6
+ type ButtonStyleProps = {
7
+ variant?: ButtonVariant;
8
+ size?: ButtonSize;
9
+ edge?: ButtonEdge;
10
+ /**
11
+ * Display an icon before the button text.
12
+ */
13
+ startIcon?: React.ReactNode;
14
+ /**
15
+ * Display an icon after the button text.
16
+ */
17
+ endIcon?: React.ReactNode;
18
+ /**
19
+ * If true (default: `false`), the button will become one size smaller at the
20
+ * `sm` breakpoint.
21
+ * - large -> medium
22
+ * - medium -> small
23
+ * - small -> small
24
+ */
25
+ responsive?: boolean;
26
+ color?: "secondary";
27
+ };
28
+ declare const DEFAULT_PROPS: Required<Omit<ButtonStyleProps, "startIcon" | "endIcon" | "color">>;
29
+ type ButtonProps = ButtonStyleProps & React.ComponentProps<"button">;
30
+ /**
31
+ * Our standard button component. See [Button Docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs).
32
+ *
33
+ * See also:
34
+ * - [ButtonLink](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs#links)
35
+ * - [ActionButton](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs) for icon-only uses
36
+ */
37
+ declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
38
+ type ButtonLinkProps = ButtonStyleProps & React.ComponentProps<"a"> & {
39
+ Component?: React.ElementType;
40
+ } & LinkAdapterPropsOverrides;
41
+ /**
42
+ * See [ButtonLink docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs#links)
43
+ */
44
+ declare const ButtonLink: React.ForwardRefExoticComponent<Omit<ButtonLinkProps, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
45
+ type ActionButtonStyleProps = Omit<ButtonStyleProps, "startIcon" | "endIcon">;
46
+ type ActionButtonProps = ActionButtonStyleProps & React.ComponentProps<"button">;
47
+ /**
48
+ * A button that should contain a remixicon icon and nothing else.
49
+ * See [ActionButton docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs).
50
+ *
51
+ * See also:
52
+ * - [ActionButtonLink](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs#links)
53
+ * - [Button](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs) for text buttons
54
+ */
55
+ declare const ActionButton: import("@emotion/styled").StyledComponent<Omit<ActionButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement> & {
56
+ theme?: import("@emotion/react").Theme;
57
+ }, {}, {}>;
58
+ type ActionButtonLinkProps = ActionButtonStyleProps & React.ComponentProps<"a"> & {
59
+ Component?: React.ElementType;
60
+ } & LinkAdapterPropsOverrides;
61
+ /**
62
+ * See [ActionButtonLink docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs#links)
63
+ */
64
+ declare const ActionButtonLink: import("@emotion/styled").StyledComponent<Omit<ActionButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement> & {
65
+ theme?: import("@emotion/react").Theme;
66
+ } & ButtonStyleProps & React.ClassAttributes<HTMLAnchorElement> & React.AnchorHTMLAttributes<HTMLAnchorElement> & {
67
+ Component?: React.ElementType;
68
+ } & LinkAdapterPropsOverrides, {}, {}>;
69
+ export { Button, ButtonLink, ActionButton, ActionButtonLink, DEFAULT_PROPS };
70
+ export type { ButtonProps, ButtonLinkProps, ActionButtonProps, ActionButtonLinkProps, };
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.DEFAULT_PROPS = exports.ActionButtonLink = exports.ActionButton = exports.ButtonLink = exports.Button = void 0;
15
+ const React = require("react");
16
+ const styled_1 = require("@emotion/styled");
17
+ const react_1 = require("@emotion/react");
18
+ const typography_1 = require("../ThemeProvider/typography");
19
+ const LinkAdapter_1 = require("../LinkAdapter/LinkAdapter");
20
+ const styleProps = {
21
+ variant: true,
22
+ size: true,
23
+ edge: true,
24
+ startIcon: true,
25
+ endIcon: true,
26
+ responsive: true,
27
+ color: true,
28
+ };
29
+ const shouldForwardProp = (prop) => !styleProps[prop];
30
+ const DEFAULT_PROPS = {
31
+ variant: "primary",
32
+ size: "medium",
33
+ edge: "rounded",
34
+ responsive: false,
35
+ };
36
+ exports.DEFAULT_PROPS = DEFAULT_PROPS;
37
+ const BORDER_WIDTHS = {
38
+ small: 1,
39
+ medium: 1,
40
+ large: 2,
41
+ };
42
+ const RESPONSIVE_SIZES = {
43
+ small: "small",
44
+ medium: "small",
45
+ large: "medium",
46
+ };
47
+ const sizeStyles = (size, hasBorder, theme) => {
48
+ const paddingAdjust = hasBorder ? BORDER_WIDTHS[size] : 0;
49
+ return [
50
+ {
51
+ boxSizing: "border-box",
52
+ borderWidth: BORDER_WIDTHS[size],
53
+ },
54
+ size === "large" && Object.assign({ padding: `${14 - paddingAdjust}px 24px` }, theme.typography.buttonLarge),
55
+ size === "medium" && Object.assign({ padding: `${11 - paddingAdjust}px 16px` }, theme.typography.button),
56
+ size === "small" && Object.assign({ padding: `${8 - paddingAdjust}px 12px` }, theme.typography.buttonSmall),
57
+ ];
58
+ };
59
+ const buildStyles = (props) => {
60
+ const { size, variant, edge, theme, color, responsive } = Object.assign(Object.assign({}, DEFAULT_PROPS), props);
61
+ const { colors } = theme.custom;
62
+ const hasBorder = variant === "secondary";
63
+ return (0, react_1.css)([
64
+ {
65
+ color: theme.palette.text.primary,
66
+ textAlign: "center",
67
+ // display
68
+ display: "inline-flex",
69
+ justifyContent: "center",
70
+ alignItems: "center",
71
+ // transitions
72
+ transition: `background ${theme.transitions.duration.short}ms`,
73
+ // cursor
74
+ cursor: "pointer",
75
+ ":disabled": {
76
+ cursor: "default",
77
+ },
78
+ minWidth: "100px",
79
+ },
80
+ ...sizeStyles(size, hasBorder, theme),
81
+ // responsive
82
+ responsive && {
83
+ [theme.breakpoints.down("sm")]: sizeStyles(RESPONSIVE_SIZES[size], hasBorder, theme),
84
+ },
85
+ // variant
86
+ variant === "primary" && {
87
+ backgroundColor: colors.mitRed,
88
+ color: colors.white,
89
+ border: "none",
90
+ /* Shadow/04dp */
91
+ boxShadow: "0px 2px 4px 0px rgba(37, 38, 43, 0.10), 0px 3px 8px 0px rgba(37, 38, 43, 0.12)",
92
+ ":hover:not(:disabled)": {
93
+ backgroundColor: colors.red,
94
+ boxShadow: "none",
95
+ },
96
+ ":disabled": {
97
+ backgroundColor: colors.silverGray,
98
+ boxShadow: "none",
99
+ },
100
+ },
101
+ hasBorder && {
102
+ backgroundColor: "transparent",
103
+ borderColor: "currentcolor",
104
+ borderStyle: "solid",
105
+ },
106
+ variant === "unstable_success" && {
107
+ backgroundColor: colors.darkGreen,
108
+ color: colors.white,
109
+ border: "none",
110
+ /* Shadow/04dp */
111
+ boxShadow: "0px 2px 4px 0px rgba(37, 38, 43, 0.10), 0px 3px 8px 0px rgba(37, 38, 43, 0.12)",
112
+ ":hover:not(:disabled)": {
113
+ backgroundColor: colors.darkGreen,
114
+ boxShadow: "none",
115
+ },
116
+ ":disabled": {
117
+ backgroundColor: colors.silverGray,
118
+ boxShadow: "none",
119
+ },
120
+ },
121
+ hasBorder && {
122
+ backgroundColor: "transparent",
123
+ borderColor: "currentcolor",
124
+ borderStyle: "solid",
125
+ },
126
+ variant === "secondary" && {
127
+ color: colors.red,
128
+ ":hover:not(:disabled)": {
129
+ // brightRed at 0.06 alpha
130
+ backgroundColor: "rgba(255, 20, 35, 0.06)",
131
+ },
132
+ ":disabled": {
133
+ color: colors.silverGray,
134
+ },
135
+ },
136
+ variant === "text" && {
137
+ backgroundColor: "transparent",
138
+ borderStyle: "none",
139
+ color: colors.darkGray2,
140
+ ":hover:not(:disabled)": {
141
+ // darkGray1 at 6% alpha
142
+ backgroundColor: "rgba(64, 70, 76, 0.06)",
143
+ },
144
+ ":disabled": {
145
+ color: colors.silverGray,
146
+ },
147
+ },
148
+ variant === "unstable_noBorder" && {
149
+ backgroundColor: colors.white,
150
+ color: colors.darkGray2,
151
+ border: "none",
152
+ ":hover:not(:disabled)": {
153
+ // darkGray1 at 6% alpha
154
+ backgroundColor: "rgba(64, 70, 76, 0.06)",
155
+ },
156
+ ":disabled": {
157
+ color: colors.silverGray,
158
+ },
159
+ },
160
+ variant === "tertiary" && {
161
+ color: colors.darkGray2,
162
+ border: "none",
163
+ backgroundColor: colors.lightGray2,
164
+ ":hover:not(:disabled)": {
165
+ backgroundColor: colors.white,
166
+ },
167
+ ":disabled": {
168
+ backgroundColor: colors.lightGray2,
169
+ color: colors.silverGrayLight,
170
+ },
171
+ },
172
+ variant === "unstable_inverted" && {
173
+ backgroundColor: colors.white,
174
+ color: colors.mitRed,
175
+ borderColor: colors.mitRed,
176
+ borderStyle: "solid",
177
+ },
178
+ // edge
179
+ edge === "rounded" && {
180
+ borderRadius: "4px",
181
+ },
182
+ edge === "circular" && {
183
+ // Pill-shaped buttons... Overlapping border radius get clipped to pill.
184
+ borderRadius: "100vh",
185
+ },
186
+ // color
187
+ color === "secondary" && {
188
+ color: theme.custom.colors.silverGray,
189
+ borderColor: theme.custom.colors.silverGray,
190
+ ":hover:not(:disabled)": {
191
+ backgroundColor: theme.custom.colors.lightGray1,
192
+ },
193
+ },
194
+ ]);
195
+ };
196
+ const ButtonStyled = (0, styled_1.default)("button", { shouldForwardProp })(buildStyles);
197
+ const LinkStyled = (0, styled_1.default)(LinkAdapter_1.LinkAdapter, {
198
+ shouldForwardProp,
199
+ })(buildStyles);
200
+ const IconContainer = styled_1.default.span(({ size, side }) => [
201
+ {
202
+ height: "1em",
203
+ display: "flex",
204
+ alignItems: "center",
205
+ },
206
+ side === "start" && {
207
+ /**
208
+ * The negative margin is to counteract the padding on the button itself.
209
+ * Without icons, the left space is 24/16/12 px.
210
+ * With icons, the left space is 20/12/8 px.
211
+ */
212
+ marginLeft: "-4px",
213
+ marginRight: "8px",
214
+ },
215
+ side === "end" && {
216
+ marginLeft: "8px",
217
+ marginRight: "-4px",
218
+ },
219
+ {
220
+ "& svg, & .MuiSvgIcon-root": {
221
+ width: "1em",
222
+ height: "1em",
223
+ fontSize: (0, typography_1.pxToRem)({
224
+ small: 16,
225
+ medium: 20,
226
+ large: 24,
227
+ }[size]),
228
+ },
229
+ },
230
+ ]);
231
+ const ButtonInner = (props) => {
232
+ const { children, size = DEFAULT_PROPS.size } = props;
233
+ return (React.createElement(React.Fragment, null,
234
+ props.startIcon ? (React.createElement(IconContainer, { size: size, side: "start" }, props.startIcon)) : null,
235
+ children,
236
+ props.endIcon ? (React.createElement(IconContainer, { size: size, side: "end" }, props.endIcon)) : null));
237
+ };
238
+ /**
239
+ * Our standard button component. See [Button Docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs).
240
+ *
241
+ * See also:
242
+ * - [ButtonLink](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs#links)
243
+ * - [ActionButton](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs) for icon-only uses
244
+ */
245
+ const Button = React.forwardRef((_a, ref) => {
246
+ var { children } = _a, props = __rest(_a, ["children"]);
247
+ return (React.createElement(ButtonStyled, Object.assign({ ref: ref, type: "button" }, props),
248
+ React.createElement(ButtonInner, Object.assign({}, props), children)));
249
+ });
250
+ exports.Button = Button;
251
+ /**
252
+ * See [ButtonLink docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs#links)
253
+ */
254
+ const ButtonLink = React.forwardRef((_a, ref) => {
255
+ var { children, Component } = _a, props = __rest(_a, ["children", "Component"]);
256
+ return (React.createElement(LinkStyled, Object.assign({ Component: Component, ref: ref }, props),
257
+ React.createElement(ButtonInner, Object.assign({}, props), children)));
258
+ });
259
+ exports.ButtonLink = ButtonLink;
260
+ ButtonLink.displayName = "ButtonLink";
261
+ const actionStyles = (size) => {
262
+ return {
263
+ minWidth: "auto",
264
+ padding: 0,
265
+ height: {
266
+ small: "32px",
267
+ medium: "40px",
268
+ large: "48px",
269
+ }[size],
270
+ width: {
271
+ small: "32px",
272
+ medium: "40px",
273
+ large: "48px",
274
+ }[size],
275
+ "& svg, & .MuiSvgIcon-root": {
276
+ width: "1em",
277
+ height: "1em",
278
+ fontSize: (0, typography_1.pxToRem)({
279
+ small: 20,
280
+ medium: 24,
281
+ large: 32,
282
+ }[size]),
283
+ },
284
+ };
285
+ };
286
+ /**
287
+ * A button that should contain a remixicon icon and nothing else.
288
+ * See [ActionButton docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs).
289
+ *
290
+ * See also:
291
+ * - [ActionButtonLink](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs#links)
292
+ * - [Button](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs) for text buttons
293
+ */
294
+ const ActionButton = (0, styled_1.default)(React.forwardRef((props, ref) => (React.createElement(ButtonStyled, Object.assign({ ref: ref, type: "button" }, props)))))(({ size = DEFAULT_PROPS.size, responsive, theme }) => {
295
+ return [
296
+ actionStyles(size),
297
+ responsive && {
298
+ [theme.breakpoints.down("sm")]: actionStyles(RESPONSIVE_SIZES[size]),
299
+ },
300
+ ];
301
+ });
302
+ exports.ActionButton = ActionButton;
303
+ /**
304
+ * See [ActionButtonLink docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs#links)
305
+ */
306
+ const ActionButtonLink = ActionButton.withComponent((_a) => {
307
+ var { Component } = _a, props = __rest(_a, ["Component"]);
308
+ return React.createElement(LinkStyled, Object.assign({ Component: Component }, props));
309
+ });
310
+ exports.ActionButtonLink = ActionButtonLink;
311
+ ActionButtonLink.displayName = "ActionButtonLink";
@@ -0,0 +1,17 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Button } from "./Button";
3
+ declare const meta: Meta<typeof Button>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof Button>;
6
+ export declare const VariantsAndEdge: Story;
7
+ export declare const Sizes: Story;
8
+ export declare const WithIcons: Story;
9
+ /**
10
+ * `ButtonLink` is a styled `Button` that renders an anchor tag.
11
+ *
12
+ * To use a custom link component (E.g. `Link` from `react-router` or `next/link`),
13
+ * pass it as the `Component` prop. Alternatively, customize the project-wide
14
+ * default link adapter via [Theme's LinkAdapter](../?path=/docs/smoot-design-themeprovider--docs)
15
+ */
16
+ export declare const Links: Story;
17
+ export declare const Showcase: Story;