Skip to content

Latest commit

 

History

818 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SLAC Drupal Profile Theme

slac is the Drupal front-end theme for SLAC National Accelerator Laboratory websites. It is derived from Gesso, a Sass-based starter theme that outputs accessible HTML5 markup. It uses a mobile-first responsive approach and leverages SMACSS to organize styles. This encourages a component-based approach to theming through the creation of discrete, reusable UI elements. The theme is heavily integrated with Storybook and the Component Libraries module, allowing Drupal and Storybook to share the same markup.

The theme is distributed as a Composer package (slac/slac-drupal-profile-theme, type drupal-theme) rather than being copied into a site's web/themes/custom/ directory. See Installation below.

This theme currently tracks Gesso 5.4.6. Component markup, design tokens and styles have diverged substantially from upstream and are intentionally not kept in sync; see Relationship to upstream Gesso.

To submit bug reports or feature requests for this theme, use this repository's issue queue. For upstream Gesso itself, see the Gesso Drupal project page, the Gesso GitHub repo, and the Gesso Storybook demo site.

Global prerequisites

The following packages need to be installed on your system in order to compile and use this theme.

  • Node version 22 (LTS), as pinned in .nvmrc. CI (ci.yml, build-assets.yml, publish-demo-site.yml) reads the same file.

  • npm version 10.7.0 or greater.

Installation

This theme is published as a Composer package through the SLAC Satis repository. It is not meant to be copied into web/themes/custom/; releases are built by CI and consumed by Composer.

  1. Make sure the SLAC Satis repository is configured in your site's composer.json, then require the theme:

    composer require slac/slac-drupal-profile-theme

    Because composer.json declares "type": "drupal-theme", your site's Composer installer paths will place it in the appropriate themes directory as slac.

  2. Enable the theme, then set it as the default theme on the Appearance admin page:

    drush theme:enable slac
  3. Enable the SLAC Helper (slac_helper) module. Unlike upstream Gesso, this module is not bundled in this repository — it is a separate package that must be required and installed on its own. It is listed in slac.info.yml dependencies, so it must be present for the theme to function. slac_helper provides the theme's PHP-side Twig filters, including unique_id.

  4. Install the Component Libraries module. Since many of the Drupal templates reference twig files inside Storybook using Twig namespaces, this module is required for the theme to function. It is listed in slac.info.yml dependencies.

  5. Install the Twig Tweak module. It is also listed in slac.info.yml dependencies.

  6. Optional: Install the Twig Field Value module. This is not required, but it can make working with Twig templates easier. Please note, however, that using the |field_value Twig filter from this module will break Drupal’s QuickEdit functionality.

  7. Optional: Install the Background Images Formatter module and its Responsive Background Images Formatter submodule. This is not required, but it will allow you to use images uploaded to Drupal as background images, with different image sizes at different breakpoints.

The screenshot shown on the Appearance admin page is screenshot.png in the theme root.

Getting started

For development, you can set the theme up as part of a Drupal site or work only in Storybook. The theme includes npm tasks to compile design tokens, CSS, JS, Storybook, and the SVG sprite using webpack.

To use these tasks, first run the following npm command in the theme folder to install node dependencies.

npm ci

To compile the theme, start Storybook, and watch for changes run the following command in the theme directory:

npm run dev

Open localhost:6006 to view Storybook. If you’re using Docker (or some other container engine) for local development, this might be mapped to a custom domain or a port on a custom domain such as storybook.ddev.site or site.ddev.site:6006.

If you add new SCSS and/or JS files, you will need to restart webpack by canceling and then re-running npm run dev. New files will not be processed until webpack restarts. Errors will also be shown for duplicate filenames.

npm scripts

The full set of scripts defined in package.json:

Script What it does
npm run start One-off build of the design tokens only (webpack.theme-config.js in development mode). It does not compile CSS or JS. It is a prerequisite for the watchers, which is why watch and dev run it first.
npm run watch-theme Watches and rebuilds the theme's CSS, JS and SVG sprite (webpack.dev.js).
npm run watch-design-tokens Watches and rebuilds the generated design-token Sass partial and JS object (webpack.theme-config.js).
npm run watch start, then watch-theme and watch-design-tokens concurrently. No Storybook. Use this when you are working against a real Drupal site.
npm run dev start, then watch-theme, watch-design-tokens and storybook concurrently. Use this when you are working in Storybook.
npm run storybook Storybook dev server on port 6006, without any theme watchers.
npm run build Full production build: design tokens (webpack.theme-config.js) followed by CSS/JS/sprite (webpack.production.js). This is the build CI runs for releases.
npm run build-storybook build, then a static Storybook export into storybook/.
npm run eslint Lints source/** JavaScript, excluding story files.
npm run stylelint Lints source/**/*.scss.
npm test Runs eslint then stylelint. Does not build anything.
npm run component Scaffolds a new component (see below).

