@awsmbiz/inbis-ui 0.1.0 → 0.2.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
@@ -9,7 +9,7 @@ visible focus indicator, touch targets of at least 24×24 px, and `prefers-reduc
9
9
  |---|---|
10
10
  | `@awsmbiz/inbis-ui` | Primitives: `Button`, `Input`, `Label`, `Card`, `Alert`, `Badge`, `Checkbox`, `Switch`, `NativeSelect` (+ `NativeSelectOption`, `NativeSelectOptGroup`), `Dialog`, `AlertDialog`, `Sheet`, `DropdownMenu`, `Tooltip` (+ `TooltipProvider`), `Tabs`, `Table`, `Pagination`, `Skeleton`, `Separator`, `Field*` layout parts, `Toaster` + `toast` (sonner), each with its shadcn sub-components; variant helpers `buttonVariants`, `badgeVariants`, `tabsListVariants`; `cn` |
11
11
  | | Forms: `useZodForm`, `Form`, `FormField`, `FormRootError` (below); types `FormProps`, `FormFieldProps`, `FormControlProps` |
12
- | `@awsmbiz/inbis-ui/globals.css` | Tailwind v4 entry: `tailwindcss`, `tw-animate-css`, `shadcn/tailwind.css`, the neutral light/dark theme tokens, the reduced-motion rule, and `@source` for this package's `dist` |
12
+ | `@awsmbiz/inbis-ui/globals.css` | Tailwind v4 entry: `tailwindcss`, `tw-animate-css`, `shadcn/tailwind.css`, the Inbis UI light/dark theme tokens (below), the reduced-motion rule, and `@source` for this package's `dist` |
13
13
 
14
14
  Peer dependencies: `react` and `react-dom` ^19.3.1, `tailwindcss` ^4.3.3, `react-hook-form`
15
15
  ^7.91.0 and `zod` ^4.6.7 (for the forms). Dependencies: `radix-ui`, `class-variance-authority`,
@@ -35,6 +35,48 @@ by the components are generated in the consuming app, also when installed from n
35
35
  Dark theme: put the `dark` class on `<html>` (and `color-scheme: dark`). Render one `<Toaster />`
36
36
  (pass `theme` to match) and wrap the app in `<TooltipProvider>` if it uses tooltips.
37
37
 
38
+ ## Design system: Inbis UI
39
+
40
+ The theme is the Inbis UI design system; the reference (tokens, per-component rules, content and
41
+ visual guidance) is in [`docs/design/inbis-ui/`](../../docs/design/inbis-ui/). In short: a warm
42
+ off-white canvas, an ink primary pill, hairline borders and almost no shadow.
43
+
44
+ - **Colour tokens** keep shadcn's names (`background`, `card`, `popover`, `primary`, `secondary`,
45
+ `muted`, `accent`, `destructive`, `border`, `input`, `ring`, `sidebar-*`), so every shadcn
46
+ component picks them up. Added: `surface-raised` (field fill), `panel`, `night` / `on-night` /
47
+ `on-night-muted`, `destructive-foreground`, status `success`, `success-soft`, `warning-soft`,
48
+ `info-soft`, `destructive-soft` (each `-soft` with a `-soft-foreground`), the identity palette
49
+ `app-green`, `app-purple`, `app-orange`, `app-rose`, `app-blue`, `rating`, and `chart-1`…`chart-5`.
50
+ All are Tailwind colours (`bg-success-soft`, `text-info-soft-foreground`, `bg-app-blue`).
51
+ The `app-*` colours are identity only (an app's icon tile, charts), never buttons, text or
52
+ badges; which app uses which colour is the app's choice, not the platform's.
53
+ - **Radius** (`--radius` is 12px): `rounded-sm` 8px (menu items), `rounded-md` 12px (fields,
54
+ popovers, alerts, icon tiles), `rounded-lg` / `rounded-2xl` 16px (cards, tables, toasts),
55
+ `rounded-xl` / `rounded-3xl` 22px (dialogs, sheets). Buttons, badges, switches, tab triggers,
56
+ avatars and sidebar items are `rounded-full`.
57
+ - **Shadows** are CSS variables, used as `shadow-(--shadow-card)`, `shadow-(--shadow-popover)` and
58
+ `shadow-(--shadow-float)` (dialogs only).
59
+ - **Focus**: a 2px solid `ring` outline at a 2px offset on every interactive element
60
+ (`focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid focus-visible:outline-ring`).
61
+ - **Status badges and alerts**: `Badge` and `Alert` have `success`, `warning`, `info` and
62
+ `destructive` variants on the `*-soft` tokens; the word always carries the state.
63
+ - **Motion**: 150ms colour transitions, the switch thumb and the skeleton pulse; all cut under
64
+ reduced motion (below).
65
+ - **Icons**: Lucide, 16px in controls, 20px in navigation.
66
+
67
+ ### Loading Inter
68
+
69
+ `--font-sans` is `var(--font-inter, "Inter"), ui-sans-serif, system-ui, sans-serif`. The package
70
+ never fetches fonts (no third-party request is made on the app's behalf); load Inter (400–700) in
71
+ the app, whichever way suits it:
72
+
73
+ - Self-hosted, e.g. `pnpm add @fontsource-variable/inter` and `import "@fontsource-variable/inter";`
74
+ in the entry, then `--font-inter: "Inter Variable";` on `:root`.
75
+ - Next.js: `next/font/google` with `variable: "--font-inter"` on `<html>`.
76
+ - A `<link>` to Google Fonts (family "Inter", weights 400–700), if the app accepts the request.
77
+
78
+ Without Inter the stack falls back to the system UI font.
79
+
38
80
  ## Forms
39
81
 
40
82
  ```tsx
