@defra/docusaurus-theme-govuk 0.0.3-alpha → 0.0.5-alpha

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
@@ -10,7 +10,7 @@ A Docusaurus 3 theme that applies the [GOV.UK Design System](https://design-syst
10
10
  - Syntax-highlighted code blocks with copy button
11
11
  - Admonition blocks (:::note, :::warning, etc.) rendered as GOV.UK InsetText / WarningText
12
12
  - 404 page with GOV.UK styling
13
- - Bundled GDS Transport fonts and GOV.UK static assets
13
+ - GOV.UK static assets included (GDS Transport is **not** bundled the theme uses Helvetica/Arial)
14
14
  - Compatible with React 18 and React 19
15
15
 
16
16
 
@@ -63,6 +63,8 @@ module.exports = {
63
63
  header: {
64
64
  serviceName: 'My Service',
65
65
  serviceHref: '/',
66
+ organisationText: 'My Organisation',
67
+ organisationHref: 'https://example.gov.uk',
66
68
  },
67
69
 
68
70
  navigation: [
@@ -108,6 +110,8 @@ module.exports = {
108
110
  |----------|------|-------------|
109
111
  | `serviceName` | `string` | Service name displayed in the GOV.UK header |
110
112
  | `serviceHref` | `string` | Link for the service name (default: `/`) |
113
+ | `organisationText` | `string` | Organisation name displayed in the header crown block |
114
+ | `organisationHref` | `string` | URL the organisation name links to |
111
115
 
112
116
  #### `themeConfig.govuk.navigation`
113
117
 
package/index.js CHANGED
@@ -91,6 +91,13 @@ module.exports = function themeGovuk(context, options) {
91
91
  return path.resolve(pkgDir, main);
92
92
  }
93
93
 
94
+ // Use MiniCssExtractPlugin for production/server builds, style-loader for dev/client
95
+ let MiniCssExtractPlugin;
96
+ if (!isServer && process.env.NODE_ENV === 'production') {
97
+ MiniCssExtractPlugin = require('mini-css-extract-plugin');
98
+ if (!config.plugins) config.plugins = [];
99
+ config.plugins.push(new MiniCssExtractPlugin({ filename: 'assets/css/govuk-theme.[contenthash].css' }));
100
+ }
94
101
  return {
95
102
  // Also resolve webpack loaders from the theme's own node_modules.
96
103
  // When consumed via file: (local dev), loaders like style-loader,
@@ -212,7 +219,9 @@ module.exports = function themeGovuk(context, options) {
212
219
  {
213
220
  test: /\.scss$/,
214
221
  use: [
215
- 'style-loader',
222
+ (!isServer && process.env.NODE_ENV === 'production')
223
+ ? require('mini-css-extract-plugin').loader
224
+ : 'style-loader',
216
225
  {
217
226
  loader: 'css-loader',
218
227
  options: {
@@ -234,10 +243,6 @@ module.exports = function themeGovuk(context, options) {
234
243
  loader: 'sass-loader',
235
244
  options: {
236
245
  implementation: require(require.resolve('sass', { paths: [siteDir] })),
237
- // Override GOV.UK asset path to include the Docusaurus baseUrl.
238
- // The default '../../assets/' produces URLs without baseUrl,
239
- // causing 404s when baseUrl is not '/'.
240
- // Only prepend for SCSS/Sass files — plain CSS can't use Sass variables.
241
246
  additionalData: (content, loaderContext) => {
242
247
  if (/\.scss$|\.sass$/.test(loaderContext.resourcePath)) {
243
248
  return `$govuk-assets-path: '${baseUrl}assets/';\n` + content;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defra/docusaurus-theme-govuk",
3
- "version": "0.0.3-alpha",
3
+ "version": "0.0.5-alpha",
4
4
  "description": "A Docusaurus theme implementing the GOV.UK Design System for consistent, accessible documentation sites",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
@@ -41,5 +41,8 @@
41
41
  },
42
42
  "engines": {
43
43
  "node": ">=18.0"
44
+ },
45
+ "devDependencies": {
46
+ "mini-css-extract-plugin": "^2.10.0"
44
47
  }
45
48
  }
@@ -29,7 +29,7 @@
29
29
  border-bottom: 1px solid #b1b4b6;
30
30
  font-size: 0.875rem;
31
31
  font-weight: 700;
32
- font-family: 'GDS Transport', arial, sans-serif;
32
+ font-family: Helvetica, Arial, sans-serif;
33
33
  }
34
34
 
35
35
  .app-code-block__pre {
@@ -38,7 +38,7 @@
38
38
  overflow: auto;
39
39
  font-size: 0.875rem;
40
40
  line-height: 1.6;
41
- font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
41
+ font-family: Menlo, Consolas, 'Courier New', monospace;
42
42
  position: relative;
43
43
  border: 1px solid #b1b4b6;
44
44
  margin: 0;
@@ -54,7 +54,7 @@
54
54
  border-radius: 0;
55
55
  background: #f3f2f1;
56
56
  cursor: pointer;
57
- font-family: 'GDS Transport', arial, sans-serif;
57
+ font-family: Helvetica, Arial, sans-serif;
58
58
  color: #0b0c0c;
59
59
 
60
60
  &:hover {
@@ -9,10 +9,27 @@
9
9
 
10
10
  /*
11
11
  * Set the default font on the body so that ALL elements
12
- * (header, footer, service-nav, etc.) inherit GDS Transport.
12
+ * (header, footer, service-nav, etc.) inherit the same stack.
13
13
  * The prose-scope only covers content inside .app-prose-scope;
14
14
  * without this, outer chrome inherits the browser default serif.
15
+ * GDS Transport is not bundled — Helvetica/Arial is used instead.
15
16
  */
16
17
  body {
17
- font-family: 'GDS Transport', arial, sans-serif;
18
+ font-family: Helvetica, Arial, sans-serif;
19
+ }
20
+
21
+ /*
22
+ * Sticky footer: Docusaurus inserts a #__docusaurus wrapper between body
23
+ * and our layout, breaking GOV.UK Frontend's flex sticky-footer chain.
24
+ * Rather than patching the chain, own the full-height context here.
25
+ */
26
+ .govuk-template--rebranded {
27
+ display: flex;
28
+ flex-direction: column;
29
+ min-height: 100vh;
30
+ }
31
+
32
+ .govuk-template--rebranded > .govuk-width-container {
33
+ flex: 1 0 auto;
34
+ width: 100%;
18
35
  }
@@ -41,15 +41,28 @@ const includes = (haystack, needle) => {
41
41
  export const useIsActive = () => {
42
42
  const location = useLocation();
43
43
 
44
- return (href, exact = true) => {
44
+ return (href, exact = true, options = {}) => {
45
45
  const target = URI.parse(href, location.pathname);
46
- const dir = target.pathname.endsWith('/') ? target.pathname : target.pathname + '/';
47
- // Root path '/' should only match exactly, not as a prefix for all paths
48
- const pathStart = target.pathname === '' || (target.pathname !== '/' && location.pathname.startsWith(dir));
49
- const pathMatch = target.pathname === '' || location.pathname === target.pathname;
46
+ const pathMatch = location.pathname === target.pathname;
50
47
  const queryMatch = includes(location.query, target.query);
51
- const activeExact = !!(pathMatch && queryMatch);
52
- return exact ? activeExact : !!(activeExact || (pathStart && queryMatch));
48
+ // Home link: exact match only (must match exactly, not as a prefix)
49
+ if (
50
+ target.pathname === '/' ||
51
+ /^\/[^/]+\/?$/.test(target.pathname) // e.g. /interactive-map or /interactive-map/
52
+ ) {
53
+ // Only highlight if the current path matches the home link's pathname exactly
54
+ return location.pathname === target.pathname && queryMatch;
55
+ }
56
+ // Overview link: href is a prefix of current path, and next char is '/' or nothing
57
+ const isOverview = location.pathname.startsWith(target.pathname)
58
+ && location.pathname.charAt(target.pathname.length) === '/';
59
+ if (isOverview) {
60
+ return pathMatch && queryMatch;
61
+ }
62
+ // All other links: startsWith logic
63
+ const dir = target.pathname.endsWith('/') ? target.pathname : target.pathname + '/';
64
+ const pathStart = location.pathname === target.pathname || location.pathname.startsWith(dir);
65
+ return pathStart && queryMatch;
53
66
  };
54
67
  };
55
68
 
@@ -15,15 +15,6 @@ export default function Heading({as: Tag = 'h2', id, children, ...props}) {
15
15
  return (
16
16
  <Tag id={id} className={className} {...props}>
17
17
  {children}
18
- {id && (
19
- <a
20
- href={`#${id}`}
21
- className="govuk-link app-heading-anchor"
22
- aria-label={`Direct link to ${typeof children === 'string' ? children : 'heading'}`}
23
- >
24
- #
25
- </a>
26
- )}
27
18
  </Tag>
28
19
  );
29
20
  }
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import '../../css/theme.scss';
2
3
  import {SkipLink, Header, Footer, PhaseBanner, ServiceNavigation, NavigationMenu} from '@not-govuk/simple-components';
3
4
  import {useLocation} from '@docusaurus/router';
4
5
  import Head from '@docusaurus/Head';
@@ -136,14 +137,17 @@ export default function Layout(props) {
136
137
  <SkipLink for="main-content">Skip to main content</SkipLink>
137
138
 
138
139
  <Header
139
- govUK
140
140
  rebrand
141
+ organisationText={header.organisationText}
142
+ organisationHref={header.organisationHref}
143
+ />
144
+
145
+ <ServiceNavigation
146
+ items={serviceNavItems}
141
147
  serviceName={header.serviceName}
142
148
  serviceHref={withBase(header.serviceHref || '/')}
143
149
  />
144
150
 
145
- <ServiceNavigation items={serviceNavItems} />
146
-
147
151
  <div className="govuk-width-container">
148
152
  {phaseBanner && (
149
153
  <PhaseBanner phase={phaseBanner.phase}>
@@ -173,7 +177,7 @@ export default function Layout(props) {
173
177
  </div>
174
178
 
175
179
  {!noFooter && (
176
- <Footer govUK rebrand meta={footer.meta} />
180
+ <Footer rebrand meta={footer.meta} />
177
181
  )}
178
182
  </div>
179
183
  </LayoutProvider>