@box/blueprint-web 7.20.0 → 7.22.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.
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { type IconDualStateButtonProps } from './types';
3
+ export declare const IconDualStateButton: import("react").ForwardRefExoticComponent<Omit<IconDualStateButtonProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,60 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { Button } from '@ariakit/react';
3
+ import { IconIconBlue, IconIconOnLightSecondary, Size4, Size5, Size6 } from '@box/blueprint-web-assets/tokens/tokens';
4
+ import clsx from 'clsx';
5
+ import { forwardRef, createElement } from 'react';
6
+ import { composeEventHandlers } from '../utils/composeEventHandlers.js';
7
+ import { useControllableState } from '../utils/useControllableState.js';
8
+ import styles from './icon-dual-state-button.module.js';
9
+
10
+ const buttonSizeToIconSize = {
11
+ xsmall: Size4,
12
+ small: Size5,
13
+ medium: Size6
14
+ };
15
+ const renderIcon = (icon, size, color) => /*#__PURE__*/createElement(icon, {
16
+ width: size,
17
+ height: size,
18
+ color,
19
+ role: 'presentation'
20
+ });
21
+ const IconDualStateButton = /*#__PURE__*/forwardRef(({
22
+ onStateAriaLabel,
23
+ offStateAriaLabel,
24
+ pressed: pressedProp,
25
+ defaultPressed = false,
26
+ onPressedChange,
27
+ disabled,
28
+ onClick,
29
+ iconOn,
30
+ iconOff,
31
+ size = 'medium',
32
+ ...rest
33
+ }, ref) => {
34
+ const [pressed = false, setPressed] = useControllableState({
35
+ prop: pressedProp,
36
+ onChange: onPressedChange,
37
+ defaultProp: defaultPressed
38
+ });
39
+ const iconSize = buttonSizeToIconSize[size];
40
+ return jsx(Button, {
41
+ ...rest,
42
+ ref: ref,
43
+ "aria-label": pressed ? onStateAriaLabel : offStateAriaLabel,
44
+ className: clsx(styles.iconDualStateButton, styles[`${size}Button`], {
45
+ [styles.pressed]: pressed
46
+ }),
47
+ "data-disabled": disabled ? '' : undefined,
48
+ "data-state": pressed ? 'on' : 'off',
49
+ disabled: disabled,
50
+ onClick: composeEventHandlers(onClick, () => {
51
+ if (!disabled) {
52
+ setPressed(!pressed);
53
+ }
54
+ }),
55
+ children: pressed ? renderIcon(iconOn, iconSize, IconIconBlue) : renderIcon(iconOff, iconSize, IconIconOnLightSecondary)
56
+ });
57
+ });
58
+ IconDualStateButton.displayName = 'IconDualStateButton';
59
+
60
+ export { IconDualStateButton };
@@ -0,0 +1,4 @@
1
+ import '../index.css';
2
+ var styles = {"iconDualStateButton":"bp_icon_dual_state_button_module_iconDualStateButton--c18d4","pressed":"bp_icon_dual_state_button_module_pressed--c18d4","xsmallButton":"bp_icon_dual_state_button_module_xsmallButton--c18d4","smallButton":"bp_icon_dual_state_button_module_smallButton--c18d4"};
3
+
4
+ export { styles as default };
@@ -0,0 +1,2 @@
1
+ export { IconDualStateButton } from './icon-dual-state-button';
2
+ export type { IconDualStateButtonProps } from './types';
@@ -0,0 +1,41 @@
1
+ import { type ButtonProps as AriakitButtonProps } from '@ariakit/react';
2
+ import { type FunctionComponent, type PropsWithChildren, type SVGProps } from 'react';
3
+ export declare const IconDualStateButtonSizes: readonly ["xsmall", "small", "medium"];
4
+ export interface IconDualStateButtonProps extends AriakitButtonProps {
5
+ /**
6
+ * Size of the button.
7
+ *
8
+ * @default 'medium'
9
+ */
10
+ size?: (typeof IconDualStateButtonSizes)[number];
11
+ /**
12
+ * The aria-label for the button in the ON state (pressed).
13
+ */
14
+ onStateAriaLabel: string;
15
+ /**
16
+ * The aria-label for the button in the OFF state.
17
+ */
18
+ offStateAriaLabel: string;
19
+ /**
20
+ * The icon to show when the button is in the ON state (pressed).
21
+ */
22
+ iconOn: FunctionComponent<PropsWithChildren<SVGProps<SVGSVGElement>>>;
23
+ /**
24
+ * The icon to show when the button is in the OFF state.
25
+ */
26
+ iconOff: FunctionComponent<PropsWithChildren<SVGProps<SVGSVGElement>>>;
27
+ /**
28
+ * The uncontrolled pressed state of the dual state button when initially rendered. Use `defaultPressed`
29
+ * if you do not need to control the state of the button.
30
+ * @defaultValue false
31
+ */
32
+ defaultPressed?: boolean;
33
+ /**
34
+ * The controlled state of the dual state button.
35
+ */
36
+ pressed?: boolean;
37
+ /**
38
+ * The callback that fires when the state of the button changes.
39
+ */
40
+ onPressedChange?(pressed: boolean): void;
41
+ }
package/lib-esm/index.css CHANGED
@@ -3398,6 +3398,72 @@
3398
3398
  margin-block-start:var(--space-5);
3399
3399
  width:100%;
3400
3400
  }
