@ziadshalaby/ngx-zs-component 3.1.4 → 3.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, signal, Injectable, inject, input, computed, effect, output, viewChild, model, untracked, HostListener, ChangeDetectionStrategy } from '@angular/core';
|
|
2
|
+
import { Component, signal, Injectable, inject, input, computed, effect, output, viewChild, model, untracked, HostListener, linkedSignal, ChangeDetectionStrategy } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i1$1 from '@angular/router';
|
|
@@ -1927,7 +1927,12 @@ class ThemeToggle {
|
|
|
1927
1927
|
bodyClass = input('zs:bg-white zs:dark:bg-gray-900 zs:text-gray-900 zs:dark:text-gray-100', ...(ngDevMode ? [{ debugName: "bodyClass" }] : []));
|
|
1928
1928
|
showDefaultUI = input(true, ...(ngDevMode ? [{ debugName: "showDefaultUI" }] : []));
|
|
1929
1929
|
setManualTheme = input(null, ...(ngDevMode ? [{ debugName: "setManualTheme" }] : []));
|
|
1930
|
-
fromTop = input(
|
|
1930
|
+
fromTop = input(1 / 4, ...(ngDevMode ? [{ debugName: "fromTop" }] : []));
|
|
1931
|
+
panelTop = linkedSignal(() => window.innerHeight * this.fromTop(), ...(ngDevMode ? [{ debugName: "panelTop" }] : []));
|
|
1932
|
+
lastPanelTop = signal(this.panelTop(), ...(ngDevMode ? [{ debugName: "lastPanelTop" }] : []));
|
|
1933
|
+
isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
|
|
1934
|
+
startY = 0;
|
|
1935
|
+
startTop = 0;
|
|
1931
1936
|
// ==============================================
|
|
1932
1937
|
// Outputs
|
|
1933
1938
|
// ==============================================
|
|
@@ -1936,6 +1941,11 @@ class ThemeToggle {
|
|
|
1936
1941
|
// Lifecycle & Side Effects
|
|
1937
1942
|
// ==============================================
|
|
1938
1943
|
constructor() {
|
|
1944
|
+
const savedTop = localStorage.getItem('themeToggleTop');
|
|
1945
|
+
if (savedTop) {
|
|
1946
|
+
this.panelTop.set(+savedTop);
|
|
1947
|
+
this.lastPanelTop.set(+savedTop);
|
|
1948
|
+
}
|
|
1939
1949
|
// ① تهيئة الثيم
|
|
1940
1950
|
const savedTheme = localStorage.getItem('theme');
|
|
1941
1951
|
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)');
|
|
@@ -1988,16 +1998,50 @@ class ThemeToggle {
|
|
|
1988
1998
|
// ==============================================
|
|
1989
1999
|
// Component Methods
|
|
1990
2000
|
// ==============================================
|
|
2001
|
+
isDragged() {
|
|
2002
|
+
const p = this.panelTop;
|
|
2003
|
+
const l = this.lastPanelTop;
|
|
2004
|
+
if (p() !== l()) {
|
|
2005
|
+
l.set(p());
|
|
2006
|
+
return true;
|
|
2007
|
+
}
|
|
2008
|
+
return false;
|
|
2009
|
+
}
|
|
1991
2010
|
toggleOpen() {
|
|
2011
|
+
if (this.isDragged())
|
|
2012
|
+
return;
|
|
1992
2013
|
this.isOpen.set(!this.isOpen());
|
|
1993
2014
|
}
|
|
1994
2015
|
setTheme(theme) {
|
|
2016
|
+
if (this.isDragged())
|
|
2017
|
+
return;
|
|
1995
2018
|
if (this.currentTheme() !== theme) {
|
|
1996
2019
|
this.currentTheme.set(theme);
|
|
1997
2020
|
this.userSelectedTheme.set(true);
|
|
1998
2021
|
}
|
|
1999
2022
|
this.isOpen.set(false);
|
|
2000
2023
|
}
|
|
2024
|
+
onDragStart(event) {
|
|
2025
|
+
this.isDragging.set(true);
|
|
2026
|
+
this.startY = event.clientY;
|
|
2027
|
+
this.startTop = this.panelTop();
|
|
2028
|
+
event.target.setPointerCapture(event.pointerId);
|
|
2029
|
+
}
|
|
2030
|
+
onDragMove(event) {
|
|
2031
|
+
if (!this.isDragging())
|
|
2032
|
+
return;
|
|
2033
|
+
const deltaY = event.clientY - this.startY;
|
|
2034
|
+
let newTop = this.startTop + deltaY;
|
|
2035
|
+
const minTop = 80;
|
|
2036
|
+
const maxTop = window.innerHeight - 120;
|
|
2037
|
+
newTop = Math.max(minTop, Math.min(maxTop, newTop));
|
|
2038
|
+
this.panelTop.set(newTop);
|
|
2039
|
+
}
|
|
2040
|
+
settimeId;
|
|
2041
|
+
onDragEnd(event) {
|
|
2042
|
+
this.isDragging.set(false);
|
|
2043
|
+
localStorage.setItem('themeToggleTop', String(this.panelTop()));
|
|
2044
|
+
}
|
|
2001
2045
|
// ==============================================
|
|
2002
2046
|
// Host Listeners
|
|
2003
2047
|
// ==============================================
|
|
@@ -2008,11 +2052,11 @@ class ThemeToggle {
|
|
|
2008
2052
|
}
|
|
2009
2053
|
}
|
|
2010
2054
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ThemeToggle, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2011
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ThemeToggle, isStandalone: true, selector: "ZS-theme-toggle", inputs: { bodyClass: { classPropertyName: "bodyClass", publicName: "bodyClass", isSignal: true, isRequired: false, transformFunction: null }, showDefaultUI: { classPropertyName: "showDefaultUI", publicName: "showDefaultUI", isSignal: true, isRequired: false, transformFunction: null }, setManualTheme: { classPropertyName: "setManualTheme", publicName: "setManualTheme", isSignal: true, isRequired: false, transformFunction: null }, fromTop: { classPropertyName: "fromTop", publicName: "fromTop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { themeChangeEv: "themeChangeEv" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<!-- ========================= Theme Switcher Panel ========================= -->\n@if(showDefaultUI()) {\n <div
|
|
2055
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: ThemeToggle, isStandalone: true, selector: "ZS-theme-toggle", inputs: { bodyClass: { classPropertyName: "bodyClass", publicName: "bodyClass", isSignal: true, isRequired: false, transformFunction: null }, showDefaultUI: { classPropertyName: "showDefaultUI", publicName: "showDefaultUI", isSignal: true, isRequired: false, transformFunction: null }, setManualTheme: { classPropertyName: "setManualTheme", publicName: "setManualTheme", isSignal: true, isRequired: false, transformFunction: null }, fromTop: { classPropertyName: "fromTop", publicName: "fromTop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { themeChangeEv: "themeChangeEv" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<!-- ========================= Theme Switcher Panel ========================= -->\n@if(showDefaultUI()) {\n <div\n class=\"zs:fixed zs:left-0 {{ zIndices.themeToggle }} zs:transform \n zs:-translate-y-1/2 zs:transition-all zs:duration-300\"\n\n [style.top.px]=\"panelTop()\"\n [ngClass]=\"[!isOpen() ? 'zs:-translate-x-24' : '']\"\n\n (pointerdown)=\"onDragStart($event)\"\n (pointermove)=\"onDragMove($event)\"\n (pointerup)=\"onDragEnd($event)\"\n (pointercancel)=\"onDragEnd($event)\"\n\n style=\"touch-action: none; cursor: grab;\"\n >\n <!-- ========================= Theme Selection Buttons ========================= -->\n <div class=\"zs:flex zs:items-center\">\n <div \n class=\"zs:flex zs:overflow-hidden zs:transition-all zs:duration-300\"\n role=\"group\"\n aria-label=\"Theme selection\"\n >\n <!-- Light Theme Button -->\n <button\n (click)=\"setTheme('light')\"\n type=\"button\"\n class=\"zs:px-3 zs:py-2 zs:rounded-l-none zs:border-l-0 zs:border-y \n zs:transition-colors zs:shrink-0\n zs:bg-white zs:text-gray-900 zs:border-gray-300\n zs:dark:bg-gray-800 zs:dark:text-gray-100 zs:dark:border-gray-600\n zs:hover:bg-gray-100 zs:dark:hover:bg-gray-700 zs:w-12\n zs:focus:outline-hidden zs:focus-visible:ring-2 zs:focus-visible:ring-offset-2 \n zs:focus-visible:ring-blue-500\"\n aria-label=\"Activate light theme\"\n [attr.aria-pressed]=\"currentTheme() === 'light'\"\n >\n <i class=\"fas fa-sun zs:text-yellow-500\" aria-hidden=\"true\"></i>\n </button>\n \n <!-- Dark Theme Button -->\n <button\n (click)=\"setTheme('dark')\"\n type=\"button\"\n class=\"zs:px-3 zs:py-2 zs:rounded-r-lg zs:border-y zs:border-r \n zs:transition-colors zs:shrink-0\n zs:bg-white zs:text-gray-900 zs:border-gray-300\n zs:dark:bg-gray-800 zs:dark:text-gray-100 zs:dark:border-gray-600\n zs:hover:bg-gray-100 zs:dark:hover:bg-gray-700 zs:w-12\n zs:focus:outline-hidden zs:focus-visible:ring-2 zs:focus-visible:ring-offset-2 \n zs:focus-visible:ring-blue-500\"\n aria-label=\"Activate dark theme\"\n [attr.aria-pressed]=\"currentTheme() === 'dark'\"\n >\n <i class=\"fas fa-moon\" aria-hidden=\"true\"></i>\n </button>\n </div>\n \n <!-- ========================= Toggle Button with Connector ========================= -->\n <div \n class=\"zs:relative\"\n [ngClass]=\"isOpen() ? 'zs:hidden' : ''\"\n >\n <!-- Connector Line -->\n <div\n class=\"zs:absolute zs:top-1/2 zs:right-0 zs:h-0.5 zs:w-3 zs:transform zs:-translate-y-1/2\n zs:bg-gray-300 zs:dark:bg-gray-600\"\n aria-hidden=\"true\"\n ></div>\n \n <!-- Toggle Button -->\n <button\n (click)=\"toggleOpen()\"\n type=\"button\"\n class=\"zs:relative zs:z-100 zs:w-12 zs:h-12 zs:rounded-full zs:rounded-l-none zs:border-l-0 \n zs:border-2\n zs:transition-all zs:duration-300 zs:flex zs:items-center zs:justify-center\n zs:bg-white zs:text-gray-900 zs:border-gray-300\n zs:dark:bg-gray-800 zs:dark:text-gray-100 zs:dark:border-gray-600\n zs:hover:bg-gray-100 zs:dark:hover:bg-gray-700\n zs:focus:outline-hidden zs:focus-visible:ring-2 zs:focus-visible:ring-offset-2 \n zs:focus-visible:ring-blue-500\"\n aria-label=\"Toggle theme switcher\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-controls=\"theme-panel\"\n >\n @if (currentTheme() === 'dark') {\n <i class=\"fas fa-moon\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fas fa-sun zs:text-yellow-500\" aria-hidden=\"true\"></i>\n }\n </button>\n </div>\n </div>\n </div>\n}", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
2012
2056
|
}
|
|
2013
2057
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: ThemeToggle, decorators: [{
|
|
2014
2058
|
type: Component,
|
|
2015
|
-
args: [{ selector: 'ZS-theme-toggle', imports: [CommonModule], template: "<!-- ========================= Theme Switcher Panel ========================= -->\n@if(showDefaultUI()) {\n <div
|
|
2059
|
+
args: [{ selector: 'ZS-theme-toggle', imports: [CommonModule], template: "<!-- ========================= Theme Switcher Panel ========================= -->\n@if(showDefaultUI()) {\n <div\n class=\"zs:fixed zs:left-0 {{ zIndices.themeToggle }} zs:transform \n zs:-translate-y-1/2 zs:transition-all zs:duration-300\"\n\n [style.top.px]=\"panelTop()\"\n [ngClass]=\"[!isOpen() ? 'zs:-translate-x-24' : '']\"\n\n (pointerdown)=\"onDragStart($event)\"\n (pointermove)=\"onDragMove($event)\"\n (pointerup)=\"onDragEnd($event)\"\n (pointercancel)=\"onDragEnd($event)\"\n\n style=\"touch-action: none; cursor: grab;\"\n >\n <!-- ========================= Theme Selection Buttons ========================= -->\n <div class=\"zs:flex zs:items-center\">\n <div \n class=\"zs:flex zs:overflow-hidden zs:transition-all zs:duration-300\"\n role=\"group\"\n aria-label=\"Theme selection\"\n >\n <!-- Light Theme Button -->\n <button\n (click)=\"setTheme('light')\"\n type=\"button\"\n class=\"zs:px-3 zs:py-2 zs:rounded-l-none zs:border-l-0 zs:border-y \n zs:transition-colors zs:shrink-0\n zs:bg-white zs:text-gray-900 zs:border-gray-300\n zs:dark:bg-gray-800 zs:dark:text-gray-100 zs:dark:border-gray-600\n zs:hover:bg-gray-100 zs:dark:hover:bg-gray-700 zs:w-12\n zs:focus:outline-hidden zs:focus-visible:ring-2 zs:focus-visible:ring-offset-2 \n zs:focus-visible:ring-blue-500\"\n aria-label=\"Activate light theme\"\n [attr.aria-pressed]=\"currentTheme() === 'light'\"\n >\n <i class=\"fas fa-sun zs:text-yellow-500\" aria-hidden=\"true\"></i>\n </button>\n \n <!-- Dark Theme Button -->\n <button\n (click)=\"setTheme('dark')\"\n type=\"button\"\n class=\"zs:px-3 zs:py-2 zs:rounded-r-lg zs:border-y zs:border-r \n zs:transition-colors zs:shrink-0\n zs:bg-white zs:text-gray-900 zs:border-gray-300\n zs:dark:bg-gray-800 zs:dark:text-gray-100 zs:dark:border-gray-600\n zs:hover:bg-gray-100 zs:dark:hover:bg-gray-700 zs:w-12\n zs:focus:outline-hidden zs:focus-visible:ring-2 zs:focus-visible:ring-offset-2 \n zs:focus-visible:ring-blue-500\"\n aria-label=\"Activate dark theme\"\n [attr.aria-pressed]=\"currentTheme() === 'dark'\"\n >\n <i class=\"fas fa-moon\" aria-hidden=\"true\"></i>\n </button>\n </div>\n \n <!-- ========================= Toggle Button with Connector ========================= -->\n <div \n class=\"zs:relative\"\n [ngClass]=\"isOpen() ? 'zs:hidden' : ''\"\n >\n <!-- Connector Line -->\n <div\n class=\"zs:absolute zs:top-1/2 zs:right-0 zs:h-0.5 zs:w-3 zs:transform zs:-translate-y-1/2\n zs:bg-gray-300 zs:dark:bg-gray-600\"\n aria-hidden=\"true\"\n ></div>\n \n <!-- Toggle Button -->\n <button\n (click)=\"toggleOpen()\"\n type=\"button\"\n class=\"zs:relative zs:z-100 zs:w-12 zs:h-12 zs:rounded-full zs:rounded-l-none zs:border-l-0 \n zs:border-2\n zs:transition-all zs:duration-300 zs:flex zs:items-center zs:justify-center\n zs:bg-white zs:text-gray-900 zs:border-gray-300\n zs:dark:bg-gray-800 zs:dark:text-gray-100 zs:dark:border-gray-600\n zs:hover:bg-gray-100 zs:dark:hover:bg-gray-700\n zs:focus:outline-hidden zs:focus-visible:ring-2 zs:focus-visible:ring-offset-2 \n zs:focus-visible:ring-blue-500\"\n aria-label=\"Toggle theme switcher\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-controls=\"theme-panel\"\n >\n @if (currentTheme() === 'dark') {\n <i class=\"fas fa-moon\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fas fa-sun zs:text-yellow-500\" aria-hidden=\"true\"></i>\n }\n </button>\n </div>\n </div>\n </div>\n}", styles: [":host{display:block}\n"] }]
|
|
2016
2060
|
}], ctorParameters: () => [], propDecorators: { bodyClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "bodyClass", required: false }] }], showDefaultUI: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDefaultUI", required: false }] }], setManualTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "setManualTheme", required: false }] }], fromTop: [{ type: i0.Input, args: [{ isSignal: true, alias: "fromTop", required: false }] }], themeChangeEv: [{ type: i0.Output, args: ["themeChangeEv"] }], onDocumentClick: [{
|
|
2017
2061
|
type: HostListener,
|
|
2018
2062
|
args: ['document:click', ['$event']]
|