| .vscode | ||
| build | ||
| components | ||
| config | ||
| fonts | ||
| icons/phosphor | ||
| lib | ||
| src | ||
| templates | ||
| .csslintrc | ||
| .editorconfig | ||
| .eslintignore | ||
| .eslintrc.json | ||
| .gitattributes | ||
| .gitignore | ||
| .nvmrc | ||
| .prettierignore | ||
| .prettierrc.json | ||
| AGENTS.md | ||
| composer.json | ||
| curtistinkers_theme.icons.yml | ||
| curtistinkers_theme.info.yml | ||
| curtistinkers_theme.libraries.yml | ||
| favicon.ico | ||
| LICENSE.txt | ||
| logo-dark.svg | ||
| logo-light.svg | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| screenshot.png | ||
CurtistinkersTheme Theme
CurtistinkersTheme is a component-based Drupal theme, providing a modern and flexible starting point for site owners to build scalable and efficient websites using Drupal Canvas.
Getting started
To use CurtistinkersTheme, you can install it via Composer, like any other Drupal theme. But CurtistinkersTheme is designed to be copied, rather than used as a contributed theme or base theme, and you should not assume that future updates will be compatible with your site.
To create the clone to use for your site, use Drupal core's starter kit tool:
cd drupal/web
php core/scripts/drupal generate-theme my_theme --name="My Custom Theme" --description="A customized version of CurtistinkersTheme." --starterkit=curtistinkers_theme
This will create a copy of CurtistinkersTheme called my_theme, and place it in themes/my_theme. This theme is yours, and you can customize it in any way you see fit!
To install it in Drupal, either visit the /admin/appearance page, or run drush theme:enable my_theme at the command line.
You can then remove the contributed version via Composer with composer remove drupal/curtistinkers_theme.
Sub-theming
Don't create your custom theme as a sub-theme of CurtistinkersTheme. CurtistinkersTheme is meant to be used as a starter kit, and does not provide backward compatibility. This allows us to rapidly innovate, iterate, and improve. If you create a sub-theme of CurtistinkersTheme, it is likely to break in the future.
Customizing
Fonts & colors
To change the fonts or colors in my_theme, edit the theme.css file. Changes to theme.css do not require a CSS rebuild, but you may need to clear the cache.
Custom components
CurtistinkersTheme uses single-directory components and comes with a variety of commonly used components. You can add new components and modify existing ones, but be sure to rebuild the CSS when you make changes.
Building CSS
CurtistinkersTheme uses Tailwind to simplify styling by using classes to compose designs directly in the markup.
If you want to customize the Tailwind-generated CSS, install the development tooling dependencies by running the following command in your theme's directory:
npm install
If you modify CSS files or classes in a Twig template, you need to rebuild the CSS:
npm run build
For development, you can watch for changes and automatically rebuild the CSS:
npm run dev
Code Formatting
CurtistinkersTheme uses Prettier to automatically format code for consistency. The project is configured with plugins for Tailwind CSS and Twig templates.
For the best experience, set up Prettier in your editor to automatically format files on save.
To format all files in the project:
npm run format
To check if files are formatted correctly without making changes:
npm run format:check
Note: Some files are excluded from formatting via .prettierignore, such as Drupal's html.html.twig template, which contains placeholder tokens that break Prettier's HTML parsing.
Component JavaScript
lib/component.js has two classes you can use to nicely encapsulate your component JS without pasting all the Drupal.behaviors.componentName boilerplate into every file. The steps are:
- Extend the
ComponentInstanceclass to a new class with the code for your component. - Create a new instance of the
ComponentTypeclass to automatically activate all the component instances on that page.
For example, here's a stub of accordion.js:
import { ComponentType, ComponentInstance } from "../../lib/component.js";
// Make a new class with the code for our component.
//
// In every method of this class, `this.el` is an HTMLElement object of
// the component container, whose selector you provide below. You don't
// have an array of elements that you have to `.forEach()` over yourself;
// the ComponentType class handles all that for you.
class Accordion extends ComponentInstance {
// Every subclass must have an `init` method to activate the component.
init() {
this.el.querySelector(".accordion--content").classList.toggle("visible");
this.el.addClass("js");
}
// You may also implement a `remove()` method to clean up when a component is
// about to be removed from the document. This will be invoked during the
// `detach()` method of the Drupal behavior.
// You can create as many other methods as you want; in all of them,
// `this.el` represents the single instance of the component. Any other
// properties you add to `this` will be isolated to that one instance
// as well.
}
// Now we instantiate ComponentType to find the component elements and run
// our script.
new ComponentType(
// First argument: The subclass of ComponentInstance we just created above.
Accordion,
// Second argument: A camel-case unique ID for the behavior (and for `once()`
// if applicable).
"accordion",
// Third argument: A selector for `querySelectorAll()`. All matching elements
// on the page get their own instance of the subclass you created, each of
// which has `this.el` pointing to one of those matches.
".accordion",
);
This is all the code required to be in each component. The ComponentType instance handles finding the elements, running them through once if available, and adding them to Drupal.behaviors.
All the objects created this way will be stored in a global variable so you can do stuff with them later. Since the namespace variable at the top of component.js is curtistinkers_themeComponents, you would find the Accordion's ComponentType instance at window.curtistinkers_themeComponents.accordion.
Furthermore, window.curtistinkers_themeComponents.accordion.instances is an array of all the ComponentInstance objects, and window.curtistinkers_themeComponents.accordion.elements is an array of all the component container elements.
Known issues
Canvas's code components are currently not compatible with Tailwind-based themes like CurtistinkersTheme, and creating a code component will break CurtistinkersTheme's styling. This will be fixed in [#3549628], but for now, here's how to work around it:
- In Canvas's in-browser code editor, open the Global CSS tab.
- Paste the contents of your custom theme's
theme.cssinto the code editor. It must be at the top. - Paste the contents of your custom theme's
main.cssinto the code editor, removing all the@importstatements at the top first. It must come after the contents oftheme.css. - Save the global CSS.
Getting help
If you have trouble or questions, please visit the issue queue or find us on Drupal Slack, in the #drupal-cms-support channel.
Roadmap
CurtistinkersTheme is under active development. Planned improvements include more components, better customization options, and Storybook support. If you want to contribute to CurtistinkersTheme, check out the #drupal-cms-development channel in Drupal Slack.