@khanacademy/wonder-blocks-button 9.0.2 → 10.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @khanacademy/wonder-blocks-button
2
2
 
3
+ ## 10.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [c7d95bf]
8
+ - Updated dependencies [668093b]
9
+ - @khanacademy/wonder-blocks-theming@3.4.0
10
+ - @khanacademy/wonder-blocks-tokens@10.2.0
11
+ - @khanacademy/wonder-blocks-clickable@7.1.2
12
+ - @khanacademy/wonder-blocks-core@12.3.0
13
+ - @khanacademy/wonder-blocks-icon@5.1.4
14
+ - @khanacademy/wonder-blocks-progress-spinner@3.1.13
15
+ - @khanacademy/wonder-blocks-styles@0.2.9
16
+ - @khanacademy/wonder-blocks-typography@3.2.3
17
+
18
+ ## 10.0.0
19
+
20
+ ### Major Changes
21
+
22
+ - a55481a: Renames `color` prop to `actionType` and changes `default` to `progressive`.
23
+
24
+ ### Minor Changes
25
+
26
+ - 812c167: Add `neutral` value to the `actionType` prop.
27
+
28
+ ### Patch Changes
29
+
30
+ - a1be4c5: Updates Button default theme to simplify its use and have more consistency with the `IconButton` styles. Also makes some changes to get this button closer to the design specs.
31
+ - 176a3bd: Splits ButtonCore to keep styles there and creates a new ButtonUnstyled to handle the semantics of the Button HTML elements"
32
+ - Updated dependencies [a1be4c5]
33
+ - Updated dependencies [d00a6f1]
34
+ - Updated dependencies [abf5496]
35
+ - Updated dependencies [812c167]
36
+ - @khanacademy/wonder-blocks-tokens@10.1.0
37
+ - @khanacademy/wonder-blocks-clickable@7.1.1
38
+ - @khanacademy/wonder-blocks-progress-spinner@3.1.12
39
+ - @khanacademy/wonder-blocks-styles@0.2.8
40
+ - @khanacademy/wonder-blocks-typography@3.2.2
41
+
3
42
  ## 9.0.2
4
43
 
5
44
  ### Patch Changes
@@ -1,9 +1,9 @@
1
1
  import * as React from "react";
2
- import { Link } from "react-router-dom-v5-compat";
3
2
  import type { ChildrenProps, ClickableState } from "@khanacademy/wonder-blocks-clickable";
4
- import type { SharedProps } from "./button";
3
+ import { Link } from "react-router-dom-v5-compat";
4
+ import type { ButtonActionType, ButtonKind, ButtonSize, ButtonProps } from "../util/button.types";
5
5
  import { ButtonThemeContract } from "../themes/themed-button";
6
- type Props = SharedProps & ChildrenProps & ClickableState;
6
+ type Props = ButtonProps & ChildrenProps & ClickableState;
7
7
  declare const ButtonCore: React.ForwardRefExoticComponent<Props & React.RefAttributes<typeof Link | HTMLButtonElement | HTMLAnchorElement>>;
8
8
  export default ButtonCore;
9
- export declare const _generateStyles: (buttonColor: string | undefined, kind: "primary" | "secondary" | "tertiary", size: "large" | "medium" | "small", theme: ButtonThemeContract, themeName: string) => any;
9
+ export declare const _generateStyles: (actionType: ButtonActionType | undefined, kind: ButtonKind, size: ButtonSize, theme: ButtonThemeContract, themeName: string) => any;
@@ -0,0 +1,11 @@
1
+ import * as React from "react";
2
+ import { Link } from "react-router-dom-v5-compat";
3
+ import { ButtonProps } from "../util/button.types";
4
+ type Props = Omit<ButtonProps, "children"> & {
5
+ /**
6
+ * The button content.
7
+ */
8
+ children: React.ReactNode;
9
+ };
10
+ declare const ButtonUnstyled: React.ForwardRefExoticComponent<Props & React.RefAttributes<typeof Link | HTMLButtonElement | HTMLAnchorElement>>;
11
+ export { ButtonUnstyled };
@@ -1,168 +1,43 @@
1
1
  import * as React from "react";
2
- import type { AriaProps, StyleType } from "@khanacademy/wonder-blocks-core";
3
- import type { PhosphorIconAsset } from "@khanacademy/wonder-blocks-icon";
4
- import { Link } from "react-router-dom-v5-compat";
5
- export type SharedProps =
6
2
  /**
7
- * aria-label should be used when `spinner={true}` to let people using screen
8
- * readers that the action taken by clicking the button will take some
9
- * time to complete.
3
+ * The `Button` component is a reusable button that can be used in various
4
+ * contexts. It can be used as a link or a button, and it supports various
5
+ * props to customize its behavior and appearance.
6
+ *
7
+ * ### Usage
8
+ *
9
+ * ```tsx
10
+ * import Button from "@khanacademy/wonder-blocks-button";
11
+ *
12
+ * <Button
13
+ * onClick={(e) => console.log("Hello, world!")}
14
+ * >
15
+ * Hello, world!
16
+ * </Button>
17
+ * ```
10
18
  */
11
- Partial<Omit<AriaProps, "aria-disabled">> & {
12
- /**
13
- * Text to appear on the button.
14
- */
19
+ declare const Button: React.ForwardRefExoticComponent<Partial<Omit<import("@khanacademy/wonder-blocks-core").AriaProps, "aria-disabled">> & {
15
20
  children: string;
16
- /**
17
- * A Phosphor icon asset (imported as a static SVG file) that
18
- * will appear at the start of the button (left for LTR, right for RTL).
19
- */
20
- startIcon?: PhosphorIconAsset;
21
- /**
22
- * A Phosphor icon asset (imported as a static SVG file) that
23
- * will appear at the end of the button (right for LTR, left for RTL).
24
- */
25
- endIcon?: PhosphorIconAsset;
26
- /**
27
- * If true, replaces the contents with a spinner.
28
- *
29
- * Note: setting this prop to `true` will disable the button.
30
- */
21
+ startIcon?: import("@khanacademy/wonder-blocks-icon").PhosphorIconAsset;
22
+ endIcon?: import("@khanacademy/wonder-blocks-icon").PhosphorIconAsset;
31
23
  spinner?: boolean;
32
- /**
33
- * The color of the button, either blue or red.
34
- */
35
- color?: "default" | "destructive";
36
- /**
37
- * The kind of the button, either primary, secondary, or tertiary.
38
- *
39
- * In default state:
40
- *
41
- * - Primary buttons have background colors
42
- * - Secondary buttons have a border and no background color
43
- * - Tertiary buttons have no background or border
44
- */
45
- kind?: "primary" | "secondary" | "tertiary";
46
- /**
47
- * The size of the button. "medium" = height: 40; "small" = height: 32;
48
- * "large" = height: 56;
49
- */
50
- size?: "medium" | "small" | "large";
51
- /**
52
- * Whether the button is disabled.
53
- */
24
+ actionType?: import("../util/button.types").ButtonActionType;
25
+ kind?: import("../util/button.types").ButtonKind;
26
+ size?: import("../util/button.types").ButtonSize;
54
27
  disabled?: boolean;
55
- /**
56
- * An optional id attribute.
57
- */
58
28
  id?: string;
59
- /**
60
- * Test ID used for e2e testing.
61
- */
62
29
  testId?: string;
63
- /**
64
- * Specifies the type of relationship between the current document and the
65
- * linked document. Should only be used when `href` is specified. This
66
- * defaults to "noopener noreferrer" when `target="_blank"`, but can be
67
- * overridden by setting this prop to something else.
68
- */
69
30
  rel?: string;
70
- /**
71
- * A target destination window for a link to open in. Should only be used
72
- * when `href` is specified.
73
- *
74
- * TODO(WB-1262): only allow this prop when `href` is also set.t
75
- */
76
31
  target?: "_blank";
77
- /**
78
- * Set the tabindex attribute on the rendered element.
79
- */
80
32
  tabIndex?: number;
81
- /**
82
- * Whether to avoid using client-side navigation.
83
- *
84
- * If the URL passed to href is local to the client-side, e.g.
85
- * /math/algebra/eval-exprs, then it tries to use react-router-dom's Link
86
- * component which handles the client-side navigation. You can set
87
- * `skipClientNav` to true avoid using client-side nav entirely.
88
- *
89
- * NOTE: All URLs containing a protocol are considered external, e.g.
90
- * https://khanacademy.org/math/algebra/eval-exprs will trigger a full
91
- * page reload.
92
- */
93
33
  skipClientNav?: boolean;
94
- /**
95
- * Optional custom styles for the inner label.
96
- */
97
- labelStyle?: StyleType;
98
- /**
99
- * Optional custom styles.
100
- */
101
- style?: StyleType;
102
- /**
103
- * URL to navigate to.
104
- */
34
+ labelStyle?: import("@khanacademy/wonder-blocks-core").StyleType;
35
+ style?: import("@khanacademy/wonder-blocks-core").StyleType;
105
36
  href?: string;
106
- /**
107
- * Used for buttons within <form>s.
108
- */
109
37
  type?: "submit";
110
- /**
111
- * Adds CSS classes to the Button.
112
- */
113
38
  className?: string;
114
- /**
115
- * Function to call when button is clicked.
116
- *
117
- * This callback should be used for running synchronous code, like
118
- * dispatching a Redux action. For asynchronous code see the
119
- * beforeNav and safeWithNav props. It should NOT be used to redirect
120
- * to a different URL.
121
- *
122
- * Note: onClick is optional if href is present, but must be defined if
123
- * href is not
124
- */
125
39
  onClick?: (e: React.SyntheticEvent) => unknown;
126
- /**
127
- * Run async code before navigating. If the promise returned rejects then
128
- * navigation will not occur.
129
- *
130
- * If both safeWithNav and beforeNav are provided, beforeNav will be run
131
- * first and safeWithNav will only be run if beforeNav does not reject.
132
- *
133
- * WARNING: Do not use with `type="submit"`.
134
- */
135
40
  beforeNav?: () => Promise<unknown>;
136
- /**
137
- * Run async code in the background while client-side navigating. If the
138
- * browser does a full page load navigation, the callback promise must be
139
- * settled before the navigation will occur. Errors are ignored so that
140
- * navigation is guaranteed to succeed.
141
- *
142
- * WARNING: Do not use with `type="submit"`.
143
- */
144
41
  safeWithNav?: () => Promise<unknown>;
145
- };
146
- type Props = SharedProps;
147
- /**
148
- * Reusable button component.
149
- *
150
- * Consisting of a [`ClickableBehavior`](#clickablebehavior) surrounding a
151
- * `ButtonCore`. `ClickableBehavior` handles interactions and state changes.
152
- * `ButtonCore` is a stateless component which displays the different states
153
- * the `Button` can take.
154
- *
155
- * ### Usage
156
- *
157
- * ```jsx
158
- * import Button from "@khanacademy/wonder-blocks-button";
159
- *
160
- * <Button
161
- * onClick={(e) => console.log("Hello, world!")}
162
- * >
163
- * Hello, world!
164
- * </Button>
165
- * ```
166
- */
167
- declare const Button: React.ForwardRefExoticComponent<Props & React.RefAttributes<typeof Link | HTMLButtonElement | HTMLAnchorElement>>;
42
+ } & React.RefAttributes<HTMLAnchorElement | HTMLButtonElement | React.ForwardRefExoticComponent<import("react-router-dom-v5-compat").LinkProps & React.RefAttributes<HTMLAnchorElement>>>>;
168
43
  export default Button;