Note that the webpack builds run ESLint and Stylelint as plugins, so lint failures break the build. The standalone eslint and stylelint scripts are there for when you want to check linting without waiting for a full build.

Generating new components

Run npm run component to create boilerplate files for a new component. This is the recommended approach as it will set up basic Twig and Storybook files that you can modify.

Interactive mode

Running the command without arguments will prompt you for the component details:

npm run component

Non-interactive mode

You can also pass arguments to skip the prompts:

npm run component -- --name my-component --folder 03-components

Available options

Option Description
--name <name> Component name (required)
--folder <folder> Component location, e.g., 03-components (required)
--title <title> Human-readable title (defaults to Capital Case of name)
--subfolder <name> Optional subfolder within the component location
--no-modular-sass Add styles to the global stylesheet instead of a separate file
--js Include a JavaScript file
--help, -h Show help message

Storybook

Name your stories files [component].stories.jsx. See source/03-components/menu/menu.stories.jsx for an example. .storybook/main.js picks up source/**/*.stories.@(js|jsx|ts|tsx).

Prose documentation pages are plain [name].mdx files, not [name].stories.mdx. Storybook 8 removed support for MDX files that define stories, so an MDX file may only contain documentation; the stories it documents have to live in a sibling .stories.jsx. Existing examples: source/01-global/global.mdx, source/03-components/dropdown-menu/dropdown-menu.mdx.

Story format (CSF2)

Stories use Component Story Format 2: the default export is the component meta, and each story is a function of its args, with args (and, if needed, storyName) attached as properties. The stories are exported as a list.

import parse from 'html-react-parser';

import twigTemplate from './menu.twig';
import data from './menu.yml';

const settings = {
  title: 'Components/Menu/Default',
};

const Default = args =>
  parse(
    twigTemplate({
      ...args,
    })
  );
Default.args = { ...data };

export default settings;
export { Default };

Story names come from the export name (LargeCard is shown as "Large Card"), or from an explicit LargeCard.storyName = '...'. Storybook's own indexer does not do that for export lists, so .storybook/main.js wraps it.

npm run component scaffolds upstream Gesso's CSF3 form (a plain object with a render function). It renders too, but convert it to CSF2 to match the rest of the theme.

Storybook 7 and later load only the current story's imports, not every story file. So:

  • A story imports its own component's stylesheet and script (for example import './menu.scss'; and import './menu.es6';).
  • A story that renders another component (through a Twig include, embed or extends) also imports that component's stories file (for example import '../tooltip/tooltip.stories';), or its stylesheet where it has no stories file. That mirrors the attach_library() calls Drupal would follow.
  • .storybook/preview.js loads dist/css/styles.css and the site-wide behaviours of the slac/global library (arrow-link, external-link, transitions) for every story.

