@getgreenline/blaze-ui 1.0.41 → 1.0.43

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.
@@ -3,7 +3,7 @@ import { type VariantProps } from "class-variance-authority";
3
3
  import { Button } from "../components/button";
4
4
  declare function InputGroup({ className, ...props }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
5
5
  declare const inputGroupAddonVariants: (props?: ({
6
- align?: "inline-end" | "inline-start" | "block-start" | "block-end" | null | undefined;
6
+ align?: "inline-end" | "inline-start" | "block-end" | "block-start" | null | undefined;
7
7
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
8
  declare function InputGroupAddon({ className, align, ...props }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>): import("react/jsx-runtime").JSX.Element;
9
9
  declare const inputGroupButtonVariants: (props?: ({
@@ -1,4 +1,8 @@
1
1
  import * as React from "react";
2
- declare function Input({ className, type, ...props }: React.ComponentProps<"input">): import("react/jsx-runtime").JSX.Element;
2
+ import { type AttentionKey } from "../hooks/use-invalid-attention";
3
+ type InputProps = React.ComponentProps<"input"> & {
4
+ attentionKey?: AttentionKey;
5
+ };
6
+ declare function Input({ attentionKey, className, style, type, ...props }: InputProps): import("react/jsx-runtime").JSX.Element;
3
7
  export { Input };
4
8
  //# sourceMappingURL=input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/components/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,iBAAS,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,2CAc1E;AAED,OAAO,EAAE,KAAK,EAAE,CAAA"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/components/input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,gCAAgC,CAAA;AAEvC,KAAK,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG;IAChD,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B,CAAA;AAED,iBAAS,KAAK,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,2CAsB5E;AAED,OAAO,EAAE,KAAK,EAAE,CAAA"}
@@ -1,8 +1,15 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { cn } from '../lib/utils.js';
3
+ import { isAriaInvalid, useInvalidAttention } from '../hooks/use-invalid-attention.js';
3
4
 
4
- function Input({ className, type, ...props }) {
5
- return (jsx("input", { type: type, "data-slot": "input", className: cn("tw:file:text-foreground tw:placeholder:text-input-placeholder tw:selection:bg-primary tw:selection:text-primary-foreground tw:dark:bg-input/30 tw:border-border tw:h-10 tw:w-full tw:min-w-0 tw:rounded-md tw:border tw:bg-transparent tw:px-3 tw:py-1 tw:text-base tw:shadow-xs tw:transition-[color,box-shadow] tw:outline-none tw:file:inline-flex tw:file:h-7 tw:file:border-0 tw:file:bg-transparent tw:file:text-sm tw:file:font-medium tw:disabled:cursor-not-allowed tw:disabled:select-none tw:disabled:bg-input tw:disabled:text-muted-foreground tw:disabled:placeholder:text-muted-foreground tw:disabled:opacity-50 tw:disabled:shadow-none tw:dark:disabled:bg-input/80 tw:md:text-sm", "tw:focus-visible:border-ring tw:focus-visible:ring-ring/50 tw:focus-visible:ring-[3px]", "tw:aria-invalid:ring-destructive/20 tw:dark:aria-invalid:ring-destructive/40 tw:aria-invalid:border-destructive", className), ...props }));
5
+ function Input({ attentionKey, className, style, type, ...props }) {
6
+ const isInvalid = isAriaInvalid(props["aria-invalid"]);
7
+ const { attentionProps } = useInvalidAttention({
8
+ attentionKey,
9
+ invalid: isInvalid,
10
+ style,
11
+ });
12
+ return (jsx("input", { type: type, "data-slot": "input", className: cn("tw:file:text-foreground tw:placeholder:text-input-placeholder tw:selection:bg-primary tw:selection:text-primary-foreground tw:dark:bg-input/30 tw:border-border tw:h-10 tw:w-full tw:min-w-0 tw:rounded-md tw:border tw:bg-transparent tw:px-3 tw:py-1 tw:text-base tw:shadow-xs tw:transition-[color,box-shadow] tw:outline-none tw:file:inline-flex tw:file:h-7 tw:file:border-0 tw:file:bg-transparent tw:file:text-sm tw:file:font-medium tw:disabled:cursor-not-allowed tw:disabled:select-none tw:disabled:bg-input tw:disabled:text-muted-foreground tw:disabled:placeholder:text-muted-foreground tw:disabled:opacity-50 tw:disabled:shadow-none tw:dark:disabled:bg-input/80 tw:md:text-sm", "tw:focus-visible:border-ring tw:focus-visible:ring-ring/50 tw:focus-visible:ring-[3px]", "tw:aria-invalid:ring-destructive/20 tw:dark:aria-invalid:ring-destructive/40 tw:aria-invalid:border-destructive", className), ...attentionProps, ...props }));
6
13
  }
7
14
 
8
15
  export { Input };
@@ -1,4 +1,5 @@
1
1
  import * as React from "react";
2
+ import { type AttentionKey } from "../hooks/use-invalid-attention";
2
3
  export interface MultiSelectOption {
3
4
  value: string;
4
5
  label: string;
@@ -8,10 +9,11 @@ export interface MultiSelectProps extends Omit<React.ComponentProps<"button">, "
8
9
  options: MultiSelectOption[];
9
10
  value: string[];
10
11
  onValueChange: (value: string[]) => void;
12
+ attentionKey?: AttentionKey;
11
13
  placeholder?: string;
12
14
  size?: "sm" | "default";
13
15
  emptyMessage?: string;
14
16
  }
15
- declare function MultiSelect({ className, options, value, onValueChange, placeholder, size, emptyMessage, disabled, ...props }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
17
+ declare function MultiSelect({ className, options, value, onValueChange, attentionKey, placeholder, size, emptyMessage, disabled, style, ...props }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
16
18
  export { MultiSelect };
17
19
  //# sourceMappingURL=multi-select.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select.d.ts","sourceRoot":"","sources":["../../src/components/multi-select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAClE,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAO,EACP,KAAK,EACL,aAAa,EACb,WAA8B,EAC9B,IAAgB,EAChB,YAAqC,EACrC,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,gBAAgB,2CA+HlB;AAqDD,OAAO,EAAE,WAAW,EAAE,CAAA"}
1
+ {"version":3,"file":"multi-select.d.ts","sourceRoot":"","sources":["../../src/components/multi-select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,gCAAgC,CAAA;AAGvC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAC9B,OAAO,GAAG,UAAU,CACrB;IACC,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACxC,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAO,EACP,KAAK,EACL,aAAa,EACb,YAAY,EACZ,WAA8B,EAC9B,IAAgB,EAChB,YAAqC,EACrC,QAAQ,EACR,KAAK,EACL,GAAG,KAAK,EACT,EAAE,gBAAgB,2CAqIlB;AAqDD,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -2,10 +2,16 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import * as PopoverPrimitive from '@radix-ui/react-popover';
4
4
  import { ChevronDownIcon, CheckIcon } from 'lucide-react';
5
+ import { isAriaInvalid, useInvalidAttention } from '../hooks/use-invalid-attention.js';
5
6
  import { cn } from '../lib/utils.js';
6
7
 
7
- function MultiSelect({ className, options, value, onValueChange, placeholder = "Select options", size = "default", emptyMessage = "No options available", disabled, ...props }) {
8
- const isInvalid = props["aria-invalid"] === true || props["aria-invalid"] === "true";
8
+ function MultiSelect({ className, options, value, onValueChange, attentionKey, placeholder = "Select options", size = "default", emptyMessage = "No options available", disabled, style, ...props }) {
9
+ const isInvalid = isAriaInvalid(props["aria-invalid"]);
10
+ const { attentionProps } = useInvalidAttention({
11
+ attentionKey,
12
+ invalid: isInvalid,
13
+ style,
14
+ });
9
15
  const valueRef = React.useRef(null);
10
16
  const selectedOptions = React.useMemo(() => options.filter((option) => value.includes(option.value)), [options, value]);
11
17
  const selectedLabels = React.useMemo(() => selectedOptions.map((option) => option.label), [selectedOptions]);
@@ -33,7 +39,7 @@ function MultiSelect({ className, options, value, onValueChange, placeholder = "
33
39
  : [...value, optionValue];
34
40
  onValueChange(nextValue);
35
41
  }
36
- return (jsxs(PopoverPrimitive.Root, { children: [jsx(PopoverPrimitive.Trigger, { asChild: true, children: jsxs("button", { type: "button", "data-slot": "multi-select-trigger", "data-size": size, disabled: disabled, className: cn("tw:!flex tw:!w-fit tw:!min-w-0 tw:!items-center tw:!justify-between tw:!gap-2 tw:!rounded-md tw:!border tw:!border-border tw:!bg-transparent tw:!px-3 tw:!py-2 tw:!text-[14px] tw:!shadow-xs tw:!transition-[color,box-shadow] tw:!outline-none", "focus-visible:tw:!border-ring focus-visible:tw:!ring-ring/50 focus-visible:tw:!ring-[3px]", "aria-invalid:tw:!border-destructive aria-invalid:tw:!ring-destructive/20 dark:aria-invalid:tw:!ring-destructive/40", "dark:tw:!bg-input/30 dark:hover:tw:!bg-input/50", "disabled:tw:!cursor-not-allowed disabled:tw:!opacity-50", "data-[size=default]:tw:!min-h-9 data-[size=sm]:tw:!min-h-8", isInvalid && "tw:!border-destructive", className), ...props, children: [jsx("span", { ref: valueRef, "data-slot": "multi-select-value", className: cn("tw:!block tw:!min-w-0 tw:!flex-1 tw:!truncate tw:!text-left", selectedOptions.length === 0 && "tw:!text-muted-foreground"), children: selectedOptions.length === 0 ? placeholder : displayValue }), jsx(ChevronDownIcon, { className: "tw:!size-4 tw:!shrink-0 tw:!opacity-50" })] }) }), jsx(PopoverPrimitive.Portal, { children: jsx(PopoverPrimitive.Content, { "data-slot": "multi-select-content", align: "start", sideOffset: 4, className: "tw:!z-50 tw:!max-h-72 tw:!min-w-[var(--radix-popover-trigger-width)] tw:!overflow-y-auto tw:!rounded-md tw:!border tw:!bg-popover tw:!p-1 tw:!text-popover-foreground tw:!shadow-md tw:!outline-none data-[state=open]:tw:!animate-in data-[state=closed]:tw:!animate-out data-[state=closed]:tw:!fade-out-0 data-[state=open]:tw:!fade-in-0 data-[state=closed]:tw:!zoom-out-95 data-[state=open]:tw:!zoom-in-95", children: options.length === 0 ? (jsx("div", { className: "tw:!px-2 tw:!py-1.5 tw:!text-[14px] tw:!text-muted-foreground", children: emptyMessage })) : (options.map((option) => {
42
+ return (jsxs(PopoverPrimitive.Root, { children: [jsx(PopoverPrimitive.Trigger, { asChild: true, children: jsxs("button", { type: "button", "data-slot": "multi-select-trigger", "data-size": size, disabled: disabled, className: cn("tw:!flex tw:!w-fit tw:!min-w-0 tw:!items-center tw:!justify-between tw:!gap-2 tw:!rounded-md tw:!border tw:!border-border tw:!bg-transparent tw:!px-3 tw:!py-2 tw:!text-[14px] tw:shadow-xs tw:!transition-[color,box-shadow] tw:!outline-none", "focus-visible:tw:!border-ring focus-visible:tw:!ring-ring/50 focus-visible:tw:!ring-[3px]", "aria-invalid:tw:!border-destructive aria-invalid:tw:!ring-destructive/20 dark:aria-invalid:tw:!ring-destructive/40", "dark:tw:!bg-input/30 dark:hover:tw:!bg-input/50", "disabled:tw:!cursor-not-allowed disabled:tw:!opacity-50", "data-[size=default]:tw:!min-h-9 data-[size=sm]:tw:!min-h-8", isInvalid && "tw:!border-destructive", className), "aria-invalid": isInvalid || undefined, style: attentionProps.style, ...props, children: [jsx("span", { ref: valueRef, "data-slot": "multi-select-value", className: cn("tw:!block tw:!min-w-0 tw:!flex-1 tw:!truncate tw:!text-left", selectedOptions.length === 0 && "tw:!text-muted-foreground"), children: selectedOptions.length === 0 ? placeholder : displayValue }), jsx(ChevronDownIcon, { className: "tw:!size-4 tw:!shrink-0 tw:!opacity-50" })] }) }), jsx(PopoverPrimitive.Portal, { children: jsx(PopoverPrimitive.Content, { "data-slot": "multi-select-content", align: "start", sideOffset: 4, className: "tw:!z-50 tw:!max-h-72 tw:!min-w-[var(--radix-popover-trigger-width)] tw:!overflow-y-auto tw:!rounded-md tw:!border tw:!bg-popover tw:!p-1 tw:!text-popover-foreground tw:!shadow-md tw:!outline-none data-[state=open]:tw:!animate-in data-[state=closed]:tw:!animate-out data-[state=closed]:tw:!fade-out-0 data-[state=open]:tw:!fade-in-0 data-[state=closed]:tw:!zoom-out-95 data-[state=open]:tw:!zoom-in-95", children: options.length === 0 ? (jsx("div", { className: "tw:!px-2 tw:!py-1.5 tw:!text-[14px] tw:!text-muted-foreground", children: emptyMessage })) : (options.map((option) => {
37
43
  const isSelected = value.includes(option.value);
38
44
  return (jsxs("button", { type: "button", "data-slot": "multi-select-item", disabled: option.disabled, className: cn("tw:!relative tw:!flex tw:!w-full tw:!cursor-default tw:!items-center tw:!gap-2 tw:!rounded-sm tw:!py-1.5 tw:!pl-2 tw:!pr-8 tw:!text-left tw:!text-[14px] tw:!outline-hidden tw:!select-none tw:!transition-colors", "hover:tw:!bg-accent hover:tw:!text-accent-foreground focus:tw:!bg-accent focus:tw:!text-accent-foreground", option.disabled &&
39
45
  "tw:!cursor-not-allowed tw:!bg-muted/50 tw:!text-muted-foreground tw:!opacity-60 hover:tw:!bg-muted/50 hover:tw:!text-muted-foreground"), onClick: () => toggleValue(option.value), children: [jsx("span", { className: "tw:!absolute tw:!right-2 tw:!flex tw:!size-3.5 tw:!items-center tw:!justify-center", children: isSelected ? jsx(CheckIcon, { className: "tw:!size-4" }) : null }), jsx("span", { className: "tw:!min-w-0 tw:!flex-1 tw:!truncate", children: option.label })] }, option.value));
@@ -1,4 +1,8 @@
1
1
  import * as React from "react";
2
- declare function Textarea({ className, ...props }: React.ComponentProps<"textarea">): import("react/jsx-runtime").JSX.Element;
2
+ import { type AttentionKey } from "../hooks/use-invalid-attention";
3
+ type TextareaProps = React.ComponentProps<"textarea"> & {
4
+ attentionKey?: AttentionKey;
5
+ };
6
+ declare function Textarea({ attentionKey, className, style, ...props }: TextareaProps): import("react/jsx-runtime").JSX.Element;
3
7
  export { Textarea };
4
8
  //# sourceMappingURL=textarea.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../src/components/textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,2CAa1E;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
1
+ {"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../src/components/textarea.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,gCAAgC,CAAA;AAEvC,KAAK,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG;IACtD,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B,CAAA;AAED,iBAAS,QAAQ,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,aAAa,2CAqB5E;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -1,8 +1,15 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { cn } from '../lib/utils.js';
3
+ import { isAriaInvalid, useInvalidAttention } from '../hooks/use-invalid-attention.js';
3
4
 
4
- function Textarea({ className, ...props }) {
5
- return (jsx("textarea", { "data-slot": "textarea", className: cn("tw:border-input tw:placeholder:text-input-placeholder tw:dark:bg-input/30 tw:flex tw:field-sizing-content tw:min-h-16 tw:w-full tw:rounded-md tw:border tw:bg-transparent tw:px-3 tw:py-2 tw:text-base tw:shadow-xs tw:transition-[color,box-shadow] tw:outline-none tw:disabled:cursor-not-allowed tw:disabled:select-none tw:disabled:bg-input tw:disabled:text-muted-foreground tw:disabled:placeholder:text-muted-foreground tw:disabled:opacity-50 tw:disabled:shadow-none tw:dark:disabled:bg-input/80 tw:md:text-sm", "tw:focus-visible:border-ring tw:focus-visible:ring-ring/50 tw:focus-visible:ring-[3px]", "tw:aria-invalid:ring-destructive/20 tw:dark:aria-invalid:ring-destructive/40 tw:aria-invalid:border-destructive", className), ...props }));
5
+ function Textarea({ attentionKey, className, style, ...props }) {
6
+ const isInvalid = isAriaInvalid(props["aria-invalid"]);
7
+ const { attentionProps } = useInvalidAttention({
8
+ attentionKey,
9
+ invalid: isInvalid,
10
+ style,
11
+ });
12
+ return (jsx("textarea", { "data-slot": "textarea", className: cn("tw:border-input tw:placeholder:text-input-placeholder tw:dark:bg-input/30 tw:flex tw:field-sizing-content tw:min-h-16 tw:w-full tw:rounded-md tw:border tw:bg-transparent tw:px-3 tw:py-2 tw:text-base tw:shadow-xs tw:transition-[color,box-shadow] tw:outline-none tw:disabled:cursor-not-allowed tw:disabled:select-none tw:disabled:bg-input tw:disabled:text-muted-foreground tw:disabled:placeholder:text-muted-foreground tw:disabled:opacity-50 tw:disabled:shadow-none tw:dark:disabled:bg-input/80 tw:md:text-sm", "tw:focus-visible:border-ring tw:focus-visible:ring-ring/50 tw:focus-visible:ring-[3px]", "tw:aria-invalid:ring-destructive/20 tw:dark:aria-invalid:ring-destructive/40 tw:aria-invalid:border-destructive", className), ...attentionProps, ...props }));
6
13
  }
7
14
 
8
15
  export { Textarea };
package/dist/globals.css CHANGED
@@ -25,10 +25,10 @@
25
25
  --accent: oklch(0.9632 0.0127 244.2532);
26
26
  --accent-foreground: oklch(0.6723 0.1606 244.9955);
27
27
  --destructive: oklch(0.6188 0.2376 25.7658);
28
- --destructive-foreground: oklch(1.0000 0 0);
28
+ --destructive-foreground: oklch(1 0 0);
29
29
  --border: oklch(0.9317 0.0118 231.6594);
30
30
  --input: oklch(0.934 0.0127 228.93);
31
- --ring: oklch(0.6818 0.1584 243.3540);
31
+ --ring: oklch(0.6818 0.1584 243.354);
32
32
  --chart-1: oklch(0.6723 0.1606 244.9955);
33
33
  --chart-2: oklch(0.6907 0.1554 160.3454);
34
34
  --chart-3: oklch(0.8214 0.16 82.5337);
@@ -54,11 +54,21 @@
54
54
  --shadow-color: rgba(29, 161, 242, 0.15);
55
55
  --shadow-2xs: 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.05);
56
56
  --shadow-xs: 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.05);
57
- --shadow-sm: 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 1px 2px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
58
- --shadow: 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 1px 2px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
59
- --shadow-md: 0px 4px 6px 0px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 2px 4px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
60
- --shadow-lg: 0px 10px 15px -3px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 4px 6px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
61
- --shadow-xl: 0px 20px 25px -5px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 8px 10px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
57
+ --shadow-sm:
58
+ 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.1),
59
+ 0px 1px 2px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
60
+ --shadow:
61
+ 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.1),
62
+ 0px 1px 2px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
63
+ --shadow-md:
64
+ 0px 4px 6px 0px hsl(202.8169 89.1213% 53.1373% / 0.1),
65
+ 0px 2px 4px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
66
+ --shadow-lg:
67
+ 0px 10px 15px -3px hsl(202.8169 89.1213% 53.1373% / 0.1),
68
+ 0px 4px 6px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
69
+ --shadow-xl:
70
+ 0px 20px 25px -5px hsl(202.8169 89.1213% 53.1373% / 0.1),
71
+ 0px 8px 10px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
62
72
  --shadow-2xl: 0px 25px 50px -12px hsl(202.8169 89.1213% 53.1373% / 0.25);
63
73
  --tracking-normal: 0em;
64
74
  --spacing: 0.25rem;
@@ -111,11 +121,21 @@
111
121
  --shadow-color: rgba(1, 6, 10, 0.15);
112
122
  --shadow-2xs: 0px 1px 2px 0px hsl(202.8169 89.1213% 53.1373% / 0.05);
113
123
  --shadow-xs: 0px 1px 2px 0px hsl(202.8169 89.1213% 53.1373% / 0.05);
114
- --shadow-sm: 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 1px 2px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
115
- --shadow: 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 1px 2px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
116
- --shadow-md: 0px 1px 6px -1px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 2px 4px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
117
- --shadow-lg: 0px 10px 15px -3px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 4px 6px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
118
- --shadow-xl: 0px 20px 25px -5px hsl(202.8169 89.1213% 53.1373% / 0.10), 0px 8px 10px -1px hsl(202.8169 89.1213% 53.1373% / 0.10);
124
+ --shadow-sm:
125
+ 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.1),
126
+ 0px 1px 2px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
127
+ --shadow:
128
+ 0px 1px 3px 0px hsl(202.8169 89.1213% 53.1373% / 0.1),
129
+ 0px 1px 2px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
130
+ --shadow-md:
131
+ 0px 1px 6px -1px hsl(202.8169 89.1213% 53.1373% / 0.1),
132
+ 0px 2px 4px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
133
+ --shadow-lg:
134
+ 0px 10px 15px -3px hsl(202.8169 89.1213% 53.1373% / 0.1),
135
+ 0px 4px 6px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
136
+ --shadow-xl:
137
+ 0px 20px 25px -5px hsl(202.8169 89.1213% 53.1373% / 0.1),
138
+ 0px 8px 10px -1px hsl(202.8169 89.1213% 53.1373% / 0.1);
119
139
  --shadow-2xl: 0px 25px 50px -12px hsl(202.8169 89.1213% 53.1373% / 0.25);
120
140
  }
121
141
 
@@ -183,6 +203,20 @@
183
203
  }
184
204
  }
185
205
 
206
+ @keyframes blaze-invalid-attention-glow {
207
+ 0% {
208
+ box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
209
+ }
210
+
211
+ 25% {
212
+ box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.24);
213
+ }
214
+
215
+ 100% {
216
+ box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
217
+ }
218
+ }
219
+
186
220
  /* Fix style collisions with poopstrap/reactstrap/mui/antd */
187
221
  .blaze-ui-root {
188
222
  --blaze-420-font-sm: 14px;
@@ -624,11 +658,11 @@
624
658
  background-color: var(--primary) !important;
625
659
  }
626
660
 
627
- .blaze-ui-root button[data-slot='switch'][data-state='unchecked'] {
661
+ .blaze-ui-root button[data-slot="switch"][data-state="unchecked"] {
628
662
  background-color: var(--border) !important;
629
663
  }
630
664
 
631
- .dark .blaze-ui-root button[data-slot='switch'][data-state='unchecked'] {
665
+ .dark .blaze-ui-root button[data-slot="switch"][data-state="unchecked"] {
632
666
  background-color: var(--input) !important;
633
667
  }
634
668
 
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+ export declare const INVALID_ATTENTION_GLOW_ANIMATION_NAME = "blaze-invalid-attention-glow";
3
+ export declare const INVALID_ATTENTION_DURATION_MS = 850;
4
+ export type AttentionKey = string | number | null | undefined;
5
+ export type InvalidAttentionProps = {
6
+ style?: React.CSSProperties;
7
+ };
8
+ export type UseInvalidAttentionResult = {
9
+ attentionProps: InvalidAttentionProps;
10
+ };
11
+ type UseInvalidAttentionOptions = {
12
+ invalid: boolean;
13
+ attentionKey?: AttentionKey;
14
+ durationMs?: number;
15
+ style?: React.CSSProperties;
16
+ };
17
+ declare function isAriaInvalid(value: React.AriaAttributes["aria-invalid"]): value is true | "true" | "grammar" | "spelling";
18
+ declare function useInvalidAttention({ invalid, attentionKey, durationMs, style, }: UseInvalidAttentionOptions): UseInvalidAttentionResult;
19
+ export { isAriaInvalid, useInvalidAttention };
20
+ //# sourceMappingURL=use-invalid-attention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-invalid-attention.d.ts","sourceRoot":"","sources":["../../src/hooks/use-invalid-attention.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,eAAO,MAAM,qCAAqC,iCAClB,CAAA;AAChC,eAAO,MAAM,6BAA6B,MAAM,CAAA;AAEhD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;AAC7D,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;CAC5B,CAAA;AACD,MAAM,MAAM,yBAAyB,GAAG;IACtC,cAAc,EAAE,qBAAqB,CAAA;CACtC,CAAA;AAED,KAAK,0BAA0B,GAAG;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;CAC5B,CAAA;AAED,iBAAS,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,mDAEjE;AAED,iBAAS,mBAAmB,CAAC,EAC3B,OAAO,EACP,YAAY,EACZ,UAA0C,EAC1C,KAAK,GACN,EAAE,0BAA0B,GAAG,yBAAyB,CA8ExD;AAED,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,CAAA"}
@@ -0,0 +1,65 @@
1
+ import * as React from 'react';
2
+
3
+ const INVALID_ATTENTION_GLOW_ANIMATION_NAME = "blaze-invalid-attention-glow";
4
+ const INVALID_ATTENTION_DURATION_MS = 850;
5
+ function isAriaInvalid(value) {
6
+ return value === true || (typeof value === "string" && value !== "false");
7
+ }
8
+ function useInvalidAttention({ invalid, attentionKey, durationMs = INVALID_ATTENTION_DURATION_MS, style, }) {
9
+ const [isGlowing, setIsGlowing] = React.useState(false);
10
+ const frameRef = React.useRef(null);
11
+ const timeoutRef = React.useRef(null);
12
+ const lastTriggeredAttentionKeyRef = React.useRef(undefined);
13
+ const clearPendingGlow = React.useCallback(() => {
14
+ if (frameRef.current !== null) {
15
+ window.cancelAnimationFrame(frameRef.current);
16
+ frameRef.current = null;
17
+ }
18
+ if (timeoutRef.current !== null) {
19
+ window.clearTimeout(timeoutRef.current);
20
+ timeoutRef.current = null;
21
+ }
22
+ }, []);
23
+ const startGlow = React.useCallback((nextDurationMs) => {
24
+ clearPendingGlow();
25
+ setIsGlowing(false);
26
+ // Restart the same animation reliably when the key changes again.
27
+ frameRef.current = window.requestAnimationFrame(() => {
28
+ setIsGlowing(true);
29
+ frameRef.current = null;
30
+ });
31
+ timeoutRef.current = window.setTimeout(() => {
32
+ setIsGlowing(false);
33
+ timeoutRef.current = null;
34
+ }, nextDurationMs);
35
+ }, [clearPendingGlow]);
36
+ React.useEffect(() => {
37
+ return clearPendingGlow;
38
+ }, [clearPendingGlow]);
39
+ React.useEffect(() => {
40
+ if (!invalid) {
41
+ setIsGlowing(false);
42
+ return;
43
+ }
44
+ const shouldTriggerGlow = !Object.is(lastTriggeredAttentionKeyRef.current, attentionKey);
45
+ if (!shouldTriggerGlow) {
46
+ return;
47
+ }
48
+ lastTriggeredAttentionKeyRef.current = attentionKey;
49
+ startGlow(durationMs);
50
+ }, [attentionKey, durationMs, invalid, startGlow]);
51
+ const glowStyle = isGlowing
52
+ ? {
53
+ animation: `${INVALID_ATTENTION_GLOW_ANIMATION_NAME} ${durationMs}ms ease-out`,
54
+ }
55
+ : undefined;
56
+ const attentionProps = React.useMemo(() => ({
57
+ style: {
58
+ ...style,
59
+ ...glowStyle,
60
+ },
61
+ }), [glowStyle, style]);
62
+ return { attentionProps };
63
+ }
64
+
65
+ export { INVALID_ATTENTION_DURATION_MS, INVALID_ATTENTION_GLOW_ANIMATION_NAME, isAriaInvalid, useInvalidAttention };
package/dist/index.d.ts CHANGED
@@ -47,6 +47,7 @@ export * from "./components/tooltip";
47
47
  export * from "./components/login-screen";
48
48
  export * from "./components/visually-hidden";
49
49
  export * from "./hooks/use-mobile";
50
+ export * from "./hooks/use-invalid-attention";
50
51
  export * from "./components/command";
51
52
  export * from "./components/item";
52
53
  export * from "./components/toggle-group";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,2BAA2B,CAAA;AACzC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,qBAAqB,CAAA;AACnC,cAAc,2BAA2B,CAAA;AACzC,cAAc,oBAAoB,CAAA;AAClC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,2BAA2B,CAAA;AACzC,cAAc,qBAAqB,CAAA;AACnC,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,2BAA2B,CAAA;AACzC,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,kBAAkB,CAAA;AAChC,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,2BAA2B,CAAA;AACzC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,qBAAqB,CAAA;AACnC,cAAc,2BAA2B,CAAA;AACzC,cAAc,oBAAoB,CAAA;AAClC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,2BAA2B,CAAA;AACzC,cAAc,qBAAqB,CAAA;AACnC,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,2BAA2B,CAAA;AACzC,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,kBAAkB,CAAA;AAChC,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,oBAAoB,CAAA;AAClC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,sBAAsB,CAAA;AACpC,cAAc,kCAAkC,CAAA;AAChD,cAAc,aAAa,CAAA"}
package/dist/index.js CHANGED
@@ -47,6 +47,7 @@ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './comp
47
47
  export { LoginScreen } from './components/login-screen.js';
48
48
  export { VisuallyHidden } from './components/visually-hidden.js';
49
49
  export { useIsMobile } from './hooks/use-mobile.js';
50
+ export { INVALID_ATTENTION_DURATION_MS, INVALID_ATTENTION_GLOW_ANIMATION_NAME, isAriaInvalid, useInvalidAttention } from './hooks/use-invalid-attention.js';
50
51
  export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from './components/command.js';
51
52
  export { Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle } from './components/item.js';
52
53
  export { ToggleGroup, ToggleGroupItem } from './components/toggle-group.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getgreenline/blaze-ui",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "@base-ui/react": "^1.4.1",
@@ -38,8 +38,8 @@
38
38
  "input-otp": "^1.4.2",
39
39
  "lucide-react": "^1.14.0",
40
40
  "next-themes": "^0.4.6",
41
- "react-hook-form": "^7.74.0",
42
- "react-resizable-panels": "^4.10.0",
41
+ "react-hook-form": "^7.75.0",
42
+ "react-resizable-panels": "^4.11.0",
43
43
  "recharts": "3.8.1",
44
44
  "sonner": "^2.0.7",
45
45
  "tailwind-merge": "^3.5.0",
@@ -57,16 +57,16 @@
57
57
  "@rollup/plugin-node-resolve": "^16.0.3",
58
58
  "@rollup/plugin-typescript": "^12.3.0",
59
59
  "@tailwindcss/postcss": "^4.2.4",
60
- "@turbo/gen": "^2.9.6",
60
+ "@turbo/gen": "^2.9.9",
61
61
  "@types/node": "^20.19.39",
62
62
  "@types/react": "^19.2.14",
63
63
  "@types/react-dom": "^19.2.3",
64
- "eslint": "^10.2.1",
65
- "rollup": "^4.60.2",
64
+ "eslint": "^10.3.0",
65
+ "rollup": "^4.60.3",
66
66
  "tailwindcss": "^4.2.4",
67
67
  "typescript": "^6.0.3",
68
- "@workspace/eslint-config": "0.0.0",
69
- "@workspace/typescript-config": "0.0.0"
68
+ "@workspace/typescript-config": "0.0.0",
69
+ "@workspace/eslint-config": "0.0.0"
70
70
  },
71
71
  "main": "./dist/index.js",
72
72
  "module": "./dist/index.js",