@douglasneuroinformatics/libui 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,6 +24,7 @@
24
24
 
25
25
  ![license](https://img.shields.io/github/license/DouglasNeuroInformatics/libui)
26
26
  ![version](https://img.shields.io/github/package-json/v/DouglasNeuroInformatics/libui)
27
+ [![codecov](https://codecov.io/gh/DouglasNeuroInformatics/libui/graph/badge.svg?token=t9PkBDS01T)](https://codecov.io/gh/DouglasNeuroInformatics/libui)
27
28
 
28
29
  </div>
29
30
  <hr />
@@ -85,6 +85,7 @@ declare const Button: React__default.ForwardRefExoticComponent<{
85
85
  unselectable?: "on" | "off" | undefined;
86
86
  inputMode?: "search" | "text" | "none" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined;
87
87
  is?: string | undefined;
88
+ children?: React__default.ReactNode | Iterable<React__default.ReactNode>;
88
89
  "aria-activedescendant"?: string | undefined;
89
90
  "aria-atomic"?: (boolean | "true" | "false") | undefined;
90
91
  "aria-autocomplete"?: "list" | "none" | "inline" | "both" | undefined;
@@ -138,7 +139,6 @@ declare const Button: React__default.ForwardRefExoticComponent<{
138
139
  "aria-valuemin"?: number | undefined;
139
140
  "aria-valuenow"?: number | undefined;
140
141
  "aria-valuetext"?: string | undefined;
141
- children?: React__default.ReactNode;
142
142
  dangerouslySetInnerHTML?: {
143
143
  __html: string | TrustedHTML;
144
144
  } | undefined;
@@ -369,6 +369,7 @@ declare const ArrowToggle: React__default.ForwardRefExoticComponent<{
369
369
  unselectable?: "on" | "off" | undefined;
370
370
  inputMode?: "search" | "text" | "none" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined;
371
371
  is?: string | undefined;
372
+ children?: React__default.ReactNode | Iterable<React__default.ReactNode>;
372
373
  "aria-activedescendant"?: string | undefined;
373
374
  "aria-atomic"?: (boolean | "true" | "false") | undefined;
374
375
  "aria-autocomplete"?: "list" | "none" | "inline" | "both" | undefined;
@@ -422,7 +423,6 @@ declare const ArrowToggle: React__default.ForwardRefExoticComponent<{
422
423
  "aria-valuemin"?: number | undefined;
423
424
  "aria-valuenow"?: number | undefined;
424
425
  "aria-valuetext"?: string | undefined;
425
- children?: React__default.ReactNode;
426
426
  dangerouslySetInnerHTML?: {
427
427
  __html: string | TrustedHTML;
428
428
  } | undefined;
@@ -37,7 +37,7 @@ var AccordionRoot = React3.forwardRef(function AccordionRoot2(props, ref) {
37
37
  // src/components/Accordion/AccordionTrigger.tsx
38
38
  import * as React4 from "react";
39
39
  import * as AccordionPrimitive4 from "@radix-ui/react-accordion";
40
- import { ChevronDownIcon } from "@radix-ui/react-icons";
40
+ import { ChevronDownIcon } from "lucide-react";
41
41
  import { jsx as jsx4, jsxs } from "react/jsx-runtime";
42
42
  var AccordionTrigger = React4.forwardRef(function AccordionTrigger2({ children, className, ...props }, ref) {
43
43
  return /* @__PURE__ */ jsx4(AccordionPrimitive4.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
@@ -66,7 +66,7 @@ var Accordion = Object.assign(AccordionRoot, {
66
66
 
67
67
  // src/components/ArrowToggle/ArrowToggle.tsx
68
68
  import React6, { useMemo } from "react";
69
- import { ChevronUpIcon } from "@radix-ui/react-icons";
69
+ import { ChevronUpIcon } from "lucide-react";
70
70
 
71
71
  // src/components/Button/Button.tsx
72
72
  import React5 from "react";
@@ -87,7 +87,7 @@ var buttonVariants = cva(
87
87
  },
88
88
  variants: {
89
89
  size: {
90
- icon: "h-9 w-9",
90
+ icon: "p-1.5",
91
91
  lg: "h-10 rounded-md px-8",
92
92
  md: "h-9 px-4 py-2",
93
93
  sm: "h-8 rounded-md px-3 text-xs"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Accordion/AccordionContent.tsx","../../src/components/Accordion/AccordionItem.tsx","../../src/components/Accordion/AccordionRoot.tsx","../../src/components/Accordion/AccordionTrigger.tsx","../../src/components/Accordion/Accordion.tsx","../../src/components/ArrowToggle/ArrowToggle.tsx","../../src/components/Button/Button.tsx","../../src/components/Input/Input.tsx","../../src/components/Label/Label.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\n\nimport { cn } from '@/utils';\n\nexport const AccordionContent = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n>(function AccordionContent({ children, className, ...props }, ref) {\n return (\n <AccordionPrimitive.Content\n className=\"overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n ref={ref}\n {...props}\n >\n <div className={cn('pb-4 pt-0', className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n});\n","import * as React from 'react';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\n\nimport { cn } from '@/utils';\n\nexport const AccordionItem = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n>(function AccordionItem({ className, ...props }, ref) {\n return <AccordionPrimitive.Item className={cn('border-b', className)} ref={ref} {...props} />;\n});\n","import * as React from 'react';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\n\nexport const AccordionRoot = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Root>\n>(function AccordionRoot(props, ref) {\n return <AccordionPrimitive.Root data-testid=\"accordion\" ref={ref} {...props} />;\n});\n","import * as React from 'react';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\nimport { ChevronDownIcon } from '@radix-ui/react-icons';\n\nimport { cn } from '@/utils';\n\nexport const AccordionTrigger = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>\n>(function AccordionTrigger({ children, className, ...props }, ref) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n className={cn(\n 'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',\n className\n )}\n ref={ref}\n {...props}\n >\n {children}\n <ChevronDownIcon className=\"h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200\" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n});\n","import { AccordionContent } from './AccordionContent';\nimport { AccordionItem } from './AccordionItem';\nimport { AccordionRoot } from './AccordionRoot';\nimport { AccordionTrigger } from './AccordionTrigger';\n\nexport const Accordion = Object.assign(AccordionRoot, {\n Content: AccordionContent,\n Item: AccordionItem,\n Trigger: AccordionTrigger\n});\n","import React, { useMemo } from 'react';\n\nimport { ChevronUpIcon } from '@radix-ui/react-icons';\nimport type { Simplify } from 'type-fest';\n\nimport { cn } from '@/utils';\n\nimport { Button, type ButtonProps } from '../Button';\n\nexport type ArrowToggleProps = Simplify<\n React.HTMLAttributes<HTMLButtonElement> & {\n /** Whether or not the arrow is currently toggled */\n isToggled?: boolean;\n\n /** The starting position of the arrow (i.e., which direction does it point to) */\n position: 'down' | 'left' | 'right' | 'up';\n\n /** The clockwise rotation of the arrow when toggled (e.g., if the position is 'right' and rotation is 90, the arrow will point down) */\n rotation?: number;\n\n /** The variant of button to use */\n variant?: Extract<ButtonProps['variant'], 'ghost' | 'outline'>;\n }\n>;\n\nexport const ArrowToggle = React.forwardRef<HTMLButtonElement, ArrowToggleProps>(function ArrowToggle(\n { className, isToggled, position, rotation = 0, variant = 'ghost', ...props },\n ref\n) {\n const computedRotation = useMemo(() => {\n const toggleRotation = isToggled ? rotation : 0;\n switch (position) {\n case 'up':\n return 0 + toggleRotation;\n case 'right':\n return 90 + toggleRotation;\n case 'down':\n return 180 + toggleRotation;\n case 'left':\n return 270 + toggleRotation;\n }\n }, [position, rotation, isToggled]);\n\n return (\n <Button\n className={cn('h-6 w-6', className)}\n data-testid=\"arrow-toggle\"\n ref={ref}\n size=\"icon\"\n type=\"button\"\n variant={variant}\n {...props}\n >\n <ChevronUpIcon\n className=\"transform-gpu transition-transform\"\n data-testid=\"arrow-up-icon\"\n style={{ transform: `rotate(${computedRotation}deg)` }}\n />\n </Button>\n );\n});\n","import React from 'react';\n\nimport { Slot, Slottable } from '@radix-ui/react-slot';\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport type { Simplify } from 'type-fest';\n\nimport { cn } from '@/utils';\n\nexport const BUTTON_ICON_SIZE = {\n lg: 18,\n md: 16,\n sm: 14\n};\n\nexport const buttonVariants = cva(\n 'flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',\n {\n defaultVariants: {\n size: 'md',\n variant: 'primary'\n },\n variants: {\n size: {\n icon: 'h-9 w-9',\n lg: 'h-10 rounded-md px-8',\n md: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs'\n },\n variant: {\n danger: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n outline: 'border border-input bg-inherit shadow-sm',\n primary: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n secondary: 'bg-secondary border text-secondary-foreground shadow-sm hover:bg-secondary/80'\n }\n }\n }\n);\n\nexport type ButtonProps = Simplify<\n React.ButtonHTMLAttributes<HTMLButtonElement> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n /** @deprecated - use children */\n label?: string;\n }\n>;\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n { asChild, children, className, label, size = 'md', variant = 'primary', ...props },\n ref\n) {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp className={cn(buttonVariants({ className, size, variant }))} ref={ref} {...props}>\n {label}\n <Slottable>{children}</Slottable>\n </Comp>\n );\n});\n","import * as React from 'react';\n\nimport { cn } from '@/utils';\n\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(function Input({ className, type, ...props }, ref) {\n return (\n <input\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n data-testid=\"input\"\n ref={ref}\n type={type}\n {...props}\n />\n );\n});\n","import * as React from 'react';\n\nimport * as LabelPrimitive from '@radix-ui/react-label';\nimport { type VariantProps, cva } from 'class-variance-authority';\n\nimport { cn } from '@/utils';\n\nconst labelVariants = cva('text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70');\n\nexport const Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>\n>(function Label({ className, ...props }, ref) {\n return <LabelPrimitive.Root className={cn(labelVariants(), className)} ref={ref} {...props} />;\n});\n"],"mappings":";;;;;AAAA,YAAY,WAAW;AAEvB,YAAY,wBAAwB;AAc9B;AAVC,IAAM,mBAAyB,iBAGpC,SAASA,kBAAiB,EAAE,UAAU,WAAW,GAAG,MAAM,GAAG,KAAK;AAClE,SACE;AAAA,IAAoB;AAAA,IAAnB;AAAA,MACC,WAAU;AAAA,MACV;AAAA,MACC,GAAG;AAAA,MAEJ,8BAAC,SAAI,WAAW,GAAG,aAAa,SAAS,GAAI,UAAS;AAAA;AAAA,EACxD;AAEJ,CAAC;;;ACnBD,YAAYC,YAAW;AAEvB,YAAYC,yBAAwB;AAQ3B,gBAAAC,YAAA;AAJF,IAAM,gBAAsB,kBAGjC,SAASC,eAAc,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AACrD,SAAO,gBAAAD,KAAoB,0BAAnB,EAAwB,WAAW,GAAG,YAAY,SAAS,GAAG,KAAW,GAAG,OAAO;AAC7F,CAAC;;;ACXD,YAAYE,YAAW;AAEvB,YAAYC,yBAAwB;AAM3B,gBAAAC,YAAA;AAJF,IAAM,gBAAsB,kBAGjC,SAASC,eAAc,OAAO,KAAK;AACnC,SAAO,gBAAAD,KAAoB,0BAAnB,EAAwB,eAAY,aAAY,KAAW,GAAG,OAAO;AAC/E,CAAC;;;ACTD,YAAYE,YAAW;AAEvB,YAAYC,yBAAwB;AACpC,SAAS,uBAAuB;AAU1B,SASE,OAAAC,MATF;AANC,IAAM,mBAAyB,kBAGpC,SAASC,kBAAiB,EAAE,UAAU,WAAW,GAAG,MAAM,GAAG,KAAK;AAClE,SACE,gBAAAD,KAAoB,4BAAnB,EAA0B,WAAU,QACnC;AAAA,IAAoB;AAAA,IAAnB;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QACD,gBAAAA,KAAC,mBAAgB,WAAU,4EAA2E;AAAA;AAAA;AAAA,EACxG,GACF;AAEJ,CAAC;;;ACrBM,IAAM,YAAY,OAAO,OAAO,eAAe;AAAA,EACpD,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AACX,CAAC;;;ACTD,OAAOE,UAAS,eAAe;AAE/B,SAAS,qBAAqB;;;ACF9B,OAAOC,YAAW;AAElB,SAAS,MAAM,iBAAiB;AAChC,SAA4B,WAAW;AAoDnC,SAEE,OAAAC,MAFF,QAAAC,aAAA;AA/CG,IAAM,mBAAmB;AAAA,EAC9B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,IACE,iBAAiB;AAAA,MACf,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,MACA,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACF;AAWO,IAAM,SAASC,OAAM,WAA2C,SAASC,QAC9E,EAAE,SAAS,UAAU,WAAW,OAAO,OAAO,MAAM,UAAU,WAAW,GAAG,MAAM,GAClF,KACA;AACA,QAAM,OAAO,UAAU,OAAO;AAC9B,SACE,gBAAAF,MAAC,QAAK,WAAW,GAAG,eAAe,EAAE,WAAW,MAAM,QAAQ,CAAC,CAAC,GAAG,KAAW,GAAG,OAC9E;AAAA;AAAA,IACD,gBAAAD,KAAC,aAAW,UAAS;AAAA,KACvB;AAEJ,CAAC;;;ADPK,gBAAAI,YAAA;AA5BC,IAAM,cAAcC,OAAM,WAAgD,SAASC,aACxF,EAAE,WAAW,WAAW,UAAU,WAAW,GAAG,UAAU,SAAS,GAAG,MAAM,GAC5E,KACA;AACA,QAAM,mBAAmB,QAAQ,MAAM;AACrC,UAAM,iBAAiB,YAAY,WAAW;AAC9C,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,eAAO,IAAI;AAAA,MACb,KAAK;AACH,eAAO,KAAK;AAAA,MACd,KAAK;AACH,eAAO,MAAM;AAAA,MACf,KAAK;AACH,eAAO,MAAM;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,UAAU,UAAU,SAAS,CAAC;AAElC,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,WAAW,SAAS;AAAA,MAClC,eAAY;AAAA,MACZ;AAAA,MACA,MAAK;AAAA,MACL,MAAK;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEJ,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,eAAY;AAAA,UACZ,OAAO,EAAE,WAAW,UAAU,gBAAgB,OAAO;AAAA;AAAA,MACvD;AAAA;AAAA,EACF;AAEJ,CAAC;;;AE5DD,YAAYG,YAAW;AAQnB,gBAAAC,YAAA;AAFG,IAAM,QAAc,kBAAyC,SAASC,OAAM,EAAE,WAAW,MAAM,GAAG,MAAM,GAAG,KAAK;AACrH,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,eAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;;;ACnBD,YAAYE,YAAW;AAEvB,YAAY,oBAAoB;AAChC,SAA4B,OAAAC,YAAW;AAU9B,gBAAAC,YAAA;AANT,IAAM,gBAAgBC,KAAI,4FAA4F;AAE/G,IAAM,QAAc,kBAGzB,SAASC,OAAM,EAAE,WAAW,GAAG,MAAM,GAAG,KAAK;AAC7C,SAAO,gBAAAF,KAAgB,qBAAf,EAAoB,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,KAAW,GAAG,OAAO;AAC9F,CAAC;","names":["AccordionContent","React","AccordionPrimitive","jsx","AccordionItem","React","AccordionPrimitive","jsx","AccordionRoot","React","AccordionPrimitive","jsx","AccordionTrigger","React","React","jsx","jsxs","React","Button","jsx","React","ArrowToggle","React","jsx","Input","React","cva","jsx","cva","Label"]}
1
+ {"version":3,"sources":["../../src/components/Accordion/AccordionContent.tsx","../../src/components/Accordion/AccordionItem.tsx","../../src/components/Accordion/AccordionRoot.tsx","../../src/components/Accordion/AccordionTrigger.tsx","../../src/components/Accordion/Accordion.tsx","../../src/components/ArrowToggle/ArrowToggle.tsx","../../src/components/Button/Button.tsx","../../src/components/Input/Input.tsx","../../src/components/Label/Label.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\n\nimport { cn } from '@/utils';\n\nexport const AccordionContent = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>\n>(function AccordionContent({ children, className, ...props }, ref) {\n return (\n <AccordionPrimitive.Content\n className=\"overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n ref={ref}\n {...props}\n >\n <div className={cn('pb-4 pt-0', className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n});\n","import * as React from 'react';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\n\nimport { cn } from '@/utils';\n\nexport const AccordionItem = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>\n>(function AccordionItem({ className, ...props }, ref) {\n return <AccordionPrimitive.Item className={cn('border-b', className)} ref={ref} {...props} />;\n});\n","import * as React from 'react';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\n\nexport const AccordionRoot = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Root>\n>(function AccordionRoot(props, ref) {\n return <AccordionPrimitive.Root data-testid=\"accordion\" ref={ref} {...props} />;\n});\n","import * as React from 'react';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\nimport { ChevronDownIcon } from 'lucide-react';\n\nimport { cn } from '@/utils';\n\nexport const AccordionTrigger = React.forwardRef<\n React.ElementRef<typeof AccordionPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>\n>(function AccordionTrigger({ children, className, ...props }, ref) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n className={cn(\n 'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',\n className\n )}\n ref={ref}\n {...props}\n >\n {children}\n <ChevronDownIcon className=\"h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200\" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n});\n","import { AccordionContent } from './AccordionContent';\nimport { AccordionItem } from './AccordionItem';\nimport { AccordionRoot } from './AccordionRoot';\nimport { AccordionTrigger } from './AccordionTrigger';\n\nexport const Accordion = Object.assign(AccordionRoot, {\n Content: AccordionContent,\n Item: AccordionItem,\n Trigger: AccordionTrigger\n});\n","import React, { useMemo } from 'react';\n\nimport { ChevronUpIcon } from 'lucide-react';\nimport type { Simplify } from 'type-fest';\n\nimport { cn } from '@/utils';\n\nimport { Button, type ButtonProps } from '../Button';\n\nexport type ArrowToggleProps = Simplify<\n React.HTMLAttributes<HTMLButtonElement> & {\n /** Whether or not the arrow is currently toggled */\n isToggled?: boolean;\n\n /** The starting position of the arrow (i.e., which direction does it point to) */\n position: 'down' | 'left' | 'right' | 'up';\n\n /** The clockwise rotation of the arrow when toggled (e.g., if the position is 'right' and rotation is 90, the arrow will point down) */\n rotation?: number;\n\n /** The variant of button to use */\n variant?: Extract<ButtonProps['variant'], 'ghost' | 'outline'>;\n }\n>;\n\nexport const ArrowToggle = React.forwardRef<HTMLButtonElement, ArrowToggleProps>(function ArrowToggle(\n { className, isToggled, position, rotation = 0, variant = 'ghost', ...props },\n ref\n) {\n const computedRotation = useMemo(() => {\n const toggleRotation = isToggled ? rotation : 0;\n switch (position) {\n case 'up':\n return 0 + toggleRotation;\n case 'right':\n return 90 + toggleRotation;\n case 'down':\n return 180 + toggleRotation;\n case 'left':\n return 270 + toggleRotation;\n }\n }, [position, rotation, isToggled]);\n\n return (\n <Button\n className={cn('h-6 w-6', className)}\n data-testid=\"arrow-toggle\"\n ref={ref}\n size=\"icon\"\n type=\"button\"\n variant={variant}\n {...props}\n >\n <ChevronUpIcon\n className=\"transform-gpu transition-transform\"\n data-testid=\"arrow-up-icon\"\n style={{ transform: `rotate(${computedRotation}deg)` }}\n />\n </Button>\n );\n});\n","import React from 'react';\n\nimport { Slot, Slottable } from '@radix-ui/react-slot';\nimport { type VariantProps, cva } from 'class-variance-authority';\nimport type { Simplify } from 'type-fest';\n\nimport { cn } from '@/utils';\n\nexport const BUTTON_ICON_SIZE = {\n lg: 18,\n md: 16,\n sm: 14\n};\n\nexport const buttonVariants = cva(\n 'flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',\n {\n defaultVariants: {\n size: 'md',\n variant: 'primary'\n },\n variants: {\n size: {\n icon: 'p-1.5',\n lg: 'h-10 rounded-md px-8',\n md: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs'\n },\n variant: {\n danger: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n outline: 'border border-input bg-inherit shadow-sm',\n primary: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n secondary: 'bg-secondary border text-secondary-foreground shadow-sm hover:bg-secondary/80'\n }\n }\n }\n);\n\nexport type ButtonProps = Simplify<\n React.ButtonHTMLAttributes<HTMLButtonElement> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n /** @deprecated - use children */\n label?: string;\n }\n>;\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n { asChild, children, className, label, size = 'md', variant = 'primary', ...props },\n ref\n) {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp className={cn(buttonVariants({ className, size, variant }))} ref={ref} {...props}>\n {label}\n <Slottable>{children}</Slottable>\n </Comp>\n );\n});\n","import * as React from 'react';\n\nimport { cn } from '@/utils';\n\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(function Input({ className, type, ...props }, ref) {\n return (\n <input\n className={cn(\n 'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n data-testid=\"input\"\n ref={ref}\n type={type}\n {...props}\n />\n );\n});\n","import * as React from 'react';\n\nimport * as LabelPrimitive from '@radix-ui/react-label';\nimport { type VariantProps, cva } from 'class-variance-authority';\n\nimport { cn } from '@/utils';\n\nconst labelVariants = cva('text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70');\n\nexport const Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>\n>(function Label({ className, ...props }, ref) {\n return <LabelPrimitive.Root className={cn(labelVariants(), className)} ref={ref} {...props} />;\n});\n"],"mappings":"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","names":["AccordionContent","React","AccordionPrimitive","jsx","AccordionItem","React","AccordionPrimitive","jsx","AccordionRoot","React","AccordionPrimitive","jsx","AccordionTrigger","React","React","jsx","jsxs","React","Button","jsx","React","ArrowToggle","React","jsx","Input","React","cva","jsx","cva","Label"]}
@@ -148,7 +148,6 @@ function useOnClickOutside(ref, handler, mouseEvent = "mousedown") {
148
148
 
149
149
  // src/hooks/useSessionStorage.ts
150
150
  import { useCallback as useCallback2, useEffect as useEffect6, useState as useState3 } from "react";
151
- var IS_SERVER = typeof window === "undefined";
152
151
  function useSessionStorage(key, initialValue, options = {}) {
153
152
  const { initializeWithValue = true } = options;
154
153
  const serializer = useCallback2(
@@ -172,8 +171,8 @@ function useSessionStorage(key, initialValue, options = {}) {
172
171
  let parsed;
173
172
  try {
174
173
  parsed = JSON.parse(value);
175
- } catch (error) {
176
- console.error("Error parsing JSON:", error);
174
+ } catch (err) {
175
+ console.error(`Error parsing JSON: ${err.message}`);
177
176
  return defaultValue;
178
177
  }
179
178
  return parsed;
@@ -182,16 +181,11 @@ function useSessionStorage(key, initialValue, options = {}) {
182
181
  );
183
182
  const readValue = useCallback2(() => {
184
183
  const initialValueToUse = initialValue instanceof Function ? initialValue() : initialValue;
185
- if (IS_SERVER) {
186
- return initialValueToUse;
187
- }
188
- try {
189
- const raw = window.sessionStorage.getItem(key);
190
- return raw ? deserializer(raw) : initialValueToUse;
191
- } catch (error) {
192
- console.warn(`Error reading sessionStorage key \u201C${key}\u201D:`, error);
184
+ if (!isBrowser()) {
193
185
  return initialValueToUse;
194
186
  }
187
+ const raw = window.sessionStorage.getItem(key);
188
+ return raw ? deserializer(raw) : initialValueToUse;
195
189
  }, [initialValue, key, deserializer]);
196
190
  const [storedValue, setStoredValue] = useState3(() => {
197
191
  if (initializeWithValue) {
@@ -200,7 +194,7 @@ function useSessionStorage(key, initialValue, options = {}) {
200
194
  return initialValue instanceof Function ? initialValue() : initialValue;
201
195
  });
202
196
  const setValue = useEventCallback((value) => {
203
- if (IS_SERVER) {
197
+ if (!isBrowser()) {
204
198
  console.warn(`Tried setting sessionStorage key \u201C${key}\u201D even though environment is not a client`);
205
199
  }
206
200
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/useDownload.ts","../../src/hooks/useNotificationsStore.ts","../../src/hooks/useEventCallback.ts","../../src/hooks/useIsomorphicLayoutEffect.ts","../../src/hooks/useEventListener.ts","../../src/hooks/useInterval.ts","../../src/hooks/useMediaQuery.ts","../../src/hooks/useOnClickOutside.ts","../../src/hooks/useSessionStorage.ts","../../src/hooks/useTheme.ts","../../src/hooks/useWindowSize.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport type { Promisable } from 'type-fest';\n\nimport { useNotificationsStore } from './useNotificationsStore';\n\n/**\n * Used to trigger downloads of arbitrary data to the client\n * @returns A function to invoke the download\n */\nexport function useDownload() {\n const notifications = useNotificationsStore();\n const [data, setData] = useState<null | string>(null);\n const [filename, setFilename] = useState<null | string>(null);\n\n useEffect(() => {\n if (data && filename) {\n const anchor = document.createElement('a');\n document.body.appendChild(anchor);\n const blob = new Blob([data], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n anchor.remove();\n setData(null);\n setFilename(null);\n }\n }, [data, filename]);\n\n return async (filename: string, fetchData: () => Promisable<string>) => {\n try {\n const data = await fetchData();\n setData(data);\n setFilename(filename);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'An unknown error occurred';\n notifications.addNotification({\n message,\n title: 'Error',\n type: 'error'\n });\n }\n };\n}\n","import { create } from 'zustand';\n\nexport type NotificationInterface = {\n id: number;\n message?: string;\n title?: string;\n type: 'error' | 'info' | 'success' | 'warning';\n variant?: 'critical' | 'standard';\n};\n\nexport type NotificationsStore = {\n addNotification: (notification: Omit<NotificationInterface, 'id'>) => void;\n dismissNotification: (id: number) => void;\n notifications: NotificationInterface[];\n};\n\nexport const useNotificationsStore = create<NotificationsStore>((set) => ({\n addNotification: (notification) => {\n set((state) => ({\n notifications: [...state.notifications, { id: Date.now(), ...notification }]\n }));\n },\n dismissNotification: (id) => {\n set((state) => ({\n notifications: state.notifications.filter((notification) => notification.id !== id)\n }));\n },\n notifications: []\n}));\n","import { useCallback, useRef } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';\n\nexport function useEventCallback<Args extends unknown[], R>(fn: (...args: Args) => R) {\n const ref = useRef<typeof fn>(() => {\n throw new Error('Cannot call an event handler while rendering.');\n });\n\n useIsomorphicLayoutEffect(() => {\n ref.current = fn;\n }, [fn]);\n\n return useCallback((...args: Args) => ref.current(...args), [ref]);\n}\n","import { useEffect, useLayoutEffect } from 'react';\n\nimport { isBrowser } from '@/utils';\n\nexport const useIsomorphicLayoutEffect = isBrowser() ? useLayoutEffect : useEffect;\n","import { type RefObject, useEffect, useRef } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';\n\n// MediaQueryList Event based useEventListener interface\nfunction useEventListener<K extends keyof MediaQueryListEventMap>(\n eventName: K,\n handler: (event: MediaQueryListEventMap[K]) => void,\n element: RefObject<MediaQueryList>,\n options?: AddEventListenerOptions | boolean\n): void;\n\n// Window Event based useEventListener interface\nfunction useEventListener<K extends keyof WindowEventMap>(\n eventName: K,\n handler: (event: WindowEventMap[K]) => void,\n element?: undefined,\n options?: AddEventListenerOptions | boolean\n): void;\n\n// Element Event based useEventListener interface\nfunction useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = HTMLDivElement>(\n eventName: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n element: RefObject<T>,\n options?: AddEventListenerOptions | boolean\n): void;\n\n// Document Event based useEventListener interface\nfunction useEventListener<K extends keyof DocumentEventMap>(\n eventName: K,\n handler: (event: DocumentEventMap[K]) => void,\n element: RefObject<Document>,\n options?: AddEventListenerOptions | boolean\n): void;\n\nfunction useEventListener<\n KW extends keyof WindowEventMap,\n KH extends keyof HTMLElementEventMap,\n KM extends keyof MediaQueryListEventMap,\n T extends HTMLElement | MediaQueryList | void = void\n>(\n eventName: KH | KM | KW,\n handler: (event: Event | HTMLElementEventMap[KH] | MediaQueryListEventMap[KM] | WindowEventMap[KW]) => void,\n element?: RefObject<T>,\n options?: AddEventListenerOptions | boolean\n) {\n // Create a ref that stores handler\n const savedHandler = useRef(handler);\n\n useIsomorphicLayoutEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n useEffect(() => {\n // Define the listening target\n const targetElement: T | Window = element?.current ?? window;\n\n if (!(targetElement && targetElement.addEventListener)) return;\n\n // Create event listener that calls handler function stored in ref\n const listener: typeof handler = (event) => savedHandler.current(event);\n\n targetElement.addEventListener(eventName, listener, options);\n\n // Remove event listener on cleanup\n return () => {\n targetElement.removeEventListener(eventName, listener, options);\n };\n }, [eventName, element, options]);\n}\n\nexport { useEventListener };\n","import { useEffect, useRef } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';\n\nexport function useInterval(callback: () => void, delay: null | number) {\n const savedCallback = useRef(callback);\n\n // Remember the latest callback if it changes.\n useIsomorphicLayoutEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n // Set up the interval.\n useEffect(() => {\n // Don't schedule if no delay is specified.\n // Note: 0 is a valid value for delay.\n if (!delay && delay !== 0) {\n return;\n }\n\n const id = setInterval(() => savedCallback.current(), delay);\n\n return () => clearInterval(id);\n }, [delay]);\n}\n","import { useEffect, useState } from 'react';\n\nimport { isBrowser } from '@/utils';\n\n/**\n * Get the result of an arbitrary CSS media query\n *\n * @param query - the CSS media query\n * @returns a boolean indicating the result of the query\n * @example\n * // true if the viewport is at least 768px wide\n * const matches = useMediaQuery('(min-width: 768px)')\n */\nexport function useMediaQuery(query: string): boolean {\n const getMatches = (query: string): boolean => {\n // Prevents SSR issues\n if (isBrowser()) {\n return window.matchMedia(query).matches;\n }\n return false;\n };\n\n const [matches, setMatches] = useState<boolean>(getMatches(query));\n\n function handleChange() {\n setMatches(getMatches(query));\n }\n\n useEffect(() => {\n const matchMedia = window.matchMedia(query);\n\n // Triggered at the first client-side load and if query changes\n handleChange();\n\n matchMedia.addEventListener('change', handleChange);\n\n return () => {\n matchMedia.removeEventListener('change', handleChange);\n };\n }, [query]);\n\n return matches;\n}\n","import { type RefObject } from 'react';\n\nimport { useEventListener } from './useEventListener';\n\ntype Handler = (event: MouseEvent) => void;\n\nexport function useOnClickOutside<T extends HTMLElement = HTMLElement>(\n ref: RefObject<T>,\n handler: Handler,\n mouseEvent: 'mousedown' | 'mouseup' = 'mousedown'\n): void {\n useEventListener(mouseEvent, (event) => {\n const el = ref.current;\n\n // Do nothing if clicking ref's element or descendent elements\n if (!el || el.contains(event.target as Node)) {\n return;\n }\n\n handler(event);\n });\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\n\nimport { useEventCallback } from './useEventCallback';\nimport { useEventListener } from './useEventListener';\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface WindowEventMap {\n 'session-storage': CustomEvent;\n }\n}\n\n/**\n * Represents the options for customizing the behavior of serialization and deserialization.\n * @template T - The type of the state to be stored in session storage.\n */\ntype UseSessionStorageOptions<T> = {\n /** A function to deserialize the stored value. */\n deserializer?: (value: string) => T;\n /**\n * If `true` (default), the hook will initialize reading the session storage. In SSR, you should set it to `false`, returning the initial value initially.\n * @default true\n */\n initializeWithValue?: boolean;\n /** A function to serialize the value before storing it. */\n serializer?: (value: T) => string;\n};\n\nconst IS_SERVER = typeof window === 'undefined';\n\n/**\n * Custom hook that uses session storage to persist state across page reloads.\n * @template T - The type of the state to be stored in session storage.\n * @param {string} key - The key under which the value will be stored in session storage.\n * @param {T | (() => T)} initialValue - The initial value of the state or a function that returns the initial value.\n * @param {?UseSessionStorageOptions<T>} [options] - Options for customizing the behavior of serialization and deserialization (optional).\n * @returns {[T, Dispatch<SetStateAction<T>>]} A tuple containing the stored value and a function to set the value.\n * @public\n * @example\n * ```tsx\n * const [count, setCount] = useSessionStorage('count', 0);\n * // Access the `count` value and the `setCount` function to update it.\n * ```\n */\nexport function useSessionStorage<T>(\n key: string,\n initialValue: (() => T) | T,\n options: UseSessionStorageOptions<T> = {}\n): [T, Dispatch<SetStateAction<T>>] {\n const { initializeWithValue = true } = options;\n\n const serializer = useCallback<(value: T) => string>(\n (value) => {\n if (options.serializer) {\n return options.serializer(value);\n }\n\n return JSON.stringify(value);\n },\n [options]\n );\n\n const deserializer = useCallback<(value: string) => T>(\n (value) => {\n if (options.deserializer) {\n return options.deserializer(value);\n }\n // Support 'undefined' as a value\n if (value === 'undefined') {\n return undefined as unknown as T;\n }\n\n const defaultValue = initialValue instanceof Function ? initialValue() : initialValue;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(value);\n } catch (error) {\n console.error('Error parsing JSON:', error);\n return defaultValue; // Return initialValue if parsing fails\n }\n\n return parsed as T;\n },\n [options, initialValue]\n );\n\n // Get from session storage then\n // parse stored json or return initialValue\n const readValue = useCallback((): T => {\n const initialValueToUse = initialValue instanceof Function ? initialValue() : initialValue;\n\n // Prevent build error \"window is undefined\" but keep keep working\n if (IS_SERVER) {\n return initialValueToUse;\n }\n\n try {\n const raw = window.sessionStorage.getItem(key);\n return raw ? deserializer(raw) : initialValueToUse;\n } catch (error) {\n console.warn(`Error reading sessionStorage key “${key}”:`, error);\n return initialValueToUse;\n }\n }, [initialValue, key, deserializer]);\n\n const [storedValue, setStoredValue] = useState(() => {\n if (initializeWithValue) {\n return readValue();\n }\n\n return initialValue instanceof Function ? initialValue() : initialValue;\n });\n\n // Return a wrapped version of useState's setter function that ...\n // ... persists the new value to sessionStorage.\n const setValue: Dispatch<SetStateAction<T>> = useEventCallback((value) => {\n // Prevent build error \"window is undefined\" but keeps working\n if (IS_SERVER) {\n console.warn(`Tried setting sessionStorage key “${key}” even though environment is not a client`);\n }\n\n try {\n // Allow value to be a function so we have the same API as useState\n const newValue = value instanceof Function ? value(readValue()) : value;\n\n // Save to session storage\n window.sessionStorage.setItem(key, serializer(newValue));\n\n // Save state\n setStoredValue(newValue);\n\n // We dispatch a custom event so every similar useSessionStorage hook is notified\n window.dispatchEvent(new StorageEvent('session-storage', { key }));\n } catch (error) {\n console.warn(`Error setting sessionStorage key “${key}”:`, error);\n }\n });\n\n useEffect(() => {\n setStoredValue(readValue());\n }, [key]);\n\n const handleStorageChange = useCallback(\n (event: CustomEvent | StorageEvent) => {\n if ((event as StorageEvent).key && (event as StorageEvent).key !== key) {\n return;\n }\n setStoredValue(readValue());\n },\n [key, readValue]\n );\n\n // this only works for other documents, not the current one\n useEventListener('storage', handleStorageChange);\n\n // this is a custom event, triggered in writeValueToSessionStorage\n // See: useSessionStorage()\n useEventListener('session-storage', handleStorageChange);\n\n return [storedValue, setValue];\n}\n","import { useCallback, useEffect, useState } from 'react';\n\nimport { isBrowser } from '@/utils';\n\ntype Theme = 'dark' | 'light';\n\ntype UpdateTheme = (theme: Theme) => void;\n\n/** @private */\nconst DEFAULT_THEME: Theme = 'light';\n\n/** @private */\nconst THEME_ATTRIBUTE = 'data-mode';\n\n/** @private */\nconst THEME_KEY = 'theme';\n\n/** @private */\nconst SYS_DARK_MEDIA_QUERY = '(prefers-color-scheme: dark)';\n\n/**\n * Returns the current theme and a function to update the current theme\n *\n * The reason the implementation of this hook is rather convoluted is for\n * cases where the theme is updated outside this hook\n */\nfunction useTheme(): readonly [Theme, UpdateTheme] {\n // Initial theme value is based on the value saved in local storage or the system theme\n const [theme, setTheme] = useState<Theme>(() => {\n if (!isBrowser()) {\n return DEFAULT_THEME;\n }\n const savedTheme = window.localStorage.getItem(THEME_KEY);\n let initialTheme: Theme;\n if (savedTheme === 'dark' || savedTheme === 'light') {\n initialTheme = savedTheme;\n } else {\n initialTheme = window.matchMedia(SYS_DARK_MEDIA_QUERY).matches ? 'dark' : 'light';\n }\n document.documentElement.setAttribute(THEME_ATTRIBUTE, initialTheme);\n return initialTheme;\n });\n\n useEffect(() => {\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.attributeName === THEME_ATTRIBUTE) {\n const updatedTheme = (mutation.target as HTMLHtmlElement).getAttribute(THEME_ATTRIBUTE);\n if (updatedTheme === 'light' || updatedTheme === 'dark') {\n window.localStorage.setItem(THEME_KEY, updatedTheme);\n setTheme(updatedTheme);\n } else {\n console.error(`Unexpected value for 'data-mode' attribute: ${updatedTheme}`);\n }\n }\n });\n });\n observer.observe(document.documentElement, {\n attributes: true\n });\n return () => observer.disconnect();\n }, []);\n\n // When the user wants to change the theme\n const updateTheme = useCallback(\n (theme: Theme) => {\n document.documentElement.setAttribute(THEME_ATTRIBUTE, theme);\n },\n [document.documentElement]\n );\n\n return [theme, updateTheme] as const;\n}\n\nexport { DEFAULT_THEME, SYS_DARK_MEDIA_QUERY, THEME_ATTRIBUTE, THEME_KEY, type Theme, useTheme };\n","import { useState } from 'react';\n\nimport { useEventListener } from './useEventListener';\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';\n\nexport type WindowSize = {\n height: number;\n width: number;\n};\n\nexport function useWindowSize(): WindowSize {\n const [windowSize, setWindowSize] = useState<WindowSize>({\n height: 0,\n width: 0\n });\n\n const handleSize = () => {\n setWindowSize({\n height: window.innerHeight,\n width: window.innerWidth\n });\n };\n\n useEventListener('resize', handleSize);\n\n // Set size at the first client-side load\n useIsomorphicLayoutEffect(() => {\n handleSize();\n }, []);\n\n return windowSize;\n}\n"],"mappings":"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","names":["filename","data","useEffect","useEffect","useEffect","useRef","useRef","useEffect","useEffect","useRef","useRef","useEffect","useEffect","useState","query","useState","useEffect","useCallback","useEffect","useState","useCallback","useState","useEffect","useCallback","useEffect","useState","useState","useEffect","useCallback","theme","useState","useState"]}
1
+ {"version":3,"sources":["../../src/hooks/useDownload.ts","../../src/hooks/useNotificationsStore.ts","../../src/hooks/useEventCallback.ts","../../src/hooks/useIsomorphicLayoutEffect.ts","../../src/hooks/useEventListener.ts","../../src/hooks/useInterval.ts","../../src/hooks/useMediaQuery.ts","../../src/hooks/useOnClickOutside.ts","../../src/hooks/useSessionStorage.ts","../../src/hooks/useTheme.ts","../../src/hooks/useWindowSize.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport type { Promisable } from 'type-fest';\n\nimport { useNotificationsStore } from './useNotificationsStore';\n\n/**\n * Used to trigger downloads of arbitrary data to the client\n * @returns A function to invoke the download\n */\nexport function useDownload() {\n const notifications = useNotificationsStore();\n const [data, setData] = useState<null | string>(null);\n const [filename, setFilename] = useState<null | string>(null);\n\n useEffect(() => {\n if (data && filename) {\n const anchor = document.createElement('a');\n document.body.appendChild(anchor);\n const blob = new Blob([data], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n anchor.remove();\n setData(null);\n setFilename(null);\n }\n }, [data, filename]);\n\n return async (filename: string, fetchData: () => Promisable<string>) => {\n try {\n const data = await fetchData();\n setData(data);\n setFilename(filename);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'An unknown error occurred';\n notifications.addNotification({\n message,\n title: 'Error',\n type: 'error'\n });\n }\n };\n}\n","import { create } from 'zustand';\n\nexport type NotificationInterface = {\n id: number;\n message?: string;\n title?: string;\n type: 'error' | 'info' | 'success' | 'warning';\n variant?: 'critical' | 'standard';\n};\n\nexport type NotificationsStore = {\n addNotification: (notification: Omit<NotificationInterface, 'id'>) => void;\n dismissNotification: (id: number) => void;\n notifications: NotificationInterface[];\n};\n\nexport const useNotificationsStore = create<NotificationsStore>((set) => ({\n addNotification: (notification) => {\n set((state) => ({\n notifications: [...state.notifications, { id: Date.now(), ...notification }]\n }));\n },\n dismissNotification: (id) => {\n set((state) => ({\n notifications: state.notifications.filter((notification) => notification.id !== id)\n }));\n },\n notifications: []\n}));\n","import { useCallback, useRef } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';\n\nexport function useEventCallback<Args extends unknown[], R>(fn: (...args: Args) => R) {\n const ref = useRef<typeof fn>(() => {\n throw new Error('Cannot call an event handler while rendering.');\n });\n\n useIsomorphicLayoutEffect(() => {\n ref.current = fn;\n }, [fn]);\n\n return useCallback((...args: Args) => ref.current(...args), [ref]);\n}\n","import { useEffect, useLayoutEffect } from 'react';\n\nimport { isBrowser } from '@/utils';\n\nexport const useIsomorphicLayoutEffect = isBrowser() ? useLayoutEffect : useEffect;\n","import { type RefObject, useEffect, useRef } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';\n\n// MediaQueryList Event based useEventListener interface\nfunction useEventListener<K extends keyof MediaQueryListEventMap>(\n eventName: K,\n handler: (event: MediaQueryListEventMap[K]) => void,\n element: RefObject<MediaQueryList>,\n options?: AddEventListenerOptions | boolean\n): void;\n\n// Window Event based useEventListener interface\nfunction useEventListener<K extends keyof WindowEventMap>(\n eventName: K,\n handler: (event: WindowEventMap[K]) => void,\n element?: undefined,\n options?: AddEventListenerOptions | boolean\n): void;\n\n// Element Event based useEventListener interface\nfunction useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = HTMLDivElement>(\n eventName: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n element: RefObject<T>,\n options?: AddEventListenerOptions | boolean\n): void;\n\n// Document Event based useEventListener interface\nfunction useEventListener<K extends keyof DocumentEventMap>(\n eventName: K,\n handler: (event: DocumentEventMap[K]) => void,\n element: RefObject<Document>,\n options?: AddEventListenerOptions | boolean\n): void;\n\nfunction useEventListener<\n KW extends keyof WindowEventMap,\n KH extends keyof HTMLElementEventMap,\n KM extends keyof MediaQueryListEventMap,\n T extends HTMLElement | MediaQueryList | void = void\n>(\n eventName: KH | KM | KW,\n handler: (event: Event | HTMLElementEventMap[KH] | MediaQueryListEventMap[KM] | WindowEventMap[KW]) => void,\n element?: RefObject<T>,\n options?: AddEventListenerOptions | boolean\n) {\n // Create a ref that stores handler\n const savedHandler = useRef(handler);\n\n useIsomorphicLayoutEffect(() => {\n savedHandler.current = handler;\n }, [handler]);\n\n useEffect(() => {\n // Define the listening target\n const targetElement: T | Window = element?.current ?? window;\n\n if (!(targetElement && targetElement.addEventListener)) return;\n\n // Create event listener that calls handler function stored in ref\n const listener: typeof handler = (event) => savedHandler.current(event);\n\n targetElement.addEventListener(eventName, listener, options);\n\n // Remove event listener on cleanup\n return () => {\n targetElement.removeEventListener(eventName, listener, options);\n };\n }, [eventName, element, options]);\n}\n\nexport { useEventListener };\n","import { useEffect, useRef } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';\n\nexport function useInterval(callback: () => void, delay: null | number) {\n const savedCallback = useRef(callback);\n\n // Remember the latest callback if it changes.\n useIsomorphicLayoutEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n // Set up the interval.\n useEffect(() => {\n // Don't schedule if no delay is specified.\n // Note: 0 is a valid value for delay.\n if (!delay && delay !== 0) {\n return;\n }\n\n const id = setInterval(() => savedCallback.current(), delay);\n\n return () => clearInterval(id);\n }, [delay]);\n}\n","import { useEffect, useState } from 'react';\n\nimport { isBrowser } from '@/utils';\n\n/**\n * Get the result of an arbitrary CSS media query\n *\n * @param query - the CSS media query\n * @returns a boolean indicating the result of the query\n * @example\n * // true if the viewport is at least 768px wide\n * const matches = useMediaQuery('(min-width: 768px)')\n */\nexport function useMediaQuery(query: string): boolean {\n const getMatches = (query: string): boolean => {\n // Prevents SSR issues\n if (isBrowser()) {\n return window.matchMedia(query).matches;\n }\n return false;\n };\n\n const [matches, setMatches] = useState<boolean>(getMatches(query));\n\n function handleChange() {\n setMatches(getMatches(query));\n }\n\n useEffect(() => {\n const matchMedia = window.matchMedia(query);\n\n // Triggered at the first client-side load and if query changes\n handleChange();\n\n matchMedia.addEventListener('change', handleChange);\n\n return () => {\n matchMedia.removeEventListener('change', handleChange);\n };\n }, [query]);\n\n return matches;\n}\n","import { type RefObject } from 'react';\n\nimport { useEventListener } from './useEventListener';\n\ntype Handler = (event: MouseEvent) => void;\n\nexport function useOnClickOutside<T extends HTMLElement = HTMLElement>(\n ref: RefObject<T>,\n handler: Handler,\n mouseEvent: 'mousedown' | 'mouseup' = 'mousedown'\n): void {\n useEventListener(mouseEvent, (event) => {\n const el = ref.current;\n\n // Do nothing if clicking ref's element or descendent elements\n if (!el || el.contains(event.target as Node)) {\n return;\n }\n\n handler(event);\n });\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\n\nimport { isBrowser } from '@/utils';\n\nimport { useEventCallback } from './useEventCallback';\nimport { useEventListener } from './useEventListener';\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface WindowEventMap {\n 'session-storage': CustomEvent;\n }\n}\n\n/**\n * Represents the options for customizing the behavior of serialization and deserialization.\n * @template T - The type of the state to be stored in session storage.\n */\ntype UseSessionStorageOptions<T> = {\n /** A function to deserialize the stored value. */\n deserializer?: (value: string) => T;\n /**\n * If `true` (default), the hook will initialize reading the session storage. In SSR, you should set it to `false`, returning the initial value initially.\n * @default true\n */\n initializeWithValue?: boolean;\n /** A function to serialize the value before storing it. */\n serializer?: (value: T) => string;\n};\n\n/**\n * Custom hook that uses session storage to persist state across page reloads.\n * @template T - The type of the state to be stored in session storage.\n * @param {string} key - The key under which the value will be stored in session storage.\n * @param {T | (() => T)} initialValue - The initial value of the state or a function that returns the initial value.\n * @param {?UseSessionStorageOptions<T>} [options] - Options for customizing the behavior of serialization and deserialization (optional).\n * @returns {[T, Dispatch<SetStateAction<T>>]} A tuple containing the stored value and a function to set the value.\n * @public\n * @example\n * ```tsx\n * const [count, setCount] = useSessionStorage('count', 0);\n * // Access the `count` value and the `setCount` function to update it.\n * ```\n */\nexport function useSessionStorage<T>(\n key: string,\n initialValue: (() => T) | T,\n options: UseSessionStorageOptions<T> = {}\n): [T, Dispatch<SetStateAction<T>>] {\n const { initializeWithValue = true } = options;\n\n const serializer = useCallback<(value: T) => string>(\n (value) => {\n if (options.serializer) {\n return options.serializer(value);\n }\n return JSON.stringify(value);\n },\n [options]\n );\n\n const deserializer = useCallback<(value: string) => T>(\n (value) => {\n if (options.deserializer) {\n return options.deserializer(value);\n }\n // Support 'undefined' as a value\n if (value === 'undefined') {\n return undefined as unknown as T;\n }\n\n const defaultValue = initialValue instanceof Function ? initialValue() : initialValue;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(value);\n } catch (err) {\n console.error(`Error parsing JSON: ${(err as Error).message}`);\n return defaultValue;\n }\n\n return parsed as T;\n },\n [options, initialValue]\n );\n\n // Get from session storage then\n // parse stored json or return initialValue\n const readValue = useCallback((): T => {\n const initialValueToUse = initialValue instanceof Function ? initialValue() : initialValue;\n\n // Prevent build error \"window is undefined\" but keep keep working\n if (!isBrowser()) {\n return initialValueToUse;\n }\n const raw = window.sessionStorage.getItem(key);\n return raw ? deserializer(raw) : initialValueToUse;\n }, [initialValue, key, deserializer]);\n\n const [storedValue, setStoredValue] = useState(() => {\n if (initializeWithValue) {\n return readValue();\n }\n\n return initialValue instanceof Function ? initialValue() : initialValue;\n });\n\n // Return a wrapped version of useState's setter function that ...\n // ... persists the new value to sessionStorage.\n const setValue: Dispatch<SetStateAction<T>> = useEventCallback((value) => {\n // Prevent build error \"window is undefined\" but keeps working\n if (!isBrowser()) {\n console.warn(`Tried setting sessionStorage key “${key}” even though environment is not a client`);\n }\n\n try {\n // Allow value to be a function so we have the same API as useState\n const newValue = value instanceof Function ? value(readValue()) : value;\n\n // Save to session storage\n window.sessionStorage.setItem(key, serializer(newValue));\n\n // Save state\n setStoredValue(newValue);\n\n // We dispatch a custom event so every similar useSessionStorage hook is notified\n window.dispatchEvent(new StorageEvent('session-storage', { key }));\n } catch (error) {\n console.warn(`Error setting sessionStorage key “${key}”:`, error);\n }\n });\n\n useEffect(() => {\n setStoredValue(readValue());\n }, [key]);\n\n const handleStorageChange = useCallback(\n (event: CustomEvent | StorageEvent) => {\n if ((event as StorageEvent).key && (event as StorageEvent).key !== key) {\n return;\n }\n setStoredValue(readValue());\n },\n [key, readValue]\n );\n\n // this only works for other documents, not the current one\n useEventListener('storage', handleStorageChange);\n\n // this is a custom event, triggered in writeValueToSessionStorage\n // See: useSessionStorage()\n useEventListener('session-storage', handleStorageChange);\n\n return [storedValue, setValue];\n}\n","import { useCallback, useEffect, useState } from 'react';\n\nimport { isBrowser } from '../utils';\n\ntype Theme = 'dark' | 'light';\n\ntype UpdateTheme = (theme: Theme) => void;\n\n/** @private */\nconst DEFAULT_THEME: Theme = 'light';\n\n/** @private */\nconst THEME_ATTRIBUTE = 'data-mode';\n\n/** @private */\nconst THEME_KEY = 'theme';\n\n/** @private */\nconst SYS_DARK_MEDIA_QUERY = '(prefers-color-scheme: dark)';\n\n/**\n * Returns the current theme and a function to update the current theme\n *\n * The reason the implementation of this hook is rather convoluted is for\n * cases where the theme is updated outside this hook\n */\nfunction useTheme(): readonly [Theme, UpdateTheme] {\n // Initial theme value is based on the value saved in local storage or the system theme\n const [theme, setTheme] = useState<Theme>(() => {\n if (!isBrowser()) {\n return DEFAULT_THEME;\n }\n const savedTheme = window.localStorage.getItem(THEME_KEY);\n let initialTheme: Theme;\n if (savedTheme === 'dark' || savedTheme === 'light') {\n initialTheme = savedTheme;\n } else {\n initialTheme = window.matchMedia(SYS_DARK_MEDIA_QUERY).matches ? 'dark' : 'light';\n }\n document.documentElement.setAttribute(THEME_ATTRIBUTE, initialTheme);\n return initialTheme;\n });\n\n useEffect(() => {\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.attributeName === THEME_ATTRIBUTE) {\n const updatedTheme = (mutation.target as HTMLHtmlElement).getAttribute(THEME_ATTRIBUTE);\n if (updatedTheme === 'light' || updatedTheme === 'dark') {\n window.localStorage.setItem(THEME_KEY, updatedTheme);\n setTheme(updatedTheme);\n } else {\n console.error(`Unexpected value for 'data-mode' attribute: ${updatedTheme}`);\n }\n }\n });\n });\n observer.observe(document.documentElement, {\n attributes: true\n });\n return () => observer.disconnect();\n }, []);\n\n // When the user wants to change the theme\n const updateTheme = useCallback(\n (theme: Theme) => {\n document.documentElement.setAttribute(THEME_ATTRIBUTE, theme);\n },\n [document.documentElement]\n );\n\n return [theme, updateTheme] as const;\n}\n\nexport { DEFAULT_THEME, SYS_DARK_MEDIA_QUERY, THEME_ATTRIBUTE, THEME_KEY, type Theme, useTheme };\n","import { useState } from 'react';\n\nimport { useEventListener } from './useEventListener';\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';\n\nexport type WindowSize = {\n height: number;\n width: number;\n};\n\nexport function useWindowSize(): WindowSize {\n const [windowSize, setWindowSize] = useState<WindowSize>({\n height: 0,\n width: 0\n });\n\n const handleSize = () => {\n setWindowSize({\n height: window.innerHeight,\n width: window.innerWidth\n });\n };\n\n useEventListener('resize', handleSize);\n\n // Set size at the first client-side load\n useIsomorphicLayoutEffect(() => {\n handleSize();\n }, []);\n\n return windowSize;\n}\n"],"mappings":"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","names":["filename","data","useEffect","useEffect","useEffect","useRef","useRef","useEffect","useEffect","useRef","useRef","useEffect","useEffect","useState","query","useState","useEffect","useCallback","useEffect","useState","useCallback","useState","useEffect","useCallback","useEffect","useState","useState","useEffect","useCallback","theme","useState","useState"]}
package/dist/i18n.d.ts CHANGED
@@ -1,52 +1,13 @@
1
1
  import { i18n as i18n$1 } from 'i18next';
2
+ import { EmptyObject, ValueOf } from 'type-fest';
2
3
 
3
- declare const defaultNS = "translations";
4
- declare const resources: {
5
- readonly en: {
6
- readonly translations: {
7
- readonly 'datetime.days': readonly ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
8
- readonly 'datetime.months': readonly ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
9
- readonly 'form.append': "Append";
10
- readonly 'form.errors.required': "This field is required";
11
- readonly 'form.errors.unknown': "Unknown error";
12
- readonly 'form.radio.labels.false': "False";
13
- readonly 'form.radio.labels.true': "True";
14
- readonly 'form.remove': "Remove";
15
- readonly 'form.reset': "Clear";
16
- readonly 'form.submit': "Submit";
17
- readonly 'notifications.types.error': "Error";
18
- readonly 'notifications.types.info': "Info";
19
- readonly 'notifications.types.success': "Success";
20
- readonly 'notifications.types.warning': "Warning";
21
- readonly 'searchBar.placeholder': "Search...";
22
- readonly 'table.pagination.info': "Showing {{first}} to {{last}} of {{total}} results";
23
- readonly 'table.pagination.next': "Next";
24
- readonly 'table.pagination.previous': "Previous";
25
- };
26
- };
27
- readonly fr: {
28
- readonly translations: {
29
- readonly 'datetime.days': readonly ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"];
30
- readonly 'datetime.months': readonly ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"];
31
- readonly 'form.append': "Ajouter";
32
- readonly 'form.errors.required': "Ce champ est obligatoire";
33
- readonly 'form.errors.unknown': "Erreur inconnue";
34
- readonly 'form.radio.labels.false': "Faux";
35
- readonly 'form.radio.labels.true': "Vrai";
36
- readonly 'form.remove': "Supprimer";
37
- readonly 'form.reset': "Réinitialiser";
38
- readonly 'form.submit': "Soumettre";
39
- readonly 'notifications.types.error': "Erreur";
40
- readonly 'notifications.types.info': "Attention";
41
- readonly 'notifications.types.success': "Succès";
42
- readonly 'notifications.types.warning': "Avertissement";
43
- readonly 'searchBar.placeholder': "Rechercher...";
44
- readonly 'table.pagination.info': "Affichage de {{first}} à {{last}} sur {{total}} résultats";
45
- readonly 'table.pagination.next': "Suivante";
46
- readonly 'table.pagination.previous': "Précédente";
47
- };
48
- };
4
+ declare const defaultNS: "libui";
5
+ declare const supportedLngs: readonly ["en", "fr"];
6
+ type DefaultNS = typeof defaultNS;
7
+ type Language = (typeof supportedLngs)[number];
8
+ type TranslatedResource<T = EmptyObject> = {
9
+ [K in keyof T]: T[K] extends Record<string, unknown> ? T[K] extends Record<Language, unknown> ? ValueOf<T[K]> : TranslatedResource<T[K]> : T[K];
49
10
  };
50
11
  declare const i18n: i18n$1;
51
12
 
52
- export { i18n as default, defaultNS, resources };
13
+ export { type DefaultNS, type Language, type TranslatedResource, i18n as default };
package/dist/i18n.js CHANGED
@@ -1,94 +1,159 @@
1
1
  // src/i18n.ts
2
2
  import { createInstance } from "i18next";
3
+ import { mapValues } from "lodash-es";
3
4
  import { initReactI18next } from "react-i18next";
4
- var defaultNS = "translations";
5
- var resources = {
6
- en: {
7
- translations: {
8
- "datetime.days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
9
- "datetime.months": [
10
- "January",
11
- "February",
12
- "March",
13
- "April",
14
- "May",
15
- "June",
16
- "July",
17
- "August",
18
- "September",
19
- "October",
20
- "November",
21
- "December"
22
- ],
23
- "form.append": "Append",
24
- "form.errors.required": "This field is required",
25
- "form.errors.unknown": "Unknown error",
26
- "form.radio.labels.false": "False",
27
- "form.radio.labels.true": "True",
28
- "form.remove": "Remove",
29
- "form.reset": "Clear",
30
- "form.submit": "Submit",
31
- "notifications.types.error": "Error",
32
- "notifications.types.info": "Info",
33
- "notifications.types.success": "Success",
34
- "notifications.types.warning": "Warning",
35
- "searchBar.placeholder": "Search...",
36
- "table.pagination.info": "Showing {{first}} to {{last}} of {{total}} results",
37
- "table.pagination.next": "Next",
38
- "table.pagination.previous": "Previous"
5
+
6
+ // src/translations/libui.json
7
+ var libui_default = {
8
+ days: {
9
+ monday: {
10
+ en: "Monday",
11
+ fr: "Lundi"
12
+ },
13
+ tuesday: {
14
+ en: "Tuesday",
15
+ fr: "Mardi"
16
+ },
17
+ wednesday: {
18
+ en: "Wednesday",
19
+ fr: "Mercredi"
20
+ },
21
+ thursday: {
22
+ en: "Thursday",
23
+ fr: "Jeudi"
24
+ },
25
+ friday: {
26
+ en: "Friday",
27
+ fr: "Vendredi"
28
+ },
29
+ saturday: {
30
+ en: "Saturday",
31
+ fr: "Samedi"
32
+ },
33
+ sunday: {
34
+ en: "Sunday",
35
+ fr: "Dimanche"
39
36
  }
40
37
  },
41
- fr: {
42
- translations: {
43
- "datetime.days": ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"],
44
- "datetime.months": [
45
- "Janvier",
46
- "F\xE9vrier",
47
- "Mars",
48
- "Avril",
49
- "Mai",
50
- "Juin",
51
- "Juillet",
52
- "Ao\xFBt",
53
- "Septembre",
54
- "Octobre",
55
- "Novembre",
56
- "D\xE9cembre"
57
- ],
58
- "form.append": "Ajouter",
59
- "form.errors.required": "Ce champ est obligatoire",
60
- "form.errors.unknown": "Erreur inconnue",
61
- "form.radio.labels.false": "Faux",
62
- "form.radio.labels.true": "Vrai",
63
- "form.remove": "Supprimer",
64
- "form.reset": "R\xE9initialiser",
65
- "form.submit": "Soumettre",
66
- "notifications.types.error": "Erreur",
67
- "notifications.types.info": "Attention",
68
- "notifications.types.success": "Succ\xE8s",
69
- "notifications.types.warning": "Avertissement",
70
- "searchBar.placeholder": "Rechercher...",
71
- "table.pagination.info": "Affichage de {{first}} \xE0 {{last}} sur {{total}} r\xE9sultats",
72
- "table.pagination.next": "Suivante",
73
- "table.pagination.previous": "Pr\xE9c\xE9dente"
38
+ months: {
39
+ january: {
40
+ en: "January",
41
+ fr: "Janvier"
42
+ },
43
+ february: {
44
+ en: "February",
45
+ fr: "F\xE9vrier"
46
+ },
47
+ march: {
48
+ en: "March",
49
+ fr: "Mars"
50
+ },
51
+ april: {
52
+ en: "April",
53
+ fr: "Avril"
54
+ },
55
+ may: {
56
+ en: "May",
57
+ fr: "Mai"
58
+ },
59
+ june: {
60
+ en: "June",
61
+ fr: "Juin"
62
+ },
63
+ july: {
64
+ en: "July",
65
+ fr: "Juillet"
66
+ },
67
+ august: {
68
+ en: "August",
69
+ fr: "Ao\xFBt"
70
+ },
71
+ september: {
72
+ en: "September",
73
+ fr: "Septembre"
74
+ },
75
+ october: {
76
+ en: "October",
77
+ fr: "Octobre"
78
+ },
79
+ november: {
80
+ en: "November",
81
+ fr: "Novembre"
82
+ },
83
+ december: {
84
+ en: "December",
85
+ fr: "D\xE9cembre"
86
+ }
87
+ },
88
+ form: {
89
+ append: {
90
+ en: "Append",
91
+ fr: "Ajouter"
92
+ },
93
+ required: {
94
+ en: "This field is required",
95
+ fr: "Ce champ est obligatoire"
96
+ },
97
+ remove: {
98
+ en: "Remove",
99
+ fr: "Supprimer"
100
+ },
101
+ radioLabels: {
102
+ true: {
103
+ en: "True",
104
+ fr: "Vrai"
105
+ },
106
+ false: {
107
+ en: "False",
108
+ fr: "Faux"
109
+ }
74
110
  }
75
111
  }
76
112
  };
113
+
114
+ // src/i18n.ts
115
+ var defaultNS = "libui";
116
+ var supportedLngs = ["en", "fr"];
117
+ function transformTranslations(translations, locale) {
118
+ const isPlainObject = Object.getPrototypeOf(translations) === Object.prototype;
119
+ if (!isPlainObject) {
120
+ throw new Error("Invalid format of translations: must be plain object");
121
+ }
122
+ const result = {};
123
+ for (const key in translations) {
124
+ const value = translations[key];
125
+ if (Object.hasOwn(value, locale)) {
126
+ result[key] = value[locale];
127
+ } else {
128
+ result[key] = transformTranslations(value, locale);
129
+ }
130
+ }
131
+ return result;
132
+ }
133
+ function createResourcesForLanguage(translations, locale) {
134
+ return mapValues(translations, (value) => transformTranslations(value, locale));
135
+ }
136
+ function createResources(translations) {
137
+ return {
138
+ en: createResourcesForLanguage(translations, "en"),
139
+ fr: createResourcesForLanguage(translations, "fr")
140
+ };
141
+ }
142
+ var resources = createResources({ libui: libui_default });
77
143
  var i18n = createInstance({
78
144
  defaultNS,
79
145
  fallbackLng: "en",
80
146
  interpolation: {
81
147
  escapeValue: false
82
148
  },
149
+ lng: "en",
83
150
  resources,
84
151
  returnObjects: true,
85
- supportedLngs: ["en", "fr"]
152
+ supportedLngs
86
153
  });
87
- void i18n.use(initReactI18next).init();
154
+ await i18n.use(initReactI18next).init();
88
155
  var i18n_default = i18n;
89
156
  export {
90
- i18n_default as default,
91
- defaultNS,
92
- resources
157
+ i18n_default as default
93
158
  };
94
159
  //# sourceMappingURL=i18n.js.map
package/dist/i18n.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/i18n.ts"],"sourcesContent":["import { type i18n as I18n, createInstance } from 'i18next';\nimport { initReactI18next } from 'react-i18next';\n\nconst defaultNS = 'translations';\n\nconst resources = {\n en: {\n translations: {\n 'datetime.days': ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n 'datetime.months': [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December'\n ],\n 'form.append': 'Append',\n 'form.errors.required': 'This field is required',\n 'form.errors.unknown': 'Unknown error',\n 'form.radio.labels.false': 'False',\n 'form.radio.labels.true': 'True',\n 'form.remove': 'Remove',\n 'form.reset': 'Clear',\n 'form.submit': 'Submit',\n 'notifications.types.error': 'Error',\n 'notifications.types.info': 'Info',\n 'notifications.types.success': 'Success',\n 'notifications.types.warning': 'Warning',\n 'searchBar.placeholder': 'Search...',\n 'table.pagination.info': 'Showing {{first}} to {{last}} of {{total}} results',\n 'table.pagination.next': 'Next',\n 'table.pagination.previous': 'Previous'\n }\n },\n fr: {\n translations: {\n 'datetime.days': ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],\n 'datetime.months': [\n 'Janvier',\n 'Février',\n 'Mars',\n 'Avril',\n 'Mai',\n 'Juin',\n 'Juillet',\n 'Août',\n 'Septembre',\n 'Octobre',\n 'Novembre',\n 'Décembre'\n ],\n 'form.append': 'Ajouter',\n 'form.errors.required': 'Ce champ est obligatoire',\n 'form.errors.unknown': 'Erreur inconnue',\n 'form.radio.labels.false': 'Faux',\n 'form.radio.labels.true': 'Vrai',\n 'form.remove': 'Supprimer',\n 'form.reset': 'Réinitialiser',\n 'form.submit': 'Soumettre',\n 'notifications.types.error': 'Erreur',\n 'notifications.types.info': 'Attention',\n 'notifications.types.success': 'Succès',\n 'notifications.types.warning': 'Avertissement',\n 'searchBar.placeholder': 'Rechercher...',\n 'table.pagination.info': 'Affichage de {{first}} à {{last}} sur {{total}} résultats',\n 'table.pagination.next': 'Suivante',\n 'table.pagination.previous': 'Précédente'\n }\n }\n} as const;\n\nconst i18n = createInstance({\n defaultNS,\n fallbackLng: 'en',\n interpolation: {\n escapeValue: false\n },\n resources,\n returnObjects: true,\n supportedLngs: ['en', 'fr']\n}) as I18n;\n\nvoid i18n.use(initReactI18next).init();\n\nexport { defaultNS, resources };\n\nexport default i18n;\n"],"mappings":";AAAA,SAA4B,sBAAsB;AAClD,SAAS,wBAAwB;AAEjC,IAAM,YAAY;AAElB,IAAM,YAAY;AAAA,EAChB,IAAI;AAAA,IACF,cAAc;AAAA,MACZ,iBAAiB,CAAC,UAAU,UAAU,WAAW,aAAa,YAAY,UAAU,UAAU;AAAA,MAC9F,mBAAmB;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,eAAe;AAAA,MACf,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,2BAA2B;AAAA,MAC3B,0BAA0B;AAAA,MAC1B,eAAe;AAAA,MACf,cAAc;AAAA,MACd,eAAe;AAAA,MACf,6BAA6B;AAAA,MAC7B,4BAA4B;AAAA,MAC5B,+BAA+B;AAAA,MAC/B,+BAA+B;AAAA,MAC/B,yBAAyB;AAAA,MACzB,yBAAyB;AAAA,MACzB,yBAAyB;AAAA,MACzB,6BAA6B;AAAA,IAC/B;AAAA,EACF;AAAA,EACA,IAAI;AAAA,IACF,cAAc;AAAA,MACZ,iBAAiB,CAAC,YAAY,SAAS,SAAS,YAAY,SAAS,YAAY,QAAQ;AAAA,MACzF,mBAAmB;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,eAAe;AAAA,MACf,wBAAwB;AAAA,MACxB,uBAAuB;AAAA,MACvB,2BAA2B;AAAA,MAC3B,0BAA0B;AAAA,MAC1B,eAAe;AAAA,MACf,cAAc;AAAA,MACd,eAAe;AAAA,MACf,6BAA6B;AAAA,MAC7B,4BAA4B;AAAA,MAC5B,+BAA+B;AAAA,MAC/B,+BAA+B;AAAA,MAC/B,yBAAyB;AAAA,MACzB,yBAAyB;AAAA,MACzB,yBAAyB;AAAA,MACzB,6BAA6B;AAAA,IAC/B;AAAA,EACF;AACF;AAEA,IAAM,OAAO,eAAe;AAAA,EAC1B;AAAA,EACA,aAAa;AAAA,EACb,eAAe;AAAA,IACb,aAAa;AAAA,EACf;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,eAAe,CAAC,MAAM,IAAI;AAC5B,CAAC;AAED,KAAK,KAAK,IAAI,gBAAgB,EAAE,KAAK;AAIrC,IAAO,eAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/i18n.ts","../src/translations/libui.json"],"sourcesContent":["import { type i18n as I18n, createInstance } from 'i18next';\nimport { mapValues } from 'lodash-es';\nimport { initReactI18next } from 'react-i18next';\nimport type { EmptyObject, ValueOf } from 'type-fest';\n\nimport libui from './translations/libui.json';\n\nconst defaultNS = 'libui' as const;\nconst supportedLngs = ['en', 'fr'] as const;\n\ntype DefaultNS = typeof defaultNS;\ntype Language = (typeof supportedLngs)[number];\n\ntype TranslationsDef = Record<string, Record<string, unknown>>;\n\ntype TranslatedResource<T = EmptyObject> = {\n [K in keyof T]: T[K] extends Record<string, unknown>\n ? T[K] extends Record<Language, unknown>\n ? ValueOf<T[K]>\n : TranslatedResource<T[K]>\n : T[K];\n};\n\nfunction transformTranslations<T extends Record<string, any>>(translations: T, locale: string) {\n const isPlainObject = Object.getPrototypeOf(translations) === Object.prototype;\n if (!isPlainObject) {\n throw new Error('Invalid format of translations: must be plain object');\n }\n const result: Record<string, unknown> = {};\n for (const key in translations) {\n const value = translations[key];\n if (Object.hasOwn(value, locale)) {\n result[key] = value[locale as keyof typeof value];\n } else {\n result[key] = transformTranslations(value, locale);\n }\n }\n return result;\n}\n\nfunction createResourcesForLanguage<T extends TranslationsDef>(translations: T, locale: Language) {\n return mapValues(translations, (value) => transformTranslations(value, locale));\n}\n\nfunction createResources<T extends TranslationsDef>(translations: T) {\n return {\n en: createResourcesForLanguage(translations, 'en'),\n fr: createResourcesForLanguage(translations, 'fr')\n } as TranslatedResource<T>;\n}\n\nconst resources = createResources({ libui });\n\nconst i18n = createInstance({\n defaultNS,\n fallbackLng: 'en' satisfies Language,\n interpolation: {\n escapeValue: false\n },\n lng: 'en' satisfies Language,\n resources,\n returnObjects: true,\n supportedLngs\n}) as I18n;\n\nawait i18n.use(initReactI18next).init();\n\nexport default i18n;\n\nexport type { DefaultNS, Language, TranslatedResource };\n","{\n \"days\": {\n \"monday\": {\n \"en\": \"Monday\",\n \"fr\": \"Lundi\"\n },\n \"tuesday\": {\n \"en\": \"Tuesday\",\n \"fr\": \"Mardi\"\n },\n \"wednesday\": {\n \"en\": \"Wednesday\",\n \"fr\": \"Mercredi\"\n },\n \"thursday\": {\n \"en\": \"Thursday\",\n \"fr\": \"Jeudi\"\n },\n \"friday\": {\n \"en\": \"Friday\",\n \"fr\": \"Vendredi\"\n },\n \"saturday\": {\n \"en\": \"Saturday\",\n \"fr\": \"Samedi\"\n },\n \"sunday\": {\n \"en\": \"Sunday\",\n \"fr\": \"Dimanche\"\n }\n },\n \"months\": {\n \"january\": {\n \"en\": \"January\",\n \"fr\": \"Janvier\"\n },\n \"february\": {\n \"en\": \"February\",\n \"fr\": \"Février\"\n },\n \"march\": {\n \"en\": \"March\",\n \"fr\": \"Mars\"\n },\n \"april\": {\n \"en\": \"April\",\n \"fr\": \"Avril\"\n },\n \"may\": {\n \"en\": \"May\",\n \"fr\": \"Mai\"\n },\n \"june\": {\n \"en\": \"June\",\n \"fr\": \"Juin\"\n },\n \"july\": {\n \"en\": \"July\",\n \"fr\": \"Juillet\"\n },\n \"august\": {\n \"en\": \"August\",\n \"fr\": \"Août\"\n },\n \"september\": {\n \"en\": \"September\",\n \"fr\": \"Septembre\"\n },\n \"october\": {\n \"en\": \"October\",\n \"fr\": \"Octobre\"\n },\n \"november\": {\n \"en\": \"November\",\n \"fr\": \"Novembre\"\n },\n \"december\": {\n \"en\": \"December\",\n \"fr\": \"Décembre\"\n }\n },\n \"form\": {\n \"append\": {\n \"en\": \"Append\",\n \"fr\": \"Ajouter\"\n },\n \"required\": {\n \"en\": \"This field is required\",\n \"fr\": \"Ce champ est obligatoire\"\n },\n \"remove\": {\n \"en\": \"Remove\",\n \"fr\": \"Supprimer\"\n },\n \"radioLabels\": {\n \"true\": {\n \"en\": \"True\",\n \"fr\": \"Vrai\"\n },\n \"false\": {\n \"en\": \"False\",\n \"fr\": \"Faux\"\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -78,3 +78,9 @@
78
78
  'calt' 1;
79
79
  }
80
80
  }
81
+
82
+ .lucide {
83
+ width: 16px;
84
+ height: 16px;
85
+ stroke-width: 1.5px;
86
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@douglasneuroinformatics/libui",
3
3
  "type": "module",
4
- "version": "1.2.0",
4
+ "version": "1.4.0",
5
5
  "packageManager": "pnpm@8.15.3",
6
6
  "description": "Generic UI components for DNP projects, built using React and TailwindCSS",
7
7
  "author": {
@@ -63,19 +63,35 @@
63
63
  "tailwindcss": "^3.3.5"
64
64
  },
65
65
  "dependencies": {
66
+ "@douglasneuroinformatics/libjs": "^0.0.3",
67
+ "@douglasneuroinformatics/libui-form-types": "^0.0.1",
66
68
  "@radix-ui/react-accordion": "^1.1.2",
67
- "@radix-ui/react-icons": "^1.3.0",
69
+ "@radix-ui/react-avatar": "^1.0.4",
70
+ "@radix-ui/react-checkbox": "^1.0.4",
71
+ "@radix-ui/react-dropdown-menu": "^2.0.6",
68
72
  "@radix-ui/react-label": "^2.0.2",
73
+ "@radix-ui/react-popover": "^1.0.7",
74
+ "@radix-ui/react-radio-group": "^1.1.3",
75
+ "@radix-ui/react-scroll-area": "^1.0.5",
76
+ "@radix-ui/react-select": "^2.0.0",
77
+ "@radix-ui/react-separator": "^1.0.3",
69
78
  "@radix-ui/react-slot": "^1.0.2",
79
+ "@radix-ui/react-switch": "^1.0.3",
80
+ "@radix-ui/react-tabs": "^1.0.4",
81
+ "@radix-ui/react-tooltip": "^1.0.7",
70
82
  "class-variance-authority": "^0.7.0",
71
83
  "clsx": "^2.1.0",
84
+ "framer-motion": "^11.0.13",
72
85
  "i18next": "23.x",
73
86
  "i18next-browser-languagedetector": "^7.2.0",
74
87
  "lodash-es": "^4.17.21",
88
+ "lucide-react": "^0.358.0",
75
89
  "react-i18next": "^14.1.0",
76
90
  "tailwind-merge": "^2.2.1",
77
91
  "tailwindcss-animate": "^1.0.7",
92
+ "ts-pattern": "^5.0.8",
78
93
  "type-fest": "^4.12.0",
94
+ "zod": "^3.22.4",
79
95
  "zustand": "^4.5.2"
80
96
  },
81
97
  "devDependencies": {
@@ -89,8 +105,8 @@
89
105
  "@storybook/addon-essentials": "^8.0.0",
90
106
  "@storybook/addon-interactions": "^8.0.0",
91
107
  "@storybook/addon-links": "^8.0.0",
92
- "@storybook/addon-themes": "^8.0.0",
93
108
  "@storybook/blocks": "^8.0.0",
109
+ "@storybook/components": "^8.0.0",
94
110
  "@storybook/icons": "^1.2.9",
95
111
  "@storybook/manager-api": "^8.0.0",
96
112
  "@storybook/react": "^8.0.0",