Shared story helpers live in source/06-utility/storybookHelper.jsx. .storybook/decorators.jsx (upstream's) exports a withGlobalWrapper decorator that no story currently uses; the global decorator that runs Drupal.attachBehaviors() after each render is defined in .storybook/preview.js.

To match Storybook to your site’s branding, change the colors, brand title, brand logo and base font in .storybook/theme.js, which .storybook/manager.js imports and passes to addons.setConfig(). Web fonts are loaded in .storybook/manager-head.html (for the Storybook UI itself) and .storybook/preview-head.html (for the rendered stories). See the Storybook docs for more information about and examples of theming.

DDEV and allowed hosts

Storybook 10 validates the Host header on dev-server requests. When you access Storybook through the DDEV router (https://<project-name>.ddev.site:6006), the hostname must be allowlisted in .storybook/main.js.

By default, this theme reads DDEV_HOSTNAME or VIRTUAL_HOST from the environment (DDEV sets VIRTUAL_HOST in the Storybook container) and uses that hostname. If neither variable is set, any *.ddev.site hostname is allowed instead. Access via localhost:6006 does not require additional configuration.

If you use a different reverse proxy or custom local domain, add its hostname to core.allowedHosts in .storybook/main.js. See the Storybook core docs for details.

Sass

Sass can be compiled as part of the global styles.css file or to individual CSS files for use in a Drupal library.

@use is used to import Sass variables, mixins, and/or functions into individual SCSS files. @import is discouraged by the Sass team and will eventually be phased out.. This means that most files will start with @use '00-config' as *;. This allows you to use the design token accessor functions without an additional namespace. Other functions and mixins can be used similarly. Note that to avoid namespace collisions, only this theme's own variables, mixins, and functions (those forwarded from source/00-config) should be used with *.

All Sass files that are compiled to individual CSS files must have a unique filename, even if they are in different directories.

Global styles

Prefix the name of your Sass file with _, e.g. _card.scss. Add it to the appropriate aggregate file (i.e. _components.scss).

Individual component/library styles

DO NOT prefix the name of your Sass file with _, e.g. menu.scss. Import the config and global aggregate files. Import your SCSS file at the top of your Storybook file. See dropdown-menu.stories.jsx for an example. Don’t forget to add it to the slac.libraries.yml file as well.

Sass Linting

Stylelint and Prettier are used to lint CSS and SCSS files. Warnings will break the build, so if you have a valid reason to break Stylelint rules you can have it ignore code in two ways:

  1. Add // stylelint-disable-next-line to the line just before where the Stylelint warning is triggered.

  2. To ignore several lines, add // stylelint-disable before the code in question and add // stylelint-enable afterwards.

In both cases above, please add a comment about the valid reason to disable the Stylelint rule(s) in your use case.

The Stylelint rules can be changed in the .stylelintrc.yml file. By default, the theme extends stylelint-config-sass-guidelines and enables the stylelint-prettier plugin (which reports Prettier formatting differences as Stylelint errors), plus stylelint-order and a local plugin/selector-pseudo-class-lvhfa rule from lib/stylelintLVHFA.js, with some additional customizations.

The Prettier config can be changed in the .prettierrc file.

You can also run Stylelint on its own with npm run stylelint.

JavaScript

JavaScript can be compiled to individual JS files for use in a JavaScript library or included within a different JS file. JS files that use modern (ES2015+) syntax must be named [name].es6.js, but this is not required by the compiler. JavaScript files should go in the appropriate folder under source (e.g., source/03-components/menu for menu-related JavaScript). There is not a separate folder for JS files as there was in older versions of this theme.

All JavaScript files must have a unique filename, even if they are in different directories.

Modules

Prefix the name of your JavaScript file with _, e.g. _Menu.es6.js. Import it to the appropriate JavaScript file(s), (i.e. primary-menu.es6.js).

Individual component/library scripts

DO NOT prefix the name of your JS file with _. Import your JS file at the top of your Storybook file. See dropdown-menu.stories.jsx for an example. Don’t forget to add it to the slac.libraries.yml file as well.

common.js

Any library you create in slac.libraries.yml that includes an individual component script must include slac/common as a dependency. (In most cases, you will also add core/drupal as a dependency, if you are using the Drupal object anywhere in your code.) common.js is generated by both the production build and the development watcher (webpack.common.js has held the splitChunks configuration since Gesso 5.4.6), and contains JavaScript that is shared across two or more components, so that it is not bundled multiple times on the page. The recommended practice is for each library to declare its dependencies, even if some of them are repeated across multiple libraries and/or shared with global. This ensures that Drupal will always load the dependencies before loading any library that depends on them. See the dropdown_menu library in slac.libraries.yml as an example.

The common JS file is created using the Webpack SplitChunksPlugin. To change how it behaves, update optimization.splitChunks in webpack.common.js. You may also need to update slac_library_info_build in includes/libraries.inc to change what files are included in the slac/common library. We recommend using the default setup unless you have a specific use case that requires advanced configuration.

JS Linting

ESLint and Prettier are used to lint JavaScript files. If you have a valid reason to break one of the rules, you can ignore a specific line using any of the options in the ESLint documentation.

Please add a comment about the valid reason to disable the ESLint rule(s) in your use case.

The ESLint config can be changed in the eslint.config.js file. The theme follows the Forum One JavaScript standards, which mostly follow the ESLint recommended config. For React files, there are additional JSX-specific linting rules. A relaxed variant used by the dev webpack build lives in eslint.dev.config.js.

The Prettier config can be changed in the .prettierrc file.

You can also run ESLint on its own with npm run eslint.

jQuery

Upstream Gesso no longer ships jQuery. This theme deliberately keeps it, because two components require it: source/03-components/dropbutton/dropbutton.es6.js (a port of Drupal core's jQuery-based dropbutton) and source/03-components/addtocal/addtocal-a11y.es6.js (the addtocal contrib module's JS requires jQuery).

jQuery is therefore retained in the following places, all of which must stay in sync:

  1. jquery in package.json dependencies.

  2. jquery: 'jQuery' in the externals block of webpack.common.js, so it is treated as a Drupal-provided global rather than bundled.

  3. core/jquery in the dependencies of both the dropbutton and addtocal_a11y libraries in slac.libraries.yml.

Storybook has no jQuery external: there is no Drupal-provided jQuery on a Storybook page, so import jQuery from 'jquery' bundles the real package into the stories that need it.

Import it at the top of a file the same way Drupal and once are imported:

import jQuery from 'jquery';

If a future refactor removes the last jQuery consumer, remove all three entries above together.

TypeScript

TypeScript is supported for component scripts. The webpack entry glob picks up source/**/!(*.stories).{cjs,js,ts}, so a component script may be named [name].es6.ts instead of [name].es6.js and will compile to the same dist/js/[name].es6.js output. The same "no leading underscore, unique filename" rules apply. .ts/.tsx files are handled by ts-loader in transpileOnly mode, with type checking done out of band by fork-ts-checker-webpack-plugin, so type errors are reported without slowing the bundle down.

Because resolve.extensionAlias maps .es6 to ['.es6.ts', '.es6.js'], an existing import Foo from './_Foo.es6' keeps working when _Foo.es6.js is renamed to _Foo.es6.ts. This means files can be migrated one at a time.

Compiler options live in tsconfig.json. The compilerOptions.paths block resolves the module specifiers that are webpack externals at build time, so that the type checker and editors can still find them:

  • drupal, drupalSettings and once resolve to the Storybook stubs in .storybook/stubs/.
  • jquery resolves to the real package (node_modules/jquery/dist/jquery.js).

lib/ is excluded from the project's type checking and has its own lib/tsconfig.json.

Design tokens

The theme uses the configuration file source/00-config/config.design-tokens.yml to manage its design tokens. The npm build and dev tasks will automatically generate a global Sass map to easily pull design tokens into individual SCSS files.

Functions

The following Sass functions can be used to access the tokens defined in config.design-tokens.yml.

gesso-box-shadow($shadow)

Output a shadow value from the box-shadow token list.

box-shadow: gesso-box-shadow(1);

gesso-breakpoint($breakpoint)

Output a size value from the breakpoints token list.

@include breakpoint(gesso-breakpoint(desktop)) {
  display: flex;
}

@include breakpoint-max(gesso-breakpoint(mobile), true) {
  display: none;
}

@include breakpoint-min-max(
  gesso-breakpoint(mobile),
  gesso-breakpoint(tablet),
  true
) {
  display: block;
}

gesso-brand($color, $variant)

Output a color value from the palette brand token list.

color: gesso-brand(cardinal, light);

gesso-color($type, $subtype)

Output a color value from the colors token list.

color: gesso-color(text, primary);

gesso-constrain($constrain)

Output a size value from the constrains token list.

max-width: gesso-constrain(sm);

gesso-duration($duration)

Output a timing value from the transitions duration token list.

transition-duration: gesso-duration(short);

gesso-easing($easing)

Output an easing value from the transitions ease token list.

transition-timing-function: gesso-easing(ease-in-out);

gesso-font-family($family)

Output a stack value from the font-family token list.

font-family: gesso-font-family(primary);

gesso-font-size($size)

Output a size value from the font-size token list.

font-size: rem(gesso-font-size(2));

gesso-font-weight($weight)

Output a weight value from the font-weight token list.

font-weight: gesso-font-weight(semibold);

gesso-grayscale($color)

Output a color value from the palette grayscale token list.

color: gesso-grayscale(gray-2);

gesso-line-height($height)

Output a height value from the line-height token list.

line-height: gesso-line-height(tight);

gesso-spacing($spacing)

Output a size value from the spacing token list.

margin-bottom: rem(gesso-spacing(4));

gesso-z-index($index)

Output an index value from the z-index token list.

z-index: gesso-z-index(modal);

Design tokens in JavaScript

The values in the design tokens configuration file are also exported to JavaScript objects so that the same values can be used in CSS and JS. The JS objects can be found in source/00-config/_GESSO.es6.js (the filename is inherited from upstream Gesso and deliberately left alone). This generated file is gitignored and is rebuilt whenever npm run start, npm run build, npm run watch or npm run dev are run.

For example, to use a breakpoint in a script:

import { BREAKPOINTS } from '../../../00-config/_GESSO.es6';

if (window.matchMedia(`min-width: ${BREAKPOINTS.desktop}`).matches) {
  // Some script that should only run on larger screens.
}

This will use the same breakpoint as breakpoint(gesso-breakpoint(desktop)) in your Sass.

Viewport width-based media queries

The theme uses custom mixins to specify viewport width based media queries:

  • breakpoint: min-width queries
  • breakpoint-max: max-width queries
  • breakpoint-min-max: queries with both a min and max width

Each mixin takes one or two width parameters, which can be a straight value (e.g., 800px, 40em) or a design token value called using the gesso-breakpoint function (e.g., gesso-breakpoint(tablet-lg)). The breakpoint-max and breakpoint-min-max mixins can also take an optional parameter to subtract one pixel from the max-width value, which can be useful when you want your query to go up to the value but not to include it, such as when using breakpoint token values.

@include breakpoint($width) { // styles }

Output a min-width based media query.

@include breakpoint(800px) {
  display: flex;
}

@include breakpoint(gesso-breakpoint(desktop)) {
  display: none;
}

@include breakpoint-max($width, $subtract_1_from_max) { // styles }

Output a max-width based media query. The optional $subtract_1_from_max parameter will subtract 1px from the width value if set to true (default: false).

@include breakpoint-max(900px) {
  display: block;
}

@include breakpoint-max(gesso-breakpoint(mobile), true) {
  display: none;
}

@include breakpoint-min-max($min-width, $max-width, $subtract_1_from_max) { // styles }

Output a media query with both a min-width and max-width. The optional $subtract_1_from_max parameter will subtract 1px from the max-width value if set to true (default: false).

@include breakpoint-min-max(400px, 700px) {
  display: flex;
}

@include breakpoint-min-max(
  gesso-breakpoint(mobile),
  gesso-breakpoint(tablet),
  true
) {
  display: block;
}

Twig filters and functions

This theme includes some additional filters and functions that can be used in Twig templates. In Storybook they are registered in .storybook/preview.js from the implementations in lib/. In Drupal they are provided by contrib modules or by the SLAC Helper (slac_helper) module, as noted for each filter below.

add_attributes

Fork of Drupal Pattern Lab's add_attribute Twig function. Allows Twig templates to add attributes that, in Drupal, will be merged with the Drupal attributes object while also rendering in Storybook. Storybook implementation: lib/addAttributesTwigExtension.js.

<div {{ add_attributes(
  {
    class: 'your-class-one your-class-two',
    'data-foo': 'bar'
  }
) }}>...</div>

keysort

Twig filter to sort an object by key alphabetically. Storybook implementation: lib/keysort.js.

{% for key, value in your_object|keysort %}
...
{% endfor %}

unique_id

Twig filter that turns a string into a value safe to use as an HTML id. This theme's templates use unique_id, with 28 call sites across 20 Twig files. Storybook implementation: lib/uniqueId.js, registered in .storybook/preview.js. In Drupal it comes from the SLAC Helper (slac_helper) module.

Upstream Gesso renamed its filter to clean_unique_id at 5.4.0 and reverted the rename at 5.4.5. This theme never followed it (it would have needed a matching slac_helper change and every template call site at once), so there is nothing to track.

{% set section_id = 'accordion-section'|unique_id %}

field_value

Twig filter to get the rendered value of a field without its wrapper markup. In Storybook it is provided by lib/fieldValue.js; in Drupal it is provided by the Twig Field Value module (see the Installation section above). Note that using |field_value breaks Drupal's QuickEdit functionality.

{{ content.field_example|field_value }}

subheading_level

Twig filter to transform a heading tag to the next level down (h2 -> h3, h3 -> h4, etc.) Used when the parent heading level can vary but, to maintain accessibility, the component's heading or subheading should change accordingly.

{% set subheading_element = title_element|subheading_level %}

<{{ subheading_element|default('h3') }}>...</{{ subheading_element|default('h3') }}>

Not available yet, in Storybook or Drupal. Upstream Gesso ships both halves (lib/subheadingLevelTwigExtension.js and a PHP extension in its helper module). This theme takes neither until slac_helper provides the Drupal filter, so that a template never renders in one and fails in the other. Do not use |subheading_level yet.

Building Storybook

A static Storybook site can be built with npm run build-storybook, which builds the theme assets first and then outputs Storybook to storybook/ in the theme root.

storybook/ is gitignored — it is a build artifact and is never committed. The published demo site is built in CI instead: the .github/workflows/publish-demo-site.yml workflow runs npm ci and npm run build-storybook on every push to main (and on manual dispatch), then deploys storybook/ to this repository's GitHub Pages site.

The demo site is published at https://slac.github.io/slac-drupal-profile-theme/.

Theme settings

Some aspects of the theme can be configured on the theme settings page (Appearance → SLAC → Settings). The form is built in theme-settings.php and the values are declared in config/schema/slac.schema.yml.

Back to Top

  • include_back_to_top — whether to include the Back to Top component (default: on).
  • threshold — how far, in pixels, a user should scroll down the page before the Back to Top component appears (default: 200).
  • smooth_scroll — whether to animate the scroll back to the top (default: on).

Breadcrumb

  • include_current_page_in_breadcrumb — whether the current page is included as the last breadcrumb item (default: on).

Hide Social Share Icons

  • hide_social_media_share_icons — if enabled, social media icons will not be shown on the side of the page.

SLAC Today header link

  • slac_today_header_link — the URL used for the SLAC Today link in the site header.

SLAC search

  • include_slac_web_search — whether to offer the SLAC-wide web search option in the search form (default: off).
  • search_this_site_placeholder — custom placeholder text shown when the "This site" search option is selected. If left empty, the Organization Acronym, then the Organization Name, then the Site Name is used.

The list above is the complete set — anything not listed is not a setting of this theme. In particular, upstream Gesso's Button styles theme setting and its Gesso Button link-field formatter are not part of this theme.

Relationship to upstream Gesso

This theme began as a copy of Gesso and still shares its build toolchain, Sass architecture, gesso-* design-token accessor functions, and Storybook integration. The rename from gesso to slac happened long ago; there is nothing left to rename.

  • The theme currently tracks Gesso 5.4.6, which is the version recorded in package.json.
  • Upstream toolchain changes (Node, webpack, ESLint, Stylelint, Storybook, TypeScript, Sass module-system migration) are merged in.
  • Upstream component, template, and design-token changes are deliberately not merged. SLAC's components and tokens have diverged and are maintained here.
  • Gesso 5.4.6 is the baseline for future merges. It was reached one upstream release at a time (the records are in .claude/: gesso-STATE.md, the per-release plans in .claude/gesso-plans/, and gesso-review-flags.md). Every deliberate deviation from upstream is listed in .claude/gesso-deviations.md with its reason; in code it carries a one-line // Local: …; see .claude/gesso-deviations.md marker (for example the jquery external and the Stylelint files scope in webpack.common.js). Keep that convention: add a register row, and a one-line marker at the site of the deviation.
  • A few upstream identifiers are retained on purpose, because renaming them would touch every SCSS and JS file for no functional gain: the gesso-* Sass function prefix, and source/00-config/_GESSO.es6.js.

Contributing

Please use this repository's GitHub issue queue for discussion, bug reports, feature requests, etc. Pull requests should target main.

Releases

Releases are cut by pushing a tag. The .github/workflows/build-assets.yml workflow then:

  1. Checks out the tag, runs npm ci and npm run build, and removes node_modules.
  2. Writes the tag name into slac.info.yml as the version property.
  3. Zips the result as slac.zip, excluding VCS files, node_modules/, .editorconfig and .claude/. source/ ships: templates include @components/... from it. A step then checks the zip's contents.
  4. Uploads slac.zip to the GitHub Release for that tag.
  5. Once the build job has succeeded, sends a repository_dispatch (release-published) to the slac-it/slac-drupal-satis repository, so that Satis picks up the new version and Composer consumers can require it.

There is no need to commit build artifacts: dist/css, dist/js, the SVG sprite, the generated design-token partials and storybook/ are all gitignored and produced by CI.

Maintainers

This theme is maintained by the SLAC web team.

It is derived from the Gesso theme by Forum One, which is maintained by Corey Lafferty, KJ Monahan, Dan Mouyard (@dcmouyard), and Tommy Alter.

About

This is the theme for the 'SLAC Drupal Install Profile' repo.

Resources

Stars

0 stars

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages