diff --git a/ui/npm-shrinkwrap.json b/ui/npm-shrinkwrap.json index 5880caf..ebb0104 100644 --- a/ui/npm-shrinkwrap.json +++ b/ui/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "web-ui-boilerplate", - "version": "2.3.0", + "version": "2.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "web-ui-boilerplate", - "version": "2.3.0", + "version": "2.4.0", "license": "ISC", "dependencies": { "dialog-polyfill": "^0.5.6" diff --git a/ui/package.json b/ui/package.json index 0d7bb4c..694591d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -2,7 +2,7 @@ "name": "web-ui-boilerplate", "description": "UI boilerplate for websites/webapps using vanilla HTML/CSS/JavaScript, powered by Storybook, bundled by Parcel.", "author": "basher", - "version": "2.3.0", + "version": "2.4.0", "license": "ISC", "repository": { "type": "git", diff --git a/ui/src/javascript/modules/message.ts b/ui/src/javascript/modules/message.ts deleted file mode 100644 index 863398a..0000000 --- a/ui/src/javascript/modules/message.ts +++ /dev/null @@ -1,30 +0,0 @@ -export default class Message { - private message: Element; - private btnClose: HTMLButtonElement | null; - - constructor(message: Element) { - this.message = message; - this.btnClose = this.message.querySelector( - '[data-button="message-close"]', - ); - - this.init(); - } - - public static start(): void { - const messages = document.querySelectorAll('[data-module="message"]'); - - messages.forEach((message) => { - const instance = new Message(message); - return instance; - }); - } - - private init(): void { - this.btnClose?.addEventListener('click', () => this.closeMessage()); - } - - private closeMessage(): void { - this.message.setAttribute('hidden', ''); - } -} diff --git a/ui/src/javascript/ui-init.ts b/ui/src/javascript/ui-init.ts index fb66961..294f161 100644 --- a/ui/src/javascript/ui-init.ts +++ b/ui/src/javascript/ui-init.ts @@ -1,7 +1,6 @@ // Dependencies. // 1. Modules. import FormValidate from './modules/form-validate'; -import Message from './modules/message'; import Prose from './modules/prose'; import RangeSlider from './modules/range-slider'; import Search from './modules/search'; @@ -17,11 +16,11 @@ import demoAjaxFetchHTML from './modules/demo-ajax-fetch-html'; import WebUIDisclosure from './web-components/webui-disclosure'; import WebUIMakeClickable from './web-components/webui-make-clickable'; import WebUIModal from './web-components/webui-modal'; +import WebUINotification from './web-components/webui-notification'; import WebUIShare from './web-components/webui-share'; export const uiInit = (): void => { FormValidate.start(); - Message.start(); RangeSlider.start(); Search.start(); Slider.start(); @@ -40,6 +39,8 @@ export const uiInit = (): void => { customElements.define('webui-make-clickable', WebUIMakeClickable); !customElements.get('webui-modal') && customElements.define('webui-modal', WebUIModal); + !customElements.get('webui-notification') && + customElements.define('webui-notification', WebUINotification); !customElements.get('webui-share') && customElements.define('webui-share', WebUIShare); }; diff --git a/ui/src/javascript/web-components/webui-make-clickable.ts b/ui/src/javascript/web-components/webui-make-clickable.ts index 7ec6df5..6a37e04 100644 --- a/ui/src/javascript/web-components/webui-make-clickable.ts +++ b/ui/src/javascript/web-components/webui-make-clickable.ts @@ -3,9 +3,7 @@ export default class WebUIMakeClickable extends HTMLElement { constructor() { super(); - this.link = this.querySelector('[data-url]') || this.querySelector('a'); - this.addEventListener('click', this); } diff --git a/ui/src/javascript/web-components/webui-notification.ts b/ui/src/javascript/web-components/webui-notification.ts new file mode 100644 index 0000000..f9d8481 --- /dev/null +++ b/ui/src/javascript/web-components/webui-notification.ts @@ -0,0 +1,14 @@ +export default class WebUIMakeNotification extends HTMLElement { + private btnClose: HTMLButtonElement | null; + + constructor() { + super(); + this.btnClose = this.querySelector('[data-close]'); + this.btnClose?.addEventListener('click', this); + } + + // Handle web component events from constructor(). + handleEvent() { + this.setAttribute('hidden', ''); + } +} diff --git a/ui/src/stylesheets/components/_index.scss b/ui/src/stylesheets/components/_index.scss index e827ed9..c21c6fd 100644 --- a/ui/src/stylesheets/components/_index.scss +++ b/ui/src/stylesheets/components/_index.scss @@ -7,7 +7,6 @@ @use 'card'; @use 'image'; @use 'image-gallery'; -@use 'message'; @use 'nav'; @use 'pagination'; @use 'prose'; diff --git a/ui/src/stylesheets/web-components/_index.scss b/ui/src/stylesheets/web-components/_index.scss index f3cd53c..6ce7e04 100644 --- a/ui/src/stylesheets/web-components/_index.scss +++ b/ui/src/stylesheets/web-components/_index.scss @@ -1,4 +1,5 @@ @use 'webui-disclosure'; @use 'webui-make-clickable'; @use 'webui-modal'; +@use 'webui-notification'; @use 'webui-share'; diff --git a/ui/src/stylesheets/components/_message.scss b/ui/src/stylesheets/web-components/_webui-notification.scss similarity index 89% rename from ui/src/stylesheets/components/_message.scss rename to ui/src/stylesheets/web-components/_webui-notification.scss index 29557f4..74c9519 100644 --- a/ui/src/stylesheets/components/_message.scss +++ b/ui/src/stylesheets/web-components/_webui-notification.scss @@ -6,7 +6,7 @@ Dependencies. @use '../base' as *; @use '../mixins' as *; -.message { +webui-notification { align-items: flex-start; border: $border-width-s solid; display: flex; @@ -17,22 +17,22 @@ Dependencies. max-inline-size: none; } - &--success { + &[data-success] { background: hsl(var(--color-accent-positive) / 15%); border-color: $color-success; } - &--warning { + &[data-warning] { background: hsl(var(--color-accent-neutral) / 15%); border-color: $color-notify; } - &--error { + &[data-error] { background: hsl(var(--color-accent-negative) / 15%); border-color: $color-error; } - &__close { + [data-close] { font-size: $icon-size-s; inset-block-start: calc($icon-size-s * -1); inset-inline-end: calc($icon-size-s * -1); diff --git a/ui/stories/3. Layout/Flex/Flex.js b/ui/stories/3. Layout/Flex/Flex.js index c847d31..70b5a6b 100644 --- a/ui/stories/3. Layout/Flex/Flex.js +++ b/ui/stories/3. Layout/Flex/Flex.js @@ -10,14 +10,13 @@ const style = ` export const FlexHtml = (args) => ` ${style} -
+ ${args.direction === undefined ? '' : `flex--${args.direction}`} + ${args.gap === undefined ? '' : `flex--${args.gap}`} + ${args.alignItems === undefined ? '' : `flex--${args.alignItems}`} + ${args.justifyContent === undefined ? '' : `flex--${args.justifyContent}`} +">
Flex item 1 - lots more content

