Skip to content

Commit

Permalink
BREAKING CHANGE(web): Add spirit infix to data attr names for compo…
Browse files Browse the repository at this point in the history
…nents and JS plugins #DS-585

 ## Migration Guide

Add `spirit` to all data-api attributes of affected components.

- `data-toggle="collapse"` → `data-spirit-toggle="collapse"`

List of affected components:
- Accordion
- Collapse
- Dropdown
- FileUploader
- Header
- Modal
- ScrollView
- Tabs
- TextArea
- TextField
- Tooltip

List of affected JS plugins:
- Collapse
- Dropdown
- FileUploader
- Header
- Modal
- Offcanvas
- Tabs
- Tooltip

To make everything work, you have to make these changes:

 ### Accordion

- `<section class="Accordion" data-toggle="accordion" …>`
→ `<section class="Accordion" data-spirit-toggle="accordion" …>`
- `<button class="Accordion__itemToggle" data-toggle="collapse"
data-target="target-id" …>` → `<button class="Accordion__itemToggle"
data-spirit-toggle="collapse" data-spirit-target="target-id" …>`

 ### Collapse

- `<button data-toggle="collapse" data-target="target-id" …>`
→ `<button data-spirit-toggle="collapse" data-spirit-target="target-id" …>`
- `<div id="target-id" class="Collapse" data-parent="#parent-id" …>`
→ `<div id="target-id" class="Collapse" data-spirit-parent="#parent-id" …>`
- `<div class="Collapse" data-breakpoint="tablet" …>`
→ `<div class="Collapse" data-spirit-breakpoint="tablet" …>`
- `<a data-toggle="collapse" data-more …>`
→ `<a data-spirit-toggle="collapse" data-spirit-more …>`

 ### Dropdown

- `<button data-toggle="dropdown" data-target="target-id" …>`
→ `<button data-spirit-toggle="dropdown" data-spirit-target="target-id" …>`
- `<button data-toggle="dropdown" data-autoclose="true" …>`
→ `<button data-spirit-toggle="dropdown" data-spirit-autoclose="true" …>`
- `<div class="Dropdown" data-breakpoint="tablet" …>`
→ `<div class="Collapse" data-spirit-breakpoint="tablet" …>`

 ### FileUploader

- `<div class="FileUploader" data-toggle="fileUploader" …>`
→ `<div class="FileUploader" data-spirit-toggle="fileUploader" …>`
- `<div class="FileUploaderInput" data-file-queue-limit="2" …>`
→ `<div class="FileUploaderInput" data-spirit-file-queue-limit="2" …>`

 ### Header

- `<button data-toggle="offcanvas" data-target="target-id" …>`
→ `<button data-spirit-toggle="offcanvas" data-spirit-target="target-id" …>`
- `<button class="HeaderDialogCloseButton" data-dismiss="offcanvas"
data-target="target-id" …>` → `<button class="HeaderDialogCloseButton"
data-spirit-dismiss="offcanvas" data-spirit-target="target-id" …>`

 ### Modal

- `<button data-toggle="modal" data-target="target-id" …>`
→ `<button data-spirit-toggle="modal" data-spirit-target="target-id" …>`
- `<button data-dismiss="modal" data-target="target-id" …>`
→ `<button data-spirit-dismiss="modal" data-spirit-target="target-id" …>`

 ### ScrollView

- `<div class="ScrollView" data-toggle="scrollView" …>`
→ `<div class="ScrollView" data-spirit-toggle="scrollView" …>`

 ### Tabs

- `<button class="Tabs__link" data-toggle="tabs" data-target="target-id" …>`
→ `<button class="Tabs__link" data-spirit-toggle="tabs"
data-spirit-target="target-id" …>`

 ### TextArea

- `<div class="TextArea" data-toggle="autoResize" …>`
→ `<div class="TextArea" data-spirit-toggle="autoResize" …>`

 ### TextField

- `<button class="TextField__passwordToggle__button" data-toggle="password" …>`
→ `<button class="TextField__passwordToggle__button" data-spirit-toggle="password" …>`

 ### Tooltip

- `<button data-toggle="tooltip" data-target="target-id" …>`
→ `<button data-spirit-toggle="tooltip" data-spirit-target="target-id" …>`
- `<button class="Tooltip__close" data-dismiss="tooltip" data-target="target-id" …>`
→ `<button class="Tooltip__close" data-spirit-dismiss="tooltip"
data-spirit-target="target-id" …>`
- `<div class="Tooltip" data-placement="top" …>`
→ `<div class="Tooltip" data-spirit-placement="top" …>`

