diff --git a/packages/kaizen-breakpoints/README.md b/packages/kaizen-breakpoints/README.md index b3aa388..0c89b68 100644 --- a/packages/kaizen-breakpoints/README.md +++ b/packages/kaizen-breakpoints/README.md @@ -7,9 +7,9 @@ _/ _/ _/_/_/ _/ _/_/_/_/ _/_/_/ _/ _/ -## What is this? +## What is it? -- This package contains some script which parses breakpoints from Drupal's themename/themename.breakpoints.yml and adds them into css and javascript. +- The goal of this package is to re-use `themename.breakpoints.yml` for providing same breakpoints into css and js ## Usage diff --git a/packages/kaizen-cg/README.md b/packages/kaizen-cg/README.md index 2e692c4..ce011c1 100644 --- a/packages/kaizen-cg/README.md +++ b/packages/kaizen-cg/README.md @@ -7,7 +7,7 @@ _/ _/ _/_/_/ _/ _/_/_/_/ _/_/_/ _/ _/ -## What is this? +## What is it? - This is a component generator for [kaizen-tg](https://www.npmjs.com/package/@skilld/kaizen-tg) @@ -17,6 +17,16 @@ Once [kaizen-tg](https://www.npmjs.com/package/@skilld/kaizen-tg) is installed, 1. `cd [themename_dir]` 2. `yarn cc` and follow instructions +## Structure +1. `*.js` to store javascript code related to the component +2. `*.json` to store modifiers of the component, such as default content for example +3. `*.css` to store css code related to the component +4. `*.html.twig` for templating +5. `*.stories.js` for storybook initiation + +## Should know +1. Every component's js uses Drupal.behaviors structure and it works in storybook same way as in Drupal. + ## Recommendations 1. Please follow BEM methodology when you are creating component. More about BEM's namings [here](http://getbem.com/naming/) diff --git a/packages/kaizen-cg/_templates/component/new/component-data.json b/packages/kaizen-cg/_templates/component/new/component-data.json index b30ea26..2ac6312 100644 --- a/packages/kaizen-cg/_templates/component/new/component-data.json +++ b/packages/kaizen-cg/_templates/component/new/component-data.json @@ -1,8 +1,8 @@ --- -to: <%= h.src() %>/packages/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.json +to: <%= h.src() %>/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.json --- { - "content": { + "defaultContent": { "content": "Lorem Ipsum" } } diff --git a/packages/kaizen-cg/_templates/component/new/component-script.js b/packages/kaizen-cg/_templates/component/new/component-script.js index cdb2cca..6e44ccc 100644 --- a/packages/kaizen-cg/_templates/component/new/component-script.js +++ b/packages/kaizen-cg/_templates/component/new/component-script.js @@ -1,18 +1,60 @@ --- -to: <%= h.src() %>/packages/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.js +to: <%= h.src() %>/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.js --- /** * @file * This is component script template. */ - -export default ({ - className = '<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>', - processingName = className, - context = document, -} = {}) => { - once(processingName, `.${className}`, context).forEach((el) => { - // eslint-disable-next-line no-console - console.log(el); - }); -}; +(({ behaviors }) => { + <% if (typeof themeName != 'undefined') { %>behaviors.<%= h.changeCase.snakeCase(themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %> = {<% } else { %>behaviors.<%= h.changeCase.snakeCase(h.themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %> = {<% } %> + defaultEntry: () => { + return { + className: '<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>', + processingName: 'storybook-<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>', + }; + }, + customEntry: () => { + // If you need a custom entry (in case if for example in drupal + // you have other classnames than in components - you can create + // a new .js file in src/js folder, and put into it the following + // construction: + // (({ behaviors }) => { + // <% if (typeof themeName != 'undefined') { %>behaviors.<%= h.changeCase.snakeCase(themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.customEntry = () => {<% } else { %>behaviors.<%= h.changeCase.snakeCase(h.themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.customEntry = () => {<% } %> + // return [ + // { + // ...your configuration, + // }, + // ...etc + // ]; + // }; + // })(Drupal); + // + // Then, you have to attach compiled version of your newly created + // js file to drupal. Be sure you have attached it before original + // component's js file -> because only in this case component's + // js can catch your custom entry. + }, + entries: () => { + let entries = [<% if (typeof themeName != 'undefined') { %>behaviors.<%= h.changeCase.snakeCase(themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.defaultEntry()<% } else { %>behaviors.<%= h.changeCase.snakeCase(h.themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.defaultEntry()<% } %>]; + if (<% if (typeof themeName != 'undefined') { %>behaviors.<%= h.changeCase.snakeCase(themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.customEntry()<% } else { %>behaviors.<%= h.changeCase.snakeCase(h.themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.customEntry()<% } %>) { + entries.push(...<% if (typeof themeName != 'undefined') { %>behaviors.<%= h.changeCase.snakeCase(themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.customEntry()<% } else { %>behaviors.<%= h.changeCase.snakeCase(h.themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.customEntry()<% } %>); + } + return entries; + }, + attach: (context) => { + <% if (typeof themeName != 'undefined') { %>behaviors.<%= h.changeCase.snakeCase(themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.entries().forEach((entry) => {<% } else { %>behaviors.<%= h.changeCase.snakeCase(h.themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.entries().forEach((entry) => {<% } %> + once( + entry.processingName, + `.${entry.className}`, + context, + ).forEach((el) => { + <% if (typeof themeName != 'undefined') { %>behaviors.<%= h.changeCase.snakeCase(themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.handler({ el, entry });<% } else { %>behaviors.<%= h.changeCase.snakeCase(h.themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.handler({ el, entry });<% } %> + }); + }); + }, + handler: (obj) => { + // eslint-disable-next-line no-console + console.log(obj.el); + }, + }; +})(Drupal); \ No newline at end of file diff --git a/packages/kaizen-cg/_templates/component/new/component-source.css b/packages/kaizen-cg/_templates/component/new/component-source.css index 926afdd..e1e09ab 100644 --- a/packages/kaizen-cg/_templates/component/new/component-source.css +++ b/packages/kaizen-cg/_templates/component/new/component-source.css @@ -1,5 +1,5 @@ --- -to: <%= h.src() %>/packages/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.css +to: <%= h.src() %>/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.css --- .<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %> { display: inherit; diff --git a/packages/kaizen-cg/_templates/component/new/component-template.html.twig b/packages/kaizen-cg/_templates/component/new/component-template.html.twig index 58d24ef..d0fc501 100644 --- a/packages/kaizen-cg/_templates/component/new/component-template.html.twig +++ b/packages/kaizen-cg/_templates/component/new/component-template.html.twig @@ -1,6 +1,6 @@ --- -to: <%= h.src() %>/packages/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.html.twig +to: <%= h.src() %>/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.html.twig --- -
- {{- content.content -}} +
-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>') }}> + {{- defaultContent.content -}}
diff --git a/packages/kaizen-cg/_templates/component/new/component.stories.js b/packages/kaizen-cg/_templates/component/new/component.stories.js index 891a6fd..d55313e 100644 --- a/packages/kaizen-cg/_templates/component/new/component.stories.js +++ b/packages/kaizen-cg/_templates/component/new/component.stories.js @@ -1,16 +1,15 @@ --- -to: <%= h.src() %>/packages/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.stories.js +to: <%= h.src() %>/components/<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>/<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.stories.js --- import './<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.css'; -import <%= h.inflection.camelize(name.replace(/ /g, '').replace(/-/g, '_'), true) %> from './<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.js'; +import './<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.js'; import drupalAttribute from 'drupal-attribute'; import { useEffect } from '@storybook/client-api'; - const template = require('./<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.html.twig'); const data = require('./<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>.json'); export default { - title: '<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.lower(h.inflection.dasherize(name)) %>', + title: '<%= h.changeCase.lower(h.inflection.pluralize(component_type)) %>/<%= h.changeCase.sentenceCase(name) %>', parameters: { // Uncomment next line if you need fullscreen mode // layout: 'fullscreen', @@ -19,12 +18,13 @@ export default { // uncomment next line if you want to define it. // argTypes: {}, }; - -data.svgSpritePath = window.svgSpritePath; - -export const basic = (args = {}) => { +<% if (typeof themeName != 'undefined') { %> +data.<%= h.changeCase.snakeCase(themeName) %>SvgSpritePath = window.<%= h.changeCase.snakeCase(themeName) %>SvgSpritePath; +<% } else { %> +data.<%= h.changeCase.snakeCase(h.themeName) %>SvgSpritePath = window.<%= h.changeCase.snakeCase(h.themeName) %>SvgSpritePath; +<% } %> +const basicRender = (args) => { const attributes = new drupalAttribute(); - attributes.addClass(['<%= h.changeCase.lower(component_type).charAt(0) %>-<%= h.changeCase.lower(h.inflection.dasherize(name)) %>']); if (args.attributes) { for (const [attrName, attrValue] of Object.entries(args.attributes)) { if (attrName === 'class') { @@ -39,10 +39,12 @@ export const basic = (args = {}) => { } data.attributes = attributes; useEffect(() => { - <%= h.inflection.camelize(name.replace(/ /g, '').replace(/-/g, '_'), true) %>(); + // Uncomment next line if you need javascript in your component. + <% if (typeof themeName != 'undefined') { %>// Drupal.behaviors.<%= h.changeCase.snakeCase(themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.attach();<% } else { %>// Drupal.behaviors.<%= h.changeCase.snakeCase(h.themeName) %>_storybook_<%= h.changeCase.lower(component_type).charAt(0) %>_<%= h.changeCase.snakeCase(h.inflection.dasherize(name)) %>.attach();<% } %> }, [args]); - return template({ - ...data, - ...args, - }) + return template(data) +}; + +export const basic = (args = {}) => { + return basicRender(args); }; diff --git a/packages/kaizen-cg/_templates/component/new/index.js b/packages/kaizen-cg/_templates/component/new/index.js new file mode 100644 index 0000000..e974f2d --- /dev/null +++ b/packages/kaizen-cg/_templates/component/new/index.js @@ -0,0 +1,40 @@ + +// see types of prompts: +// https://github.com/enquirer/enquirer/tree/master/examples +// +const cliArgs = process.argv.slice(2); +const themeName = cliArgs ? cliArgs.join(',').split('--theme_name=').pop().split(',')[0] : ''; + +module.exports = { + prompt: ({ inquirer, args }) => { + const askForThemeName = themeName ? '' : { + type: 'input', + name: 'themeName', + message: "What's your theme name?", + required: true + }; + const questions = [ + askForThemeName, + { + type: 'input', + name: 'name', + message: "What's your component name?", + required: true + }, + { + type: 'select', + name: 'component_type', + message: 'What type of component?', + choices: ['Atom', 'Molecule', 'Organism', 'Template', 'Helper'], + }, + { + type: 'input', + name: 'description', + message: "What's your component description?", + initial: "Component description placeholder" + } + ]; + + return inquirer.prompt(questions) + }, +} diff --git a/packages/kaizen-cg/_templates/component/new/prompt.js b/packages/kaizen-cg/_templates/component/new/prompt.js deleted file mode 100644 index 628f36a..0000000 --- a/packages/kaizen-cg/_templates/component/new/prompt.js +++ /dev/null @@ -1,25 +0,0 @@ - -// see types of prompts: -// https://github.com/enquirer/enquirer/tree/master/examples -// - -module.exports = [ - { - type: 'input', - name: 'name', - message: "What's your component name?", - required: true - }, - { - type: 'select', - name: 'component_type', - message: 'What type of component?', - choices: ['Atom', 'Molecule', 'Organism', 'Template', 'Helper'], - }, - { - type: 'input', - name: 'description', - message: "What's your component description?", - initial: "Component description placeholder" - } -] diff --git a/packages/kaizen-cg/index.js b/packages/kaizen-cg/index.js index c05b88e..d10a784 100644 --- a/packages/kaizen-cg/index.js +++ b/packages/kaizen-cg/index.js @@ -2,6 +2,9 @@ const hygen = require("hygen"); const path = require("path"); +const cliArgs = process.argv.slice(2); +const themeName = cliArgs ? cliArgs.join(',').split('--theme_name=').pop().split(',')[0] : ''; + const config = { templates: `${__dirname}/_templates`, cwd: __dirname, @@ -14,6 +17,7 @@ const config = { helpers: { relative: (from, to) => path.relative(from, to), src: () => process.cwd(), + themeName, }, }; diff --git a/packages/kaizen-cg/package.json b/packages/kaizen-cg/package.json index 158b933..b7a47fd 100644 --- a/packages/kaizen-cg/package.json +++ b/packages/kaizen-cg/package.json @@ -1,6 +1,6 @@ { "name": "@skilld/kaizen-cg", - "version": "2.0.0-alpha.3", + "version": "2.0.0-alpha.6", "description": "Kaizen component generator", "bin": "index.js", "main": "index.js", diff --git a/packages/kaizen-core/README.md b/packages/kaizen-core/README.md index 5518239..668128f 100644 --- a/packages/kaizen-core/README.md +++ b/packages/kaizen-core/README.md @@ -7,10 +7,10 @@ _/ _/ _/_/_/ _/ _/_/_/_/ _/_/_/ _/ _/ -## What is this? +## What is it? - This package contains several helper's components which we are using on every project usually. And also it contains several css files which attached globally to storybook and drupal by default. - +- This package can not be used as standalone. It's only working as a part of [kaizen-tg](https://www.npmjs.com/package/@skilld/kaizen-tg) package. ### Entity fake link helper This component helps you to easily simulate link to some wrapper, based on link inside of this wrapper. For example sometimes you need a whole teaser clickable based on its title's link-field. This script requires two data attributes added to the wrapper and to the link itself. @@ -18,30 +18,27 @@ This component helps you to easily simulate link to some wrapper, based on link Example of usage: ```
+
... Some content ...
Lorem ipsum
``` -Note that you can even skip this attribute `data-h-entity-fake-link-target` if your clickable-container contains only one link inside. The script has a fallback in that case and it will take first link in the tree if target data attribute wasn't added for the link. +Note that you can even skip this attribute `data-h-entity-fake-link-target` for your link if your clickable-container contains only one link inside. The script has a fallback in that case and it will take first link in the tree if target data attribute wasn't added for the link. In storybook you have to call this script for your story like this: ``` -import entityFakeLink from '@skilld/kaizen-core/helpers/entity-fake-link/h-entity-fake-link'; - -export const basic = (args = {}) => { - ... - useEffect(() => { - entityFakeLink(); - }, [args]); - ... -}; +useEffect(() => { + Drupal.behaviors.kaizen_core_h_entity_fake_link.attach(); +}, [args]); ``` Styles for this helper called globally for storybook, so you don't need to import them manually (but actually the styles of this component contains only `cursor: pointer;` for the wrapper) -In Drupal this helper is not added by default, so if you need it - you have to manually import this component in `src/` folder and call its js/css globally or using drupal's libraries. +If you need to use this helper in drupal - just uncomment drupal's library `h-entity-fake-link` in themename.libraries.yml and it will automatically work. + +If you need to specify your custom configuration for drupal's usage, please see how it can be done from `themename/src/js/components/h-entity-fake-link.js`. ### Focus visible helper -This script improves focus experience for the people who don't need a visual accessibility. For example a native browser's behavior when you clicking on the button - is to add a focus rings automatically around button, but what if user doesn't have a problems with health? Browser's native focus rings creates sometimes a lot of unnecessary noise and worsens perception of the site actually. So this helper component helps to show focus ring only to the people who really needs it (for example with that helper focus ring can be shown by pressing TAB key, but it will be hidden if interactive element was focused by using mouse's buttons) +This script improves focus experience for the people who don't need a visual accessibility. For example a native browser's behavior when you clicking on the button - is to add a focus rings automatically around button, but what if user doesn't have disabilities? Browser's native focus rings creates sometimes a lot of unnecessary noise and worsens perception of the site actually. So this helper component helps to show focus ring only to the people who really needs it (for example with that helper focus ring can be shown by pressing TAB key, but it will be hidden if interactive element was focused by using mouse's buttons) This helper component is included globally already in storybook, when you installing [@skilld/kaizen-tg](https://www.npmjs.com/package/@skilld/kaizen-tg) theme. And also this script is included globally in `src/` folder (so Drupal have this script loaded by default too). You don't need to do anything manually with it. diff --git a/packages/kaizen-core/_border-box.css b/packages/kaizen-core/_border-box.css index fb6c81e..b398bde 100644 --- a/packages/kaizen-core/_border-box.css +++ b/packages/kaizen-core/_border-box.css @@ -1,10 +1,7 @@ /* https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */ -html { - box-sizing: border-box; -} - +html, *, *::before, *::after { - box-sizing: inherit; + box-sizing: border-box; } diff --git a/packages/kaizen-core/helpers/entity-fake-link/entity-fake-link.css b/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.css similarity index 100% rename from packages/kaizen-core/helpers/entity-fake-link/entity-fake-link.css rename to packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.css diff --git a/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.js b/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.js index ac3dc87..a404cf8 100644 --- a/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.js +++ b/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.js @@ -4,58 +4,98 @@ * link wrapper around whole entity. */ -const fakeLinkEvents = (el, e) => { - if (e.type === 'click' || e.key === 'Enter') { - const ref = e.target != null ? e.target : e.srcElement; - if (ref && ref.tagName !== 'A') { - window.open(el.getAttribute('data-href'), el.getAttribute('data-target')); - } - } -}; +(({ behaviors }) => { + behaviors.kaizen_core_h_entity_fake_link = { + defaultEntry: () => { + return { + wrapperData: '[data-h-entity-fake-link-container]', + targetData: '[data-h-entity-fake-link-target]', + processingName: 'storybook-a-button', + }; + }, + customEntry: () => { + // If you need a custom entry (in case if for example in drupal + // you have other classnames than in components - you can create + // a new .js file in src/js folder, and put into it the following + // construction: + // (({ behaviors }) => { + // behaviors.kaizen_core_h_entity_fake_link.customEntry = () => { + // return [ + // { + // ...your configuration, + // }, + // ...etc + // ]; + // }; + // })(Drupal); + // + // Then, you have to attach compiled version of your newly created + // js file to drupal. Be sure you have attached it before original + // component's js file -> because only in this case component's + // js can catch your custom entry. + }, + entries: () => { + let entries = [behaviors.kaizen_core_h_entity_fake_link.defaultEntry()]; + if (behaviors.kaizen_core_h_entity_fake_link.customEntry()) { + entries.push(...behaviors.kaizen_core_h_entity_fake_link.customEntry()); + } + return entries; + }, + attach: (context) => { + behaviors.kaizen_core_h_entity_fake_link.entries().forEach((entry) => { + once(entry.processingName, `${entry.wrapperData}`, context).forEach( + (el) => { + // Multiple links inside of element you want to wrap is not expected + // with this script. So it searches only the first matched. + let link = el.querySelector(`a${entry.targetData}[href]`); + if (!link) { + // Fallback search. If targetData is not defined, then let's try + // to catch just first matched link. + link = el.querySelector('a[href]'); + } + if (link) { + behaviors.kaizen_core_h_entity_fake_link.handler({ el, link }); + } + }, + ); + }); + }, + handler: (obj) => { + const { el } = obj; + const { link } = obj; + el.setAttribute('data-h-entity-fake-link-built', ''); + el.setAttribute('tabindex', '0'); + el.setAttribute('role', 'link'); + el.setAttribute('data-href', link.getAttribute('href')); + el.setAttribute( + 'aria-label', + link.hasAttribute('title') + ? link.getAttribute('title') + : link.textContent.replace(/\s+/g, ' ').trim(), + ); + el.setAttribute( + 'data-target', + link.hasAttribute('target') ? link.getAttribute('target') : '_self', + ); + Array.prototype.forEach.call(el.querySelectorAll('a'), (innerLink) => { + innerLink.setAttribute('tabindex', '-1'); + }); -const fakeLinkProcessed = (el, link) => { - el.setAttribute('data-h-entity-fake-link-built', ''); - el.setAttribute('tabindex', '0'); - el.setAttribute('role', 'link'); - el.setAttribute('data-href', link.getAttribute('href')); - el.setAttribute( - 'aria-label', - link.hasAttribute('title') ? link.getAttribute('title') : link.textContent.replace(/\s+/g, ' ').trim(), - ); - el.setAttribute( - 'data-target', - link.hasAttribute('target') ? link.getAttribute('target') : '_self', - ); - Array.prototype.forEach.call(el.querySelectorAll('a'), (innerLink) => { - innerLink.setAttribute('tabindex', '-1'); - }); + el.addEventListener('click', (e) => { + behaviors.kaizen_core_h_entity_fake_link.fakeLinkEvents({ el, e }); + }); - el.addEventListener('click', (e) => { - fakeLinkEvents(el, e); - }); - - el.addEventListener('keydown', (e) => { - fakeLinkEvents(el, e); - }); -}; - -export default ({ - wrapperData = '[data-h-entity-fake-link-container]', - targetData = '[data-h-entity-fake-link-target]', - processingName = 'h-entity-fake-link', - context = document, -} = {}) => { - once(processingName, wrapperData, context).forEach((el) => { - // Multiple links inside of element you want to wrap is not expected - // with this script. So it searches only the first matched. - let link = el.querySelector(`a${targetData}[href]`); - if (!link) { - // Fallback search. If targetData is not defined, then let's try - // to catch just first matched link. - link = el.querySelector('a[href]'); - } - if (link) { - fakeLinkProcessed(el, link); - } - }); -}; \ No newline at end of file + el.addEventListener('keydown', (e) => { + behaviors.kaizen_core_h_entity_fake_link.fakeLinkEvents({ el, e }); + }); + }, + fakeLinkEvents: (obj) => { + if (obj.e.type === 'click' || obj.e.key === 'Enter') { + const ref = obj.e.target != null ? obj.e.target : obj.e.srcElement; + if (ref && ref.tagName !== 'A') { + window.open(obj.el.getAttribute('data-href'), obj.el.getAttribute('data-target')); + } + } + }, + }; +})(Drupal); diff --git a/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.md b/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.md index 8bb144b..01fdea5 100644 --- a/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.md +++ b/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.md @@ -1,3 +1,3 @@ # Helper / Entity-fake-link -This component helps to simulate link around element, which contains original link. +This component helps to simulate link around element, based on some original link. diff --git a/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.stories.js b/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.stories.js index c54c0db..ffbeb64 100644 --- a/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.stories.js +++ b/packages/kaizen-core/helpers/entity-fake-link/h-entity-fake-link.stories.js @@ -1 +1,2 @@ -import './entity-fake-link.css'; +import './h-entity-fake-link.css'; +import './h-entity-fake-link'; diff --git a/packages/kaizen-core/helpers/focus-visible/focus-visible.css b/packages/kaizen-core/helpers/focus-visible/h-focus-visible.css similarity index 100% rename from packages/kaizen-core/helpers/focus-visible/focus-visible.css rename to packages/kaizen-core/helpers/focus-visible/h-focus-visible.css diff --git a/packages/kaizen-core/helpers/focus-visible/h-focus-visible.js b/packages/kaizen-core/helpers/focus-visible/h-focus-visible.js index e479417..8620ffd 100644 --- a/packages/kaizen-core/helpers/focus-visible/h-focus-visible.js +++ b/packages/kaizen-core/helpers/focus-visible/h-focus-visible.js @@ -1,6 +1,6 @@ /** * @file - * This is Javascript slider functionality. + * This is Javascript focus-visible functionality. */ import 'focus-visible'; diff --git a/packages/kaizen-core/helpers/focus-visible/h-focus-visible.stories.js b/packages/kaizen-core/helpers/focus-visible/h-focus-visible.stories.js index 36a6fa1..ae1f0a1 100644 --- a/packages/kaizen-core/helpers/focus-visible/h-focus-visible.stories.js +++ b/packages/kaizen-core/helpers/focus-visible/h-focus-visible.stories.js @@ -1,2 +1,2 @@ -import './focus-visible.css'; +import './h-focus-visible.css'; import './h-focus-visible'; diff --git a/packages/kaizen-core/helpers/root-variables/h-root-variables.js b/packages/kaizen-core/helpers/root-variables/h-root-variables.js index 23d6262..ab0e29c 100644 --- a/packages/kaizen-core/helpers/root-variables/h-root-variables.js +++ b/packages/kaizen-core/helpers/root-variables/h-root-variables.js @@ -14,12 +14,20 @@ const hRootVariablesHandler = () => { ); }; -const body = once('h-root-variables', document.documentElement).shift(); -if (body) { - hRootVariablesHandler(); - ['load', 'resize'].forEach(event => { - window.addEventListener(event, () => { - hRootVariablesHandler(); - }); - }) -} +(({ behaviors }) => { + behaviors.kaizen_core_h_root_variables = { + attach: (context) => { + const body = once( + 'h-root-variables', + document.documentElement, + context, + ).unshift(); + if (body) { + hRootVariablesHandler(); + ['DOMContentLoaded', 'load', 'resize'].forEach((event) => + window.addEventListener(event, () => hRootVariablesHandler()), + ); + } + }, + }; +})(Drupal); diff --git a/packages/kaizen-core/helpers/root-variables/h-root-variables.stories.js b/packages/kaizen-core/helpers/root-variables/h-root-variables.stories.js index 8cce6dd..375cce3 100644 --- a/packages/kaizen-core/helpers/root-variables/h-root-variables.stories.js +++ b/packages/kaizen-core/helpers/root-variables/h-root-variables.stories.js @@ -1 +1,2 @@ import './h-root-variables'; +Drupal.behaviors.kaizen_core_h_root_variables.attach(); diff --git a/packages/kaizen-tg/README.md b/packages/kaizen-tg/README.md index fd24c5b..5dcd11d 100644 --- a/packages/kaizen-tg/README.md +++ b/packages/kaizen-tg/README.md @@ -9,17 +9,13 @@ ## Requirements -- Docker-ce - -Or - - Node.js - Yarn ## Features -- PostCss +- Postcss - Storybook - Webpack - Browsersync @@ -34,10 +30,13 @@ Or ## Usage 1. `cd web/themes/custom` -2. `npx @skilld/kaizen-tg` and follow instructions. Or alternative installation using Docker `docker run -it --rm -u $(id -u):$(id -g) -v "$PWD":/app -w /app node:lts-alpine npx @skilld/kaizen-tg` +2. `npx @skilld/kaizen-tg` 3. `cd [theme_name]` -4. `yarn && yarn build` or `make install && make build` if you want to use docker instead of local +4. `yarn install` + +## Compilation +Run `yarn build` from theme dir ## Components creation @@ -45,7 +44,7 @@ Run `yarn cc` from theme dir ## Storybook -Run `yarn storybook` from theme dir to init storybook +Run `yarn storybook` from theme dir ## Linting and fixing diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/.eslintignore b/packages/kaizen-tg/_templates/drupal-9-theme/new/.eslintignore index 950f6c9..2200005 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/.eslintignore +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/.eslintignore @@ -1,8 +1,7 @@ --- to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/.eslintignore --- -/dist/js/*.js -/dist/storybook/ +/dist/**/*.js /color/*.js postcss.config.js *.stories.js diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/.gitignore.t b/packages/kaizen-tg/_templates/drupal-9-theme/new/.gitignore.t index f748c6b..f82d027 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/.gitignore.t +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/.gitignore.t @@ -4,3 +4,4 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/.gitignore dist node_modules yarn-error.log +storybook-static diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/.storybook/preview-head.html b/packages/kaizen-tg/_templates/drupal-9-theme/new/.storybook/preview-head.html index 3a2633a..26714bc 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/.storybook/preview-head.html +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/.storybook/preview-head.html @@ -4,3 +4,4 @@ + diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/.storybook/preview.js b/packages/kaizen-tg/_templates/drupal-9-theme/new/.storybook/preview.js index d4788ba..e5b86d8 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/.storybook/preview.js +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/.storybook/preview.js @@ -8,8 +8,8 @@ import config from '../<%= h.changeCase.lower(name) %>.breakpoints.yml'; window.themeBreakpoints = config; // Import sprite. -import svgSpritePath from '../dist/svg/sprite.svg'; -window.svgSpritePath = svgSpritePath; +import svgSpritePath from '../dist/assets/sprite.svg'; +window.<%= h.changeCase.lower(name) %>SvgSpritePath = svgSpritePath; // Extend Twig.js with drupal filters. import Twig from 'twig'; @@ -17,3 +17,36 @@ import twigDrupalFilters from 'twig-drupal-filters'; import once from '@drupal/once'; window.once = once; twigDrupalFilters(Twig); + +window.Drupal = { behaviors: {} }; + +((Drupal, drupalSettings) => { + // Simplified Drupal.t() function just to be able to use such constructions + // directly from component's js behaviors. + Drupal.t = function (str) { + return str; + }; + + Drupal.throwError = function (error) { + setTimeout(function () { + throw error; + }, 0); + }; + + Drupal.attachBehaviors = function (context, settings) { + context = context || document; + settings = settings || drupalSettings; + const behaviors = Drupal.behaviors; + // Execute all of them. + Object.keys(behaviors || {}).forEach((i) => { + if (typeof behaviors[i].attach === 'function') { + // Don't stop the execution of behaviors in case of an error. + try { + behaviors[i].attach(context, settings); + } catch (e) { + Drupal.throwError(e); + } + } + }); + }; +})(Drupal, window.drupalSettings); diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/.stylelintignore b/packages/kaizen-tg/_templates/drupal-9-theme/new/.stylelintignore index d2ccd0c..694710c 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/.stylelintignore +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/.stylelintignore @@ -2,3 +2,4 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/.stylelintignore --- /color/*.css +/dist/**/*.css diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/Makefile b/packages/kaizen-tg/_templates/drupal-9-theme/new/Makefile deleted file mode 100644 index 39fa2d9..0000000 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/Makefile +++ /dev/null @@ -1,24 +0,0 @@ ---- -to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/Makefile ---- -IMAGE_FRONT = node:lts-alpine - -# Execute front container function. -front = docker run \ - --rm \ - --init \ - -v $(shell pwd):/usr/src/app -w /usr/src/app \ - -w /usr/src/app \ - $(IMAGE_FRONT) ${1} - -# Build front tasks. -install: - @echo "Installing dependencies..." - $(call front, yarn install --ignore-optional --prod) - -build: - $(call front, yarn build --verbose) - -lint: - $(call front, yarn lint-fix) - diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/README.md.t b/packages/kaizen-tg/_templates/drupal-9-theme/new/README.md.t new file mode 100644 index 0000000..5d30999 --- /dev/null +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/README.md.t @@ -0,0 +1,53 @@ +--- +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/README.md +--- +# <%= h.changeCase.sentenceCase(name) %> + +This theme was generated using [kaizen-tg](https://www.npmjs.com/package/@skilld/kaizen-tg) package. + +## Requirements + +- Node.js +- Yarn + + +## Features + +- Postcss +- Storybook +- Webpack +- Browsersync +- eslint +- stylelint +- Autoprefixer +- Drupal Color Module support +- Drupal breakpoints.yml config parser in css/js +- Svg sprite generation +- Several basic helpers which improves quality and perception of the web-sites. [Read more](https://www.npmjs.com/package/@skilld/kaizen-core) + +# Usage + +### Compilation + +Run `yarn build` from theme dir or `yarn build-dev` for development mode + +### Components creation + +Run `yarn cc` from theme dir + +### Storybook + +Run `yarn storybook` from theme dir + +### Linting and fixing + +Run `yarn lint-fix` from theme dir + +## Documentation about other related kaizen's packages. +1. [kaizen-cg](https://www.npmjs.com/package/@skilld/kaizen-cg) +2. [kaizen-core](https://www.npmjs.com/package/@skilld/kaizen-core) +3. [kaizen-breakpoints](https://www.npmjs.com/package/@skilld/kaizen-breakpoints) + +# License + +This project is licensed under the MIT open source license. diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/assets/fonts/README.txt.t b/packages/kaizen-tg/_templates/drupal-9-theme/new/assets/fonts/README.txt.t new file mode 100644 index 0000000..88008d0 --- /dev/null +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/assets/fonts/README.txt.t @@ -0,0 +1,4 @@ +--- +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/assets/fonts/README.txt +--- +Place your fonts here. diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/images/svg/test.svg.t b/packages/kaizen-tg/_templates/drupal-9-theme/new/assets/images/svg/test.svg.t similarity index 93% rename from packages/kaizen-tg/_templates/drupal-9-theme/new/images/svg/test.svg.t rename to packages/kaizen-tg/_templates/drupal-9-theme/new/assets/images/svg/test.svg.t index 4c3a5f6..e418b61 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/images/svg/test.svg.t +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/assets/images/svg/test.svg.t @@ -1,5 +1,5 @@ --- -to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/images/svg/test.svg +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/assets/images/svg/test.svg --- diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_colors.css b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_colors.css similarity index 55% rename from packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_colors.css rename to packages/kaizen-tg/_templates/drupal-9-theme/new/components/_colors.css index ec4c294..b746f4e 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_colors.css +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_colors.css @@ -1,5 +1,5 @@ --- -to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/packages/components/_colors.css +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/components/_colors.css --- /* Functional colors */ diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_typography.css b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_root.css similarity index 65% rename from packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_typography.css rename to packages/kaizen-tg/_templates/drupal-9-theme/new/components/_root.css index 15be234..b3a8595 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_typography.css +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_root.css @@ -1,5 +1,5 @@ --- -to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/packages/components/_typography.css +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/components/_root.css --- html { font-size: var(--root-font-size); diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_typography.css b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_typography.css new file mode 100644 index 0000000..1250be1 --- /dev/null +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_typography.css @@ -0,0 +1,4 @@ +--- +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/components/_typography.css +--- +/* ---------- Connect your fonts here ----------- */ diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_variables.css b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_variables.css similarity index 56% rename from packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_variables.css rename to packages/kaizen-tg/_templates/drupal-9-theme/new/components/_variables.css index 9164ce8..435e854 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/_variables.css +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/_variables.css @@ -1,5 +1,5 @@ --- -to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/packages/components/_variables.css +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/components/_variables.css --- :root { --root-font-size: 2vw; diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/globals.stories.js b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/globals.stories.js similarity index 97% rename from packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/globals.stories.js rename to packages/kaizen-tg/_templates/drupal-9-theme/new/components/globals.stories.js index 9a52217..f9e5d20 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/globals.stories.js +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/globals.stories.js @@ -1,10 +1,10 @@ --- -to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/packages/components/globals.stories.js +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/components/globals.stories.js --- import { useEffect, useState } from '@storybook/client-api'; const component = { - title: 'globals/variables', + title: 'globals/Variables', }; export default component; diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/package.json b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/package.json similarity index 68% rename from packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/package.json rename to packages/kaizen-tg/_templates/drupal-9-theme/new/components/package.json index 133f525..f92d7d9 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/packages/components/package.json +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/components/package.json @@ -1,5 +1,5 @@ --- -to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/packages/components/package.json +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/components/package.json --- { "name": "@<%= h.changeCase.lower(name) %>/components", diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/fonts/README.txt.t b/packages/kaizen-tg/_templates/drupal-9-theme/new/fonts/README.txt.t deleted file mode 100644 index 498d3f3..0000000 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/fonts/README.txt.t +++ /dev/null @@ -1,4 +0,0 @@ ---- -to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/fonts/README.txt ---- -Place your fonts here. diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen-options.js b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen-options.js index 897ae53..c2dac40 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen-options.js +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen-options.js @@ -10,27 +10,31 @@ let options = {}; options.rootPath = { project: `${__dirname}/`, + storybook: `${__dirname}/components/`, src: `${__dirname}/src/`, dist: `${__dirname}/dist/`, }; options.theme = { name: '<%= h.changeCase.lower(name) %>', - css: `${options.rootPath.src}css/`, - js: `${options.rootPath.src}js/`, + storybook: `${options.rootPath.storybook}**/**/`, + drupalCss: `${options.rootPath.src}css/`, + drupalJs: `${options.rootPath.src}js/`, }; options.cssFiles = { - components: `${options.theme.css}**/*.css`, - ignore: `${options.theme.css}**/_*.css`, + storybookComponents: `${options.theme.storybook}*.css`, + storybookIgnore: `${options.theme.storybook}_*.css`, + drupalComponents: `${options.theme.drupalCss}**/*.css`, + drupalIgnore: `${options.theme.drupalCss}**/_*.css`, }; options.jsFiles = { - components: `${options.theme.js}**/*.js`, + storybookComponents: `${options.theme.storybook}*.js`, + storybookIgnore: `${options.theme.storybook}*.stories.js`, + drupalComponents: `${options.theme.drupalJs}**/*.js`, }; -options.buildAssets = `${options.rootPath.project}scripts/assets/`; - options.postCssConfigDirectory = `${options.rootPath.project}`; // Check if this is primary theme with own config overrides. diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.breakpoints.yml b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.breakpoints.yml index e737217..0f339e5 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.breakpoints.yml +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.breakpoints.yml @@ -11,7 +11,7 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/<%= h.changeCase.lower(name) - 2x <%= h.changeCase.lower(name) %>.s: label: s - mediaQuery: 'all and (min-width: 480px)' + mediaQuery: 'all and (min-width: 481px)' weight: 10 group: <%= h.changeCase.lower(name) %> multipliers: @@ -19,7 +19,7 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/<%= h.changeCase.lower(name) - 2x <%= h.changeCase.lower(name) %>.m: label: m - mediaQuery: 'all and (min-width: 768px)' + mediaQuery: 'all and (min-width: 769px)' weight: 20 group: <%= h.changeCase.lower(name) %> multipliers: @@ -27,7 +27,7 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/<%= h.changeCase.lower(name) - 2x <%= h.changeCase.lower(name) %>.l: label: l - mediaQuery: 'all and (min-width: 1024px)' + mediaQuery: 'all and (min-width: 1025px)' weight: 30 group: <%= h.changeCase.lower(name) %> multipliers: @@ -35,7 +35,7 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/<%= h.changeCase.lower(name) - 2x <%= h.changeCase.lower(name) %>.xl: label: xl - mediaQuery: 'all and (min-width: 1440px)' + mediaQuery: 'all and (min-width: 1441px)' weight: 40 group: <%= h.changeCase.lower(name) %> multipliers: @@ -43,7 +43,7 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/<%= h.changeCase.lower(name) - 2x <%= h.changeCase.lower(name) %>.xxl: label: xxl - mediaQuery: 'all and (min-width: 1920px)' + mediaQuery: 'all and (min-width: 1921px)' weight: 50 group: <%= h.changeCase.lower(name) %> multipliers: diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.info.yml b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.info.yml index 6a7cbb3..46b4577 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.info.yml +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.info.yml @@ -1,7 +1,7 @@ --- to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/<%= h.changeCase.lower(name) %>.info.yml --- -name: <%= name %> +name: <%= h.changeCase.sentenceCase(name) %> type: theme base theme: false description: <%= description %> diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.libraries.yml b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.libraries.yml index d9888ad..b3f0fa9 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.libraries.yml +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.libraries.yml @@ -6,9 +6,9 @@ base: theme: color/colors.css: {} base: - dist/css/styles.css: {} + dist/css/drupal/styles.css: {} js: - dist/js/init.js: {} + dist/js/drupal/init.js: {} dependencies: - core/drupal - core/once @@ -21,3 +21,11 @@ color.preview: color/preview.js: {} dependencies: - color/drupal.color + +# Uncomment next library if you need entity-fake-link functionality +#h-entity-fake-link: +# css: +# component: +# dist/css/drupal/h-entity-fake-link.css: {} +# js: +# dist/js/drupal/h-entity-fake-link.js: {} diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.theme b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.theme index 7f3539e..5101ceb 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.theme +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/kaizen.theme @@ -12,13 +12,13 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/<%= h.changeCase.lower(name) * Returns path to svg sprite. */ function _<%= h.changeCase.lower(name) %>_get_svg_sprite_path() { - return base_path() . \Drupal::theme()->getActiveTheme()->getPath() . '/dist/svg/sprite.svg'; + return base_path() . \Drupal::theme()->getActiveTheme()->getPath() . '/dist/assets/sprite.svg'; } /** * Hook_page_attachments(). * - * Prepares <%= h.changeCase.lower(name) %>_svg_sprite_path variable to get + * Prepares <%= h.changeCase.lower(name) %>SvgSpritePath variable to get * full path to svg sprite from js. */ function <%= h.changeCase.lower(name) %>_page_attachments_alter(array &$attachments) { @@ -39,9 +39,9 @@ function <%= h.changeCase.lower(name) %>_page_attachments_alter(array &$attachme /** * Hook_preprocess(). * - * Prepares <%= h.changeCase.lower(name) %>_svg_sprite_path variable to get + * Prepares <%= h.changeCase.lower(name) %>SvgSpritePath variable to get * full path to svg sprite from twig. */ function <%= h.changeCase.lower(name) %>_preprocess(&$variables, $hook) { - $variables['<%= h.changeCase.lower(name) %>_svg_sprite_path'] = _<%= h.changeCase.lower(name) %>_get_svg_sprite_path(); + $variables['<%= h.changeCase.lower(name) %>SvgSpritePath'] = _<%= h.changeCase.lower(name) %>_get_svg_sprite_path(); } diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/package.json.t b/packages/kaizen-tg/_templates/drupal-9-theme/new/package.json.t index 943034e..d66170f 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/package.json.t +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/package.json.t @@ -9,12 +9,13 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/package.json "author": "Skilld", "license": "MIT", "devDependencies": { - "@skilld/kaizen-cg": "^2.0.0-alpha.3", + "@skilld/kaizen-cg": "^2.0.0-alpha.4", "@storybook/addon-essentials": "^6.4.19", "@storybook/addon-postcss": "^2.0.0", "@storybook/builder-webpack5": "^6.4.19", "@storybook/html": "^6.4.19", "@storybook/manager-webpack5": "^6.4.19", + "clean-webpack-plugin": "^4.0.0", "browser-sync": "^2.27.9", "drupal-attribute": "^1.0.2", "react": "^17.0.2", @@ -28,6 +29,7 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/package.json "@skilld/kaizen-breakpoints": "^2.0.0-alpha.3", "@skilld/kaizen-core": "^2.0.0-alpha.3", "autoprefixer": "^10.4.4", + "copy-webpack-plugin": "^11.0.0", "cross-env": "^7.0.3", "css-loader": "^6.7.1", "eslint": "^8.9.0", @@ -39,7 +41,6 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/package.json "extract-loader": "^5.1.0", "file-loader": "^6.2.0", "glob": "^7.2.0", - "mini-css-extract-plugin": "^2.6.0", "npm-run-all": "^4.1.5", "postcss": "^8.4.12", "postcss-cli": "^9.1.0", @@ -55,12 +56,12 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/package.json "stylelint-config-standard": "^25.0.0", "stylelint-order": "^5.0.0", "svg-sprite-loader": "^6.0.11", - "terser-webpack-plugin": "^5.3.1", "webpack": "^5.70.0", "webpack-cli": "^4.9.2" }, "scripts": { "build": "cross-env ./node_modules/.bin/webpack", + "build-dev": "cross-env NODE_ENV=development ./node_modules/.bin/webpack", "lint": "cross-env ./node_modules/.bin/run-p lint:*", "lint-fix": "cross-env ./node_modules/.bin/run-p \"lint:* --fix\"", "lint:js": "node ./node_modules/eslint/bin/eslint.js .", @@ -69,12 +70,12 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/package.json "browsersync": "yarn run browser-sync start --proxy '127.0.0.1:8888' --files ./dist", "watch": "cross-env ./node_modules/.bin/webpack -w", "watch:bs": "cross-env NODE_ENV=development ./node_modules/.bin/run-p browsersync watch", - "cc": "npx @skilld/kaizen-cg", + "cc": "npx @skilld/kaizen-cg --theme_name=<%= h.changeCase.snakeCase(name) %>", "storybook": "start-storybook", "build-storybook": "build-storybook -c .storybook -o dist/storybook" }, "private": true, "workspaces": [ - "packages/*" + "components" ] } diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/postcss.config.js b/packages/kaizen-tg/_templates/drupal-9-theme/new/postcss.config.js index 52ba519..26eb03c 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/postcss.config.js +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/postcss.config.js @@ -15,7 +15,20 @@ module.exports = () => ({ map: false, plugins: [ postcssImport(), - postcssUrl(), + postcssUrl([ + { + url: 'inline', + filter: (asset) => { + return ['png', 'jpg', 'jpeg', 'svg', 'gif', 'webp', 'avif'].includes(asset.url.split('.').pop()); + }, + }, + { + url: 'rebase', + filter: (asset) => { + return !['png', 'jpg', 'jpeg', 'svg', 'gif', 'webp', 'avif'].includes(asset.url.split('.').pop()); + }, + }, + ]), postCssDrupalBreakpoints({ importFrom: './<%= h.changeCase.lower(name) %>.breakpoints.yml', themeName: '<%= h.changeCase.lower(name) %>', diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/src/css/components/h-entity-fake-link.css b/packages/kaizen-tg/_templates/drupal-9-theme/new/src/css/components/h-entity-fake-link.css new file mode 100644 index 0000000..5bb58e6 --- /dev/null +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/src/css/components/h-entity-fake-link.css @@ -0,0 +1,4 @@ +--- +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/src/css/components/h-entity-fake-link.css +--- +@import "@skilld/kaizen-core/helpers/entity-fake-link/h-entity-fake-link"; diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/src/css/styles.css b/packages/kaizen-tg/_templates/drupal-9-theme/new/src/css/styles.css index 7f108e5..9e6bed8 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/src/css/styles.css +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/src/css/styles.css @@ -7,3 +7,5 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/src/css/styles.css @import "@<%= h.changeCase.lower(name) %>/components/_colors"; @import "@<%= h.changeCase.lower(name) %>/components/_typography"; @import "@<%= h.changeCase.lower(name) %>/components/_variables"; +@import "@<%= h.changeCase.lower(name) %>/components/_root"; +@import "@skilld/kaizen-core/helpers/focus-visible/h-focus-visible"; diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/src/js/components/h-entity-fake-link.js b/packages/kaizen-tg/_templates/drupal-9-theme/new/src/js/components/h-entity-fake-link.js new file mode 100644 index 0000000..52c238b --- /dev/null +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/src/js/components/h-entity-fake-link.js @@ -0,0 +1,16 @@ +--- +to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/src/js/components/h-entity-fake-link.js +--- +import '@skilld/kaizen-core/helpers/entity-fake-link/h-entity-fake-link'; + +// Uncomment next behavior if you need custom entity-fake-link functionality. +// (({ behaviors }) => { +// behaviors.kaizen_core_h_entity_fake_link.customEntry = () => { +// return [ +// { +// ...your configuration, +// }, +// ...etc +// ]; +// }; +// })(Drupal); diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/src/js/init.js b/packages/kaizen-tg/_templates/drupal-9-theme/new/src/js/init.js index c31cbee..a4fa2f9 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/src/js/init.js +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/src/js/init.js @@ -1,8 +1,16 @@ --- to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/src/js/init.js --- -import { initBreakpointsCssReload } from '@skilld/kaizen-breakpoints'; +import '@skilld/kaizen-core/helpers/focus-visible/h-focus-visible'; +import '@skilld/kaizen-core/helpers/root-variables/h-root-variables'; import config from '../../<%= h.changeCase.lower(name) %>.breakpoints.yml'; window.themeBreakpoints = config; -initBreakpointsCssReload(config); + +(({ behaviors }) => { + behaviors.<%= h.changeCase.lower(name) %>SvgSpritePath = { + attach: (context, settings) => { + window.<%= h.changeCase.lower(name) %>SvgSpritePath = settings.<%= h.changeCase.lower(name) %>SvgSpritePath; + }, + }; +})(Drupal); \ No newline at end of file diff --git a/packages/kaizen-tg/_templates/drupal-9-theme/new/webpack.config.js b/packages/kaizen-tg/_templates/drupal-9-theme/new/webpack.config.js index a853c66..eec351f 100644 --- a/packages/kaizen-tg/_templates/drupal-9-theme/new/webpack.config.js +++ b/packages/kaizen-tg/_templates/drupal-9-theme/new/webpack.config.js @@ -8,30 +8,49 @@ to: <%= h.src() %>/<%= h.changeCase.lower(name) %>/webpack.config.js const glob = require('glob'); const path = require('path'); const SpriteLoaderPlugin = require('svg-sprite-loader/plugin'); -const TerserPlugin = require('terser-webpack-plugin'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); +const CopyPlugin = require('copy-webpack-plugin'); const options = require('./<%= h.changeCase.lower(name) %>-options'); const mapJSFilenamesToEntries = (pattern, globOptions) => glob.sync(pattern, globOptions).reduce((entries, filename) => { const [, name] = filename.match(/([^/]+)\.js$/); + const entryName = filename.includes(options.rootPath.storybook) + ? `js/storybook/${name}/${name}` + : `js/drupal/${name}`; return { ...entries, - [name]: filename, + [entryName]: filename, }; }, {}); +const entries = { + 'entries/sprite': glob.sync(path.resolve(__dirname, 'assets/images/svg/**/*.svg')), + 'entries/drupalStyles': glob.sync( + options.cssFiles.drupalComponents, + options.cssFiles.drupalIgnore, + ), + ...mapJSFilenamesToEntries(options.jsFiles.drupalComponents, {}), + ...mapJSFilenamesToEntries(options.jsFiles.storybookComponents, { + ignore: options.jsFiles.storybookIgnore, + }), +}; + +const storybookStyles = glob.sync(options.cssFiles.storybookComponents, { + ignore: options.cssFiles.storybookIgnore, +}); + +if (storybookStyles.length) { + entries['entries/storybookStyles'] = storybookStyles; +} + module.exports = { - entry: { - sprite: glob.sync(path.resolve(__dirname, 'images/svg/**/*.svg')), - styles: glob.sync(options.cssFiles.components, options.cssFiles.ignore), - ...mapJSFilenamesToEntries(options.jsFiles.components, {}), - }, + entry: entries, output: { path: options.rootPath.dist, - filename: 'js/[name].js', + filename: '[name].js', }, - mode: 'production', + mode: process.env.NODE_ENV === 'development' ? process.env.NODE_ENV : 'production', module: { rules: [ { @@ -48,7 +67,11 @@ module.exports = { { loader: 'file-loader', options: { - name: 'css/[name].css', + name(resourcePath) { + return resourcePath.includes(options.rootPath.storybook) + ? 'css/storybook/[name].css' + : 'css/drupal/[name].css'; + }, sourceMap: process.env.NODE_ENV === 'development', }, }, @@ -79,10 +102,11 @@ module.exports = { { loader: 'svg-sprite-loader', options: { + publicPath: 'assets/', extract: true, symbolId: (filePath) => `svg-${path.basename(filePath.slice(0, -4))}`, - publicPath: 'svg/', + name: 'sprite.svg', }, }, ], @@ -93,21 +117,23 @@ module.exports = { new SpriteLoaderPlugin({ plainSprite: true, }), - new MiniCssExtractPlugin({ - filename: './dist/css/[name].css', + new CopyPlugin({ + patterns: [ + { + from: path.resolve(__dirname, 'assets/fonts'), + to: path.resolve(__dirname, 'dist/assets/fonts'), + noErrorOnMissing: true, + globOptions: { + ignore: ['**/*.txt'], + }, + }, + ], + }), + new CleanWebpackPlugin({ + cleanAfterEveryBuildPatterns: ['entries/'], }), ], optimization: { - minimize: true, - minimizer: [ - new TerserPlugin({ - extractComments: true, - terserOptions: { - mangle: { - reserved: ['Drupal'], - }, - }, - }), - ], + minimize: false, }, };