purity-world-ui 1.0.1
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.
- package/LICENSE +21 -0
- package/README.md +39 -0
- package/index.cjs +397 -0
- package/index.d.ts +1 -0
- package/index.js +1939 -0
- package/package.json +46 -0
- package/style.css +1 -0
- package/style.d.ts +1 -0
- package/styles/_base.scss +525 -0
- package/styles/_mixins.scss +57 -0
- package/styles/_theme-dark.scss +103 -0
- package/styles/_theme-light.scss +103 -0
- package/styles/_themes.scss +34 -0
- package/styles/_ui.scss +28 -0
- package/styles/_variables.scss +72 -0
- package/styles/index.scss +7 -0
- package/types/app/shared/behaviors/draggable/draggable.d.ts +14 -0
- package/types/app/shared/behaviors/draggable/draggable.d.ts.map +1 -0
- package/types/app/shared/behaviors/droppable/droppable.d.ts +23 -0
- package/types/app/shared/behaviors/droppable/droppable.d.ts.map +1 -0
- package/types/app/shared/components/date-time-picker/date-time-picker.component.d.ts +91 -0
- package/types/app/shared/components/date-time-picker/date-time-picker.component.d.ts.map +1 -0
- package/types/app/shared/components/expander/expander.component.d.ts +36 -0
- package/types/app/shared/components/expander/expander.component.d.ts.map +1 -0
- package/types/app/shared/components/loader/loader.component.d.ts +21 -0
- package/types/app/shared/components/loader/loader.component.d.ts.map +1 -0
- package/types/app/shared/components/modal/modal-view.component.d.ts +19 -0
- package/types/app/shared/components/modal/modal-view.component.d.ts.map +1 -0
- package/types/app/shared/components/navigation-menu/navigation-menu.component.d.ts +19 -0
- package/types/app/shared/components/navigation-menu/navigation-menu.component.d.ts.map +1 -0
- package/types/app/shared/components/notification/notification.component.d.ts +13 -0
- package/types/app/shared/components/notification/notification.component.d.ts.map +1 -0
- package/types/app/shared/components/popover/popover.component.d.ts +45 -0
- package/types/app/shared/components/popover/popover.component.d.ts.map +1 -0
- package/types/app/shared/components/radial-context-menu/radial-context-menu.component.d.ts +57 -0
- package/types/app/shared/components/radial-context-menu/radial-context-menu.component.d.ts.map +1 -0
- package/types/app/shared/components/switch-button/switch-button.component.d.ts +27 -0
- package/types/app/shared/components/switch-button/switch-button.component.d.ts.map +1 -0
- package/types/app/shared/directives/dropdown/dropdown.directive.d.ts +35 -0
- package/types/app/shared/directives/dropdown/dropdown.directive.d.ts.map +1 -0
- package/types/app/shared/directives/highlight/highlight.directive.d.ts +11 -0
- package/types/app/shared/directives/highlight/highlight.directive.d.ts.map +1 -0
- package/types/app/shared/interceptors/auth.interceptor.d.ts +11 -0
- package/types/app/shared/interceptors/auth.interceptor.d.ts.map +1 -0
- package/types/app/shared/interceptors/logging.interceptor.d.ts +9 -0
- package/types/app/shared/interceptors/logging.interceptor.d.ts.map +1 -0
- package/types/app/shared/pipes/date.pipe.d.ts +10 -0
- package/types/app/shared/pipes/date.pipe.d.ts.map +1 -0
- package/types/app/shared/pipes/transform-sample.pipe.d.ts +5 -0
- package/types/app/shared/pipes/transform-sample.pipe.d.ts.map +1 -0
- package/types/app/shared/pipes/uppercase.pipe.d.ts +5 -0
- package/types/app/shared/pipes/uppercase.pipe.d.ts.map +1 -0
- package/types/app/shared/validators/forms-validation.validator.d.ts +6 -0
- package/types/app/shared/validators/forms-validation.validator.d.ts.map +1 -0
- package/types/app/shared/widgets/analogue-clock/analogue-clock.component.d.ts +84 -0
- package/types/app/shared/widgets/analogue-clock/analogue-clock.component.d.ts.map +1 -0
- package/types/data/notify.service.d.ts +65 -0
- package/types/data/notify.service.d.ts.map +1 -0
- package/types/data/theme.service.d.ts +20 -0
- package/types/data/theme.service.d.ts.map +1 -0
- package/types/framework/bootstrap.d.ts +42 -0
- package/types/framework/bootstrap.d.ts.map +1 -0
- package/types/framework/component.d.ts +57 -0
- package/types/framework/component.d.ts.map +1 -0
- package/types/framework/core.d.ts +46 -0
- package/types/framework/core.d.ts.map +1 -0
- package/types/framework/di.d.ts +53 -0
- package/types/framework/di.d.ts.map +1 -0
- package/types/framework/directive.d.ts +47 -0
- package/types/framework/directive.d.ts.map +1 -0
- package/types/framework/http.d.ts +211 -0
- package/types/framework/http.d.ts.map +1 -0
- package/types/framework/pipe.d.ts +34 -0
- package/types/framework/pipe.d.ts.map +1 -0
- package/types/framework/router.d.ts +145 -0
- package/types/framework/router.d.ts.map +1 -0
- package/types/framework/seo.d.ts +134 -0
- package/types/framework/seo.d.ts.map +1 -0
- package/types/framework/validator.d.ts +73 -0
- package/types/framework/validator.d.ts.map +1 -0
- package/types/framework/virtual-for.d.ts +36 -0
- package/types/framework/virtual-for.d.ts.map +1 -0
- package/types/ui.d.ts +30 -0
- package/types/ui.d.ts.map +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Purity Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Purity World UI
|
|
2
|
+
|
|
3
|
+
Rich Adwaita glassmorphic UI components, directives, widgets, and interaction behaviors for Purity Framework (`purity-world`).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install purity-world purity-world-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { signal } from 'purity-world/core';
|
|
15
|
+
import { DropdownComponent, SwitchButtonComponent, ModalViewComponent } from 'purity-world-ui';
|
|
16
|
+
import 'purity-world/styles';
|
|
17
|
+
import 'purity-world-ui/styles';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Included Components & Directives
|
|
21
|
+
|
|
22
|
+
- `<dropdown>` / `[dropdown]` (`DropdownComponent` / `DropdownDirective`)
|
|
23
|
+
- `<switch-button>` (`SwitchButtonComponent`)
|
|
24
|
+
- `<modal-view>` (`ModalViewComponent`)
|
|
25
|
+
- `<date-time-picker>` (`DateTimePickerComponent`)
|
|
26
|
+
- `<notification-component>` (`NotificationComponent`)
|
|
27
|
+
- `<loader-component>` (`LoaderComponent`)
|
|
28
|
+
- `<popover-component>` (`PopoverComponent`)
|
|
29
|
+
- `<radial-context-menu>` (`RadialContextMenuComponent`)
|
|
30
|
+
- `<expander>` (`ExpanderComponent`)
|
|
31
|
+
- `<navigation-menu>` (`NavigationMenuComponent`)
|
|
32
|
+
- `<analogue-clock>` (`AnalogueClockComponent`)
|
|
33
|
+
- `[highlight]` (`HighlightDirective`)
|
|
34
|
+
- `drag` / `draggable`, `droppable` behaviors
|
|
35
|
+
- `ThemeService`, `NotifyService`
|
|
36
|
+
|
|
37
|
+
## License
|
|
38
|
+
|
|
39
|
+
MIT
|
package/index.cjs
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("purity-world/core");var t=class extends e.BaseDirective{isOpen=!1;triggerEl=null;labelEl=null;bodyEl=null;boundDocClick;boundKeydown;boundTriggerClick;boundBodyClick;boundResize;boundScroll;isCustomTrigger=!1;openedAt=0;onInit(){let e=this.element;!e||e.hasAttribute(`data-dropdown-ready`)||(e.setAttribute(`data-dropdown-ready`,`true`),e.classList.add(`p-dropdown`),this.setupDOM(),this.bindEvents())}onChanges(e){e!=null&&!this.isCustomTrigger&&this.labelEl&&(this.labelEl.textContent=String(e))}onDOMChange(e){if(this.element&&e instanceof MutationRecord){if(e.attributeName===`label`||e.attributeName===`placeholder`){let e=this.element.getAttribute(`label`)||this.element.getAttribute(`placeholder`);e&&this.labelEl&&!this.isCustomTrigger&&(this.labelEl.textContent=e)}else if(e.attributeName===`disabled`){let e=this.element.hasAttribute(`disabled`)&&this.element.getAttribute(`disabled`)!==`false`;this.triggerEl&&(e?this.triggerEl.setAttribute(`disabled`,``):this.triggerEl.removeAttribute(`disabled`))}else e.attributeName===`align`&&this.isOpen&&this.updatePosition()}}open(){this.isOpen||this.isDisabled()||this.bodyEl&&(this.bodyEl.parentElement!==document.body&&document.body.appendChild(this.bodyEl),this.openedAt=Date.now(),this.isOpen=!0,this.element.classList.add(`dropdown-open`,`p-dropdown--open`),this.triggerEl&&this.triggerEl.setAttribute(`aria-expanded`,`true`),this.bodyEl.classList.add(`is-open`),this.updatePosition())}close(){this.isOpen&&(this.isOpen=!1,this.element.classList.remove(`dropdown-open`,`p-dropdown--open`),this.triggerEl&&this.triggerEl.setAttribute(`aria-expanded`,`false`),this.bodyEl&&this.bodyEl.classList.remove(`is-open`))}toggle(){this.isOpen?this.close():this.open()}setLabel(e){this.labelEl&&(this.labelEl.textContent=e)}updatePosition(){if(!this.triggerEl||!this.bodyEl)return;let e=this.triggerEl.getBoundingClientRect(),t=this.bodyEl.getBoundingClientRect(),n=window.innerHeight,r=window.innerWidth,i=t.height||220,a=t.width||e.width||180,o=n-e.bottom,s=e.top,c=this.element.getAttribute(`placement`),l=!1;c===`top`?l=!0:c===`bottom`?l=!1:o<220&&s>o&&(l=!0),this.bodyEl.classList.toggle(`placement-top`,l),this.bodyEl.classList.toggle(`placement-bottom`,!l);let u=l?e.top-i-6:e.bottom+6,d=e.left;(this.element.getAttribute(`align`)===`right`||d+a>r-10)&&(d=Math.max(10,e.right-a)),u<10&&(u=10),u+i>n-10&&(u=Math.max(10,n-i-10)),d<10&&(d=10);let f=Math.max(e.width,160);this.bodyEl.style.minWidth=`${f}px`,this.bodyEl.style.top=`${Math.round(u)}px`,this.bodyEl.style.left=`${Math.round(d)}px`}onDestroy(){this.boundDocClick&&document.removeEventListener(`pointerdown`,this.boundDocClick),this.boundKeydown&&window.removeEventListener(`keydown`,this.boundKeydown),this.boundResize&&window.removeEventListener(`resize`,this.boundResize),this.boundScroll&&window.removeEventListener(`scroll`,this.boundScroll,!0),this.triggerEl&&this.boundTriggerClick&&this.triggerEl.removeEventListener(`click`,this.boundTriggerClick),this.bodyEl&&this.boundBodyClick&&this.bodyEl.removeEventListener(`click`,this.boundBodyClick),this.bodyEl&&this.bodyEl.parentElement&&(this.bodyEl.parentElement.removeChild(this.bodyEl),this.bodyEl=null)}setupDOM(){let e=this.element,t=Array.from(e.childNodes),n=null;for(let e of t)if(e instanceof HTMLElement&&(e.getAttribute(`slot`)===`trigger`||e.classList.contains(`dropdown-trigger`))){n=e;break}if(n)this.isCustomTrigger=!0,this.triggerEl=n;else{this.isCustomTrigger=!1;let t=e.getAttribute(`label`)||e.getAttribute(`placeholder`)||`Select option`,n=document.createElement(`button`);n.type=`button`,n.className=`dropdown-trigger`,n.setAttribute(`aria-haspopup`,`true`),n.setAttribute(`aria-expanded`,`false`),this.isDisabled()&&n.setAttribute(`disabled`,``);let r=document.createElement(`span`);r.className=`dropdown-label`,r.textContent=t;let i=document.createElement(`span`);i.className=`dropdown-chevron`,i.innerHTML=`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>`,n.appendChild(r),n.appendChild(i),this.triggerEl=n,this.labelEl=r}let r=document.createElement(`div`);r.className=`dropdown-body p-dropdown-body`,r.setAttribute(`role`,`menu`),r.setAttribute(`tabindex`,`-1`);for(let e of t)e!==n&&r.appendChild(e);e.innerHTML=``,this.triggerEl&&e.appendChild(this.triggerEl),document.body.appendChild(r),this.bodyEl=r}bindEvents(){let e=this.element;this.boundTriggerClick=e=>{e.preventDefault(),e.stopPropagation(),this.toggle()},this.triggerEl?.addEventListener(`click`,this.boundTriggerClick),this.boundBodyClick=t=>{let n=t.target;if(!n)return;let r=n.closest(`li, a, button, .dropdown-item`);if(!r||!this.bodyEl?.contains(r)||r.hasAttribute(`disabled`)||r.classList.contains(`disabled`)||r.getAttribute(`aria-disabled`)===`true`)return;let i=r.textContent?.trim()||``,a=r.getAttribute(`data-value`)??r.getAttribute(`value`)??i;e.getAttribute(`auto-label`)!==`false`&&!this.isCustomTrigger&&this.labelEl&&i&&(this.labelEl.textContent=i),this.bodyEl.querySelectorAll(`li, a, button, .dropdown-item`).forEach(e=>{e.classList.remove(`is-selected`,`active`)}),r.classList.add(`is-selected`);let o={item:r,value:a,label:i};e.dispatchEvent(new CustomEvent(`change`,{bubbles:!0,composed:!0,detail:o})),e.dispatchEvent(new CustomEvent(`select`,{bubbles:!0,composed:!0,detail:o})),e.getAttribute(`keep-open`)===`true`||r.hasAttribute(`data-keep-open`)||this.close()},this.bodyEl?.addEventListener(`click`,this.boundBodyClick),this.boundDocClick=t=>{if(!this.isOpen||Date.now()-this.openedAt<100)return;let n=t.composedPath?t.composedPath():[],r=t.target;e&&(n.includes(e)||r&&e.contains(r))||this.bodyEl&&(n.includes(this.bodyEl)||r&&this.bodyEl.contains(r))||this.close()},document.addEventListener(`pointerdown`,this.boundDocClick),this.boundResize=()=>{this.isOpen&&this.updatePosition()},this.boundScroll=()=>{this.isOpen&&this.updatePosition()},window.addEventListener(`resize`,this.boundResize),window.addEventListener(`scroll`,this.boundScroll,!0),this.boundKeydown=e=>{if(!this.isOpen){(e.key===`Enter`||e.key===` `||e.key===`ArrowDown`)&&document.activeElement===this.triggerEl&&(e.preventDefault(),this.open());return}e.key===`Escape`?(e.preventDefault(),this.close(),this.triggerEl?.focus()):(e.key===`ArrowDown`||e.key===`ArrowUp`)&&(e.preventDefault(),this.navigateItems(e.key===`ArrowDown`?1:-1))},e.addEventListener(`keydown`,this.boundKeydown)}navigateItems(e){if(!this.bodyEl)return;let t=Array.from(this.bodyEl.querySelectorAll(`li, a, button, .dropdown-item:not(.disabled):not([disabled])`));if(t.length===0)return;let n=t.findIndex(e=>e===document.activeElement||e.contains(document.activeElement))+e;n<0&&(n=t.length-1),n>=t.length&&(n=0),t[n]?.focus()}isDisabled(){return this.element.hasAttribute(`disabled`)&&this.element.getAttribute(`disabled`)!==`false`}};(0,e.Directive)(`dropdown`)(t);var n=class extends e.BaseDirective{currentModifierClass=``;onInit(){this.element.classList.add(`p-highlight`),this.applyHighlightClass(this.value||`blue`)}onChanges(e){this.applyHighlightClass(e)}onDOMChange(e){if(`attributeName`in e||typeof MutationRecord<`u`&&e instanceof MutationRecord){let t=e.attributeName;if(t===`highlight`||t===`[highlight]`){let e=this.element.getAttribute(`highlight`)||this.element.getAttribute(`[highlight]`);e&&e!==this.value&&this.onChanges(e)}}else if(e instanceof Event&&e.type===`input`){let e=this.element;e.value&&e.value.length>5?this.element.classList.add(`p-highlight--valid`):this.element.classList.remove(`p-highlight--valid`)}}onDestroy(){this.element.classList.remove(`p-highlight`,`p-highlight--valid`),this.currentModifierClass&&this.element.classList.remove(this.currentModifierClass)}applyHighlightClass(e){if(this.currentModifierClass&&=(this.element.classList.remove(this.currentModifierClass),``),e){let t=e.replace(/^#|rgba?.*$/,``).trim().toLowerCase(),n=t.startsWith(`p-highlight--`)?t:`p-highlight--${t||`blue`}`;this.currentModifierClass=n,this.element.classList.add(n)}}};(0,e.Directive)(`highlight`)(n);var r=`<div class="switch-container {{isOn() ? 'is-on' : 'is-off'}} {{disabled() ? 'is-disabled' : ''}}">
|
|
2
|
+
<div class="switch-track" aria-hidden="true">
|
|
3
|
+
<div class="switch-thumb"></div>
|
|
4
|
+
</div>
|
|
5
|
+
<span class="switch-label">
|
|
6
|
+
<slot></slot>
|
|
7
|
+
</span>
|
|
8
|
+
</div>
|
|
9
|
+
`,i=class{isOn=(0,e.signal)(!1);checked=this.isOn;disabled=(0,e.signal)(!1);handleClick=e=>{this.disabled()||e.target?.closest(`a, button, input, textarea, select`)||this.toggle()};handleKeydown=e=>{this.disabled()||(e.key===` `||e.key===`Enter`)&&(e.preventDefault(),this.toggle())};onInit(){let t=this;if(t&&typeof t.getAttribute==`function`){let e=t.getAttribute(`checked`),n=t.getAttribute(`is-on`);(e!==null&&e!==`false`&&e!==`null`&&e!==`0`||n!==null&&n!==`false`&&n!==`null`&&n!==`0`)&&this.isOn.set(!0);let r=t.getAttribute(`disabled`);r!==null&&r!==`false`&&r!==`null`&&r!==`0`&&this.disabled.set(!0),t.hasAttribute(`role`)||t.setAttribute(`role`,`switch`),t.hasAttribute(`tabindex`)||t.setAttribute(`tabindex`,this.disabled()?`-1`:`0`),t.addEventListener(`click`,this.handleClick),t.addEventListener(`keydown`,this.handleKeydown)}(0,e.effect)(()=>{let e=this.isOn(),t=this;t&&t.classList&&(t.classList.toggle(`is-on`,e),t.classList.toggle(`is-checked`,e),t.setAttribute(`aria-checked`,String(e)))}),(0,e.effect)(()=>{let e=this.disabled(),t=this;t&&t.classList&&(t.classList.toggle(`is-disabled`,e),e?(t.setAttribute(`aria-disabled`,`true`),t.setAttribute(`tabindex`,`-1`)):(t.removeAttribute(`aria-disabled`),t.setAttribute(`tabindex`,`0`)))})}onDestroy(){let e=this;e&&typeof e.removeEventListener==`function`&&(e.removeEventListener(`click`,this.handleClick),e.removeEventListener(`keydown`,this.handleKeydown))}switchOn(){this.disabled()||this.isOn()||(this.isOn.set(!0),this.dispatchChangeEvent())}switchOff(){this.disabled()||this.isOn()&&(this.isOn.set(!1),this.dispatchChangeEvent())}toggle(){if(this.disabled())return;let e=!this.isOn();this.isOn.set(e),this.dispatchChangeEvent()}dispatchChangeEvent(){let e=this;e&&typeof e.dispatchEvent==`function`&&e.dispatchEvent(new CustomEvent(`change`,{detail:{checked:this.isOn(),isOn:this.isOn()},bubbles:!0,composed:!0}))}};(0,e.Component)({selector:`switch-button`,templateUrl:`./switch-button.component.html`,template:r})(i);var a=`<div
|
|
10
|
+
class="modal-backdrop {{isOpen() ? 'is-open' : 'is-closed'}} {{isMaximized() ? 'is-maximized' : ''}}"
|
|
11
|
+
onclick="onBackdropClick(event)"
|
|
12
|
+
>
|
|
13
|
+
<div class="modal-dialog window" onclick="event.stopPropagation()">
|
|
14
|
+
<div class="modal-header">
|
|
15
|
+
<div class="modal-title-area">
|
|
16
|
+
<span class="modal-icon">🪟</span>
|
|
17
|
+
<h3 class="modal-title">{{title()}}</h3>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="modal-controls">
|
|
20
|
+
<button
|
|
21
|
+
type="button"
|
|
22
|
+
class="modal-control-btn maximize-btn"
|
|
23
|
+
title="{{isMaximized() ? 'Restore' : 'Maximize'}}"
|
|
24
|
+
onclick="maximize()"
|
|
25
|
+
>
|
|
26
|
+
{{isMaximized() ? '🗗' : '🗖'}}
|
|
27
|
+
</button>
|
|
28
|
+
<button
|
|
29
|
+
type="button"
|
|
30
|
+
class="modal-control-btn close-btn"
|
|
31
|
+
title="Close"
|
|
32
|
+
onclick="close()"
|
|
33
|
+
>
|
|
34
|
+
✕
|
|
35
|
+
</button>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div class="modal-body">
|
|
40
|
+
<div class="modal-content-area">
|
|
41
|
+
<slot>
|
|
42
|
+
<p>Welcome to the <strong>Purity Modal Dialog Component</strong>.</p>
|
|
43
|
+
<p>
|
|
44
|
+
This modal is managed reactively via Purity signals with fixed viewport overlay and <code>z-index: 1000</code>.
|
|
45
|
+
</p>
|
|
46
|
+
<div class="modal-info-card">
|
|
47
|
+
<div><strong>Status:</strong> <span class="status-pill is-active">Active</span></div>
|
|
48
|
+
<div><strong>Maximized:</strong> {{isMaximized() ? 'Yes' : 'No'}}</div>
|
|
49
|
+
</div>
|
|
50
|
+
</slot>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="modal-footer">
|
|
55
|
+
<button type="button" class="button-cancel" onclick="close()">
|
|
56
|
+
Cancel
|
|
57
|
+
</button>
|
|
58
|
+
<button type="button" class="button-primary" onclick="close()">
|
|
59
|
+
Done
|
|
60
|
+
</button>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
`,o=class{isOpen=(0,e.signal)(!1);isMaximized=(0,e.signal)(!1);title=(0,e.signal)(`Purity Modal Dialog`);_hostEl;_backdropEl;keydownHandler=e=>{e.key===`Escape`&&this.isOpen()&&this.close()};onInit(){window.addEventListener(`keydown`,this.keydownHandler);let e=this;if(this._hostEl=e,e&&typeof e.getAttribute==`function`){let t=e.getAttribute(`title`);t&&this.title.set(t);let n=e.getAttribute(`is-open`)||e.getAttribute(`open`);n!==null&&n!==`false`&&n!==`null`&&n!==`0`&&this.isOpen.set(!0)}let t=e.querySelector(`.modal-backdrop`);t&&t.parentElement!==document.body&&(this._backdropEl=t,document.body.appendChild(t))}onDestroy(){window.removeEventListener(`keydown`,this.keydownHandler),this._backdropEl&&this._backdropEl.parentElement===document.body&&this._backdropEl.remove()}disconnectedCallback(){this.onDestroy()}open(e){e?.title&&this.title.set(e.title);let t=this._hostEl||this,n=this._backdropEl||t?.querySelector?.(`.modal-backdrop`);n&&n.parentElement!==document.body&&(this._backdropEl=n,document.body.appendChild(n)),this.isOpen.set(!0)}close(){this.isOpen.set(!1)}maximize(){this.isMaximized.update(e=>!e)}onBackdropClick(e){e.target===e.currentTarget&&this.close()}};(0,e.Component)({selector:`modal-view`,templateUrl:`./src/app/shared/components/modal/modal-view.component.html`,template:a})(o);var s=`<div class="date-time-picker-container">
|
|
65
|
+
<button
|
|
66
|
+
class="picker-toggle"
|
|
67
|
+
type="button"
|
|
68
|
+
aria-haspopup="dialog"
|
|
69
|
+
aria-expanded="{{isOpen() ? 'true' : 'false'}}"
|
|
70
|
+
onclick="togglePicker(event)"
|
|
71
|
+
>
|
|
72
|
+
<span class="picker-toggle-icon">📅</span>
|
|
73
|
+
<span class="picker-toggle-text">{{displayLabel}}</span>
|
|
74
|
+
</button>
|
|
75
|
+
|
|
76
|
+
<div
|
|
77
|
+
class="picker-overlay {{isOpen() ? 'is-open' : 'is-closed'}} {{enableBlur() ? 'blur-enabled' : ''}} {{placement()}} {{alignPlacement()}}"
|
|
78
|
+
role="dialog"
|
|
79
|
+
aria-label="Date and time picker"
|
|
80
|
+
>
|
|
81
|
+
<div class="calendar-header">
|
|
82
|
+
<div class="label-group">
|
|
83
|
+
<button
|
|
84
|
+
class="year-toggle-btn"
|
|
85
|
+
type="button"
|
|
86
|
+
aria-label="Toggle year picker"
|
|
87
|
+
onclick="toggleYearPicker()"
|
|
88
|
+
>
|
|
89
|
+
<span class="month-label">{{monthYearLabel}}</span>
|
|
90
|
+
<svg class="chevron-icon {{viewMode() === 'year' ? 'is-rotated' : ''}}" viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
91
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
92
|
+
</svg>
|
|
93
|
+
</button>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="header-nav">
|
|
96
|
+
<button
|
|
97
|
+
type="button"
|
|
98
|
+
class="nav-btn prev-btn"
|
|
99
|
+
aria-label="Previous month"
|
|
100
|
+
onclick="prevMonth()"
|
|
101
|
+
>
|
|
102
|
+
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
103
|
+
<polyline points="15 18 9 12 15 6"></polyline>
|
|
104
|
+
</svg>
|
|
105
|
+
</button>
|
|
106
|
+
<button
|
|
107
|
+
type="button"
|
|
108
|
+
class="nav-btn next-btn"
|
|
109
|
+
aria-label="Next month"
|
|
110
|
+
onclick="nextMonth()"
|
|
111
|
+
>
|
|
112
|
+
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
|
113
|
+
<polyline points="9 18 15 12 9 6"></polyline>
|
|
114
|
+
</svg>
|
|
115
|
+
</button>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<div class="picker-content-wrapper">
|
|
120
|
+
<div class="calendar-body {{viewMode() === 'year' ? 'blurred' : ''}}">
|
|
121
|
+
<div class="calendar-grid" onclick="onCalendarGridClick(event)">
|
|
122
|
+
<div class="weekday">Sun</div>
|
|
123
|
+
<div class="weekday">Mon</div>
|
|
124
|
+
<div class="weekday">Tue</div>
|
|
125
|
+
<div class="weekday">Wed</div>
|
|
126
|
+
<div class="weekday">Thu</div>
|
|
127
|
+
<div class="weekday">Fri</div>
|
|
128
|
+
<div class="weekday">Sat</div>
|
|
129
|
+
|
|
130
|
+
<button
|
|
131
|
+
for="let day of calendarDays"
|
|
132
|
+
class="{{day.cellClass}}"
|
|
133
|
+
type="button"
|
|
134
|
+
data-time="{{day.time}}"
|
|
135
|
+
>
|
|
136
|
+
{{day.dateNum}}
|
|
137
|
+
</button>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
<div class="year-selector-overlay {{viewMode() === 'year' ? 'is-visible' : 'is-hidden'}}">
|
|
142
|
+
<div class="year-grid" onclick="onYearGridClick(event)">
|
|
143
|
+
<button
|
|
144
|
+
for="let yr of years"
|
|
145
|
+
class="year-cell {{yr === viewYear ? 'selected' : ''}}"
|
|
146
|
+
type="button"
|
|
147
|
+
data-year="{{yr}}"
|
|
148
|
+
>
|
|
149
|
+
{{yr}}
|
|
150
|
+
</button>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<div class="time-picker">
|
|
156
|
+
<div class="time-label">
|
|
157
|
+
<span class="time-icon">🕒</span>
|
|
158
|
+
<span>Time:</span>
|
|
159
|
+
</div>
|
|
160
|
+
<div class="time-inner-container">
|
|
161
|
+
<div class="time-input-group">
|
|
162
|
+
<input
|
|
163
|
+
type="text"
|
|
164
|
+
inputmode="numeric"
|
|
165
|
+
pattern="\\d*"
|
|
166
|
+
maxlength="2"
|
|
167
|
+
value="{{workingHoursFormatted}}"
|
|
168
|
+
oninput="onHoursInput(this)"
|
|
169
|
+
onchange="onTimeChange()"
|
|
170
|
+
onkeydown="handleTimeKeydown(event, 'hours')"
|
|
171
|
+
onwheel="handleWheel(event, 'hours')"
|
|
172
|
+
aria-label="Hours"
|
|
173
|
+
title="Scroll middle mouse or use Up/Down arrows to change hours (00-23)"
|
|
174
|
+
/>
|
|
175
|
+
<span class="separator">:</span>
|
|
176
|
+
<input
|
|
177
|
+
type="text"
|
|
178
|
+
inputmode="numeric"
|
|
179
|
+
pattern="\\d*"
|
|
180
|
+
maxlength="2"
|
|
181
|
+
value="{{workingMinutesFormatted}}"
|
|
182
|
+
oninput="onMinutesInput(this)"
|
|
183
|
+
onchange="onTimeChange()"
|
|
184
|
+
onkeydown="handleTimeKeydown(event, 'minutes')"
|
|
185
|
+
onwheel="handleWheel(event, 'minutes')"
|
|
186
|
+
aria-label="Minutes"
|
|
187
|
+
title="Scroll middle mouse or use Up/Down arrows to change minutes (00-59)"
|
|
188
|
+
/>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div class="picker-footer">
|
|
194
|
+
<button
|
|
195
|
+
class="confirm-button"
|
|
196
|
+
type="button"
|
|
197
|
+
onclick="confirmSelection()"
|
|
198
|
+
>
|
|
199
|
+
OK
|
|
200
|
+
</button>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
`,c=class{isOpen=(0,e.signal)(!1);selectedDate=(0,e.signal)(null);viewDate=(0,e.signal)(new Date);enableBlur=(0,e.signal)(!1);restrictions=(0,e.signal)(null);workingDate=(0,e.signal)(null);workingHours=(0,e.signal)(12);workingMinutes=(0,e.signal)(0);viewMode=(0,e.signal)(`calendar`);placement=(0,e.signal)(`placement-bottom`);alignPlacement=(0,e.signal)(`align-left`);onDateSelected;_hostEl;_overlayEl;_openedAt=0;_boundDocClick;_boundKeydown;_boundResize;_boundScroll;getHost(){if(this._hostEl)return this._hostEl;let e=this;return e&&typeof e.querySelector==`function`?e:null}onInit(){let e=this;this._hostEl=e,this.initWorkingState();let t=e.getAttribute?.(`value`)||e.getAttribute?.(`selected-date`);if(t){let e=new Date(t);isNaN(e.getTime())||(this.selectedDate.set(e),this.viewDate.set(new Date(e)),this.workingDate.set(new Date(e)),this.workingHours.set(e.getHours()),this.workingMinutes.set(e.getMinutes()))}let n=e.querySelector(`.picker-overlay`);n&&(this._overlayEl=n,n.parentElement!==document.body&&document.body.appendChild(n),n.classList.toggle(`blur-enabled`,this.enableBlur())),this._boundDocClick=t=>{if(!this.isOpen()||Date.now()-this._openedAt<200)return;let n=t.composedPath?t.composedPath():[],r=t.target;e&&(n.includes(e)||r&&e.contains(r))||this._overlayEl&&(n.includes(this._overlayEl)||r&&this._overlayEl.contains(r))||this.close()},this._boundKeydown=e=>{this.isOpen()&&e.key===`Escape`&&this.close()},this._boundResize=()=>{this.isOpen()&&this.updateOverlayPosition()},this._boundScroll=()=>{this.isOpen()&&this.updateOverlayPosition()},document.addEventListener(`click`,this._boundDocClick),window.addEventListener(`keydown`,this._boundKeydown),window.addEventListener(`resize`,this._boundResize),window.addEventListener(`scroll`,this._boundScroll,!0)}onDestroy(){this._boundDocClick&&document.removeEventListener(`click`,this._boundDocClick),this._boundKeydown&&window.removeEventListener(`keydown`,this._boundKeydown),this._boundResize&&window.removeEventListener(`resize`,this._boundResize),this._boundScroll&&window.removeEventListener(`scroll`,this._boundScroll,!0),this._overlayEl&&this._overlayEl.parentNode&&(this._overlayEl.parentNode.removeChild(this._overlayEl),this._overlayEl=void 0)}disconnectedCallback(){this.onDestroy()}get effectiveMinDate(){let e=this.restrictions();if(!e)return null;let t=new Date,n=new Date(t.getFullYear(),t.getMonth(),t.getDate()),r=[];if(e.minDate&&r.push(e.minDate.getTime()),e.daysBack!==void 0&&r.push(n.getTime()-e.daysBack*864e5),e.weeksBack!==void 0&&r.push(n.getTime()-e.weeksBack*7*864e5),e.monthsBack!==void 0){let t=new Date(n);t.setMonth(t.getMonth()-e.monthsBack),r.push(t.getTime())}if(e.yearsBack!==void 0){let t=new Date(n);t.setFullYear(t.getFullYear()-e.yearsBack),r.push(t.getTime())}e.futureOnly&&r.push(t.getTime());let i=r.filter(e=>e!==null);return i.length>0?new Date(Math.max(...i)):null}get effectiveMaxDate(){let e=this.restrictions();if(!e)return null;let t=new Date,n=new Date(t.getFullYear(),t.getMonth(),t.getDate(),23,59,59,999),r=[];if(e.maxDate&&r.push(e.maxDate.getTime()),e.daysForward!==void 0&&r.push(n.getTime()+e.daysForward*864e5),e.weeksForward!==void 0&&r.push(n.getTime()+e.weeksForward*7*864e5),e.monthsForward!==void 0){let t=new Date(n);t.setMonth(t.getMonth()+e.monthsForward),r.push(t.getTime())}if(e.yearsForward!==void 0){let t=new Date(n);t.setFullYear(t.getFullYear()+e.yearsForward),r.push(t.getTime())}e.pastOnly&&r.push(t.getTime());let i=r.filter(e=>e!==null);return i.length>0?new Date(Math.min(...i)):null}get displayLabel(){let e=this.selectedDate();return e?`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)} ${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}`:`Select Date & Time`}get monthYearLabel(){return this.viewDate().toLocaleDateString(void 0,{month:`long`,year:`numeric`})}get viewYear(){return this.viewDate().getFullYear()}get workingHoursFormatted(){return String(this.workingHours()).padStart(2,`0`)}get workingMinutesFormatted(){return String(this.workingMinutes()).padStart(2,`0`)}get calendarDays(){let e=this.viewDate(),t=e.getFullYear(),n=e.getMonth(),r=new Date(t,n,1),i=new Date(t,n+1,0),a=r.getDay(),o=i.getDate(),s=[],c=new Date,l=this.workingDate(),u=new Date(t,n,0).getDate();for(let e=a-1;e>=0;e--){let r=new Date(t,n-1,u-e);s.push(this.createCalendarDay(r,!1,c,l))}for(let e=1;e<=o;e++){let r=new Date(t,n,e);s.push(this.createCalendarDay(r,!0,c,l))}let d=42-s.length;for(let e=1;e<=d;e++){let r=new Date(t,n+1,e);s.push(this.createCalendarDay(r,!1,c,l))}return s}get years(){let e=this.viewYear,t=[],n=e-12,r=e+15;for(let e=n;e<=r;e++)t.push(e);return t}createCalendarDay(e,t,n,r){let i=e.getDate()===n.getDate()&&e.getMonth()===n.getMonth()&&e.getFullYear()===n.getFullYear(),a=r!==null&&e.getDate()===r.getDate()&&e.getMonth()===r.getMonth()&&e.getFullYear()===r.getFullYear(),o=this.isDateDisabled(e),s=[`day-cell`];return t||s.push(`off-month`),i&&s.push(`today`),a&&s.push(`selected`),o&&s.push(`disabled`),{date:e,time:e.getTime(),dateNum:e.getDate(),isCurrentMonth:t,isToday:i,isSelected:a,isDisabled:o,cellClass:s.join(` `)}}isDateDisabled(e){let t=this.effectiveMinDate,n=this.effectiveMaxDate,r=new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime();if(t&&r<new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()||n&&r>new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime())return!0;let i=this.restrictions();if(i?.disabledDates&&i.disabledDates.length>0){for(let t of i.disabledDates)if(e.getDate()===t.getDate()&&e.getMonth()===t.getMonth()&&e.getFullYear()===t.getFullYear())return!0}return!1}initWorkingState(){let e=this.selectedDate();if(e)this.workingDate.set(new Date(e)),this.workingHours.set(e.getHours()),this.workingMinutes.set(e.getMinutes()),this.viewDate.set(new Date(e.getFullYear(),e.getMonth(),1));else{let e=new Date;this.workingDate.set(null),this.workingHours.set(12),this.workingMinutes.set(0),this.viewDate.set(new Date(e.getFullYear(),e.getMonth(),1))}this.enforceTimeRestrictions()}updateOverlayPosition(){let e=this.getHost(),t=this._overlayEl||e?.querySelector(`.picker-overlay`);if(!e||!t)return;let n=e.querySelector(`.picker-toggle`);if(!n)return;let r=n.getBoundingClientRect(),i=window.innerHeight,a=window.innerWidth,o=i-r.bottom,s=r.top,c=!1;o<380&&s>=380&&(c=!0),this.placement.set(c?`placement-top`:`placement-bottom`);let l=c?r.top-380-6:r.bottom+6,u=r.left;u+290>a-10?(u=Math.max(10,a-290-10),this.alignPlacement.set(`align-right`)):this.alignPlacement.set(`align-left`),l<10&&(l=10),l+380>i-10&&(l=Math.max(10,i-380-10)),t.style.top=`${l}px`,t.style.left=`${u}px`}togglePicker(e){e?.stopPropagation(),this.isOpen()?this.close():this.open()}open(){let e=this.getHost();if(!this._overlayEl&&e){let t=e.querySelector(`.picker-overlay`);t&&(this._overlayEl=t,t.parentElement!==document.body&&document.body.appendChild(t))}if(!this._overlayEl)return;this._openedAt=Date.now(),this.initWorkingState(),this.viewMode.set(`calendar`),this.updateOverlayPosition(),this.isOpen.set(!0),this._overlayEl.classList.add(`is-open`),this._overlayEl.classList.remove(`is-closed`),this._overlayEl.classList.toggle(`blur-enabled`,this.enableBlur());let t=this._overlayEl.querySelector(`.calendar-body`),n=this._overlayEl.querySelector(`.year-selector-overlay`);t&&t.classList.remove(`blurred`),n&&(n.classList.remove(`is-visible`),n.classList.add(`is-hidden`))}close(){this.isOpen.set(!1),this._overlayEl&&(this._overlayEl.classList.remove(`is-open`),this._overlayEl.classList.add(`is-closed`))}onCalendarGridClick(e){let t=e.target?.closest(`.day-cell`);if(t&&t.dataset.time){let e=Number(t.dataset.time);isNaN(e)||this.selectDayByTime(e)}}onYearGridClick(e){let t=e.target?.closest(`.year-cell`);if(t&&t.dataset.year){let e=Number(t.dataset.year);isNaN(e)||this.selectYear(e)}}selectDayByTime(e){let t=new Date(e);this.createCalendarDay(t,!0,new Date,null).isDisabled||(this.workingDate.set(t),(t.getMonth()!==this.viewDate().getMonth()||t.getFullYear()!==this.viewDate().getFullYear())&&this.viewDate.set(new Date(t.getFullYear(),t.getMonth(),1)),this.enforceTimeRestrictions())}toggleYearPicker(){let e=this.viewMode()===`calendar`?`year`:`calendar`;if(this.viewMode.set(e),this._overlayEl){let t=this._overlayEl.querySelector(`.calendar-body`),n=this._overlayEl.querySelector(`.year-selector-overlay`);t&&t.classList.toggle(`blurred`,e===`year`),n&&(n.classList.toggle(`is-visible`,e===`year`),n.classList.toggle(`is-hidden`,e!==`year`))}}selectYear(e){let t=this.viewDate();if(this.viewDate.set(new Date(e,t.getMonth(),1)),this.viewMode.set(`calendar`),this._overlayEl){let e=this._overlayEl.querySelector(`.calendar-body`),t=this._overlayEl.querySelector(`.year-selector-overlay`);e&&e.classList.remove(`blurred`),t&&(t.classList.remove(`is-visible`),t.classList.add(`is-hidden`))}}prevMonth(){let e=this.viewDate();this.viewDate.set(new Date(e.getFullYear(),e.getMonth()-1,1))}nextMonth(){let e=this.viewDate();this.viewDate.set(new Date(e.getFullYear(),e.getMonth()+1,1))}onHoursInput(e){let t=e.value.replace(/\D/g,``),n=parseInt(t,10);isNaN(n)&&(n=0),n>23&&(n=23),n<0&&(n=0),this.workingHours.set(n)}onMinutesInput(e){let t=e.value.replace(/\D/g,``),n=parseInt(t,10);isNaN(n)&&(n=0),n>59&&(n=59),n<0&&(n=0),this.workingMinutes.set(n)}onTimeChange(){this.enforceTimeRestrictions()}handleTimeKeydown(e,t){let n=e.target,r=e.key;if(r===`ArrowUp`||r===`ArrowDown`){e.preventDefault(),e.stopPropagation();let i=r===`ArrowUp`?1:-1;if(t===`hours`||n.getAttribute(`aria-label`)===`Hours`){let e=this.workingHours()+i;e>23&&(e=0),e<0&&(e=23),this.workingHours.set(e),n.value=this.workingHoursFormatted}else{let e=this.workingMinutes()+i;e>59&&(e=0),e<0&&(e=59),this.workingMinutes.set(e),n.value=this.workingMinutesFormatted}this.onTimeChange(),n.select();return}if(!([`Backspace`,`Tab`,`Enter`,`Escape`,`Delete`,`ArrowLeft`,`ArrowRight`,`Home`,`End`].includes(r)||e.ctrlKey&&[`a`,`c`,`v`,`x`].includes(r.toLowerCase()))){if(!/^\d$/.test(r)){e.preventDefault(),e.stopPropagation();return}n.selectionStart===n.selectionEnd&&n.value.length>=2&&(e.preventDefault(),e.stopPropagation())}}handleWheel(e,t){e.preventDefault(),e.stopPropagation();let n=e.deltaY<0?1:-1;if(t===`hours`){let e=this.workingHours()+n;e>23&&(e=0),e<0&&(e=23),this.workingHours.set(e)}else{let e=this.workingMinutes()+n;e>59&&(e=0),e<0&&(e=59),this.workingMinutes.set(e)}this.onTimeChange();let r=e.target;r&&(r.value=t===`hours`?this.workingHoursFormatted:this.workingMinutesFormatted,r.select())}confirmSelection(){let e=this.workingDate();if(!e&&(e=new Date,this.isDateDisabled(e)))return;let t=new Date(e.getFullYear(),e.getMonth(),e.getDate(),this.workingHours(),this.workingMinutes(),0,0);this.selectedDate.set(t),this.emitSelection(),this.close()}enforceTimeRestrictions(){let e=this.workingDate(),t=this.restrictions();if(t&&(e&&t.minDate&&e.getDate()===t.minDate.getDate()&&e.getMonth()===t.minDate.getMonth()&&e.getFullYear()===t.minDate.getFullYear()||!e)){let e=this.workingHours()*60+this.workingMinutes();if(t.minTime){let[n,r]=t.minTime.split(`:`).map(Number);e<n*60+r&&this.setWorkingTime(n,r)}if(t.maxTime){let[n,r]=t.maxTime.split(`:`).map(Number);e>n*60+r&&this.setWorkingTime(n,r)}}}setWorkingTime(e,t){this.workingHours.set(e),this.workingMinutes.set(t)}setDate(e){this.selectedDate.set(e),this.initWorkingState()}setRestrictions(e){this.restrictions.set(e),this.enforceTimeRestrictions()}setBlur(e){this.enableBlur.set(e),this._overlayEl&&this._overlayEl.classList.toggle(`blur-enabled`,e)}emitSelection(){let e=this.selectedDate();if(e){this.onDateSelected?.(e);let t=this.getHost();t?.dispatchEvent?.(new CustomEvent(`date-selected`,{detail:{date:e},bubbles:!0,composed:!0})),t?.dispatchEvent?.(new CustomEvent(`change`,{detail:{date:e,value:e},bubbles:!0,composed:!0}))}}get value(){return this.selectedDate()}set value(e){if(!e){this.selectedDate.set(null);return}let t=e instanceof Date?e:new Date(e);isNaN(t.getTime())||(this.selectedDate.set(t),this.viewDate.set(new Date(t)),this.workingDate.set(new Date(t)),this.workingHours.set(t.getHours()),this.workingMinutes.set(t.getMinutes()))}};(0,e.Component)({selector:`date-time-picker`,templateUrl:`./src/app/shared/components/date-time-picker/date-time-picker.component.html`,template:s})(c);var l=`<div class="notification-container" aria-live="polite">
|
|
205
|
+
<div for="let group of positionGroups" class="toast-stack pos-{{group.position}}">
|
|
206
|
+
<div
|
|
207
|
+
for="let item of group.items"
|
|
208
|
+
class="toast-card toast-{{item.type}} {{item.blink ? 'toast-blink' : ''}}"
|
|
209
|
+
style="{{item.width ? 'width: ' + item.width + ';' : ''}} {{item.height ? 'height: ' + item.height + ';' : ''}}"
|
|
210
|
+
>
|
|
211
|
+
<div class="toast-icon-wrapper">
|
|
212
|
+
<span class="toast-icon icon-{{item.type}}"></span>
|
|
213
|
+
</div>
|
|
214
|
+
<div class="toast-body">
|
|
215
|
+
<div class="toast-title">{{item.title}}</div>
|
|
216
|
+
<div class="toast-subtitle">{{item.subtitle}}</div>
|
|
217
|
+
</div>
|
|
218
|
+
<button
|
|
219
|
+
type="button"
|
|
220
|
+
class="toast-close-btn"
|
|
221
|
+
title="Close notification"
|
|
222
|
+
onclick="dismiss(item.id)"
|
|
223
|
+
>
|
|
224
|
+
<span class="toast-countdown">{{item.remainingSeconds ? item.remainingSeconds + 's' : ''}}</span>
|
|
225
|
+
<span class="toast-close-icon">✕</span>
|
|
226
|
+
</button>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
`,u=class{notifications=(0,e.signal)([]);timers=new Map;tickerInterval=null;ensureTicker(){this.tickerInterval||typeof window>`u`||(this.tickerInterval=setInterval(()=>{let e=this.notifications();if(e.length===0){clearInterval(this.tickerInterval),this.tickerInterval=null;return}let t=!1,n=e.map(e=>e.duration>0&&e.remainingSeconds>0?(t=!0,{...e,remainingSeconds:Math.max(0,e.remainingSeconds-1)}):e);t&&this.notifications.set(n)},1e3))}notify(e){let t=e.id||`notify_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,n=e.duration===void 0?1e4:e.duration,r=n>0?Math.ceil(n/1e3):0,i={id:t,type:e.type||`info`,title:e.title,subtitle:e.subtitle||``,position:e.position||`top-right`,duration:n,remainingSeconds:r,blink:e.blink===!0,width:e.width||``,height:e.height||``,dismissible:e.dismissible!==!1,createdAt:Date.now(),onClose:e.onClose};if(this.notifications.update(e=>[...e,i]),n>0&&typeof window<`u`){let e=setTimeout(()=>{this.dismiss(t)},n);this.timers.set(t,e),this.ensureTicker()}return t}success(e,t,n){return this.notify({...n,type:`success`,title:e,subtitle:t})}error(e,t,n){return this.notify({...n,type:`error`,title:e,subtitle:t})}warn(e,t,n){return this.notify({...n,type:`warn`,title:e,subtitle:t})}info(e,t,n){return this.notify({...n,type:`info`,title:e,subtitle:t})}dismiss(e){let t=this.timers.get(e);t&&(clearTimeout(t),this.timers.delete(e));let n=this.notifications(),r=n.find(t=>t.id===e);if(r&&r.onClose)try{r.onClose()}catch(e){console.error(`[NotifyService] Error in onClose handler:`,e)}let i=n.filter(t=>t.id!==e);i.length===0&&this.tickerInterval&&(clearInterval(this.tickerInterval),this.tickerInterval=null),this.notifications.set(i)}clear(){for(let e of this.timers.values())clearTimeout(e);this.timers.clear(),this.tickerInterval&&=(clearInterval(this.tickerInterval),null),this.notifications.set([])}};(0,e.Injectable)(`NotifyService`)(u);var d=[`top-right`,`top-left`,`top-center`,`bottom-right`,`bottom-left`,`bottom-center`,`center`],f=class{notifyService=(0,e.inject)(u);positionGroups=(0,e.signal)([]);onInit(){(0,e.effect)(()=>{let e=this.notifyService.notifications(),t=[];for(let n of d){let r=e.filter(e=>e.position===n);r.length>0&&t.push({position:n,items:r})}this.positionGroups.set(t)})}dismiss(e){this.notifyService.dismiss(e)}};(0,e.Component)({selector:`notification-component`,templateUrl:`./src/app/shared/components/notification/notification.component.html`,template:l})(f);var p=`<div class="loader-inline-root {{isLoading() ? 'visible' : ''}}" aria-hidden="{{!isLoading()}}">
|
|
231
|
+
<div class="loader-spinner-box">
|
|
232
|
+
<svg class="loader-svg" viewBox="0 0 50 50" aria-label="Loading">
|
|
233
|
+
<circle class="loader-track" cx="25" cy="25" r="20" fill="none" stroke-width="4"></circle>
|
|
234
|
+
<circle class="loader-head" cx="25" cy="25" r="20" fill="none" stroke-width="4"></circle>
|
|
235
|
+
</svg>
|
|
236
|
+
</div>
|
|
237
|
+
<span class="loader-text">{{message()}}</span>
|
|
238
|
+
</div>
|
|
239
|
+
`,m=class{isLoading=(0,e.signal)(!1);message=(0,e.signal)(`Loading...`);isHoldingCursor=!1;onInit(){let t=this.element||this;if(t&&typeof t.getAttribute==`function`){let e=t.getAttribute(`message`);e&&this.message.set(e);let n=t.getAttribute(`is-loading`);n!==null&&n!==`false`&&n!==`null`&&n!==`0`&&this.isLoading.set(!0)}(0,e.effect)(()=>{let n=this.isLoading();t&&t.classList.toggle(`is-loading`,n),n&&!this.isHoldingCursor?(this.isHoldingCursor=!0,(0,e.startLoadingCursor)()):!n&&this.isHoldingCursor&&(this.isHoldingCursor=!1,(0,e.stopLoadingCursor)())})}onDestroy(){this.isHoldingCursor&&(this.isHoldingCursor=!1,(0,e.stopLoadingCursor)())}show(e=`Loading...`){this.message.set(e||`Loading...`),this.isLoading.set(!0)}hide(){this.isLoading.set(!1)}toggle(e,t=`Loading...`){this.message.set(t||`Loading...`),e===void 0?this.isLoading.update(e=>!e):this.isLoading.set(e)}};(0,e.Component)({selector:`loader-component`,templateUrl:`./src/app/shared/components/loader/loader.component.html`,template:p})(m);var h=`<div class="purity-popover-portal {{isOpen() ? 'is-open' : 'is-closed'}} pos-{{effectivePosition()}}">
|
|
240
|
+
<div class="popover-arrow"></div>
|
|
241
|
+
<div class="popover-surface">
|
|
242
|
+
<slot>Popover content</slot>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
`,g=class{isOpen=(0,e.signal)(!1);targetFor=(0,e.signal)(``);position=(0,e.signal)(`bottom`);effectivePosition=(0,e.signal)(`bottom`);offset=8;closeDelay=120;_portalEl=null;_targetEl=null;_closeTimer=null;_boundOnTargetEnter=()=>this.handleTargetEnter();_boundOnTargetLeave=()=>this.handleTargetLeave();_boundOnPopoverEnter=()=>this.handlePopoverEnter();_boundOnPopoverLeave=()=>this.handlePopoverLeave();_boundOnWindowChange=()=>{this.isOpen()&&this.updatePosition()};onInit(){let t=this,n=t.getAttribute?.(`target-for`)||t.getAttribute?.(`target`);if(n){let e=n.replace(/^['"]|['"]$/g,``).trim();this.targetFor.set(e)}let r=t.getAttribute?.(`position`);if(r){let e=r.replace(/^['"]|['"]$/g,``).trim();[`top`,`bottom`,`left`,`right`].includes(e)&&(this.position.set(e),this.effectivePosition.set(e))}let i=t.getAttribute?.(`offset`);if(i){let e=parseInt(i,10);isNaN(e)||(this.offset=e)}this._portalEl=t.querySelector?.(`.purity-popover-portal`),this._portalEl&&this._portalEl.parentElement!==document.body&&document.body.appendChild(this._portalEl),this._portalEl&&(this._portalEl.addEventListener(`mouseenter`,this._boundOnPopoverEnter),this._portalEl.addEventListener(`mouseleave`,this._boundOnPopoverLeave)),this.bindTargetListeners(),(0,e.effect)(()=>{this.targetFor()&&this.bindTargetListeners()}),(0,e.effect)(()=>{let e=this.position();e&&(this.effectivePosition.set(e),this.isOpen()&&this.updatePosition())}),window.addEventListener(`resize`,this._boundOnWindowChange,{passive:!0}),window.addEventListener(`scroll`,this._boundOnWindowChange,{passive:!0,capture:!0})}onDestroy(){this.clearCloseTimer(),this.unbindTargetListeners(),this._portalEl&&(this._portalEl.removeEventListener(`mouseenter`,this._boundOnPopoverEnter),this._portalEl.removeEventListener(`mouseleave`,this._boundOnPopoverLeave),this._portalEl.parentElement===document.body&&this._portalEl.remove()),this._portalEl=null,this._targetEl=null,window.removeEventListener(`resize`,this._boundOnWindowChange),window.removeEventListener(`scroll`,this._boundOnWindowChange,!0)}disconnectedCallback(){this.onDestroy()}bindTargetListeners(){let e=this.targetFor();if(!e||typeof document>`u`)return;this.unbindTargetListeners();let t=document.querySelector(e);t&&(this._targetEl=t,t.addEventListener(`mouseenter`,this._boundOnTargetEnter),t.addEventListener(`mouseleave`,this._boundOnTargetLeave))}unbindTargetListeners(){this._targetEl&&=(this._targetEl.removeEventListener(`mouseenter`,this._boundOnTargetEnter),this._targetEl.removeEventListener(`mouseleave`,this._boundOnTargetLeave),null)}setTargetFor(e){this.targetFor.set(e.replace(/^['"]|['"]$/g,``).trim()),this.bindTargetListeners()}setPosition(e){[`top`,`bottom`,`left`,`right`].includes(e)&&(this.position.set(e),this.effectivePosition.set(e),this.isOpen()&&this.updatePosition())}open(e){if(this.clearCloseTimer(),e){if(typeof e==`string`){let t=document.querySelector(e);t&&(this._targetEl=t)}else e instanceof HTMLElement&&(this._targetEl=e)}if(!this._targetEl&&this.targetFor()&&(this._targetEl=document.querySelector(this.targetFor())),!this._portalEl){let e=this;this._portalEl=e?.querySelector?.(`.purity-popover-portal`)||document.querySelector(`.purity-popover-portal`),this._portalEl&&this._portalEl.parentElement!==document.body&&document.body.appendChild(this._portalEl)}this.isOpen.set(!0),this._portalEl&&(this._portalEl.classList.remove(`is-closed`),this._portalEl.classList.add(`is-open`)),requestAnimationFrame(()=>{this.updatePosition()})}close(){this.clearCloseTimer(),this.isOpen.set(!1),this._portalEl&&(this._portalEl.classList.remove(`is-open`),this._portalEl.classList.add(`is-closed`))}toggle(e){this.isOpen()?this.close():this.open(e)}updatePosition(){let e=this._portalEl,t=this._targetEl||(this.targetFor()?document.querySelector(this.targetFor()):null);if(!e||!t||typeof window>`u`)return;let n=t.getBoundingClientRect(),r=e.getBoundingClientRect(),i=r.width||200,a=r.height||80,o=window.innerWidth,s=window.innerHeight,c=this.offset,l=this.position(),u=0,d=0;if(l===`bottom`){let e=n.bottom+c+a>s-8,t=n.top-c-a>=8;e&&t&&(l=`top`)}else if(l===`top`){let e=n.top-c-a<8,t=n.bottom+c+a<=s-8;e&&t&&(l=`bottom`)}else if(l===`left`){let e=n.left-c-i<8,t=n.right+c+i<=o-8;e&&t&&(l=`right`)}else if(l===`right`){let e=n.right+c+i>o-8,t=n.left-c-i>=8;e&&t&&(l=`left`)}l===`bottom`?(u=n.bottom+c,d=n.left+(n.width-i)/2):l===`top`?(u=n.top-a-c,d=n.left+(n.width-i)/2):l===`left`?(u=n.top+(n.height-a)/2,d=n.left-i-c):l===`right`&&(u=n.top+(n.height-a)/2,d=n.right+c),d=Math.max(8,Math.min(d,o-i-8)),u=Math.max(8,Math.min(u,s-a-8)),e.style.top=`${Math.round(u)}px`,e.style.left=`${Math.round(d)}px`,e.classList.remove(`pos-top`,`pos-bottom`,`pos-left`,`pos-right`),e.classList.add(`pos-${l}`),this.effectivePosition.set(l)}handleTargetEnter(){this.open()}handleTargetLeave(){this.scheduleClose()}handlePopoverEnter(){this.clearCloseTimer()}handlePopoverLeave(){this.scheduleClose()}scheduleClose(){this.clearCloseTimer(),this._closeTimer=setTimeout(()=>{this.close()},this.closeDelay)}clearCloseTimer(){this._closeTimer&&=(clearTimeout(this._closeTimer),null)}},_=class extends e.BaseDirective{instance;onInit(){let e=this.element;if(!e||e.hasAttribute(`data-popover-ready`))return;e.setAttribute(`data-popover-ready`,`true`),e.style.display=`none`;let t=document.createElement(`div`);t.className=`purity-popover-portal is-closed pos-bottom`,t.innerHTML=`
|
|
246
|
+
<div class="popover-arrow"></div>
|
|
247
|
+
<div class="popover-surface"></div>
|
|
248
|
+
`;let n=t.querySelector(`.popover-surface`);for(;e.firstChild;)n.appendChild(e.firstChild);document.body.appendChild(t);let r=new g;r._portalEl=t;let i=e.getAttribute(`target-for`)||e.getAttribute(`target`);i&&r.setTargetFor(i);let a=e.getAttribute(`position`);a&&r.setPosition(a.replace(/^['"]|['"]$/g,``)),t.addEventListener(`mouseenter`,()=>r.handlePopoverEnter()),t.addEventListener(`mouseleave`,()=>r.handlePopoverLeave()),e.open=e=>r.open(e),e.close=()=>r.close(),e.toggle=e=>r.toggle(e),e.isOpen=()=>r.isOpen(),e.setPosition=e=>r.setPosition(e),e.setTargetFor=e=>r.setTargetFor(e),e.targetFor=r.targetFor,e.position=r.position,e.effectivePosition=r.effectivePosition,this.instance=r}onDestroy(){this.instance?.onDestroy()}};(0,e.Component)({selector:`popover-component`,templateUrl:`./src/app/shared/components/popover/popover.component.html`,template:h})(g),(0,e.Directive)(`popover`)(_);var v=`<div
|
|
249
|
+
class="radial-menu-root is-closed"
|
|
250
|
+
role="menu"
|
|
251
|
+
aria-label="Radial Context Menu"
|
|
252
|
+
>
|
|
253
|
+
<button
|
|
254
|
+
class="center-button"
|
|
255
|
+
type="button"
|
|
256
|
+
aria-label="Menu Center Action"
|
|
257
|
+
>
|
|
258
|
+
<span class="center-icon">×</span>
|
|
259
|
+
<span class="menu-title-pop"></span>
|
|
260
|
+
</button>
|
|
261
|
+
</div>
|
|
262
|
+
`,y=class{itemsSource=(0,e.signal)([]);navigationStack=(0,e.signal)([]);isOpen=(0,e.signal)(!1);coords=(0,e.signal)({x:0,y:0});radius=(0,e.signal)(150);activeHoverItem=(0,e.signal)(null);selector=(0,e.signal)(null);enableBlur=(0,e.signal)(!0);onSelectItem;onHover;onOpen;onClose;onNavigate;menuEl=null;titlePopEl=null;centerBtnEl=null;itemsContainerEl=null;_openedAt=0;_boundContextMenu;_boundClick;_boundKeydown;onInit(){this._boundContextMenu=e=>this.onDocumentContextMenu(e),this._boundClick=e=>this.onDocumentClick(e),this._boundKeydown=e=>this.onDocumentKeydown(e),this.createMenuDOM(),document.addEventListener(`contextmenu`,this._boundContextMenu),document.addEventListener(`click`,this._boundClick),window.addEventListener(`keydown`,this._boundKeydown)}onDestroy(){this._boundContextMenu&&document.removeEventListener(`contextmenu`,this._boundContextMenu),this._boundClick&&document.removeEventListener(`click`,this._boundClick),this._boundKeydown&&window.removeEventListener(`keydown`,this._boundKeydown),this.menuEl&&this.menuEl.parentNode&&this.menuEl.parentNode.removeChild(this.menuEl),this.menuEl=null,this.titlePopEl=null,this.centerBtnEl=null,this.itemsContainerEl=null}disconnectedCallback(){this.onDestroy()}createMenuDOM(){if(this.menuEl)return;let e=this.radius();this.menuEl=document.createElement(`div`),this.menuEl.className=`radial-menu`,this.enableBlur()&&this.menuEl.classList.add(`blur-enabled`),this.menuEl.style.width=`${e*2}px`,this.menuEl.style.height=`${e*2}px`,this.menuEl.style.display=`none`,this.menuEl.setAttribute(`role`,`menu`),this.menuEl.setAttribute(`aria-label`,`Radial Context Menu`),this.titlePopEl=document.createElement(`div`),this.titlePopEl.className=`menu-title-pop`,this.menuEl.appendChild(this.titlePopEl),this.centerBtnEl=document.createElement(`button`),this.centerBtnEl.className=`center-button`,this.centerBtnEl.type=`button`,this.centerBtnEl.setAttribute(`aria-label`,`Menu Center Action`),this.centerBtnEl.innerHTML=`<span class="center-icon">×</span>`,this.centerBtnEl.addEventListener(`click`,e=>{e.stopPropagation(),this.navigationStack().length>0?this.goBack():this.close()}),this.menuEl.appendChild(this.centerBtnEl),document.body.appendChild(this.menuEl)}get currentItems(){let e=this.navigationStack();return e.length===0?this.itemsSource():e[e.length-1].children||[]}get centerIcon(){return this.navigationStack().length>0?`←`:`×`}get centerTitle(){let e=this.activeHoverItem();if(e)return e.name;let t=this.navigationStack();return t.length>0?t[t.length-1].name:``}getPoint(e,t){let n=e*Math.PI/180;return{x:50+t*Math.cos(n),y:50+t*Math.sin(n)}}setItems(e){this.itemsSource.set(e),this.navigationStack.set([]),this.activeHoverItem.set(null),this.isOpen()&&(this.renderSegments(`in`),this.updateCenterButton())}setSelector(e){this.selector.set(e)}setBlur(e){this.enableBlur.set(e),this.menuEl&&(e?this.menuEl.classList.add(`blur-enabled`):this.menuEl.classList.remove(`blur-enabled`))}open(e,t){if(this.menuEl||this.createMenuDOM(),!this.menuEl)return;let n=this.radius(),r=e===void 0?window.innerWidth/2:e,i=t===void 0?window.innerHeight/2:t,a=Math.max(n+12,Math.min(window.innerWidth-n-12,r)),o=Math.max(n+12,Math.min(window.innerHeight-n-12,i));this.coords.set({x:a,y:o}),this.navigationStack.set([]),this.activeHoverItem.set(null),this.isOpen.set(!0),this._openedAt=Date.now(),this.menuEl.style.left=`${a-n}px`,this.menuEl.style.top=`${o-n}px`,this.menuEl.style.width=`${n*2}px`,this.menuEl.style.height=`${n*2}px`,this.menuEl.style.display=`block`,this.enableBlur()?this.menuEl.classList.add(`blur-enabled`):this.menuEl.classList.remove(`blur-enabled`),this.menuEl.offsetHeight,this.menuEl.classList.add(`active`),this.renderSegments(`in`),this.updateCenterButton(),this.onOpen?.(),this.emitEvent(`menu-open`,{x:a,y:o})}close(){this.menuEl&&(this.isOpen.set(!1),this.activeHoverItem.set(null),this.menuEl.classList.remove(`active`),this.onClose?.(),this.emitEvent(`menu-close`,{}),setTimeout(()=>{!this.isOpen()&&this.menuEl&&!this.menuEl.classList.contains(`active`)&&(this.menuEl.style.display=`none`)},300))}navigateTo(e){e.children&&e.children.length>0&&(this.navigationStack.update(t=>[...t,e]),this.activeHoverItem.set(null),this.renderSegments(`in`),this.updateCenterButton(),this.onNavigate?.(e,this.navigationStack().length),this.emitEvent(`menu-navigate`,{item:e,depth:this.navigationStack().length}))}goBack(){if(this.navigationStack().length>0){this.navigationStack.update(e=>e.slice(0,-1)),this.activeHoverItem.set(null),this.renderSegments(`out`),this.updateCenterButton();let e=this.navigationStack().length>0?this.navigationStack()[this.navigationStack().length-1]:null;this.onNavigate?.(e,this.navigationStack().length),this.emitEvent(`menu-back`,{current:e,depth:this.navigationStack().length})}else this.close()}updateCenterButton(){if(!this.centerBtnEl)return;let e=this.centerBtnEl.querySelector(`.center-icon`);if(e&&(e.textContent=this.centerIcon,this.activeHoverItem()?e.style.opacity=`0`:e.style.opacity=`1`),this.titlePopEl){let e=this.centerTitle;this.titlePopEl.textContent=e,this.activeHoverItem()?this.titlePopEl.classList.add(`visible`):this.titlePopEl.classList.remove(`visible`)}}renderSegments(e=`in`){if(!this.menuEl)return;let t=this.itemsContainerEl,n=document.createElement(`div`);n.className=`items-container entering`,e===`out`&&(n.className=`items-container exiting`);let r=this.currentItems,i=r.length;if(i>0){let e=360/i;r.forEach((t,r)=>{let i=this.createSegmentElement(t,r,e);n.appendChild(i)})}this.centerBtnEl?this.menuEl.insertBefore(n,this.centerBtnEl):this.menuEl.appendChild(n),this.itemsContainerEl=n,requestAnimationFrame(()=>{t&&(t.classList.add(e===`in`?`exiting`:`entering`),t.classList.remove(`active`),setTimeout(()=>{t.parentNode&&t.parentNode.removeChild(t)},400)),n.classList.remove(`entering`,`exiting`),n.classList.add(`active`)})}createSegmentElement(e,t,n){let r=t*n-90,i=(t+1)*n-90,a=r+n/2,o=document.createElement(`div`);o.className=`menu-segment`,e.children&&e.children.length>0&&o.classList.add(`has-children`),o.style.zIndex=`${t+1}`;let s=49.5,c=.5,l=[];for(let e=r;e<=i;e+=c)l.push(this.getPoint(e,s));l.push(this.getPoint(i,s));for(let e=i;e>=r;e-=c)l.push(this.getPoint(e,26));l.push(this.getPoint(r,26));let u=`polygon(${l.map(e=>`${e.x.toFixed(4)}% ${e.y.toFixed(4)}%`).join(`, `)})`;o.style.clipPath=u,o.style.webkitClipPath=u;let d=document.createElement(`div`);d.className=`segment-glass`,o.appendChild(d);let f=document.createElement(`div`);f.className=`segment-shine`,o.appendChild(f);let p=document.createElement(`span`);p.className=`segment-label`;let m=this.getPoint(a,38.5);if(p.style.left=`${m.x.toFixed(2)}%`,p.style.top=`${m.y.toFixed(2)}%`,e.image&&typeof e.image==`string`){let t=e.image.trim();if(t.startsWith(`<svg`))p.innerHTML=t;else if(t.endsWith(`.svg`)||t.startsWith(`data:image/svg`)||t.startsWith(`/`)||t.startsWith(`./`)||t.startsWith(`http`)){let n=document.createElement(`img`);n.src=t,n.className=`segment-icon`,n.alt=e.name,p.appendChild(n)}else p.textContent=t}else p.textContent=e.name;if(o.appendChild(p),e.children&&e.children.length>0){let e=document.createElement(`div`);e.className=`submenu-indicator`;let t=this.getPoint(a,47.2);e.style.left=`${t.x.toFixed(2)}%`,e.style.top=`${t.y.toFixed(2)}%`,o.appendChild(e)}return o.addEventListener(`click`,t=>{t.stopPropagation(),e.children&&e.children.length>0?this.navigateTo(e):(this.onSelectItem?.(e),this.emitEvent(`item-selected`,{item:e}),this.close())}),o.addEventListener(`mouseenter`,()=>{this.activeHoverItem.set(e),this.onHover?.(e),this.emitEvent(`menu-hover`,{item:e}),this.updateCenterButton()}),o.addEventListener(`mouseleave`,()=>{this.activeHoverItem.set(null),this.onHover?.(null),this.emitEvent(`menu-hover`,{item:null}),this.updateCenterButton()}),o}onDocumentContextMenu(e){let t=this.selector();t&&e.target?.closest?.(t)&&(e.preventDefault(),e.stopPropagation(),this.open(e.clientX,e.clientY))}onDocumentClick(e){if(this.isOpen()&&!(Date.now()-this._openedAt<150)){if(this.menuEl){if((e.composedPath?e.composedPath():[]).includes(this.menuEl))return;let t=e.target;if(t&&typeof this.menuEl.contains==`function`&&this.menuEl.contains(t))return}this.close()}}onDocumentKeydown(e){e.key===`Escape`&&this.isOpen()&&(this.navigationStack().length>0?this.goBack():this.close())}emitEvent(e,t){this?.dispatchEvent?.(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}};(0,e.Component)({selector:`radial-context-menu`,templateUrl:`./src/app/shared/components/radial-context-menu/radial-context-menu.component.html`,template:v})(y);var b=`<slot></slot>
|
|
263
|
+
`,x=class{isExpanded=(0,e.signal)(!1);hostEl=null;titleEl=null;cleanupEffect;handleTitleClick=e=>{e.target?.closest(`a, button, input, textarea, select`)||this.toggle()};handleTitleKeydown=e=>{(e.key===` `||e.key===`Enter`)&&(e.preventDefault(),this.toggle())};initOnHost(t){this.hostEl=t;let n=t.getAttribute(`is-expanded`),r=t.getAttribute(`expanded`);(n!==null&&n!==`false`&&n!==`null`&&n!==`0`||r!==null&&r!==`false`&&r!==`null`&&r!==`0`)&&this.isExpanded.set(!0);let i=t.getAttribute(`title`);this.titleEl=t.querySelector(`.title`),!this.titleEl&&i&&(this.titleEl=document.createElement(`div`),this.titleEl.className=`title`,this.titleEl.textContent=i,t.insertBefore(this.titleEl,t.firstChild)),this.titleEl&&(this.titleEl.hasAttribute(`role`)||this.titleEl.setAttribute(`role`,`button`),this.titleEl.hasAttribute(`tabindex`)||this.titleEl.setAttribute(`tabindex`,`0`),this.titleEl.addEventListener(`click`,this.handleTitleClick),this.titleEl.addEventListener(`keydown`,this.handleTitleKeydown));let a=t.querySelector(`.body`);a&&!a.hasAttribute(`role`)&&a.setAttribute(`role`,`region`),this.cleanupEffect=(0,e.effect)(()=>{let e=this.isExpanded();t.classList.toggle(`is-expanded`,e),t.classList.toggle(`is-collapsed`,!e),t.setAttribute(`aria-expanded`,String(e));let n=t.querySelector(`.body`);n&&(n.style.display=e?`block`:`none`,n.setAttribute(`aria-hidden`,String(!e)),n.classList.toggle(`is-expanded`,e),n.classList.toggle(`is-collapsed`,!e));let r=t.querySelector(`.title`);r&&r.setAttribute(`aria-expanded`,String(e))}),t!==this&&(t.toggle=()=>this.toggle(),t.expand=()=>this.expand(),t.collapse=()=>this.collapse(),t.isExpanded=this.isExpanded,t.expandOrCollapseIcon=()=>this.expandOrCollapseIcon())}onInit(){let e=this;e&&typeof e.querySelector==`function`&&this.initOnHost(e)}destroy(){this.titleEl&&=(this.titleEl.removeEventListener(`click`,this.handleTitleClick),this.titleEl.removeEventListener(`keydown`,this.handleTitleKeydown),null),this.cleanupEffect&&=(this.cleanupEffect(),void 0),this.hostEl=null}onDestroy(){this.destroy()}toggle(){this.isExpanded.update(e=>!e),this.dispatchToggleEvent()}expand(){this.isExpanded()||(this.isExpanded.set(!0),this.dispatchToggleEvent())}collapse(){this.isExpanded()&&(this.isExpanded.set(!1),this.dispatchToggleEvent())}expandOrCollapseIcon(){return this.isExpanded()?`icon-collapse`:`icon-expand`}dispatchToggleEvent(){let e=this.hostEl||this;e&&typeof e.dispatchEvent==`function`&&e.dispatchEvent(new CustomEvent(`change`,{detail:{isExpanded:this.isExpanded()},bubbles:!0,composed:!0}))}};(0,e.Component)({selector:`expander`,templateUrl:`./expander.component.html`,template:b})(x);var S=`<div id="nav-ball" class="nav-ball-container" aria-label="Floating Navigation Menu">
|
|
264
|
+
<!-- Hover Drag Handle -->
|
|
265
|
+
<div class="nav-drag-handle" title="Drag to reposition navigation ball">
|
|
266
|
+
<svg class="drag-grip-icon" viewBox="0 0 24 24" width="14" height="14" fill="currentColor">
|
|
267
|
+
<circle cx="9" cy="6" r="1.5"></circle>
|
|
268
|
+
<circle cx="15" cy="6" r="1.5"></circle>
|
|
269
|
+
<circle cx="9" cy="12" r="1.5"></circle>
|
|
270
|
+
<circle cx="15" cy="12" r="1.5"></circle>
|
|
271
|
+
<circle cx="9" cy="18" r="1.5"></circle>
|
|
272
|
+
<circle cx="15" cy="18" r="1.5"></circle>
|
|
273
|
+
</svg>
|
|
274
|
+
<span class="handle-text">DRAG</span>
|
|
275
|
+
</div>
|
|
276
|
+
|
|
277
|
+
<!-- Interactive Navigation Ball -->
|
|
278
|
+
<button
|
|
279
|
+
type="button"
|
|
280
|
+
class="nav-ball-orb"
|
|
281
|
+
id="nav-ball-trigger"
|
|
282
|
+
title="Open Navigation Menu"
|
|
283
|
+
onclick="onOrbClick(event)"
|
|
284
|
+
aria-haspopup="menu"
|
|
285
|
+
aria-expanded="{{isOpen()}}"
|
|
286
|
+
>
|
|
287
|
+
<span class="orb-shine"></span>
|
|
288
|
+
<span class="orb-glow"></span>
|
|
289
|
+
<span class="orb-icon">🧭</span>
|
|
290
|
+
</button>
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
<!-- Integrated Radial Context Menu -->
|
|
294
|
+
<radial-context-menu id="nav-radial-menu"></radial-context-menu>
|
|
295
|
+
`,C=class{currentTheme=(0,e.signal)(`dark`);isDark=(0,e.signal)(!0);constructor(){this.applyInitialTheme()}applyInitialTheme(){if(typeof window>`u`)return;let e=null;try{e=window.localStorage?.getItem(`purity-theme`)}catch{}let t=e===`light`?`light`:`dark`;this.applyTheme(t,!!e)}setTheme(e){this.applyTheme(e,!0)}toggleTheme(){let e=this.currentTheme()===`dark`?`light`:`dark`;this.setTheme(e)}applyTheme(e,t=!0){if(this.currentTheme.set(e),this.isDark.set(e===`dark`),t)try{window.localStorage?.setItem(`purity-theme`,e)}catch{}typeof document<`u`&&(document.documentElement.setAttribute(`data-theme`,e),document.body?.setAttribute(`data-theme`,e))}};(0,e.Injectable)(`ThemeService`)(C);var w=new Set;function T(t){let n=(0,e.getElement)(t.selector);if(!n)return console.warn(`Droppable behavior: Element "${t.selector}" not found.`),{destroy:()=>{}};let r={element:n,options:t};return w.add(r),{destroy:()=>{w.delete(r)}}}function E(e,t,n){for(let r of w){if(!r.element||!r.element.isConnected||r.element===n)continue;let i=r.element.getBoundingClientRect();if(e>=i.left&&e<=i.right&&t>=i.top&&t<=i.bottom&&D(r.options,n))return r}return null}function D(e,t){return!e.accepts||t.matches(e.accepts)}function O(t){let n=(0,e.getElement)(t.selector);if(!n)return console.warn(`Drag behavior: Element with selector "${t.selector}" not found.`),{destroy:()=>{}};let r=!1,i=0,a=0,o=0,s=0,c=0,l=0,u=0,d=0,f=0,p=0,m=0,h=0,g=null,_=null,v=null,y=()=>{let e=window.getComputedStyle(n);if(!e.transform||e.transform===`none`)return{x:0,y:0};try{let t=new DOMMatrix(e.transform);return{x:t.m41,y:t.m42}}catch{return{x:0,y:0}}},b=e=>{if(e.button!==0)return;let r=e.target;if(r.closest(`button, input, textarea, a, select`))return;if(t.handle){if(_=r.closest(t.handle),!_||!n.contains(_)&&_!==n){_=null;return}}else _=n;c=e.clientX,l=e.clientY;let{x:i,y:a}=y();o=i,s=a},x=y=>{if(!_&&!r)return;if(!r){let e=Math.abs(y.clientX-c),g=Math.abs(y.clientY-l);if(e>3||g>3){r=!0,i=c,a=l;try{n.setPointerCapture(y.pointerId)}catch{}n.classList.add(`is-dragging`);let e=n.getBoundingClientRect();u=e.left-o,d=e.top-s,f=e.width,p=e.height,m=window.scrollX,h=window.scrollY,t.onDragStart?.(n)}else return}let b=o+(y.clientX-i),x=s+(y.clientY-a),S=window.scrollX-m,C=window.scrollY-h,w=u-S,T=d-C,D=E(y.clientX,y.clientY,n);if(D!==g){if(g){let e=g.options.hoverClass||`droppable-hover`;g.element.classList.remove(e),g.options.onLeave?.(n)}if(D){let e=D.options.hoverClass||`droppable-hover`;D.element.classList.add(e),D.options.onEnter?.(n)}g=D}if(t.snapTo&&g?.element.matches(t.snapTo)){let e=g.element.getBoundingClientRect(),t=e.left+e.width/2,r=e.top+e.height/2,i=w+f/2,a=T+p/2;b=t-i,x=r-a,n.classList.add(`snap-hit`)}else n.classList.remove(`snap-hit`);let O=t.constrainTo?t.constrainTo===`parent`?n.parentElement:(0,e.getElement)(t.constrainTo)||n.closest(t.constrainTo):null;if(O&&O!==document.body){let e=O.getBoundingClientRect(),t=e.left-w,n=e.right-(w+f),r=e.top-T,i=e.bottom-(T+p);t<=n&&(b=Math.max(t,Math.min(n,b))),r<=i&&(x=Math.max(r,Math.min(i,x)))}t.onDragMove?.(n,b,x),v&&cancelAnimationFrame(v),v=requestAnimationFrame(()=>{n.style.transform=`translate3d(${b}px, ${x}px, 0px)`,v=null})},S=e=>{if(!r){_=null;return}if(v&&=(cancelAnimationFrame(v),null),t.onDragEnd?.(n),r=!1,n.hasPointerCapture(e.pointerId))try{n.releasePointerCapture(e.pointerId)}catch{}if(g){let e=g.options.hoverClass||`droppable-hover`;g.element.classList.remove(e),g.options.onDrop?.(n),g=null}n.classList.remove(`is-dragging`,`snap-hit`),_=null};return n.addEventListener(`pointerdown`,b),n.addEventListener(`pointermove`,x),n.addEventListener(`pointerup`,S),n.addEventListener(`pointercancel`,S),n.classList.add(`draggable-target`),{destroy:()=>{r=!1,v&&cancelAnimationFrame(v),n.removeEventListener(`pointerdown`,b),n.removeEventListener(`pointermove`,x),n.removeEventListener(`pointerup`,S),n.removeEventListener(`pointercancel`,S),n.classList.remove(`draggable-target`,`is-dragging`,`snap-hit`)}}}function k(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var A=class{themeService=(0,e.inject)(C);isOpen=(0,e.signal)(!1);radialMenu;navBallEl;dragInstance;wasDragged=!1;onInit(){this.initMenu(),this.initDrag()}onDestroy(){this.dragInstance?.destroy()}disconnectedCallback(){this.onDestroy()}initDrag(){this.dragInstance=O({selector:`#nav-ball`,handle:`#nav-ball`,onDragStart:()=>{this.wasDragged=!0,this.radialMenu?.close()},onDragEnd:()=>{setTimeout(()=>{this.wasDragged=!1},100)}})}initMenu(){let e=[{name:`Core`,image:`⚡`,children:[{name:`Signal Router`,image:`🗺️`,data:{hash:`#router-sample`}},{name:`Conditionals (if)`,image:`🔀`,data:{hash:`#if-sample`}},{name:`Array Repeater`,image:`🔁`,data:{hash:`#for-sample`}},{name:`Virtual Scroll (100k)`,image:`⚡`,data:{hash:`#virtual-for-sample`}},{name:`Transform Pipes`,image:`🏷️`,data:{hash:`#pipe-sample`}},{name:`DOM Directives`,image:`🎯`,data:{hash:`#directive-sample`}},{name:`Form Validation`,image:`📋`,data:{hash:`#forms-validation`}},{name:`HTTP Client`,image:`🌐`,data:{hash:`#http-sample`}}]},{name:`UI Components`,image:`🧩`,children:[{name:`Expander`,image:`↕️`,data:{hash:`#expander-sample`}},{name:`Switch Button`,image:`🎛️`,data:{hash:`#switch-button-sample`}},{name:`Date Time Picker`,image:`📅`,data:{hash:`#date-time-picker-sample`}},{name:`Modal Dialog`,image:`🪟`,data:{hash:`#modal-sample`}},{name:`Popover Anchoring`,image:`💬`,data:{hash:`#popover-sample`}},{name:`Toast Notify`,image:`🔔`,data:{hash:`#notification-sample`}},{name:`Radial Menu`,image:`🔘`,data:{hash:`#radial-context-menu-sample`}},{name:`Async Loader`,image:`⏳`,data:{hash:`#app-loader`}}]},{name:`Widgets`,image:`⏱️`,children:[{name:`Analogue Clock`,image:`🕒`,data:{hash:`#analogue-clock-sample`}}]},{name:`Theme`,image:`🎨`,children:[{name:`Dark Theme`,image:`🌙`,data:{theme:`dark`}},{name:`Light Theme`,image:`☀️`,data:{theme:`light`}},{name:`Toggle Theme`,image:`🌓`,data:{theme:`toggle`}}]},{name:`Playground`,image:`🎮`,data:{hash:`#playground-window`}},{name:`Overview / Intro`,image:`🏠`,data:{hash:`.intro-component-root`}}];this.radialMenu?(this.radialMenu.setItems(e),this.radialMenu.radius.set(155),this.radialMenu.onSelectItem=e=>this.handleNavigate(e),this.radialMenu.onOpen=()=>this.isOpen.set(!0),this.radialMenu.onClose=()=>this.isOpen.set(!1)):setTimeout(()=>{this.radialMenu&&(this.radialMenu.setItems(e),this.radialMenu.radius.set(155),this.radialMenu.onSelectItem=e=>this.handleNavigate(e),this.radialMenu.onOpen=()=>this.isOpen.set(!0),this.radialMenu.onClose=()=>this.isOpen.set(!1))},50)}onOrbClick(e){if(e.stopPropagation(),this.wasDragged||!this.radialMenu)return;if(this.radialMenu.isOpen()){this.radialMenu.close();return}let t=this.navBallEl||document.querySelector(`#nav-ball`),n=window.innerWidth-60,r=window.innerHeight-60;if(t){let e=t.getBoundingClientRect();n=e.left+e.width/2,r=e.top+e.height/2}this.radialMenu.open(n,r)}handleNavigate(e){if(e.data?.theme){e.data.theme===`toggle`?this.themeService.toggleTheme():(e.data.theme===`dark`||e.data.theme===`light`)&&this.themeService.setTheme(e.data.theme);return}let t=e.data?.hash;if(!t||typeof document>`u`)return;let n=document.querySelector(`#demo-window`);if((n&&n.querySelector(t)||t.includes(`sample`)||t.includes(`forms`)||t.includes(`app-loader`)||t.includes(`demo`))&&n&&(n.classList.remove(`demo-hidden`),n.classList.add(`demo-visible`)),t.startsWith(`#`))try{history.pushState(null,``,t)}catch{window.location.hash=t}setTimeout(()=>{let e=document.querySelector(t);e&&(e.scrollIntoView({behavior:`smooth`,block:`start`}),e.classList.remove(`p-nav-highlight`),e.offsetHeight,e.classList.add(`p-nav-highlight`),setTimeout(()=>{e.classList.remove(`p-nav-highlight`)},1900))},120)}};k([(0,e.ViewChild)(`#nav-radial-menu`)],A.prototype,`radialMenu`,void 0),k([(0,e.ViewChild)(`#nav-ball`)],A.prototype,`navBallEl`,void 0),(0,e.Component)({selector:`navigation-menu`,templateUrl:`./src/app/shared/components/navigation-menu/navigation-menu.component.html`,template:S})(A);var j=`<div class="analogue-clock-widget">
|
|
296
|
+
<!-- Header Bar -->
|
|
297
|
+
<div class="clock-header">
|
|
298
|
+
<div class="clock-title-group">
|
|
299
|
+
<span class="clock-icon">⏱️</span>
|
|
300
|
+
<span class="clock-title">{{title()}}</span>
|
|
301
|
+
<span class="clock-badge">{{smoothSeconds() ? 'Smooth' : 'Quartz'}}</span>
|
|
302
|
+
</div>
|
|
303
|
+
<div class="clock-tz-badge" title="Active Timezone">
|
|
304
|
+
<span class="tz-icon">🌐</span>
|
|
305
|
+
<span class="tz-text">{{timezoneLabel()}}</span>
|
|
306
|
+
</div>
|
|
307
|
+
</div>
|
|
308
|
+
|
|
309
|
+
<!-- Clock Canvas Stage -->
|
|
310
|
+
<div class="clock-stage">
|
|
311
|
+
<canvas
|
|
312
|
+
id="clock-canvas-el"
|
|
313
|
+
class="clock-canvas"
|
|
314
|
+
title="Click to toggle Smooth / Quartz ticking"
|
|
315
|
+
onclick="toggleSweep()"
|
|
316
|
+
></canvas>
|
|
317
|
+
</div>
|
|
318
|
+
|
|
319
|
+
<!-- Digital Readout Display -->
|
|
320
|
+
<div class="clock-digital-readout">
|
|
321
|
+
<span class="digital-time">{{digitalTime()}}</span>
|
|
322
|
+
<span class="digital-date">{{dateString()}}</span>
|
|
323
|
+
</div>
|
|
324
|
+
|
|
325
|
+
<!-- Interactive Controls Bar -->
|
|
326
|
+
<div class="clock-controls">
|
|
327
|
+
<button
|
|
328
|
+
type="button"
|
|
329
|
+
class="button-secondary clock-control-btn {{smoothSeconds() ? 'is-active' : ''}}"
|
|
330
|
+
onclick="toggleSweep()"
|
|
331
|
+
title="Toggle between continuous smooth sweep and precision quartz step"
|
|
332
|
+
>
|
|
333
|
+
<span>{{smoothSeconds() ? '⚡ Smooth Sweep' : '⏱ Precision Tick'}}</span>
|
|
334
|
+
</button>
|
|
335
|
+
|
|
336
|
+
<button
|
|
337
|
+
type="button"
|
|
338
|
+
class="button-secondary clock-control-btn {{showSeconds() ? 'is-active' : ''}}"
|
|
339
|
+
onclick="toggleSeconds()"
|
|
340
|
+
title="Toggle second hand visibility"
|
|
341
|
+
>
|
|
342
|
+
<span>{{showSeconds() ? '🔴 Seconds Hand' : '⚪ Hide Seconds'}}</span>
|
|
343
|
+
</button>
|
|
344
|
+
|
|
345
|
+
<button
|
|
346
|
+
type="button"
|
|
347
|
+
class="button-secondary clock-control-btn {{showNumbers() ? 'is-active' : ''}}"
|
|
348
|
+
onclick="toggleNumbers()"
|
|
349
|
+
title="Toggle dial numerals"
|
|
350
|
+
>
|
|
351
|
+
<span>{{showNumbers() ? '🔢 12/3/6/9 Numerals' : '➖ Minimal Indices'}}</span>
|
|
352
|
+
</button>
|
|
353
|
+
|
|
354
|
+
<button
|
|
355
|
+
type="button"
|
|
356
|
+
class="button-secondary clock-control-btn {{showDateBadge() ? 'is-active' : ''}}"
|
|
357
|
+
onclick="toggleDateBadge()"
|
|
358
|
+
title="Toggle dial date aperture window"
|
|
359
|
+
>
|
|
360
|
+
<span>{{showDateBadge() ? '📅 Date Aperture' : '🔲 Clean Dial'}}</span>
|
|
361
|
+
</button>
|
|
362
|
+
|
|
363
|
+
<dropdown label="{{timezoneLabel()}}" class="tz-dropdown">
|
|
364
|
+
<ul>
|
|
365
|
+
<li onclick="onTimezoneChange('local')" class="{{timezone() === 'local' ? 'is-selected' : ''}}">
|
|
366
|
+
<span class="item-icon">📍</span>
|
|
367
|
+
<span class="item-text">Local Time</span>
|
|
368
|
+
</li>
|
|
369
|
+
<li onclick="onTimezoneChange('UTC')" class="{{timezone() === 'UTC' ? 'is-selected' : ''}}">
|
|
370
|
+
<span class="item-icon">🌐</span>
|
|
371
|
+
<span class="item-text">UTC / GMT</span>
|
|
372
|
+
</li>
|
|
373
|
+
<li onclick="onTimezoneChange('America/New_York')" class="{{timezone() === 'America/New_York' ? 'is-selected' : ''}}">
|
|
374
|
+
<span class="item-icon">🗽</span>
|
|
375
|
+
<span class="item-text">New York (EST/EDT)</span>
|
|
376
|
+
</li>
|
|
377
|
+
<li onclick="onTimezoneChange('Europe/London')" class="{{timezone() === 'Europe/London' ? 'is-selected' : ''}}">
|
|
378
|
+
<span class="item-icon">🇬🇧</span>
|
|
379
|
+
<span class="item-text">London (GMT/BST)</span>
|
|
380
|
+
</li>
|
|
381
|
+
<li onclick="onTimezoneChange('Europe/Paris')" class="{{timezone() === 'Europe/Paris' ? 'is-selected' : ''}}">
|
|
382
|
+
<span class="item-icon">🇫🇷</span>
|
|
383
|
+
<span class="item-text">Paris (CET/CEST)</span>
|
|
384
|
+
</li>
|
|
385
|
+
<li onclick="onTimezoneChange('Asia/Tokyo')" class="{{timezone() === 'Asia/Tokyo' ? 'is-selected' : ''}}">
|
|
386
|
+
<span class="item-icon">🇯🇵</span>
|
|
387
|
+
<span class="item-text">Tokyo (JST)</span>
|
|
388
|
+
</li>
|
|
389
|
+
<li onclick="onTimezoneChange('Australia/Sydney')" class="{{timezone() === 'Australia/Sydney' ? 'is-selected' : ''}}">
|
|
390
|
+
<span class="item-icon">🇦🇺</span>
|
|
391
|
+
<span class="item-text">Sydney (AEST/AEDT)</span>
|
|
392
|
+
</li>
|
|
393
|
+
</ul>
|
|
394
|
+
</dropdown>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
`,M=class{themeService=(0,e.inject)(C);canvasEl;size=(0,e.signal)(280);title=(0,e.signal)(`Purity Chrono`);timezone=(0,e.signal)(`local`);smoothSeconds=(0,e.signal)(!0);showSeconds=(0,e.signal)(!0);showNumbers=(0,e.signal)(!0);showDateBadge=(0,e.signal)(!0);digitalTime=(0,e.signal)(`00:00:00`);dateString=(0,e.signal)(``);timezoneLabel=(0,e.signal)(`Local Time`);animationFrameId=null;ctx=null;onInit(){let t=this;if(t&&typeof t.getAttribute==`function`){let e=t.getAttribute(`title`);e&&this.title.set(e);let n=t.getAttribute(`timezone`);n&&this.timezone.set(n);let r=t.getAttribute(`size`);if(r){let e=parseFloat(r);isNaN(e)||this.size.set(e)}let i=t.getAttribute(`smooth-seconds`);i!==null&&this.smoothSeconds.set(i===`true`||i===``);let a=t.getAttribute(`show-seconds`);a!==null&&this.showSeconds.set(a===`true`||a===``);let o=t.getAttribute(`show-numbers`);o!==null&&this.showNumbers.set(o===`true`||o===``);let s=t.getAttribute(`show-date-badge`);s!==null&&this.showDateBadge.set(s===`true`||s===``)}(0,e.effect)(()=>{this.themeService.isDark(),this.smoothSeconds(),this.showSeconds(),this.showNumbers(),this.showDateBadge(),this.timezone(),this.size(),this.updateLabels(),this.initCanvas()}),this.initCanvas(),this.startClockLoop()}onDestroy(){this.stopClockLoop()}disconnectedCallback(){this.stopClockLoop()}initCanvas(){let e=this?.querySelector?.(`canvas`)||this.canvasEl||document.querySelector(`#clock-canvas-el`);if(!e)return;let t=this.size(),n=typeof window<`u`&&window.devicePixelRatio||1;e.width=t*n,e.height=t*n,e.style.width=`${t}px`,e.style.height=`${t}px`,this.ctx=e.getContext(`2d`),this.ctx&&(this.ctx.setTransform(1,0,0,1,0,0),this.ctx.scale(n,n))}startClockLoop(){this.stopClockLoop();let e=()=>{this.renderClock(),this.animationFrameId=requestAnimationFrame(e)};this.animationFrameId=requestAnimationFrame(e)}stopClockLoop(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}getTimeData(){let e=new Date,t=e,n=this.timezone();if(n!==`local`)try{let r=e.toLocaleString(`en-US`,{timeZone:n});t=new Date(r)}catch{t=e}let r=t.getHours(),i=t.getMinutes(),a=t.getSeconds(),o=t.getMilliseconds(),s=`${String(r).padStart(2,`0`)}:${String(i).padStart(2,`0`)}:${String(a).padStart(2,`0`)}`,c=t.toLocaleDateString(`en-US`,{weekday:`short`}).toUpperCase(),l=t.toLocaleDateString(`en-US`,{month:`short`}).toUpperCase(),u=t.getDate();return{hours:r,minutes:i,seconds:a,millis:o,digitalStr:s,dateStr:`${c}, ${l} ${u}`,dayName:c,dayNum:u}}updateLabels(){let e=this.timezone();if(e===`local`)this.timezoneLabel.set(`Local Time`);else if(e===`UTC`)this.timezoneLabel.set(`UTC / GMT`);else{let t=e.split(`/`).pop()?.replace(/_/g,` `)||e;this.timezoneLabel.set(t)}}renderClock(){if(!(this.canvasEl||document.querySelector(`#clock-canvas-el`))||!this.ctx&&(this.initCanvas(),!this.ctx))return;let e=this.ctx,t=this.size(),n=t/2,r=t/2,i=t*.44,a=this.themeService.isDark(),o=this.getTimeData();this.digitalTime.set(o.digitalStr),this.dateString.set(o.dateStr),e.clearRect(0,0,t,t),this.drawBezel(e,n,r,i,a),this.drawDialFace(e,n,r,i,a),this.showDateBadge()&&this.drawDateAperture(e,n,r,i,o.dayName,o.dayNum,a),this.drawMarkersAndTicks(e,n,r,i,a),this.showNumbers()&&this.drawNumerals(e,n,r,i,a),this.drawGlassReflection(e,n,r,i,a);let s=this.smoothSeconds()?o.seconds+o.millis/1e3:o.seconds,c=o.minutes+s/60,l=(o.hours%12+c/60)*(Math.PI/6)-Math.PI/2,u=Math.PI/30*c-Math.PI/2,d=Math.PI/30*s-Math.PI/2;this.drawHourHand(e,n,r,i,l,a),this.drawMinuteHand(e,n,r,i,u,a),this.showSeconds()&&this.drawSecondHand(e,n,r,i,d,a),this.drawCenterPivot(e,n,r,t,a)}drawBezel(e,t,n,r,i){let a=r+r*.14;e.save(),e.beginPath(),e.arc(t,n,a,0,Math.PI*2),e.shadowColor=i?`rgba(0, 0, 0, 0.65)`:`rgba(0, 0, 0, 0.18)`,e.shadowBlur=i?28:18,e.shadowOffsetX=0,e.shadowOffsetY=i?12:8,e.fillStyle=i?`#1a1d26`:`#e6ebf2`,e.fill(),e.shadowColor=`transparent`;let o=e.createLinearGradient(t-a,n-a,t+a,n+a);i?(o.addColorStop(0,`rgba(85, 95, 115, 0.9)`),o.addColorStop(.25,`rgba(40, 45, 58, 0.95)`),o.addColorStop(.5,`rgba(75, 85, 105, 0.85)`),o.addColorStop(.75,`rgba(30, 34, 44, 0.98)`),o.addColorStop(1,`rgba(95, 108, 130, 0.9)`)):(o.addColorStop(0,`rgba(255, 255, 255, 0.98)`),o.addColorStop(.25,`rgba(215, 222, 232, 0.95)`),o.addColorStop(.5,`rgba(245, 248, 252, 0.98)`),o.addColorStop(.75,`rgba(205, 214, 226, 0.95)`),o.addColorStop(1,`rgba(255, 255, 255, 0.98)`)),e.beginPath(),e.arc(t,n,a,0,Math.PI*2),e.fillStyle=o,e.fill(),e.beginPath(),e.arc(t,n,a,0,Math.PI*2),e.strokeStyle=i?`rgba(255, 255, 255, 0.22)`:`rgba(255, 255, 255, 0.9)`,e.lineWidth=1.5,e.stroke(),e.beginPath(),e.arc(t,n,r+1,0,Math.PI*2),e.strokeStyle=i?`rgba(0, 0, 0, 0.7)`:`rgba(0, 0, 0, 0.12)`,e.lineWidth=1.5,e.stroke(),e.restore()}drawDialFace(e,t,n,r,i){e.save();let a=e.createRadialGradient(t,n*.9,r*.1,t,n,r);i?(a.addColorStop(0,`rgba(34, 38, 52, 0.96)`),a.addColorStop(.65,`rgba(22, 25, 36, 0.98)`),a.addColorStop(1,`rgba(14, 16, 24, 1.0)`)):(a.addColorStop(0,`rgba(255, 255, 255, 0.98)`),a.addColorStop(.65,`rgba(244, 247, 252, 0.96)`),a.addColorStop(1,`rgba(230, 236, 246, 0.98)`)),e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fillStyle=a,e.fill(),e.beginPath(),e.arc(t,n,r-.5,0,Math.PI*2),e.strokeStyle=i?`rgba(0, 0, 0, 0.45)`:`rgba(0, 0, 0, 0.08)`,e.lineWidth=2,e.stroke(),e.beginPath(),e.arc(t,n,r*.83,0,Math.PI*2),e.strokeStyle=i?`rgba(255, 255, 255, 0.06)`:`rgba(0, 0, 0, 0.05)`,e.lineWidth=1,e.stroke(),e.beginPath(),e.arc(t,n,r*.54,0,Math.PI*2),e.strokeStyle=i?`rgba(255, 255, 255, 0.035)`:`rgba(0, 0, 0, 0.035)`,e.lineWidth=1,e.stroke(),e.textAlign=`center`,e.textBaseline=`middle`,e.font=`700 9px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`,e.fillStyle=i?`rgba(255, 255, 255, 0.35)`:`rgba(0, 0, 0, 0.38)`,e.letterSpacing=`2px`,e.fillText(`PURITY`,t,n-r*.34),e.font=`500 7px "Adwaita Mono", monospace`,e.fillStyle=i?`rgba(53, 132, 228, 0.75)`:`rgba(28, 113, 216, 0.85)`,e.fillText(`AUTOMATIC`,t,n-r*.24),e.restore()}drawDateAperture(e,t,n,r,i,a,o){e.save();let s=r*.44,c=r*.16,l=t+r*.28,u=n-c/2;e.beginPath(),e.roundRect(l,u,s,c,4),e.fillStyle=o?`rgba(16, 18, 26, 0.95)`:`rgba(255, 255, 255, 0.98)`,e.fill(),e.strokeStyle=o?`rgba(255, 255, 255, 0.14)`:`rgba(0, 0, 0, 0.14)`,e.lineWidth=1,e.stroke();let d=l+s*.48;e.beginPath(),e.moveTo(d,u+2),e.lineTo(d,u+c-2),e.strokeStyle=o?`rgba(255, 255, 255, 0.08)`:`rgba(0, 0, 0, 0.08)`,e.stroke(),e.textAlign=`center`,e.textBaseline=`middle`,e.font=`700 8.5px "Adwaita Mono", monospace`,e.fillStyle=o?`#3584e4`:`#1c71d8`,e.fillText(i,l+s*.24,n),e.font=`700 10px "Adwaita Mono", monospace`,e.fillStyle=o?`#ffffff`:`#1c1c1c`,e.fillText(String(a).padStart(2,`0`),l+s*.74,n),e.restore()}drawMarkersAndTicks(e,t,n,r,i){e.save();for(let a=0;a<60;a++){let o=Math.PI/30*a-Math.PI/2,s=Math.cos(o),c=Math.sin(o);if(a%5==0){let o=a%15==0,l=o?r*.78:r*.81,u=r*.93,d=o?3.5:2.5,f=t+l*s,p=n+l*c,m=t+u*s,h=n+u*c;if(e.beginPath(),e.moveTo(f,p),e.lineTo(m,h),e.lineWidth=d,e.lineCap=`round`,o?(e.strokeStyle=i?`#ffffff`:`#1c1c1c`,e.shadowColor=i?`rgba(53, 132, 228, 0.6)`:`rgba(28, 113, 216, 0.3)`,e.shadowBlur=4):(e.strokeStyle=i?`rgba(255, 255, 255, 0.85)`:`rgba(40, 45, 55, 0.85)`,e.shadowBlur=0),e.stroke(),o){let a=r*.74,o=t+a*s,l=n+a*c;e.beginPath(),e.arc(o,l,2,0,Math.PI*2),e.fillStyle=i?`#3584e4`:`#1c71d8`,e.fill()}}else{let a=r*.88,o=r*.93,l=t+a*s,u=n+a*c,d=t+o*s,f=n+o*c;e.beginPath(),e.moveTo(l,u),e.lineTo(d,f),e.lineWidth=1,e.lineCap=`butt`,e.strokeStyle=i?`rgba(255, 255, 255, 0.28)`:`rgba(0, 0, 0, 0.24)`,e.shadowBlur=0,e.stroke()}}e.restore()}drawNumerals(e,t,n,r,i){e.save(),e.textAlign=`center`,e.textBaseline=`middle`,e.font=`700 13px "Adwaita Mono", -apple-system, monospace`,e.fillStyle=i?`rgba(255, 255, 255, 0.9)`:`#1c1c1c`;let a=r*.67;e.fillText(`12`,t,n-a),e.fillText(`6`,t,n+a),e.fillText(`9`,t-a,n),this.showDateBadge()||e.fillText(`3`,t+a,n),e.restore()}drawGlassReflection(e,t,n,r,i){e.save(),e.beginPath(),e.arc(t,n,r-1,0,Math.PI*2),e.clip();let a=e.createLinearGradient(t-r,n-r,t+r,n+r*.2);i?(a.addColorStop(0,`rgba(255, 255, 255, 0.16)`),a.addColorStop(.35,`rgba(255, 255, 255, 0.05)`),a.addColorStop(.7,`rgba(255, 255, 255, 0.0)`)):(a.addColorStop(0,`rgba(255, 255, 255, 0.55)`),a.addColorStop(.35,`rgba(255, 255, 255, 0.2)`),a.addColorStop(.7,`rgba(255, 255, 255, 0.0)`)),e.beginPath(),e.ellipse(t,n-r*.22,r*.92,r*.65,-.2,0,Math.PI*2),e.fillStyle=a,e.fill();let o=e.createRadialGradient(t,n+r*.9,r*.05,t,n+r*.9,r*.45);o.addColorStop(0,i?`rgba(53, 132, 228, 0.12)`:`rgba(255, 255, 255, 0.4)`),o.addColorStop(1,`rgba(255, 255, 255, 0.0)`),e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fillStyle=o,e.fill(),e.restore()}drawHourHand(e,t,n,r,i,a){e.save(),e.translate(t,n),e.rotate(i);let o=r*.52,s=r*.09,c=r*.12;e.shadowColor=a?`rgba(0, 0, 0, 0.65)`:`rgba(0, 0, 0, 0.25)`,e.shadowBlur=8,e.shadowOffsetX=3,e.shadowOffsetY=4,e.beginPath(),e.moveTo(-c,0),e.lineTo(0,-s/2),e.lineTo(o,0),e.closePath(),e.fillStyle=a?`#ffffff`:`#282e38`,e.fill(),e.beginPath(),e.moveTo(-c,0),e.lineTo(0,s/2),e.lineTo(o,0),e.closePath(),e.fillStyle=a?`#98a2b5`:`#4b5563`,e.fill(),e.restore()}drawMinuteHand(e,t,n,r,i,a){e.save(),e.translate(t,n),e.rotate(i);let o=r*.76,s=r*.07,c=r*.14;e.shadowColor=a?`rgba(0, 0, 0, 0.65)`:`rgba(0, 0, 0, 0.25)`,e.shadowBlur=10,e.shadowOffsetX=3,e.shadowOffsetY=5,e.beginPath(),e.moveTo(-c,0),e.lineTo(0,-s/2),e.lineTo(o,0),e.closePath(),e.fillStyle=a?`#ffffff`:`#282e38`,e.fill(),e.beginPath(),e.moveTo(-c,0),e.lineTo(0,s/2),e.lineTo(o,0),e.closePath(),e.fillStyle=a?`#8a94a6`:`#475366`,e.fill(),e.restore()}drawSecondHand(e,t,n,r,i,a){e.save(),e.translate(t,n),e.rotate(i);let o=r*.86,s=r*.22,c=a?`#3584e4`:`#1c71d8`;e.shadowColor=a?`rgba(0, 0, 0, 0.55)`:`rgba(0, 0, 0, 0.2)`,e.shadowBlur=6,e.shadowOffsetX=2,e.shadowOffsetY=3,e.beginPath(),e.moveTo(-s,0),e.lineTo(o,0),e.strokeStyle=c,e.lineWidth=1.5,e.lineCap=`round`,e.stroke(),e.beginPath(),e.arc(-s*.55,0,4.5,0,Math.PI*2),e.fillStyle=c,e.fill(),e.beginPath(),e.arc(-s*.55,0,2.2,0,Math.PI*2),e.fillStyle=a?`#141620`:`#ffffff`,e.fill(),e.beginPath(),e.arc(o-4,0,2.5,0,Math.PI*2),e.fillStyle=a?`#78aeed`:`#3584e4`,e.shadowColor=c,e.shadowBlur=8,e.fill(),e.restore()}drawCenterPivot(e,t,n,r,i){e.save();let a=r*.038,o=r*.024,s=r*.012;e.beginPath(),e.arc(t,n,a,0,Math.PI*2),e.shadowColor=`rgba(0, 0, 0, 0.5)`,e.shadowBlur=6,e.fillStyle=i?`#2e3442`:`#cbd5e1`,e.fill(),e.strokeStyle=i?`rgba(255, 255, 255, 0.4)`:`rgba(0, 0, 0, 0.15)`,e.lineWidth=1,e.stroke(),e.shadowColor=`transparent`;let c=e.createLinearGradient(t-o,n-o,t+o,n+o);i?(c.addColorStop(0,`#ffffff`),c.addColorStop(.5,`#7b879c`),c.addColorStop(1,`#2b313d`)):(c.addColorStop(0,`#ffffff`),c.addColorStop(.5,`#e2e8f0`),c.addColorStop(1,`#94a3b8`)),e.beginPath(),e.arc(t,n,o,0,Math.PI*2),e.fillStyle=c,e.fill(),e.beginPath(),e.arc(t,n,s,0,Math.PI*2),e.fillStyle=i?`#3584e4`:`#1c71d8`,e.shadowColor=i?`#3584e4`:`#1c71d8`,e.shadowBlur=4,e.fill(),e.restore()}toggleSweep(){this.smoothSeconds.update(e=>!e)}toggleSeconds(){this.showSeconds.update(e=>!e)}toggleNumbers(){this.showNumbers.update(e=>!e)}toggleDateBadge(){this.showDateBadge.update(e=>!e)}onTimezoneChange(e){this.timezone.set(e||`local`),this.updateLabels()}};k([(0,e.ViewChild)(`#clock-canvas-el`)],M.prototype,`canvasEl`,void 0),(0,e.Component)({selector:`analogue-clock`,templateUrl:`./src/app/shared/widgets/analogue-clock/analogue-clock.component.html`,template:j})(M);var N=class{token=`purity_jwt_sample_token`;setToken(e){this.token=e}async intercept(e,t){return e.headers.has(`Authorization`)?t(e):t(e.clone({headers:e.headers.set(`Authorization`,`Bearer ${this.token}`)}))}},P=class{async intercept(e,t){let n=performance.now(),r=new Date().toLocaleTimeString();console.log(`%c[HTTP Request] ${r} %c${e.method} %c${e.url}`,`color: #9a9996;`,`color: #3584e4; font-weight: bold;`,`color: var(--text-main, #ffffff);`);try{let i=await t(e),a=Math.round(performance.now()-n);return console.log(`%c[HTTP Response] ${r} %c${e.method} ${e.url} %c-> ${i.status} ${i.statusText} (${a}ms)`,`color: #9a9996;`,`color: #2ec27e; font-weight: bold;`,`color: #2ec27e;`),i}catch(t){let i=Math.round(performance.now()-n);throw console.error(`%c[HTTP Error] ${r} %c${e.method} ${e.url} %cfailed (${t.status||`Network`}) in ${i}ms:`,`color: #9a9996;`,`color: #e01b24; font-weight: bold;`,`color: #e01b24;`,t),t}}},F=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],I=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],L=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],R=[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`],z={short:`M/d/yy, h:mm a`,medium:`MMM d, yyyy, h:mm:ss a`,long:`MMMM d, yyyy, h:mm:ss a`,full:`EEEE, MMMM d, yyyy, h:mm:ss a`,shortDate:`M/d/yy`,mediumDate:`MMM d, yyyy`,longDate:`MMMM d, yyyy`,fullDate:`EEEE, MMMM d, yyyy`,shortTime:`h:mm a`,mediumTime:`h:mm:ss a`},B=class extends e.BasePipe{transform(e,t=`mediumDate`){if(e==null||e===``)return``;let n;if(e instanceof Date)n=e;else if(typeof e==`number`||typeof e==`string`)n=new Date(e);else return``;if(isNaN(n.getTime()))return``;let r=z[t]||t;return this.formatDate(n,r)}formatDate(e,t){let n=e.getFullYear(),r=e.getMonth(),i=e.getDate(),a=e.getDay(),o=e.getHours(),s=o%12||12,c=e.getMinutes(),l=e.getSeconds(),u=o>=12?`PM`:`AM`,d=(e,t=2)=>String(e).padStart(t,`0`);return t.replace(/(EEEE|EEE|yyyy|yy|MMMM|MMM|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|a)/g,e=>{switch(e){case`EEEE`:return R[a];case`EEE`:return L[a];case`yyyy`:return String(n);case`yy`:return String(n).slice(-2);case`MMMM`:return I[r];case`MMM`:return F[r];case`MM`:return d(r+1);case`M`:return String(r+1);case`dd`:return d(i);case`d`:return String(i);case`HH`:return d(o);case`H`:return String(o);case`hh`:return d(s);case`h`:return String(s);case`mm`:return d(c);case`m`:return String(c);case`ss`:return d(l);case`s`:return String(l);case`a`:return u;default:return e}})}};(0,e.Pipe)(`date`)(B);var V=class extends e.BasePipe{transform(e,t=!1,n){if(e==null)return``;let r=String(e);return t&&(r=r.toUpperCase()),n?`${n}: ${r}`:r}};(0,e.Pipe)(`myTransformPipe`)(V);var H=class extends e.BasePipe{transform(e){return e==null?``:String(e).toUpperCase()}};(0,e.Pipe)(`uppercase`)(H);var U=class extends e.BaseValidator{validateInput1(e){return e.trim().length>=3}validateInput2(e){return e.trim().length>=5}};(0,e.Validator)({form:`.forms-validation-form`,fields:{input1:`#input1`,input2:`#input2`},validClass:`is-valid`,invalidClass:`is-invalid`})(U),exports.AnalogueClockComponent=M,exports.AuthInterceptor=N,exports.DatePipe=B,exports.DateTimePickerComponent=c,exports.DropDownDirective=t,exports.DropdownComponent=t,exports.DropdownDirective=t,exports.ExpanderComponent=x,exports.FormsValidationValidator=U,exports.HighlightDirective=n,exports.LoaderComponent=m,exports.LoggingInterceptor=P,exports.ModalViewComponent=o,exports.MyTransformPipe=V,exports.TransformSamplePipe=V,exports.NavigationMenuComponent=A,exports.NotificationComponent=f,exports.NotifyService=u,exports.PopoverComponent=g,exports.PopoverDirective=_,exports.RadialContextMenuComponent=y,exports.SwitchButtonComponent=i,exports.ThemeService=C,exports.UppercasePipe=H,exports.drag=O,exports.draggable=O,exports.droppable=T,exports.findDropTarget=E;
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types/ui';
|