Please refer back to this guide or reach out to our team
if you encounter any issues during migration.
  • Loading branch information
crishpeen authored and literat committed Jul 21, 2023
1 parent 2028c6b commit 1a8acd9
Show file tree
Hide file tree
Showing 50 changed files with 441 additions and 418 deletions.
4 changes: 2 additions & 2 deletions packages/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ We provide a version of Spirit Web as `ESM` (`spirit-web.esm.js` and `spirit-web
Nearly all Spirit-Web plugins can be enabled and configured through HTML alone with data attributes (our preferred way of using JavaScript functionality).
Be sure to only use one set of data attributes on a single element (e.g., you cannot trigger a tooltip and modal from the same button.).

ℹ️ For turning off this functionality just do not set the `data-toggle` attribute and use the Programnatic API.
ℹ️ For turning off this functionality just do not set the `data-spirit-toggle` attribute and use the Programnatic API.

> #### Selectors
>
Expand Down Expand Up @@ -140,7 +140,7 @@ Currently the element for the plugin is found by the `querySelector` method sinc

```javascript
var modal = new Modal('#myModal');
var dropdown = new Dropdown('[data-toggle="dropdown"]');
var dropdown = new Dropdown('[data-spirit-toggle="dropdown"]');
```

## Rebranding
Expand Down
10 changes: 6 additions & 4 deletions packages/web/src/js/Collapse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ class Collapse extends BaseComponent {

constructor(element: HTMLElement) {
super(element);
this.target = this.element.dataset.target ? SelectorEngine.findOne(`#${this.element.dataset.target}`) : null;
this.target = this.element.dataset.spiritTarget
? SelectorEngine.findOne(`#${this.element.dataset.spiritTarget}`)
: null;
this.meta = {
id: this.element.dataset.target,
hideOnCollapse: !!(this.element.dataset.more || this.element.dataset.more === ''),
parent: this.target?.dataset.parent,
id: this.element.dataset.spiritTarget,
hideOnCollapse: !!(this.element.dataset.spiritMore || this.element.dataset.spiritMore === ''),
parent: this.target?.dataset.spiritParent,
triggerParent: this.element && this.element.parentElement,
};
this.state = {
Expand Down
6 changes: 3 additions & 3 deletions packages/web/src/js/Dropdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Dropdown extends BaseComponent {

constructor(element: SpiritElement) {
super(element);
this.target = SelectorEngine.findOne(`${this.element.dataset.target}`);
this.target = SelectorEngine.findOne(`${this.element.dataset.spiritTarget}`);
this.reference = this.findReferenceElement();
this.state = {
open: false,
Expand All @@ -49,7 +49,7 @@ class Dropdown extends BaseComponent {
getOptions() {
const options = { ...this.options };
const dataset = this.element?.dataset;
const optionsAutoClose = dataset?.autoclose;
const optionsAutoClose = dataset?.spiritAutoclose;

if (optionsAutoClose) options.autoClose = Boolean(!optionsAutoClose);

Expand Down Expand Up @@ -78,7 +78,7 @@ class Dropdown extends BaseComponent {
updateTriggerElement(open: boolean = this.state.open) {
this.element.classList.toggle(CLASSNAME_EXPANDED, open);
this.element.setAttribute(ARIA_EXPANDED_ATTRIBUTE, open);
this.element.setAttribute(ARIA_CONTROLS_ATTRIBUTE, this.element.dataset.target);
this.element.setAttribute(ARIA_CONTROLS_ATTRIBUTE, this.element.dataset.spiritTarget);
}

updateTargetElement(open: boolean = this.state.open) {
Expand Down
5 changes: 2 additions & 3 deletions packages/web/src/js/FileUploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ const LIST_ELEMENT_SELECTOR = '[data-spirit-element="list"]';
const DROP_ZONE_ELEMENT_SELECTOR = '[data-spirit-element="dropZone"]';
const TEMPLATE_ELEMENT_SELECTOR = '[data-spirit-snippet="item"]';
const TEMPLATE_ELEMENT_SLOT_NAME = 'data-spirit-populate-field';
// @deprecated Will be renamed to `data-spirit-dismiss`
const DATA_DISMISS_ATTRIBUTE = 'data-dismiss';
const DATA_DISMISS_ATTRIBUTE = 'data-spirit-dismiss';
const DATA_ELEMENT_VALIDATION_TEXT = 'validation_text';
const SELECTOR_VALIDATION_TEXT = `[data-spirit-element="${DATA_ELEMENT_VALIDATION_TEXT}"]`;
const DEFAULT_FILE_SIZE_LIMIT = 10000000; // = 10 MB
Expand Down Expand Up @@ -272,7 +271,7 @@ class FileUploader extends BaseComponent {
currentItem &&
EventHandler.on(currentItem, 'click', (event: Event) => {
event.preventDefault();
const target = (event.target as HTMLElement)?.dataset?.dismiss;
const target = (event.target as HTMLElement)?.dataset?.spiritDismiss;
if (target) {
this.removeFromQueue(target);
}
Expand Down
10 changes: 5 additions & 5 deletions packages/web/src/js/Modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { enableToggleTrigger, ScrollControl } from './utils';

const NAME = 'modal';

const MODAL_TOGGLE_SELECTOR = '[data-toggle="modal"]';
const MODAL_TOGGLE_SELECTOR = '[data-spirit-toggle="modal"]';

class Modal extends BaseComponent {
isShown: boolean;
Expand All @@ -28,7 +28,7 @@ class Modal extends BaseComponent {
// Using `Element | Window` - Property 'hasAttribute' does not exist on type 'EventTarget'.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onClick(event: Event & { target: any }) {
if (event.target === this.element || event.target.dataset.dismiss) {
if (event.target === this.element || event.target.dataset.spiritDismiss) {
event.preventDefault();
event.stopPropagation();
this.hide(event);
Expand Down Expand Up @@ -89,8 +89,8 @@ class Modal extends BaseComponent {
if (!event?.target?.dataset) {
target = this.element;
// hiding by clicking
} else if (event.target.dataset.target) {
target = SelectorEngine.findOne(event.target.dataset.target);
} else if (event.target.dataset.spiritTarget) {
target = SelectorEngine.findOne(event.target.dataset.spiritTarget);
// hiding by keyboard
} else {
target = event.target;
Expand All @@ -116,7 +116,7 @@ class Modal extends BaseComponent {
if (!relatedTarget) {
// eslint-disable-next-line no-console
console.warn(
'👻 Boo…! Target modal pane does not exist. Maybe you forgot to prefix the "data-target" selector with "#"? ',
'👻 Boo…! Target modal pane does not exist. Maybe you forgot to prefix the "data-spirit-target" selector with "#"? ',
);

return;
Expand Down
4 changes: 2 additions & 2 deletions packages/web/src/js/Offcanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Offcanvas extends BaseComponent {
// Using `Element | Window` - Property 'hasAttribute' does not exist on type 'EventTarget'.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onClick(event: Event & { target: any }) {
if (event.target === this.element || event.target.dataset.dismiss) {
if (event.target === this.element || event.target.dataset.spiritDismiss) {
event.preventDefault();
event.stopPropagation();
this.hide();
Expand Down Expand Up @@ -124,7 +124,7 @@ class Offcanvas extends BaseComponent {
if (!targetElement) {
// eslint-disable-next-line no-console
console.warn(
'👻 Boo…! Target dialog does not exist. Maybe you forgot to prefix the "data-target" selector with "#"? ',
'👻 Boo…! Target dialog does not exist. Maybe you forgot to prefix the "data-spirit-target" selector with "#"? ',
);

return;
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/js/Tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const CLASS_NAME_ACTIVE = 'is-selected';
const SELECTOR_TAB_PANEL = '[role="tablist"]';
const SELECTOR_OUTER = '[role="presentation"]';
const SELECTOR_INNER = '[role="tab"]';
const SELECTOR_DATA_TOGGLE = `[data-toggle="${NAME}"]`;
const SELECTOR_DATA_TOGGLE = `[data-spirit-toggle="${NAME}"]`;
const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;

class Tabs extends BaseComponent {
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/js/Tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class Tooltip extends BaseComponent {
getTipElement() {
if (!this.tip) {
this.tip =
(SelectorEngine.findOne(this.element?.dataset?.target) as HTMLElement) ||
(SelectorEngine.findOne(this.element?.dataset?.spiritTarget) as HTMLElement) ||
this.element ||
this.element?.parentElement;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/js/__tests__/AutoResize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('AutoResize', () => {

beforeEach(() => {
fixtureEl.innerHTML = `
<div class="TextArea" data-toggle="autoResize">
<div class="TextArea" data-spirit-toggle="autoResize">
<label for="textarea" class="TextArea__label">Label</label>
<textarea id="textarea" class="TextArea__input">Test content</textarea>
</div>
Expand Down
34 changes: 18 additions & 16 deletions packages/web/src/js/__tests__/Collapse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ describe('Collapse', () => {
describe('constructor', () => {
it('should take care of element passed as a CSS selector', () => {
fixtureEl.innerHTML = `
<button data-toggle="collapse" data-target="CollapseExample0"></button>
<button data-spirit-toggle="collapse" data-spirit-target="CollapseExample0"></button>
<div id="CollapseExample0" class="Collapse">
<div class="Collapse__content">
test content
</div>
</div>
`;

const element = fixtureEl.querySelector('[data-toggle="collapse"]') as HTMLElement;
const element = fixtureEl.querySelector('[data-spirit-toggle="collapse"]') as HTMLElement;
const elementBySelector = new Collapse(element);

expect(elementBySelector.element).toEqual(element);
Expand All @@ -35,7 +35,7 @@ describe('Collapse', () => {
describe('toggle', () => {
it('should toggle a collapse', async () => {
fixtureEl.innerHTML = `
<button data-toggle="collapse" data-target="CollapseExample0" aria-expanded="false"></button>
<button data-spirit-toggle="collapse" data-spirit-target="CollapseExample0" aria-expanded="false"></button>
<div id="CollapseExample0" class="Collapse">
<div class="Collapse__content">
test content
Expand All @@ -44,7 +44,7 @@ describe('Collapse', () => {
`;

const toggleSpy = jest.spyOn(Collapse.prototype, 'toggle');
const element = fixtureEl.querySelector('[data-toggle="collapse"]') as HTMLElement;
const element = fixtureEl.querySelector('[data-spirit-toggle="collapse"]') as HTMLElement;
const collapse = new Collapse(element);

await collapse.toggle();
Expand All @@ -60,15 +60,15 @@ describe('Collapse', () => {
describe('show', () => {
it('should show a collapse', async () => {
fixtureEl.innerHTML = `
<button data-toggle="collapse" data-target="CollapseExample0" aria-expanded="false"></button>
<button data-spirit-toggle="collapse" data-spirit-target="CollapseExample0" aria-expanded="false"></button>
<div id="CollapseExample0" class="Collapse">
<div class="Collapse__content">
test content
</div>
</div>
`;

const element = fixtureEl.querySelector('[data-toggle="collapse"]') as HTMLElement;
const element = fixtureEl.querySelector('[data-spirit-toggle="collapse"]') as HTMLElement;
const target = fixtureEl.querySelector('#CollapseExample0') as HTMLElement;
const collapse = new Collapse(element);

Expand All @@ -85,15 +85,15 @@ describe('Collapse', () => {
describe('hide', () => {
it('should hide a collapse', async () => {
fixtureEl.innerHTML = `
<button data-toggle="collapse" data-target="CollapseExample0" aria-expanded="true"></button>
<button data-spirit-toggle="collapse" data-spirit-target="CollapseExample0" aria-expanded="true"></button>
<div id="CollapseExample0" class="Collapse">
<div class="Collapse__content">
test content
</div>
</div>
`;

const element = fixtureEl.querySelector('[data-toggle="collapse"]') as HTMLElement;
const element = fixtureEl.querySelector('[data-spirit-toggle="collapse"]') as HTMLElement;
const collapse = new Collapse(element);

await collapse.hide();
Expand All @@ -108,7 +108,7 @@ describe('Collapse', () => {
<section
id="accordionExample1"
class="Accordion"
data-toggle="accordion"
data-spirit-toggle="accordion"
>
<article
id="accordionExample1_article_0"
Expand All @@ -121,8 +121,8 @@ describe('Collapse', () => {
<button
type="button"
class="Accordion__itemToggle"
data-toggle="collapse"
data-target="accordionExample1_article_0_collapse"
data-spirit-toggle="collapse"
data-spirit-target="accordionExample1_article_0_collapse"
>
header
</button>
Expand All @@ -140,7 +140,7 @@ describe('Collapse', () => {
<div
id="accordionExample1_article_0_collapse"
class="Collapse"
data-parent="#accordionExample1"
data-spirit-parent="#accordionExample1"
aria-labelledby="accordionExample1_article_0_header"
>
<div class="Collapse__content">
Expand All @@ -159,8 +159,8 @@ describe('Collapse', () => {
<button
type="button"
class="Accordion__itemToggle"
data-toggle="collapse"
data-target="accordionExample1_article_1_collapse"
data-spirit-toggle="collapse"
data-spirit-target="accordionExample1_article_1_collapse"
aria-expanded="true"
>
header
Expand All @@ -179,7 +179,7 @@ describe('Collapse', () => {
<div
id="accordionExample1_article_1_collapse"
class="Collapse is-open"
data-parent="#accordionExample1"
data-spirit-parent="#accordionExample1"
aria-labelledby="accordionExample1_article_1_header"
>
<div class="Collapse__content">
Expand All @@ -190,7 +190,9 @@ describe('Collapse', () => {
</section>
`;

const element0 = fixtureEl.querySelector('[data-target="accordionExample1_article_0_collapse"]') as HTMLElement;
const element0 = fixtureEl.querySelector(
'[data-spirit-target="accordionExample1_article_0_collapse"]',
) as HTMLElement;
const target0 = fixtureEl.querySelector('#accordionExample1_article_0_collapse') as HTMLElement;
const target1 = fixtureEl.querySelector('#accordionExample1_article_1_collapse') as HTMLElement;
const collapse0 = new Collapse(element0);
Expand Down
24 changes: 12 additions & 12 deletions packages/web/src/js/__tests__/Dropdown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ describe('Dropdown', () => {
it('should take care of element passed as a CSS selector', () => {
fixtureEl.innerHTML = `
<button
data-toggle="dropdown"
data-target="#DropdownDemo1"
data-spirit-toggle="dropdown"
data-spirit-target="#DropdownDemo1"
>
toggle
</button>
<div class="Dropdown" id="DropdownDemo1">${childrenHtml}</div>
`;

const element = fixtureEl.querySelector('[data-toggle="dropdown"]') as HTMLElement;
const element = fixtureEl.querySelector('[data-spirit-toggle="dropdown"]') as HTMLElement;
const elementBySelector = new Dropdown(element);

expect(elementBySelector.element).toEqual(element);
Expand All @@ -44,16 +44,16 @@ describe('Dropdown', () => {
it('should toggle a dropdown', async () => {
fixtureEl.innerHTML = `
<button
data-toggle="dropdown"
data-target="#DropdownDemo1"
data-spirit-toggle="dropdown"
data-spirit-target="#DropdownDemo1"
>
toggle
</button>
<div class="Dropdown" id="DropdownDemo1">${childrenHtml}</div>
`;

const toggleSpy = jest.spyOn(Dropdown.prototype, 'toggle');
const element = fixtureEl.querySelector('[data-toggle="dropdown"]') as HTMLElement;
const element = fixtureEl.querySelector('[data-spirit-toggle="dropdown"]') as HTMLElement;
const dropdown = new Dropdown(element);

await dropdown.toggle();
Expand All @@ -70,15 +70,15 @@ describe('Dropdown', () => {
it('should show a dropdown', async () => {
fixtureEl.innerHTML = `
<button
data-toggle="dropdown"
data-target="#DropdownDemo1"
data-spirit-toggle="dropdown"
data-spirit-target="#DropdownDemo1"
>
toggle
</button>
<div class="Dropdown" id="DropdownDemo1">${childrenHtml}</div>
`;

const element = fixtureEl.querySelector('[data-toggle="dropdown"]') as HTMLElement;
const element = fixtureEl.querySelector('[data-spirit-toggle="dropdown"]') as HTMLElement;
const target = fixtureEl.querySelector('#DropdownDemo1') as HTMLElement;
const dropdown = new Dropdown(element);

Expand All @@ -94,15 +94,15 @@ describe('Dropdown', () => {
it('should hide a dropdown', async () => {
fixtureEl.innerHTML = `
<button
data-toggle="dropdown"
data-target="#DropdownDemo1"
data-spirit-toggle="dropdown"
data-spirit-target="#DropdownDemo1"
>
toggle
</button>
<div class="Dropdown" id="DropdownDemo1">${childrenHtml}</div>
`;

const element = fixtureEl.querySelector('[data-toggle="dropdown"]') as HTMLElement;
const element = fixtureEl.querySelector('[data-spirit-toggle="dropdown"]') as HTMLElement;
const dropdown = new Dropdown(element);

await dropdown.hide();
Expand Down
Loading

0 comments on commit 1a8acd9

Please sign in to comment.