3401
+
3402
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4{
3403
+ align-items:center;
3404
+ background-color:initial;
3405
+ border-radius:var(--radius-1);
3406
+ border-style:none;
3407
+ cursor:pointer;
3408
+ display:flex;
3409
+ font-family:Lato, -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
3410
+ font-size:.875rem;
3411
+ font-weight:400;
3412
+ height:var(--size-10);
3413
+ justify-content:center;
3414
+ letter-spacing:.01875rem;
3415
+ line-height:1.25rem;
3416
+ padding:0;
3417
+ text-decoration:none;
3418
+ text-transform:none;
3419
+ width:var(--size-10);
3420
+ }
3421
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4:disabled{
3422
+ opacity:.3;
3423
+ pointer-events:none;
3424
+ }
3425
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4:hover{
3426
+ background:var(--surface-toggle-surface-off-hover);
3427
+ }
3428
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4:active{
3429
+ background:var(--surface-toggle-surface-off-pressed);
3430
+ }
3431
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4[data-focus-visible]{
3432
+ background:var(--surface-toggle-surface-off-hover);
3433
+ outline:var(--border-2) solid var(--outline-focus-on-light);
3434
+ }
3435
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4[data-focus-visible]:active{
3436
+ background:var(--surface-toggle-surface-off-pressed);
3437
+ }
3438
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4.bp_icon_dual_state_button_module_pressed--c18d4{
3439
+ background:var(--surface-toggle-surface-on);
3440
+ border:var(--border-1) solid var(--border-toggle-border-on);
3441
+ color:var(--icon-icon-blue);
3442
+ }
3443
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4.bp_icon_dual_state_button_module_pressed--c18d4:hover{
3444
+ background:var(--surface-toggle-surface-on-hover);
3445
+ }
3446
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4.bp_icon_dual_state_button_module_pressed--c18d4:active{
3447
+ background:var(--surface-toggle-surface-on-pressed);
3448
+ }
3449
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4.bp_icon_dual_state_button_module_pressed--c18d4[data-focus-visible]{
3450
+ background:var(--surface-toggle-surface-on-hover);
3451
+ border:var(--border-1) solid #fff;
3452
+ outline:var(--border-2) solid var(--outline-focus-on-light);
3453
+ }
3454
+ .bp_icon_dual_state_button_module_iconDualStateButton--c18d4.bp_icon_dual_state_button_module_pressed--c18d4[data-focus-visible]:active{
3455
+ background:var(--surface-toggle-surface-on-pressed);
3456
+ }
3457
+
3458
+ .bp_icon_dual_state_button_module_xsmallButton--c18d4{
3459
+ height:var(--size-6);
3460
+ width:var(--size-6);
3461
+ }
3462
+
3463
+ .bp_icon_dual_state_button_module_smallButton--c18d4{
3464
+ height:var(--size-8);
3465
+ width:var(--size-8);
3466
+ }
3401
3467
  table.bp_inline_table_module_inlineTable--b023b{
3402
3468
  background:var(--gray-white);
3403
3469
  border:var(--border-1) solid var(--gray-10);
@@ -18,6 +18,7 @@ export * from './empty-state';
18
18
  export * from './ghost';
19
19
  export * from './grid-list-item';
20
20
  export * from './guided-tooltip';
21
+ export * from './icon-dual-state-button';
21
22
  export * from './inline-notice/inline-notice';
22
23
  export * from './inline-table/inline-table';
23
24
  export * from './input-chip';
package/lib-esm/index.js CHANGED
@@ -22,6 +22,7 @@ export { Ghost } from './ghost/ghost.js';
22
22
  export { GridList } from './grid-list-item/index.js';
23
23
  export { GuidedTooltip } from './guided-tooltip/guided-tooltip.js';
24
24
  export { GuidedTooltipContext } from './guided-tooltip/utils/guided-tooltip-context.js';
25
+ export { IconDualStateButton } from './icon-dual-state-button/icon-dual-state-button.js';
25
26
  export { InlineNotice } from './inline-notice/inline-notice.js';
26
27
  export { InlineTable } from './inline-table/inline-table.js';
27
28
  export { InputChip } from './input-chip/input-chip.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@box/blueprint-web",
3
- "version": "7.20.0",
3
+ "version": "7.22.0",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "publishConfig": {
@@ -15,10 +15,7 @@
15
15
  "scripts": {
16
16
  "build-storybook": "nx run blueprint-web:build-storybook",
17
17
  "prepare": "nx run blueprint-web:prepare",
18
- "test-storybook": "test-storybook --watch --url http://localhost:4400",
19
- "bp-score-fetch-repos": "sh tools/bp-score/fetch-repos.sh",
20
- "bp-score-full": "sh tools/bp-score/fetch-repos.sh && sh tools/bp-score/bp-score.sh",
21
- "bp-score": "sh tools/bp-score/bp-score.sh"
18
+ "test-storybook": "test-storybook --watch --url http://localhost:4400"
22
19
  },
23
20
  "sideEffects": [
24
21
  "**/*.css",
@@ -66,7 +63,7 @@
66
63
  "react-stately": "^3.31.1",
67
64
  "tsx": "^4.16.5"
68
65
  },
69
- "gitHead": "194653f3af1b0b647738e4ee473940cad442bee8",
66
+ "gitHead": "31fd57a978e09716c6f7e46863c4fef7765130ce",
70
67
  "module": "lib-esm/index.js",
71
68
  "main": "lib-esm/index.js",
72
69
  "exports": {