@tinybigui/react 0.4.2 → 0.5.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/dist/index.cjs +404 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +143 -99
- package/dist/index.d.ts +143 -99
- package/dist/index.js +404 -146
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1118,81 +1118,113 @@ var IconButtonHeadless = React.forwardRef(
|
|
|
1118
1118
|
tabIndex = 0,
|
|
1119
1119
|
onMouseDown,
|
|
1120
1120
|
type,
|
|
1121
|
-
|
|
1121
|
+
isSelected,
|
|
1122
|
+
isToggle = false,
|
|
1123
|
+
isDisabled = false,
|
|
1122
1124
|
"aria-label": ariaLabel,
|
|
1123
1125
|
title,
|
|
1124
1126
|
...props
|
|
1125
1127
|
}, forwardedRef) => {
|
|
1126
1128
|
const internalRef = React.useRef(null);
|
|
1127
1129
|
const ref = forwardedRef ?? internalRef;
|
|
1128
|
-
const { buttonProps } = reactAria.useButton(
|
|
1130
|
+
const { buttonProps, isPressed } = reactAria.useButton(
|
|
1129
1131
|
{
|
|
1130
1132
|
...props,
|
|
1131
|
-
// Ensure element type is 'button' for proper semantics
|
|
1132
1133
|
elementType: "button",
|
|
1133
|
-
|
|
1134
|
-
|
|
1134
|
+
"aria-label": ariaLabel,
|
|
1135
|
+
isDisabled
|
|
1135
1136
|
},
|
|
1136
1137
|
ref
|
|
1137
1138
|
);
|
|
1139
|
+
const { isHovered, hoverProps } = reactAria.useHover({ isDisabled });
|
|
1140
|
+
const { isFocusVisible, focusProps } = reactAria.useFocusRing();
|
|
1138
1141
|
const domProps = utils.filterDOMProps(props);
|
|
1139
|
-
const mergedProps = utils.mergeProps(
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
+
const mergedProps = utils.mergeProps(buttonProps, hoverProps, focusProps, domProps, {
|
|
1143
|
+
tabIndex,
|
|
1144
|
+
className,
|
|
1145
|
+
onMouseDown,
|
|
1146
|
+
type: type ?? "button",
|
|
1147
|
+
...title && { title },
|
|
1148
|
+
// aria-pressed only when acting as a toggle button
|
|
1149
|
+
...isToggle && { "aria-pressed": isSelected ?? false }
|
|
1150
|
+
});
|
|
1151
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1152
|
+
"button",
|
|
1142
1153
|
{
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1154
|
+
...mergedProps,
|
|
1155
|
+
ref,
|
|
1156
|
+
type: type === "submit" ? "submit" : type === "reset" ? "reset" : "button",
|
|
1157
|
+
...getInteractionDataAttributes({
|
|
1158
|
+
isHovered,
|
|
1159
|
+
isFocusVisible,
|
|
1160
|
+
isPressed,
|
|
1161
|
+
...isToggle ? { isSelected: isSelected ?? false } : {},
|
|
1162
|
+
isDisabled
|
|
1163
|
+
}),
|
|
1164
|
+
"data-toggle": isToggle ? "" : void 0,
|
|
1165
|
+
children
|
|
1151
1166
|
}
|
|
1152
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1153
|
-
);
|
|
1154
|
-
return (
|
|
1155
|
-
// eslint-disable-next-line react/button-has-type
|
|
1156
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { ...mergedProps, ref, type: type ?? "button", children })
|
|
1157
1167
|
);
|
|
1158
1168
|
}
|
|
1159
1169
|
);
|
|
1160
1170
|
IconButtonHeadless.displayName = "IconButtonHeadless";
|
|
1161
|
-
var
|
|
1171
|
+
var iconButtonRootVariants = classVarianceAuthority.cva(
|
|
1162
1172
|
[
|
|
1163
|
-
//
|
|
1164
|
-
"relative inline-flex items-center justify-center
|
|
1165
|
-
"
|
|
1166
|
-
|
|
1167
|
-
//
|
|
1168
|
-
//
|
|
1169
|
-
//
|
|
1173
|
+
// Layout
|
|
1174
|
+
"relative inline-flex items-center justify-center",
|
|
1175
|
+
"cursor-pointer select-none",
|
|
1176
|
+
"overflow-hidden",
|
|
1177
|
+
// Corner radius driven by CSS variable — set per shape×size in compoundVariants.
|
|
1178
|
+
// Fallback 9999px is only reached if both shape and size props are absent,
|
|
1179
|
+
// which cannot happen in normal usage.
|
|
1180
|
+
"rounded-[var(--ib-radius,9999px)]",
|
|
1181
|
+
// Split MD3 transition via the existing btn-transition utility:
|
|
1182
|
+
// border-radius → emphasized-decelerate (no overshoot, no sharp-corner flash)
|
|
1183
|
+
// color/bg/border/opacity → standard-fast-effects (no overshoot on effects)
|
|
1184
|
+
// This is identical to the approach used by Button/connected ButtonGroup and is
|
|
1185
|
+
// the standard fix for the 9999px overshoot problem documented in styles.css.
|
|
1170
1186
|
"btn-transition",
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
"
|
|
1174
|
-
"
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
"
|
|
1178
|
-
"
|
|
1187
|
+
// Background + border + text driven from CSS role variables
|
|
1188
|
+
"bg-[var(--ib-bg,transparent)]",
|
|
1189
|
+
"border border-[var(--ib-border,transparent)]",
|
|
1190
|
+
"text-[var(--ib-fg,currentColor)]",
|
|
1191
|
+
// Toggle: off state (data-toggle present but data-selected absent)
|
|
1192
|
+
// Uses doubly-chained selector to beat single-chain specificity of defaults
|
|
1193
|
+
"data-[toggle]:bg-[var(--ib-bg-off,var(--ib-bg,transparent))]",
|
|
1194
|
+
"data-[toggle]:text-[var(--ib-fg-off,var(--ib-fg,currentColor))]",
|
|
1195
|
+
// Selected state
|
|
1196
|
+
"data-[selected]:bg-[var(--ib-bg-on,var(--ib-bg,transparent))]",
|
|
1197
|
+
"data-[selected]:text-[var(--ib-fg-on,var(--ib-fg,currentColor))]",
|
|
1198
|
+
"data-[selected]:border-transparent",
|
|
1199
|
+
// Press shape-morph: radius collapses to --ib-radius-press on press
|
|
1200
|
+
// (only has visual effect when --ib-radius-press differs from --ib-radius)
|
|
1201
|
+
"data-[pressed]:rounded-[var(--ib-radius-press,var(--ib-radius,9999px))]",
|
|
1202
|
+
// Focus ring (outline, not a state layer — stays outside overflow-hidden
|
|
1203
|
+
// because it's drawn as outline on the root element itself)
|
|
1204
|
+
"outline-none",
|
|
1205
|
+
"group-data-[focus-visible]/icon-button:outline-2",
|
|
1206
|
+
"group-data-[focus-visible]/icon-button:outline-offset-2",
|
|
1207
|
+
"group-data-[focus-visible]/icon-button:outline-secondary",
|
|
1208
|
+
// Disabled — content opacity 38%, container handled per variant via CSS vars
|
|
1209
|
+
"data-[disabled]:cursor-not-allowed data-[disabled]:pointer-events-none",
|
|
1210
|
+
"data-[disabled]:text-on-surface/38"
|
|
1211
|
+
// Filled/tonal/outlined-selected backgrounds collapse to on-surface/12 — set
|
|
1212
|
+
// via compoundVariants on the root for variants that have a container.
|
|
1213
|
+
// For variants with transparent bg (standard, outlined-unselected) we do nothing.
|
|
1179
1214
|
],
|
|
1180
1215
|
{
|
|
1181
1216
|
variants: {
|
|
1182
1217
|
/**
|
|
1183
|
-
*
|
|
1218
|
+
* Visual style variant (MD3 icon button types)
|
|
1184
1219
|
*/
|
|
1185
1220
|
variant: {
|
|
1186
|
-
standard: "
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
tonal: "",
|
|
1191
|
-
// Container background
|
|
1192
|
-
outlined: "bg-transparent border border-outline"
|
|
1221
|
+
standard: "",
|
|
1222
|
+
filled: "data-[disabled]:bg-on-surface/12",
|
|
1223
|
+
tonal: "data-[disabled]:bg-on-surface/12",
|
|
1224
|
+
outlined: ""
|
|
1193
1225
|
},
|
|
1194
1226
|
/**
|
|
1195
|
-
* Color scheme
|
|
1227
|
+
* Color scheme — sets CSS role variables via compoundVariants.
|
|
1196
1228
|
*/
|
|
1197
1229
|
color: {
|
|
1198
1230
|
primary: "",
|
|
@@ -1201,180 +1233,400 @@ var iconButtonVariants = classVarianceAuthority.cva(
|
|
|
1201
1233
|
error: ""
|
|
1202
1234
|
},
|
|
1203
1235
|
/**
|
|
1204
|
-
*
|
|
1236
|
+
* Size tier (M3 Expressive 5-tier)
|
|
1205
1237
|
*/
|
|
1206
1238
|
size: {
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
medium: "h-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
// 48×48px
|
|
1239
|
+
xsmall: "h-8",
|
|
1240
|
+
small: "h-10",
|
|
1241
|
+
medium: "h-14",
|
|
1242
|
+
large: "h-24",
|
|
1243
|
+
xlarge: "h-[8.5rem]"
|
|
1213
1244
|
},
|
|
1214
1245
|
/**
|
|
1215
|
-
*
|
|
1246
|
+
* Width variant — adjusts container width
|
|
1216
1247
|
*/
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1248
|
+
width: {
|
|
1249
|
+
narrow: "",
|
|
1250
|
+
default: "",
|
|
1251
|
+
wide: ""
|
|
1220
1252
|
},
|
|
1221
1253
|
/**
|
|
1222
|
-
*
|
|
1254
|
+
* Shape — base values only; per-size radii set via compoundVariants below.
|
|
1255
|
+
*
|
|
1256
|
+
* round: --ib-radius = half the container height (true circle), set per size.
|
|
1257
|
+
* --ib-radius-press = square corner for that size (set per size).
|
|
1258
|
+
* Morph distance is small (e.g. 28px → 16px for medium), so the
|
|
1259
|
+
* emphasized-decelerate curve from btn-transition produces a smooth,
|
|
1260
|
+
* non-overshooting transition. The old 9999px fallback caused the
|
|
1261
|
+
* spring to overshoot below 0 = sharp-corner flash.
|
|
1262
|
+
* square: --ib-radius = size-tiered MD3 corner, set per size. No press morph.
|
|
1223
1263
|
*/
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1264
|
+
shape: {
|
|
1265
|
+
round: [],
|
|
1266
|
+
square: []
|
|
1227
1267
|
}
|
|
1228
1268
|
},
|
|
1229
|
-
/**
|
|
1230
|
-
* Compound variants - combinations of variant + color + selected
|
|
1231
|
-
*/
|
|
1232
1269
|
compoundVariants: [
|
|
1233
|
-
//
|
|
1234
|
-
//
|
|
1235
|
-
//
|
|
1236
|
-
{
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
},
|
|
1270
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
1271
|
+
// SIZE × WIDTH — container width
|
|
1272
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
1273
|
+
{ size: "xsmall", width: "narrow", className: "w-6" },
|
|
1274
|
+
{ size: "xsmall", width: "default", className: "w-8" },
|
|
1275
|
+
{ size: "xsmall", width: "wide", className: "w-10" },
|
|
1276
|
+
{ size: "small", width: "narrow", className: "w-8" },
|
|
1277
|
+
{ size: "small", width: "default", className: "w-10" },
|
|
1278
|
+
{ size: "small", width: "wide", className: "w-13" },
|
|
1279
|
+
{ size: "medium", width: "narrow", className: "w-12" },
|
|
1280
|
+
{ size: "medium", width: "default", className: "w-14" },
|
|
1281
|
+
{ size: "medium", width: "wide", className: "w-18" },
|
|
1282
|
+
{ size: "large", width: "narrow", className: "w-18" },
|
|
1283
|
+
{ size: "large", width: "default", className: "w-24" },
|
|
1284
|
+
{ size: "large", width: "wide", className: "w-32" },
|
|
1285
|
+
{ size: "xlarge", width: "narrow", className: "w-24" },
|
|
1286
|
+
{ size: "xlarge", width: "default", className: "w-[8.5rem]" },
|
|
1287
|
+
{ size: "xlarge", width: "wide", className: "w-42" },
|
|
1288
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
1289
|
+
// SHAPE × SIZE — corner radii for both round and square shapes
|
|
1290
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
1291
|
+
//
|
|
1292
|
+
// Round rest radius = half container height (true circle).
|
|
1293
|
+
// Using the exact half-height keeps the morph distance small, so the
|
|
1294
|
+
// no-overshoot emphasized-decelerate curve in btn-transition produces a
|
|
1295
|
+
// smooth animation. Using 9999px was the original cause of the sharp-
|
|
1296
|
+
// corner flash (the spring overshoots below 0 before settling).
|
|
1297
|
+
//
|
|
1298
|
+
// xsmall h-8 = 32px → half = 16px = 1rem
|
|
1299
|
+
// small h-10 = 40px → half = 20px = 1.25rem
|
|
1300
|
+
// medium h-14 = 56px → half = 28px = 1.75rem
|
|
1301
|
+
// large h-24 = 96px → half = 48px = 3rem
|
|
1302
|
+
// xlarge h-34 = 136px → half = 68px = 4.25rem
|
|
1303
|
+
//
|
|
1304
|
+
// Round press-morph target = MD3 square corner for that size tier.
|
|
1305
|
+
// Square rest radius = same MD3 corner (no morph).
|
|
1306
|
+
// ── round: rest radius (half height) ──────────────────────────────────
|
|
1307
|
+
{ shape: "round", size: "xsmall", className: "[--ib-radius:1rem]" },
|
|
1308
|
+
{ shape: "round", size: "small", className: "[--ib-radius:1.25rem]" },
|
|
1309
|
+
{ shape: "round", size: "medium", className: "[--ib-radius:1.75rem]" },
|
|
1310
|
+
{ shape: "round", size: "large", className: "[--ib-radius:3rem]" },
|
|
1311
|
+
{ shape: "round", size: "xlarge", className: "[--ib-radius:4.25rem]" },
|
|
1312
|
+
// ── round: press-morph target (square corner for that size) ───────────
|
|
1313
|
+
{ shape: "round", size: "xsmall", className: "[--ib-radius-press:0.75rem]" },
|
|
1314
|
+
{ shape: "round", size: "small", className: "[--ib-radius-press:0.75rem]" },
|
|
1315
|
+
{ shape: "round", size: "medium", className: "[--ib-radius-press:1rem]" },
|
|
1316
|
+
{ shape: "round", size: "large", className: "[--ib-radius-press:1.75rem]" },
|
|
1317
|
+
{ shape: "round", size: "xlarge", className: "[--ib-radius-press:1.75rem]" },
|
|
1318
|
+
// ── square: rest radius (MD3 shape scale) ─────────────────────────────
|
|
1319
|
+
// xsmall / small → 12px (0.75rem), medium → 16px (1rem), large / xlarge → 28px (1.75rem)
|
|
1320
|
+
{ shape: "square", size: "xsmall", className: "[--ib-radius:0.75rem]" },
|
|
1321
|
+
{ shape: "square", size: "small", className: "[--ib-radius:0.75rem]" },
|
|
1322
|
+
{ shape: "square", size: "medium", className: "[--ib-radius:1rem]" },
|
|
1323
|
+
{ shape: "square", size: "large", className: "[--ib-radius:1.75rem]" },
|
|
1324
|
+
{ shape: "square", size: "xlarge", className: "[--ib-radius:1.75rem]" },
|
|
1325
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
1326
|
+
// VARIANT × COLOR — CSS role variable assignments
|
|
1327
|
+
// Only variant × color (design-time decisions); no state variants here.
|
|
1328
|
+
// ══════════════════════════════════════════════════════════════════════
|
|
1329
|
+
// ── STANDARD ──────────────────────────────────────────────────────────
|
|
1330
|
+
// Non-toggle standard: transparent bg, on-surface-variant fg
|
|
1331
|
+
// Selected: primary fg
|
|
1332
|
+
// State layer: on-surface-variant (unselected) / primary (selected)
|
|
1241
1333
|
{
|
|
1242
1334
|
variant: "standard",
|
|
1243
|
-
selected: true,
|
|
1244
|
-
className: "text-primary"
|
|
1245
|
-
},
|
|
1246
|
-
// ====================
|
|
1247
|
-
// FILLED VARIANTS (UNSELECTED)
|
|
1248
|
-
// ====================
|
|
1249
|
-
{
|
|
1250
|
-
variant: "filled",
|
|
1251
1335
|
color: "primary",
|
|
1252
|
-
|
|
1253
|
-
|
|
1336
|
+
className: [
|
|
1337
|
+
"[--ib-bg:transparent]",
|
|
1338
|
+
"[--ib-fg:var(--color-on-surface-variant)]",
|
|
1339
|
+
"[--ib-fg-on:var(--color-primary)]",
|
|
1340
|
+
"[--ib-sl:var(--color-on-surface-variant)]",
|
|
1341
|
+
// toggle-off same as non-toggle
|
|
1342
|
+
"[--ib-bg-off:transparent]",
|
|
1343
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1344
|
+
// toggle-on: selected
|
|
1345
|
+
"[--ib-bg-on:transparent]"
|
|
1346
|
+
]
|
|
1254
1347
|
},
|
|
1255
1348
|
{
|
|
1256
|
-
variant: "
|
|
1349
|
+
variant: "standard",
|
|
1257
1350
|
color: "secondary",
|
|
1258
|
-
|
|
1259
|
-
|
|
1351
|
+
className: [
|
|
1352
|
+
"[--ib-bg:transparent]",
|
|
1353
|
+
"[--ib-fg:var(--color-on-surface-variant)]",
|
|
1354
|
+
"[--ib-fg-on:var(--color-secondary)]",
|
|
1355
|
+
"[--ib-sl:var(--color-on-surface-variant)]",
|
|
1356
|
+
"[--ib-bg-off:transparent]",
|
|
1357
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1358
|
+
"[--ib-bg-on:transparent]"
|
|
1359
|
+
]
|
|
1260
1360
|
},
|
|
1261
1361
|
{
|
|
1262
|
-
variant: "
|
|
1362
|
+
variant: "standard",
|
|
1263
1363
|
color: "tertiary",
|
|
1264
|
-
|
|
1265
|
-
|
|
1364
|
+
className: [
|
|
1365
|
+
"[--ib-bg:transparent]",
|
|
1366
|
+
"[--ib-fg:var(--color-on-surface-variant)]",
|
|
1367
|
+
"[--ib-fg-on:var(--color-tertiary)]",
|
|
1368
|
+
"[--ib-sl:var(--color-on-surface-variant)]",
|
|
1369
|
+
"[--ib-bg-off:transparent]",
|
|
1370
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1371
|
+
"[--ib-bg-on:transparent]"
|
|
1372
|
+
]
|
|
1266
1373
|
},
|
|
1267
1374
|
{
|
|
1268
|
-
variant: "
|
|
1375
|
+
variant: "standard",
|
|
1269
1376
|
color: "error",
|
|
1270
|
-
|
|
1271
|
-
|
|
1377
|
+
className: [
|
|
1378
|
+
"[--ib-bg:transparent]",
|
|
1379
|
+
"[--ib-fg:var(--color-on-surface-variant)]",
|
|
1380
|
+
"[--ib-fg-on:var(--color-error)]",
|
|
1381
|
+
"[--ib-sl:var(--color-on-surface-variant)]",
|
|
1382
|
+
"[--ib-bg-off:transparent]",
|
|
1383
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1384
|
+
"[--ib-bg-on:transparent]"
|
|
1385
|
+
]
|
|
1272
1386
|
},
|
|
1273
|
-
//
|
|
1274
|
-
//
|
|
1275
|
-
//
|
|
1387
|
+
// ── FILLED ────────────────────────────────────────────────────────────
|
|
1388
|
+
// Non-toggle: bg primary / fg on-primary
|
|
1389
|
+
// Toggle off: bg surface-container-highest / fg primary
|
|
1390
|
+
// Toggle on (selected): bg primary / fg on-primary
|
|
1391
|
+
// State layer: on-primary (non-toggle / selected), primary (toggle-off)
|
|
1276
1392
|
{
|
|
1277
1393
|
variant: "filled",
|
|
1278
1394
|
color: "primary",
|
|
1279
|
-
|
|
1280
|
-
|
|
1395
|
+
className: [
|
|
1396
|
+
"[--ib-bg:var(--color-primary)]",
|
|
1397
|
+
"[--ib-fg:var(--color-on-primary)]",
|
|
1398
|
+
"[--ib-sl:var(--color-on-primary)]",
|
|
1399
|
+
"[--ib-bg-off:var(--color-surface-container-highest)]",
|
|
1400
|
+
"[--ib-fg-off:var(--color-primary)]",
|
|
1401
|
+
"[--ib-bg-on:var(--color-primary)]",
|
|
1402
|
+
"[--ib-fg-on:var(--color-on-primary)]"
|
|
1403
|
+
]
|
|
1281
1404
|
},
|
|
1282
1405
|
{
|
|
1283
1406
|
variant: "filled",
|
|
1284
1407
|
color: "secondary",
|
|
1285
|
-
|
|
1286
|
-
|
|
1408
|
+
className: [
|
|
1409
|
+
"[--ib-bg:var(--color-secondary)]",
|
|
1410
|
+
"[--ib-fg:var(--color-on-secondary)]",
|
|
1411
|
+
"[--ib-sl:var(--color-on-secondary)]",
|
|
1412
|
+
"[--ib-bg-off:var(--color-surface-container-highest)]",
|
|
1413
|
+
"[--ib-fg-off:var(--color-secondary)]",
|
|
1414
|
+
"[--ib-bg-on:var(--color-secondary)]",
|
|
1415
|
+
"[--ib-fg-on:var(--color-on-secondary)]"
|
|
1416
|
+
]
|
|
1287
1417
|
},
|
|
1288
1418
|
{
|
|
1289
1419
|
variant: "filled",
|
|
1290
1420
|
color: "tertiary",
|
|
1291
|
-
|
|
1292
|
-
|
|
1421
|
+
className: [
|
|
1422
|
+
"[--ib-bg:var(--color-tertiary)]",
|
|
1423
|
+
"[--ib-fg:var(--color-on-tertiary)]",
|
|
1424
|
+
"[--ib-sl:var(--color-on-tertiary)]",
|
|
1425
|
+
"[--ib-bg-off:var(--color-surface-container-highest)]",
|
|
1426
|
+
"[--ib-fg-off:var(--color-tertiary)]",
|
|
1427
|
+
"[--ib-bg-on:var(--color-tertiary)]",
|
|
1428
|
+
"[--ib-fg-on:var(--color-on-tertiary)]"
|
|
1429
|
+
]
|
|
1293
1430
|
},
|
|
1294
1431
|
{
|
|
1295
1432
|
variant: "filled",
|
|
1296
1433
|
color: "error",
|
|
1297
|
-
|
|
1298
|
-
|
|
1434
|
+
className: [
|
|
1435
|
+
"[--ib-bg:var(--color-error)]",
|
|
1436
|
+
"[--ib-fg:var(--color-on-error)]",
|
|
1437
|
+
"[--ib-sl:var(--color-on-error)]",
|
|
1438
|
+
"[--ib-bg-off:var(--color-surface-container-highest)]",
|
|
1439
|
+
"[--ib-fg-off:var(--color-error)]",
|
|
1440
|
+
"[--ib-bg-on:var(--color-error)]",
|
|
1441
|
+
"[--ib-fg-on:var(--color-on-error)]"
|
|
1442
|
+
]
|
|
1299
1443
|
},
|
|
1300
|
-
//
|
|
1301
|
-
//
|
|
1302
|
-
//
|
|
1444
|
+
// ── TONAL ─────────────────────────────────────────────────────────────
|
|
1445
|
+
// Non-toggle: bg secondary-container / fg on-secondary-container
|
|
1446
|
+
// Toggle off: bg surface-container-highest / fg on-surface-variant
|
|
1447
|
+
// Toggle on (selected): bg secondary-container / fg on-secondary-container
|
|
1303
1448
|
{
|
|
1304
1449
|
variant: "tonal",
|
|
1305
1450
|
color: "primary",
|
|
1306
|
-
|
|
1307
|
-
|
|
1451
|
+
className: [
|
|
1452
|
+
"[--ib-bg:var(--color-secondary-container)]",
|
|
1453
|
+
"[--ib-fg:var(--color-on-secondary-container)]",
|
|
1454
|
+
"[--ib-sl:var(--color-on-secondary-container)]",
|
|
1455
|
+
"[--ib-bg-off:var(--color-surface-container-highest)]",
|
|
1456
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1457
|
+
"[--ib-bg-on:var(--color-secondary-container)]",
|
|
1458
|
+
"[--ib-fg-on:var(--color-on-secondary-container)]"
|
|
1459
|
+
]
|
|
1308
1460
|
},
|
|
1309
1461
|
{
|
|
1310
1462
|
variant: "tonal",
|
|
1311
1463
|
color: "secondary",
|
|
1312
|
-
|
|
1313
|
-
|
|
1464
|
+
className: [
|
|
1465
|
+
"[--ib-bg:var(--color-secondary-container)]",
|
|
1466
|
+
"[--ib-fg:var(--color-on-secondary-container)]",
|
|
1467
|
+
"[--ib-sl:var(--color-on-secondary-container)]",
|
|
1468
|
+
"[--ib-bg-off:var(--color-surface-container-highest)]",
|
|
1469
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1470
|
+
"[--ib-bg-on:var(--color-secondary-container)]",
|
|
1471
|
+
"[--ib-fg-on:var(--color-on-secondary-container)]"
|
|
1472
|
+
]
|
|
1314
1473
|
},
|
|
1315
1474
|
{
|
|
1316
1475
|
variant: "tonal",
|
|
1317
1476
|
color: "tertiary",
|
|
1318
|
-
|
|
1319
|
-
|
|
1477
|
+
className: [
|
|
1478
|
+
"[--ib-bg:var(--color-tertiary-container)]",
|
|
1479
|
+
"[--ib-fg:var(--color-on-tertiary-container)]",
|
|
1480
|
+
"[--ib-sl:var(--color-on-tertiary-container)]",
|
|
1481
|
+
"[--ib-bg-off:var(--color-surface-container-highest)]",
|
|
1482
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1483
|
+
"[--ib-bg-on:var(--color-tertiary-container)]",
|
|
1484
|
+
"[--ib-fg-on:var(--color-on-tertiary-container)]"
|
|
1485
|
+
]
|
|
1320
1486
|
},
|
|
1321
1487
|
{
|
|
1322
1488
|
variant: "tonal",
|
|
1323
1489
|
color: "error",
|
|
1324
|
-
|
|
1325
|
-
|
|
1490
|
+
className: [
|
|
1491
|
+
"[--ib-bg:var(--color-error-container)]",
|
|
1492
|
+
"[--ib-fg:var(--color-on-error-container)]",
|
|
1493
|
+
"[--ib-sl:var(--color-on-error-container)]",
|
|
1494
|
+
"[--ib-bg-off:var(--color-surface-container-highest)]",
|
|
1495
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1496
|
+
"[--ib-bg-on:var(--color-error-container)]",
|
|
1497
|
+
"[--ib-fg-on:var(--color-on-error-container)]"
|
|
1498
|
+
]
|
|
1326
1499
|
},
|
|
1327
|
-
//
|
|
1328
|
-
//
|
|
1329
|
-
//
|
|
1500
|
+
// ── OUTLINED ──────────────────────────────────────────────────────────
|
|
1501
|
+
// Non-toggle: transparent bg, border-outline, on-surface-variant fg
|
|
1502
|
+
// Toggle off: same as non-toggle
|
|
1503
|
+
// Toggle on (selected): inverse-surface bg, inverse-on-surface fg, no border
|
|
1504
|
+
// Disabled: border becomes on-surface/12 (set via Tailwind utility on root)
|
|
1330
1505
|
{
|
|
1331
|
-
variant: "
|
|
1332
|
-
|
|
1333
|
-
className:
|
|
1506
|
+
variant: "outlined",
|
|
1507
|
+
color: "primary",
|
|
1508
|
+
className: [
|
|
1509
|
+
"[--ib-bg:transparent]",
|
|
1510
|
+
"[--ib-fg:var(--color-on-surface-variant)]",
|
|
1511
|
+
"[--ib-sl:var(--color-on-surface-variant)]",
|
|
1512
|
+
"[--ib-border:var(--color-outline)]",
|
|
1513
|
+
"[--ib-bg-off:transparent]",
|
|
1514
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1515
|
+
"[--ib-bg-on:var(--color-inverse-surface)]",
|
|
1516
|
+
"[--ib-fg-on:var(--color-inverse-on-surface)]",
|
|
1517
|
+
// Disabled outlined border
|
|
1518
|
+
"data-[disabled]:border-on-surface/12"
|
|
1519
|
+
]
|
|
1334
1520
|
},
|
|
1335
|
-
// ====================
|
|
1336
|
-
// OUTLINED VARIANTS (UNSELECTED)
|
|
1337
|
-
// ====================
|
|
1338
1521
|
{
|
|
1339
1522
|
variant: "outlined",
|
|
1340
|
-
|
|
1341
|
-
className:
|
|
1523
|
+
color: "secondary",
|
|
1524
|
+
className: [
|
|
1525
|
+
"[--ib-bg:transparent]",
|
|
1526
|
+
"[--ib-fg:var(--color-on-surface-variant)]",
|
|
1527
|
+
"[--ib-sl:var(--color-on-surface-variant)]",
|
|
1528
|
+
"[--ib-border:var(--color-outline)]",
|
|
1529
|
+
"[--ib-bg-off:transparent]",
|
|
1530
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1531
|
+
"[--ib-bg-on:var(--color-inverse-surface)]",
|
|
1532
|
+
"[--ib-fg-on:var(--color-inverse-on-surface)]",
|
|
1533
|
+
"data-[disabled]:border-on-surface/12"
|
|
1534
|
+
]
|
|
1342
1535
|
},
|
|
1343
|
-
// ====================
|
|
1344
|
-
// OUTLINED VARIANTS (SELECTED - uses inverse colors)
|
|
1345
|
-
// ====================
|
|
1346
1536
|
{
|
|
1347
1537
|
variant: "outlined",
|
|
1348
|
-
|
|
1349
|
-
className:
|
|
1538
|
+
color: "tertiary",
|
|
1539
|
+
className: [
|
|
1540
|
+
"[--ib-bg:transparent]",
|
|
1541
|
+
"[--ib-fg:var(--color-on-surface-variant)]",
|
|
1542
|
+
"[--ib-sl:var(--color-on-surface-variant)]",
|
|
1543
|
+
"[--ib-border:var(--color-outline)]",
|
|
1544
|
+
"[--ib-bg-off:transparent]",
|
|
1545
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1546
|
+
"[--ib-bg-on:var(--color-inverse-surface)]",
|
|
1547
|
+
"[--ib-fg-on:var(--color-inverse-on-surface)]",
|
|
1548
|
+
"data-[disabled]:border-on-surface/12"
|
|
1549
|
+
]
|
|
1550
|
+
},
|
|
1551
|
+
{
|
|
1552
|
+
variant: "outlined",
|
|
1553
|
+
color: "error",
|
|
1554
|
+
className: [
|
|
1555
|
+
"[--ib-bg:transparent]",
|
|
1556
|
+
"[--ib-fg:var(--color-on-surface-variant)]",
|
|
1557
|
+
"[--ib-sl:var(--color-on-surface-variant)]",
|
|
1558
|
+
"[--ib-border:var(--color-outline)]",
|
|
1559
|
+
"[--ib-bg-off:transparent]",
|
|
1560
|
+
"[--ib-fg-off:var(--color-on-surface-variant)]",
|
|
1561
|
+
"[--ib-bg-on:var(--color-inverse-surface)]",
|
|
1562
|
+
"[--ib-fg-on:var(--color-inverse-on-surface)]",
|
|
1563
|
+
"data-[disabled]:border-on-surface/12"
|
|
1564
|
+
]
|
|
1350
1565
|
}
|
|
1351
1566
|
],
|
|
1352
|
-
/**
|
|
1353
|
-
* Default variants
|
|
1354
|
-
*/
|
|
1355
1567
|
defaultVariants: {
|
|
1356
1568
|
variant: "standard",
|
|
1357
1569
|
color: "primary",
|
|
1358
1570
|
size: "medium",
|
|
1359
|
-
|
|
1360
|
-
|
|
1571
|
+
width: "default",
|
|
1572
|
+
shape: "round"
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
);
|
|
1576
|
+
var iconButtonStateLayerVariants = classVarianceAuthority.cva([
|
|
1577
|
+
"absolute inset-0 rounded-[inherit] pointer-events-none opacity-0",
|
|
1578
|
+
"bg-[var(--ib-sl,currentColor)]",
|
|
1579
|
+
// Effects transition (opacity — no spatial overshoot)
|
|
1580
|
+
"transition-opacity duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
|
|
1581
|
+
// Interaction opacities (MD3: hover 8%, focus/pressed 10%)
|
|
1582
|
+
"group-data-[hovered]/icon-button:opacity-8",
|
|
1583
|
+
"group-data-[focus-visible]/icon-button:opacity-10",
|
|
1584
|
+
"group-data-[pressed]/icon-button:opacity-10",
|
|
1585
|
+
// No state layer when disabled
|
|
1586
|
+
"group-data-[disabled]/icon-button:hidden"
|
|
1587
|
+
]);
|
|
1588
|
+
var iconButtonIconVariants = classVarianceAuthority.cva(
|
|
1589
|
+
[
|
|
1590
|
+
"relative z-10 inline-flex shrink-0 items-center justify-center",
|
|
1591
|
+
"transition-colors duration-spring-standard-fast-effects ease-spring-standard-fast-effects"
|
|
1592
|
+
],
|
|
1593
|
+
{
|
|
1594
|
+
variants: {
|
|
1595
|
+
size: {
|
|
1596
|
+
xsmall: "size-5",
|
|
1597
|
+
// 20dp
|
|
1598
|
+
small: "size-6",
|
|
1599
|
+
// 24dp
|
|
1600
|
+
medium: "size-6",
|
|
1601
|
+
// 24dp
|
|
1602
|
+
large: "size-8",
|
|
1603
|
+
// 32dp
|
|
1604
|
+
xlarge: "size-10"
|
|
1605
|
+
// 40dp
|
|
1606
|
+
}
|
|
1607
|
+
},
|
|
1608
|
+
defaultVariants: {
|
|
1609
|
+
size: "medium"
|
|
1361
1610
|
}
|
|
1362
1611
|
}
|
|
1363
1612
|
);
|
|
1364
1613
|
var IconButton = React.forwardRef(
|
|
1365
1614
|
({
|
|
1366
|
-
// Variant props (CVA)
|
|
1615
|
+
// Variant props (CVA / design-time)
|
|
1367
1616
|
variant = "standard",
|
|
1368
1617
|
color = "primary",
|
|
1369
1618
|
size = "medium",
|
|
1619
|
+
width = "default",
|
|
1620
|
+
shape = "round",
|
|
1370
1621
|
// IconButton specific props
|
|
1371
1622
|
children,
|
|
1623
|
+
selectedIcon,
|
|
1372
1624
|
value,
|
|
1373
1625
|
selected,
|
|
1374
1626
|
disableRipple = false,
|
|
1375
1627
|
className,
|
|
1376
1628
|
// React Aria props
|
|
1377
|
-
isDisabled
|
|
1629
|
+
isDisabled = false,
|
|
1378
1630
|
onPress,
|
|
1379
1631
|
onMouseDown,
|
|
1380
1632
|
"aria-label": ariaLabel,
|
|
@@ -1393,7 +1645,8 @@ var IconButton = React.forwardRef(
|
|
|
1393
1645
|
console.warn("[IconButton] IconButton should have an icon as children.");
|
|
1394
1646
|
}
|
|
1395
1647
|
}
|
|
1396
|
-
const
|
|
1648
|
+
const isToggle = selected !== void 0;
|
|
1649
|
+
const isSelected = isToggle ? selected ?? false : false;
|
|
1397
1650
|
const { onMouseDown: handleRipple, ripples } = useRipple({
|
|
1398
1651
|
disabled: isDisabled || disableRipple
|
|
1399
1652
|
});
|
|
@@ -1411,32 +1664,37 @@ var IconButton = React.forwardRef(
|
|
|
1411
1664
|
...getConnectedRadiusClasses(groupCtx, value),
|
|
1412
1665
|
groupCtx.enforceMinWidth ? "min-w-12" : ""
|
|
1413
1666
|
] : [];
|
|
1667
|
+
const iconNode = isToggle && isSelected && selectedIcon ? selectedIcon : children;
|
|
1414
1668
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1415
1669
|
IconButtonHeadless,
|
|
1416
1670
|
{
|
|
1417
1671
|
ref,
|
|
1418
1672
|
className: cn(
|
|
1419
|
-
// CVA
|
|
1420
|
-
|
|
1421
|
-
//
|
|
1422
|
-
|
|
1423
|
-
//
|
|
1424
|
-
// path, preventing the overshoot-to-0px sharp-corner flash.
|
|
1673
|
+
// Root CVA — sets CSS role variables, dimensions, shape, transitions
|
|
1674
|
+
iconButtonRootVariants({ variant, color, size, width, shape }),
|
|
1675
|
+
// Group scope for child slot selectors
|
|
1676
|
+
"group/icon-button",
|
|
1677
|
+
// ButtonGroup asymmetric border-radius easing (connected selection morph)
|
|
1425
1678
|
isGroupSelected ? "btn-transition-selected" : "",
|
|
1426
1679
|
...connectedClasses,
|
|
1427
|
-
//
|
|
1680
|
+
// Consumer custom classes
|
|
1428
1681
|
className
|
|
1429
1682
|
),
|
|
1430
1683
|
"aria-label": ariaLabel,
|
|
1684
|
+
isSelected,
|
|
1685
|
+
isToggle,
|
|
1431
1686
|
"data-variant": variant,
|
|
1432
1687
|
"data-color": color,
|
|
1688
|
+
"data-size": size,
|
|
1689
|
+
"data-width": width,
|
|
1690
|
+
"data-shape": shape,
|
|
1433
1691
|
"data-group-selected": isGroupSelected ? "" : void 0,
|
|
1434
|
-
...selected !== void 0 && { selected },
|
|
1435
1692
|
...title && { title },
|
|
1436
1693
|
...mergedPropsValue,
|
|
1437
1694
|
children: [
|
|
1695
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: iconButtonStateLayerVariants(), "aria-hidden": "true", "data-state-layer": "" }),
|
|
1438
1696
|
ripples,
|
|
1439
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className:
|
|
1697
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: iconButtonIconVariants({ size }), "data-icon-slot": "", "aria-hidden": "true", children: iconNode })
|
|
1440
1698
|
]
|
|
1441
1699
|
}
|
|
1442
1700
|
);
|