srcdev-nuxt-components 9.0.12 → 9.0.14

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.
@@ -0,0 +1,59 @@
1
+ # Disable Colour Scheme in a Consumer App
2
+
3
+ ## Overview
4
+
5
+ This layer includes light/dark/auto colour scheme support (not via CSS `color-scheme` — iPadOS 16 compatibility). By default it:
6
+
7
+ 1. Injects a synchronous `<head>` script to apply the saved scheme before first paint (FOUC prevention)
8
+ 2. Provides `useColourScheme()` composable to read/write the active scheme via localStorage and `document.documentElement.dataset.colorScheme`
9
+
10
+ A consumer app that only uses the default (no dark/light switching) can opt out entirely. Both the head script and composable behaviour are disabled together.
11
+
12
+ ## Steps
13
+
14
+ ### 1. Set `runtimeConfig.public.colourScheme.enabled` to `false`
15
+
16
+ In the consumer's `nuxt.config.ts`:
17
+
18
+ ```ts
19
+ export default defineNuxtConfig({
20
+ extends: ["srcdev-nuxt-components"],
21
+ runtimeConfig: {
22
+ public: {
23
+ colourScheme: {
24
+ enabled: false,
25
+ },
26
+ },
27
+ },
28
+ });
29
+ ```
30
+
31
+ Or via environment variable (useful for CI or deployment config):
32
+
33
+ ```bash
34
+ NUXT_PUBLIC_COLOUR_SCHEME_ENABLED=false
35
+ ```
36
+
37
+ That's all that's needed. Nuxt merges `runtimeConfig.public` from the consumer over the layer default (`enabled: true`).
38
+
39
+ ### 2. Remove any `useColourScheme()` usage (if present)
40
+
41
+ If the consumer app has a colour scheme toggle component, remove it or replace it with a no-op. The composable returns `{ currentColourScheme }` (always `"auto"`) when disabled, so it won't throw — but the toggle UI would be non-functional.
42
+
43
+ ### 3. Remove `data-color-scheme` overrides from CSS (if any)
44
+
45
+ If the consumer's CSS references `[data-color-scheme="dark"]` selectors, those can be removed since the attribute will never be set.
46
+
47
+ ## How it works
48
+
49
+ | Part | Behaviour when disabled |
50
+ |---|---|
51
+ | `<head>` inline script | Not injected — no localStorage read, no `data-color-scheme` set |
52
+ | `useColourScheme()` | Returns `{ currentColourScheme: ref("auto") }`, no localStorage/DOM side effects |
53
+
54
+ The injection is controlled by [modules/colour-scheme.ts](../../modules/colour-scheme.ts), which reads `runtimeConfig.public.colourScheme.enabled` at build time via a Nuxt module hook. The composable is in [app/composables/useColourScheme.ts](../../app/composables/useColourScheme.ts).
55
+
56
+ ## Notes
57
+
58
+ - The layer default is `enabled: true` — no change required for apps that use the colour scheme feature
59
+ - The env var `NUXT_PUBLIC_COLOUR_SCHEME_ENABLED` follows Nuxt's standard automatic env var mapping for `runtimeConfig.public` values
@@ -16,7 +16,7 @@ Skills land in `.claude/skills/srcdev-nuxt-components/` — safe to re-run witho
16
16
 
17
17
  Each skill is a single markdown file named `<area>-<task>.md`.
18
18
 
19
- ```
19
+ ```text
20
20
  .claude/skills/
21
21
  ├── index.md — this file
22
22
  ├── storybook-add-story.md — create a Storybook story for a component
@@ -24,6 +24,7 @@ Each skill is a single markdown file named `<area>-<task>.md`.
24
24
  ├── testing-add-unit-test.md — create a Vitest unit test with snapshots
25
25
  ├── testing-add-playwright.md — create a Playwright visual regression test
26
26
  ├── theming-override-default.md — override the default theme with a custom colour scale
27
+ ├── colour-scheme-disable.md — disable light/dark scheme support in a consumer app
27
28
  └── components/
28
29
  ├── eyebrow-text.md — EyebrowText props, usage patterns, styling
29
30
  ├── hero-text.md — HeroText props, usage patterns, styling
package/README.md CHANGED
@@ -46,6 +46,39 @@ Skills are copied into `.claude/skills/srcdev-nuxt-components/` so they never co
46
46
 
47
47
  ---
48
48
 
49
+ ## Consumer App Configuration
50
+
51
+ Configuration options for apps extending this layer. All options go in the consumer's `nuxt.config.ts` under `runtimeConfig.public` and can also be set via environment variable.
52
+
53
+ ### Colour Scheme
54
+
55
+ The layer ships with light/dark/auto colour scheme support. This includes a synchronous `<head>` script (FOUC prevention) and the `useColourScheme()` composable.
56
+
57
+ Consumer apps that only use a single default scheme can disable it entirely:
58
+
59
+ ```ts
60
+ // nuxt.config.ts
61
+ runtimeConfig: {
62
+ public: {
63
+ colourScheme: {
64
+ enabled: false, // disables head script injection and composable side effects
65
+ },
66
+ },
67
+ },
68
+ ```
69
+
70
+ Or via environment variable:
71
+
72
+ ```bash
73
+ NUXT_PUBLIC_COLOUR_SCHEME_ENABLED=false
74
+ ```
75
+
76
+ When disabled, no `data-color-scheme` attribute is set on `<html>` and `useColourScheme()` is a no-op. The default is `true`.
77
+
78
+ > See [.claude/skills/colour-scheme-disable.md](.claude/skills/colour-scheme-disable.md) for the full guide.
79
+
80
+ ---
81
+
49
82
  ## Known Dev Server Warnings