@@ -72,9 +114,9 @@ Generated files are kept as the CLI writes them except for these deliberate chan
72
114
  checked by a test:
73
115
 
74
116
  - **Tokens** (`test/theme-contrast.test.ts` checks every text/surface pair at 4.5:1 and every
75
- control boundary, checked state and focus ring at 3:1, in both themes): light `--destructive`
76
- is red-700; light `--muted-foreground`, `--input`, `--ring` and `--sidebar-ring` are darker;
77
- dark `--input` is opaque.
117
+ control boundary, checked state and focus ring at 3:1, in both themes, plus every `*-soft`
118
+ status pair and a white icon on each `app-*` tile): the Inbis UI tokens pass as designed;
119
+ `--input` is a 3:1 field border on the page, card, popover and field fill.
78
120
  - **Select** is shadcn's `native-select`, not the Radix listbox: Radix's select always hides the
79
121
  rest of the page with `aria-hidden` while it is open, which axe reports (`aria-hidden-focus`).
80
122
  A native select is fully accessible and gives phones their own picker.
@@ -85,6 +127,15 @@ checked by a test:
85
127
  cut off (WCAG 1.4.10 Reflow; `e2e/a11y-admin.spec.ts`).
86
128
  - **Tab panels** show the focus ring; **pagination** links are named "Previous page"/"Next page"
87
129
  (the visible text is part of the name); the **toaster** takes `theme` instead of `next-themes`.
130
+ - **Breadcrumb**: the current page is text with `aria-current="page"` (not shadcn's disabled
131
+ `role="link"`), separators are presentational list items, and the landmark is named
132
+ "Breadcrumb" by default (pass `aria-label` to translate).
133
+ - **Avatar group** (not in shadcn): `AvatarGroup max={n}` collapses the rest into a "+N" avatar;
134
+ name the group with `aria-label` so the total is announced.
135
+ - **Steps** (not in shadcn): a step indicator for multi-step forms, a named `<nav>` over an
136
+ `<ol>`; the current step has `aria-current="step"`, a completed step announces
137
+ `completedLabel` ("Completed") before its label, and a step with `onClick` is a button.
138
+ - **Progress** needs a name (`aria-label`/`aria-labelledby`); its value is `aria-valuenow`.
88
139
  - **Reduced motion**: `globals.css` cuts every animation and transition to an instant under