package/dist/es/index.js CHANGED
@@ -7,19 +7,22 @@ import { LabelSmall, LabelLarge } from '@khanacademy/wonder-blocks-typography';
7
7
  import { addStyle, View } from '@khanacademy/wonder-blocks-core';
8
8
  import { CircularSpinner } from '@khanacademy/wonder-blocks-progress-spinner';
9
9
  import { mergeTheme, createThemeContext, ThemeSwitcherContext, useScopedTheme, useStyles } from '@khanacademy/wonder-blocks-theming';
10
- import * as tokens from '@khanacademy/wonder-blocks-tokens';
10
+ import { focusStyles } from '@khanacademy/wonder-blocks-styles';
11
+ import { sizing, semanticColor, border, font, color } from '@khanacademy/wonder-blocks-tokens';
11
12
  import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
12
13
 
13
- const{semanticColor}=tokens;const textUnderlineOffset=tokens.sizing.size_040;const focusOutline={border:semanticColor.focus.outer};const theme$1={color:{primary:{progressive:{...semanticColor.action.primary.progressive,focus:focusOutline},destructive:{...semanticColor.action.primary.destructive,focus:focusOutline},disabled:semanticColor.action.primary.disabled},secondary:{progressive:{...semanticColor.action.secondary.progressive,focus:focusOutline,hover:{...semanticColor.action.secondary.progressive.hover,icon:"transparent"}},destructive:{...semanticColor.action.secondary.destructive,focus:focusOutline,hover:{...semanticColor.action.secondary.destructive.hover,icon:"transparent"}},disabled:{...semanticColor.action.secondary.disabled,border:semanticColor.action.primary.disabled.border}},tertiary:{progressive:{...semanticColor.action.tertiary.progressive,focus:focusOutline},destructive:{...semanticColor.action.tertiary.destructive,focus:focusOutline},disabled:semanticColor.action.tertiary.disabled}},border:{width:{secondary:tokens.border.width.thin,focused:tokens.border.width.medium,disabled:tokens.border.width.medium},offset:{primary:tokens.spacing.xxxxSmall_2,secondary:-tokens.spacing.xxxxSmall_2},radius:{default:tokens.border.radius.radius_040,small:tokens.border.radius.radius_040,large:tokens.border.radius.radius_040,icon:tokens.border.radius.radius_full}},size:{height:{small:tokens.spacing.xLarge_32,medium:40,large:56},underline:{hover:tokens.spacing.xxxxSmall_2,active:1}},margin:{icon:{offset:-tokens.spacing.xxxxSmall_2}},padding:{xsmall:tokens.spacing.xxxxSmall_2,small:tokens.spacing.xxSmall_6,medium:tokens.spacing.small_12,large:tokens.spacing.medium_16,xLarge:tokens.spacing.xLarge_32},font:{size:{large:"1.8rem"},lineHeight:{small:tokens.font.lineHeight.xMedium,default:tokens.font.lineHeight.large,large:"2.6rem"},weight:{default:tokens.font.weight.bold},offset:{default:textUnderlineOffset}}};
14
+ const textUnderlineOffset=sizing.size_040;const theme$1={root:{color:semanticColor.action,border:{width:{primary:{default:border.width.none,hover:border.width.medium,press:border.width.medium},secondary:{default:border.width.thin,hover:border.width.thin,press:border.width.thin},tertiary:{default:border.width.none,hover:border.width.medium,press:border.width.medium}},offset:{primary:border.width.medium,secondary:0,tertiary:0},radius:{small:border.radius.radius_040,medium:border.radius.radius_040,large:border.radius.radius_040}},sizing:{height:{small:sizing.size_320,medium:sizing.size_400,large:sizing.size_560},underline:{hover:sizing.size_020,press:sizing.size_010}},padding:{medium:sizing.size_160,large:sizing.size_320},font:{size:{large:"1.8rem"},lineHeight:{small:font.lineHeight.xMedium,default:font.lineHeight.large,large:"2.6rem"},weight:{default:font.weight.bold},offset:{default:textUnderlineOffset}}},icon:{color:{secondary:{progressive:{hover:{background:"transparent",foreground:semanticColor.action.secondary.progressive.hover.foreground}},destructive:{hover:{background:"transparent",foreground:semanticColor.action.secondary.destructive.hover.foreground}},neutral:{hover:{background:"transparent",foreground:semanticColor.action.secondary.neutral.hover.foreground}}}},border:{radius:border.radius.radius_full},margin:{inline:{inner:sizing.size_060,outer:`calc(-1 * ${border.width.medium})`}},padding:sizing.size_020}};
14
15
 
15
- const secondaryBgColor=tokens.color.offWhite;const theme=mergeTheme(theme$1,{color:{secondary:{progressive:{default:{border:tokens.color.fadedBlue,background:secondaryBgColor},hover:{background:secondaryBgColor,icon:tokens.color.fadedBlue16,foreground:tokens.semanticColor.action.secondary.progressive.default.foreground},press:{background:tokens.color.fadedBlue8}},destructive:{default:{border:tokens.color.fadedRed,background:secondaryBgColor},hover:{background:secondaryBgColor,icon:tokens.color.fadedRed16,foreground:tokens.semanticColor.action.secondary.destructive.default.foreground},press:{background:tokens.color.fadedRed8}}}},border:{radius:{default:tokens.border.radius.radius_120,small:tokens.border.radius.radius_080,large:tokens.border.radius.radius_120},width:{focused:tokens.border.width.thin}},margin:{icon:{offset:-tokens.spacing.xSmall_8}},font:{weight:{default:tokens.font.weight.regular}}});
16
+ const secondaryBgColor=color.offWhite;const theme=mergeTheme(theme$1,{root:{color:{secondary:{progressive:{default:{border:color.fadedBlue,background:secondaryBgColor},hover:{background:secondaryBgColor,foreground:semanticColor.action.secondary.progressive.default.foreground},press:{background:color.fadedBlue8}},destructive:{default:{border:color.fadedRed,background:secondaryBgColor},hover:{background:secondaryBgColor,foreground:semanticColor.action.secondary.destructive.default.foreground},press:{background:color.fadedRed8}}}},border:{radius:{medium:border.radius.radius_120,small:border.radius.radius_080,large:border.radius.radius_120}},font:{weight:{default:font.weight.regular}}},icon:{color:{secondary:{progressive:{hover:{background:color.fadedBlue16,foreground:semanticColor.action.secondary.progressive.default.foreground}},destructive:{hover:{background:color.fadedRed16,foreground:semanticColor.action.secondary.destructive.default.foreground}}}},border:{radius:border.radius.radius_full},margin:{inline:{outer:`calc(-1 * ${sizing.size_080})`}},padding:sizing.size_020}});
16
17
 
