-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2577 from exadel-inc/feat/esl-anchornav
feat(esl-anchornav): create esl-anchornav to provide anchor navigation
- Loading branch information
Showing
22 changed files
with
566 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
+3.24 KB
(100%)
...-feature-feature-homepage-looks-fine-test-homepage-footer-on-desktop-1-snap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
@BG_COLOR: #f7f7f7; | ||
@SHADOW: 1px 2px 3px rgba(0, 0, 0, 0.2); | ||
|
||
esl-anchornav { | ||
[esl-anchornav-items] { | ||
display: flex; | ||
gap: 10px; | ||
flex-wrap: wrap; | ||
} | ||
|
||
.esl-anchornav-item.active { | ||
font-weight: bold; | ||
text-decoration: underline; | ||
} | ||
} | ||
|
||
[esl-anchor].highlighted { | ||
border-top: 1px dotted #f00; | ||
} | ||
|
||
.esl-anchornav-pseudo-fixed { | ||
position: sticky; | ||
top: 0; | ||
right: 0; | ||
padding: 10px 0 10px 10px; | ||
|
||
esl-anchornav { | ||
min-width: 160px; | ||
background: @BG_COLOR; | ||
box-shadow: @SHADOW; | ||
} | ||
|
||
[esl-anchornav-items] { | ||
display: flex; | ||
justify-content: center; | ||
} | ||
} | ||
|
||
[esl-anchornav-sticked] { | ||
background-color: @BG_COLOR; | ||
padding-block: 5px; | ||
|
||
&[sticked] { | ||
box-shadow: @SHADOW; | ||
} | ||
|
||
esl-anchornav { | ||
display: flex; | ||
gap: 10px; | ||
} | ||
|
||
.uip-preview-inner & { | ||
top: -10px; | ||
margin-inline: -10px; | ||
padding-inline: 10px; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import {ESLAnchor, ESLAnchornav, ESLAnchornavSticked} from '@exadel/esl/modules/esl-anchornav/core'; | ||
|
||
import type {ESLAnchornavRender, ESLAnchorData} from '@exadel/esl/modules/esl-anchornav/core'; | ||
|
||
const demoRenderer: ESLAnchornavRender = (data: ESLAnchorData): Element => { | ||
const a = document.createElement('a'); | ||
a.href = `#${data.id}`; | ||
a.className = 'esl-anchornav-item'; | ||
a.dataset.index = `${data.index + 1}`; | ||
a.textContent = data.title; | ||
return a; | ||
}; | ||
|
||
ESLAnchor.register(); | ||
ESLAnchornav.setRenderer(demoRenderer); | ||
ESLAnchornav.register(); | ||
ESLAnchornavSticked.register(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--- | ||
layout: content | ||
title: ESL Anchornav | ||
seoTitle: ESL Anchornav - custom element that collects content anchors from the page and provides anchor navigation | ||
name: ESL Anchornav | ||
tags: [components, beta] | ||
aside: | ||
source: src/modules/esl-anchornav | ||
examples: | ||
- anchornav | ||
--- | ||
|
||
{% mdRender 'src/modules/esl-anchornav/README.md', 'intro' %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
--- | ||
layout: content | ||
title: Anchornav | ||
seoTitle: Anchornav component for prompt navigation to different sections of a page | ||
name: Anchornav | ||
tags: [examples, beta, playground] | ||
icon: examples/anchornav.svg | ||
aside: | ||
components: | ||
- esl-anchornav | ||
--- | ||
{% import 'lorem.njk' as lorem %} | ||
|
||
{% set imageSrcBase = '/assets/' | url %} | ||
|
||
<section class="row"> | ||
<div class="col-12"> | ||
<uip-root> | ||
<script type="text/html" | ||
label="Anchornav fixed" | ||
uip-snippet | ||
uip-snippet-js="js-snippet-anchornav-element"> | ||
<div class="d-flex"> | ||
<div> | ||
<!-- paragraph 4 --> | ||
<div esl-anchor id="my-anchor-1" title="Anchor one"></div> | ||
<p>⚓ № 1</p> | ||
<!-- paragraph 5 --> | ||
<div esl-anchor id="my-anchor-2" title="Anchor two"></div> | ||
<p>⚓ № 2</p> | ||
<!-- paragraph 6 --> | ||
<div esl-anchor id="my-anchor-3" title="Anchor three"></div> | ||
<p>⚓ № 3</p> | ||
<!-- paragraph 7 --> | ||
<div esl-anchor id="my-anchor-4" title="Anchor four"></div> | ||
<p>⚓ № 4</p> | ||
<!-- paragraph 6 --> | ||
<div esl-anchor id="my-anchor-5" title="Anchor five"></div> | ||
<p>⚓ № 5</p> | ||
<!-- paragraph 5 --> | ||
<div esl-anchor id="my-anchor-6" title="Anchor six"></div> | ||
<p>⚓ № 6</p> | ||
<!-- paragraph 6 --> | ||
<div esl-anchor id="my-anchor-7" title="Anchor seven"></div> | ||
<p>⚓ № 7</p> | ||
<!-- paragraph 7 --> | ||
</div> | ||
<div> | ||
<div class="esl-anchornav-pseudo-fixed"> | ||
<esl-anchornav> | ||
<div class="h4 text-center">Anchornav</div> | ||
</esl-anchornav> | ||
</div> | ||
</div> | ||
</div> | ||
</script> | ||
|
||
<script type="text/html" | ||
label="Anchornav sticked" | ||
uip-snippet | ||
uip-snippet-js="js-snippet-anchornav-element"> | ||
<div> | ||
<!-- paragraph 3 --> | ||
<div esl-anchornav-sticked><esl-anchornav>Anchors: <nav esl-anchors-items></nav></esl-anchornav></div> | ||
<!-- paragraph 4 --> | ||
<div esl-anchor id="my-anchor-1" title="Anchor one"></div> | ||
<br><p>⚓ № 1</p> | ||
<!-- paragraph 8 --> | ||
<div esl-anchor id="my-anchor-2" title="Anchor two"></div> | ||
<br><p>⚓ № 2</p> | ||
<!-- paragraph 9 --> | ||
<div esl-anchor id="my-anchor-3" title="Anchor three"></div> | ||
<br><p>⚓ № 3</p> | ||
<!-- paragraph 10 --> | ||
<div esl-anchor id="my-anchor-4" title="Anchor four"></div> | ||
<br><p>⚓ № 4</p> | ||
<!-- paragraph 9 --> | ||
<div esl-anchor id="my-anchor-5" title="Anchor five"></div> | ||
<br><p>⚓ № 5</p> | ||
<!-- paragraph 8 --> | ||
<div esl-anchor id="my-anchor-6" title="Anchor six"></div> | ||
<br><p>⚓ № 6</p> | ||
<!-- paragraph 9 --> | ||
<div esl-anchor id="my-anchor-7" title="Anchor seven"></div> | ||
<br><p>⚓ № 7</p> | ||
<!-- paragraph 10 --> | ||
</div> | ||
</script> | ||
|
||
<script id="js-snippet-anchornav-element" type="text/plain"> | ||
import { ESLAnchornav, ESLAnchorMixin, ESLAnchornavStickedMixin } from '@exadel/esl'; | ||
ESLAnchornav.register(); | ||
ESLAnchorMixin.register(); | ||
ESLAnchornavStickedMixin.register(); | ||
</script> | ||
|
||
<uip-snippets class="uip-toolbar" dropdown-view="@xs"></uip-snippets> | ||
<uip-settings label="Settings" resizable vertical="@+sm"> | ||
<uip-bool-setting label="Highlight anchor" target="[esl-anchor]" mode="append" attribute="class" value="highlighted"></uip-bool-setting> | ||
</uip-settings> | ||
<uip-preview style="max-height: 500px"></uip-preview> | ||
<uip-editor label="Source code (HTML)" collapsible copy></uip-editor> | ||
<uip-editor source="js" label="Source code (JS)" collapsible collapsed copy></uip-editor> | ||
</uip-root> | ||
</div> | ||
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,3 +28,5 @@ | |
@import './esl-share/core.less'; | ||
|
||
@import './esl-carousel/all.less'; | ||
|
||
@import './esl-anchornav/core.less'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# [ESL](../../../) Anchornav | ||
|
||
Version: *1.0.0-beta*. | ||
|
||
Authors: *Dmytro Shovchko*. | ||
|
||
***Important Notice: the component is under beta version, it is tested and ready to use but be aware of its potential critical API changes.*** | ||
|
||
<a name="intro"></a> | ||
|
||
The ESL Anchornav component allows users to quickly jump to specific page content via predefined anchors. The list of anchors is collected from the page dynamically, so any page updates will be processed and the component updates the navigation list. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
@import './core/esl-anchor.less'; | ||
@import './core/esl-anchornav.less'; | ||
@import './core/esl-anchornav-sticked.less'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export type * from './core/esl-anchornav-types'; | ||
|
||
export * from './core/esl-anchornav'; | ||
export * from './core/esl-anchornav-sticked'; | ||
export * from './core/esl-anchor'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[esl-anchor] { | ||
margin-block-end: -2px; | ||
height: 2px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import {ESLMixinElement} from '../../esl-mixin-element/core'; | ||
import {ExportNs} from '../../esl-utils/environment/export-ns'; | ||
import {prop} from '../../esl-utils/decorators'; | ||
import {ESLEventUtils} from '../../esl-event-listener/core'; | ||
|
||
/** | ||
* ESLAnchor - custom mixin element for setting up anchor for {@link ESLAnchornav} attaching | ||
* | ||
* Use example: | ||
* `<div esl-anchor id="my-anchor-id" title="My anchor title"></div>` | ||
*/ | ||
@ExportNs('Anchor') | ||
export class ESLAnchor extends ESLMixinElement { | ||
static override is = 'esl-anchor'; | ||
|
||
@prop('esl:anchor:change') public CHANGE_EVENT: string; | ||
|
||
protected override connectedCallback(): void { | ||
super.connectedCallback(); | ||
this.sendRequestEvent(); | ||
} | ||
|
||
protected override disconnectedCallback(): void { | ||
this.sendRequestEvent(); | ||
super.disconnectedCallback(); | ||
} | ||
|
||
/** Sends a broadcast event to Anchornav components to refresh the list of anchors */ | ||
protected sendRequestEvent(): void { | ||
ESLEventUtils.dispatch(document.body, this.CHANGE_EVENT); | ||
} | ||
} | ||
|
||
declare global { | ||
export interface ESLLibrary { | ||
Anchor: typeof ESLAnchor; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[esl-anchornav-sticked] { | ||
position: sticky; | ||
top: 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import {ESLMixinElement} from '../../esl-mixin-element/core'; | ||
import {listen} from '../../esl-utils/decorators'; | ||
import {ESLIntersectionTarget, ESLResizeObserverTarget} from '../../esl-event-listener/core'; | ||
import {getViewportForEl} from '../../esl-utils/dom/scroll'; | ||
import {ESLAnchornav} from './esl-anchornav'; | ||
|
||
import type {ESLIntersectionEvent, ESLElementResizeEvent} from '../../esl-event-listener/core'; | ||
|
||
/** | ||
* ESLAnchornavSticked - custom mixin element for sticky positioned of {@link ESLAnchornav} element | ||
* | ||
* Use example: | ||
* `<div esl-anchornav-sticked><esl-anchornav></esl-anchornav></div>` | ||
*/ | ||
export class ESLAnchornavSticked extends ESLMixinElement { | ||
static override is = 'esl-anchornav-sticked'; | ||
|
||
protected _sticked: boolean = false; | ||
|
||
/** The height of this anchornav container */ | ||
public get anchornavHeight(): number { | ||
return this.$host.getBoundingClientRect().height; | ||
} | ||
|
||
/** Sticked state */ | ||
public get sticked(): boolean { | ||
return this._sticked; | ||
} | ||
public set sticked(value: boolean) { | ||
if (this._sticked === value) return; | ||
this._sticked = value; | ||
this.$$attr('sticked', value); | ||
this._onStateChange(); | ||
} | ||
|
||
/** Childs anchornav element */ | ||
protected get $anchornav(): ESLAnchornav | null { | ||
return this.$host.querySelector<ESLAnchornav>(ESLAnchornav.is); | ||
} | ||
|
||
/** Handles changing sticky state */ | ||
protected _onStateChange(): void { | ||
if (!this.$anchornav) return; | ||
this.$anchornav.offset = this.sticked ? this.anchornavHeight : 0; | ||
} | ||
|
||
@listen({ | ||
event: 'intersects', | ||
target: (that: ESLAnchornavSticked) => ESLIntersectionTarget.for(that.$host, { | ||
root: getViewportForEl(that.$host), | ||
rootMargin: '-1px 0px 0px 0px', | ||
threshold: [0.99, 1] | ||
}) | ||
}) | ||
protected _onIntersection(e: ESLIntersectionEvent): void { | ||
this.sticked = e.intersectionRect.y > e.boundingClientRect.y; | ||
} | ||
|
||
@listen({event: 'resize', target: (that: ESLAnchornavSticked) => ESLResizeObserverTarget.for(that.$host)}) | ||
protected _onResize({borderBoxSize}: ESLElementResizeEvent): void { | ||
this._onStateChange(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** {@link ESLAnchornav} item renderer */ | ||
export type ESLAnchornavRender = (data: ESLAnchorData) => string | Element; | ||
|
||
/** {@link ESLAnchornav} anchor data interface */ | ||
export interface ESLAnchorData { | ||
id: string; | ||
title: string; | ||
index: number; // order number in the anchor list | ||
$anchor: HTMLElement; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
esl-anchornav { | ||
display: block; | ||
} |
Oops, something went wrong.