89
140
  `prefers-reduced-motion: reduce`.
90
141
 
@@ -95,7 +146,9 @@ desktop and phone widths, and checks keyboard use, focus indicators, touch targe
95
146
  ## Tests
96
147
 
97
148
  `test/theme-contrast.test.ts` (every token pair in both themes) and `test/form.test.tsx` (label,
98
- description and error wiring, focus on the first error) run in `pnpm test` (Vitest + jsdom).
149
+ description and error wiring, focus on the first error) and `test/components.test.tsx` (behaviour,
150
+ ARIA and axe in both themes for the accordion, breadcrumb, radio group, textarea, progress, avatar
151
+ and steps) run in `pnpm test` (Vitest + jsdom).
99
152
  The components are covered in a real browser by the playground: `e2e/ui-gallery.spec.ts` (every
100
153
  component and state) and, as used by the screens, `e2e/accessibility.spec.ts`,
101
154
  `e2e/a11y-app.spec.ts`, `e2e/a11y-admin.spec.ts` and `e2e/a11y-focus.spec.ts`.
package/dist/index.d.ts CHANGED
@@ -1,13 +1,17 @@
1
1
  import * as React$1 from "react";
2
2
  import { ComponentProps, ReactNode } from "react";
3
- import { VariantProps } from "class-variance-authority";
4
3
  import { cn } from "cn";
5
- import { AlertDialog as AlertDialog$1, Checkbox as Checkbox$1, Dialog as Dialog$1, DropdownMenu as DropdownMenu$1, Label as Label$1, Separator as Separator$1, Switch as Switch$1, Tabs as Tabs$1, Tooltip as Tooltip$1 } from "radix-ui";
4
+ import { Accordion as Accordion$1, AlertDialog as AlertDialog$1, Avatar as Avatar$1, Checkbox as Checkbox$1, Dialog as Dialog$1, DropdownMenu as DropdownMenu$1, Label as Label$1, Progress as Progress$1, RadioGroup as RadioGroup$1, Separator as Separator$1, Switch as Switch$1, Tabs as Tabs$1, Tooltip as Tooltip$1 } from "radix-ui";
5
+ import { VariantProps } from "class-variance-authority";
6
6
  import { ToasterProps, toast } from "sonner";
7
7
  import { Control, ControllerFieldState, ControllerRenderProps, FieldPath, FieldValues, SubmitHandler, UseFormProps, UseFormReturn } from "react-hook-form";
8
8
  import { z } from "zod";