17
18
  const themes={default:theme$1,khanmigo:theme};const ButtonThemeContext=createThemeContext(theme$1);function ThemedButton(props){const currentTheme=React.useContext(ThemeSwitcherContext);const theme=themes[currentTheme]||theme$1;return jsx(ButtonThemeContext.Provider,{value:theme,children:props.children})}
18
19
 
19
20
  function ButtonIcon({icon,size,style,testId}){const commonProps={"aria-hidden":true,color:"currentColor",style:style,testId};switch(size){case"small":return jsx(PhosphorIcon,{...commonProps,size:"small",icon:icon});case"medium":default:return jsx(PhosphorIcon,{...commonProps,size:"medium",icon:icon})}}
20
21
 
21
- const StyledA=addStyle("a");const StyledButton=addStyle("button");const StyledLink=addStyle(Link);const ButtonCore=React.forwardRef(function ButtonCore(props,ref){const{theme,themeName}=useScopedTheme(ButtonThemeContext);const sharedStyles=useStyles(themedSharedStyles,theme);const inRouterContext=useInRouterContext();const{children,skipClientNav,color,disabled:disabledProp,focused,hovered,href=undefined,kind="primary",labelStyle,pressed,size="medium",style,testId,type=undefined,spinner,startIcon,endIcon,id,waiting:_,...restProps}=props;const buttonStyles=_generateStyles(color,kind,size,theme,themeName);const disabled=spinner||disabledProp;const defaultStyle=[sharedStyles.shared,disabled&&sharedStyles.disabled,startIcon&&sharedStyles.withStartIcon,endIcon&&sharedStyles.withEndIcon,buttonStyles.default,disabled&&buttonStyles.disabled,!disabled&&(pressed?buttonStyles.pressed:focused&&buttonStyles.focused),size==="small"&&sharedStyles.small,size==="large"&&sharedStyles.large];const commonProps={"data-testid":testId,id:id,role:"button",style:[defaultStyle,style],...restProps};const Label=size==="small"?LabelSmall:LabelLarge;const label=jsx(Label,{style:[sharedStyles.text,size==="small"&&sharedStyles.smallText,size==="large"&&sharedStyles.largeText,labelStyle,spinner&&sharedStyles.hiddenText,kind==="tertiary"&&sharedStyles.textWithFocus,kind==="tertiary"&&!disabled&&(pressed?[buttonStyles.hover,buttonStyles.active]:hovered&&buttonStyles.hover)],testId:testId?`${testId}-inner-label`:undefined,children:children});const sizeMapping={medium:"small",small:"xsmall",large:"medium"};const iconSize=size==="small"?"small":"medium";const contents=jsxs(React.Fragment,{children:[startIcon&&jsx(View,{style:sharedStyles.iconWrapper,children:jsx(ButtonIcon,{size:iconSize,icon:startIcon,style:[sharedStyles.startIcon,kind==="tertiary"&&sharedStyles.tertiaryStartIcon],testId:testId?`${testId}-start-icon`:undefined})}),label,spinner&&jsx(CircularSpinner,{style:sharedStyles.spinner,size:sizeMapping[size],light:kind==="primary",testId:`${testId||"button"}-spinner`}),endIcon&&jsx(View,{testId:testId?`${testId}-end-icon-wrapper`:undefined,style:[styles.endIcon,sharedStyles.iconWrapper,sharedStyles.endIconWrapper,kind==="tertiary"&&sharedStyles.endIconWrapperTertiary,!disabled&&(focused||hovered)&&kind!=="primary"&&buttonStyles.iconWrapperHovered],children:jsx(ButtonIcon,{size:iconSize,icon:endIcon,testId:testId?`${testId}-end-icon`:undefined})})]});if(href&&!disabled){return inRouterContext&&!skipClientNav&&isClientSideUrl(href)?jsx(StyledLink,{...commonProps,to:href,ref:ref,children:contents}):jsx(StyledA,{...commonProps,href:href,ref:ref,children:contents})}else {return jsx(StyledButton,{type:type||"button",...commonProps,"aria-disabled":disabled,ref:ref,children:contents})}});const themedSharedStyles=theme=>({shared:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",height:theme.size.height.medium,paddingTop:0,paddingBottom:0,paddingLeft:theme.padding.large,paddingRight:theme.padding.large,border:"none",borderRadius:theme.border.radius.default,cursor:"pointer",outline:"none",textDecoration:"none",boxSizing:"border-box",touchAction:"manipulation",userSelect:"none",":focus":{WebkitTapHighlightColor:"rgba(0,0,0,0)"}},disabled:{cursor:"auto"},small:{borderRadius:theme.border.radius.small,height:theme.size.height.small},large:{borderRadius:theme.border.radius.large,height:theme.size.height.large},text:{alignItems:"center",fontWeight:theme.font.weight.default,whiteSpace:"nowrap",overflow:"hidden",lineHeight:theme.font.lineHeight.default,textOverflow:"ellipsis",display:"inline-block",pointerEvents:"none"},smallText:{lineHeight:theme.font.lineHeight.small},largeText:{fontSize:theme.font.size.large,lineHeight:theme.font.lineHeight.large},textWithFocus:{position:"relative"},hiddenText:{visibility:"hidden"},spinner:{position:"absolute"},startIcon:{marginRight:theme.padding.small,marginLeft:theme.margin.icon.offset},tertiaryStartIcon:{marginLeft:0},endIcon:{marginLeft:theme.padding.small},iconWrapper:{borderRadius:theme.border.radius.icon,padding:theme.padding.xsmall,minWidth:"auto"},endIconWrapper:{marginLeft:theme.padding.small,marginRight:theme.margin.icon.offset},endIconWrapperTertiary:{marginRight:0}});const styles={};const _generateStyles=(buttonColor="default",kind,size,theme,themeName)=>{const buttonType=`${buttonColor}-${kind}-${size}-${themeName}`;if(styles[buttonType]){return styles[buttonType]}const padding=size==="large"?theme.padding.xLarge:theme.padding.large;const colorToAction=buttonColor==="destructive"?"destructive":"progressive";const disabledState=theme.color[kind].disabled;const disabledStateStyles={borderColor:disabledState.border,background:disabledState.background,color:disabledState.foreground};let newStyles={};if(kind==="primary"){const themeColorAction=theme.color.primary[colorToAction];const sharedFocusHoverStyling={outlineOffset:theme.border.offset.primary,outlineStyle:"solid",outlineWidth:theme.border.width.focused};const focusStyling={...sharedFocusHoverStyling,outlineColor:themeColorAction.focus.border};const hoverStyling={...sharedFocusHoverStyling,outlineColor:themeColorAction.hover.border};const activePressedStyling={background:themeColorAction.press.background,outlineColor:themeColorAction.press.border,outlineOffset:theme.border.offset.primary,outlineStyle:"solid",outlineWidth:theme.border.width.focused};newStyles={default:{background:themeColorAction.default.background,color:themeColorAction.default.foreground,paddingInline:padding,":hover":hoverStyling,":focus-visible":focusStyling,":active":activePressedStyling},focused:focusStyling,pressed:activePressedStyling,disabled:{...disabledStateStyles,cursor:"not-allowed",":hover":{...disabledStateStyles,outline:"none"},":active":{...disabledStateStyles,outline:"none"},":focus-visible":focusStyling}};}else if(kind==="secondary"){const themeColorAction=theme.color.secondary[colorToAction];const sharedFocusHoverStyling={background:themeColorAction.hover.background,outlineStyle:"solid",outlineOffset:theme.border.offset.secondary,outlineWidth:theme.border.width.focused};const focusStyling={...sharedFocusHoverStyling,outlineColor:themeColorAction.focus.border};const hoverStyling={...sharedFocusHoverStyling,borderColor:themeColorAction.hover.border};const activePressedStyling={background:themeColorAction.press.background,color:themeColorAction.press.foreground,outlineColor:themeColorAction.press.border,outlineStyle:"solid",outlineWidth:theme.border.width.focused};newStyles={default:{background:themeColorAction.default.background,color:themeColorAction.default.foreground,borderColor:themeColorAction.default.border,borderStyle:"solid",borderWidth:theme.border.width.secondary,paddingInline:padding,":hover":hoverStyling,":focus-visible":focusStyling,":active":activePressedStyling},focused:focusStyling,pressed:activePressedStyling,disabled:{...disabledStateStyles,cursor:"not-allowed",":hover":{...disabledStateStyles,outline:"none"},":active":{...disabledStateStyles,outline:"none"},":focus-visible":focusStyling},iconWrapperHovered:{backgroundColor:themeColorAction.hover.icon,color:themeColorAction.hover.foreground}};}else if(kind==="tertiary"){const themeColorAction=theme.color.tertiary[colorToAction];const focusStyling={outlineStyle:"solid",borderColor:"transparent",outlineColor:themeColorAction.focus.border,outlineWidth:theme.border.width.focused,borderRadius:theme.border.radius.default};const activePressedStyling={color:themeColorAction.press.foreground,textDecoration:"underline",textDecorationThickness:theme.size.underline.active,textUnderlineOffset:theme.font.offset.default};const sharedDisabledStyling={...disabledStateStyles,textDecoration:"none",textDecorationThickness:"unset",textUnderlineOffset:"unset",outline:"none"};newStyles={default:{background:themeColorAction.default.background,color:themeColorAction.default.foreground,paddingInline:0,":hover":{textUnderlineOffset:theme.font.offset.default,textDecoration:"underline",textDecorationThickness:theme.size.underline.hover},":focus-visible":focusStyling,":active":activePressedStyling},focused:focusStyling,pressed:activePressedStyling,disabled:{...disabledStateStyles,cursor:"not-allowed",":hover":sharedDisabledStyling,":active":sharedDisabledStyling,":focus-visible":focusStyling}};}else {throw new Error("Button kind not recognized")}styles[buttonType]=StyleSheet.create(newStyles);return styles[buttonType]};
22
+ const StyledA=addStyle("a");const StyledButton=addStyle("button");const StyledLink=addStyle(Link);const ButtonUnstyled=React.forwardRef(function ButtonUnstyled(props,ref){const{children,disabled,href,id,skipClientNav,style,testId,type,...restProps}=props;const commonProps={"data-testid":testId,id:id,role:"button",style:[styles$1.reset,style],...restProps};const inRouterContext=useInRouterContext();if(href&&!disabled){return inRouterContext&&!skipClientNav&&isClientSideUrl(href)?jsx(StyledLink,{...commonProps,to:href,ref:ref,children:children}):jsx(StyledA,{...commonProps,href:href,ref:ref,children:children})}else {return jsx(StyledButton,{type:type||"button",...commonProps,"aria-disabled":disabled,ref:ref,children:children})}});const styles$1=StyleSheet.create({reset:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",margin:0,padding:0,border:"none",cursor:"pointer",outline:"none",textDecoration:"none",boxSizing:"border-box",touchAction:"manipulation",userSelect:"none",":focus":{WebkitTapHighlightColor:"rgba(0,0,0,0)"}}});
22
23
 
23
- const Button=React.forwardRef(function Button(props,ref){const{href=undefined,type=undefined,children,skipClientNav,onClick,beforeNav=undefined,safeWithNav=undefined,tabIndex,target,rel,color="default",kind="primary",size="medium",disabled=false,spinner=false,...sharedButtonCoreProps}=props;const inRouterContext=useInRouterContext();const ClickableBehavior=getClickableBehavior(href,skipClientNav,inRouterContext);const renderProp=(state,restChildProps)=>{return jsx(ThemedButton,{children:jsx(ButtonCore,{...sharedButtonCoreProps,...state,...restChildProps,disabled:disabled,spinner:spinner||state.waiting,color:color,kind:kind,size:size,skipClientNav:skipClientNav,href:href,target:target,type:type,tabIndex:tabIndex,ref:ref,children:children})})};if(beforeNav){return jsx(ClickableBehavior,{disabled:spinner||disabled,href:href,role:"button",type:type,onClick:onClick,beforeNav:beforeNav,safeWithNav:safeWithNav,rel:rel,children:renderProp})}else {return jsx(ClickableBehavior,{disabled:spinner||disabled,href:href,role:"button",type:type,onClick:onClick,safeWithNav:safeWithNav,target:target,rel:rel,children:renderProp})}});
24
+ const ButtonCore=React.forwardRef(function ButtonCore(props,ref){const{theme,themeName}=useScopedTheme(ButtonThemeContext);const sharedStyles=useStyles(themedSharedStyles,theme);const{children,skipClientNav,actionType,disabled:disabledProp,focused,hovered,href=undefined,kind="primary",labelStyle,pressed,size="medium",style,testId,type=undefined,spinner,startIcon,endIcon,id,waiting:_,...restProps}=props;const buttonStyles=_generateStyles(actionType,kind,size,theme,themeName);const disabled=spinner||disabledProp;const defaultStyle=[sharedStyles.shared,startIcon&&sharedStyles.withStartIcon,endIcon&&sharedStyles.withEndIcon,buttonStyles.default,disabled&&buttonStyles.disabled,!disabled&&(pressed?buttonStyles.pressed:focused&&buttonStyles.focused),size==="small"&&sharedStyles.small,size==="large"&&sharedStyles.large];const Label=size==="small"?LabelSmall:LabelLarge;const label=jsx(Label,{style:[sharedStyles.text,size==="small"&&sharedStyles.smallText,size==="large"&&sharedStyles.largeText,labelStyle,spinner&&sharedStyles.hiddenText,kind==="tertiary"&&!disabled&&(pressed?[buttonStyles.hover,buttonStyles.active]:hovered&&buttonStyles.hover)],testId:testId?`${testId}-inner-label`:undefined,children:children});const sizeMapping={medium:"small",small:"xsmall",large:"medium"};const iconSize=size==="small"?"small":"medium";const contents=jsxs(React.Fragment,{children:[startIcon&&jsx(View,{style:sharedStyles.iconWrapper,children:jsx(ButtonIcon,{size:iconSize,icon:startIcon,style:[sharedStyles.startIcon,kind==="tertiary"&&sharedStyles.tertiaryStartIcon],testId:testId?`${testId}-start-icon`:undefined})}),label,spinner&&jsx(CircularSpinner,{style:sharedStyles.spinner,size:sizeMapping[size],light:kind==="primary",testId:`${testId||"button"}-spinner`}),endIcon&&jsx(View,{testId:testId?`${testId}-end-icon-wrapper`:undefined,style:[styles.endIcon,sharedStyles.iconWrapper,sharedStyles.endIconWrapper,kind==="tertiary"&&sharedStyles.endIconWrapperTertiary,!disabled&&(focused||hovered)&&kind!=="primary"&&buttonStyles.iconWrapperHovered],children:jsx(ButtonIcon,{size:iconSize,icon:endIcon,testId:testId?`${testId}-end-icon`:undefined})})]});return jsx(ButtonUnstyled,{...restProps,disabled:disabled,href:href,id:id,ref:ref,skipClientNav:skipClientNav,style:[defaultStyle,style],testId:testId,tabIndex:props.tabIndex,type:type,children:contents})});const themedSharedStyles=theme=>({shared:{height:theme.root.sizing.height.medium,paddingBlock:0,paddingInline:theme.root.padding.medium},small:{borderRadius:theme.root.border.radius.small,height:theme.root.sizing.height.small},large:{borderRadius:theme.root.border.radius.large,height:theme.root.sizing.height.large},text:{alignItems:"center",fontWeight:theme.root.font.weight.default,whiteSpace:"nowrap",overflow:"hidden",lineHeight:theme.root.font.lineHeight.default,textOverflow:"ellipsis",display:"inline-block",pointerEvents:"none"},smallText:{lineHeight:theme.root.font.lineHeight.small},largeText:{fontSize:theme.root.font.size.large,lineHeight:theme.root.font.lineHeight.large},hiddenText:{visibility:"hidden"},spinner:{position:"absolute"},startIcon:{marginInlineStart:theme.icon.margin.inline.outer,marginInlineEnd:theme.icon.margin.inline.inner},tertiaryStartIcon:{marginInlineStart:0},endIcon:{marginInlineStart:theme.icon.margin.inline.inner},iconWrapper:{borderRadius:theme.icon.border.radius,padding:theme.icon.padding,minWidth:"auto"},endIconWrapper:{marginInlineStart:theme.icon.margin.inline.inner,marginInlineEnd:theme.icon.margin.inline.outer},endIconWrapperTertiary:{marginInlineEnd:0}});const styles={};const _generateStyles=(actionType="progressive",kind,size,theme,themeName)=>{const buttonType=`${actionType}-${kind}-${size}-${themeName}`;if(styles[buttonType]){return styles[buttonType]}const padding=size==="large"?theme.root.padding.large:theme.root.padding.medium;const borderWidthKind=theme.root.border.width[kind];const outlineOffsetKind=theme.root.border.offset[kind];const themeVariant=theme.root.color[kind][actionType];const disabledState=theme.root.color[kind].disabled;const disabledStatesStyles={borderColor:disabledState.border,borderWidth:borderWidthKind.default,background:disabledState.background,color:disabledState.foreground};const disabledStatesOverrides={...disabledStatesStyles,outline:"none",boxShadow:"none",textDecoration:"none",textDecorationThickness:"unset",textUnderlineOffset:"unset"};const newStyles={default:{borderRadius:theme.root.border.radius[size],paddingInline:kind==="tertiary"?0:padding,borderStyle:"solid",borderWidth:borderWidthKind.default,borderColor:themeVariant.default.border,background:themeVariant.default.background,color:themeVariant.default.foreground,":hover":{background:themeVariant.hover.background,color:themeVariant.hover.foreground,...kind==="primary"?{outline:`${borderWidthKind.hover} solid ${themeVariant.hover.border}`,outlineOffset:outlineOffsetKind}:undefined,...kind==="secondary"?{borderColor:themeVariant.hover.border,boxShadow:`inset 0 0 0 ${borderWidthKind.hover} ${themeVariant.hover.border}`}:undefined,...kind==="tertiary"?{textDecoration:"underline",textUnderlineOffset:theme.root.font.offset.default,textDecorationThickness:theme.root.sizing.underline.hover}:undefined},["@media not (hover: hover)"]:{":hover":{backgroundColor:"transparent"}},":active":{background:themeVariant.press.background,color:themeVariant.press.foreground,...kind==="primary"?{outline:`${borderWidthKind.press} solid ${themeVariant.press.border}`,outlineOffset:outlineOffsetKind}:undefined,...kind==="secondary"?{borderColor:themeVariant.press.border,boxShadow:`inset 0 0 0 ${borderWidthKind.press} ${themeVariant.press.border}`}:undefined,...kind==="tertiary"?{textDecoration:"underline",textUnderlineOffset:theme.root.font.offset.default,textDecorationThickness:theme.root.sizing.underline.press}:undefined},...focusStyles.focus,...kind==="secondary"?{":focus-visible:hover":{...focusStyles.focus[":focus-visible"],boxShadow:`inset 0 0 0 ${borderWidthKind.hover} ${themeVariant.hover.border}, ${focusStyles.focus[":focus-visible"].boxShadow}`},":focus-visible:active":{...focusStyles.focus[":focus-visible"],boxShadow:`inset 0 0 0 ${borderWidthKind.press} ${themeVariant.press.border}, ${focusStyles.focus[":focus-visible"].boxShadow}`}}:{}},disabled:{cursor:"not-allowed",...disabledStatesStyles,":hover":disabledStatesOverrides,":active":disabledStatesOverrides,":focus-visible":disabledStatesStyles},iconWrapperHovered:{...kind==="secondary"?{backgroundColor:theme.icon.color[kind][actionType].hover.background,color:theme.icon.color[kind][actionType].hover.foreground}:undefined}};styles[buttonType]=StyleSheet.create(newStyles);return styles[buttonType]};
25
+
26
+ const Button=React.forwardRef(function Button(props,ref){const{href=undefined,type=undefined,children,skipClientNav,onClick,beforeNav=undefined,safeWithNav=undefined,tabIndex,target,rel,actionType="progressive",kind="primary",size="medium",disabled=false,spinner=false,...sharedButtonCoreProps}=props;const inRouterContext=useInRouterContext();const ClickableBehavior=getClickableBehavior(href,skipClientNav,inRouterContext);const extraClickableProps=beforeNav?{beforeNav}:{target};return jsx(ClickableBehavior,{disabled:spinner||disabled,href:href,role:"button",type:type,onClick:onClick,safeWithNav:safeWithNav,rel:rel,...extraClickableProps,children:(state,restChildProps)=>jsx(ThemedButton,{children:jsx(ButtonCore,{...sharedButtonCoreProps,...state,...restChildProps,disabled:disabled,spinner:spinner||state.waiting,actionType:actionType,kind:kind,size:size,skipClientNav:skipClientNav,href:href,target:target,type:type,tabIndex:tabIndex,ref:ref,children:children})})})});
24
27
 
25
28
  export { Button as default };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import Button from "./components/button";
2
- import type { SharedProps } from "./components/button";
3
- export type { SharedProps as ButtonProps };
2
+ import type { ButtonProps } from "./util/button.types";
3
+ export type { ButtonProps };
4
4
  export { Button as default };
package/dist/index.js CHANGED
@@ -9,7 +9,8 @@ var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
9
9
  var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
10
10
  var wonderBlocksProgressSpinner = require('@khanacademy/wonder-blocks-progress-spinner');
11
11
  var wonderBlocksTheming = require('@khanacademy/wonder-blocks-theming');
12
- var tokens = require('@khanacademy/wonder-blocks-tokens');
12
+ var wonderBlocksStyles = require('@khanacademy/wonder-blocks-styles');
13
+ var wonderBlocksTokens = require('@khanacademy/wonder-blocks-tokens');
13
14
  var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
14
15
 
15
16
  function _interopNamespace(e) {
@@ -31,18 +32,19 @@ function _interopNamespace(e) {
31
32
  }
32
33
 
33
34
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
34
- var tokens__namespace = /*#__PURE__*/_interopNamespace(tokens);
35
35
 
36
- const{semanticColor}=tokens__namespace;const textUnderlineOffset=tokens__namespace.sizing.size_040;const focusOutline={border:semanticColor.focus.outer};const theme$1={color:{primary:{progressive:{...semanticColor.action.primary.progressive,focus:focusOutline},destructive:{...semanticColor.action.primary.destructive,focus:focusOutline},disabled:semanticColor.action.primary.disabled},secondary:{progressive:{...semanticColor.action.secondary.progressive,focus:focusOutline,hover:{...semanticColor.action.secondary.progressive.hover,icon:"transparent"}},destructive:{...semanticColor.action.secondary.destructive,focus:focusOutline,hover:{...semanticColor.action.secondary.destructive.hover,icon:"transparent"}},disabled:{...semanticColor.action.secondary.disabled,border:semanticColor.action.primary.disabled.border}},tertiary:{progressive:{...semanticColor.action.tertiary.progressive,focus:focusOutline},destructive:{...semanticColor.action.tertiary.destructive,focus:focusOutline},disabled:semanticColor.action.tertiary.disabled}},border:{width:{secondary:tokens__namespace.border.width.thin,focused:tokens__namespace.border.width.medium,disabled:tokens__namespace.border.width.medium},offset:{primary:tokens__namespace.spacing.xxxxSmall_2,secondary:-tokens__namespace.spacing.xxxxSmall_2},radius:{default:tokens__namespace.border.radius.radius_040,small:tokens__namespace.border.radius.radius_040,large:tokens__namespace.border.radius.radius_040,icon:tokens__namespace.border.radius.radius_full}},size:{height:{small:tokens__namespace.spacing.xLarge_32,medium:40,large:56},underline:{hover:tokens__namespace.spacing.xxxxSmall_2,active:1}},margin:{icon:{offset:-tokens__namespace.spacing.xxxxSmall_2}},padding:{xsmall:tokens__namespace.spacing.xxxxSmall_2,small:tokens__namespace.spacing.xxSmall_6,medium:tokens__namespace.spacing.small_12,large:tokens__namespace.spacing.medium_16,xLarge:tokens__namespace.spacing.xLarge_32},font:{size:{large:"1.8rem"},lineHeight:{small:tokens__namespace.font.lineHeight.xMedium,default:tokens__namespace.font.lineHeight.large,large:"2.6rem"},weight:{default:tokens__namespace.font.weight.bold},offset:{default:textUnderlineOffset}}};
36
+ const textUnderlineOffset=wonderBlocksTokens.sizing.size_040;const theme$1={root:{color:wonderBlocksTokens.semanticColor.action,border:{width:{primary:{default:wonderBlocksTokens.border.width.none,hover:wonderBlocksTokens.border.width.medium,press:wonderBlocksTokens.border.width.medium},secondary:{default:wonderBlocksTokens.border.width.thin,hover:wonderBlocksTokens.border.width.thin,press:wonderBlocksTokens.border.width.thin},tertiary:{default:wonderBlocksTokens.border.width.none,hover:wonderBlocksTokens.border.width.medium,press:wonderBlocksTokens.border.width.medium}},offset:{primary:wonderBlocksTokens.border.width.medium,secondary:0,tertiary:0},radius:{small:wonderBlocksTokens.border.radius.radius_040,medium:wonderBlocksTokens.border.radius.radius_040,large:wonderBlocksTokens.border.radius.radius_040}},sizing:{height:{small:wonderBlocksTokens.sizing.size_320,medium:wonderBlocksTokens.sizing.size_400,large:wonderBlocksTokens.sizing.size_560},underline:{hover:wonderBlocksTokens.sizing.size_020,press:wonderBlocksTokens.sizing.size_010}},padding:{medium:wonderBlocksTokens.sizing.size_160,large:wonderBlocksTokens.sizing.size_320},font:{size:{large:"1.8rem"},lineHeight:{small:wonderBlocksTokens.font.lineHeight.xMedium,default:wonderBlocksTokens.font.lineHeight.large,large:"2.6rem"},weight:{default:wonderBlocksTokens.font.weight.bold},offset:{default:textUnderlineOffset}}},icon:{color:{secondary:{progressive:{hover:{background:"transparent",foreground:wonderBlocksTokens.semanticColor.action.secondary.progressive.hover.foreground}},destructive:{hover:{background:"transparent",foreground:wonderBlocksTokens.semanticColor.action.secondary.destructive.hover.foreground}},neutral:{hover:{background:"transparent",foreground:wonderBlocksTokens.semanticColor.action.secondary.neutral.hover.foreground}}}},border:{radius:wonderBlocksTokens.border.radius.radius_full},margin:{inline:{inner:wonderBlocksTokens.sizing.size_060,outer:`calc(-1 * ${wonderBlocksTokens.border.width.medium})`}},padding:wonderBlocksTokens.sizing.size_020}};
37
37
 
38
- const secondaryBgColor=tokens__namespace.color.offWhite;const theme=wonderBlocksTheming.mergeTheme(theme$1,{color:{secondary:{progressive:{default:{border:tokens__namespace.color.fadedBlue,background:secondaryBgColor},hover:{background:secondaryBgColor,icon:tokens__namespace.color.fadedBlue16,foreground:tokens__namespace.semanticColor.action.secondary.progressive.default.foreground},press:{background:tokens__namespace.color.fadedBlue8}},destructive:{default:{border:tokens__namespace.color.fadedRed,background:secondaryBgColor},hover:{background:secondaryBgColor,icon:tokens__namespace.color.fadedRed16,foreground:tokens__namespace.semanticColor.action.secondary.destructive.default.foreground},press:{background:tokens__namespace.color.fadedRed8}}}},border:{radius:{default:tokens__namespace.border.radius.radius_120,small:tokens__namespace.border.radius.radius_080,large:tokens__namespace.border.radius.radius_120},width:{focused:tokens__namespace.border.width.thin}},margin:{icon:{offset:-tokens__namespace.spacing.xSmall_8}},font:{weight:{default:tokens__namespace.font.weight.regular}}});
38
+ const secondaryBgColor=wonderBlocksTokens.color.offWhite;const theme=wonderBlocksTheming.mergeTheme(theme$1,{root:{color:{secondary:{progressive:{default:{border:wonderBlocksTokens.color.fadedBlue,background:secondaryBgColor},hover:{background:secondaryBgColor,foreground:wonderBlocksTokens.semanticColor.action.secondary.progressive.default.foreground},press:{background:wonderBlocksTokens.color.fadedBlue8}},destructive:{default:{border:wonderBlocksTokens.color.fadedRed,background:secondaryBgColor},hover:{background:secondaryBgColor,foreground:wonderBlocksTokens.semanticColor.action.secondary.destructive.default.foreground},press:{background:wonderBlocksTokens.color.fadedRed8}}}},border:{radius:{medium:wonderBlocksTokens.border.radius.radius_120,small:wonderBlocksTokens.border.radius.radius_080,large:wonderBlocksTokens.border.radius.radius_120}},font:{weight:{default:wonderBlocksTokens.font.weight.regular}}},icon:{color:{secondary:{progressive:{hover:{background:wonderBlocksTokens.color.fadedBlue16,foreground:wonderBlocksTokens.semanticColor.action.secondary.progressive.default.foreground}},destructive:{hover:{background:wonderBlocksTokens.color.fadedRed16,foreground:wonderBlocksTokens.semanticColor.action.secondary.destructive.default.foreground}}}},border:{radius:wonderBlocksTokens.border.radius.radius_full},margin:{inline:{outer:`calc(-1 * ${wonderBlocksTokens.sizing.size_080})`}},padding:wonderBlocksTokens.sizing.size_020}});
39
39
 
40
40
  const themes={default:theme$1,khanmigo:theme};const ButtonThemeContext=wonderBlocksTheming.createThemeContext(theme$1);function ThemedButton(props){const currentTheme=React__namespace.useContext(wonderBlocksTheming.ThemeSwitcherContext);const theme=themes[currentTheme]||theme$1;return jsxRuntime.jsx(ButtonThemeContext.Provider,{value:theme,children:props.children})}
41
41
 
42
42
  function ButtonIcon({icon,size,style,testId}){const commonProps={"aria-hidden":true,color:"currentColor",style:style,testId};switch(size){case"small":return jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{...commonProps,size:"small",icon:icon});case"medium":default:return jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{...commonProps,size:"medium",icon:icon})}}
43
43
 
44
- const StyledA=wonderBlocksCore.addStyle("a");const StyledButton=wonderBlocksCore.addStyle("button");const StyledLink=wonderBlocksCore.addStyle(reactRouterDomV5Compat.Link);const ButtonCore=React__namespace.forwardRef(function ButtonCore(props,ref){const{theme,themeName}=wonderBlocksTheming.useScopedTheme(ButtonThemeContext);const sharedStyles=wonderBlocksTheming.useStyles(themedSharedStyles,theme);const inRouterContext=reactRouterDomV5Compat.useInRouterContext();const{children,skipClientNav,color,disabled:disabledProp,focused,hovered,href=undefined,kind="primary",labelStyle,pressed,size="medium",style,testId,type=undefined,spinner,startIcon,endIcon,id,waiting:_,...restProps}=props;const buttonStyles=_generateStyles(color,kind,size,theme,themeName);const disabled=spinner||disabledProp;const defaultStyle=[sharedStyles.shared,disabled&&sharedStyles.disabled,startIcon&&sharedStyles.withStartIcon,endIcon&&sharedStyles.withEndIcon,buttonStyles.default,disabled&&buttonStyles.disabled,!disabled&&(pressed?buttonStyles.pressed:focused&&buttonStyles.focused),size==="small"&&sharedStyles.small,size==="large"&&sharedStyles.large];const commonProps={"data-testid":testId,id:id,role:"button",style:[defaultStyle,style],...restProps};const Label=size==="small"?wonderBlocksTypography.LabelSmall:wonderBlocksTypography.LabelLarge;const label=jsxRuntime.jsx(Label,{style:[sharedStyles.text,size==="small"&&sharedStyles.smallText,size==="large"&&sharedStyles.largeText,labelStyle,spinner&&sharedStyles.hiddenText,kind==="tertiary"&&sharedStyles.textWithFocus,kind==="tertiary"&&!disabled&&(pressed?[buttonStyles.hover,buttonStyles.active]:hovered&&buttonStyles.hover)],testId:testId?`${testId}-inner-label`:undefined,children:children});const sizeMapping={medium:"small",small:"xsmall",large:"medium"};const iconSize=size==="small"?"small":"medium";const contents=jsxRuntime.jsxs(React__namespace.Fragment,{children:[startIcon&&jsxRuntime.jsx(wonderBlocksCore.View,{style:sharedStyles.iconWrapper,children:jsxRuntime.jsx(ButtonIcon,{size:iconSize,icon:startIcon,style:[sharedStyles.startIcon,kind==="tertiary"&&sharedStyles.tertiaryStartIcon],testId:testId?`${testId}-start-icon`:undefined})}),label,spinner&&jsxRuntime.jsx(wonderBlocksProgressSpinner.CircularSpinner,{style:sharedStyles.spinner,size:sizeMapping[size],light:kind==="primary",testId:`${testId||"button"}-spinner`}),endIcon&&jsxRuntime.jsx(wonderBlocksCore.View,{testId:testId?`${testId}-end-icon-wrapper`:undefined,style:[styles.endIcon,sharedStyles.iconWrapper,sharedStyles.endIconWrapper,kind==="tertiary"&&sharedStyles.endIconWrapperTertiary,!disabled&&(focused||hovered)&&kind!=="primary"&&buttonStyles.iconWrapperHovered],children:jsxRuntime.jsx(ButtonIcon,{size:iconSize,icon:endIcon,testId:testId?`${testId}-end-icon`:undefined})})]});if(href&&!disabled){return inRouterContext&&!skipClientNav&&wonderBlocksClickable.isClientSideUrl(href)?jsxRuntime.jsx(StyledLink,{...commonProps,to:href,ref:ref,children:contents}):jsxRuntime.jsx(StyledA,{...commonProps,href:href,ref:ref,children:contents})}else {return jsxRuntime.jsx(StyledButton,{type:type||"button",...commonProps,"aria-disabled":disabled,ref:ref,children:contents})}});const themedSharedStyles=theme=>({shared:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",height:theme.size.height.medium,paddingTop:0,paddingBottom:0,paddingLeft:theme.padding.large,paddingRight:theme.padding.large,border:"none",borderRadius:theme.border.radius.default,cursor:"pointer",outline:"none",textDecoration:"none",boxSizing:"border-box",touchAction:"manipulation",userSelect:"none",":focus":{WebkitTapHighlightColor:"rgba(0,0,0,0)"}},disabled:{cursor:"auto"},small:{borderRadius:theme.border.radius.small,height:theme.size.height.small},large:{borderRadius:theme.border.radius.large,height:theme.size.height.large},text:{alignItems:"center",fontWeight:theme.font.weight.default,whiteSpace:"nowrap",overflow:"hidden",lineHeight:theme.font.lineHeight.default,textOverflow:"ellipsis",display:"inline-block",pointerEvents:"none"},smallText:{lineHeight:theme.font.lineHeight.small},largeText:{fontSize:theme.font.size.large,lineHeight:theme.font.lineHeight.large},textWithFocus:{position:"relative"},hiddenText:{visibility:"hidden"},spinner:{position:"absolute"},startIcon:{marginRight:theme.padding.small,marginLeft:theme.margin.icon.offset},tertiaryStartIcon:{marginLeft:0},endIcon:{marginLeft:theme.padding.small},iconWrapper:{borderRadius:theme.border.radius.icon,padding:theme.padding.xsmall,minWidth:"auto"},endIconWrapper:{marginLeft:theme.padding.small,marginRight:theme.margin.icon.offset},endIconWrapperTertiary:{marginRight:0}});const styles={};const _generateStyles=(buttonColor="default",kind,size,theme,themeName)=>{const buttonType=`${buttonColor}-${kind}-${size}-${themeName}`;if(styles[buttonType]){return styles[buttonType]}const padding=size==="large"?theme.padding.xLarge:theme.padding.large;const colorToAction=buttonColor==="destructive"?"destructive":"progressive";const disabledState=theme.color[kind].disabled;const disabledStateStyles={borderColor:disabledState.border,background:disabledState.background,color:disabledState.foreground};let newStyles={};if(kind==="primary"){const themeColorAction=theme.color.primary[colorToAction];const sharedFocusHoverStyling={outlineOffset:theme.border.offset.primary,outlineStyle:"solid",outlineWidth:theme.border.width.focused};const focusStyling={...sharedFocusHoverStyling,outlineColor:themeColorAction.focus.border};const hoverStyling={...sharedFocusHoverStyling,outlineColor:themeColorAction.hover.border};const activePressedStyling={background:themeColorAction.press.background,outlineColor:themeColorAction.press.border,outlineOffset:theme.border.offset.primary,outlineStyle:"solid",outlineWidth:theme.border.width.focused};newStyles={default:{background:themeColorAction.default.background,color:themeColorAction.default.foreground,paddingInline:padding,":hover":hoverStyling,":focus-visible":focusStyling,":active":activePressedStyling},focused:focusStyling,pressed:activePressedStyling,disabled:{...disabledStateStyles,cursor:"not-allowed",":hover":{...disabledStateStyles,outline:"none"},":active":{...disabledStateStyles,outline:"none"},":focus-visible":focusStyling}};}else if(kind==="secondary"){const themeColorAction=theme.color.secondary[colorToAction];const sharedFocusHoverStyling={background:themeColorAction.hover.background,outlineStyle:"solid",outlineOffset:theme.border.offset.secondary,outlineWidth:theme.border.width.focused};const focusStyling={...sharedFocusHoverStyling,outlineColor:themeColorAction.focus.border};const hoverStyling={...sharedFocusHoverStyling,borderColor:themeColorAction.hover.border};const activePressedStyling={background:themeColorAction.press.background,color:themeColorAction.press.foreground,outlineColor:themeColorAction.press.border,outlineStyle:"solid",outlineWidth:theme.border.width.focused};newStyles={default:{background:themeColorAction.default.background,color:themeColorAction.default.foreground,borderColor:themeColorAction.default.border,borderStyle:"solid",borderWidth:theme.border.width.secondary,paddingInline:padding,":hover":hoverStyling,":focus-visible":focusStyling,":active":activePressedStyling},focused:focusStyling,pressed:activePressedStyling,disabled:{...disabledStateStyles,cursor:"not-allowed",":hover":{...disabledStateStyles,outline:"none"},":active":{...disabledStateStyles,outline:"none"},":focus-visible":focusStyling},iconWrapperHovered:{backgroundColor:themeColorAction.hover.icon,color:themeColorAction.hover.foreground}};}else if(kind==="tertiary"){const themeColorAction=theme.color.tertiary[colorToAction];const focusStyling={outlineStyle:"solid",borderColor:"transparent",outlineColor:themeColorAction.focus.border,outlineWidth:theme.border.width.focused,borderRadius:theme.border.radius.default};const activePressedStyling={color:themeColorAction.press.foreground,textDecoration:"underline",textDecorationThickness:theme.size.underline.active,textUnderlineOffset:theme.font.offset.default};const sharedDisabledStyling={...disabledStateStyles,textDecoration:"none",textDecorationThickness:"unset",textUnderlineOffset:"unset",outline:"none"};newStyles={default:{background:themeColorAction.default.background,color:themeColorAction.default.foreground,paddingInline:0,":hover":{textUnderlineOffset:theme.font.offset.default,textDecoration:"underline",textDecorationThickness:theme.size.underline.hover},":focus-visible":focusStyling,":active":activePressedStyling},focused:focusStyling,pressed:activePressedStyling,disabled:{...disabledStateStyles,cursor:"not-allowed",":hover":sharedDisabledStyling,":active":sharedDisabledStyling,":focus-visible":focusStyling}};}else {throw new Error("Button kind not recognized")}styles[buttonType]=aphrodite.StyleSheet.create(newStyles);return styles[buttonType]};
44
+ const StyledA=wonderBlocksCore.addStyle("a");const StyledButton=wonderBlocksCore.addStyle("button");const StyledLink=wonderBlocksCore.addStyle(reactRouterDomV5Compat.Link);const ButtonUnstyled=React__namespace.forwardRef(function ButtonUnstyled(props,ref){const{children,disabled,href,id,skipClientNav,style,testId,type,...restProps}=props;const commonProps={"data-testid":testId,id:id,role:"button",style:[styles$1.reset,style],...restProps};const inRouterContext=reactRouterDomV5Compat.useInRouterContext();if(href&&!disabled){return inRouterContext&&!skipClientNav&&wonderBlocksClickable.isClientSideUrl(href)?jsxRuntime.jsx(StyledLink,{...commonProps,to:href,ref:ref,children:children}):jsxRuntime.jsx(StyledA,{...commonProps,href:href,ref:ref,children:children})}else {return jsxRuntime.jsx(StyledButton,{type:type||"button",...commonProps,"aria-disabled":disabled,ref:ref,children:children})}});const styles$1=aphrodite.StyleSheet.create({reset:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",margin:0,padding:0,border:"none",cursor:"pointer",outline:"none",textDecoration:"none",boxSizing:"border-box",touchAction:"manipulation",userSelect:"none",":focus":{WebkitTapHighlightColor:"rgba(0,0,0,0)"}}});
45
45
 
46
- const Button=React__namespace.forwardRef(function Button(props,ref){const{href=undefined,type=undefined,children,skipClientNav,onClick,beforeNav=undefined,safeWithNav=undefined,tabIndex,target,rel,color="default",kind="primary",size="medium",disabled=false,spinner=false,...sharedButtonCoreProps}=props;const inRouterContext=reactRouterDomV5Compat.useInRouterContext();const ClickableBehavior=wonderBlocksClickable.getClickableBehavior(href,skipClientNav,inRouterContext);const renderProp=(state,restChildProps)=>{return jsxRuntime.jsx(ThemedButton,{children:jsxRuntime.jsx(ButtonCore,{...sharedButtonCoreProps,...state,...restChildProps,disabled:disabled,spinner:spinner||state.waiting,color:color,kind:kind,size:size,skipClientNav:skipClientNav,href:href,target:target,type:type,tabIndex:tabIndex,ref:ref,children:children})})};if(beforeNav){return jsxRuntime.jsx(ClickableBehavior,{disabled:spinner||disabled,href:href,role:"button",type:type,onClick:onClick,beforeNav:beforeNav,safeWithNav:safeWithNav,rel:rel,children:renderProp})}else {return jsxRuntime.jsx(ClickableBehavior,{disabled:spinner||disabled,href:href,role:"button",type:type,onClick:onClick,safeWithNav:safeWithNav,target:target,rel:rel,children:renderProp})}});
46
+ const ButtonCore=React__namespace.forwardRef(function ButtonCore(props,ref){const{theme,themeName}=wonderBlocksTheming.useScopedTheme(ButtonThemeContext);const sharedStyles=wonderBlocksTheming.useStyles(themedSharedStyles,theme);const{children,skipClientNav,actionType,disabled:disabledProp,focused,hovered,href=undefined,kind="primary",labelStyle,pressed,size="medium",style,testId,type=undefined,spinner,startIcon,endIcon,id,waiting:_,...restProps}=props;const buttonStyles=_generateStyles(actionType,kind,size,theme,themeName);const disabled=spinner||disabledProp;const defaultStyle=[sharedStyles.shared,startIcon&&sharedStyles.withStartIcon,endIcon&&sharedStyles.withEndIcon,buttonStyles.default,disabled&&buttonStyles.disabled,!disabled&&(pressed?buttonStyles.pressed:focused&&buttonStyles.focused),size==="small"&&sharedStyles.small,size==="large"&&sharedStyles.large];const Label=size==="small"?wonderBlocksTypography.LabelSmall:wonderBlocksTypography.LabelLarge;const label=jsxRuntime.jsx(Label,{style:[sharedStyles.text,size==="small"&&sharedStyles.smallText,size==="large"&&sharedStyles.largeText,labelStyle,spinner&&sharedStyles.hiddenText,kind==="tertiary"&&!disabled&&(pressed?[buttonStyles.hover,buttonStyles.active]:hovered&&buttonStyles.hover)],testId:testId?`${testId}-inner-label`:undefined,children:children});const sizeMapping={medium:"small",small:"xsmall",large:"medium"};const iconSize=size==="small"?"small":"medium";const contents=jsxRuntime.jsxs(React__namespace.Fragment,{children:[startIcon&&jsxRuntime.jsx(wonderBlocksCore.View,{style:sharedStyles.iconWrapper,children:jsxRuntime.jsx(ButtonIcon,{size:iconSize,icon:startIcon,style:[sharedStyles.startIcon,kind==="tertiary"&&sharedStyles.tertiaryStartIcon],testId:testId?`${testId}-start-icon`:undefined})}),label,spinner&&jsxRuntime.jsx(wonderBlocksProgressSpinner.CircularSpinner,{style:sharedStyles.spinner,size:sizeMapping[size],light:kind==="primary",testId:`${testId||"button"}-spinner`}),endIcon&&jsxRuntime.jsx(wonderBlocksCore.View,{testId:testId?`${testId}-end-icon-wrapper`:undefined,style:[styles.endIcon,sharedStyles.iconWrapper,sharedStyles.endIconWrapper,kind==="tertiary"&&sharedStyles.endIconWrapperTertiary,!disabled&&(focused||hovered)&&kind!=="primary"&&buttonStyles.iconWrapperHovered],children:jsxRuntime.jsx(ButtonIcon,{size:iconSize,icon:endIcon,testId:testId?`${testId}-end-icon`:undefined})})]});return jsxRuntime.jsx(ButtonUnstyled,{...restProps,disabled:disabled,href:href,id:id,ref:ref,skipClientNav:skipClientNav,style:[defaultStyle,style],testId:testId,tabIndex:props.tabIndex,type:type,children:contents})});const themedSharedStyles=theme=>({shared:{height:theme.root.sizing.height.medium,paddingBlock:0,paddingInline:theme.root.padding.medium},small:{borderRadius:theme.root.border.radius.small,height:theme.root.sizing.height.small},large:{borderRadius:theme.root.border.radius.large,height:theme.root.sizing.height.large},text:{alignItems:"center",fontWeight:theme.root.font.weight.default,whiteSpace:"nowrap",overflow:"hidden",lineHeight:theme.root.font.lineHeight.default,textOverflow:"ellipsis",display:"inline-block",pointerEvents:"none"},smallText:{lineHeight:theme.root.font.lineHeight.small},largeText:{fontSize:theme.root.font.size.large,lineHeight:theme.root.font.lineHeight.large},hiddenText:{visibility:"hidden"},spinner:{position:"absolute"},startIcon:{marginInlineStart:theme.icon.margin.inline.outer,marginInlineEnd:theme.icon.margin.inline.inner},tertiaryStartIcon:{marginInlineStart:0},endIcon:{marginInlineStart:theme.icon.margin.inline.inner},iconWrapper:{borderRadius:theme.icon.border.radius,padding:theme.icon.padding,minWidth:"auto"},endIconWrapper:{marginInlineStart:theme.icon.margin.inline.inner,marginInlineEnd:theme.icon.margin.inline.outer},endIconWrapperTertiary:{marginInlineEnd:0}});const styles={};const _generateStyles=(actionType="progressive",kind,size,theme,themeName)=>{const buttonType=`${actionType}-${kind}-${size}-${themeName}`;if(styles[buttonType]){return styles[buttonType]}const padding=size==="large"?theme.root.padding.large:theme.root.padding.medium;const borderWidthKind=theme.root.border.width[kind];const outlineOffsetKind=theme.root.border.offset[kind];const themeVariant=theme.root.color[kind][actionType];const disabledState=theme.root.color[kind].disabled;const disabledStatesStyles={borderColor:disabledState.border,borderWidth:borderWidthKind.default,background:disabledState.background,color:disabledState.foreground};const disabledStatesOverrides={...disabledStatesStyles,outline:"none",boxShadow:"none",textDecoration:"none",textDecorationThickness:"unset",textUnderlineOffset:"unset"};const newStyles={default:{borderRadius:theme.root.border.radius[size],paddingInline:kind==="tertiary"?0:padding,borderStyle:"solid",borderWidth:borderWidthKind.default,borderColor:themeVariant.default.border,background:themeVariant.default.background,color:themeVariant.default.foreground,":hover":{background:themeVariant.hover.background,color:themeVariant.hover.foreground,...kind==="primary"?{outline:`${borderWidthKind.hover} solid ${themeVariant.hover.border}`,outlineOffset:outlineOffsetKind}:undefined,...kind==="secondary"?{borderColor:themeVariant.hover.border,boxShadow:`inset 0 0 0 ${borderWidthKind.hover} ${themeVariant.hover.border}`}:undefined,...kind==="tertiary"?{textDecoration:"underline",textUnderlineOffset:theme.root.font.offset.default,textDecorationThickness:theme.root.sizing.underline.hover}:undefined},["@media not (hover: hover)"]:{":hover":{backgroundColor:"transparent"}},":active":{background:themeVariant.press.background,color:themeVariant.press.foreground,...kind==="primary"?{outline:`${borderWidthKind.press} solid ${themeVariant.press.border}`,outlineOffset:outlineOffsetKind}:undefined,...kind==="secondary"?{borderColor:themeVariant.press.border,boxShadow:`inset 0 0 0 ${borderWidthKind.press} ${themeVariant.press.border}`}:undefined,...kind==="tertiary"?{textDecoration:"underline",textUnderlineOffset:theme.root.font.offset.default,textDecorationThickness:theme.root.sizing.underline.press}:undefined},...wonderBlocksStyles.focusStyles.focus,...kind==="secondary"?{":focus-visible:hover":{...wonderBlocksStyles.focusStyles.focus[":focus-visible"],boxShadow:`inset 0 0 0 ${borderWidthKind.hover} ${themeVariant.hover.border}, ${wonderBlocksStyles.focusStyles.focus[":focus-visible"].boxShadow}`},":focus-visible:active":{...wonderBlocksStyles.focusStyles.focus[":focus-visible"],boxShadow:`inset 0 0 0 ${borderWidthKind.press} ${themeVariant.press.border}, ${wonderBlocksStyles.focusStyles.focus[":focus-visible"].boxShadow}`}}:{}},disabled:{cursor:"not-allowed",...disabledStatesStyles,":hover":disabledStatesOverrides,":active":disabledStatesOverrides,":focus-visible":disabledStatesStyles},iconWrapperHovered:{...kind==="secondary"?{backgroundColor:theme.icon.color[kind][actionType].hover.background,color:theme.icon.color[kind][actionType].hover.foreground}:undefined}};styles[buttonType]=aphrodite.StyleSheet.create(newStyles);return styles[buttonType]};
47
+
48
+ const Button=React__namespace.forwardRef(function Button(props,ref){const{href=undefined,type=undefined,children,skipClientNav,onClick,beforeNav=undefined,safeWithNav=undefined,tabIndex,target,rel,actionType="progressive",kind="primary",size="medium",disabled=false,spinner=false,...sharedButtonCoreProps}=props;const inRouterContext=reactRouterDomV5Compat.useInRouterContext();const ClickableBehavior=wonderBlocksClickable.getClickableBehavior(href,skipClientNav,inRouterContext);const extraClickableProps=beforeNav?{beforeNav}:{target};return jsxRuntime.jsx(ClickableBehavior,{disabled:spinner||disabled,href:href,role:"button",type:type,onClick:onClick,safeWithNav:safeWithNav,rel:rel,...extraClickableProps,children:(state,restChildProps)=>jsxRuntime.jsx(ThemedButton,{children:jsxRuntime.jsx(ButtonCore,{...sharedButtonCoreProps,...state,...restChildProps,disabled:disabled,spinner:spinner||state.waiting,actionType:actionType,kind:kind,size:size,skipClientNav:skipClientNav,href:href,target:target,type:type,tabIndex:tabIndex,ref:ref,children:children})})})});
47
49
 
48
50
  module.exports = Button;