to demonstrate (default) equal height columns
Flex item 2
diff --git a/ui/stories/3. Layout/Grid/Grid.js b/ui/stories/3. Layout/Grid/Grid.js index 18070a5..2e86d56 100644 --- a/ui/stories/3. Layout/Grid/Grid.js +++ b/ui/stories/3. Layout/Grid/Grid.js @@ -17,7 +17,7 @@ const style = ` export const GridHtml = (args) => ` ${style}

Try removing grid items via devtools to see how grid auto-arranges itself.

-
+
Grid item 1 - lots more content

to demonstrate (default) equal height columns
Grid item 2
@@ -32,7 +32,7 @@ ${style}

Use semantic <ul> if it makes sense to have a list of related items rendered in a grid.

For example, a gallery of images, or a collection of product cards.

-
    +
    • Grid item 1 - lots more content

      to demonstrate (default) equal height columns
    • Grid item 2
    • @@ -45,14 +45,14 @@ ${style} export const Grid2EqualColsHtml = (args) => ` ${style}

      Divide a page (or section of a page) into equal width columns, etc.

      -
      +
      Col 1
      Col 2

      And here's another grid on same page.

      -
      +
      Col 1
      Col 2
      @@ -60,7 +60,7 @@ ${style}

      What if you really want 2 columns on small screens?
      Use the grid--2-cols@small classname to override the grid-template-columns.

      -
      +
      Col 1
      Col 2
      @@ -69,7 +69,7 @@ Use the grid--2-cols@small classname to override the grid-tem export const Grid3EqualColsHtml = (args) => ` ${style}

      Divide a page (or section of a page) into equal width columns, etc.

      -
      +
      Col 1
      Col 2
      Col 3
      @@ -77,7 +77,7 @@ ${style}

      And here's another grid on same page.

      -
      +
      Col 1
      Col 2
      Col 3
      @@ -89,7 +89,7 @@ ${style}

      All these examples use container queries in supported browsers, rather than media queries.

      -
      +
      Asymmetric col 1
      Default width = 66.66% @@ -102,7 +102,7 @@ ${style}
      -
      +
      Asymmetric col 1
      Override width = 75% @@ -115,7 +115,7 @@ ${style}
      -
      +
      Asymmetric col 1
      Override width = 25% diff --git a/ui/stories/5. Components/Message/Message.mdx b/ui/stories/5. Components/Message/Message.mdx deleted file mode 100644 index d99795b..0000000 --- a/ui/stories/5. Components/Message/Message.mdx +++ /dev/null @@ -1,8 +0,0 @@ -import { Meta, Canvas, Controls } from '@storybook/blocks'; -import * as Message from './Message.stories'; - - - -# Message - - diff --git a/ui/stories/5. Components/Message/Message.stories.js b/ui/stories/5. Components/Message/Message.stories.js deleted file mode 100644 index 952de15..0000000 --- a/ui/stories/5. Components/Message/Message.stories.js +++ /dev/null @@ -1,23 +0,0 @@ -import { MessageTemplate } from './Message'; - -export default { - title: 'Components/Message', - parameters: { - status: { - type: 'stable', - }, - }, - argTypes: { - messageType: { - control: 'select', - options: ['success', 'warning', 'error'], - }, - hasCloseButton: { - control: 'boolean', - }, - }, -}; - -export const Message = { - render: (args) => MessageTemplate(args), -}; diff --git a/ui/stories/5. Components/Notification/Notification.mdx b/ui/stories/5. Components/Notification/Notification.mdx new file mode 100644 index 0000000..e5a7b90 --- /dev/null +++ b/ui/stories/5. Components/Notification/Notification.mdx @@ -0,0 +1,6 @@ +import { Meta } from '@storybook/blocks'; + + + +# Notification +- See the [``](/docs/web-components-or-custom-elements-webui-notification--docs) custom element. diff --git a/ui/stories/5. Components/Message/Message.js b/ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.js similarity index 72% rename from ui/stories/5. Components/Message/Message.js rename to ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.js index 923d157..974a80a 100644 --- a/ui/stories/5. Components/Message/Message.js +++ b/ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.js @@ -1,5 +1,8 @@ -export const MessageTemplate = (args) => ` -
      +export const WebUINotificationHtml = (args) => ` +

      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

      Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur?

      @@ -9,7 +12,7 @@ export const MessageTemplate = (args) => ` ? `` : '' } -
      +
      `; diff --git a/ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.mdx b/ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.mdx new file mode 100644 index 0000000..0041747 --- /dev/null +++ b/ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.mdx @@ -0,0 +1,13 @@ +import { Meta, Canvas, Controls } from '@storybook/blocks'; +import * as WebUINotification from './WebUINotification.stories'; + + + +# `` + +## Accessibility considerations +- Error notifications have an ARIA `role="error"`. +- Other notifications have an ARIA `role="status"`. + + + diff --git a/ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.stories.js b/ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.stories.js new file mode 100644 index 0000000..2a5516e --- /dev/null +++ b/ui/stories/6. Web Components Or Custom Elements/WebUINotification/WebUINotification.stories.js @@ -0,0 +1,24 @@ +import { WebUINotificationHtml } from './WebUINotification'; + +export default { + title: 'Web Components Or Custom Elements/', + parameters: { + status: { + type: 'stable', + }, + }, + argTypes: { + notificationType: { + control: 'select', + options: ['success', 'warning', 'error'], + }, + hasCloseButton: { + control: 'boolean', + }, + }, +}; + +export const WebUINotification = { + render: (args) => WebUINotificationHtml(args), +}; +WebUINotification.storyName = '';