@mitodl/smoot-design 1.0.1 → 1.1.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/README.md +14 -0
- package/dist/cjs/components/Button/ActionButton.d.ts +30 -0
- package/dist/cjs/components/Button/ActionButton.js +73 -0
- package/dist/cjs/components/Button/ActionButton.stories.d.ts +1 -4
- package/dist/cjs/components/Button/ActionButton.stories.js +22 -32
- package/dist/cjs/components/Button/Button.d.ts +13 -27
- package/dist/cjs/components/Button/Button.js +15 -60
- package/dist/cjs/components/Button/Button.stories.js +0 -30
- package/dist/cjs/components/Button/Button.test.js +7 -4
- package/dist/cjs/components/Input/Input.d.ts +115 -0
- package/dist/cjs/components/Input/Input.js +219 -0
- package/dist/cjs/components/Input/Input.stories.d.ts +19 -0
- package/dist/cjs/components/Input/Input.stories.js +134 -0
- package/dist/cjs/components/Input/Input.test.d.ts +1 -0
- package/dist/cjs/components/Input/Input.test.js +32 -0
- package/dist/cjs/components/LinkAdapter/LinkAdapter.js +1 -1
- package/dist/cjs/components/TextField/TextField.d.ts +29 -0
- package/dist/cjs/components/TextField/TextField.js +33 -0
- package/dist/cjs/components/TextField/TextField.stories.d.ts +10 -0
- package/dist/cjs/components/TextField/TextField.stories.js +135 -0
- package/dist/cjs/components/TextField/TextField.test.d.ts +1 -0
- package/dist/cjs/components/TextField/TextField.test.js +77 -0
- package/dist/cjs/components/ThemeProvider/ThemeProvider.js +0 -16
- package/dist/cjs/components/ThemeProvider/ThemeProvider.stories.js +1 -1
- package/dist/cjs/components/ThemeProvider/Typography.stories.d.ts +2 -0
- package/dist/cjs/components/ThemeProvider/Typography.stories.js +3 -1
- package/dist/cjs/components/internal/FormHelpers/FormHelpers.d.ts +39 -0
- package/dist/cjs/components/internal/FormHelpers/FormHelpers.js +78 -0
- package/dist/cjs/components/internal/FormHelpers/FormHelpers.test.d.ts +1 -0
- package/dist/cjs/components/internal/FormHelpers/FormHelpers.test.js +93 -0
- package/dist/cjs/index.d.ts +4 -2
- package/dist/cjs/index.js +3 -2
- package/dist/cjs/jest-setup.d.ts +1 -0
- package/dist/cjs/jest-setup.js +2 -0
- package/dist/cjs/story-utils/index.d.ts +3 -20
- package/dist/cjs/story-utils/index.js +2 -22
- package/dist/esm/components/Button/ActionButton.d.ts +30 -0
- package/dist/esm/components/Button/ActionButton.js +68 -0
- package/dist/esm/components/Button/ActionButton.stories.d.ts +1 -4
- package/dist/esm/components/Button/ActionButton.stories.js +2 -12
- package/dist/esm/components/Button/Button.d.ts +13 -27
- package/dist/esm/components/Button/Button.js +12 -58
- package/dist/esm/components/Button/Button.stories.js +2 -32
- package/dist/esm/components/Button/Button.test.js +7 -4
- package/dist/esm/components/Input/Input.d.ts +115 -0
- package/dist/esm/components/Input/Input.js +214 -0
- package/dist/esm/components/Input/Input.stories.d.ts +19 -0
- package/dist/esm/components/Input/Input.stories.js +131 -0
- package/dist/esm/components/Input/Input.test.d.ts +1 -0
- package/dist/esm/components/Input/Input.test.js +30 -0
- package/dist/esm/components/LinkAdapter/LinkAdapter.js +1 -1
- package/dist/esm/components/TextField/TextField.d.ts +29 -0
- package/dist/esm/components/TextField/TextField.js +30 -0
- package/dist/esm/components/TextField/TextField.stories.d.ts +10 -0
- package/dist/esm/components/TextField/TextField.stories.js +132 -0
- package/dist/esm/components/TextField/TextField.test.d.ts +1 -0
- package/dist/esm/components/TextField/TextField.test.js +75 -0
- package/dist/esm/components/ThemeProvider/ThemeProvider.js +0 -16
- package/dist/esm/components/ThemeProvider/ThemeProvider.stories.js +1 -1
- package/dist/esm/components/ThemeProvider/Typography.stories.d.ts +2 -0
- package/dist/esm/components/ThemeProvider/Typography.stories.js +3 -1
- package/dist/esm/components/internal/FormHelpers/FormHelpers.d.ts +39 -0
- package/dist/esm/components/internal/FormHelpers/FormHelpers.js +73 -0
- package/dist/esm/components/internal/FormHelpers/FormHelpers.test.d.ts +1 -0
- package/dist/esm/components/internal/FormHelpers/FormHelpers.test.js +91 -0
- package/dist/esm/index.d.ts +4 -2
- package/dist/esm/index.js +2 -1
- package/dist/esm/jest-setup.d.ts +1 -0
- package/dist/esm/jest-setup.js +1 -1
- package/dist/esm/story-utils/index.d.ts +3 -20
- package/dist/esm/story-utils/index.js +2 -21
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type-augmentation/theme.d.ts +0 -2
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -11,3 +11,17 @@ To trigger a release, run the "Release" github action. Using [semantic-release](
|
|
|
11
11
|
1. Inspect the commit history since previous release for [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) an
|
|
12
12
|
2. Determine whether the version bump should be major, minor, or patch based on commit types. Breaking changes (e.g., `feat!: remove Button variant 'outlined'`) will result in major version bumps.
|
|
13
13
|
3. Publish the package to NPM and the repository's [Github Releases](https://github.com/mitodl/smoot-design/releases).
|
|
14
|
+
|
|
15
|
+
## Documentation
|
|
16
|
+
|
|
17
|
+
Documentation for `smoot-design` components is available at https://mitodl.github.io/smoot-design.
|
|
18
|
+
|
|
19
|
+
### Storybook
|
|
20
|
+
|
|
21
|
+
Components in `smoot-design` are documented using Storybook's [autodocs](https://storybook.js.org/docs/writing-docs/autodocs) feature.
|
|
22
|
+
|
|
23
|
+
Autodocs _should_ infer props and comments from Typescript + JSDoc comments. However, autodocs can be a bit finnicky. Tips:
|
|
24
|
+
|
|
25
|
+
- **Filename should match Component Name:** If you're documenting `Button`, it must be exported from a file called `Button.tsx`.
|
|
26
|
+
- **Component `displayName`:** Some components may need an explicit `displayName`, this can be set by `Button.displayName="Button"`.
|
|
27
|
+
- _React component display names are not visible to end users; they are used in React's Dev Tools. React automatically adds display names for most components while transpiling, but autodocs uses un-transpiled code to generate documentation._
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { DEFAULT_PROPS } from "./Button";
|
|
3
|
+
import type { ButtonStyleProps } from "./Button";
|
|
4
|
+
import type { LinkAdapterPropsOverrides } from "../LinkAdapter/LinkAdapter";
|
|
5
|
+
type ActionButtonStyleProps = Omit<ButtonStyleProps, "startIcon" | "endIcon">;
|
|
6
|
+
type ActionButtonProps = ActionButtonStyleProps & React.ComponentProps<"button">;
|
|
7
|
+
/**
|
|
8
|
+
* A button that should contain a remixicon icon and nothing else.
|
|
9
|
+
* See [ActionButton docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs).
|
|
10
|
+
*
|
|
11
|
+
* See also:
|
|
12
|
+
* - [ActionButtonLink](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs#links)
|
|
13
|
+
* - [Button](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs) for text buttons
|
|
14
|
+
*/
|
|
15
|
+
declare const ActionButton: import("@emotion/styled").StyledComponent<Omit<ActionButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement> & {
|
|
16
|
+
theme?: import("@emotion/react").Theme;
|
|
17
|
+
}, {}, {}>;
|
|
18
|
+
type ActionButtonLinkProps = ActionButtonStyleProps & React.ComponentProps<"a"> & {
|
|
19
|
+
Component?: React.ElementType;
|
|
20
|
+
} & LinkAdapterPropsOverrides;
|
|
21
|
+
/**
|
|
22
|
+
* See [ActionButtonLink docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs#links)
|
|
23
|
+
*/
|
|
24
|
+
declare const ActionButtonLink: import("@emotion/styled").StyledComponent<Omit<ActionButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement> & {
|
|
25
|
+
theme?: import("@emotion/react").Theme;
|
|
26
|
+
} & ActionButtonStyleProps & React.ClassAttributes<HTMLAnchorElement> & React.AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
27
|
+
Component?: React.ElementType;
|
|
28
|
+
} & LinkAdapterPropsOverrides, {}, {}>;
|
|
29
|
+
export { ActionButton, ActionButtonLink, DEFAULT_PROPS };
|
|
30
|
+
export type { ActionButtonProps, ActionButtonLinkProps };
|
|
@@ -0,0 +1,73 @@
|
|
|
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 = void 0;
|
|
15
|
+
const React = require("react");
|
|
16
|
+
const styled_1 = require("@emotion/styled");
|
|
17
|
+
const typography_1 = require("../ThemeProvider/typography");
|
|
18
|
+
const Button_1 = require("./Button");
|
|
19
|
+
Object.defineProperty(exports, "DEFAULT_PROPS", { enumerable: true, get: function () { return Button_1.DEFAULT_PROPS; } });
|
|
20
|
+
const actionStyles = (size) => {
|
|
21
|
+
return {
|
|
22
|
+
minWidth: "auto",
|
|
23
|
+
padding: 0,
|
|
24
|
+
height: {
|
|
25
|
+
small: "32px",
|
|
26
|
+
medium: "40px",
|
|
27
|
+
large: "48px",
|
|
28
|
+
}[size],
|
|
29
|
+
width: {
|
|
30
|
+
small: "32px",
|
|
31
|
+
medium: "40px",
|
|
32
|
+
large: "48px",
|
|
33
|
+
}[size],
|
|
34
|
+
"& svg, & .MuiSvgIcon-root": {
|
|
35
|
+
width: "1em",
|
|
36
|
+
height: "1em",
|
|
37
|
+
fontSize: (0, typography_1.pxToRem)({
|
|
38
|
+
small: 20,
|
|
39
|
+
medium: 24,
|
|
40
|
+
large: 32,
|
|
41
|
+
}[size]),
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* A button that should contain a remixicon icon and nothing else.
|
|
47
|
+
* See [ActionButton docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs).
|
|
48
|
+
*
|
|
49
|
+
* See also:
|
|
50
|
+
* - [ActionButtonLink](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs#links)
|
|
51
|
+
* - [Button](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs) for text buttons
|
|
52
|
+
*/
|
|
53
|
+
const ActionButton = (0, styled_1.default)(React.forwardRef(function Root(props, ref) {
|
|
54
|
+
return React.createElement(Button_1.ButtonRoot, Object.assign({ ref: ref, type: "button" }, props));
|
|
55
|
+
}))(({ size = Button_1.DEFAULT_PROPS.size, responsive, theme }) => {
|
|
56
|
+
return [
|
|
57
|
+
actionStyles(size),
|
|
58
|
+
responsive && {
|
|
59
|
+
[theme.breakpoints.down("sm")]: actionStyles(Button_1.RESPONSIVE_SIZES[size]),
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
});
|
|
63
|
+
exports.ActionButton = ActionButton;
|
|
64
|
+
ActionButton.displayName = "ActionButton";
|
|
65
|
+
/**
|
|
66
|
+
* See [ActionButtonLink docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-actionbutton--docs#links)
|
|
67
|
+
*/
|
|
68
|
+
const ActionButtonLink = ActionButton.withComponent((_a) => {
|
|
69
|
+
var { Component } = _a, props = __rest(_a, ["Component"]);
|
|
70
|
+
return React.createElement(Button_1.ButtonLinkRoot, Object.assign({ Component: Component }, props));
|
|
71
|
+
});
|
|
72
|
+
exports.ActionButtonLink = ActionButtonLink;
|
|
73
|
+
ActionButtonLink.displayName = "ActionButtonLink";
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
-
import { ActionButton } from "./
|
|
3
|
-
/**
|
|
4
|
-
* A button that should contain a remixicon icon and nothing else.
|
|
5
|
-
*/
|
|
2
|
+
import { ActionButton } from "./ActionButton";
|
|
6
3
|
declare const meta: Meta<typeof ActionButton>;
|
|
7
4
|
export default meta;
|
|
8
5
|
type Story = StoryObj<typeof ActionButton>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Links = exports.Showcase = exports.VariantsAndEdge = void 0;
|
|
4
4
|
const React = require("react");
|
|
5
|
-
const
|
|
5
|
+
const ActionButton_1 = require("./ActionButton");
|
|
6
6
|
const Grid2_1 = require("@mui/material/Grid2");
|
|
7
7
|
const Stack_1 = require("@mui/material/Stack");
|
|
8
8
|
const react_1 = require("@remixicon/react");
|
|
@@ -34,61 +34,51 @@ const EDGES = (0, story_utils_1.enumValues)({
|
|
|
34
34
|
rounded: true,
|
|
35
35
|
none: true,
|
|
36
36
|
});
|
|
37
|
-
/**
|
|
38
|
-
* A button that should contain a remixicon icon and nothing else.
|
|
39
|
-
*/
|
|
40
37
|
const meta = {
|
|
41
38
|
title: "smoot-design/ActionButton",
|
|
42
|
-
component:
|
|
39
|
+
component: ActionButton_1.ActionButton,
|
|
43
40
|
argTypes: {
|
|
44
41
|
variant: {
|
|
45
|
-
options: VARIANTS,
|
|
46
42
|
control: { type: "select" },
|
|
47
43
|
table: {
|
|
48
|
-
|
|
49
|
-
defaultValue: { summary: Button_1.DEFAULT_PROPS.variant },
|
|
44
|
+
defaultValue: { summary: ActionButton_1.DEFAULT_PROPS.variant },
|
|
50
45
|
},
|
|
51
46
|
},
|
|
52
47
|
size: {
|
|
53
|
-
options: SIZES,
|
|
54
48
|
control: { type: "select" },
|
|
55
49
|
table: {
|
|
56
|
-
|
|
57
|
-
defaultValue: { summary: Button_1.DEFAULT_PROPS.size },
|
|
50
|
+
defaultValue: { summary: ActionButton_1.DEFAULT_PROPS.size },
|
|
58
51
|
},
|
|
59
52
|
},
|
|
60
53
|
edge: {
|
|
61
|
-
options: EDGES,
|
|
62
54
|
control: { type: "select" },
|
|
63
55
|
table: {
|
|
64
|
-
|
|
65
|
-
defaultValue: { summary: Button_1.DEFAULT_PROPS.edge },
|
|
56
|
+
defaultValue: { summary: ActionButton_1.DEFAULT_PROPS.edge },
|
|
66
57
|
},
|
|
67
58
|
},
|
|
68
59
|
},
|
|
69
60
|
args: {
|
|
70
61
|
onClick: (0, test_1.fn)(),
|
|
71
62
|
},
|
|
72
|
-
tags: ["autodocs"],
|
|
73
63
|
};
|
|
74
64
|
exports.default = meta;
|
|
75
65
|
exports.VariantsAndEdge = {
|
|
76
66
|
render: (args) => (React.createElement(React.Fragment, null,
|
|
77
67
|
React.createElement(Stack_1.default, { direction: "row", gap: 2, sx: { my: 2 } },
|
|
78
|
-
React.createElement(
|
|
79
|
-
React.createElement(
|
|
80
|
-
React.createElement(
|
|
81
|
-
React.createElement(
|
|
68
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "none", variant: "primary" }), ICONS.DeleteIcon),
|
|
69
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "none", variant: "secondary" }), ICONS.DeleteIcon),
|
|
70
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "none", variant: "tertiary" }), ICONS.DeleteIcon),
|
|
71
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "none", variant: "text" }), ICONS.DeleteIcon)),
|
|
82
72
|
React.createElement(Stack_1.default, { direction: "row", gap: 2, sx: { my: 2 } },
|
|
83
|
-
React.createElement(
|
|
84
|
-
React.createElement(
|
|
85
|
-
React.createElement(
|
|
86
|
-
React.createElement(
|
|
73
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "rounded", variant: "primary" }), ICONS.DeleteIcon),
|
|
74
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "rounded", variant: "secondary" }), ICONS.DeleteIcon),
|
|
75
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "rounded", variant: "tertiary" }), ICONS.DeleteIcon),
|
|
76
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "rounded", variant: "text" }), ICONS.DeleteIcon)),
|
|
87
77
|
React.createElement(Stack_1.default, { direction: "row", gap: 2, sx: { my: 2 } },
|
|
88
|
-
React.createElement(
|
|
89
|
-
React.createElement(
|
|
90
|
-
React.createElement(
|
|
91
|
-
React.createElement(
|
|
78
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "circular", variant: "primary" }), ICONS.DeleteIcon),
|
|
79
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "circular", variant: "secondary" }), ICONS.DeleteIcon),
|
|
80
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "circular", variant: "tertiary" }), ICONS.DeleteIcon),
|
|
81
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({}, args, { edge: "circular", variant: "text" }), ICONS.DeleteIcon)))),
|
|
92
82
|
tags: ["main"],
|
|
93
83
|
};
|
|
94
84
|
exports.Showcase = {
|
|
@@ -103,7 +93,7 @@ exports.Showcase = {
|
|
|
103
93
|
SIZES.flatMap((size) => Object.entries(ICONS)
|
|
104
94
|
.filter(([_key, icon]) => icon)
|
|
105
95
|
.map(([iconKey, icon]) => (React.createElement(Grid2_1.default, { size: { xs: 4, sm: 1 }, key: `${size}-${iconKey}` },
|
|
106
|
-
React.createElement(
|
|
96
|
+
React.createElement(ActionButton_1.ActionButton, Object.assign({ variant: variant, edge: edge, size: size }, args), icon))))))))))),
|
|
107
97
|
};
|
|
108
98
|
/**
|
|
109
99
|
* `ActionButtonLink` is styled as a `ActionButton` that renders an anchor tag.
|
|
@@ -114,8 +104,8 @@ exports.Showcase = {
|
|
|
114
104
|
*/
|
|
115
105
|
exports.Links = {
|
|
116
106
|
render: () => (React.createElement(Stack_1.default, { direction: "row", gap: 2, sx: { my: 2 } },
|
|
117
|
-
React.createElement(
|
|
118
|
-
React.createElement(
|
|
119
|
-
React.createElement(
|
|
120
|
-
React.createElement(
|
|
107
|
+
React.createElement(ActionButton_1.ActionButtonLink, { href: "#fake", variant: "primary" }, ICONS.DeleteIcon),
|
|
108
|
+
React.createElement(ActionButton_1.ActionButtonLink, { href: "#fake", variant: "secondary" }, ICONS.DeleteIcon),
|
|
109
|
+
React.createElement(ActionButton_1.ActionButtonLink, { href: "#fake", variant: "tertiary" }, ICONS.DeleteIcon),
|
|
110
|
+
React.createElement(ActionButton_1.ActionButtonLink, { href: "#fake", variant: "text" }, ICONS.DeleteIcon))),
|
|
121
111
|
};
|
|
@@ -8,7 +8,7 @@ type ButtonStyleProps = {
|
|
|
8
8
|
size?: ButtonSize;
|
|
9
9
|
edge?: ButtonEdge;
|
|
10
10
|
/**
|
|
11
|
-
* Display an icon before the button text
|
|
11
|
+
* Display an icon before the button text
|
|
12
12
|
*/
|
|
13
13
|
startIcon?: React.ReactNode;
|
|
14
14
|
/**
|
|
@@ -26,6 +26,16 @@ type ButtonStyleProps = {
|
|
|
26
26
|
color?: "secondary";
|
|
27
27
|
};
|
|
28
28
|
declare const DEFAULT_PROPS: Required<Omit<ButtonStyleProps, "startIcon" | "endIcon" | "color">>;
|
|
29
|
+
declare const RESPONSIVE_SIZES: Record<ButtonSize, ButtonSize>;
|
|
30
|
+
declare const ButtonRoot: import("@emotion/styled").StyledComponent<{
|
|
31
|
+
theme?: import("@emotion/react").Theme;
|
|
32
|
+
as?: React.ElementType;
|
|
33
|
+
} & ButtonStyleProps, React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {}>;
|
|
34
|
+
declare const ButtonLinkRoot: import("@emotion/styled").StyledComponent<Omit<React.ClassAttributes<HTMLAnchorElement> & React.AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
35
|
+
Component?: React.ElementType;
|
|
36
|
+
} & LinkAdapterPropsOverrides, "ref"> & React.RefAttributes<HTMLAnchorElement> & {
|
|
37
|
+
theme?: import("@emotion/react").Theme;
|
|
38
|
+
} & ButtonStyleProps, {}, {}>;
|
|
29
39
|
type ButtonProps = ButtonStyleProps & React.ComponentProps<"button">;
|
|
30
40
|
/**
|
|
31
41
|
* Our standard button component. See [Button Docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs).
|
|
@@ -42,29 +52,5 @@ type ButtonLinkProps = ButtonStyleProps & React.ComponentProps<"a"> & {
|
|
|
42
52
|
* See [ButtonLink docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs#links)
|
|
43
53
|
*/
|
|
44
54
|
declare const ButtonLink: React.ForwardRefExoticComponent<Omit<ButtonLinkProps, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
|
|
45
|
-
|
|
46
|
-
type
|
|
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, };
|
|
55
|
+
export { Button, ButtonLink, ButtonRoot, DEFAULT_PROPS, ButtonLinkRoot, RESPONSIVE_SIZES, };
|
|
56
|
+
export type { ButtonProps, ButtonLinkProps, ButtonStyleProps, ButtonSize };
|
|
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.
|
|
14
|
+
exports.RESPONSIVE_SIZES = exports.ButtonLinkRoot = exports.DEFAULT_PROPS = exports.ButtonRoot = exports.ButtonLink = exports.Button = void 0;
|
|
15
15
|
const React = require("react");
|
|
16
16
|
const styled_1 = require("@emotion/styled");
|
|
17
17
|
const react_1 = require("@emotion/react");
|
|
@@ -26,7 +26,7 @@ const styleProps = {
|
|
|
26
26
|
responsive: true,
|
|
27
27
|
color: true,
|
|
28
28
|
};
|
|
29
|
-
const
|
|
29
|
+
const shouldForwardButtonProp = (prop) => !styleProps[prop];
|
|
30
30
|
const DEFAULT_PROPS = {
|
|
31
31
|
variant: "primary",
|
|
32
32
|
size: "medium",
|
|
@@ -44,6 +44,7 @@ const RESPONSIVE_SIZES = {
|
|
|
44
44
|
medium: "small",
|
|
45
45
|
large: "medium",
|
|
46
46
|
};
|
|
47
|
+
exports.RESPONSIVE_SIZES = RESPONSIVE_SIZES;
|
|
47
48
|
const sizeStyles = (size, hasBorder, theme) => {
|
|
48
49
|
const paddingAdjust = hasBorder ? BORDER_WIDTHS[size] : 0;
|
|
49
50
|
return [
|
|
@@ -56,7 +57,7 @@ const sizeStyles = (size, hasBorder, theme) => {
|
|
|
56
57
|
size === "small" && Object.assign({ padding: `${8 - paddingAdjust}px 12px` }, theme.typography.buttonSmall),
|
|
57
58
|
];
|
|
58
59
|
};
|
|
59
|
-
const
|
|
60
|
+
const buttonStyles = (props) => {
|
|
60
61
|
const { size, variant, edge, theme, color, responsive } = Object.assign(Object.assign({}, DEFAULT_PROPS), props);
|
|
61
62
|
const { colors } = theme.custom;
|
|
62
63
|
const hasBorder = variant === "secondary";
|
|
@@ -193,10 +194,14 @@ const buildStyles = (props) => {
|
|
|
193
194
|
},
|
|
194
195
|
]);
|
|
195
196
|
};
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
const ButtonRoot = (0, styled_1.default)("button", {
|
|
198
|
+
shouldForwardProp: shouldForwardButtonProp,
|
|
199
|
+
})(buttonStyles);
|
|
200
|
+
exports.ButtonRoot = ButtonRoot;
|
|
201
|
+
const ButtonLinkRoot = (0, styled_1.default)(LinkAdapter_1.LinkAdapter, {
|
|
202
|
+
shouldForwardProp: shouldForwardButtonProp,
|
|
203
|
+
})(buttonStyles);
|
|
204
|
+
exports.ButtonLinkRoot = ButtonLinkRoot;
|
|
200
205
|
const IconContainer = styled_1.default.span(({ size, side }) => [
|
|
201
206
|
{
|
|
202
207
|
height: "1em",
|
|
@@ -244,68 +249,18 @@ const ButtonInner = (props) => {
|
|
|
244
249
|
*/
|
|
245
250
|
const Button = React.forwardRef((_a, ref) => {
|
|
246
251
|
var { children } = _a, props = __rest(_a, ["children"]);
|
|
247
|
-
return (React.createElement(
|
|
252
|
+
return (React.createElement(ButtonRoot, Object.assign({ ref: ref, type: "button" }, props),
|
|
248
253
|
React.createElement(ButtonInner, Object.assign({}, props), children)));
|
|
249
254
|
});
|
|
250
255
|
exports.Button = Button;
|
|
256
|
+
Button.displayName = "Button";
|
|
251
257
|
/**
|
|
252
258
|
* See [ButtonLink docs](https://mitodl.github.io/smoot-design/?path=/docs/smoot-design-button--docs#links)
|
|
253
259
|
*/
|
|
254
260
|
const ButtonLink = React.forwardRef((_a, ref) => {
|
|
255
261
|
var { children, Component } = _a, props = __rest(_a, ["children", "Component"]);
|
|
256
|
-
return (React.createElement(
|
|
262
|
+
return (React.createElement(ButtonLinkRoot, Object.assign({ Component: Component, ref: ref }, props),
|
|
257
263
|
React.createElement(ButtonInner, Object.assign({}, props), children)));
|
|
258
264
|
});
|
|
259
265
|
exports.ButtonLink = ButtonLink;
|
|
260
266
|
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";
|
|
@@ -38,30 +38,6 @@ const meta = {
|
|
|
38
38
|
title: "smoot-design/Button",
|
|
39
39
|
component: Button_1.Button,
|
|
40
40
|
argTypes: {
|
|
41
|
-
variant: {
|
|
42
|
-
options: VARIANTS,
|
|
43
|
-
control: { type: "select" },
|
|
44
|
-
table: {
|
|
45
|
-
type: { summary: (0, story_utils_1.docsEnum)(VARIANTS) },
|
|
46
|
-
defaultValue: { summary: Button_1.DEFAULT_PROPS.variant },
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
size: {
|
|
50
|
-
options: SIZES,
|
|
51
|
-
control: { type: "select" },
|
|
52
|
-
table: {
|
|
53
|
-
type: { summary: (0, story_utils_1.docsEnum)(SIZES) },
|
|
54
|
-
defaultValue: { summary: Button_1.DEFAULT_PROPS.size },
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
edge: {
|
|
58
|
-
options: ["circular", "rounded"],
|
|
59
|
-
control: { type: "select" },
|
|
60
|
-
table: {
|
|
61
|
-
type: { summary: (0, story_utils_1.docsEnum)(EDGES) },
|
|
62
|
-
defaultValue: { summary: Button_1.DEFAULT_PROPS.edge },
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
41
|
startIcon: {
|
|
66
42
|
options: Object.keys(ICONS),
|
|
67
43
|
mapping: ICONS,
|
|
@@ -70,16 +46,10 @@ const meta = {
|
|
|
70
46
|
options: Object.keys(ICONS),
|
|
71
47
|
mapping: ICONS,
|
|
72
48
|
},
|
|
73
|
-
responsive: {
|
|
74
|
-
table: {
|
|
75
|
-
defaultValue: { summary: Button_1.DEFAULT_PROPS.responsive.toString() },
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
49
|
},
|
|
79
50
|
args: {
|
|
80
51
|
onClick: (0, test_1.fn)(),
|
|
81
52
|
},
|
|
82
|
-
tags: ["autodocs"],
|
|
83
53
|
};
|
|
84
54
|
exports.default = meta;
|
|
85
55
|
exports.VariantsAndEdge = {
|
|
@@ -4,17 +4,20 @@ const React = require("react");
|
|
|
4
4
|
const react_1 = require("@testing-library/react");
|
|
5
5
|
const ThemeProvider_1 = require("../ThemeProvider/ThemeProvider");
|
|
6
6
|
const Button_1 = require("./Button");
|
|
7
|
+
const ActionButton_1 = require("./ActionButton");
|
|
7
8
|
const withLinkOverride = (0, ThemeProvider_1.createTheme)({
|
|
8
9
|
custom: {
|
|
9
|
-
LinkAdapter: React.forwardRef((props, ref)
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
LinkAdapter: React.forwardRef(function LinkAdapter(props, ref) {
|
|
11
|
+
return (
|
|
12
|
+
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
|
13
|
+
React.createElement("a", Object.assign({ ref: ref, "data-custom": "theme-default" }, props)));
|
|
14
|
+
}),
|
|
12
15
|
},
|
|
13
16
|
});
|
|
14
17
|
describe.each([
|
|
15
18
|
//
|
|
16
19
|
{ ButtonComponent: Button_1.ButtonLink },
|
|
17
|
-
{ ButtonComponent:
|
|
20
|
+
{ ButtonComponent: ActionButton_1.ActionButtonLink },
|
|
18
21
|
])("$ButtonComponent.displayName overrides", ({ ButtonComponent }) => {
|
|
19
22
|
test("Uses anchor by default", () => {
|
|
20
23
|
(0, react_1.render)(React.createElement(ButtonComponent, { href: "/test" }, "Link text here"), {
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { InputBaseProps } from "@mui/material/InputBase";
|
|
3
|
+
import type { Theme } from "@mui/material/styles";
|
|
4
|
+
type Size = "small" | "medium" | "large" | "hero";
|
|
5
|
+
type CustomInputProps = {
|
|
6
|
+
/**
|
|
7
|
+
* If true, the input will display one size smaller at mobile breakpoint.
|
|
8
|
+
*/
|
|
9
|
+
responsive?: boolean;
|
|
10
|
+
};
|
|
11
|
+
type MuiDocOverride = {
|
|
12
|
+
size?: Size;
|
|
13
|
+
/**
|
|
14
|
+
* Slot for icon adornments.
|
|
15
|
+
*
|
|
16
|
+
* If the icon is a button, use `AdornmentButton` component.
|
|
17
|
+
*/
|
|
18
|
+
startAdornment?: React.ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* Slot for icon adornments.
|
|
21
|
+
*
|
|
22
|
+
* If the icon is a button, use `AdornmentButton` component.
|
|
23
|
+
*/
|
|
24
|
+
endAdornment?: React.ReactNode;
|
|
25
|
+
};
|
|
26
|
+
type InputProps = CustomInputProps & MuiDocOverride & Omit<InputBaseProps, "color" | keyof MuiDocOverride>;
|
|
27
|
+
/**
|
|
28
|
+
* Base styles for Input and Select components. Includes border, color, hover effects.
|
|
29
|
+
*/
|
|
30
|
+
declare const baseInputStyles: (theme: Theme) => {
|
|
31
|
+
backgroundColor: string;
|
|
32
|
+
color: string;
|
|
33
|
+
borderColor: string;
|
|
34
|
+
borderWidth: string;
|
|
35
|
+
borderStyle: string;
|
|
36
|
+
borderRadius: string;
|
|
37
|
+
"&.Mui-disabled": {
|
|
38
|
+
backgroundColor: string;
|
|
39
|
+
};
|
|
40
|
+
"&:hover:not(.Mui-disabled):not(.Mui-focused)": {
|
|
41
|
+
borderColor: string;
|
|
42
|
+
};
|
|
43
|
+
"&.Mui-focused": {
|
|
44
|
+
/**
|
|
45
|
+
* When change border width, it affects either the elements outside of it or
|
|
46
|
+
* inside based on the border-box setting.
|
|
47
|
+
*
|
|
48
|
+
* Instead of changing the border width, we hide the border and change width
|
|
49
|
+
* using outline.
|
|
50
|
+
*/
|
|
51
|
+
borderColor: string;
|
|
52
|
+
outline: string;
|
|
53
|
+
outlineOffset: string;
|
|
54
|
+
};
|
|
55
|
+
"&.Mui-error": {
|
|
56
|
+
borderColor: string;
|
|
57
|
+
outlineColor: string;
|
|
58
|
+
};
|
|
59
|
+
"& input::placeholder, textarea::placeholder": {
|
|
60
|
+
color: string;
|
|
61
|
+
opacity: number;
|
|
62
|
+
};
|
|
63
|
+
"& input:placeholder-shown, textarea:placeholder-shown": {
|
|
64
|
+
textOverflow: string;
|
|
65
|
+
};
|
|
66
|
+
"& textarea": {
|
|
67
|
+
paddingTop: string;
|
|
68
|
+
paddingBottom: string;
|
|
69
|
+
};
|
|
70
|
+
"&.MuiInputBase-adornedStart": {
|
|
71
|
+
paddingLeft: string;
|
|
72
|
+
input: {
|
|
73
|
+
paddingLeft: string;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
"&.MuiInputBase-adornedEnd": {
|
|
77
|
+
paddingRight: string;
|
|
78
|
+
input: {
|
|
79
|
+
paddingRight: string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Use `Input` for a visually unlabelled input field. If used, it should still
|
|
85
|
+
* have an accessible label, e.g., provided via `aria-label`.
|
|
86
|
+
* For a labeled input field, use `TextField`. instead.
|
|
87
|
+
*
|
|
88
|
+
* **Note:** This component is a styled version of MUI's `InputBase`. See
|
|
89
|
+
* MUI's documentation for full info.
|
|
90
|
+
*
|
|
91
|
+
* - [Smoot Design Input Documentation](https://mitodl.github.io/smoot-design/https://mitodl.github.io/smoot-design/)
|
|
92
|
+
* - [InputBase Documentation](https://mui.com/api/input-base/)
|
|
93
|
+
*/
|
|
94
|
+
declare const Input: React.FC<InputProps>;
|
|
95
|
+
declare const AdornmentButtonStyled: import("@emotion/styled").StyledComponent<{
|
|
96
|
+
theme?: import("@emotion/react").Theme;
|
|
97
|
+
as?: React.ElementType;
|
|
98
|
+
}, React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {}>;
|
|
99
|
+
type AdornmentButtonProps = React.ComponentProps<typeof AdornmentButtonStyled>;
|
|
100
|
+
/**
|
|
101
|
+
* Button to be used with `startAdornment` and `endAdornment` props on Input and
|
|
102
|
+
* TextField components. AdornmentButton takes care of positioning and other
|
|
103
|
+
* styling concerns.
|
|
104
|
+
*
|
|
105
|
+
* NOTES:
|
|
106
|
+
* - It is generally expected that the content of the AdornmentButton is a
|
|
107
|
+
* Remix Icon component. https://remixicon.com/
|
|
108
|
+
* - By default, the AdornmentButton calls `preventDefault` on `mouseDown`
|
|
109
|
+
* events. This prevents the button from stealing focus from the input on
|
|
110
|
+
* click. The button is still focusable via keyboard events. You can override
|
|
111
|
+
* this behavior by passing your own `onMouseDown` handler.
|
|
112
|
+
*/
|
|
113
|
+
declare const AdornmentButton: React.FC<AdornmentButtonProps>;
|
|
114
|
+
export { AdornmentButton, Input, baseInputStyles };
|
|
115
|
+
export type { InputProps, AdornmentButtonProps };
|