@box/blueprint-web 7.10.3 → 7.13.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/lib-esm/index.css +89 -35
- package/lib-esm/index.d.ts +1 -0
- package/lib-esm/index.js +1 -0
- package/lib-esm/primitives/icon-button/icon-button.js +5 -5
- package/lib-esm/primitives/icon-button/icon-button.module.js +1 -1
- package/lib-esm/primitives/icon-button/types.d.ts +9 -5
- package/lib-esm/primitives/icon-button/utils.d.ts +2 -2
- package/lib-esm/primitives/icon-button/utils.js +1 -7
- package/lib-esm/text-toggle-button/index.d.ts +2 -0
- package/lib-esm/text-toggle-button/text-toggle-button.d.ts +3 -0
- package/lib-esm/text-toggle-button/text-toggle-button.js +40 -0
- package/lib-esm/text-toggle-button/text-toggle-button.module.js +4 -0
- package/lib-esm/text-toggle-button/types.d.ts +21 -0
- package/lib-esm/utils/composeEventHandlers.d.ts +4 -0
- package/lib-esm/utils/composeEventHandlers.js +13 -0
- package/lib-esm/utils/useCallbackRef.d.ts +6 -0
- package/lib-esm/utils/useCallbackRef.js +18 -0
- package/lib-esm/utils/useControllableState.d.ts +8 -0
- package/lib-esm/utils/useControllableState.js +48 -0
- package/package.json +3 -3
package/lib-esm/index.css
CHANGED
|
@@ -1134,10 +1134,8 @@
|
|
|
1134
1134
|
cursor:default;
|
|
1135
1135
|
}
|
|
1136
1136
|
|
|
1137
|
-
.bp_icon_button_module_iconButton--
|
|
1137
|
+
.bp_icon_button_module_iconButton--b6e1c{
|
|
1138
1138
|
align-items:center;
|
|
1139
|
-
background:var(--surface-cta-surface-icon);
|
|
1140
|
-
border:0;
|
|
1141
1139
|
border-radius:var(--radius-2);
|
|
1142
1140
|
border-style:none;
|
|
1143
1141
|
cursor:pointer;
|
|
@@ -1145,82 +1143,94 @@
|
|
|
1145
1143
|
justify-content:center;
|
|
1146
1144
|
padding:0;
|
|
1147
1145
|
}
|
|
1148
|
-
.bp_icon_button_module_iconButton--
|
|
1149
|
-
fill:var(--icon-cta-icon);
|
|
1150
|
-
}
|
|
1151
|
-
.bp_icon_button_module_iconButton--a3df7[aria-disabled=true]{
|
|
1146
|
+
.bp_icon_button_module_iconButton--b6e1c[aria-disabled=true]{
|
|
1152
1147
|
background:var(--surface-cta-surface-icon-disabled);
|
|
1153
1148
|
opacity:.3;
|
|
1154
1149
|
}
|
|
1155
|
-
.bp_icon_button_module_iconButton--
|
|
1150
|
+
.bp_icon_button_module_iconButton--b6e1c[aria-disabled=true] .bp_icon_button_module_icon--b6e1c *{
|
|
1156
1151
|
fill:var(--gray-50);
|
|
1157
1152
|
}
|
|
1158
|
-
.bp_icon_button_module_iconButton--
|
|
1153
|
+
.bp_icon_button_module_iconButton--b6e1c:focus-visible{
|
|
1159
1154
|
outline:none;
|
|
1160
1155
|
}
|
|
1161
|
-
.bp_icon_button_module_iconButton--
|
|
1156
|
+
.bp_icon_button_module_iconButton--b6e1c[data-focus-visible]{
|
|
1162
1157
|
outline:var(--border-2) solid var(--outline-focus-on-light);
|
|
1163
1158
|
}
|
|
1164
|
-
.bp_icon_button_module_iconButton--
|
|
1159
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c{
|
|
1160
|
+
background:var(--surface-cta-surface-icon);
|
|
1161
|
+
}
|
|
1162
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c .bp_icon_button_module_icon--b6e1c *{
|
|
1163
|
+
fill:var(--icon-cta-icon);
|
|
1164
|
+
}
|
|
1165
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c:hover,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c[data-focus-visible]{
|
|
1165
1166
|
background:var(--surface-cta-surface-icon-hover);
|
|
1166
1167
|
}
|
|
1167
|
-
.bp_icon_button_module_iconButton--
|
|
1168
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c:hover .bp_icon_button_module_icon--b6e1c *,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c[data-focus-visible] .bp_icon_button_module_icon--b6e1c *{
|
|
1168
1169
|
fill:var(--icon-cta-icon-hover);
|
|
1169
1170
|
}
|
|
1170
|
-
.bp_icon_button_module_iconButton--
|
|
1171
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c:active,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c[data-active]{
|
|
1171
1172
|
background:var(--surface-cta-surface-icon-pressed);
|
|
1172
1173
|
}
|
|
1173
|
-
.bp_icon_button_module_iconButton--
|
|
1174
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c:active .bp_icon_button_module_icon--b6e1c *,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_default--b6e1c[data-active] .bp_icon_button_module_icon--b6e1c *{
|
|
1174
1175
|
fill:var(--icon-cta-icon-pressed);
|
|
1175
1176
|
}
|
|
1176
|
-
.bp_icon_button_module_iconButton--
|
|
1177
|
-
|
|
1178
|
-
width:var(--size-10);
|
|
1177
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_icon-logo--b6e1c{
|
|
1178
|
+
background:var(--surface-cta-surface-icon);
|
|
1179
1179
|
}
|
|
1180
|
-
.bp_icon_button_module_iconButton--
|
|
1181
|
-
|
|
1182
|
-
width:var(--size-8);
|
|
1180
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_icon-logo--b6e1c:hover,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_icon-logo--b6e1c[data-focus-visible]{
|
|
1181
|
+
background:var(--surface-cta-surface-icon-hover);
|
|
1183
1182
|
}
|
|
1184
|
-
.bp_icon_button_module_iconButton--
|
|
1185
|
-
|
|
1186
|
-
width:var(--size-6);
|
|
1183
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_icon-logo--b6e1c:active,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_icon-logo--b6e1c[data-active]{
|
|
1184
|
+
background:var(--surface-cta-surface-icon-pressed);
|
|
1187
1185
|
}
|
|
1188
|
-
.bp_icon_button_module_iconButton--
|
|
1186
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c{
|
|
1189
1187
|
background:var(--surface-cta-surface-icon);
|
|
1190
1188
|
}
|
|
1191
|
-
.bp_icon_button_module_iconButton--
|
|
1189
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c .bp_icon_button_module_icon--b6e1c *{
|
|
1192
1190
|
fill:var(--icon-cta-icon-on-color);
|
|
1193
1191
|
}
|
|
1194
|
-
.bp_icon_button_module_iconButton--
|
|
1192
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c:hover,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c[data-focus-visible]{
|
|
1195
1193
|
background:var(--surface-cta-surface-icon-hover);
|
|
1196
1194
|
}
|
|
1197
|
-
.bp_icon_button_module_iconButton--
|
|
1195
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c:hover .bp_icon_button_module_icon--b6e1c *,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c[data-focus-visible] .bp_icon_button_module_icon--b6e1c *{
|
|
1198
1196
|
fill:var(--icon-cta-icon-on-color-hover);
|
|
1199
1197
|
}
|
|
1200
|
-
.bp_icon_button_module_iconButton--
|
|
1198
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c:active,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c[data-active]{
|
|
1201
1199
|
background:var(--surface-cta-surface-icon-pressed);
|
|
1202
1200
|
}
|
|
1203
|
-
.bp_icon_button_module_iconButton--
|
|
1201
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c:active .bp_icon_button_module_icon--b6e1c *,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_high-contrast--b6e1c[data-active] .bp_icon_button_module_icon--b6e1c *{
|
|
1204
1202
|
fill:var(--icon-cta-icon-on-color-pressed);
|
|
1205
1203
|
}
|
|
1206
|
-
.bp_icon_button_module_iconButton--
|
|
1204
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c{
|
|
1207
1205
|
background:var(--surface-cta-surface-icon-utility);
|
|
1208
1206
|
}
|
|
1209
|
-
.bp_icon_button_module_iconButton--
|
|
1207
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c .bp_icon_button_module_icon--b6e1c *{
|
|
1210
1208
|
fill:var(--icon-cta-icon-utility);
|
|
1211
1209
|
}
|
|
1212
|
-
.bp_icon_button_module_iconButton--
|
|
1210
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c:hover,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c[data-focus-visible]{
|
|
1213
1211
|
background:var(--surface-cta-surface-icon-utility-hover);
|
|
1214
1212
|
}
|
|
1215
|
-
.bp_icon_button_module_iconButton--
|
|
1213
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c:hover .bp_icon_button_module_icon--b6e1c *,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c[data-focus-visible] .bp_icon_button_module_icon--b6e1c *{
|
|
1216
1214
|
fill:var(--icon-cta-icon-utility-hover);
|
|
1217
1215
|
}
|
|
1218
|
-
.bp_icon_button_module_iconButton--
|
|
1216
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c:active,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c[data-active]{
|
|
1219
1217
|
background:var(--surface-cta-surface-icon-utility-pressed);
|
|
1220
1218
|
}
|
|
1221
|
-
.bp_icon_button_module_iconButton--
|
|
1219
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c:active .bp_icon_button_module_icon--b6e1c *,.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small-utility--b6e1c[data-active] .bp_icon_button_module_icon--b6e1c *{
|
|
1222
1220
|
fill:var(--icon-cta-icon-utility-pressed);
|
|
1223
1221
|
}
|
|
1222
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_large--b6e1c{
|
|
1223
|
+
height:var(--size-10);
|
|
1224
|
+
width:var(--size-10);
|
|
1225
|
+
}
|
|
1226
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_small--b6e1c{
|
|
1227
|
+
height:var(--size-8);
|
|
1228
|
+
width:var(--size-8);
|
|
1229
|
+
}
|
|
1230
|
+
.bp_icon_button_module_iconButton--b6e1c.bp_icon_button_module_x-small--b6e1c{
|
|
1231
|
+
height:var(--size-6);
|
|
1232
|
+
width:var(--size-6);
|
|
1233
|
+
}
|
|
1224
1234
|
|
|
1225
1235
|
.bp_collapsible_section_module_collapsibleSection--f411c{
|
|
1226
1236
|
width:100%;
|
|
@@ -5285,6 +5295,50 @@ table.bp_inline_table_module_inlineTable--b023b tr:not(:last-child) td{
|
|
|
5285
5295
|
.bp_text_input_module_textInput--3c0cc input:has(+ .bp_text_input_module_iconLoading--3c0cc){
|
|
5286
5296
|
padding-inline-end:1.875rem;
|
|
5287
5297
|
}
|
|
5298
|
+
|
|
5299
|
+
.bp_text_toggle_button_module_textToggleButton--527c5{
|
|
5300
|
+
background:var(--surface-toggle-surface);
|
|
5301
|
+
border:var(--border-1) solid var(--border-switch-border);
|
|
5302
|
+
border-radius:var(--radius-2);
|
|
5303
|
+
color:var(--text-text-on-light);
|
|
5304
|
+
cursor:pointer;
|
|
5305
|
+
font-family:Lato, -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
|
5306
|
+
font-size:.875rem;
|
|
5307
|
+
font-weight:400;
|
|
5308
|
+
letter-spacing:.01875rem;
|
|
5309
|
+
line-height:1.25rem;
|
|
5310
|
+
min-height:var(--size-8);
|
|
5311
|
+
outline:0;
|
|
5312
|
+
padding-inline:var(--space-2);
|
|
5313
|
+
text-decoration:none;
|
|
5314
|
+
text-transform:none;
|
|
5315
|
+
-webkit-user-select:none;
|
|
5316
|
+
user-select:none;
|
|
5317
|
+
white-space:nowrap;
|
|
5318
|
+
}
|
|
5319
|
+
.bp_text_toggle_button_module_textToggleButton--527c5:disabled{
|
|
5320
|
+
opacity:.3;
|
|
5321
|
+
pointer-events:none;
|
|
5322
|
+
}
|
|
5323
|
+
.bp_text_toggle_button_module_textToggleButton--527c5[data-focus-visible]{
|
|
5324
|
+
box-shadow:0 0 0 .0625rem #fff,0 0 0 .1875rem #2486fc;
|
|
5325
|
+
}
|
|
5326
|
+
.bp_text_toggle_button_module_textToggleButton--527c5:active,.bp_text_toggle_button_module_textToggleButton--527c5[data-focus-visible]{
|
|
5327
|
+
background:var(--surface-switch-surface-hover);
|
|
5328
|
+
border:var(--border-1) solid var(--border-switch-border-hover);
|
|
5329
|
+
}
|
|
5330
|
+
.bp_text_toggle_button_module_textToggleButton--527c5:hover{
|
|
5331
|
+
background:var(--surface-toggle-surface-hover);
|
|
5332
|
+
}
|
|
5333
|
+
.bp_text_toggle_button_module_textToggleButton--527c5[aria-pressed=true]{
|
|
5334
|
+
background:var(--surface-toggle-surface-pressed);
|
|
5335
|
+
border:var(--border-1) solid var(--surface-toggle-surface-pressed);
|
|
5336
|
+
color:var(--text-text-on-dark);
|
|
5337
|
+
}
|
|
5338
|
+
.bp_text_toggle_button_module_textToggleButton--527c5[aria-pressed=true]:active,.bp_text_toggle_button_module_textToggleButton--527c5[aria-pressed=true]:hover,.bp_text_toggle_button_module_textToggleButton--527c5[aria-pressed=true][data-focus-visible]{
|
|
5339
|
+
background:var(--surface-toggle-surface-pressed-hover);
|
|
5340
|
+
border:var(--border-1) solid var(--surface-toggle-surface-pressed-hover);
|
|
5341
|
+
}
|
|
5288
5342
|
:root{
|
|
5289
5343
|
--notification-default-paragraph-indent:0rem;
|
|
5290
5344
|
--notification-default-paragraph-spacing:0;
|
package/lib-esm/index.d.ts
CHANGED
package/lib-esm/index.js
CHANGED
|
@@ -69,6 +69,7 @@ export { Text } from './text/text.js';
|
|
|
69
69
|
export { TextArea } from './text-area/text-area.js';
|
|
70
70
|
export { TextButton } from './text-button/text-button.js';
|
|
71
71
|
export { TextInput } from './text-input/text-input.js';
|
|
72
|
+
export { TextToggleButton } from './text-toggle-button/text-toggle-button.js';
|
|
72
73
|
export { Toolbar } from './toolbar/index.js';
|
|
73
74
|
export { Tooltip, TooltipProvider } from './tooltip/tooltip.js';
|
|
74
75
|
export { TriggerButton } from './trigger-button/trigger-button.js';
|
|
@@ -4,7 +4,7 @@ import clsx from 'clsx';
|
|
|
4
4
|
import { forwardRef, useRef, createElement } from 'react';
|
|
5
5
|
import { useForkRef } from '../../utils/useForkRef.js';
|
|
6
6
|
import styles from './icon-button.module.js';
|
|
7
|
-
import {
|
|
7
|
+
import { iconSizeMap } from './utils.js';
|
|
8
8
|
|
|
9
9
|
const IconButton = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
10
10
|
const {
|
|
@@ -17,11 +17,11 @@ const IconButton = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
|
17
17
|
return jsx(Button, {
|
|
18
18
|
...rest,
|
|
19
19
|
ref: useForkRef(ref, forwardedRef),
|
|
20
|
-
className: clsx(
|
|
20
|
+
className: clsx(styles.iconButton, styles[variant], styles[size], props.className),
|
|
21
21
|
children: /*#__PURE__*/createElement(icon, {
|
|
22
|
-
className: styles.
|
|
23
|
-
height:
|
|
24
|
-
width:
|
|
22
|
+
className: styles.icon,
|
|
23
|
+
height: iconSizeMap[size],
|
|
24
|
+
width: iconSizeMap[size],
|
|
25
25
|
role: 'presentation'
|
|
26
26
|
})
|
|
27
27
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '../../index.css';
|
|
2
|
-
var styles = {"iconButton":"bp_icon_button_module_iconButton--
|
|
2
|
+
var styles = {"iconButton":"bp_icon_button_module_iconButton--b6e1c","icon":"bp_icon_button_module_icon--b6e1c","default":"bp_icon_button_module_default--b6e1c","icon-logo":"bp_icon_button_module_icon-logo--b6e1c","high-contrast":"bp_icon_button_module_high-contrast--b6e1c","small-utility":"bp_icon_button_module_small-utility--b6e1c","large":"bp_icon_button_module_large--b6e1c","small":"bp_icon_button_module_small--b6e1c","x-small":"bp_icon_button_module_x-small--b6e1c"};
|
|
3
3
|
|
|
4
4
|
export { styles as default };
|
|
@@ -10,29 +10,33 @@ interface IconButtonCommonProps extends AriakitButtonProps {
|
|
|
10
10
|
*/
|
|
11
11
|
icon: FunctionComponent<PropsWithChildren<SVGProps<SVGSVGElement>>>;
|
|
12
12
|
}
|
|
13
|
+
export declare const IconButtonSizes: readonly ["x-small", "small", "large"];
|
|
14
|
+
export type IconButtonSize = (typeof IconButtonSizes)[number];
|
|
15
|
+
export declare const IconButtonVariants: readonly ["default", "high-contrast", "icon-logo", "small-utility"];
|
|
16
|
+
export type IconButtonVariant = (typeof IconButtonVariants)[number];
|
|
13
17
|
export interface IconButtonVariantsProps extends IconButtonCommonProps {
|
|
14
18
|
/**
|
|
15
19
|
* The variant of the button.
|
|
16
20
|
*
|
|
17
21
|
* @default 'default'
|
|
18
22
|
*/
|
|
19
|
-
variant?:
|
|
23
|
+
variant?: Exclude<IconButtonVariant, 'small-utility'>;
|
|
20
24
|
/**
|
|
21
25
|
* Size of the button.
|
|
22
26
|
*
|
|
23
27
|
* @default 'small'
|
|
24
28
|
*/
|
|
25
|
-
size?:
|
|
29
|
+
size?: IconButtonSize;
|
|
26
30
|
}
|
|
27
31
|
export interface IconButtonSmallUtilityVariantProps extends IconButtonCommonProps {
|
|
28
32
|
/**
|
|
29
33
|
* The variant of the button.
|
|
30
34
|
*/
|
|
31
|
-
variant: 'small-utility'
|
|
35
|
+
variant: Extract<IconButtonVariant, 'small-utility'>;
|
|
32
36
|
/**
|
|
33
|
-
* The only acceptable size for the small-utility variant is 'small'.
|
|
37
|
+
* The only acceptable size for the 'small-utility' variant is 'small'.
|
|
34
38
|
*/
|
|
35
|
-
size: 'small'
|
|
39
|
+
size: Extract<IconButtonSize, 'small'>;
|
|
36
40
|
}
|
|
37
41
|
export type IconButtonProps = IconButtonVariantsProps | IconButtonSmallUtilityVariantProps;
|
|
38
42
|
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type IconButtonProps } from './types';
|
|
2
|
-
declare
|
|
3
|
-
export {
|
|
2
|
+
declare const iconSizeMap: Record<NonNullable<IconButtonProps['size']>, string>;
|
|
3
|
+
export { iconSizeMap };
|
|
@@ -5,11 +5,5 @@ const iconSizeMap = {
|
|
|
5
5
|
small: Size5,
|
|
6
6
|
large: Size6
|
|
7
7
|
};
|
|
8
|
-
function getIconSize(props) {
|
|
9
|
-
if (props.variant === 'small-utility') {
|
|
10
|
-
return Size4;
|
|
11
|
-
}
|
|
12
|
-
return iconSizeMap[props.size || 'small'];
|
|
13
|
-
}
|
|
14
8
|
|
|
15
|
-
export {
|
|
9
|
+
export { iconSizeMap };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Button } from '@ariakit/react';
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
import { composeEventHandlers } from '../utils/composeEventHandlers.js';
|
|
6
|
+
import { useControllableState } from '../utils/useControllableState.js';
|
|
7
|
+
import styles from './text-toggle-button.module.js';
|
|
8
|
+
|
|
9
|
+
const TextToggleButton = /*#__PURE__*/forwardRef(({
|
|
10
|
+
pressed: pressedProp,
|
|
11
|
+
defaultPressed = false,
|
|
12
|
+
onPressedChange,
|
|
13
|
+
disabled,
|
|
14
|
+
onClick,
|
|
15
|
+
className,
|
|
16
|
+
...rest
|
|
17
|
+
}, ref) => {
|
|
18
|
+
const [pressed = false, setPressed] = useControllableState({
|
|
19
|
+
prop: pressedProp,
|
|
20
|
+
onChange: onPressedChange,
|
|
21
|
+
defaultProp: defaultPressed
|
|
22
|
+
});
|
|
23
|
+
return jsx(Button, {
|
|
24
|
+
"aria-pressed": pressed,
|
|
25
|
+
"data-disabled": disabled ? '' : undefined,
|
|
26
|
+
"data-state": pressed ? 'on' : 'off',
|
|
27
|
+
...rest,
|
|
28
|
+
ref: ref,
|
|
29
|
+
className: clsx(styles.textToggleButton, className),
|
|
30
|
+
disabled: disabled,
|
|
31
|
+
onClick: composeEventHandlers(onClick, () => {
|
|
32
|
+
if (!disabled) {
|
|
33
|
+
setPressed(!pressed);
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
TextToggleButton.displayName = 'TextToggleButton';
|
|
39
|
+
|
|
40
|
+
export { TextToggleButton };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ButtonProps as AriakitButtonProps } from '@ariakit/react';
|
|
2
|
+
export interface TextToggleButtonProps extends AriakitButtonProps {
|
|
3
|
+
/**
|
|
4
|
+
* The text content of the button.
|
|
5
|
+
*/
|
|
6
|
+
children: string;
|
|
7
|
+
/**
|
|
8
|
+
* The controlled state of the toggle.
|
|
9
|
+
*/
|
|
10
|
+
pressed?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* The state of the toggle when initially rendered. Use `defaultPressed`
|
|
13
|
+
* if you do not need to control the state of the toggle.
|
|
14
|
+
* @defaultValue false
|
|
15
|
+
*/
|
|
16
|
+
defaultPressed?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The callback that fires when the state of the toggle changes.
|
|
19
|
+
*/
|
|
20
|
+
onPressedChange?(pressed: boolean): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// copy of radix function: https://github.com/radix-ui/primitives/blob/main/packages/core/primitive/src/primitive.tsx
|
|
2
|
+
function composeEventHandlers(originalEventHandler, ourEventHandler, {
|
|
3
|
+
checkForDefaultPrevented = true
|
|
4
|
+
} = {}) {
|
|
5
|
+
return function handleEvent(event) {
|
|
6
|
+
originalEventHandler?.(event);
|
|
7
|
+
if (checkForDefaultPrevented === false || !event.defaultPrevented) {
|
|
8
|
+
ourEventHandler?.(event);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { composeEventHandlers };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A custom hook that converts a callback to a ref to avoid triggering re-renders when passed as a
|
|
3
|
+
* prop or avoid re-executing effects when passed as a dependency
|
|
4
|
+
*/
|
|
5
|
+
declare function useCallbackRef<T extends (...args: any[]) => any>(callback: T | undefined): T;
|
|
6
|
+
export { useCallbackRef };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
// copy of radix hook: https://github.com/radix-ui/primitives/blob/main/packages/react/use-callback-ref/src/useCallbackRef.tsx
|
|
4
|
+
/**
|
|
5
|
+
* A custom hook that converts a callback to a ref to avoid triggering re-renders when passed as a
|
|
6
|
+
* prop or avoid re-executing effects when passed as a dependency
|
|
7
|
+
*/
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
function useCallbackRef(callback) {
|
|
10
|
+
const callbackRef = React.useRef(callback);
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
callbackRef.current = callback;
|
|
13
|
+
});
|
|
14
|
+
// https://github.com/facebook/react/issues/19240
|
|
15
|
+
return React.useMemo(() => (...args) => callbackRef.current?.(...args), []);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { useCallbackRef };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
interface UseControllableStateParams<T> {
|
|
3
|
+
prop?: T | undefined;
|
|
4
|
+
defaultProp?: T | undefined;
|
|
5
|
+
onChange?: (state: T) => void;
|
|
6
|
+
}
|
|
7
|
+
declare function useControllableState<T>({ prop, defaultProp, onChange }: UseControllableStateParams<T>): readonly [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>];
|
|
8
|
+
export { useControllableState };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useCallbackRef } from './useCallbackRef.js';
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
5
|
+
function useControllableState({
|
|
6
|
+
prop,
|
|
7
|
+
defaultProp,
|
|
8
|
+
onChange = () => {}
|
|
9
|
+
}) {
|
|
10
|
+
const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({
|
|
11
|
+
defaultProp,
|
|
12
|
+
onChange
|
|
13
|
+
});
|
|
14
|
+
const isControlled = prop !== undefined;
|
|
15
|
+
const value = isControlled ? prop : uncontrolledProp;
|
|
16
|
+
const handleChange = useCallbackRef(onChange);
|
|
17
|
+
const setValue = React.useCallback(nextValue => {
|
|
18
|
+
if (isControlled) {
|
|
19
|
+
const setter = nextValue;
|
|
20
|
+
// renamed variable since it overlapped with variable "value" in the outer scope of hook
|
|
21
|
+
const internalValue = typeof nextValue === 'function' ? setter(prop) : nextValue;
|
|
22
|
+
if (internalValue !== prop) {
|
|
23
|
+
handleChange(internalValue);
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
setUncontrolledProp(nextValue);
|
|
27
|
+
}
|
|
28
|
+
}, [isControlled, prop, setUncontrolledProp, handleChange]);
|
|
29
|
+
return [value, setValue];
|
|
30
|
+
}
|
|
31
|
+
function useUncontrolledState({
|
|
32
|
+
defaultProp,
|
|
33
|
+
onChange
|
|
34
|
+
}) {
|
|
35
|
+
const uncontrolledState = React.useState(defaultProp);
|
|
36
|
+
const [value] = uncontrolledState;
|
|
37
|
+
const prevValueRef = React.useRef(value);
|
|
38
|
+
const handleChange = useCallbackRef(onChange);
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
if (prevValueRef.current !== value) {
|
|
41
|
+
handleChange(value);
|
|
42
|
+
prevValueRef.current = value;
|
|
43
|
+
}
|
|
44
|
+
}, [value, prevValueRef, handleChange]);
|
|
45
|
+
return uncontrolledState;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { useControllableState };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@box/blueprint-web",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.13.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"type-fest": "^3.2.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@box/storybook-utils": "^0.
|
|
57
|
+
"@box/storybook-utils": "^0.3.0",
|
|
58
58
|
"react-stately": "^3.31.1"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "4291826556f62c20172aa6e6f4d6274071000aac",
|
|
61
61
|
"module": "lib-esm/index.js",
|
|
62
62
|
"main": "lib-esm/index.js",
|
|
63
63
|
"exports": {
|