9
+ declare function Accordion({ ...props }: React$1.ComponentProps<typeof Accordion$1.Root>): React$1.JSX.Element;
10
+ declare function AccordionItem({ className, ...props }: React$1.ComponentProps<typeof Accordion$1.Item>): React$1.JSX.Element;
11
+ declare function AccordionTrigger({ className, children, ...props }: React$1.ComponentProps<typeof Accordion$1.Trigger>): React$1.JSX.Element;
12
+ declare function AccordionContent({ className, children, ...props }: React$1.ComponentProps<typeof Accordion$1.Content>): React$1.JSX.Element;
9
13
  declare const alertVariants: (props?: ({
10
- variant?: "default" | "destructive" | null | undefined;
14
+ variant?: "default" | "success" | "warning" | "info" | "destructive" | null | undefined;
11
15
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
16
  declare function Alert({ className, variant, ...props }: React$1.ComponentProps<"div"> & VariantProps<typeof alertVariants>): React$1.JSX.Element;
13
17
  declare function AlertTitle({ className, ...props }: React$1.ComponentProps<"div">): React$1.JSX.Element;
@@ -34,12 +38,33 @@ declare function AlertDialogTitle({ className, ...props }: React$1.ComponentProp
34
38
  declare function AlertDialogDescription({ className, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Description>): React$1.JSX.Element;
35
39
  declare function AlertDialogAction({ className, variant, size, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Action> & Pick<React$1.ComponentProps<typeof Button>, "variant" | "size">): React$1.JSX.Element;
36
40
  declare function AlertDialogCancel({ className, variant, size, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Cancel> & Pick<React$1.ComponentProps<typeof Button>, "variant" | "size">): React$1.JSX.Element;
41
+ type AvatarSize = "xs" | "sm" | "default" | "lg";
42
+ declare function Avatar({ className, size, ...props }: React$1.ComponentProps<typeof Avatar$1.Root> & {
43
+ size?: AvatarSize;
44
+ }): React$1.JSX.Element;
45
+ declare function AvatarImage({ className, ...props }: React$1.ComponentProps<typeof Avatar$1.Image>): React$1.JSX.Element;
46
+ declare function AvatarFallback({ className, ...props }: React$1.ComponentProps<typeof Avatar$1.Fallback>): React$1.JSX.Element;
47
+ declare function AvatarGroup({ className, children, max, size, ...props }: React$1.ComponentProps<"div"> & {
48
+ max?: number;
49
+ size?: AvatarSize;
50
+ }): React$1.JSX.Element;
37
51
  declare const badgeVariants: (props?: ({
38
- variant?: "default" | "destructive" | "secondary" | "outline" | "ghost" | "link" | null | undefined;
52
+ variant?: "default" | "success" | "warning" | "info" | "destructive" | "secondary" | "outline" | "ghost" | "link" | null | undefined;
39
53
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
40
54
  declare function Badge({ className, variant, asChild, ...props }: React$1.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & {
41
55
  asChild?: boolean;
42
56
  }): React$1.JSX.Element;
57
+ declare function Breadcrumb({ "aria-label": label, ...props }: React$1.ComponentProps<"nav">): React$1.JSX.Element;
58
+ declare function BreadcrumbList({ className, ...props }: React$1.ComponentProps<"ol">): React$1.JSX.Element;
59
+ declare function BreadcrumbItem({ className, ...props }: React$1.ComponentProps<"li">): React$1.JSX.Element;
60
+ declare function BreadcrumbLink({ asChild, className, ...props }: React$1.ComponentProps<"a"> & {
61
+ asChild?: boolean;
62
+ }): React$1.JSX.Element;
63
+ declare function BreadcrumbPage({ className, ...props }: React$1.ComponentProps<"span">): React$1.JSX.Element;
64
+ declare function BreadcrumbSeparator({ children, className, ...props }: React$1.ComponentProps<"li">): React$1.JSX.Element;
65
+ declare function BreadcrumbEllipsis({ className, label, ...props }: React$1.ComponentProps<"span"> & {
66
+ label?: string;
67
+ }): React$1.JSX.Element;
43
68
  declare function Card({ className, size, ...props }: React$1.ComponentProps<"div"> & {
44
69
  size?: "default" | "sm";
45
70
  }): React$1.JSX.Element;
@@ -133,6 +158,9 @@ type NativeSelectProps = Omit<React$1.ComponentProps<"select">, "size"> & {
133
158
  declare function NativeSelect({ className, size, ...props }: NativeSelectProps): React$1.JSX.Element;
134
159
  declare function NativeSelectOption({ className, ...props }: React$1.ComponentProps<"option">): React$1.JSX.Element;
135
160
  declare function NativeSelectOptGroup({ className, ...props }: React$1.ComponentProps<"optgroup">): React$1.JSX.Element;
161
+ declare function Progress({ className, value, ...props }: React$1.ComponentProps<typeof Progress$1.Root>): React$1.JSX.Element;
162
+ declare function RadioGroup({ className, ...props }: React$1.ComponentProps<typeof RadioGroup$1.Root>): React$1.JSX.Element;
163
+ declare function RadioGroupItem({ className, ...props }: React$1.ComponentProps<typeof RadioGroup$1.Item>): React$1.JSX.Element;
136
164
  declare function Separator({ className, orientation, decorative, ...props }: React$1.ComponentProps<typeof Separator$1.Root>): React$1.JSX.Element;
137
165
  declare function Sheet({ ...props }: React$1.ComponentProps<typeof Dialog$1.Root>): React$1.JSX.Element;
138
166
  declare function SheetTrigger({ ...props }: React$1.ComponentProps<typeof Dialog$1.Trigger>): React$1.JSX.Element;
@@ -147,6 +175,16 @@ declare function SheetTitle({ className, ...props }: React$1.ComponentProps<type
147
175
  declare function SheetDescription({ className, ...props }: React$1.ComponentProps<typeof Dialog$1.Description>): React$1.JSX.Element;
148
176
  declare function Skeleton({ className, ...props }: React.ComponentProps<"div">): import("react").JSX.Element;
149
177
  declare const Toaster: ({ ...props }: ToasterProps) => import("react").JSX.Element;
178
+ type StepStatus = "complete" | "current" | "upcoming";
179
+ declare function Steps({ className, children, "aria-label": label, ...props }: React$1.ComponentProps<"nav">): React$1.JSX.Element;
180
+ interface StepsItemProps extends Omit<React$1.ComponentProps<"button">, "type"> {
181
+ /** The step's number, shown until it is complete. */
182
+ step: number;
183
+ status: StepStatus;
184
+ /** Prefix announced before a completed step's label (visually a check mark). */
185
+ completedLabel?: string;
186
+ }
187
+ declare function StepsItem({ className, children, step, status, completedLabel, onClick, ...props }: StepsItemProps): React$1.JSX.Element;
150
188
  declare function Switch({ className, size, ...props }: React$1.ComponentProps<typeof Switch$1.Root> & {
151
189
  size?: "sm" | "default";
152
190
  }): React$1.JSX.Element;
@@ -165,6 +203,7 @@ declare const tabsListVariants: (props?: ({
165
203
  declare function TabsList({ className, variant, ...props }: React$1.ComponentProps<typeof Tabs$1.List> & VariantProps<typeof tabsListVariants>): React$1.JSX.Element;
166
204
  declare function TabsTrigger({ className, ...props }: React$1.ComponentProps<typeof Tabs$1.Trigger>): React$1.JSX.Element;
167
205
  declare function TabsContent({ className, ...props }: React$1.ComponentProps<typeof Tabs$1.Content>): React$1.JSX.Element;
206
+ declare function Textarea({ className, ...props }: React$1.ComponentProps<"textarea">): React$1.JSX.Element;
168
207
  declare function TooltipProvider({ delayDuration, ...props }: React$1.ComponentProps<typeof Tooltip$1.Provider>): React$1.JSX.Element;
169
208
  declare function Tooltip({ ...props }: React$1.ComponentProps<typeof Tooltip$1.Root>): React$1.JSX.Element;
170
209
  declare function TooltipTrigger({ ...props }: React$1.ComponentProps<typeof Tooltip$1.Trigger>): React$1.JSX.Element;
@@ -204,5 +243,5 @@ export declare function FormField<TFieldValues extends FieldValues, TName extend
204
243
  export declare function FormRootError({ className }: {
205
244
  className?: string;
206
245
  }): import("react").JSX.Element | null;
207
- export { Alert, AlertAction, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, Badge, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, type FormControlProps, type FormFieldProps, type FormProps, Input, Label, NativeSelect, NativeSelectOptGroup, NativeSelectOption, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Skeleton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, cn, tabsListVariants, toast };
246
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertAction, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, Avatar, AvatarFallback, AvatarGroup, AvatarImage, type AvatarSize, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, type FormControlProps, type FormFieldProps, type FormProps, Input, Label, NativeSelect, NativeSelectOptGroup, NativeSelectOption, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Progress, RadioGroup, RadioGroupItem, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Skeleton, type StepStatus, Steps, StepsItem, type StepsItemProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toaster, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, cn, tabsListVariants, toast };
208
247
  //# sourceMappingURL=index.d.ts.map