bambuddy/frontend
maziggy 82d6d98266 Restore the pointer cursor on interactive controls (#2791)
Hovering most of Bambuddy gave an arrow rather than a hand. Not everywhere,
which is what made it read as sloppiness rather than a bug: the update pill was
inert while the buttons beside it were fine, a bed or nozzle tile responded but
the history-graph button in its corner did not, and dropdowns went either way
with no pattern behind it.

The pattern was there. Tailwind v3's Preflight set `button { cursor: pointer }`.
v4 dropped it to match the browser default, which for a button is `default`.
Bambuddy has been on v4 since the frontend was built, and `src/index.css` never
had a base layer restoring it, so a button only looked clickable where someone
had written `cursor-pointer` by hand. 15 of 934 had. 0 of 149 selects, and 19
of 130 checkbox/radio inputs. The 233 ad-hoc `cursor-pointer` usages are why it
looked arbitrary instead of uniformly broken.

One `@layer base` rule now covers button, select, checkbox, radio, summary and
[role=button]. base sits below utilities, so `cursor-not-allowed` and the
`disabled:cursor-*` variants still win; the `:not(:disabled)` guard catches the
disabled controls that carry no such utility. Verified against the built bundle
rather than the source -- the rule lands inside @layer base, and
`.cursor-not-allowed` is emitted after it.

Click-outside backdrops are deliberately excluded. 90 of the 96 remaining
onClick divs are `fixed inset-0` overlays; a full-screen sheet advertising
itself as a button is worse than one that says nothing. Of the rest, 50 are
stopPropagation wrappers and 3 are the temperature tiles, which already set the
cursor through `statusControlClass` -- which is exactly why those tiles worked
while the button nested inside them did not. That left two real ones: Card, now
conditional on an onClick actually being passed, and the queue card, whose
existing `sm:cursor-default` kept the desktop intent.

Separately, from the same report. FilamentHoverCard draws the slot menu twice,
and the two paths had drifted into opposite orders: Configure above Assign Spool
on an empty slot, the reverse on a filled one, so the menu reshuffled itself
depending on whether the slot held filament. Both now lead with the spool
action. Tests assert the order on each path, so one can no longer move without
the other -- checked by reinstating the old order and confirming the empty-slot
test fails.

Those buttons also used justify-center, which centred each label independently
and left the icons in a ragged column; they are justify-start now. Their hover
was a 10% opacity step that was very hard to see, now 20%. And the favourites
star previews yellow on hover, suppressed when the user lacks archives:update.
2026-08-08 10:06:45 +02:00
..
docs [Fix] Virtual Printer FTP routed to wrong VP with different access codes (#735) 2026-03-18 09:04:31 +01:00
mockups - Refactored printer card's AMS section for better experience 2026-01-01 12:08:55 +01:00
public fix(a2l): transparent printer-card image + getPrinterImage resolver 2026-06-10 11:09:02 +02:00
scripts fix(i18n): bring the Ukrainian locale up to parity and drop two English strings 2026-07-28 15:27:04 +02:00
src Restore the pointer cursor on interactive controls (#2791) 2026-08-08 10:06:45 +02:00
.gitignore Added screenshots 2025-11-28 10:23:59 +01:00
.npmrc Fix npm audit high-severity minimatch ReDoS (GHSA-3ppc-4f35-3m26) 2026-02-19 08:23:53 +01:00
eslint.config.js Improved frontend tests 2026-01-30 13:02:57 +01:00
index.html fix: unbreak CSP for sidebar iframes, service worker, and Google Fonts 2026-04-13 16:38:17 +02:00
package-lock.json brace-expansion override ^5.0.8 -> ^5.0.9 (GHSA-rgw5-rvv9-x895, DoS). 2026-08-05 07:48:23 +02:00
package.json brace-expansion override ^5.0.8 -> ^5.0.9 (GHSA-rgw5-rvv9-x895, DoS). 2026-08-05 07:48:23 +02:00
postcss.config.js Added screenshots 2025-11-28 10:23:59 +01:00
README.md Added screenshots 2025-11-28 10:23:59 +01:00
tailwind.config.js Add SpoolBuddy tag detection modal and fix NFC reader silent failure 2026-02-28 08:54:39 +01:00
tsconfig.app.json Fix docker build 2025-12-12 16:48:12 +01:00
tsconfig.json Added screenshots 2025-11-28 10:23:59 +01:00
tsconfig.node.json Added screenshots 2025-11-28 10:23:59 +01:00
vite.config.ts fix(frontend): revert base: '' so deep SPA routes load their assets on initial navigation (issue #1221) 2026-05-08 08:39:00 +02:00
vitest.config.ts feat: Centralise sidebar ordering and add page visibility options (#1673) 2026-06-17 12:04:57 +02:00

React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.

Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      // Other configs...

      // Remove tseslint.configs.recommended and replace with this
      tseslint.configs.recommendedTypeChecked,
      // Alternatively, use this for stricter rules
      tseslint.configs.strictTypeChecked,
      // Optionally, add this for stylistic rules
      tseslint.configs.stylisticTypeChecked,

      // Other configs...
    ],
    languageOptions: {
      parserOptions: {
        project: ['./tsconfig.node.json', './tsconfig.app.json'],
        tsconfigRootDir: import.meta.dirname,
      },
      // other options...
    },
  },
])

You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:

// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      // Other configs...
      // Enable lint rules for React
      reactX.configs['recommended-typescript'],
      // Enable lint rules for React DOM
      reactDom.configs.recommended,
    ],
    languageOptions: {
      parserOptions: {
        project: ['./tsconfig.node.json', './tsconfig.app.json'],
        tsconfigRootDir: import.meta.dirname,
      },
      // other options...
    },
  },
])