diff --git a/.changeset/class-names-and-rest-props.md b/.changeset/class-names-and-rest-props.md new file mode 100644 index 000000000..57dcbd72b --- /dev/null +++ b/.changeset/class-names-and-rest-props.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +More components accept rest props and `ref` on their root and a `classNames` slot map, and `BackToTop`, `ConditionalLink` and `LinkButton` gain `asChild`. diff --git a/.changeset/config.json b/.changeset/config.json index fcfcf83e0..a1571f742 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -2,7 +2,7 @@ "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", "changelog": "@changesets/cli/changelog", "commit": false, - "fixed": [], + "fixed": [["@javaabu/onu", "@javaabu/onu-mcp"]], "linked": [], "access": "public", "baseBranch": "main", diff --git a/.changeset/docs-pass.md b/.changeset/docs-pass.md new file mode 100644 index 000000000..e291d478c --- /dev/null +++ b/.changeset/docs-pass.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +Docs: an installation page with requirements and per-entry peer dependencies, complete Props tables, and corrected stale text. diff --git a/.changeset/drop-unused-peers.md b/.changeset/drop-unused-peers.md new file mode 100644 index 000000000..dd1573a71 --- /dev/null +++ b/.changeset/drop-unused-peers.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +Removed four optional peers nothing imports: `@tiptap/extension-link`, `@tiptap/extension-drag-handle-react`, `@tiptap/extension-code-block-lowlight` and `lowlight`. diff --git a/.changeset/editor-dialog-thaana.md b/.changeset/editor-dialog-thaana.md new file mode 100644 index 000000000..ad73e8ced --- /dev/null +++ b/.changeset/editor-dialog-thaana.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +The editors' image alt text field now follows the editor's `thaana` prop. diff --git a/.changeset/hard-coded-english.md b/.changeset/hard-coded-english.md new file mode 100644 index 000000000..480b2e7e9 --- /dev/null +++ b/.changeset/hard-coded-english.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +`DialogFooter`'s close button, the `useConfirm` `window.confirm` fallback and a `ValidationError` without a message no longer show hard-coded English. diff --git a/.changeset/labels-with-placeholders.md b/.changeset/labels-with-placeholders.md new file mode 100644 index 000000000..0336060d2 --- /dev/null +++ b/.changeset/labels-with-placeholders.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +The move, switch account and inline edit labels are now whole translated sentences with a placeholder, instead of two strings joined together. diff --git a/.changeset/locale-cleanup.md b/.changeset/locale-cleanup.md new file mode 100644 index 000000000..c6ae32dee --- /dev/null +++ b/.changeset/locale-cleanup.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +Remove unused locale keys, give Dhivehi separate words for clear and delete, and announce applied filters and cleared selections to screen readers. diff --git a/.changeset/logical-sides.md b/.changeset/logical-sides.md new file mode 100644 index 000000000..99e2cb192 --- /dev/null +++ b/.changeset/logical-sides.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +`Tip`, `PopoverPanel` and `ActionMenu` take `side="top" | "bottom" | "start" | "end"`; `left` and `right` are gone. diff --git a/.changeset/navigation-menu-rtl-motion.md b/.changeset/navigation-menu-rtl-motion.md new file mode 100644 index 000000000..6d939d4ff --- /dev/null +++ b/.changeset/navigation-menu-rtl-motion.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +`NavigationMenu` content slides in from the logical side, so its motion follows the reading direction in RTL. diff --git a/.changeset/on-value-change.md b/.changeset/on-value-change.md new file mode 100644 index 000000000..17199ff29 --- /dev/null +++ b/.changeset/on-value-change.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +Every component that reports a value now uses `onValueChange(value)`; `onChange` only ever means the native event. `FileInput` loses `onChange(files)` (use `onValueChange(entries)`), and `onReject` always takes an array. diff --git a/.changeset/overlay-token.md b/.changeset/overlay-token.md new file mode 100644 index 000000000..1b5632ffd --- /dev/null +++ b/.changeset/overlay-token.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +New `--onu-overlay` token for the dim behind dialogs, sheets and drawers (`bg-overlay`). The app shell classes use the shell token utilities instead of hex fallbacks. diff --git a/.changeset/peer-form-and-query.md b/.changeset/peer-form-and-query.md new file mode 100644 index 000000000..e44f976d4 --- /dev/null +++ b/.changeset/peer-form-and-query.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +`react-hook-form` and `@tanstack/react-query` are now peer dependencies. `getOnuQueryClient` is gone: the fallback client belongs to each `OnuProvider`, and `invalidateApiOptions` takes the client first. diff --git a/.changeset/primitive-a11y-fixes.md b/.changeset/primitive-a11y-fixes.md new file mode 100644 index 000000000..791107a87 --- /dev/null +++ b/.changeset/primitive-a11y-fixes.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +Fix axe violations in three primitives: `Calendar` week numbers, the `role="list"` on `ItemGroup`, and `CommandSeparator` inside its listbox. diff --git a/.changeset/prop-names.md b/.changeset/prop-names.md new file mode 100644 index 000000000..42688c560 --- /dev/null +++ b/.changeset/prop-names.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +The accessible name of a root region is `label` everywhere (`CommandPalette` and `OverlayMenu` `title`, `TopNav` `navLabel`, `Tabs` `listLabel`), and the minimum query length is `minChars` everywhere (`CommandPalette` `minQueryLength`, `PlaceSearchBox` `minLength`). diff --git a/.changeset/react-19-only.md b/.changeset/react-19-only.md new file mode 100644 index 000000000..26b0686b2 --- /dev/null +++ b/.changeset/react-19-only.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +Onu now requires React 19; React 18 is no longer in the peer range. diff --git a/.changeset/remove-base-ui-combobox.md b/.changeset/remove-base-ui-combobox.md new file mode 100644 index 000000000..d3b40b2b4 --- /dev/null +++ b/.changeset/remove-base-ui-combobox.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +Removed the unused `Combobox` primitive from `@javaabu/onu/primitives`, and with it the `@base-ui/react` dependency. diff --git a/.changeset/segmented-control-name.md b/.changeset/segmented-control-name.md new file mode 100644 index 000000000..a532f8f07 --- /dev/null +++ b/.changeset/segmented-control-name.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +`SegmentedControl`'s `name` prop is now part of its type. diff --git a/.changeset/shared-helpers.md b/.changeset/shared-helpers.md new file mode 100644 index 000000000..d08ab1692 --- /dev/null +++ b/.changeset/shared-helpers.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +Shared helpers move to `src/lib` and `src/hooks` with one behaviour each: `toArray` and the `initials` media export are gone, `normalizeUrl` returns `string | null`, the editor's `Callout` node is now `CalloutNode`, `CommandPalette` debounces by 300 ms, and the auth forms use `PasswordInput`. diff --git a/.changeset/size-scale.md b/.changeset/size-scale.md new file mode 100644 index 000000000..9d27c88d0 --- /dev/null +++ b/.changeset/size-scale.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +`Tag`, `SkeletonText`, `Modal` and `UserAvatar` rename size `md` to `default`. `NumberInput` is now `h-8` like every other field, and `TextInput` gains the same `size` prop. diff --git a/.changeset/stable-first-render.md b/.changeset/stable-first-render.md new file mode 100644 index 000000000..8e67d99dd --- /dev/null +++ b/.changeset/stable-first-render.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +`Countdown`, `RelativeDate`, `Timeline`, `PublishBox` and `SidebarMenuSkeleton` render the same markup on the server and the client's first render. `SidebarMenuSkeleton` takes an `index` to vary its width. diff --git a/.changeset/stable-labels.md b/.changeset/stable-labels.md new file mode 100644 index 000000000..049985d91 --- /dev/null +++ b/.changeset/stable-labels.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +The vertical `Carousel` arrows point the right way in RTL, and `KanbanBoard`'s column count is real screen reader text instead of an `aria-label` on a `span`. diff --git a/.changeset/thaana-fonts-always.md b/.changeset/thaana-fonts-always.md new file mode 100644 index 000000000..134cc89d2 --- /dev/null +++ b/.changeset/thaana-fonts-always.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +Faruma and MV Faseyha now load from `tailwind.css` and `styles.css`, so Thaana text works without the optional font pack. diff --git a/.changeset/toast-close-size.md b/.changeset/toast-close-size.md new file mode 100644 index 000000000..bc24348b3 --- /dev/null +++ b/.changeset/toast-close-size.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": patch +--- + +The toast close button is now 24 px, and 44 px on touch screens. diff --git a/.changeset/tone-scale.md b/.changeset/tone-scale.md new file mode 100644 index 000000000..850f8d3bd --- /dev/null +++ b/.changeset/tone-scale.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +One severity scale, `tone`: `neutral`, `info`, `success`, `warning`, `danger`. `Callout`, `AnnouncementBar` and `NotificationCenter` items rename `variant` to `tone`, `destructive` and `error` become `danger`, and `default` becomes `neutral` (also on `IconText`). `AnnouncementBar` gains `success` and `danger`. `Button` keeps `variant="destructive"`. diff --git a/.changeset/uncontrolled-partners.md b/.changeset/uncontrolled-partners.md new file mode 100644 index 000000000..662178bc3 --- /dev/null +++ b/.changeset/uncontrolled-partners.md @@ -0,0 +1,5 @@ +--- +"@javaabu/onu": minor +--- + +`LanguageSwitcher` and `RepeatingGroup` gain `defaultValue`, `Callout`, `FilterPanel` and `Lightbox` gain `defaultOpen`, and `Lightbox` `open` and `onOpenChange` become optional with `index` controlled only when it is passed. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index edbe35091..656e38966 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,8 @@ jobs: fail_ci_if_error: false - name: MCP server tests run: pnpm --filter @javaabu/onu-mcp test + - name: Figma plugin tests + run: pnpm figma:test - name: Build packages run: pnpm build - name: Size budgets diff --git a/.github/workflows/e2e-smoke.yml b/.github/workflows/e2e-smoke.yml new file mode 100644 index 000000000..3bd75ea3d --- /dev/null +++ b/.github/workflows/e2e-smoke.yml @@ -0,0 +1,40 @@ +name: E2E smoke + +# The quick E2E tier: on a pull request that touches the library, the web app or the E2E +# tests, run the accessibility scans and the Thaana keyboard check in Chromium. No visual +# diff and no baseline download: the full five-browser and visual run stays in e2e.yml. +on: + pull_request: + paths: + - "packages/onu/**" + - "web/**" + - "e2e/**" + +concurrency: + group: e2e-smoke-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + smoke: + name: Playwright smoke (chromium) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v5 + with: + node-version: 22 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm exec playwright install --with-deps chromium + - run: pnpm build:web + - run: pnpm e2e:chromium e2e/a11y.spec.ts e2e/thaana.spec.ts + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: playwright-report-smoke + path: playwright-report + retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 202f2020e..5041de7ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,6 +41,7 @@ jobs: exit 1 fi done + node scripts/sync-plugin-version.mjs --check - name: Check the npm token run: | if [ -z "$NPM_TOKEN" ]; then diff --git a/AGENTS.md b/AGENTS.md index 6954cb21d..3853b76f5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,7 +33,7 @@ pnpm e2e:chromium # Playwright (a11y with axe, visual) ## Rules -- A component is done only with: light/dark, LTR/RTL, `dv` strings, `thaana` on free-text fields, tokens-only colours, `className`/`classNames`/`asChild`, axe-clean, unit tests, a demo, a docs page and a changeset (`.changeset/*.md`). +- A component is done only with: light/dark, LTR/RTL, `dv` strings, `thaana` on free-text fields, tokens-only colours, `className`/`classNames`, `asChild` where the component renders one element an app may need to replace (links, buttons, triggers), axe-clean, unit tests, a demo, a docs page and a changeset (`.changeset/*.md`). - Logical Tailwind utilities only (`ms-`, `pe-`, `start-`, `text-start`); ESLint rejects `left`/`right` ones. Theme tokens only, never raw colours. - Icons through `` with semantic names; never render Lucide components or import `src/icons/lucide-map` in a component. - No hard-coded English: strings live in `src/locales/{en,dv}/.ts`, and a module registers the English namespaces it uses with `registerEnglish(...)`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f6c04d146..cde4a3763 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,7 @@ Maps in the web app use Google Maps when `VITE_GOOGLE_MAPS_API_KEY` (and optiona ## Definition of done -A component is done only when it meets REQUIREMENTS §21: light/dark, LTR/RTL, `dv` locale, `thaana` prop for free text, tokens-only colours, responsive and touch-friendly, `className`/`classNames`/`asChild` overrides, WCAG 2.2 AA with axe tests, unit tests, a showcase demo in `web/src/showcase`, a docs page in `docs/`, and a changeset. +A component is done only when it meets REQUIREMENTS §21: light/dark, LTR/RTL, `dv` locale, `thaana` prop for free text, tokens-only colours, responsive and touch-friendly, `className`/`classNames` overrides, `asChild` where the component renders one element an app may need to replace (links, buttons, triggers), WCAG 2.2 AA with axe tests, unit tests, a showcase demo in `web/src/showcase`, a docs page in `docs/`, and a changeset. ## Where things go @@ -33,6 +33,7 @@ A component is done only when it meets REQUIREMENTS §21: light/dark, LTR/RTL, ` ## Rules of thumb - Use logical Tailwind utilities (`ms-`, `pe-`, `start-`, `text-start`, …). ESLint rejects physical `left`/`right` ones. +- Report a value with `onValueChange(value)`; `onChange` is only for the native event. - Use theme tokens (`bg-primary`, `text-muted-foreground`), never raw colours. - Use `` (from `src/icons/icon`) with semantic names, so `OnuProvider icons` overrides apply. Never render a Lucide component directly. When a component always shows the same glyph (a spinner, a close button, a chevron), also pass that Lucide icon as `fallback`, e.g. ``: overrides still win, and the component keeps its glyph outside `OnuProvider`. - Never import `src/icons/lucide-map` in a component. `OnuProvider` loads the default set on demand, so neither a single component nor the provider ships ~250 icons. ESLint and `src/icons/icon-imports.test.ts` enforce this, and `pnpm --filter @javaabu/onu size` checks the bundle budgets. @@ -52,7 +53,12 @@ The files in `packages/onu/src/ui` started as shadcn/ui's components (Radix base ## Checks -E2E (Playwright: accessibility in five browsers, and Chromium screenshots) is slow, so CI runs it only when the last commit pushed to `main` starts with `e2e` (for example `e2e: new date picker`), or when you run the **E2E** workflow by hand from the Actions tab. Run it locally with `pnpm e2e:chromium`. +E2E (Playwright) runs in two tiers: + +- **Smoke, on pull requests.** The **E2E smoke** workflow runs `e2e/a11y.spec.ts` and `e2e/thaana.spec.ts` in Chromium, with no screenshots, when a pull request touches `packages/onu/**`, `web/**` or `e2e/**`. +- **Full, on demand.** The **E2E** workflow (accessibility in five browsers, and Chromium screenshots) is slow, so CI runs it only when the last commit pushed to `main` starts with `e2e` (for example `e2e: new date picker`), or when you run it by hand from the Actions tab. + +Run either locally with `pnpm e2e:chromium`, adding the two spec files for the smoke tier. The Chromium job compares a desktop screenshot of every component demo, in light LTR and dark RTL, with baselines stored as the `visual-baselines` Actions artifact (not in git). After an intended visual change, or when you add a component, run **E2E** by hand with **Update the visual baselines** ticked. Look at the screenshots in that run's `visual-baselines` artifact before relying on them. Baselines are kept for 90 days (about 90 MB). If none are stored (the first run, or 90 days after the last update), the run takes new ones instead of comparing. @@ -85,10 +91,10 @@ Every change that affects a published package adds a changeset (`pnpm changeset` To release: -1. On `dev`, run `pnpm changeset version`. It bumps every package with pending changesets, writes their `CHANGELOG.md` and deletes the changesets. All packages share one version, so check that `packages/onu` and `packages/onu-mcp` match. +1. On `dev`, run `pnpm changeset version && node scripts/sync-plugin-version.mjs`. `@javaabu/onu` and `@javaabu/onu-mcp` are a fixed group in `.changeset/config.json`, so they always move to the same version; the script copies that version into `plugins/onu/.claude-plugin/plugin.json`, which changesets can't see. `changeset version` also writes their `CHANGELOG.md` and deletes the changesets. 2. Commit (`Release v0.1.0`) and merge `dev` into `main`. Wait for CI to pass on `main`. 3. Tag that commit on `main` and push the tag: `git tag v0.1.0 && git push origin v0.1.0`. -The **Release** workflow runs only for `v*` tags. It checks that the tagged commit is on `main` and that every package's version matches the tag, then builds and publishes to npm (versions already on npm are skipped). Tags with a pre-release suffix (`v1.0.0-beta.1`) publish under the `next` dist-tag. +The **Release** workflow runs only for `v*` tags. It checks that the tagged commit is on `main` and that every package's version and the plugin's match the tag, then builds and publishes to npm (versions already on npm are skipped). Tags with a pre-release suffix (`v1.0.0-beta.1`) publish under the `next` dist-tag. Publishing needs an `NPM_TOKEN` repository secret: an npm granular access token with read and write access to the `@javaabu` scope and "bypass 2FA" allowed, from an account that can publish to `@javaabu`. Write tokens expire after about 90 days. Provenance is signed only once the repository is public. After the first release, you can switch to npm trusted publishing (each package's settings on npmjs.com, pointing at `release.yml`) and remove the token. diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 5a2362888..739888933 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -9,7 +9,6 @@ Selection order: shadcn/ui component → reputable library (shadcn ecosystem fir | Package | Purpose | Licence | Notes | | -------------------------------------------------- | -------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------ | | `radix-ui` | Accessible primitives behind the shadcn components | MIT | shadcn default base | -| `@base-ui/react` | Combobox primitive (shadcn's combobox) | MIT | From the Radix / MUI team | | `class-variance-authority` | Variants (`buttonVariants`, …) | Apache-2.0 | Stable and feature-complete; last release 2024 (exception to the 12-month rule, used by shadcn) | | `clsx`, `tailwind-merge` | `cn()` class merging so consumer classes win | MIT | | | `tw-animate-css` | Enter/exit animations | MIT | shadcn default | @@ -19,32 +18,36 @@ Selection order: shadcn/ui component → reputable library (shadcn ecosystem fir | `vaul` | Drawer / bottom sheet | MIT | shadcn `drawer`. **Watch-list**: reduced maintenance (R4.3); kept behind Onu's API | | `input-otp` | OTP input | MIT | shadcn `input-otp` | | `react-day-picker`, `date-fns` | Calendar and date maths | MIT | shadcn `calendar`; Dhivehi locale maintained in Onu | -| `@internationalized/date` | Hijri (Umm al-Qura) calendar maths, date/time fields | Apache-2.0 | Adobe | -| `react-aria-components` | Tree, colour picker, date/time segment fields | Apache-2.0 | Adobe; fills Radix gaps (§4 step 3) | +| `@internationalized/date` | Hijri (Umm al-Qura) calendar maths, date/time segment fields | Apache-2.0 | Adobe | +| `react-aria-components` | Tree, colour picker | Apache-2.0 | Adobe; fills Radix gaps (§4 step 3) | | `embla-carousel-react` | Carousel | MIT | shadcn `carousel` | -| `react-hook-form` | Form state | MIT | | | `@tanstack/react-table`, `@tanstack/react-virtual` | Tables, data grid, virtualised lists | MIT | | -| `@tanstack/react-query` | API select caching and de-duplication | MIT | R16.5 | | `@dnd-kit/react`, `@dnd-kit/helpers` | Drag and drop (kanban, sortable lists, row reordering) with touch sensors | MIT | The maintained successor of `@dnd-kit/core` | | `@dnd-kit/dom` | dnd-kit's `Accessibility` plugin, configured with translated announcements | MIT | Already installed by `@dnd-kit/react`; imported directly so drag announcements follow the locale | | `react-phone-number-input` | Phone input (libphonenumber) | MIT | Default region MV | | `@sindresorhus/slugify` | Slug generator | MIT | | | `uqr` | QR code encoding for `QrCode` (media entry); Onu renders the SVG | MIT | unjs; zero-dep, typed. Picked over `qrcode` (Node deps), `qrcode-generator` (stale) | +## Peers (core) + +`react-hook-form` (form state, MIT) and `@tanstack/react-query` (API select caching and de-duplication, R16.5, MIT) are required peers, alongside `react` and `react-dom`. Onu reads their React context, so the app and Onu must resolve the same copy. They stay required because the core entry imports them statically. + ## Optional peers (entry points) -| Entry | Packages | Licence | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | -| `@javaabu/onu/charts` | `recharts` | MIT | -| `@javaabu/onu/maps` | `@vis.gl/react-google-maps`, `terra-draw`, `terra-draw-google-maps-adapter`, `@googlemaps/markerclusterer`, `@deck.gl/core`, `@deck.gl/layers`, `@deck.gl/aggregation-layers`, `@deck.gl/google-maps`, `@turf/turf` | MIT / Apache-2.0 | -| `@javaabu/onu/editor` | `@tiptap/core`, `@tiptap/react`, `@tiptap/pm`, `@tiptap/starter-kit`, `@tiptap/static-renderer`, `@tiptap/suggestion` (slash menu), `@tiptap/extension-*` (MIT packages only), `lowlight`, `shiki` | MIT | -| `@javaabu/onu/calendar` | `@fullcalendar/core`, `@fullcalendar/react`, `@fullcalendar/daygrid`, `@fullcalendar/timegrid`, `@fullcalendar/list`, `@fullcalendar/interaction` (standard plugins only, v6) | MIT | -| `@javaabu/onu/media` | `react-easy-crop`, `signature_pad`, `barcode-detector`, `yet-another-react-lightbox`, `media-chrome` | MIT | -| `@javaabu/onu/export` | `write-excel-file` (Excel `.xlsx` only; CSV and PDF need nothing). Loaded with `import()` on the first Excel export. Chosen over the npm `xlsx` (SheetJS) package, whose npm release is outdated; supports right-to-left sheets and keeps Thaana text intact | MIT | -| `@javaabu/onu/icons/iconify` | `@iconify/react` + any `@iconify-json/*` collections | MIT (icon sets vary, mostly MIT/Apache/OFL) | -| `@javaabu/onu/icons/fontawesome` | `@fortawesome/fontawesome-svg-core`, `@fortawesome/react-fontawesome`, plus your Free or **Pro** icon packages | MIT (code); icons per FontAwesome licence. Pro is never bundled | -| `@javaabu/onu/fonts.css` | `@fontsource-variable/inter`, `@fontsource-variable/jetbrains-mono`, `@fontsource-variable/noto-sans-thaana` (fallback) | OFL-1.1 | -| `@javaabu/onu/fonts-optional.css` | `@fontsource-variable/geist`, `@fontsource-variable/source-serif-4` | OFL-1.1 | +The packages each entry needs are listed once, under [Peer dependencies per entry](docs/installation-and-setup.md#peer-dependencies-per-entry). This table keeps their licences and the choices behind them. + +| Entry | Licence | Notes | +| --------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `@javaabu/onu/charts` | MIT | | +| `@javaabu/onu/maps` | MIT / Apache-2.0 | | +| `@javaabu/onu/editor` | MIT | MIT-licensed Tiptap packages only | +| `@javaabu/onu/calendar` | MIT | FullCalendar v6, standard plugins only | +| `@javaabu/onu/media` | MIT | | +| `@javaabu/onu/export` | MIT | `write-excel-file`, chosen over the npm `xlsx` (SheetJS) package, whose npm release is outdated; supports right-to-left sheets and keeps Thaana text intact | +| `@javaabu/onu/icons/iconify` | MIT (icon sets vary, mostly MIT/Apache/OFL) | | +| `@javaabu/onu/icons/fontawesome` | MIT (code); icons per FontAwesome licence. Pro is never bundled | | +| `@javaabu/onu/fonts.css` | OFL-1.1 | | +| `@javaabu/onu/fonts-optional.css` | OFL-1.1 | | Faruma and MV Faseyha, the Thaana fonts, are bundled as subset `woff2` files in `src/styles/fonts/` (R7.3). They are free to use and redistribute. diff --git a/README.md b/README.md index 10a9fbe8a..fae963795 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ See [`REQUIREMENTS.md`](REQUIREMENTS.md) for the full specification and [`docs/` ## Install ```bash -npm install @javaabu/onu -# optional font pack (Inter, JetBrains Mono, Noto Sans Thaana; Faruma and MV Faseyha are bundled) +npm install @javaabu/onu react-hook-form @tanstack/react-query +# optional font pack (Inter, JetBrains Mono, Noto Sans Thaana; Faruma and MV Faseyha come with tailwind.css and styles.css) npm install @fontsource-variable/inter @fontsource-variable/jetbrains-mono @fontsource-variable/noto-sans-thaana ``` diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index dee9bb8db..cf3bd45ac 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -86,7 +86,7 @@ This document captures the requirements, constraints and full build list for Onu - `@javaabu/onu/styles.css` — theme tokens + base styles - `@javaabu/onu/tailwind.css` — Tailwind `@theme` / `@source` entry for consumers - **R2.6** Heavy or licensed third-party dependencies (map SDKs, chart libs, editors, scanners, FontAwesome, fonts) are **optional peer dependencies**, required only when the matching subpath is imported. -- **R2.7** Peer dependencies: `react` and `react-dom` `^18.3 || ^19`, `tailwindcss` `^4`. +- **R2.7** Peer dependencies: `react` and `react-dom` `^19`, `tailwindcss` `^4`. - **R2.8** Ship TypeScript declarations; source written in TypeScript `strict` mode. No `any` in public APIs. - **R2.9** Every client component file carries a `"use client"` directive so it works in React Server Component environments (Next.js App Router). - **R2.10** Semantic versioning. Releases managed with [Changesets](https://github.com/changesets/changesets); `CHANGELOG.md` generated from them. @@ -181,7 +181,7 @@ A dependency must meet **all** of these criteria: - **Maintained**: a release or meaningful commit within the last 12 months, a responsive issue tracker, and not archived or deprecated. - **Reputable**: widely adopted, and backed by an organisation or established maintainers. - **Typed**: first-party TypeScript types. -- **Compatible**: React 18 and 19, SSR-safe, tree-shakable. +- **Compatible**: React 19, SSR-safe, tree-shakable. - **Accessible and RTL-capable**, or can be made so by wrapping. - **Reasonable bundle size** for what it provides. @@ -347,7 +347,7 @@ Javaabu currently uses the JTK (JavaScript Thaana Keyboard) approach for typing - `useThaanaInput(ref, options)` hook that can be attached to any ``, `