-
-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
331 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@suid/material": patch | ||
--- | ||
|
||
Add `Fab` component |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
import ButtonBase from "../ButtonBase"; | ||
import styled from "../styles/styled"; | ||
import capitalize from "../utils/capitalize"; | ||
import { FabTypeMap } from "./FabProps"; | ||
import fabClasses, { getFabUtilityClass } from "./fabClasses"; | ||
import createComponentFactory from "@suid/base/createComponentFactory"; | ||
import { ComponentInProps } from "@suid/types"; | ||
import clsx from "clsx"; | ||
|
||
const $ = createComponentFactory<FabTypeMap>()({ | ||
name: "MuiFab", | ||
propDefaults: ({ set }) => | ||
set({ | ||
color: "default", | ||
component: "button", | ||
disabled: false, | ||
disableFocusRipple: false, | ||
size: "large", | ||
variant: "circular", | ||
}), | ||
selfPropNames: [ | ||
"children", | ||
"classes", | ||
"color", | ||
"disableFocusRipple", | ||
"disableRipple", | ||
"disabled", | ||
"href", | ||
"size", | ||
"variant", | ||
], | ||
utilityClass: getFabUtilityClass, | ||
slotClasses: (ownerState) => ({ | ||
root: [ | ||
"root", | ||
ownerState.variant, | ||
`size${capitalize(ownerState.size)}`, | ||
ownerState.color === "inherit" ? "colorInherit" : ownerState.color, | ||
], | ||
}), | ||
}); | ||
|
||
const FabRoot = styled(ButtonBase, { | ||
name: "MuiFab", | ||
slot: "Root", | ||
overridesResolver: (props, styles) => { | ||
const { ownerState } = props; | ||
|
||
return [ | ||
styles.root, | ||
styles[ownerState.variant], | ||
styles[`size${capitalize(ownerState.size)}`], | ||
ownerState.color === "inherit" && styles.colorInherit, | ||
styles[capitalize(ownerState.size)], | ||
styles[ownerState.color], | ||
]; | ||
}, | ||
})<ComponentInProps<FabTypeMap>>( | ||
({ theme, ownerState }) => ({ | ||
...theme.typography.button, | ||
minHeight: 36, | ||
transition: theme.transitions.create( | ||
["background-color", "box-shadow", "border-color"], | ||
{ | ||
duration: theme.transitions.duration.short, | ||
} | ||
), | ||
borderRadius: "50%", | ||
padding: 0, | ||
minWidth: 0, | ||
width: 56, | ||
height: 56, | ||
boxShadow: theme.shadows[6], | ||
"&:active": { | ||
boxShadow: theme.shadows[12], | ||
}, | ||
color: theme.palette.getContrastText(theme.palette.grey[300]), | ||
backgroundColor: theme.palette.grey[300], | ||
"&:hover": { | ||
backgroundColor: theme.palette.grey.A100, | ||
// Reset on touch devices, it doesn't add specificity | ||
"@media (hover: none)": { | ||
backgroundColor: theme.palette.grey[300], | ||
}, | ||
textDecoration: "none", | ||
}, | ||
[`&.${fabClasses.focusVisible}`]: { | ||
boxShadow: theme.shadows[6], | ||
}, | ||
[`&.${fabClasses.disabled}`]: { | ||
color: theme.palette.action.disabled, | ||
boxShadow: theme.shadows[0], | ||
backgroundColor: theme.palette.action.disabledBackground, | ||
}, | ||
...(ownerState.size === "small" && { | ||
width: 40, | ||
height: 40, | ||
}), | ||
...(ownerState.size === "medium" && { | ||
width: 48, | ||
height: 48, | ||
}), | ||
...(ownerState.variant === "extended" && { | ||
borderRadius: 48 / 2, | ||
padding: "0 16px", | ||
width: "auto", | ||
minHeight: "auto", | ||
minWidth: 48, | ||
height: 48, | ||
}), | ||
...(ownerState.variant === "extended" && | ||
ownerState.size === "small" && { | ||
width: "auto", | ||
padding: "0 8px", | ||
borderRadius: 34 / 2, | ||
minWidth: 34, | ||
height: 34, | ||
}), | ||
...(ownerState.variant === "extended" && | ||
ownerState.size === "medium" && { | ||
width: "auto", | ||
padding: "0 16px", | ||
borderRadius: 40 / 2, | ||
minWidth: 40, | ||
height: 40, | ||
}), | ||
...(ownerState.color === "inherit" && { | ||
color: "inherit", | ||
}), | ||
}), | ||
({ theme, ownerState }) => ({ | ||
...(ownerState.color !== "inherit" && | ||
ownerState.color !== "default" && | ||
theme.palette[ownerState.color] != null && { | ||
color: theme.palette[ownerState.color].contrastText, | ||
backgroundColor: theme.palette[ownerState.color].main, | ||
"&:hover": { | ||
backgroundColor: theme.palette[ownerState.color].dark, | ||
// Reset on touch devices, it doesn't add specificity | ||
"@media (hover: none)": { | ||
backgroundColor: theme.palette[ownerState.color].main, | ||
}, | ||
}, | ||
}), | ||
}) | ||
); | ||
|
||
/** | ||
* | ||
* Demos: | ||
* | ||
* - [Floating Action Button](https://mui.com/components/floating-action-button/) | ||
* | ||
* API: | ||
* | ||
* - [Fab API](https://mui.com/api/fab/) | ||
* - inherits [ButtonBase API](https://mui.com/api/button-base/) | ||
*/ | ||
const Fab = $.component(function Fab({ allProps, classes, otherProps, props }) { | ||
return ( | ||
<FabRoot | ||
className={clsx(classes.root, otherProps.className)} | ||
disabled={props.disabled} | ||
focusRipple={!props.disableFocusRipple} | ||
focusVisibleClassName={clsx( | ||
props.classes?.focusVisible, | ||
otherProps.focusVisibleClassName | ||
)} | ||
ownerState={allProps} | ||
{...otherProps} | ||
> | ||
{props.children} | ||
</FabRoot> | ||
); | ||
}); | ||
|
||
export default Fab; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { PropTypes, Theme } from ".."; | ||
import { ButtonBaseTypeMap } from "../ButtonBase"; | ||
import { OverrideProps } from "../OverridableComponent"; | ||
import { FabClasses } from "./fabClasses"; | ||
import { SxProps } from "@suid/system"; | ||
import { OverridableStringUnion, ElementType } from "@suid/types"; | ||
import { JSXElement } from "solid-js"; | ||
|
||
export interface FabPropsVariantOverrides {} | ||
|
||
export interface FabPropsSizeOverrides {} | ||
|
||
export interface FabPropsColorOverrides {} | ||
|
||
export type FabTypeMap<P = {}, D extends ElementType = "button"> = { | ||
name: "MuiFab"; | ||
defaultPropNames: | ||
| "color" | ||
| "disabled" | ||
| "disableFocusRipple" | ||
| "size" | ||
| "variant"; | ||
selfProps: { | ||
/** | ||
* The content of the component. | ||
*/ | ||
children?: JSXElement; | ||
/** | ||
* Override or extend the styles applied to the component. | ||
*/ | ||
classes?: Partial<FabClasses>; | ||
/** | ||
* The color of the component. It supports those theme colors that make sense for this component. | ||
* @default 'default' | ||
*/ | ||
color?: OverridableStringUnion< | ||
PropTypes.Color | "success" | "error" | "info" | "warning", | ||
FabPropsColorOverrides | ||
>; | ||
/** | ||
* If `true`, the component is disabled. | ||
* @default false | ||
*/ | ||
disabled?: boolean; | ||
/** | ||
* If `true`, the keyboard focus ripple is disabled. | ||
* @default false | ||
*/ | ||
disableFocusRipple?: boolean; | ||
/** | ||
* If `true`, the ripple effect is disabled. | ||
*/ | ||
disableRipple?: boolean; | ||
/** | ||
* The URL to link to when the button is clicked. | ||
* If defined, an `a` element will be used as the root node. | ||
*/ | ||
href?: string; | ||
/** | ||
* The size of the component. | ||
* `small` is equivalent to the dense button styling. | ||
* @default 'large' | ||
*/ | ||
size?: OverridableStringUnion< | ||
"small" | "medium" | "large", | ||
FabPropsSizeOverrides | ||
>; | ||
/** | ||
* The variant to use. | ||
* @default 'circular' | ||
*/ | ||
variant?: OverridableStringUnion< | ||
"circular" | "extended", | ||
FabPropsVariantOverrides | ||
>; | ||
/** | ||
* The system prop that allows defining system overrides as well as additional CSS styles. | ||
*/ | ||
sx?: SxProps<Theme>; | ||
}; | ||
props: P & | ||
FabTypeMap["selfProps"] & | ||
Omit<ButtonBaseTypeMap["props"], "classes">; | ||
defaultComponent: D; | ||
}; | ||
|
||
export type FabProps< | ||
D extends ElementType = FabTypeMap["defaultComponent"], | ||
P = {} | ||
> = OverrideProps<FabTypeMap<P, D>, D>; | ||
|
||
export default FabProps; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { generateUtilityClass, generateUtilityClasses } from "@suid/base"; | ||
|
||
export interface FabClasses { | ||
/** Styles applied to the root element. */ | ||
root: string; | ||
/** Styles applied to the root element if `color="primary"`. */ | ||
primary: string; | ||
/** Styles applied to the root element if `color="secondary"`. */ | ||
secondary: string; | ||
/** Styles applied to the root element if `variant="extended"`. */ | ||
extended: string; | ||
/** Styles applied to the root element if `variant="circular"`. */ | ||
circular: string; | ||
/** State class applied to the ButtonBase root element if the button is keyboard focused. */ | ||
focusVisible: string; | ||
/** State class applied to the root element if `disabled={true}`. */ | ||
disabled: string; | ||
/** Styles applied to the root element if `color="inherit"`. */ | ||
colorInherit: string; | ||
/** Styles applied to the root element if `size="small"``. */ | ||
sizeSmall: string; | ||
/** Styles applied to the root element if `size="medium"``. */ | ||
sizeMedium: string; | ||
} | ||
|
||
export type FabClassKey = keyof FabClasses; | ||
|
||
export function getFabUtilityClass(slot: string): string { | ||
return generateUtilityClass("MuiFab", slot); | ||
} | ||
|
||
const fabClasses: FabClasses = generateUtilityClasses("MuiFab", [ | ||
"root", | ||
"primary", | ||
"secondary", | ||
"extended", | ||
"circular", | ||
"focusVisible", | ||
"disabled", | ||
"colorInherit", | ||
"sizeSmall", | ||
"sizeMedium", | ||
"sizeLarge", | ||
"info", | ||
"error", | ||
"warning", | ||
"success", | ||
]); | ||
|
||
export default fabClasses; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export { default } from "./Fab"; | ||
export * from "./Fab"; | ||
export * from "./FabProps"; | ||
|
||
export { default as fabClasses } from "./fabClasses"; | ||
export * from "./fabClasses"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters