@akira-io/ui 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NosFerry
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ <p align="center">
2
+ <img src="assets/banner.svg" alt="Akira UI" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license: MIT">
7
+ <img src="https://img.shields.io/badge/react-18%20%7C%2019-61dafb.svg" alt="react 18 or 19">
8
+ <img src="https://img.shields.io/badge/package%20manager-bun-fbf0df.svg" alt="bun">
9
+ </p>
10
+
11
+ Open-source React component library: the full shadcn/ui (New York) set on an OKLCH design-token system,
12
+ plus a handful of blocks and application shells built on top of it. The default palette is Akira purple.
13
+ Swap it for your own brand with a single CSS import, no component code changes required.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ bun add @akira-io/ui
19
+ ```
20
+
21
+ ```bash
22
+ # npm
23
+ npm install @akira-io/ui
24
+
25
+ # pnpm
26
+ pnpm add @akira-io/ui
27
+
28
+ # yarn
29
+ yarn add @akira-io/ui
30
+ ```
31
+
32
+ Peer dependencies: `react` and `react-dom`, 18 or 19. `@inertiajs/react` is only needed if you import from
33
+ the `/inertia` entry point; `react-hook-form` is only needed for the `<Form>` component. Neither is required
34
+ for the primitives, the blocks, or the generic shells.
35
+
36
+ ## Theme (Tailwind v4)
37
+
38
+ Import the tokens once, in your app's main CSS:
39
+
40
+ ```css
41
+ @import 'tailwindcss';
42
+ @plugin 'tailwindcss-animate';
43
+ @import '@akira-io/ui/theme.css';
44
+ @source '../../node_modules/@akira-io/ui/dist';
45
+ ```
46
+
47
+ `tailwindcss-animate` generates the `animate-in` / `fade-in` / `zoom-in` utility classes several components
48
+ use for enter and exit transitions (dialogs, dropdowns, tooltips). `@source` points Tailwind at the compiled
49
+ package output so those utility classes are not purged.
50
+
51
+ No configuration is required to get the default Akira purple palette: `theme.css` sets `--primary` from the
52
+ Akira ramp in both light and dark mode.
53
+
54
+ ### Switching brands
55
+
56
+ Import a brand preset after `theme.css` and set `data-brand` on `<html>`:
57
+
58
+ ```css
59
+ @import '@akira-io/ui/theme.css';
60
+ @import '@akira-io/ui/themes/nosferry.css';
61
+ ```
62
+
63
+ ```html
64
+ <html data-brand="nosferry"></html>
65
+ ```
66
+
67
+ `themes/nosferry.css` ships today as the worked example: four custom properties (`--primary` and
68
+ `--primary-foreground`, light and dark) scoped to `[data-brand='nosferry']`. Write your own preset the same
69
+ way and ship it alongside your app; omitting `data-brand` renders Akira purple.
70
+
71
+ ## Use components
72
+
73
+ ```tsx
74
+ import { Button, Card, cn } from '@akira-io/ui';
75
+
76
+ export function Example() {
77
+ return (
78
+ <Card>
79
+ <Button className={cn('gap-2')}>Continue</Button>
80
+ </Card>
81
+ );
82
+ }
83
+ ```
84
+
85
+ The package is framework-agnostic at its core: the primitives and the tokens work in any React app (Inertia,
86
+ Next.js, plain Vite). Only the application shells need a router, and they take it as a prop rather than
87
+ importing one.
88
+
89
+ ## Subpath exports
90
+
91
+ | Import | Contents |
92
+ | --------------------------- | ----------------------------------------------------------------------------------------------------------- |
93
+ | `@akira-io/ui` | 55 shadcn/ui components + `cn` (zero framework coupling) |
94
+ | `@akira-io/ui/blocks` | 8 higher-level blocks: command palette, stat cards, settings cards, tour, and more |
95
+ | `@akira-io/ui/shells` | 12 application shell pieces: sidebar, header, nav, settings layout; take a polymorphic `linkComponent` prop |
96
+ | `@akira-io/ui/inertia` | The same shells with the Inertia `Link` and `usePage().url` pre-bound |
97
+ | `@akira-io/ui/theme.css` | The design tokens |
98
+ | `@akira-io/ui/themes/*.css` | Brand presets (`nosferry.css` ships as the example) |
99
+ | `@akira-io/ui/locales/pt` | Portuguese labels for the components that take them, as a typed object to spread |
100
+
101
+ Component text defaults to English. To render it in Portuguese, spread the locale object rather than
102
+ restating each prop:
103
+
104
+ ```tsx
105
+ import { DataTable } from '@akira-io/ui';
106
+ import { dataTableLabelsPt } from '@akira-io/ui/locales/pt';
107
+
108
+ <DataTable {...dataTableLabelsPt} columns={columns} data={rows} />;
109
+ ```
110
+
111
+ ## Documentation
112
+
113
+ Full documentation starts at [`docs/00-index.md`](docs/00-index.md):
114
+
115
+ - [Installation](docs/01-installation.md)
116
+ - [Theme & Tokens](docs/02-theme-and-tokens.md)
117
+ - [Components](docs/03-components.md)
118
+ - [Shells](docs/04-shells.md)
119
+ - [Adoption Guide](docs/05-adoption-guide.md)
120
+ - [Development & Release](docs/06-development.md)
121
+
122
+ A hosted documentation site is planned but does not exist yet.
123
+
124
+ ## Testing
125
+
126
+ ```bash
127
+ bun run test
128
+ ```
129
+
130
+ ## Changelog
131
+
132
+ Release notes are generated from conventional commits via [git-cliff](https://git-cliff.org) when a
133
+ `vX.Y.Z` tag is pushed (see `cliff.toml` and `.github/workflows/release.yml`). `CHANGELOG.md` appears in the
134
+ repository after the first tagged release.
135
+
136
+ ## Contributing
137
+
138
+ Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.
139
+
140
+ ## Security
141
+
142
+ Please review [SECURITY.md](SECURITY.md) for how to report a vulnerability.
143
+
144
+ ## Credits
145
+
146
+ - [Kidiatoliny](https://github.com/kidiatoliny)
147
+ - [All Contributors](https://github.com/akira-io/ui/graphs/contributors)
148
+
149
+ ## License
150
+
151
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,186 @@
1
+ import { D as DateFilterValue, a as DateFilterLabels, b as DateFilterOption, c as DateFilterUnit } from './types-cOieac8G.js';
2
+ export { C as CommandPalette, d as CommandPaletteGroup, e as CommandPaletteItem, f as CommandPaletteProps, g as DATE_FILTER_LABELS, h as DATE_FILTER_OPERATORS, i as DATE_FILTER_PRESETS, j as DATE_FILTER_UNITS, k as DateFilterMode, l as DateFilterOperator, u as useCommandPalette } from './types-cOieac8G.js';
3
+ import * as React from 'react';
4
+ import { ReactNode, PropsWithChildren, ReactElement } from 'react';
5
+ import { LucideIcon } from 'lucide-react';
6
+ import { S as SurfaceProps } from './language-Bft6rBBt.js';
7
+ import { T as TourStep, a as TourDefinition, b as TourBreakpoint, c as TourProgress, d as TourLabels } from './types-u1qfmJQi.js';
8
+ export { D as DEFAULT_TOUR_LABELS, e as TourOutcome } from './types-u1qfmJQi.js';
9
+
10
+ type DateFilterPanel = 'root' | 'fixed' | 'relative';
11
+ interface DateFilterContextValue {
12
+ value: DateFilterValue;
13
+ draft: DateFilterValue;
14
+ labels: DateFilterLabels;
15
+ presets: DateFilterOption[];
16
+ operators: DateFilterOption[];
17
+ units: DateFilterOption[];
18
+ panel: DateFilterPanel;
19
+ setDraft: (value: DateFilterValue) => void;
20
+ openPanel: (panel: DateFilterPanel, seed: DateFilterValue) => void;
21
+ backToRoot: () => void;
22
+ commit: (value: DateFilterValue) => void;
23
+ }
24
+ declare function useDateFilter(): DateFilterContextValue;
25
+
26
+ interface DateFilterProps {
27
+ value: DateFilterValue;
28
+ onChange: (value: DateFilterValue) => void;
29
+ presets?: DateFilterOption[];
30
+ operators?: DateFilterOption[];
31
+ units?: DateFilterOption[];
32
+ labels?: Partial<DateFilterLabels>;
33
+ children?: ReactNode;
34
+ }
35
+ declare function DateFilter({ value, onChange, presets, operators, units, labels, children, }: DateFilterProps): React.JSX.Element;
36
+ declare function DateFilterTrigger({ className, children, }: {
37
+ className?: string;
38
+ children?: ReactNode;
39
+ }): React.JSX.Element;
40
+ declare function DateFilterContent({ children, className, }: {
41
+ children: ReactNode;
42
+ className?: string;
43
+ }): React.JSX.Element;
44
+ declare function DateFilterItem({ active, onSelect, children, }: {
45
+ active: boolean;
46
+ onSelect: () => void;
47
+ children: ReactNode;
48
+ }): React.JSX.Element;
49
+ declare function DateFilterSeparator(): React.JSX.Element;
50
+ declare function DateFilterAll({ children }: {
51
+ children?: ReactNode;
52
+ }): React.JSX.Element;
53
+ declare function DateFilterPresets({ only }: {
54
+ only?: string[];
55
+ }): React.JSX.Element;
56
+ declare function DateFilterFixed({ children }: {
57
+ children?: ReactNode;
58
+ }): React.JSX.Element;
59
+ declare function DateFilterRelative({ children }: {
60
+ children?: ReactNode;
61
+ }): React.JSX.Element;
62
+
63
+ declare function encodeDateFilter(filter: DateFilterValue): string | null;
64
+
65
+ declare function resolveRelativeRange(unit: DateFilterUnit, amount: number, includeCurrent: boolean, now?: Date, offsetAmount?: number, offsetUnit?: DateFilterUnit): {
66
+ start: Date;
67
+ end: Date;
68
+ } | null;
69
+ declare function formatRangePreview(range: {
70
+ start: Date;
71
+ end: Date;
72
+ }): string;
73
+
74
+ declare function summariseDateFilter(value: DateFilterValue, presets: DateFilterOption[], operators: DateFilterOption[], units: DateFilterOption[], labels: DateFilterLabels): string;
75
+
76
+ interface InfoFieldProps {
77
+ icon: LucideIcon;
78
+ label: string;
79
+ value: ReactNode;
80
+ iconClassName?: string;
81
+ className?: string;
82
+ }
83
+ declare function InfoField({ icon: Icon, label, value, iconClassName, className, }: InfoFieldProps): React.JSX.Element;
84
+ interface InfoFieldGroupProps {
85
+ children: ReactNode;
86
+ className?: string;
87
+ }
88
+ declare function InfoFieldGroup({ children, className }: InfoFieldGroupProps): React.JSX.Element;
89
+
90
+ interface LocalizedField {
91
+ name: string;
92
+ label: string;
93
+ type?: 'text' | 'textarea';
94
+ rows?: number;
95
+ }
96
+ interface LocalizedFieldsProps {
97
+ locales: string[];
98
+ localeLabels?: Record<string, string>;
99
+ fields: LocalizedField[];
100
+ values: Record<string, Record<string, string>>;
101
+ onChange: (field: string, locale: string, value: string) => void;
102
+ errors?: Record<string, string>;
103
+ defaultLocale?: string;
104
+ className?: string;
105
+ }
106
+ declare function LocalizedFields({ locales, localeLabels, fields, values, onChange, errors, defaultLocale, className, }: LocalizedFieldsProps): React.JSX.Element;
107
+
108
+ interface SectionHeaderProps {
109
+ icon?: ReactNode;
110
+ title: string;
111
+ description?: string;
112
+ control?: ReactNode;
113
+ className?: string;
114
+ }
115
+ declare function SectionHeader({ icon, title, description, control, className, }: SectionHeaderProps): React.JSX.Element;
116
+
117
+ interface SettingsCardProps extends SurfaceProps {
118
+ icon: LucideIcon;
119
+ iconClassName?: string;
120
+ title: string;
121
+ description: string;
122
+ control?: ReactNode;
123
+ children: ReactNode;
124
+ className?: string;
125
+ }
126
+ declare function SettingsCard({ icon: Icon, iconClassName, title, description, control, children, inset, className, }: SettingsCardProps): React.JSX.Element;
127
+ interface SettingsPanelProps extends SurfaceProps {
128
+ title?: string;
129
+ description?: string;
130
+ children: ReactNode;
131
+ className?: string;
132
+ }
133
+ declare function SettingsPanel({ title, description, children, inset, className, }: SettingsPanelProps): React.JSX.Element;
134
+ interface ToggleRowProps {
135
+ id: string;
136
+ label: string;
137
+ description?: string;
138
+ checked: boolean;
139
+ onChange: (checked: boolean) => void;
140
+ disabled?: boolean;
141
+ }
142
+ declare function ToggleRow({ id, label, description, checked, onChange, disabled, }: ToggleRowProps): React.JSX.Element;
143
+
144
+ interface StatCardProps extends SurfaceProps {
145
+ title: string;
146
+ value: ReactNode;
147
+ icon: LucideIcon;
148
+ iconClassName?: string;
149
+ trend?: number;
150
+ comparisonLabel?: string;
151
+ className?: string;
152
+ }
153
+ declare function StatCard({ title, value, icon: Icon, iconClassName, trend, comparisonLabel, inset, className, }: StatCardProps): React.JSX.Element;
154
+ interface StatsGridProps {
155
+ children: ReactNode;
156
+ className?: string;
157
+ }
158
+ declare function StatsGrid({ children, className }: StatsGridProps): React.JSX.Element;
159
+
160
+ declare function stepsForBreakpoint(steps: TourStep[], breakpoint: TourBreakpoint): TourStep[];
161
+ declare function resolveSteps(steps: TourStep[], isPresent: (target: string) => boolean): TourStep[];
162
+ declare function shouldStartTour(input: {
163
+ definition: TourDefinition;
164
+ seen: Record<string, number>;
165
+ resolvedStepCount: number;
166
+ force?: boolean;
167
+ }): boolean;
168
+
169
+ interface TourControllerValue {
170
+ startTour: (definition: TourDefinition, options?: {
171
+ force?: boolean;
172
+ }) => void;
173
+ }
174
+ declare function TourProvider({ children, seen, onProgress, labels, }: PropsWithChildren<{
175
+ seen: Record<string, number>;
176
+ onProgress: (progress: TourProgress) => void;
177
+ labels?: Partial<TourLabels>;
178
+ }>): ReactElement;
179
+ declare function useTourController(): TourControllerValue;
180
+ declare function useTour(definition: TourDefinition, options?: {
181
+ enabled?: boolean;
182
+ }): {
183
+ restart: () => void;
184
+ };
185
+
186
+ export { DateFilter, DateFilterAll, DateFilterContent, type DateFilterContextValue, DateFilterFixed, DateFilterItem, DateFilterLabels, DateFilterOption, type DateFilterPanel, DateFilterPresets, type DateFilterProps, DateFilterRelative, DateFilterSeparator, DateFilterTrigger, DateFilterUnit, DateFilterValue, InfoField, InfoFieldGroup, type InfoFieldGroupProps, type InfoFieldProps, type LocalizedField, LocalizedFields, type LocalizedFieldsProps, SectionHeader, type SectionHeaderProps, SettingsCard, type SettingsCardProps, SettingsPanel, type SettingsPanelProps, StatCard, type StatCardProps, StatsGrid, type StatsGridProps, ToggleRow, type ToggleRowProps, TourBreakpoint, TourDefinition, TourLabels, TourProgress, TourProvider, TourStep, encodeDateFilter, formatRangePreview, resolveRelativeRange, resolveSteps, shouldStartTour, stepsForBreakpoint, summariseDateFilter, useDateFilter, useTour, useTourController };