@nurix/ui-component-library 1.1.4-stage.116 → 1.1.4-stage.118
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.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +158 -59
- package/dist/index.mjs +158 -59
- package/dist/styles.css +60 -43
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1408,6 +1408,7 @@ declare const DEFAULT_THEME: {
|
|
|
1408
1408
|
readonly borderBrand: "#1d4885";
|
|
1409
1409
|
readonly borderDestructive: "#b91c1c";
|
|
1410
1410
|
readonly borderInput: "#e5e5e5";
|
|
1411
|
+
readonly borderInputHover: "#dadada";
|
|
1411
1412
|
readonly hovOpacityPrimary: "#0a0a0a0d";
|
|
1412
1413
|
readonly hovOpacitySecondary: "#0a0a0a0d";
|
|
1413
1414
|
readonly hovSolidPrimary: "#fafafa";
|
|
@@ -1494,6 +1495,7 @@ declare const DEFAULT_THEME: {
|
|
|
1494
1495
|
readonly borderBrand: "#bfdbfe";
|
|
1495
1496
|
readonly borderDestructive: "#f87171";
|
|
1496
1497
|
readonly borderInput: "#262626";
|
|
1498
|
+
readonly borderInputHover: "#404040";
|
|
1497
1499
|
readonly hovOpacityPrimary: "#ffffff0d";
|
|
1498
1500
|
readonly hovOpacitySecondary: "#ffffff1a";
|
|
1499
1501
|
readonly hovSolidPrimary: "#262626";
|
package/dist/index.d.ts
CHANGED
|
@@ -1408,6 +1408,7 @@ declare const DEFAULT_THEME: {
|
|
|
1408
1408
|
readonly borderBrand: "#1d4885";
|
|
1409
1409
|
readonly borderDestructive: "#b91c1c";
|
|
1410
1410
|
readonly borderInput: "#e5e5e5";
|
|
1411
|
+
readonly borderInputHover: "#dadada";
|
|
1411
1412
|
readonly hovOpacityPrimary: "#0a0a0a0d";
|
|
1412
1413
|
readonly hovOpacitySecondary: "#0a0a0a0d";
|
|
1413
1414
|
readonly hovSolidPrimary: "#fafafa";
|
|
@@ -1494,6 +1495,7 @@ declare const DEFAULT_THEME: {
|
|
|
1494
1495
|
readonly borderBrand: "#bfdbfe";
|
|
1495
1496
|
readonly borderDestructive: "#f87171";
|
|
1496
1497
|
readonly borderInput: "#262626";
|
|
1498
|
+
readonly borderInputHover: "#404040";
|
|
1497
1499
|
readonly hovOpacityPrimary: "#ffffff0d";
|
|
1498
1500
|
readonly hovOpacitySecondary: "#ffffff1a";
|
|
1499
1501
|
readonly hovSolidPrimary: "#262626";
|
package/dist/index.js
CHANGED
|
@@ -6974,6 +6974,7 @@ var DEFAULT_THEME = {
|
|
|
6974
6974
|
borderBrand: "#1d4885",
|
|
6975
6975
|
borderDestructive: "#b91c1c",
|
|
6976
6976
|
borderInput: "#e5e5e5",
|
|
6977
|
+
borderInputHover: "#dadada",
|
|
6977
6978
|
// Interaction tokens (Figma: color > interaction)
|
|
6978
6979
|
hovOpacityPrimary: "#0a0a0a0d",
|
|
6979
6980
|
hovOpacitySecondary: "#0a0a0a0d",
|
|
@@ -7065,6 +7066,7 @@ var DEFAULT_THEME = {
|
|
|
7065
7066
|
borderBrand: "#bfdbfe",
|
|
7066
7067
|
borderDestructive: "#f87171",
|
|
7067
7068
|
borderInput: "#262626",
|
|
7069
|
+
borderInputHover: "#404040",
|
|
7068
7070
|
// Interaction tokens (Figma: color > interaction)
|
|
7069
7071
|
hovOpacityPrimary: "#ffffff0d",
|
|
7070
7072
|
hovOpacitySecondary: "#ffffff1a",
|
|
@@ -7305,14 +7307,19 @@ var INPUT_TOKENS = {
|
|
|
7305
7307
|
// Borderless: used in table-like contexts (key-value editor). No visible
|
|
7306
7308
|
// border at rest. Focus reveals the brand border. No hover/pressed overlay.
|
|
7307
7309
|
fieldBgBorderless: "bg-transparent",
|
|
7308
|
-
// Base border + focus-within treatment.
|
|
7309
|
-
//
|
|
7310
|
-
|
|
7310
|
+
// Base border + focus-within treatment. Hover darkens the border (Figma
|
|
7311
|
+
// hover variant: #dadada). focus-within wins over hover via pseudo-class
|
|
7312
|
+
// ordering, so focus colour still applies when the field is hovered.
|
|
7313
|
+
fieldBase: "border border-token-input focus-within:border-token-brand disabled:pointer-events-none transition-colors",
|
|
7314
|
+
// Hover-only border darkening for the active (non-invalid, non-disabled)
|
|
7315
|
+
// state. Applied conditionally by the component so it does not override
|
|
7316
|
+
// the destructive border on invalid fields.
|
|
7317
|
+
fieldHover: "hover:border-token-input-hover",
|
|
7311
7318
|
// Borderless base — transparent resting border, brand border only on focus.
|
|
7312
7319
|
// No hover/pressed overlay (these cells sit inside a larger interactive row).
|
|
7313
7320
|
// Layout-shift safe: border width stays 1px across states (color-only swap).
|
|
7314
7321
|
fieldBaseBorderless: "border border-transparent focus-within:border-token-brand disabled:pointer-events-none [&>*]:relative [&>*]:z-10",
|
|
7315
|
-
fieldDisabled: "border-token-xlight
|
|
7322
|
+
fieldDisabled: "border-token-xlight",
|
|
7316
7323
|
fieldInvalid: "border-token-destructive focus-within:border-token-destructive",
|
|
7317
7324
|
// Leading/trailing icon slots (Figma: 16px, text-fg-grey-secondary)
|
|
7318
7325
|
slotIcon: "shrink-0 size-4 [&>svg]:size-4 text-fg-grey-secondary",
|
|
@@ -7358,6 +7365,7 @@ var Input = React2.forwardRef(
|
|
|
7358
7365
|
}, ref) => {
|
|
7359
7366
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7360
7367
|
const isFocussed = forceState === "focussed";
|
|
7368
|
+
const isInvalid = invalid || supportingTextType === "error";
|
|
7361
7369
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
7362
7370
|
"div",
|
|
7363
7371
|
{
|
|
@@ -7376,9 +7384,10 @@ var Input = React2.forwardRef(
|
|
|
7376
7384
|
inputSize === "sm" ? INPUT_TOKENS.fieldSizeSm : INPUT_TOKENS.fieldSizeMd,
|
|
7377
7385
|
inputVariant === "borderless" ? INPUT_TOKENS.fieldBgBorderless : inputVariant === "white" ? INPUT_TOKENS.fieldBgWhite : INPUT_TOKENS.fieldBgGrey,
|
|
7378
7386
|
inputVariant === "borderless" ? INPUT_TOKENS.fieldBaseBorderless : INPUT_TOKENS.fieldBase,
|
|
7387
|
+
inputVariant !== "borderless" && !isDisabled && !isInvalid && INPUT_TOKENS.fieldHover,
|
|
7379
7388
|
isDisabled && INPUT_TOKENS.fieldDisabled,
|
|
7380
7389
|
isFocussed && "border-token-brand",
|
|
7381
|
-
|
|
7390
|
+
isInvalid && INPUT_TOKENS.fieldInvalid
|
|
7382
7391
|
),
|
|
7383
7392
|
style: {
|
|
7384
7393
|
borderRadius: INPUT_TOKENS.radius[input_border_radius],
|
|
@@ -7522,7 +7531,10 @@ var INPUT_GROUP_TOKENS = {
|
|
|
7522
7531
|
field: "flex h-[var(--input-height,40px)] w-full items-center gap-2 overflow-hidden px-[var(--input-padding-horizontal,12px)] py-[10px] text-sm shadow-none",
|
|
7523
7532
|
fieldBgGrey: "bg-token-white",
|
|
7524
7533
|
fieldBgWhite: "bg-token-white",
|
|
7525
|
-
fieldBase: "border border-token-light focus-within:border-token-brand disabled:pointer-events-none",
|
|
7534
|
+
fieldBase: "border border-token-light focus-within:border-token-brand disabled:pointer-events-none transition-colors",
|
|
7535
|
+
// Hover-only border darkening (Figma hover variant: #dadada). Applied
|
|
7536
|
+
// conditionally by the component so it does not override invalid/disabled.
|
|
7537
|
+
fieldHover: "hover:border-token-input-hover",
|
|
7526
7538
|
fieldInvalid: "border-token-destructive focus-within:border-token-destructive",
|
|
7527
7539
|
fieldDisabled: "border-token-xlight",
|
|
7528
7540
|
// Inner input area
|
|
@@ -7531,7 +7543,8 @@ var INPUT_GROUP_TOKENS = {
|
|
|
7531
7543
|
segment: "shrink-0 flex items-center text-xs font-normal text-fg-placeholder px-3",
|
|
7532
7544
|
segmentDivider: "border-token-light",
|
|
7533
7545
|
// Textarea
|
|
7534
|
-
textareaField: "w-full bg-token-white py-[10px] px-[var(--input-padding-horizontal,12px)] text-sm border border-token-light focus-visible:outline-none focus-visible:border-token-brand disabled:pointer-events-none shadow-none",
|
|
7546
|
+
textareaField: "w-full bg-token-white py-[10px] px-[var(--input-padding-horizontal,12px)] text-sm border border-token-light focus-visible:outline-none focus-visible:border-token-brand disabled:pointer-events-none shadow-none transition-colors",
|
|
7547
|
+
textareaHover: "hover:border-token-input-hover",
|
|
7535
7548
|
textareaInvalid: "border-token-destructive focus-visible:border-token-destructive",
|
|
7536
7549
|
textareaDisabled: "border-token-xlight",
|
|
7537
7550
|
radius: {
|
|
@@ -7581,6 +7594,7 @@ var InputGroup = React4.forwardRef(
|
|
|
7581
7594
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7582
7595
|
const isFocussed = forceState === "focussed";
|
|
7583
7596
|
const isActive = forceState === "active";
|
|
7597
|
+
const isInvalid = !!invalid;
|
|
7584
7598
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
7585
7599
|
"div",
|
|
7586
7600
|
{
|
|
@@ -7595,9 +7609,10 @@ var InputGroup = React4.forwardRef(
|
|
|
7595
7609
|
INPUT_GROUP_TOKENS.field,
|
|
7596
7610
|
inputVariant === "white" ? INPUT_GROUP_TOKENS.fieldBgWhite : INPUT_GROUP_TOKENS.fieldBgGrey,
|
|
7597
7611
|
INPUT_GROUP_TOKENS.fieldBase,
|
|
7612
|
+
!isDisabled && !isInvalid && INPUT_GROUP_TOKENS.fieldHover,
|
|
7598
7613
|
isDisabled && INPUT_GROUP_TOKENS.fieldDisabled,
|
|
7599
7614
|
isFocussed && "border-token-brand",
|
|
7600
|
-
|
|
7615
|
+
isInvalid && INPUT_GROUP_TOKENS.fieldInvalid
|
|
7601
7616
|
),
|
|
7602
7617
|
style: {
|
|
7603
7618
|
borderRadius: INPUT_GROUP_TOKENS.radius[input_border_radius],
|
|
@@ -7690,16 +7705,18 @@ var TEXTAREA_TOKENS = {
|
|
|
7690
7705
|
labelRow: "flex items-center gap-[2px] text-xs font-medium leading-4 tracking-normal text-fg-black",
|
|
7691
7706
|
mandatory: "text-fg-destructive",
|
|
7692
7707
|
// Base shared field layout/typography.
|
|
7693
|
-
// `relative` + `overflow-hidden` so the `before:` overlay respects the
|
|
7694
|
-
// field's rounded corners via [border-radius:inherit].
|
|
7695
7708
|
field: "relative flex min-h-[80px] w-full flex-col overflow-hidden px-[var(--input-padding-horizontal,12px)] py-[10px] text-sm shadow-none",
|
|
7696
7709
|
fieldBgGrey: "bg-token-white",
|
|
7697
7710
|
fieldBgWhite: "bg-token-white",
|
|
7698
|
-
// Base border + focus treatment.
|
|
7699
|
-
//
|
|
7711
|
+
// Base border + focus treatment. Hover darkens the border (Figma hover
|
|
7712
|
+
// variant: #dadada). focus-within wins over hover via pseudo-class
|
|
7713
|
+
// ordering, so focus colour still applies when the field is hovered.
|
|
7700
7714
|
// Focus ring uses outline (not ring) so it doesn't contribute to box size.
|
|
7701
|
-
fieldBase: "border border-token-input focus-within:border-token-brand disabled:pointer-events-none
|
|
7702
|
-
|
|
7715
|
+
fieldBase: "border border-token-input focus-within:border-token-brand disabled:pointer-events-none transition-colors",
|
|
7716
|
+
// Hover-only border darkening. Applied conditionally by the component so
|
|
7717
|
+
// it does not override invalid/disabled borders.
|
|
7718
|
+
fieldHover: "hover:border-token-input-hover",
|
|
7719
|
+
fieldDisabled: "border-token-xlight",
|
|
7703
7720
|
fieldInvalid: "border-token-destructive focus-within:border-token-destructive",
|
|
7704
7721
|
// Textarea itself.
|
|
7705
7722
|
// `selection:` applies styles to the user's text selection (::selection):
|
|
@@ -7744,6 +7761,7 @@ var Textarea = React5.forwardRef(
|
|
|
7744
7761
|
}, ref) => {
|
|
7745
7762
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7746
7763
|
const isFocussed = forceState === "focussed";
|
|
7764
|
+
const isInvalid = invalid || supportingTextType === "error";
|
|
7747
7765
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
7748
7766
|
"div",
|
|
7749
7767
|
{
|
|
@@ -7761,9 +7779,10 @@ var Textarea = React5.forwardRef(
|
|
|
7761
7779
|
TEXTAREA_TOKENS.field,
|
|
7762
7780
|
inputVariant === "white" ? TEXTAREA_TOKENS.fieldBgWhite : TEXTAREA_TOKENS.fieldBgGrey,
|
|
7763
7781
|
TEXTAREA_TOKENS.fieldBase,
|
|
7782
|
+
!isDisabled && !isInvalid && TEXTAREA_TOKENS.fieldHover,
|
|
7764
7783
|
isDisabled && TEXTAREA_TOKENS.fieldDisabled,
|
|
7765
7784
|
isFocussed && "border-token-brand outline outline-2 outline-token-brand outline-offset-2",
|
|
7766
|
-
|
|
7785
|
+
isInvalid && TEXTAREA_TOKENS.fieldInvalid
|
|
7767
7786
|
),
|
|
7768
7787
|
style: {
|
|
7769
7788
|
borderRadius: TEXTAREA_TOKENS.radius[input_border_radius],
|
|
@@ -8072,14 +8091,25 @@ var NAVIGATION_TOKENS = {
|
|
|
8072
8091
|
// Shared base — focus ring uses design system pattern.
|
|
8073
8092
|
base: "inline-flex items-center cursor-pointer transition-colors focus-visible:outline-2 focus-visible:outline outline-token-brand focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
8074
8093
|
// ----- Page Top Tab -----
|
|
8075
|
-
// Figma 5229:66149 — px-12 py-8, rounded-12, 1.5px
|
|
8076
|
-
//
|
|
8094
|
+
// Figma 5229:66149 — px-12 py-8, rounded-12 (all corners), 1.5px
|
|
8095
|
+
// underline rendered just outside the rounded pill. Same padding
|
|
8096
|
+
// across states to prevent layout shift on selection. The pill itself
|
|
8097
|
+
// does NOT visually merge with the underline; the underline sits
|
|
8098
|
+
// below the pill as a separate horizontal bar that is brand-coloured
|
|
8099
|
+
// for selected, 5% black on hover-unselected, and transparent at rest.
|
|
8077
8100
|
topBase: "justify-center gap-2 px-3 py-2 rounded-xl relative",
|
|
8078
8101
|
topBaseSelected: "justify-center gap-2 px-3 py-2 rounded-xl relative",
|
|
8079
8102
|
topLabelSelected: "text-base font-semibold leading-6 text-fg-brand shrink-0",
|
|
8080
8103
|
topLabelUnselected: "text-base font-semibold leading-6 text-fg-grey-primary shrink-0",
|
|
8081
|
-
// 1.5px
|
|
8082
|
-
|
|
8104
|
+
// 1.5px underline anchored ~6px BELOW the rounded pill (Figma 5229:66149
|
|
8105
|
+
// places the bar at `top-[46px]` for a 40px pill — a 6px breathing gap
|
|
8106
|
+
// between pill bottom and bar). Coloured per state via the *Selected /
|
|
8107
|
+
// *Hover / *Default modifiers.
|
|
8108
|
+
topHighlight: "pointer-events-none absolute -bottom-1.5 left-0 right-0 h-[1.5px] rounded-sm transition-colors",
|
|
8109
|
+
topHighlightSelected: "bg-token-brand-primary",
|
|
8110
|
+
// Faint 5% black bar on hover of unselected — matches Figma 5229:66155.
|
|
8111
|
+
topHighlightHover: "bg-transparent group-hover/tab:bg-interaction-hov-opacity-primary",
|
|
8112
|
+
topHighlightDefault: "bg-transparent",
|
|
8083
8113
|
// Interaction layers specific to top tab.
|
|
8084
8114
|
topHoverUnselected: "hover:bg-interaction-hov-solid-primary",
|
|
8085
8115
|
topHoverSelected: "hover:bg-interaction-hov-solid-primary",
|
|
@@ -8269,6 +8299,7 @@ var TabsTrigger = React12.forwardRef(
|
|
|
8269
8299
|
selected ? selectedClass : NAVIGATION_TOKENS.tab.unselected,
|
|
8270
8300
|
hoverClass,
|
|
8271
8301
|
pressedClass,
|
|
8302
|
+
v2 === "top" && "group/tab",
|
|
8272
8303
|
className
|
|
8273
8304
|
),
|
|
8274
8305
|
disabled,
|
|
@@ -8279,7 +8310,16 @@ var TabsTrigger = React12.forwardRef(
|
|
|
8279
8310
|
children: [
|
|
8280
8311
|
iconLeft ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: cn(NAVIGATION_TOKENS.tab.iconWrap, iconColor), children: iconLeft }) : null,
|
|
8281
8312
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: cn(NAVIGATION_TOKENS.tab.labelBase, labelClass), children }),
|
|
8282
|
-
v2 === "top" &&
|
|
8313
|
+
v2 === "top" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
8314
|
+
"span",
|
|
8315
|
+
{
|
|
8316
|
+
className: cn(
|
|
8317
|
+
NAVIGATION_TOKENS.tab.topHighlight,
|
|
8318
|
+
selected ? NAVIGATION_TOKENS.tab.topHighlightSelected : NAVIGATION_TOKENS.tab.topHighlightHover
|
|
8319
|
+
),
|
|
8320
|
+
"aria-hidden": "true"
|
|
8321
|
+
}
|
|
8322
|
+
)
|
|
8283
8323
|
]
|
|
8284
8324
|
}
|
|
8285
8325
|
);
|
|
@@ -8857,6 +8897,7 @@ var UI_COLOR_KEY_TO_CSS_VAR = {
|
|
|
8857
8897
|
borderBrand: "--border-brand",
|
|
8858
8898
|
borderDestructive: "--border-destructive",
|
|
8859
8899
|
borderInput: "--border-input",
|
|
8900
|
+
borderInputHover: "--border-input-hover",
|
|
8860
8901
|
// Interaction tokens (Figma: color > interaction)
|
|
8861
8902
|
hovOpacityPrimary: "--hov-opacity-primary",
|
|
8862
8903
|
hovOpacitySecondary: "--hov-opacity-secondary",
|
|
@@ -9227,8 +9268,12 @@ var import_lucide_react6 = require("lucide-react");
|
|
|
9227
9268
|
var SELECT_TOKENS = {
|
|
9228
9269
|
// Main select container
|
|
9229
9270
|
container: {
|
|
9230
|
-
// Figma: trigger uses rounded-xl (12px), border visible, padding px-12 py-10
|
|
9231
|
-
|
|
9271
|
+
// Figma: trigger uses rounded-xl (12px), border visible, padding px-12 py-10.
|
|
9272
|
+
// Hover darkens the border to match Figma (#dadada) — `data-[state=open]`
|
|
9273
|
+
// and `disabled:` use higher specificity (attribute / pseudo-class) so they
|
|
9274
|
+
// override the hover border when the dropdown is open or the trigger is
|
|
9275
|
+
// disabled.
|
|
9276
|
+
default: "rounded-[var(--rounded-xl,12px)] border border-token-input flex items-center justify-between gap-2 transition-colors hover:border-token-input-hover disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:border-token-input focus-visible:outline-none data-[state=open]:border-token-brand",
|
|
9232
9277
|
// bg variants: default = input (grey), white = card
|
|
9233
9278
|
bgDefault: "bg-token-white",
|
|
9234
9279
|
bgWhite: "bg-token-white",
|
|
@@ -10709,9 +10754,9 @@ var TOAST_TOKENS = {
|
|
|
10709
10754
|
// Inner content row — Figma: px-16 py-12, gap-12, items-center, full width
|
|
10710
10755
|
innerRow: "flex gap-3 items-center px-4 py-3 w-full",
|
|
10711
10756
|
icon: {
|
|
10712
|
-
success: "text-fg-success shrink-0
|
|
10713
|
-
error: "text-fg-destructive shrink-0
|
|
10714
|
-
default: "text-fg-black shrink-0
|
|
10757
|
+
success: "text-fg-success shrink-0 size-4",
|
|
10758
|
+
error: "text-fg-destructive shrink-0 size-4",
|
|
10759
|
+
default: "text-fg-black shrink-0 size-4"
|
|
10715
10760
|
},
|
|
10716
10761
|
// Title + subtext column — Figma: flex-1, flex-col, gap-0
|
|
10717
10762
|
content: "flex flex-col flex-1 min-w-0",
|
|
@@ -11446,7 +11491,24 @@ var TABLE_TOKENS = {
|
|
|
11446
11491
|
* element itself and stays visible through the scroll.
|
|
11447
11492
|
* A second outer shadow extends to the right so users can tell the column
|
|
11448
11493
|
* is pinned even when the bordering unpinned column is visually similar. */
|
|
11449
|
-
|
|
11494
|
+
// Pinned-column right edge — Figma 5087:54840.
|
|
11495
|
+
// • `inset` shadow draws a 1px hairline at the cell's right edge.
|
|
11496
|
+
// • `before:` pseudo paints the elevation gradient INSIDE the cell at
|
|
11497
|
+
// its right edge. CSS `border-collapse: collapse` plus the cell's
|
|
11498
|
+
// own `overflow-hidden` (needed for text truncation) blocks an
|
|
11499
|
+
// outer drop-shadow from rendering, so we simulate the shadow with
|
|
11500
|
+
// an absolutely-positioned gradient that fades from transparent to
|
|
11501
|
+
// ~10% black across the last 8px of the cell. The pinned column
|
|
11502
|
+
// reads as elevated above the scrolling content beside it without
|
|
11503
|
+
// us having to drop overflow-hidden everywhere.
|
|
11504
|
+
// Pinned-column right edge — Figma 5087:54840.
|
|
11505
|
+
// • Inset 1px hairline (border-light) so the column always has a clear
|
|
11506
|
+
// boundary line.
|
|
11507
|
+
// • Outer drop-shadow extending right INTO the unpinned area below it.
|
|
11508
|
+
// Using strong x-offset / -spread so the shadow only paints to the
|
|
11509
|
+
// right (not on top/bottom). Sticky cell sits at z-20, unpinned cells
|
|
11510
|
+
// at z-0, so the shadow is always painted above the scrolling content.
|
|
11511
|
+
pinnedLastBorder: "shadow-[inset_-1px_0_0_0_hsl(var(--border-light)),12px_0_12px_-8px_rgba(0,0,0,0.18)]",
|
|
11450
11512
|
// ── Checkbox column — Figma: w-40, px-12 py-8
|
|
11451
11513
|
checkboxCell: "w-10 px-3 py-2",
|
|
11452
11514
|
// ── Actions column ──
|
|
@@ -12038,8 +12100,10 @@ var FILTER_SELECT_TOKENS = {
|
|
|
12038
12100
|
// Disabled
|
|
12039
12101
|
disabled: "disabled:opacity-50 disabled:pointer-events-none"
|
|
12040
12102
|
},
|
|
12041
|
-
// Left icon — Figma: icon/black, 16px
|
|
12042
|
-
|
|
12103
|
+
// Left icon — Figma: icon/black, 16px. Force `stroke-width: 1.5` on inner
|
|
12104
|
+
// SVG so lucide icons (which default to 2) read at the same visual weight
|
|
12105
|
+
// as the lighter HugeiconsIcon strokes used elsewhere in the bar.
|
|
12106
|
+
icon: "shrink-0 size-4 text-fg-black [&]:[stroke-width:1.5]",
|
|
12043
12107
|
// Label — Label/sm: Nunito medium 12/16 black.
|
|
12044
12108
|
// The "Without Label" variant (used as right pill inside CompoundFilterSelect — Figma
|
|
12045
12109
|
// 5427:32334) shows the selected value as the label itself in text/brand, Subtext/xs
|
|
@@ -12067,7 +12131,7 @@ var FILTER_SELECT_TOKENS = {
|
|
|
12067
12131
|
// Symmetric 4px padding on all sides — prevents the extra whitespace
|
|
12068
12132
|
// below the last list item / footer that used to come from `pb-2`.
|
|
12069
12133
|
"p-1 rounded-[16px] shadow-sm",
|
|
12070
|
-
"min-w-[196px] font-sans",
|
|
12134
|
+
"min-w-[196px] min-h-[144px] font-sans",
|
|
12071
12135
|
"outline-none"
|
|
12072
12136
|
].join(" "),
|
|
12073
12137
|
// Date dropdown — tight 4px padding on all sides so the calendar / presets
|
|
@@ -12271,8 +12335,10 @@ var FILTER_SELECT_TOKENS = {
|
|
|
12271
12335
|
"w-full resize-none",
|
|
12272
12336
|
"min-h-[114px] px-2 py-1",
|
|
12273
12337
|
"rounded-[12px] bg-token-white",
|
|
12274
|
-
//
|
|
12275
|
-
|
|
12338
|
+
// Reserve 1px border so focus state doesn't shift layout. The brand
|
|
12339
|
+
// colour only paints while the textarea actually has focus.
|
|
12340
|
+
"border border-solid border-token-light",
|
|
12341
|
+
"focus:border-token-brand",
|
|
12276
12342
|
"font-sans text-xs font-normal leading-4 text-fg-black",
|
|
12277
12343
|
"placeholder:text-fg-placeholder",
|
|
12278
12344
|
"outline-none transition-colors"
|
|
@@ -12289,10 +12355,11 @@ var FILTER_SELECT_TOKENS = {
|
|
|
12289
12355
|
"focus-within:border-token-brand"
|
|
12290
12356
|
].join(" "),
|
|
12291
12357
|
// Compact variant — used by the duration filter so the dropdown doesn't
|
|
12292
|
-
// stretch edge-to-edge.
|
|
12358
|
+
// stretch edge-to-edge. Sized to roughly match a single field of the
|
|
12359
|
+
// range layout so single/range modes feel visually consistent.
|
|
12293
12360
|
wrapperCompact: [
|
|
12294
12361
|
"flex items-center gap-2",
|
|
12295
|
-
"w-
|
|
12362
|
+
"w-[88px] px-3 h-8 min-h-[32px]",
|
|
12296
12363
|
"rounded-[12px] bg-token-white",
|
|
12297
12364
|
"border border-solid border-token-light",
|
|
12298
12365
|
"transition-colors",
|
|
@@ -12947,8 +13014,9 @@ var CalendarMonthCaption = ({
|
|
|
12947
13014
|
onDateChange == null ? void 0 : onDateChange({ start: date == null ? void 0 : date.start, end: d });
|
|
12948
13015
|
}
|
|
12949
13016
|
};
|
|
13017
|
+
const phantomSlotClass = "size-8 shrink-0";
|
|
12950
13018
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center justify-between gap-1 w-full px-0 py-1", children: [
|
|
12951
|
-
isFirst
|
|
13019
|
+
isFirst ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
12952
13020
|
"button",
|
|
12953
13021
|
{
|
|
12954
13022
|
type: "button",
|
|
@@ -12958,8 +13026,8 @@ var CalendarMonthCaption = ({
|
|
|
12958
13026
|
disabled: !previousMonth,
|
|
12959
13027
|
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react16.ChevronLeft, { className: "size-4" })
|
|
12960
13028
|
}
|
|
12961
|
-
),
|
|
12962
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center gap-1 flex-1 justify-
|
|
13029
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: phantomSlotClass, "aria-hidden": "true" }),
|
|
13030
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center gap-1 flex-1 justify-center", children: [
|
|
12963
13031
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
12964
13032
|
MonthSelectPill,
|
|
12965
13033
|
{
|
|
@@ -12991,7 +13059,7 @@ var CalendarMonthCaption = ({
|
|
|
12991
13059
|
}
|
|
12992
13060
|
)
|
|
12993
13061
|
] }),
|
|
12994
|
-
isLast
|
|
13062
|
+
isLast ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
12995
13063
|
"button",
|
|
12996
13064
|
{
|
|
12997
13065
|
type: "button",
|
|
@@ -13001,7 +13069,7 @@ var CalendarMonthCaption = ({
|
|
|
13001
13069
|
disabled: !nextMonth,
|
|
13002
13070
|
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react16.ChevronRight, { className: "size-4" })
|
|
13003
13071
|
}
|
|
13004
|
-
)
|
|
13072
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: phantomSlotClass, "aria-hidden": "true" })
|
|
13005
13073
|
] });
|
|
13006
13074
|
};
|
|
13007
13075
|
var DEFAULT_DURATION_UNITS = [
|
|
@@ -13066,7 +13134,20 @@ var FilterSelect = React37.forwardRef(
|
|
|
13066
13134
|
const open = controlledOpen != null ? controlledOpen : internalOpen;
|
|
13067
13135
|
const [searchQuery, setSearchQuery] = React37.useState("");
|
|
13068
13136
|
const triggerRef = React37.useRef(null);
|
|
13137
|
+
const searchInputRef = React37.useRef(null);
|
|
13138
|
+
const numericInputRef = React37.useRef(null);
|
|
13139
|
+
const rangeMinInputRef = React37.useRef(null);
|
|
13069
13140
|
const [triggerWidth, setTriggerWidth] = React37.useState(null);
|
|
13141
|
+
const focusActiveBodyInput = React37.useCallback(() => {
|
|
13142
|
+
requestAnimationFrame(() => {
|
|
13143
|
+
var _a5, _b5;
|
|
13144
|
+
if (isRangeMode) {
|
|
13145
|
+
(_a5 = rangeMinInputRef.current) == null ? void 0 : _a5.focus();
|
|
13146
|
+
} else {
|
|
13147
|
+
(_b5 = numericInputRef.current) == null ? void 0 : _b5.focus();
|
|
13148
|
+
}
|
|
13149
|
+
});
|
|
13150
|
+
}, [isRangeMode]);
|
|
13070
13151
|
const [focusedMonth, setFocusedMonth] = React37.useState(
|
|
13071
13152
|
() => {
|
|
13072
13153
|
var _a5;
|
|
@@ -13393,8 +13474,13 @@ var FilterSelect = React37.forwardRef(
|
|
|
13393
13474
|
setDraggedValue(null);
|
|
13394
13475
|
setDragOverValue(null);
|
|
13395
13476
|
}, []);
|
|
13396
|
-
const isCompactBody = type === "duration"
|
|
13397
|
-
const
|
|
13477
|
+
const isCompactBody = type === "duration";
|
|
13478
|
+
const supportsRangeOperand = type === "numeric_with_operands" && operands.some(
|
|
13479
|
+
(op) => op.value === "Is between" || op.label === "Is between" || /between/i.test(op.value) || /between/i.test(op.label)
|
|
13480
|
+
);
|
|
13481
|
+
const numericWithOperandsWidth = 224;
|
|
13482
|
+
const bodyMinWidth = supportsRangeOperand ? Math.max(numericWithOperandsWidth, triggerWidth != null ? triggerWidth : 0) : isCompactBody ? Math.max(160, triggerWidth != null ? triggerWidth : 0) : Math.max(196, triggerWidth != null ? triggerWidth : 0);
|
|
13483
|
+
const bodyMaxWidth = supportsRangeOperand ? Math.max(numericWithOperandsWidth, triggerWidth != null ? triggerWidth : 0) : void 0;
|
|
13398
13484
|
const renderFooterClear = (onClick, labelText, ariaLabel) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: FILTER_SELECT_TOKENS.footer.wrapper, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
13399
13485
|
"button",
|
|
13400
13486
|
{
|
|
@@ -13521,7 +13607,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13521
13607
|
maxHeight: type === "date" ? void 0 : dropdownMaxHeight,
|
|
13522
13608
|
minHeight: loading ? dropdownMaxHeight : void 0,
|
|
13523
13609
|
minWidth: bodyMinWidth,
|
|
13524
|
-
maxWidth:
|
|
13610
|
+
maxWidth: bodyMaxWidth
|
|
13525
13611
|
},
|
|
13526
13612
|
side: "bottom",
|
|
13527
13613
|
align: "start",
|
|
@@ -13551,7 +13637,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13551
13637
|
autoFocus: true
|
|
13552
13638
|
}
|
|
13553
13639
|
) }),
|
|
13554
|
-
|
|
13640
|
+
showClearBtn && renderFooterClear(handleTextClear, footerActionLabel, `${footerActionLabel} text`)
|
|
13555
13641
|
] }) : type === "text_with_operands" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
13556
13642
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "p-1 flex flex-col gap-2", children: [
|
|
13557
13643
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
@@ -13576,7 +13662,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13576
13662
|
}
|
|
13577
13663
|
)
|
|
13578
13664
|
] }),
|
|
13579
|
-
|
|
13665
|
+
showClearBtn && renderFooterClear(
|
|
13580
13666
|
handleTextClear,
|
|
13581
13667
|
footerActionLabel,
|
|
13582
13668
|
`${footerActionLabel} filter`
|
|
@@ -13596,25 +13682,29 @@ var FilterSelect = React37.forwardRef(
|
|
|
13596
13682
|
),
|
|
13597
13683
|
unitLabel && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: FILTER_SELECT_TOKENS.bodyInput.unit, children: unitLabel })
|
|
13598
13684
|
] }) }),
|
|
13599
|
-
|
|
13685
|
+
showClearBtn && renderFooterClear(handleTextClear, footerActionLabel, `${footerActionLabel} number`)
|
|
13600
13686
|
] }) : type === "numeric_with_operands" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
13601
13687
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "p-1 flex flex-col gap-2", children: [
|
|
13602
13688
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13603
13689
|
OperandDropdown,
|
|
13604
13690
|
{
|
|
13605
13691
|
value: operand != null ? operand : "",
|
|
13606
|
-
onChange: (v2) =>
|
|
13692
|
+
onChange: (v2) => {
|
|
13693
|
+
onOperandChange == null ? void 0 : onOperandChange(v2);
|
|
13694
|
+
focusActiveBodyInput();
|
|
13695
|
+
},
|
|
13607
13696
|
options: operands,
|
|
13608
13697
|
placeholder: operandPlaceholder,
|
|
13609
13698
|
container,
|
|
13610
13699
|
themeClass
|
|
13611
13700
|
}
|
|
13612
13701
|
),
|
|
13613
|
-
isRangeMode ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center gap-2
|
|
13614
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: FILTER_SELECT_TOKENS.bodyInput.
|
|
13702
|
+
isRangeMode ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
13703
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: FILTER_SELECT_TOKENS.bodyInput.wrapperCompact, children: [
|
|
13615
13704
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13616
13705
|
"input",
|
|
13617
13706
|
{
|
|
13707
|
+
ref: rangeMinInputRef,
|
|
13618
13708
|
type: "text",
|
|
13619
13709
|
inputMode: "numeric",
|
|
13620
13710
|
pattern: "[0-9]*",
|
|
@@ -13638,7 +13728,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13638
13728
|
)
|
|
13639
13729
|
] }),
|
|
13640
13730
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: FILTER_SELECT_TOKENS.rangeDivider, children: "-" }),
|
|
13641
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: FILTER_SELECT_TOKENS.bodyInput.
|
|
13731
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: FILTER_SELECT_TOKENS.bodyInput.wrapperCompact, children: [
|
|
13642
13732
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13643
13733
|
"input",
|
|
13644
13734
|
{
|
|
@@ -13668,6 +13758,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13668
13758
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13669
13759
|
"input",
|
|
13670
13760
|
{
|
|
13761
|
+
ref: numericInputRef,
|
|
13671
13762
|
type: "number",
|
|
13672
13763
|
value: text != null ? text : "",
|
|
13673
13764
|
onChange: (e) => onTextChange == null ? void 0 : onTextChange(e.target.value),
|
|
@@ -13679,7 +13770,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13679
13770
|
unitLabel && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: FILTER_SELECT_TOKENS.bodyInput.unit, children: unitLabel })
|
|
13680
13771
|
] })
|
|
13681
13772
|
] }),
|
|
13682
|
-
|
|
13773
|
+
showClearBtn && renderFooterClear(
|
|
13683
13774
|
() => {
|
|
13684
13775
|
onTextChange == null ? void 0 : onTextChange("");
|
|
13685
13776
|
onOperandChange == null ? void 0 : onOperandChange("");
|
|
@@ -13735,7 +13826,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13735
13826
|
unitLabel && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: FILTER_SELECT_TOKENS.bodyInput.unit, children: unitLabel })
|
|
13736
13827
|
] })
|
|
13737
13828
|
] }) }),
|
|
13738
|
-
|
|
13829
|
+
showClearBtn && renderFooterClear(
|
|
13739
13830
|
() => {
|
|
13740
13831
|
onRangeMinChange == null ? void 0 : onRangeMinChange("");
|
|
13741
13832
|
onRangeMaxChange == null ? void 0 : onRangeMaxChange("");
|
|
@@ -13769,7 +13860,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13769
13860
|
}
|
|
13770
13861
|
)
|
|
13771
13862
|
] }),
|
|
13772
|
-
|
|
13863
|
+
showClearBtn && renderFooterClear(
|
|
13773
13864
|
() => {
|
|
13774
13865
|
onTextChange == null ? void 0 : onTextChange("");
|
|
13775
13866
|
onDurationUnitChange == null ? void 0 : onDurationUnitChange("");
|
|
@@ -13812,7 +13903,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13812
13903
|
preset.value
|
|
13813
13904
|
);
|
|
13814
13905
|
}) }),
|
|
13815
|
-
|
|
13906
|
+
showClearBtn && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13816
13907
|
"div",
|
|
13817
13908
|
{
|
|
13818
13909
|
className: FILTER_SELECT_TOKENS.datePresetSidebarAction.wrapper,
|
|
@@ -13895,7 +13986,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13895
13986
|
// inside our custom MonthCaption on the outer edges.
|
|
13896
13987
|
Nav: () => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_jsx_runtime33.Fragment, {})
|
|
13897
13988
|
},
|
|
13898
|
-
className: "p-0 font-sans [&_.rdp-day_button]:rounded-[8px]"
|
|
13989
|
+
className: "p-0 font-sans [&_.rdp-day_button]:rounded-[8px] [&_.rdp-months]:gap-3"
|
|
13899
13990
|
}
|
|
13900
13991
|
)
|
|
13901
13992
|
}
|
|
@@ -13903,7 +13994,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13903
13994
|
]
|
|
13904
13995
|
}
|
|
13905
13996
|
),
|
|
13906
|
-
datePresets === false &&
|
|
13997
|
+
datePresets === false && showClearBtn && renderFooterClear(
|
|
13907
13998
|
handleDateClear,
|
|
13908
13999
|
footerActionLabel,
|
|
13909
14000
|
`${footerActionLabel} date range`
|
|
@@ -13918,11 +14009,13 @@ var FilterSelect = React37.forwardRef(
|
|
|
13918
14009
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13919
14010
|
"input",
|
|
13920
14011
|
{
|
|
14012
|
+
ref: searchInputRef,
|
|
13921
14013
|
type: "text",
|
|
13922
14014
|
value: searchQuery,
|
|
13923
14015
|
onChange: (e) => setSearchQuery(e.target.value),
|
|
13924
14016
|
placeholder: searchPlaceholder || "Search...",
|
|
13925
14017
|
"aria-label": "Search options",
|
|
14018
|
+
autoFocus: true,
|
|
13926
14019
|
className: FILTER_SELECT_TOKENS.searchBar.input
|
|
13927
14020
|
}
|
|
13928
14021
|
),
|
|
@@ -13999,7 +14092,7 @@ var FilterSelect = React37.forwardRef(
|
|
|
13999
14092
|
String(item.value)
|
|
14000
14093
|
);
|
|
14001
14094
|
}) }),
|
|
14002
|
-
showClearBtn &&
|
|
14095
|
+
showClearBtn && renderFooterClear(
|
|
14003
14096
|
handleClearAll,
|
|
14004
14097
|
footerActionLabel,
|
|
14005
14098
|
`${footerActionLabel} all selected items`
|
|
@@ -14156,8 +14249,12 @@ function CompoundFilterSelect({
|
|
|
14156
14249
|
// Force children's rounded corners to be right-only and remove left border to overlap
|
|
14157
14250
|
"[&>*]:!rounded-none [&>*]:!rounded-r-[16px]",
|
|
14158
14251
|
"[&_button[data-state]]:!rounded-none [&_button[data-state]]:!rounded-r-[16px]",
|
|
14159
|
-
// Paint the FilterSelect label in brand blue
|
|
14160
|
-
|
|
14252
|
+
// Paint the FilterSelect label in brand blue when it carries a value
|
|
14253
|
+
// (Figma 5427:32334). When the right pill is empty / showing a
|
|
14254
|
+
// placeholder, render the label in placeholder grey instead so it
|
|
14255
|
+
// reads as a hint rather than a real selection.
|
|
14256
|
+
"[&_button[data-has-value]_[data-filter-label]]:!text-fg-brand",
|
|
14257
|
+
"[&_button:not([data-has-value])_[data-filter-label]]:!text-fg-placeholder",
|
|
14161
14258
|
"[&_[data-filter-label]]:!font-normal",
|
|
14162
14259
|
// In a compound pill, the right-side label IS the value — there is no
|
|
14163
14260
|
// separate label/value split to divide. Hide the internal separator
|
|
@@ -15729,8 +15826,10 @@ var CHAT_BUBBLE_TOKENS = {
|
|
|
15729
15826
|
timestampRow: "flex items-center justify-end gap-2 pr-5"
|
|
15730
15827
|
},
|
|
15731
15828
|
user: {
|
|
15732
|
-
// Row: avatar first, then text (no bubble).
|
|
15733
|
-
|
|
15829
|
+
// Row: avatar first, then text (no bubble). `pr-5` mirrors the
|
|
15830
|
+
// 16px avatar + 4px gap on the left so message text doesn't run flush
|
|
15831
|
+
// to the container's right edge.
|
|
15832
|
+
row: "flex items-end gap-1 w-full pr-5",
|
|
15734
15833
|
// 16px grey circle holding the user icon.
|
|
15735
15834
|
avatar: "shrink-0 size-4 rounded-full bg-token-grey flex items-center justify-center text-fg-grey-secondary [&>svg]:size-3",
|
|
15736
15835
|
// Message text — per Figma: 14px regular, grey-secondary.
|