@nurix/ui-component-library 1.1.4-stage.117 → 1.1.4-stage.119
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 +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +55 -19
- package/dist/index.mjs +55 -19
- package/dist/styles.css +30 -36
- 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";
|
|
@@ -1588,6 +1590,10 @@ interface DialogProps {
|
|
|
1588
1590
|
showCancel?: boolean;
|
|
1589
1591
|
onCancel?: () => void;
|
|
1590
1592
|
onConfirm?: () => void;
|
|
1593
|
+
/** @default "primary" */
|
|
1594
|
+
confirmVariant?: ButtonVariant;
|
|
1595
|
+
/** Disable the confirm button. */
|
|
1596
|
+
confirmDisabled?: boolean;
|
|
1591
1597
|
className?: string;
|
|
1592
1598
|
}
|
|
1593
1599
|
interface DialogIconProps {
|
|
@@ -1615,6 +1621,10 @@ interface DialogFooterProps {
|
|
|
1615
1621
|
showCancel?: boolean;
|
|
1616
1622
|
onCancel?: () => void;
|
|
1617
1623
|
onConfirm?: () => void;
|
|
1624
|
+
/** @default "primary" */
|
|
1625
|
+
confirmVariant?: ButtonVariant;
|
|
1626
|
+
/** Disable the confirm button. */
|
|
1627
|
+
confirmDisabled?: boolean;
|
|
1618
1628
|
showDivider?: boolean;
|
|
1619
1629
|
className?: string;
|
|
1620
1630
|
}
|
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";
|
|
@@ -1588,6 +1590,10 @@ interface DialogProps {
|
|
|
1588
1590
|
showCancel?: boolean;
|
|
1589
1591
|
onCancel?: () => void;
|
|
1590
1592
|
onConfirm?: () => void;
|
|
1593
|
+
/** @default "primary" */
|
|
1594
|
+
confirmVariant?: ButtonVariant;
|
|
1595
|
+
/** Disable the confirm button. */
|
|
1596
|
+
confirmDisabled?: boolean;
|
|
1591
1597
|
className?: string;
|
|
1592
1598
|
}
|
|
1593
1599
|
interface DialogIconProps {
|
|
@@ -1615,6 +1621,10 @@ interface DialogFooterProps {
|
|
|
1615
1621
|
showCancel?: boolean;
|
|
1616
1622
|
onCancel?: () => void;
|
|
1617
1623
|
onConfirm?: () => void;
|
|
1624
|
+
/** @default "primary" */
|
|
1625
|
+
confirmVariant?: ButtonVariant;
|
|
1626
|
+
/** Disable the confirm button. */
|
|
1627
|
+
confirmDisabled?: boolean;
|
|
1618
1628
|
showDivider?: boolean;
|
|
1619
1629
|
className?: string;
|
|
1620
1630
|
}
|
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,10 +7307,17 @@ 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.
|
|
7311
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. The `:not(:focus-within)`
|
|
7317
|
+
// guard is required because Tailwind emits `:hover` rules AFTER
|
|
7318
|
+
// `:focus-within` — without it, hovering a focused field would replace
|
|
7319
|
+
// the brand border with the hover border.
|
|
7320
|
+
fieldHover: "[&:not(:focus-within)]:hover:border-token-input-hover",
|
|
7312
7321
|
// Borderless base — transparent resting border, brand border only on focus.
|
|
7313
7322
|
// No hover/pressed overlay (these cells sit inside a larger interactive row).
|
|
7314
7323
|
// Layout-shift safe: border width stays 1px across states (color-only swap).
|
|
@@ -7359,6 +7368,7 @@ var Input = React2.forwardRef(
|
|
|
7359
7368
|
}, ref) => {
|
|
7360
7369
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7361
7370
|
const isFocussed = forceState === "focussed";
|
|
7371
|
+
const isInvalid = invalid || supportingTextType === "error";
|
|
7362
7372
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
7363
7373
|
"div",
|
|
7364
7374
|
{
|
|
@@ -7377,9 +7387,10 @@ var Input = React2.forwardRef(
|
|
|
7377
7387
|
inputSize === "sm" ? INPUT_TOKENS.fieldSizeSm : INPUT_TOKENS.fieldSizeMd,
|
|
7378
7388
|
inputVariant === "borderless" ? INPUT_TOKENS.fieldBgBorderless : inputVariant === "white" ? INPUT_TOKENS.fieldBgWhite : INPUT_TOKENS.fieldBgGrey,
|
|
7379
7389
|
inputVariant === "borderless" ? INPUT_TOKENS.fieldBaseBorderless : INPUT_TOKENS.fieldBase,
|
|
7390
|
+
inputVariant !== "borderless" && !isDisabled && !isInvalid && INPUT_TOKENS.fieldHover,
|
|
7380
7391
|
isDisabled && INPUT_TOKENS.fieldDisabled,
|
|
7381
7392
|
isFocussed && "border-token-brand",
|
|
7382
|
-
|
|
7393
|
+
isInvalid && INPUT_TOKENS.fieldInvalid
|
|
7383
7394
|
),
|
|
7384
7395
|
style: {
|
|
7385
7396
|
borderRadius: INPUT_TOKENS.radius[input_border_radius],
|
|
@@ -7523,7 +7534,12 @@ var INPUT_GROUP_TOKENS = {
|
|
|
7523
7534
|
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",
|
|
7524
7535
|
fieldBgGrey: "bg-token-white",
|
|
7525
7536
|
fieldBgWhite: "bg-token-white",
|
|
7526
|
-
fieldBase: "border border-token-light focus-within:border-token-brand disabled:pointer-events-none",
|
|
7537
|
+
fieldBase: "border border-token-light focus-within:border-token-brand disabled:pointer-events-none transition-colors",
|
|
7538
|
+
// Hover-only border darkening (Figma hover variant: #dadada). Applied
|
|
7539
|
+
// conditionally by the component so it does not override invalid/disabled.
|
|
7540
|
+
// The `:not(:focus-within)` guard prevents the hover border from beating
|
|
7541
|
+
// the brand focus border (Tailwind emits `:hover` after `:focus-within`).
|
|
7542
|
+
fieldHover: "[&:not(:focus-within)]:hover:border-token-input-hover",
|
|
7527
7543
|
fieldInvalid: "border-token-destructive focus-within:border-token-destructive",
|
|
7528
7544
|
fieldDisabled: "border-token-xlight",
|
|
7529
7545
|
// Inner input area
|
|
@@ -7532,7 +7548,8 @@ var INPUT_GROUP_TOKENS = {
|
|
|
7532
7548
|
segment: "shrink-0 flex items-center text-xs font-normal text-fg-placeholder px-3",
|
|
7533
7549
|
segmentDivider: "border-token-light",
|
|
7534
7550
|
// Textarea
|
|
7535
|
-
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",
|
|
7551
|
+
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",
|
|
7552
|
+
textareaHover: "[&:not(:focus-within)]:hover:border-token-input-hover",
|
|
7536
7553
|
textareaInvalid: "border-token-destructive focus-visible:border-token-destructive",
|
|
7537
7554
|
textareaDisabled: "border-token-xlight",
|
|
7538
7555
|
radius: {
|
|
@@ -7582,6 +7599,7 @@ var InputGroup = React4.forwardRef(
|
|
|
7582
7599
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7583
7600
|
const isFocussed = forceState === "focussed";
|
|
7584
7601
|
const isActive = forceState === "active";
|
|
7602
|
+
const isInvalid = !!invalid;
|
|
7585
7603
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
7586
7604
|
"div",
|
|
7587
7605
|
{
|
|
@@ -7596,9 +7614,10 @@ var InputGroup = React4.forwardRef(
|
|
|
7596
7614
|
INPUT_GROUP_TOKENS.field,
|
|
7597
7615
|
inputVariant === "white" ? INPUT_GROUP_TOKENS.fieldBgWhite : INPUT_GROUP_TOKENS.fieldBgGrey,
|
|
7598
7616
|
INPUT_GROUP_TOKENS.fieldBase,
|
|
7617
|
+
!isDisabled && !isInvalid && INPUT_GROUP_TOKENS.fieldHover,
|
|
7599
7618
|
isDisabled && INPUT_GROUP_TOKENS.fieldDisabled,
|
|
7600
7619
|
isFocussed && "border-token-brand",
|
|
7601
|
-
|
|
7620
|
+
isInvalid && INPUT_GROUP_TOKENS.fieldInvalid
|
|
7602
7621
|
),
|
|
7603
7622
|
style: {
|
|
7604
7623
|
borderRadius: INPUT_GROUP_TOKENS.radius[input_border_radius],
|
|
@@ -7691,16 +7710,20 @@ var TEXTAREA_TOKENS = {
|
|
|
7691
7710
|
labelRow: "flex items-center gap-[2px] text-xs font-medium leading-4 tracking-normal text-fg-black",
|
|
7692
7711
|
mandatory: "text-fg-destructive",
|
|
7693
7712
|
// Base shared field layout/typography.
|
|
7694
|
-
// `relative` + `overflow-hidden` so the `before:` overlay respects the
|
|
7695
|
-
// field's rounded corners via [border-radius:inherit].
|
|
7696
7713
|
field: "relative flex min-h-[80px] w-full flex-col overflow-hidden px-[var(--input-padding-horizontal,12px)] py-[10px] text-sm shadow-none",
|
|
7697
7714
|
fieldBgGrey: "bg-token-white",
|
|
7698
7715
|
fieldBgWhite: "bg-token-white",
|
|
7699
|
-
// Base border + focus treatment.
|
|
7700
|
-
//
|
|
7716
|
+
// Base border + focus treatment. Hover darkens the border (Figma hover
|
|
7717
|
+
// variant: #dadada). focus-within wins over hover via pseudo-class
|
|
7718
|
+
// ordering, so focus colour still applies when the field is hovered.
|
|
7701
7719
|
// Focus ring uses outline (not ring) so it doesn't contribute to box size.
|
|
7702
|
-
fieldBase: "border border-token-input focus-within:border-token-brand disabled:pointer-events-none
|
|
7703
|
-
|
|
7720
|
+
fieldBase: "border border-token-input focus-within:border-token-brand disabled:pointer-events-none transition-colors",
|
|
7721
|
+
// Hover-only border darkening. Applied conditionally by the component so
|
|
7722
|
+
// it does not override invalid/disabled borders. The `:not(:focus-within)`
|
|
7723
|
+
// guard keeps the brand focus border visible when a focused field is
|
|
7724
|
+
// hovered (Tailwind emits `:hover` after `:focus-within`).
|
|
7725
|
+
fieldHover: "[&:not(:focus-within)]:hover:border-token-input-hover",
|
|
7726
|
+
fieldDisabled: "border-token-xlight",
|
|
7704
7727
|
fieldInvalid: "border-token-destructive focus-within:border-token-destructive",
|
|
7705
7728
|
// Textarea itself.
|
|
7706
7729
|
// `selection:` applies styles to the user's text selection (::selection):
|
|
@@ -7745,6 +7768,7 @@ var Textarea = React5.forwardRef(
|
|
|
7745
7768
|
}, ref) => {
|
|
7746
7769
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7747
7770
|
const isFocussed = forceState === "focussed";
|
|
7771
|
+
const isInvalid = invalid || supportingTextType === "error";
|
|
7748
7772
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
7749
7773
|
"div",
|
|
7750
7774
|
{
|
|
@@ -7762,9 +7786,10 @@ var Textarea = React5.forwardRef(
|
|
|
7762
7786
|
TEXTAREA_TOKENS.field,
|
|
7763
7787
|
inputVariant === "white" ? TEXTAREA_TOKENS.fieldBgWhite : TEXTAREA_TOKENS.fieldBgGrey,
|
|
7764
7788
|
TEXTAREA_TOKENS.fieldBase,
|
|
7789
|
+
!isDisabled && !isInvalid && TEXTAREA_TOKENS.fieldHover,
|
|
7765
7790
|
isDisabled && TEXTAREA_TOKENS.fieldDisabled,
|
|
7766
7791
|
isFocussed && "border-token-brand outline outline-2 outline-token-brand outline-offset-2",
|
|
7767
|
-
|
|
7792
|
+
isInvalid && TEXTAREA_TOKENS.fieldInvalid
|
|
7768
7793
|
),
|
|
7769
7794
|
style: {
|
|
7770
7795
|
borderRadius: TEXTAREA_TOKENS.radius[input_border_radius],
|
|
@@ -8879,6 +8904,7 @@ var UI_COLOR_KEY_TO_CSS_VAR = {
|
|
|
8879
8904
|
borderBrand: "--border-brand",
|
|
8880
8905
|
borderDestructive: "--border-destructive",
|
|
8881
8906
|
borderInput: "--border-input",
|
|
8907
|
+
borderInputHover: "--border-input-hover",
|
|
8882
8908
|
// Interaction tokens (Figma: color > interaction)
|
|
8883
8909
|
hovOpacityPrimary: "--hov-opacity-primary",
|
|
8884
8910
|
hovOpacitySecondary: "--hov-opacity-secondary",
|
|
@@ -9249,8 +9275,12 @@ var import_lucide_react6 = require("lucide-react");
|
|
|
9249
9275
|
var SELECT_TOKENS = {
|
|
9250
9276
|
// Main select container
|
|
9251
9277
|
container: {
|
|
9252
|
-
// Figma: trigger uses rounded-xl (12px), border visible, padding px-12 py-10
|
|
9253
|
-
|
|
9278
|
+
// Figma: trigger uses rounded-xl (12px), border visible, padding px-12 py-10.
|
|
9279
|
+
// Hover darkens the border to match Figma (#dadada). The hover is scoped
|
|
9280
|
+
// via `[&:not([data-state=open])]` so the brand border wins when the
|
|
9281
|
+
// dropdown is open (Tailwind emits `data-[*]` selectors before `:hover`,
|
|
9282
|
+
// so without the guard hover would override the open-state border).
|
|
9283
|
+
default: "rounded-[var(--rounded-xl,12px)] border border-token-input flex items-center justify-between gap-2 transition-colors [&:not([data-state=open])]: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",
|
|
9254
9284
|
// bg variants: default = input (grey), white = card
|
|
9255
9285
|
bgDefault: "bg-token-white",
|
|
9256
9286
|
bgWhite: "bg-token-white",
|
|
@@ -10519,7 +10549,7 @@ var DIALOG_TOKENS = {
|
|
|
10519
10549
|
},
|
|
10520
10550
|
header: {
|
|
10521
10551
|
wrapper: "flex flex-col shrink-0",
|
|
10522
|
-
row: "flex items-center gap-[10px] px-6
|
|
10552
|
+
row: "flex items-center gap-[10px] px-6 pt-6 pb-2",
|
|
10523
10553
|
title: "flex-1 text-lg font-semibold leading-7 text-fg-black",
|
|
10524
10554
|
closeBtn: "size-9 flex items-center justify-center rounded-md text-fg-black hover:bg-token-grey transition-colors cursor-pointer",
|
|
10525
10555
|
divider: "h-px bg-border-token-light"
|
|
@@ -10554,6 +10584,8 @@ var Dialog = React29.forwardRef(
|
|
|
10554
10584
|
showCancel = true,
|
|
10555
10585
|
onCancel,
|
|
10556
10586
|
onConfirm,
|
|
10587
|
+
confirmVariant = "primary",
|
|
10588
|
+
confirmDisabled = false,
|
|
10557
10589
|
className
|
|
10558
10590
|
}, ref) => {
|
|
10559
10591
|
const close = React29.useCallback(() => onOpenChange(false), [onOpenChange]);
|
|
@@ -10626,9 +10658,10 @@ var Dialog = React29.forwardRef(
|
|
|
10626
10658
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
10627
10659
|
Button,
|
|
10628
10660
|
{
|
|
10629
|
-
variant:
|
|
10661
|
+
variant: confirmVariant,
|
|
10630
10662
|
button_border_radius: "rounded",
|
|
10631
10663
|
onClick: onConfirm,
|
|
10664
|
+
disabled: confirmDisabled,
|
|
10632
10665
|
children: confirmLabel
|
|
10633
10666
|
}
|
|
10634
10667
|
)
|
|
@@ -10688,6 +10721,8 @@ var DialogFooter = React29.forwardRef(
|
|
|
10688
10721
|
showCancel = true,
|
|
10689
10722
|
onCancel,
|
|
10690
10723
|
onConfirm,
|
|
10724
|
+
confirmVariant = "primary",
|
|
10725
|
+
confirmDisabled = false,
|
|
10691
10726
|
showDivider = false,
|
|
10692
10727
|
className
|
|
10693
10728
|
}, ref) => {
|
|
@@ -10707,9 +10742,10 @@ var DialogFooter = React29.forwardRef(
|
|
|
10707
10742
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
10708
10743
|
Button,
|
|
10709
10744
|
{
|
|
10710
|
-
variant:
|
|
10745
|
+
variant: confirmVariant,
|
|
10711
10746
|
button_border_radius: "rounded",
|
|
10712
10747
|
onClick: onConfirm,
|
|
10748
|
+
disabled: confirmDisabled,
|
|
10713
10749
|
children: confirmLabel
|
|
10714
10750
|
}
|
|
10715
10751
|
)
|
package/dist/index.mjs
CHANGED
|
@@ -6870,6 +6870,7 @@ var DEFAULT_THEME = {
|
|
|
6870
6870
|
borderBrand: "#1d4885",
|
|
6871
6871
|
borderDestructive: "#b91c1c",
|
|
6872
6872
|
borderInput: "#e5e5e5",
|
|
6873
|
+
borderInputHover: "#dadada",
|
|
6873
6874
|
// Interaction tokens (Figma: color > interaction)
|
|
6874
6875
|
hovOpacityPrimary: "#0a0a0a0d",
|
|
6875
6876
|
hovOpacitySecondary: "#0a0a0a0d",
|
|
@@ -6961,6 +6962,7 @@ var DEFAULT_THEME = {
|
|
|
6961
6962
|
borderBrand: "#bfdbfe",
|
|
6962
6963
|
borderDestructive: "#f87171",
|
|
6963
6964
|
borderInput: "#262626",
|
|
6965
|
+
borderInputHover: "#404040",
|
|
6964
6966
|
// Interaction tokens (Figma: color > interaction)
|
|
6965
6967
|
hovOpacityPrimary: "#ffffff0d",
|
|
6966
6968
|
hovOpacitySecondary: "#ffffff1a",
|
|
@@ -7201,10 +7203,17 @@ var INPUT_TOKENS = {
|
|
|
7201
7203
|
// Borderless: used in table-like contexts (key-value editor). No visible
|
|
7202
7204
|
// border at rest. Focus reveals the brand border. No hover/pressed overlay.
|
|
7203
7205
|
fieldBgBorderless: "bg-transparent",
|
|
7204
|
-
// Base border + focus-within treatment.
|
|
7205
|
-
//
|
|
7206
|
-
//
|
|
7206
|
+
// Base border + focus-within treatment. Hover darkens the border (Figma
|
|
7207
|
+
// hover variant: #dadada). focus-within wins over hover via pseudo-class
|
|
7208
|
+
// ordering, so focus colour still applies when the field is hovered.
|
|
7207
7209
|
fieldBase: "border border-token-input focus-within:border-token-brand disabled:pointer-events-none transition-colors",
|
|
7210
|
+
// Hover-only border darkening for the active (non-invalid, non-disabled)
|
|
7211
|
+
// state. Applied conditionally by the component so it does not override
|
|
7212
|
+
// the destructive border on invalid fields. The `:not(:focus-within)`
|
|
7213
|
+
// guard is required because Tailwind emits `:hover` rules AFTER
|
|
7214
|
+
// `:focus-within` — without it, hovering a focused field would replace
|
|
7215
|
+
// the brand border with the hover border.
|
|
7216
|
+
fieldHover: "[&:not(:focus-within)]:hover:border-token-input-hover",
|
|
7208
7217
|
// Borderless base — transparent resting border, brand border only on focus.
|
|
7209
7218
|
// No hover/pressed overlay (these cells sit inside a larger interactive row).
|
|
7210
7219
|
// Layout-shift safe: border width stays 1px across states (color-only swap).
|
|
@@ -7255,6 +7264,7 @@ var Input = React2.forwardRef(
|
|
|
7255
7264
|
}, ref) => {
|
|
7256
7265
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7257
7266
|
const isFocussed = forceState === "focussed";
|
|
7267
|
+
const isInvalid = invalid || supportingTextType === "error";
|
|
7258
7268
|
return /* @__PURE__ */ jsxs2(
|
|
7259
7269
|
"div",
|
|
7260
7270
|
{
|
|
@@ -7273,9 +7283,10 @@ var Input = React2.forwardRef(
|
|
|
7273
7283
|
inputSize === "sm" ? INPUT_TOKENS.fieldSizeSm : INPUT_TOKENS.fieldSizeMd,
|
|
7274
7284
|
inputVariant === "borderless" ? INPUT_TOKENS.fieldBgBorderless : inputVariant === "white" ? INPUT_TOKENS.fieldBgWhite : INPUT_TOKENS.fieldBgGrey,
|
|
7275
7285
|
inputVariant === "borderless" ? INPUT_TOKENS.fieldBaseBorderless : INPUT_TOKENS.fieldBase,
|
|
7286
|
+
inputVariant !== "borderless" && !isDisabled && !isInvalid && INPUT_TOKENS.fieldHover,
|
|
7276
7287
|
isDisabled && INPUT_TOKENS.fieldDisabled,
|
|
7277
7288
|
isFocussed && "border-token-brand",
|
|
7278
|
-
|
|
7289
|
+
isInvalid && INPUT_TOKENS.fieldInvalid
|
|
7279
7290
|
),
|
|
7280
7291
|
style: {
|
|
7281
7292
|
borderRadius: INPUT_TOKENS.radius[input_border_radius],
|
|
@@ -7419,7 +7430,12 @@ var INPUT_GROUP_TOKENS = {
|
|
|
7419
7430
|
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",
|
|
7420
7431
|
fieldBgGrey: "bg-token-white",
|
|
7421
7432
|
fieldBgWhite: "bg-token-white",
|
|
7422
|
-
fieldBase: "border border-token-light focus-within:border-token-brand disabled:pointer-events-none",
|
|
7433
|
+
fieldBase: "border border-token-light focus-within:border-token-brand disabled:pointer-events-none transition-colors",
|
|
7434
|
+
// Hover-only border darkening (Figma hover variant: #dadada). Applied
|
|
7435
|
+
// conditionally by the component so it does not override invalid/disabled.
|
|
7436
|
+
// The `:not(:focus-within)` guard prevents the hover border from beating
|
|
7437
|
+
// the brand focus border (Tailwind emits `:hover` after `:focus-within`).
|
|
7438
|
+
fieldHover: "[&:not(:focus-within)]:hover:border-token-input-hover",
|
|
7423
7439
|
fieldInvalid: "border-token-destructive focus-within:border-token-destructive",
|
|
7424
7440
|
fieldDisabled: "border-token-xlight",
|
|
7425
7441
|
// Inner input area
|
|
@@ -7428,7 +7444,8 @@ var INPUT_GROUP_TOKENS = {
|
|
|
7428
7444
|
segment: "shrink-0 flex items-center text-xs font-normal text-fg-placeholder px-3",
|
|
7429
7445
|
segmentDivider: "border-token-light",
|
|
7430
7446
|
// Textarea
|
|
7431
|
-
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",
|
|
7447
|
+
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",
|
|
7448
|
+
textareaHover: "[&:not(:focus-within)]:hover:border-token-input-hover",
|
|
7432
7449
|
textareaInvalid: "border-token-destructive focus-visible:border-token-destructive",
|
|
7433
7450
|
textareaDisabled: "border-token-xlight",
|
|
7434
7451
|
radius: {
|
|
@@ -7478,6 +7495,7 @@ var InputGroup = React4.forwardRef(
|
|
|
7478
7495
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7479
7496
|
const isFocussed = forceState === "focussed";
|
|
7480
7497
|
const isActive = forceState === "active";
|
|
7498
|
+
const isInvalid = !!invalid;
|
|
7481
7499
|
return /* @__PURE__ */ jsxs4(
|
|
7482
7500
|
"div",
|
|
7483
7501
|
{
|
|
@@ -7492,9 +7510,10 @@ var InputGroup = React4.forwardRef(
|
|
|
7492
7510
|
INPUT_GROUP_TOKENS.field,
|
|
7493
7511
|
inputVariant === "white" ? INPUT_GROUP_TOKENS.fieldBgWhite : INPUT_GROUP_TOKENS.fieldBgGrey,
|
|
7494
7512
|
INPUT_GROUP_TOKENS.fieldBase,
|
|
7513
|
+
!isDisabled && !isInvalid && INPUT_GROUP_TOKENS.fieldHover,
|
|
7495
7514
|
isDisabled && INPUT_GROUP_TOKENS.fieldDisabled,
|
|
7496
7515
|
isFocussed && "border-token-brand",
|
|
7497
|
-
|
|
7516
|
+
isInvalid && INPUT_GROUP_TOKENS.fieldInvalid
|
|
7498
7517
|
),
|
|
7499
7518
|
style: {
|
|
7500
7519
|
borderRadius: INPUT_GROUP_TOKENS.radius[input_border_radius],
|
|
@@ -7587,16 +7606,20 @@ var TEXTAREA_TOKENS = {
|
|
|
7587
7606
|
labelRow: "flex items-center gap-[2px] text-xs font-medium leading-4 tracking-normal text-fg-black",
|
|
7588
7607
|
mandatory: "text-fg-destructive",
|
|
7589
7608
|
// Base shared field layout/typography.
|
|
7590
|
-
// `relative` + `overflow-hidden` so the `before:` overlay respects the
|
|
7591
|
-
// field's rounded corners via [border-radius:inherit].
|
|
7592
7609
|
field: "relative flex min-h-[80px] w-full flex-col overflow-hidden px-[var(--input-padding-horizontal,12px)] py-[10px] text-sm shadow-none",
|
|
7593
7610
|
fieldBgGrey: "bg-token-white",
|
|
7594
7611
|
fieldBgWhite: "bg-token-white",
|
|
7595
|
-
// Base border + focus treatment.
|
|
7596
|
-
//
|
|
7612
|
+
// Base border + focus treatment. Hover darkens the border (Figma hover
|
|
7613
|
+
// variant: #dadada). focus-within wins over hover via pseudo-class
|
|
7614
|
+
// ordering, so focus colour still applies when the field is hovered.
|
|
7597
7615
|
// Focus ring uses outline (not ring) so it doesn't contribute to box size.
|
|
7598
|
-
fieldBase: "border border-token-input focus-within:border-token-brand disabled:pointer-events-none
|
|
7599
|
-
|
|
7616
|
+
fieldBase: "border border-token-input focus-within:border-token-brand disabled:pointer-events-none transition-colors",
|
|
7617
|
+
// Hover-only border darkening. Applied conditionally by the component so
|
|
7618
|
+
// it does not override invalid/disabled borders. The `:not(:focus-within)`
|
|
7619
|
+
// guard keeps the brand focus border visible when a focused field is
|
|
7620
|
+
// hovered (Tailwind emits `:hover` after `:focus-within`).
|
|
7621
|
+
fieldHover: "[&:not(:focus-within)]:hover:border-token-input-hover",
|
|
7622
|
+
fieldDisabled: "border-token-xlight",
|
|
7600
7623
|
fieldInvalid: "border-token-destructive focus-within:border-token-destructive",
|
|
7601
7624
|
// Textarea itself.
|
|
7602
7625
|
// `selection:` applies styles to the user's text selection (::selection):
|
|
@@ -7641,6 +7664,7 @@ var Textarea = React5.forwardRef(
|
|
|
7641
7664
|
}, ref) => {
|
|
7642
7665
|
const isDisabled = forceState === "disabled" || disabled;
|
|
7643
7666
|
const isFocussed = forceState === "focussed";
|
|
7667
|
+
const isInvalid = invalid || supportingTextType === "error";
|
|
7644
7668
|
return /* @__PURE__ */ jsxs5(
|
|
7645
7669
|
"div",
|
|
7646
7670
|
{
|
|
@@ -7658,9 +7682,10 @@ var Textarea = React5.forwardRef(
|
|
|
7658
7682
|
TEXTAREA_TOKENS.field,
|
|
7659
7683
|
inputVariant === "white" ? TEXTAREA_TOKENS.fieldBgWhite : TEXTAREA_TOKENS.fieldBgGrey,
|
|
7660
7684
|
TEXTAREA_TOKENS.fieldBase,
|
|
7685
|
+
!isDisabled && !isInvalid && TEXTAREA_TOKENS.fieldHover,
|
|
7661
7686
|
isDisabled && TEXTAREA_TOKENS.fieldDisabled,
|
|
7662
7687
|
isFocussed && "border-token-brand outline outline-2 outline-token-brand outline-offset-2",
|
|
7663
|
-
|
|
7688
|
+
isInvalid && TEXTAREA_TOKENS.fieldInvalid
|
|
7664
7689
|
),
|
|
7665
7690
|
style: {
|
|
7666
7691
|
borderRadius: TEXTAREA_TOKENS.radius[input_border_radius],
|
|
@@ -8775,6 +8800,7 @@ var UI_COLOR_KEY_TO_CSS_VAR = {
|
|
|
8775
8800
|
borderBrand: "--border-brand",
|
|
8776
8801
|
borderDestructive: "--border-destructive",
|
|
8777
8802
|
borderInput: "--border-input",
|
|
8803
|
+
borderInputHover: "--border-input-hover",
|
|
8778
8804
|
// Interaction tokens (Figma: color > interaction)
|
|
8779
8805
|
hovOpacityPrimary: "--hov-opacity-primary",
|
|
8780
8806
|
hovOpacitySecondary: "--hov-opacity-secondary",
|
|
@@ -9145,8 +9171,12 @@ import { Check as Check3, ChevronDown as ChevronDown3, Search } from "lucide-rea
|
|
|
9145
9171
|
var SELECT_TOKENS = {
|
|
9146
9172
|
// Main select container
|
|
9147
9173
|
container: {
|
|
9148
|
-
// Figma: trigger uses rounded-xl (12px), border visible, padding px-12 py-10
|
|
9149
|
-
|
|
9174
|
+
// Figma: trigger uses rounded-xl (12px), border visible, padding px-12 py-10.
|
|
9175
|
+
// Hover darkens the border to match Figma (#dadada). The hover is scoped
|
|
9176
|
+
// via `[&:not([data-state=open])]` so the brand border wins when the
|
|
9177
|
+
// dropdown is open (Tailwind emits `data-[*]` selectors before `:hover`,
|
|
9178
|
+
// so without the guard hover would override the open-state border).
|
|
9179
|
+
default: "rounded-[var(--rounded-xl,12px)] border border-token-input flex items-center justify-between gap-2 transition-colors [&:not([data-state=open])]: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",
|
|
9150
9180
|
// bg variants: default = input (grey), white = card
|
|
9151
9181
|
bgDefault: "bg-token-white",
|
|
9152
9182
|
bgWhite: "bg-token-white",
|
|
@@ -10415,7 +10445,7 @@ var DIALOG_TOKENS = {
|
|
|
10415
10445
|
},
|
|
10416
10446
|
header: {
|
|
10417
10447
|
wrapper: "flex flex-col shrink-0",
|
|
10418
|
-
row: "flex items-center gap-[10px] px-6
|
|
10448
|
+
row: "flex items-center gap-[10px] px-6 pt-6 pb-2",
|
|
10419
10449
|
title: "flex-1 text-lg font-semibold leading-7 text-fg-black",
|
|
10420
10450
|
closeBtn: "size-9 flex items-center justify-center rounded-md text-fg-black hover:bg-token-grey transition-colors cursor-pointer",
|
|
10421
10451
|
divider: "h-px bg-border-token-light"
|
|
@@ -10450,6 +10480,8 @@ var Dialog = React29.forwardRef(
|
|
|
10450
10480
|
showCancel = true,
|
|
10451
10481
|
onCancel,
|
|
10452
10482
|
onConfirm,
|
|
10483
|
+
confirmVariant = "primary",
|
|
10484
|
+
confirmDisabled = false,
|
|
10453
10485
|
className
|
|
10454
10486
|
}, ref) => {
|
|
10455
10487
|
const close = React29.useCallback(() => onOpenChange(false), [onOpenChange]);
|
|
@@ -10522,9 +10554,10 @@ var Dialog = React29.forwardRef(
|
|
|
10522
10554
|
/* @__PURE__ */ jsx25(
|
|
10523
10555
|
Button,
|
|
10524
10556
|
{
|
|
10525
|
-
variant:
|
|
10557
|
+
variant: confirmVariant,
|
|
10526
10558
|
button_border_radius: "rounded",
|
|
10527
10559
|
onClick: onConfirm,
|
|
10560
|
+
disabled: confirmDisabled,
|
|
10528
10561
|
children: confirmLabel
|
|
10529
10562
|
}
|
|
10530
10563
|
)
|
|
@@ -10584,6 +10617,8 @@ var DialogFooter = React29.forwardRef(
|
|
|
10584
10617
|
showCancel = true,
|
|
10585
10618
|
onCancel,
|
|
10586
10619
|
onConfirm,
|
|
10620
|
+
confirmVariant = "primary",
|
|
10621
|
+
confirmDisabled = false,
|
|
10587
10622
|
showDivider = false,
|
|
10588
10623
|
className
|
|
10589
10624
|
}, ref) => {
|
|
@@ -10603,9 +10638,10 @@ var DialogFooter = React29.forwardRef(
|
|
|
10603
10638
|
/* @__PURE__ */ jsx25(
|
|
10604
10639
|
Button,
|
|
10605
10640
|
{
|
|
10606
|
-
variant:
|
|
10641
|
+
variant: confirmVariant,
|
|
10607
10642
|
button_border_radius: "rounded",
|
|
10608
10643
|
onClick: onConfirm,
|
|
10644
|
+
disabled: confirmDisabled,
|
|
10609
10645
|
children: confirmLabel
|
|
10610
10646
|
}
|
|
10611
10647
|
)
|
package/dist/styles.css
CHANGED
|
@@ -1511,15 +1511,9 @@
|
|
|
1511
1511
|
.lego-land .py-4 {
|
|
1512
1512
|
padding-block: calc(var(--spacing) * 4);
|
|
1513
1513
|
}
|
|
1514
|
-
.lego-land .py-6 {
|
|
1515
|
-
padding-block: calc(var(--spacing) * 6);
|
|
1516
|
-
}
|
|
1517
1514
|
.lego-land .py-8 {
|
|
1518
1515
|
padding-block: calc(var(--spacing) * 8);
|
|
1519
1516
|
}
|
|
1520
|
-
.lego-land .py-10 {
|
|
1521
|
-
padding-block: calc(var(--spacing) * 10);
|
|
1522
|
-
}
|
|
1523
1517
|
.lego-land .py-\[3px\] {
|
|
1524
1518
|
padding-block: 3px;
|
|
1525
1519
|
}
|
|
@@ -1541,6 +1535,9 @@
|
|
|
1541
1535
|
.lego-land .pt-4 {
|
|
1542
1536
|
padding-top: calc(var(--spacing) * 4);
|
|
1543
1537
|
}
|
|
1538
|
+
.lego-land .pt-6 {
|
|
1539
|
+
padding-top: calc(var(--spacing) * 6);
|
|
1540
|
+
}
|
|
1544
1541
|
.lego-land .pr-2 {
|
|
1545
1542
|
padding-right: calc(var(--spacing) * 2);
|
|
1546
1543
|
}
|
|
@@ -2160,24 +2157,12 @@
|
|
|
2160
2157
|
inset: calc(var(--spacing) * 0);
|
|
2161
2158
|
}
|
|
2162
2159
|
}
|
|
2163
|
-
.lego-land .before\:\[border-radius\:inherit\] {
|
|
2164
|
-
.lego-land &::before {
|
|
2165
|
-
content: var(--tw-content);
|
|
2166
|
-
border-radius: inherit;
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
2160
|
.lego-land .before\:rounded-full {
|
|
2170
2161
|
.lego-land &::before {
|
|
2171
2162
|
content: var(--tw-content);
|
|
2172
2163
|
border-radius: calc(infinity * 1px);
|
|
2173
2164
|
}
|
|
2174
2165
|
}
|
|
2175
|
-
.lego-land .before\:bg-transparent {
|
|
2176
|
-
.lego-land &::before {
|
|
2177
|
-
content: var(--tw-content);
|
|
2178
|
-
background-color: transparent;
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
2166
|
.lego-land .before\:transition-colors {
|
|
2182
2167
|
.lego-land &::before {
|
|
2183
2168
|
content: var(--tw-content);
|
|
@@ -2388,16 +2373,6 @@
|
|
|
2388
2373
|
}
|
|
2389
2374
|
}
|
|
2390
2375
|
}
|
|
2391
|
-
.lego-land .hover\:before\:bg-transparent {
|
|
2392
|
-
.lego-land &:hover {
|
|
2393
|
-
@media (hover: hover) {
|
|
2394
|
-
&::before {
|
|
2395
|
-
content: var(--tw-content);
|
|
2396
|
-
background-color: transparent;
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
}
|
|
2400
|
-
}
|
|
2401
2376
|
.lego-land .hover\:after\:opacity-100 {
|
|
2402
2377
|
.lego-land &:hover {
|
|
2403
2378
|
@media (hover: hover) {
|
|
@@ -2531,14 +2506,6 @@
|
|
|
2531
2506
|
}
|
|
2532
2507
|
}
|
|
2533
2508
|
}
|
|
2534
|
-
.lego-land .active\:before\:bg-transparent {
|
|
2535
|
-
.lego-land &:active {
|
|
2536
|
-
.lego-land &::before {
|
|
2537
|
-
content: var(--tw-content);
|
|
2538
|
-
background-color: transparent;
|
|
2539
|
-
}
|
|
2540
|
-
}
|
|
2541
|
-
}
|
|
2542
2509
|
.lego-land .active\:after\:bg-black\/25 {
|
|
2543
2510
|
.lego-land &:active {
|
|
2544
2511
|
.lego-land &::after {
|
|
@@ -2608,6 +2575,15 @@
|
|
|
2608
2575
|
opacity: 100%;
|
|
2609
2576
|
}
|
|
2610
2577
|
}
|
|
2578
|
+
.lego-land .disabled\:hover\:border-token-input {
|
|
2579
|
+
.lego-land &:disabled {
|
|
2580
|
+
.lego-land &:hover {
|
|
2581
|
+
@media (hover: hover) {
|
|
2582
|
+
border-color: hsl(var(--border-input));
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2611
2587
|
.lego-land .disabled\:hover\:before\:bg-transparent {
|
|
2612
2588
|
.lego-land &:disabled {
|
|
2613
2589
|
.lego-land &:hover {
|
|
@@ -2842,6 +2818,24 @@
|
|
|
2842
2818
|
appearance: none;
|
|
2843
2819
|
}
|
|
2844
2820
|
}
|
|
2821
|
+
.lego-land .\[\&\:not\(\:focus-within\)\]\:hover\:border-token-input-hover {
|
|
2822
|
+
.lego-land &:not(:focus-within) {
|
|
2823
|
+
.lego-land &:hover {
|
|
2824
|
+
@media (hover: hover) {
|
|
2825
|
+
border-color: hsl(var(--border-input-hover));
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
.lego-land .\[\&\:not\(\[data-state\=open\]\)\]\:hover\:border-token-input-hover {
|
|
2831
|
+
.lego-land &:not([data-state=open]) {
|
|
2832
|
+
.lego-land &:hover {
|
|
2833
|
+
@media (hover: hover) {
|
|
2834
|
+
border-color: hsl(var(--border-input-hover));
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2845
2839
|
.lego-land .\[\&\>\*\]\:relative {
|
|
2846
2840
|
.lego-land &>* {
|
|
2847
2841
|
position: relative;
|