50
83
 
51
84
  ### `[request error] [GET] http://localhost:3000/_nuxt/` (404)
@@ -1,14 +1,14 @@
1
1
  html {
2
- color-scheme: light dark;
2
+ /* color-scheme: light dark; */
3
3
  interpolate-size: allow-keywords;
4
4
 
5
- &.light {
5
+ /* &.light {
6
6
  color-scheme: light;
7
7
  }
8
8
 
9
9
  &.dark {
10
10
  color-scheme: dark;
11
- }
11
+ } */
12
12
 
13
13
  font-size: 62.5%;
14
14
 
@@ -1,8 +1,13 @@
1
1
  import { COLOUR_SCHEME_KEY, type ColourScheme, getValidScheme, applyColourScheme } from "~/utils/colour-scheme-init";
2
2
 
3
3
  export const useColourScheme = () => {
4
+ const config = useRuntimeConfig();
5
+ const enabled = (config.public.colourScheme as { enabled?: boolean } | undefined)?.enabled ?? true;
6
+
4
7
  const currentColourScheme = ref<ColourScheme>("auto");
5
8
 
9
+ if (!enabled) return { currentColourScheme };
10
+
6
11
  onMounted(() => {
7
12
  // DOM already has correct scheme applied by the head script,
8
13
  // this just syncs the reactive state to match
@@ -0,0 +1,27 @@
1
+ import { defineNuxtModule } from "@nuxt/kit";
2
+
3
+ export default defineNuxtModule({
4
+ meta: {
5
+ name: "colour-scheme",
6
+ configKey: "colourScheme",
7
+ },
8
+ setup(_, nuxt) {
9
+ const enabled = (nuxt.options.runtimeConfig.public?.colourScheme as { enabled?: boolean } | undefined)?.enabled ?? true;
10
+
11
+ if (!enabled) return;
12
+
13
+ nuxt.options.app.head.script ||= [];
14
+ nuxt.options.app.head.script.push({
15
+ innerHTML: `
16
+ (function() {
17
+ var saved = localStorage.getItem('colourScheme');
18
+ var valid = ['auto', 'dark', 'light'];
19
+ var scheme = valid.includes(saved) ? saved : 'auto';
20
+ document.documentElement.dataset.colorScheme = scheme;
21
+ })();
22
+ `,
23
+ tagPosition: "head",
24
+ tagPriority: "critical",
25
+ } as Parameters<typeof nuxt.options.app.head.script.push>[0]);
26
+ },
27
+ });
package/nuxt.config.ts CHANGED
@@ -11,10 +11,18 @@ export default defineNuxtConfig({
11
11
  resendApiKey: "", // NUXT_RESEND_API_KEY
12
12
  contactEmailTo: "", // NUXT_CONTACT_EMAIL_TO — inbox that receives enquiries
13
13
  contactEmailFrom: "", // NUXT_CONTACT_EMAIL_FROM — must be a verified Resend domain
14
+ public: {
15
+ // Consumer apps that don't support dark/light mode can opt out entirely:
16
+ // set NUXT_PUBLIC_COLOUR_SCHEME_ENABLED=false (env var) or override in their nuxt.config.ts
17
+ colourScheme: {
18
+ enabled: true,
19
+ },
20
+ },
14
21
  },
15
22
  css: ["./app/assets/styles/main.css"],
16
23
  modules: [
17
24
  // Required by consumers — always included
25
+ "./modules/colour-scheme",
18
26
  "@nuxt/icon",
19
27
  ...(process.env.STORYBOOK ? [] : ["@nuxt/fonts"]),
20
28
  "@nuxt/image",
@@ -37,21 +45,6 @@ export default defineNuxtConfig({
37
45
  bodyAttrs: {
38
46
  class: "srcdev-components-extended",
39
47
  },
40
- script: [
41
- {
42
- // Inlined so it runs synchronously before first paint
43
- innerHTML: `
44
- (function() {
45
- var saved = localStorage.getItem('colourScheme');
46
- var valid = ['auto', 'dark', 'light'];
47
- var scheme = valid.includes(saved) ? saved : 'auto';
48
- document.documentElement.dataset.colorScheme = scheme;
49
- })();
50
- `,
51
- tagPosition: "head",
52
- tagPriority: "critical",
53
- },
54
- ],
55
48
  },
56
49
  pageTransition: {
57
50
  name: "page",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "9.0.12",
4
+ "version": "9.0.14",
5
5
  "main": "nuxt.config.ts",
6
6
  "types": "types.d.ts",
7
7
  "license": "MIT",
@@ -35,6 +35,7 @@
35
35
  "files": [
36
36
  ".claude/",
37
37
  "app/",
38
+ "modules/",
38
39
  "nuxt.config.ts",
39
40
  "types.d.ts"
40
41
  ],