Skip to content

Commit

Permalink
feat: support initial and hide
Browse files Browse the repository at this point in the history
  • Loading branch information
v8tenko committed Aug 12, 2024
1 parent d36f6b6 commit 59131e2
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const TAB_CLASSNAME = 'yfm-tab';
export const TAB_PANEL_CLASSNAME = 'yfm-tab-panel';
export const ACTIVE_CLASSNAME = 'active';
export const VERTICAL_TAB_CLASSNAME = 'yfm-vertical-tab';
export const VERTICAL_TAB_FORCED_OPEN = 'data-diplodoc-radio-forced'

Check failure on line 11 in src/common.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Insert `;`

export const GROUP_DATA_KEY = 'data-diplodoc-group';
export const TAB_DATA_KEY = 'data-diplodoc-key';
Expand Down
66 changes: 54 additions & 12 deletions src/plugin/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
TAB_DATA_VERTICAL_TAB,
TAB_PANEL_CLASSNAME,
VERTICAL_TAB_CLASSNAME,
VERTICAL_TAB_FORCED_OPEN,
} from '../common';

export type PluginOptions = {
Expand All @@ -30,7 +31,7 @@ export type PluginOptions = {

export type TabsOrientation = 'radio' | 'horizontal';

const TAB_RE = /`?{% list tabs( group=([^ ]*))?( (radio)|(horizontal))? %}`?/;
const TAB_RE = /`?{% list tabs .*%}`?/;

let runsCounter = 0;

Expand Down Expand Up @@ -121,10 +122,12 @@ function findTabs(tokens: Token[], idx: number) {
};
}


Check failure on line 125 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Delete `⏎`
function insertTabs(
tabs: Tab[],
state: StateCore,
align: TabsOrientation,
initial: number | undefined,
{start, end}: {start: number; end: number},
{
containerClasses,
Expand Down Expand Up @@ -227,16 +230,18 @@ function insertTabs(
if (align === 'radio') {
tabOpen.attrSet(TAB_DATA_VERTICAL_TAB, 'true');
tabOpen.attrJoin('class', VERTICAL_TAB_CLASSNAME);
}

if (i === 0) {
if (align === 'horizontal') {
tabOpen.attrJoin('class', ACTIVE_CLASSNAME);
tabOpen.attrSet('aria-selected', 'true');
} else {

Check failure on line 234 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Delete `⏎`
if (i + 1 === initial) {
tabOpen.attrSet(VERTICAL_TAB_FORCED_OPEN, 'true')

Check failure on line 236 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Insert `;`
verticalTabOpen.attrSet('checked', 'true');
tabPanelOpen.attrJoin('class', ACTIVE_CLASSNAME);
}
}

if (i === 0 && align === 'horizontal') {
tabOpen.attrJoin('class', ACTIVE_CLASSNAME);
tabOpen.attrSet('aria-selected', 'true');
tabPanelOpen.attrJoin('class', ACTIVE_CLASSNAME);
}

Expand Down Expand Up @@ -291,14 +296,51 @@ function matchCloseToken(tokens: Token[], i: number) {
);
}

type TabsProps = {
content: string;
orientation: TabsOrientation,

Check failure on line 301 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `,` with `;`
group: string;
initial?: number

Check failure on line 303 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Insert `;`
}

Check failure on line 304 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Insert `;`

function matchOpenToken(tokens: Token[], i: number) {
return (
tokens[i].type === 'paragraph_open' &&
tokens[i + 1].type === 'inline' &&
tokens[i + 1].content.match(TAB_RE)
TAB_RE.test(tokens[i + 1].content) &&
matchProps(tokens[i + 1])
);
}

function matchProps(token: Token) {
const {content} = token;
const query = 'list tabs ';

let index = content.indexOf(query) + query.length;

let inner = '';

while (content[index] !== '%') {
inner += content[index];

index++;
}

const args = inner.split(' ');
const orientation: TabsOrientation = args.includes('radio') ? 'radio' : 'horizontal'

Check failure on line 330 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Insert `;`
const group = args.find((str) => str.startsWith('group'))?.slice('group'.length + 1) || `${DEFAULT_TABS_GROUP_PREFIX}${generateID()}`

Check failure on line 331 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `·args.find((str)·=>··str.startsWith('group'))?.slice('group'.length·+·1)·||·`${DEFAULT_TABS_GROUP_PREFIX}${generateID()}`` with `⏎········args.find((str)·=>·str.startsWith('group'))?.slice('group'.length·+·1)·||⏎········`${DEFAULT_TABS_GROUP_PREFIX}${generateID()}`;`
const initial = args.find((str) => str.startsWith('initial'))?.slice('initial'.length + 1)

Check failure on line 332 in src/plugin/transform.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Replace `·str.startsWith('initial'))?.slice('initial'.length·+·1)` with `str.startsWith('initial'))?.slice('initial'.length·+·1);`

const props: TabsProps = {
content,
orientation,
group,
initial: typeof initial === 'undefined' ? undefined : Number(initial)
};

return props;
}

export function transform({
runtimeJsPath = '_assets/tabs-extension.js',
runtimeCssPath = '_assets/tabs-extension.css',
Expand All @@ -318,7 +360,7 @@ export function transform({

while (i < tokens.length) {
const match = matchOpenToken(tokens, i);
const openTag = match && match[0];
const openTag = match && match.content;
const isNotEscaped = openTag && !(openTag.startsWith('`') && openTag.endsWith('`'));

if (!match || !isNotEscaped) {
Expand All @@ -334,16 +376,16 @@ export function transform({
continue;
}

const tabsGroup = match[2] || `${DEFAULT_TABS_GROUP_PREFIX}${generateID()}`;
const orientation = (match[4] || 'horizontal') as TabsOrientation;
const tabsGroup = match.group;

const {tabs} = findTabs(state.tokens, i + 3);

if (tabs.length > 0) {
insertTabs(
tabs,
state,
orientation,
match.orientation,
match.initial,
{start: i, end: closeTokenIdx + 2},
{
containerClasses,
Expand Down
56 changes: 45 additions & 11 deletions src/runtime/TabsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
TAB_DATA_KEY,
TAB_PANEL_CLASSNAME,
Tab,
VERTICAL_TAB_FORCED_OPEN,
} from '../common';
import type {TabsOrientation} from '../plugin/transform';
import {
Expand Down Expand Up @@ -152,7 +153,7 @@ export class TabsController {
const previousTargetOffset =
scrollableParent && getOffsetByScrollableParent(targetTab, scrollableParent);

const updatedTabs = this.updateHTML({group, key, align}, align);
const updatedTabs = this.updateHTML({group, key, align}, targetTab, align);

if (updatedTabs > 0) {
this.fireSelectTabEvent({group, key, align}, targetTab?.dataset.diplodocId);
Expand All @@ -163,10 +164,10 @@ export class TabsController {
}
}

private updateHTML(tab: Required<Tab>, align: TabsOrientation) {
private updateHTML(tab: Required<Tab>, target: HTMLElement | undefined, align: TabsOrientation) {
switch (align) {
case 'radio': {
return this.updateHTMLVertical(tab);
return this.updateHTMLRadio(tab, target);
}
case 'horizontal': {
return this.updateHTMLHorizontal(tab);
Expand All @@ -176,13 +177,21 @@ export class TabsController {
return 0;
}

private updateHTMLVertical(tab: Required<Tab>) {
private updateHTMLRadio(tab: Required<Tab>, target: HTMLElement | undefined) {
const {group, key} = tab;

const {isForced, root} = this.didTabOpenForced(target);

const singleTabSelector = isForced ? `.yfm-vertical-tab[${VERTICAL_TAB_FORCED_OPEN}="true"]` : ''

const tabs = this._document.querySelectorAll(
`${Selector.TABS}[${GROUP_DATA_KEY}="${group}"] ${Selector.TAB}[${TAB_DATA_KEY}="${key}"]`,
`${Selector.TABS}[${GROUP_DATA_KEY}="${group}"] ${Selector.TAB}[${TAB_DATA_KEY}="${key}"]${singleTabSelector}`,
);

if (isForced) {
root?.removeAttribute(VERTICAL_TAB_FORCED_OPEN);
}

let updated = 0;

tabs.forEach((tab) => {
Expand All @@ -194,16 +203,29 @@ export class TabsController {

const input = title.children.item(0) as HTMLInputElement;

if (title === tab) {
const checked = input.checked;

if (checked) {
title.classList.remove('active');
content?.classList.remove('active');

input.removeAttribute('checked');
} else {
title.classList.add('active');
content?.classList.add('active');

input.setAttribute('checked', 'true');
}

continue;
}

if (input.hasAttribute('checked')) {
title.classList.remove('active');
content?.classList.remove('active');
input.removeAttribute('checked');
}

if (title === tab) {
title.classList.add('active');
content?.classList.add('active');
input.setAttribute('checked', 'true');
input.removeAttribute('checked');
}

updated++;
Expand Down Expand Up @@ -272,6 +294,18 @@ export class TabsController {
);
}

private didTabOpenForced(target?: HTMLElement) {
if (!target) {
return {}
}

const root = target.dataset.diplodocVerticalTab ? target : target.parentElement;

const isForced = typeof root?.dataset.diplodocRadioForced !== 'undefined';

return {root, isForced};
}

private fireSelectTabEvent(tab: Required<Tab>, diplodocId?: string) {
const {group, key, align} = tab;

Expand Down

0 comments on commit 59131e2

Please sign in to comment.