Skip to content

Commit 0325ae6

Browse files
committed
Implemented TabActivation with permalinks
1 parent 7ff462f commit 0325ae6

File tree

14 files changed

+291
-29
lines changed

14 files changed

+291
-29
lines changed

.github/docs/PermaLink.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ For more details see Usage section.
3434
Starts a navigation watcher which will check for Permalinks in the URLs.
3535
- **`ChangePermalink()`**: **`void ChangePermalink(string? newPermalink, bool doNotNavigate)`** <br />
3636
Modify the current URL with given new peralink value and trigger navigation or just update browser History.
37+
- **`CheckPermalink()`**: **`string? CheckPermalink(bool triggerEvent = false)`** <br />
38+
Checks the current URL for permalink again and re-triggers `PermalinkDetected` event if requested.
3739
- **`Dispose()`: `@implements IDisposable` interface** <br />
3840
Component implements `IDisposable` interface Blazor framework will call it when parent removed from render tree.
3941

.github/docs/Tabs.md

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ Sets all `TabItem` elements height in `px`.
3737
Sets all `TabItem` elements element width in `px`.
3838
- **`Disabled`: `bool { get; set; }` (default: false)** <br />
3939
Determines whether all the rendered HTML elements should be disabled or not.
40+
- **`AllowTabActivationByPermalink`: `bool { get; set; }` (default: true)** <br />
41+
Enables or disables `TabItem` activation with URL Permalink fragment.
42+
**NOTE: in order to make TabActivation work `Majorsoft.Blazor.Components.PermaLink` component is used and it MUST [set up correctly](https://github.com/majorimi/blazor-components/blob/master/.github/docs/PermaLink.md#configuration)!**
4043
- **`Animate`: `bool { get; set; }` (default: true)** <br />
4144
Determines to apply CSS animation and transion on Tab changes or not.
4245
- **`TabPositon`: `TabPositons { get; set; }` (default: TabPositons.Left)** <br />
@@ -67,6 +70,9 @@ Required HTML content to show content of current TabItem.
6770
Determines whether the current rendered TabItem should be disabled or not.
6871
- **`Hidden`: `bool { get; set; }` (default: false)** <br />
6972
Determines whether the current rendered TabItem should be hidden or not.
73+
- **`Permalink`: `string { get; set; }` (default: "")** <br />
74+
Permalink value to append to the URL and activate the `TabItem` based on matching value.
75+
**NOTE: in order to make TabActivation work `Majorsoft.Blazor.Components.PermaLink` component is used and it MUST [set up correctly](https://github.com/majorimi/blazor-components/blob/master/.github/docs/PermaLink.md#configuration)!**
7076

7177
**Arbitrary HTML attributes e.g.: `tabindex="1"` will be passed to the corresponding rendered HTML element `<input>`**.
7278

@@ -88,11 +94,42 @@ Add using statement to your Blazor `<component/page>.razor` file. Or globally re
8894
@using Majorsoft.Blazor.Components.Tabs
8995
```
9096

97+
### Dependences
98+
**Majorsoft.Blazor.Components.Tabs** package "partially" depends on other Majorsoft Nuget packages:
99+
- [Majorsoft.Blazor.Components.Common.JsInterop](https://www.nuget.org/packages/Majorsoft.Blazor.Components.Common.JsInterop)
100+
which handles JS Interop for many features e.g. scrolling, etc.
101+
- [Majorsoft.Blazor.Components.Common.PermaLink](https://www.nuget.org/packages/Majorsoft.Blazor.Components.PermaLink)
102+
which track navigations (URL changes) and identify permalink elements.
103+
104+
**NOTE: only TabItem activation feature depend on Permalink. If you don't want to use that feature just leave `Permalink` parameters empty and do not setup PermalinkWatcher.
105+
Also later this feature can be disabled by `AllowTabActivationByPermalink = false`.**
106+
91107
### `TabsPanel` and `TabItem` usage
92108

93109
Following code example shows how to use **`TabsPanel`** with **`TabItem`** component in your Blazor App.
94110

111+
**NOTE: to use TabActivation feature `Permalink="Tab1"` must be set and Permalink services must be [configured correctly](https://github.com/majorimi/blazor-components/blob/master/.github/docs/PermaLink.md#configuration)!**
112+
95113
```
114+
@*Simple tab usage*@
115+
<TabsPanel>
116+
<TabItems>
117+
<TabItem>
118+
<Header>Tab1</Header>
119+
<Content>Tab1</Content>
120+
</TabItem>
121+
<TabItem>
122+
<Header>Tab2</Header>
123+
<Content>Tab2</Content>
124+
</TabItem>
125+
<TabItem>
126+
<Header>Tab3</Header>
127+
<Content>Tab3</Content>
128+
</TabItem>
129+
</TabItems>
130+
</TabsPanel>
131+
132+
@*Advanced tab usage*@
96133
<TabsPanel @ref="_tabs"
97134
ActiveColor="@_activeColor"
98135
InactiveColor="@_inactiveColor"
@@ -105,26 +142,26 @@ Following code example shows how to use **`TabsPanel`** with **`TabItem`** comp
105142
Animate="@_isAnimated"
106143
OnTabChanged="OnTabChanged">
107144
<TabItems>
108-
<TabItem id="tab1" @ref="_tab1">
145+
<TabItem id="tab1" @ref="_tab1" Disabled="false" Permalink="Tab1" Hidden="false">
109146
<Header><strong>Tab 1</strong></Header>
110147
<Content>
111148
<h1>The first tab</h1>
112149
</Content>
113150
</TabItem>
114-
<TabItem @ref="_tab2">
151+
<TabItem @ref="_tab2" Disabled="false" Permalink="Tab2" Hidden="false">
115152
<Header><i>Tab 2</i></Header>
116153
<Content>
117154
<h1>The second tab</h1>
118155
</Content>
119156
</TabItem>
120-
<TabItem id="tab3" @ref="_tab3" Disabled="@_isTabDisabled" Hidden="@_isTabHidden">
157+
<TabItem id="tab3" @ref="_tab3" Disabled="@_isTabDisabled" Permalink="Tab3" Hidden="@_isTabHidden">
121158
<Header><u>Can disable</u></Header>
122159
<Content>
123160
<h1>This tab can be disabled</h1>
124161
<p>And also any <code>TabItem</code> can be disabled by using <code>Disabled</code> property.</p>
125162
</Content>
126163
</TabItem>
127-
<TabItem id="tab4" @ref="_tab4">
164+
<TabItem id="tab4" @ref="_tab4" Disabled="false" Permalink="Tab4" Hidden="false">
128165
<Header>Header icon <i class="fa fa-home"></i></Header>
129166
<Content>
130167
<h1>Tab with icon in header</h1>

src/Majorsoft.Blazor.Components.Common.JsInterop/Majorsoft.Blazor.Components.Common.JsInterop.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<RepositoryType>Git</RepositoryType>
1818
<Description>Blazor component that provides useful functionality and event notifications which can be achieved only with JS Interop e.g. scroll, clipboard, focus, resize, language detection, GEO location, etc. Part of Majorsoft Blazor library.</Description>
1919
<PackageReleaseNotes>See Releases here: https://github.com/majorimi/blazor-components/releases</PackageReleaseNotes>
20-
<PackageTags>.Net5 Blazor Js Interop Click Scroll Focus BoundRect</PackageTags>
20+
<PackageTags>.Net5 Blazor Js Interop Click Scroll Resize Focus BoundRect Browser Geolocation Head History ColorTheme</PackageTags>
2121
<PackageLicenseFile>License.txt</PackageLicenseFile>
2222
<Title>Blazor Components JsInterop</Title>
2323
</PropertyGroup>

src/Majorsoft.Blazor.Components.PermaLink/IPermaLinkWatcherService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ public interface IPermaLinkWatcherService : IDisposable
2626
/// <param name="doNotNavigate">False, will trigger a navigation. When true, just add new URL to the History</param>
2727
void ChangePermalink(string? newPermalink, bool doNotNavigate);
2828

29+
/// <summary>
30+
/// Checks the current URL for permalink again and re-triggers `PermalinkDetected` event if requested.
31+
/// </summary>
32+
/// <param name="triggerEvent">PermalinkDetected should be re-triggered or not</param>
33+
/// <returns>Found permalink value or NULL</returns>
34+
string? CheckPermalink(bool triggerEvent = false);
35+
2936
/// <summary>
3037
/// Starts a navigation watcher which will check for Permalinks in the URLs.
3138
/// </summary>

src/Majorsoft.Blazor.Components.PermaLink/Majorsoft.Blazor.Components.PermaLink.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Majorsoft.Blazor.Components.PermaLink/PermaLinkWatcherService.cs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,11 @@ public void WatchPermaLinks()
5151

5252
private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
5353
{
54-
_logger.LogDebug($"{nameof(PermaLinkWatcherService)} - {nameof(HandleLocationChanged)}: navigation happened new URL: {e.Location}");
54+
_logger.LogDebug($"{nameof(PermaLinkWatcherService)} - {nameof(HandleLocationChanged)}: navigation happened new URL: '{e.Location}'");
5555
var perma = DetectPermalink(e.Location);
5656

5757
if(!string.IsNullOrWhiteSpace(perma))
5858
{
59-
_logger.LogDebug($"{nameof(PermaLinkWatcherService)} - {nameof(HandleLocationChanged)}: PermaLink found: {perma}");
60-
6159
if(PermalinkDetected is not null)
6260
{
6361
PermalinkDetected.Invoke(this, new PermalinkDetectedEventArgs(e, perma));
@@ -69,14 +67,11 @@ private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
6967

7068
public void ChangePermalink(string? newPermalink, bool doNotNavigate)
7169
{
70+
_logger.LogDebug($"{nameof(PermaLinkWatcherService)} - {nameof(ChangePermalink)}: current URL: '{_navigationManager.Uri}', new URL Permalink: '{newPermalink}'");
71+
7272
var perma = DetectPermalink(_navigationManager.Uri);
7373
if (!string.IsNullOrWhiteSpace(perma))
7474
{
75-
if (newPermalink?.ToLower() == perma?.ToLower()) //same
76-
{
77-
return;
78-
}
79-
8075
var newUri = _navigationManager.Uri.Replace($"#{perma}", "");
8176
if (string.IsNullOrWhiteSpace(newPermalink)) //remove
8277
{
@@ -94,21 +89,39 @@ public void ChangePermalink(string? newPermalink, bool doNotNavigate)
9489

9590
private void SetBrowserUrl(string uri, bool doNotNavigate)
9691
{
97-
if(doNotNavigate)
92+
_logger.LogDebug($"{nameof(PermaLinkWatcherService)} - {nameof(SetBrowserUrl)}: new URL: '{uri}', doNotNavigate: '{doNotNavigate}'");
93+
94+
if (doNotNavigate)
9895
{
9996
_navigationHistoryService?.PushStateAsync(null, "", uri);
10097
return;
10198
}
10299

103100
_navigationManager.NavigateTo(uri, false);
104101
}
102+
public string? CheckPermalink(bool triggerEvent)
103+
{
104+
var perma = DetectPermalink(_navigationManager.Uri);
105+
if (!string.IsNullOrWhiteSpace(perma))
106+
{
107+
if (PermalinkDetected is not null)
108+
{
109+
PermalinkDetected.Invoke(this, new PermalinkDetectedEventArgs(
110+
new LocationChangedEventArgs(_navigationManager.Uri, false), perma));
111+
}
112+
}
113+
114+
return perma;
115+
}
105116

106-
private string DetectPermalink(string uri)
117+
private string? DetectPermalink(string uri)
107118
{
108119
var match = _poundRegex.Match(uri);
109120
if (match.Success && match.Groups.Count == 2)
110121
{
111122
var perma = match.Groups[1].Value;
123+
_logger.LogDebug($"{nameof(PermaLinkWatcherService)} - {nameof(DetectPermalink)}: PermaLink found: '{perma}'");
124+
112125
return perma;
113126
}
114127

0 commit comments

Comments
 (0)