@madebywild/wvk 0.0.1 → 0.0.2

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
@@ -52,9 +52,7 @@ In your global stylesheet (after `@import "tailwindcss";`):
52
52
 
53
53
  This registers the `wvk-*` color, surface, foreground, border, transparency, primitive, radius, size, and cursor tokens, plus light/dark theme values (toggle by adding `class="dark"` to `<html>`).
54
54
 
55
- ### Cursor assets (optional)
56
-
57
- The cursor tokens reference `/cursors/arrow.svg`, `/cursors/pointer.svg`, and `/cursors/move.svg`. To use them, copy those three SVGs into your app's public root (e.g. `public/cursors/` for Next.js). They are not bundled with the package because a kit cannot ship into a consumer's static asset folder. If the files are missing the browser falls back to system cursors via the keyword fallbacks declared in the tokens.
55
+ Custom cursors are self-contained. The cursor tokens embed the SVG artwork as data URLs, so consumers do not need to copy files into `public/` or configure asset hosting. If a browser does not support SVG cursors, the tokens still end with system keyword fallbacks.
58
56
 
59
57
  ## Theme switching
60
58
 
@@ -73,6 +71,8 @@ export default function RootLayout({ children }) {
73
71
  }
74
72
  ```
75
73
 
74
+ `ThemeProvider` also installs a small cursor fallback stylesheet when the full package stylesheet is not present yet. For full component styling and design tokens, still import `@madebywild/wvk/styles.css` from your global stylesheet.
75
+
76
76
  ## Design-token philosophy
77
77
 
78
78
  Tokens are organized in three tiers:
package/dist/index.cjs CHANGED
@@ -7271,12 +7271,79 @@ ToggleSwitch.displayName = "ToggleSwitch";
7271
7271
  var React25 = __toESM(require("react"), 1);
7272
7272
  var import_jsx_runtime209 = require("react/jsx-runtime");
7273
7273
  var STORAGE_KEY = "wvk-theme";
7274
+ var CURSOR_STYLE_ID = "wvk-cursor-style";
7275
+ var CURSOR_DEFAULT = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDMyIDMyIj4KICA8ZGVmcz4KICAgIDxmaWx0ZXIKICAgICAgaWQ9Ind2ay1jdXJzb3Itc2hhZG93IgogICAgICBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgIHg9Ii00IgogICAgICB5PSItNCIKICAgICAgd2lkdGg9IjQwIgogICAgICBoZWlnaHQ9IjQwIgogICAgICBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiCiAgICA+CiAgICAgIDxmZURyb3BTaGFkb3cgZHg9IjAiIGR5PSIxLjI1IiBzdGREZXZpYXRpb249IjEiIGZsb29kLWNvbG9yPSIjMDAwMDAwIiBmbG9vZC1vcGFjaXR5PSIwLjM4IiAvPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgogIDxnIGZpbHRlcj0idXJsKCN3dmstY3Vyc29yLXNoYWRvdykiPgogICAgPHBhdGggZmlsbD0iIzAwNTVGRiIgZD0iTTEwIDYuMDI4djE0LjYzN2EuNS41IDAgMCAwIC44Ni4zNDhsMi40MjQtMi41MDNhLjUuNSAwIDAgMSAuODA4LjEyN2wyLjIyNSA0LjUyM2ExIDEgMCAwIDAgMS4zNzkuNDM1bDIuMjM0LTEuMjI5YTEgMSAwIDAgMCAuNDEtMS4zM2wtMi4xOTItNC4zMWEuNS41IDAgMCAxIC40NDYtLjcyNmgzLjk2YS41LjUgMCAwIDAgLjMxLS44OTNMMTAuODA4IDUuNjM1YS41LjUgMCAwIDAtLjgwOS4zOTNaIi8+CiAgICA8cGF0aCBzdHJva2U9IndoaXRlIiBzdHJva2Utb3BhY2l0eT0iLjgiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTkuNDIgNC45ODVhMS41MDIgMS41MDIgMCAwIDEgMS44ODItLjIyNWwuMTI1LjA4OUwyMy40OCAxNC4zMmExLjUwMSAxLjUwMSAwIDAgMS0uOTI2IDIuNjhoLTMuMTQ3bDEuODIzIDMuNTgzYTIgMiAwIDAgMS0uODE5IDIuNjZsLTIuMjM0IDEuMjI5YTIgMiAwIDAgMS0yLjc1OS0uODdsLTEuOTExLTMuODg2LTEuOTMgMS45OTNBMS41IDEuNSAwIDAgMSA5IDIwLjY2NVY2LjAyOGExLjUgMS41IDAgMCAxIC4zMi0uOTI2bC4xLS4xMTdaIi8+CiAgPC9nPgo8L3N2Zz4K") 9 5, default';
7276
+ var CURSOR_POINTER = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDMyIDMyIj4KICA8ZGVmcz4KICAgIDxmaWx0ZXIKICAgICAgaWQ9Ind2ay1jdXJzb3Itc2hhZG93IgogICAgICBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgIHg9Ii00IgogICAgICB5PSItNCIKICAgICAgd2lkdGg9IjQwIgogICAgICBoZWlnaHQ9IjQwIgogICAgICBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiCiAgICA+CiAgICAgIDxmZURyb3BTaGFkb3cgZHg9IjAiIGR5PSIxLjI1IiBzdGREZXZpYXRpb249IjEiIGZsb29kLWNvbG9yPSIjMDAwMDAwIiBmbG9vZC1vcGFjaXR5PSIwLjM4IiAvPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgogIDxnIGZpbHRlcj0idXJsKCN3dmstY3Vyc29yLXNoYWRvdykiPgogICAgPHBhdGggZmlsbD0id2hpdGUiIGQ9Ik0xOC41IDMwSDEzYy01LjQ0IDAtOS4wODMtNC45NjQtMTEuNDEtMTQuMjcyQy42NTkgMTIuMDAzIDMuOTE3IDguOTEzIDcgOS42NVY2YTUgNSAwIDAgMSAxMCAwdjIuMWE0Ljk5IDQuOTkgMCAwIDEgMi4xMDUuOThBNSA1IDAgMCAxIDI0LjAwMSAxMWE1IDUgMCAwIDEgNSA1djRjMCAuMTktLjAxOS4zOC0uMDU0LjU2NUMyOC40MDkgMjUuODk3IDIzLjkwNyAzMCAxOC41IDMwWiIvPgogICAgPHBhdGggZmlsbD0iIzAwNTVGRiIgZD0iTTI1IDE5LjVWMTZhMSAxIDAgMSAwLTIgMCAxIDEgMCAxIDEtMiAwdi0yYTEgMSAwIDEgMC0yIDAgMSAxIDAgMSAxLTIgMCAzIDMgMCAwIDEgNS44OTUtLjc5QTMgMyAwIDAgMSAyNyAxNnY0YTEgMSAwIDAgMS0uMDMzLjI1NkE4LjUgOC41IDAgMCAxIDE4LjUgMjhIMTNjLTQuMjg0IDAtNy4zNy00LjM1Ny05LjQ3LTEyLjc1OC0uNjk4LTIuNzkyIDIuMzIxLTQuODA1IDQuMTc3LTIuOTVMOSAxMy41ODdWNmEzIDMgMCAxIDEgNiAwdjdhMSAxIDAgMSAxLTIgMFY2YTEgMSAwIDEgMC0yIDB2MTBhMSAxIDAgMCAxLTEuNzA3LjcwN2wtMy0zYy0uMzQ0LS4zNDQtMS4wNTMuMTI5LS44MjMgMS4wNUM3LjM3IDIyLjM1OCA5Ljk1IDI2IDEzIDI2aDUuNWE2LjUgNi41IDAgMCAwIDYuNS02LjVaTTE2IDEwYTMgMyAwIDAgMSAzIDN2MWExIDEgMCAxIDEtMiAwdi0xYTEgMSAwIDEgMC0yIDAgMSAxIDAgMSAxLTIgMCAzIDMgMCAwIDEgMy0zWm0tMSA3YTEgMSAwIDAgMSAxIDF2M2ExIDEgMCAxIDEtMiAwdi0zYTEgMSAwIDAgMSAxLTFabTQgMGExIDEgMCAwIDEgMSAxdjNhMSAxIDAgMSAxLTIgMHYtM2ExIDEgMCAwIDEgMS0xWiIvPgogIDwvZz4KPC9zdmc+Cg==") 12 8, pointer';
7277
+ var CURSOR_MOVE = 'url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSIgdmlld0JveD0iMCAwIDMyIDMyIj4KICA8ZGVmcz4KICAgIDxmaWx0ZXIKICAgICAgaWQ9Ind2ay1jdXJzb3Itc2hhZG93IgogICAgICBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgIHg9Ii00IgogICAgICB5PSItNCIKICAgICAgd2lkdGg9IjQwIgogICAgICBoZWlnaHQ9IjQwIgogICAgICBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiCiAgICA+CiAgICAgIDxmZURyb3BTaGFkb3cgZHg9IjAiIGR5PSIxLjI1IiBzdGREZXZpYXRpb249IjEiIGZsb29kLWNvbG9yPSIjMDAwMDAwIiBmbG9vZC1vcGFjaXR5PSIwLjM4IiAvPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgogIDxnIGZpbHRlcj0idXJsKCN3dmstY3Vyc29yLXNoYWRvdykiPgogICAgPHBhdGggZmlsbD0id2hpdGUiIGQ9Im0xNiAyLjAzIDE0LjE0MiAxNC4xNEwxNiAzMC4zMTQgMS44NTggMTYuMTcgMTYgMi4wM1oiLz4KICAgIDxwYXRoIGZpbGw9IiMwMDU1RkYiIGQ9Ik0xMCAxOC45NmEuNS41IDAgMCAxLS44MTMuMzlsLTMuNy0yLjk2YS41LjUgMCAwIDEgMC0uNzhsMy43LTIuOTZhLjUuNSAwIDAgMSAuODEzLjM5VjE1bDQuOTk5LS4wMDF2LTVoLTEuOTZhLjUuNSAwIDAgMS0uMzktLjgxMmwyLjk2LTMuN2EuNS41IDAgMCAxIC43ODEgMGwyLjk2IDMuN2EuNS41IDAgMCAxLS4zOS44MTJIMTdsLS4wMDEgNWg1di0xLjk2YS41LjUgMCAwIDEgLjgxMy0uMzlsMy43IDIuOTZhLjUuNSAwIDAgMSAwIC43OGwtMy43IDIuOTZhLjUuNSAwIDAgMS0uODEyLS4zOVYxN2gtNS4wMDF2NWgxLjk2YS41LjUgMCAwIDEgLjM5LjgxM2wtMi45NTkgMy43YS41LjUgMCAwIDEtLjc4IDBsLTIuOTYtMy43YS41LjUgMCAwIDEgLjM5LS44MTNIMTVsLS4wMDEtNWgtNXYxLjk2WiIvPgogIDwvZz4KPC9zdmc+Cg==") 16 16, move';
7278
+ var CURSOR_FALLBACK_CSS = `
7279
+ :root {
7280
+ --wvk-cursor-default: ${CURSOR_DEFAULT};
7281
+ --wvk-cursor-pointer: ${CURSOR_POINTER};
7282
+ --wvk-cursor-move: ${CURSOR_MOVE};
7283
+ }
7284
+
7285
+ html {
7286
+ cursor: var(--wvk-cursor-default);
7287
+ }
7288
+
7289
+ input:not([type]),
7290
+ input[type="text"],
7291
+ input[type="search"],
7292
+ input[type="email"],
7293
+ input[type="tel"],
7294
+ input[type="url"],
7295
+ input[type="password"],
7296
+ input[type="number"],
7297
+ textarea,
7298
+ [contenteditable="true"] {
7299
+ cursor: text;
7300
+ }
7301
+
7302
+ a[href],
7303
+ button:not(:disabled),
7304
+ [role="button"]:not([aria-disabled="true"]),
7305
+ [role="link"],
7306
+ [role="tab"],
7307
+ [role="menuitem"],
7308
+ label[for],
7309
+ summary,
7310
+ input[type="checkbox"]:not(:disabled),
7311
+ input[type="radio"]:not(:disabled),
7312
+ select:not(:disabled),
7313
+ .cursor-pointer {
7314
+ cursor: var(--wvk-cursor-pointer);
7315
+ }
7316
+
7317
+ .cursor-default {
7318
+ cursor: var(--wvk-cursor-default);
7319
+ }
7320
+
7321
+ .cursor-move,
7322
+ .cursor-grab,
7323
+ .cursor-grabbing {
7324
+ cursor: var(--wvk-cursor-move);
7325
+ }
7326
+ `;
7274
7327
  var ThemeContext = React25.createContext(null);
7275
7328
  function applyThemeClass(theme) {
7276
7329
  document.documentElement.classList.toggle("dark", theme === "dark");
7277
7330
  }
7331
+ function ensureCursorStyleFallback() {
7332
+ const root = document.documentElement;
7333
+ const hasPackageCursorCss = getComputedStyle(root).getPropertyValue("--wvk-cursor-default").trim();
7334
+ if (hasPackageCursorCss || document.getElementById(CURSOR_STYLE_ID)) {
7335
+ return;
7336
+ }
7337
+ const style = document.createElement("style");
7338
+ style.id = CURSOR_STYLE_ID;
7339
+ style.textContent = CURSOR_FALLBACK_CSS;
7340
+ document.head.appendChild(style);
7341
+ }
7278
7342
  function ThemeProvider({ children }) {
7279
7343
  const [theme, setThemeState] = React25.useState("light");
7344
+ React25.useInsertionEffect(() => {
7345
+ ensureCursorStyleFallback();
7346
+ }, []);
7280
7347
  React25.useEffect(() => {
7281
7348
  const stored = localStorage.getItem(STORAGE_KEY);
7282
7349
  if (stored === "dark" || stored === "light") {