juxscript 1.1.113 → 1.1.115

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
- "totalFiles": 67,
3
- "totalClasses": 196,
2
+ "totalFiles": 69,
3
+ "totalClasses": 203,
4
4
  "classList": [
5
5
  "?",
6
6
  "jux-alert",
@@ -99,6 +99,13 @@
99
99
  "jux-input-required",
100
100
  "jux-input-with-icon",
101
101
  "jux-layer",
102
+ "jux-link",
103
+ "jux-link-active",
104
+ "jux-link-disabled",
105
+ "jux-link-icon",
106
+ "jux-link-icon-left",
107
+ "jux-link-icon-right",
108
+ "jux-link-text",
102
109
  "jux-list",
103
110
  "jux-list-header",
104
111
  "jux-list-item",
@@ -3694,6 +3701,180 @@
3694
3701
  }
3695
3702
  ]
3696
3703
  },
3704
+ {
3705
+ "file": "link.js",
3706
+ "path": "link.js",
3707
+ "methods": {
3708
+ "render": [
3709
+ "jux-link",
3710
+ "jux-link-active",
3711
+ "jux-link-disabled",
3712
+ "jux-link-icon",
3713
+ "jux-link-icon-left",
3714
+ "jux-link-icon-right",
3715
+ "jux-link-text"
3716
+ ]
3717
+ },
3718
+ "allClasses": [
3719
+ "jux-link",
3720
+ "jux-link-active",
3721
+ "jux-link-disabled",
3722
+ "jux-link-icon",
3723
+ "jux-link-icon-left",
3724
+ "jux-link-icon-right",
3725
+ "jux-link-text"
3726
+ ],
3727
+ "classCount": 7,
3728
+ "domStructures": [
3729
+ {
3730
+ "method": "render",
3731
+ "elements": [
3732
+ {
3733
+ "tag": "a",
3734
+ "classes": [
3735
+ "jux-link",
3736
+ "jux-link-active",
3737
+ "jux-link-disabled"
3738
+ ],
3739
+ "id": null
3740
+ },
3741
+ {
3742
+ "tag": "span",
3743
+ "classes": [
3744
+ "jux-link-icon",
3745
+ "jux-link-icon-left",
3746
+ "jux-link-icon-right"
3747
+ ],
3748
+ "id": null
3749
+ },
3750
+ {
3751
+ "tag": "span",
3752
+ "classes": [
3753
+ "jux-link-text"
3754
+ ],
3755
+ "id": null
3756
+ }
3757
+ ],
3758
+ "hierarchy": [
3759
+ {
3760
+ "tag": "a",
3761
+ "classes": [
3762
+ "jux-link",
3763
+ "jux-link-active",
3764
+ "jux-link-disabled"
3765
+ ],
3766
+ "id": null,
3767
+ "orphan": true
3768
+ },
3769
+ {
3770
+ "tag": "span",
3771
+ "classes": [
3772
+ "jux-link-icon",
3773
+ "jux-link-icon-left",
3774
+ "jux-link-icon-right"
3775
+ ],
3776
+ "id": null,
3777
+ "orphan": true
3778
+ },
3779
+ {
3780
+ "tag": "span",
3781
+ "classes": [
3782
+ "jux-link-text"
3783
+ ],
3784
+ "id": null,
3785
+ "orphan": true
3786
+ }
3787
+ ]
3788
+ }
3789
+ ]
3790
+ },
3791
+ {
3792
+ "file": "link.ts",
3793
+ "path": "link.ts",
3794
+ "methods": {
3795
+ "render": [
3796
+ "jux-link",
3797
+ "jux-link-active",
3798
+ "jux-link-disabled",
3799
+ "jux-link-icon",
3800
+ "jux-link-icon-left",
3801
+ "jux-link-icon-right",
3802
+ "jux-link-text"
3803
+ ]
3804
+ },
3805
+ "allClasses": [
3806
+ "jux-link",
3807
+ "jux-link-active",
3808
+ "jux-link-disabled",
3809
+ "jux-link-icon",
3810
+ "jux-link-icon-left",
3811
+ "jux-link-icon-right",
3812
+ "jux-link-text"
3813
+ ],
3814
+ "classCount": 7,
3815
+ "domStructures": [
3816
+ {
3817
+ "method": "render",
3818
+ "elements": [
3819
+ {
3820
+ "tag": "a",
3821
+ "classes": [
3822
+ "jux-link",
3823
+ "jux-link-active",
3824
+ "jux-link-disabled"
3825
+ ],
3826
+ "id": null
3827
+ },
3828
+ {
3829
+ "tag": "span",
3830
+ "classes": [
3831
+ "jux-link-icon",
3832
+ "jux-link-icon-left",
3833
+ "jux-link-icon-right"
3834
+ ],
3835
+ "id": null
3836
+ },
3837
+ {
3838
+ "tag": "span",
3839
+ "classes": [
3840
+ "jux-link-text"
3841
+ ],
3842
+ "id": null
3843
+ }
3844
+ ],
3845
+ "hierarchy": [
3846
+ {
3847
+ "tag": "a",
3848
+ "classes": [
3849
+ "jux-link",
3850
+ "jux-link-active",
3851
+ "jux-link-disabled"
3852
+ ],
3853
+ "id": null,
3854
+ "orphan": true
3855
+ },
3856
+ {
3857
+ "tag": "span",
3858
+ "classes": [
3859
+ "jux-link-icon",
3860
+ "jux-link-icon-left",
3861
+ "jux-link-icon-right"
3862
+ ],
3863
+ "id": null,
3864
+ "orphan": true
3865
+ },
3866
+ {
3867
+ "tag": "span",
3868
+ "classes": [
3869
+ "jux-link-text"
3870
+ ],
3871
+ "id": null,
3872
+ "orphan": true
3873
+ }
3874
+ ]
3875
+ }
3876
+ ]
3877
+ },
3697
3878
  {
3698
3879
  "file": "list.js",
3699
3880
  "path": "list.js",
@@ -7989,6 +8170,13 @@
7989
8170
  "jux-input-counter",
7990
8171
  "jux-input-with-icon",
7991
8172
  "jux-layer",
8173
+ "jux-link",
8174
+ "jux-link-active",
8175
+ "jux-link-disabled",
8176
+ "jux-link-icon",
8177
+ "jux-link-icon-left",
8178
+ "jux-link-icon-right",
8179
+ "jux-link-text",
7992
8180
  "jux-list",
7993
8181
  "jux-list-header",
7994
8182
  "jux-list-item",
@@ -1,6 +1,6 @@
1
1
  {
2
- "totalComponents": 67,
3
- "generatedAt": "2026-02-13T02:44:21.345Z",
2
+ "totalComponents": 69,
3
+ "generatedAt": "2026-02-13T03:14:49.691Z",
4
4
  "components": [
5
5
  {
6
6
  "file": "alert.js",
@@ -2862,6 +2862,138 @@
2862
2862
  }
2863
2863
  ]
2864
2864
  },
2865
+ {
2866
+ "file": "link.js",
2867
+ "path": "link.js",
2868
+ "domStructures": [
2869
+ {
2870
+ "method": "render",
2871
+ "elements": [
2872
+ {
2873
+ "tag": "a",
2874
+ "classes": [
2875
+ "jux-link",
2876
+ "jux-link-active",
2877
+ "jux-link-disabled"
2878
+ ],
2879
+ "id": null
2880
+ },
2881
+ {
2882
+ "tag": "span",
2883
+ "classes": [
2884
+ "jux-link-icon",
2885
+ "jux-link-icon-left",
2886
+ "jux-link-icon-right"
2887
+ ],
2888
+ "id": null
2889
+ },
2890
+ {
2891
+ "tag": "span",
2892
+ "classes": [
2893
+ "jux-link-text"
2894
+ ],
2895
+ "id": null
2896
+ }
2897
+ ],
2898
+ "hierarchy": [
2899
+ {
2900
+ "tag": "a",
2901
+ "classes": [
2902
+ "jux-link",
2903
+ "jux-link-active",
2904
+ "jux-link-disabled"
2905
+ ],
2906
+ "id": null,
2907
+ "orphan": true
2908
+ },
2909
+ {
2910
+ "tag": "span",
2911
+ "classes": [
2912
+ "jux-link-icon",
2913
+ "jux-link-icon-left",
2914
+ "jux-link-icon-right"
2915
+ ],
2916
+ "id": null,
2917
+ "orphan": true
2918
+ },
2919
+ {
2920
+ "tag": "span",
2921
+ "classes": [
2922
+ "jux-link-text"
2923
+ ],
2924
+ "id": null,
2925
+ "orphan": true
2926
+ }
2927
+ ]
2928
+ }
2929
+ ]
2930
+ },
2931
+ {
2932
+ "file": "link.ts",
2933
+ "path": "link.ts",
2934
+ "domStructures": [
2935
+ {
2936
+ "method": "render",
2937
+ "elements": [
2938
+ {
2939
+ "tag": "a",
2940
+ "classes": [
2941
+ "jux-link",
2942
+ "jux-link-active",
2943
+ "jux-link-disabled"
2944
+ ],
2945
+ "id": null
2946
+ },
2947
+ {
2948
+ "tag": "span",
2949
+ "classes": [
2950
+ "jux-link-icon",
2951
+ "jux-link-icon-left",
2952
+ "jux-link-icon-right"
2953
+ ],
2954
+ "id": null
2955
+ },
2956
+ {
2957
+ "tag": "span",
2958
+ "classes": [
2959
+ "jux-link-text"
2960
+ ],
2961
+ "id": null
2962
+ }
2963
+ ],
2964
+ "hierarchy": [
2965
+ {
2966
+ "tag": "a",
2967
+ "classes": [
2968
+ "jux-link",
2969
+ "jux-link-active",
2970
+ "jux-link-disabled"
2971
+ ],
2972
+ "id": null,
2973
+ "orphan": true
2974
+ },
2975
+ {
2976
+ "tag": "span",
2977
+ "classes": [
2978
+ "jux-link-icon",
2979
+ "jux-link-icon-left",
2980
+ "jux-link-icon-right"
2981
+ ],
2982
+ "id": null,
2983
+ "orphan": true
2984
+ },
2985
+ {
2986
+ "tag": "span",
2987
+ "classes": [
2988
+ "jux-link-text"
2989
+ ],
2990
+ "id": null,
2991
+ "orphan": true
2992
+ }
2993
+ ]
2994
+ }
2995
+ ]
2996
+ },
2865
2997
  {
2866
2998
  "file": "list.js",
2867
2999
  "path": "list.js",
package/index.d.ts CHANGED
@@ -22,6 +22,7 @@ import { icon } from './lib/components/icon.js';
22
22
  import { image } from './lib/components/image.js';
23
23
  import { include } from './lib/components/include.js';
24
24
  import { input } from './lib/components/input.js';
25
+ import { link, navLink, externalLink } from './lib/components/link.js';
25
26
  import { list } from './lib/components/list.js';
26
27
  import { loading } from './lib/components/loading.js';
27
28
  import { menu } from './lib/components/menu.js';
@@ -50,8 +51,13 @@ export { state, registry, stateHistory };
50
51
  import { VStack, vstack } from './lib/components/stack/VStack.js';
51
52
  import { HStack, hstack } from './lib/components/stack/HStack.js';
52
53
  import { ZStack, zstack } from './lib/components/stack/ZStack.js';
54
+ export { Link, link, navLink, externalLink } from './lib/components/link.js';
55
+ export type { LinkOptions } from './lib/components/link.js';
53
56
  export { Layer, layer, gradient, overlay, glassLayer, animatedGradient } from './lib/components/layer.js';
54
57
  export type { LayerOptions, LayerPreset } from './lib/components/layer.js';
58
+ /**
59
+ * JUX Namespace - Main API
60
+ */
55
61
  export declare const jux: {
56
62
  alert: typeof alert;
57
63
  app: typeof app;
@@ -77,6 +83,9 @@ export declare const jux: {
77
83
  include: typeof include;
78
84
  input: typeof input;
79
85
  list: typeof list;
86
+ link: typeof link;
87
+ navLink: typeof navLink;
88
+ externalLink: typeof externalLink;
80
89
  loading: typeof loading;
81
90
  menu: typeof menu;
82
91
  modal: typeof modal;
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -22,6 +22,7 @@ import { icon } from './lib/components/icon.js';
22
22
  import { image } from './lib/components/image.js';
23
23
  import { include } from './lib/components/include.js';
24
24
  import { input } from './lib/components/input.js';
25
+ import { link, navLink, externalLink } from './lib/components/link.js';
25
26
  import { list } from './lib/components/list.js';
26
27
  import { loading } from './lib/components/loading.js';
27
28
  import { menu } from './lib/components/menu.js';
@@ -53,10 +54,15 @@ export { state, registry, stateHistory }; // ✅ Export history
53
54
  import { VStack, vstack } from './lib/components/stack/VStack.js';
54
55
  import { HStack, hstack } from './lib/components/stack/HStack.js';
55
56
  import { ZStack, zstack } from './lib/components/stack/ZStack.js';
57
+ // ✅ Link component
58
+ export { Link, link, navLink, externalLink } from './lib/components/link.js';
56
59
  // ✅ Layer component
57
60
  export { Layer, layer, gradient, overlay, glassLayer, animatedGradient } from './lib/components/layer.js';
58
- // Utilities
61
+ /**
62
+ * JUX Namespace - Main API
63
+ */
59
64
  export const jux = {
65
+ // Existing components
60
66
  alert,
61
67
  app,
62
68
  badge,
@@ -81,6 +87,9 @@ export const jux = {
81
87
  include,
82
88
  input,
83
89
  list,
90
+ link,
91
+ navLink,
92
+ externalLink,
84
93
  loading,
85
94
  menu,
86
95
  modal,
@@ -0,0 +1,41 @@
1
+ import { BaseComponent, BaseState } from './base/BaseComponent.js';
2
+ export interface LinkOptions {
3
+ href?: string;
4
+ text?: string;
5
+ icon?: string;
6
+ iconPosition?: 'left' | 'right';
7
+ target?: '_self' | '_blank' | '_parent' | '_top';
8
+ external?: boolean;
9
+ active?: boolean;
10
+ disabled?: boolean;
11
+ style?: string;
12
+ class?: string;
13
+ }
14
+ interface LinkState extends BaseState {
15
+ href: string;
16
+ text: string;
17
+ icon: string;
18
+ iconPosition: 'left' | 'right';
19
+ target: string;
20
+ external: boolean;
21
+ active: boolean;
22
+ }
23
+ export declare class Link extends BaseComponent<LinkState> {
24
+ constructor(id: string, options?: LinkOptions);
25
+ protected getTriggerEvents(): readonly string[];
26
+ protected getCallbackEvents(): readonly string[];
27
+ href(value: string): this;
28
+ text(value: string): this;
29
+ icon(value: string): this;
30
+ iconPosition(value: 'left' | 'right'): this;
31
+ target(value: '_self' | '_blank' | '_parent' | '_top'): this;
32
+ external(value?: boolean): this;
33
+ active(value?: boolean): this;
34
+ render(targetId?: string | HTMLElement | BaseComponent<any>): this;
35
+ update(prop: string, value: any): void;
36
+ }
37
+ export declare function link(id: string, options?: LinkOptions): Link;
38
+ export declare function navLink(id: string, text?: string): Link;
39
+ export declare function externalLink(id: string, href: string, text?: string): Link;
40
+ export {};
41
+ //# sourceMappingURL=link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAQnE,MAAM,WAAW,WAAW;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,SAAU,SAAQ,SAAS;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,IAAK,SAAQ,aAAa,CAAC,SAAS,CAAC;gBAClC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB;IAkBjD,SAAS,CAAC,gBAAgB,IAAI,SAAS,MAAM,EAAE;IAI/C,SAAS,CAAC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAQhD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IASzB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAYzB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKzB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAK3C,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI;IAS5D,QAAQ,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IAQrC,MAAM,CAAC,KAAK,GAAE,OAAc,GAAG,IAAI;IAanC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI;IAyFlE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;CAiCzC;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI,CAEhE;AAGD,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAKvD;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAQ1E"}
@@ -0,0 +1,216 @@
1
+ import { BaseComponent } from './base/BaseComponent.js';
2
+ import { renderIcon } from './icons.js';
3
+ import { formatIdAsLabel } from '../utils/formatId.js';
4
+ // Event definitions
5
+ const TRIGGER_EVENTS = [];
6
+ const CALLBACK_EVENTS = ['click'];
7
+ export class Link extends BaseComponent {
8
+ constructor(id, options = {}) {
9
+ super(id, {
10
+ visible: true,
11
+ disabled: options.disabled ?? false,
12
+ loading: false,
13
+ class: options.class ?? '',
14
+ style: options.style ?? '',
15
+ attributes: {},
16
+ href: options.href ?? `/${id}`,
17
+ text: options.text ?? formatIdAsLabel(id),
18
+ icon: options.icon ?? '',
19
+ iconPosition: options.iconPosition ?? 'left',
20
+ target: options.target ?? '_self',
21
+ external: options.external ?? false,
22
+ active: options.active ?? false
23
+ });
24
+ }
25
+ getTriggerEvents() {
26
+ return TRIGGER_EVENTS;
27
+ }
28
+ getCallbackEvents() {
29
+ return CALLBACK_EVENTS;
30
+ }
31
+ /* ═════════════════════════════════════════════════════════════════
32
+ * FLUENT API
33
+ * ═════════════════════════════════════════════════════════════════ */
34
+ href(value) {
35
+ this.state.href = value;
36
+ if (this.container) {
37
+ const link = this.container.querySelector(`#${this._id}`);
38
+ if (link)
39
+ link.href = value;
40
+ }
41
+ return this;
42
+ }
43
+ text(value) {
44
+ this.state.text = value;
45
+ if (this.container) {
46
+ const link = this.container.querySelector(`#${this._id}`);
47
+ if (link) {
48
+ const textNode = link.querySelector('.jux-link-text');
49
+ if (textNode)
50
+ textNode.textContent = value;
51
+ }
52
+ }
53
+ return this;
54
+ }
55
+ icon(value) {
56
+ this.state.icon = value;
57
+ return this;
58
+ }
59
+ iconPosition(value) {
60
+ this.state.iconPosition = value;
61
+ return this;
62
+ }
63
+ target(value) {
64
+ this.state.target = value;
65
+ if (this.container) {
66
+ const link = this.container.querySelector(`#${this._id}`);
67
+ if (link)
68
+ link.target = value;
69
+ }
70
+ return this;
71
+ }
72
+ external(value = true) {
73
+ this.state.external = value;
74
+ if (value) {
75
+ this.state.target = '_blank';
76
+ }
77
+ return this;
78
+ }
79
+ active(value = true) {
80
+ this.state.active = value;
81
+ if (this.container) {
82
+ const link = this.container.querySelector(`#${this._id}`);
83
+ if (link)
84
+ link.classList.toggle('jux-link-active', value);
85
+ }
86
+ return this;
87
+ }
88
+ /* ═════════════════════════════════════════════════════════════════
89
+ * RENDER
90
+ * ═════════════════════════════════════════════════════════════════ */
91
+ render(targetId) {
92
+ const container = this._setupContainer(targetId);
93
+ const { href, text, icon, iconPosition, target, external, active, disabled, style, class: className } = this.state;
94
+ const link = document.createElement('a');
95
+ link.id = this._id;
96
+ link.className = 'jux-link';
97
+ if (active)
98
+ link.classList.add('jux-link-active');
99
+ if (disabled)
100
+ link.classList.add('jux-link-disabled');
101
+ if (className)
102
+ link.className += ` ${className}`;
103
+ if (style)
104
+ link.setAttribute('style', style);
105
+ link.href = href;
106
+ link.target = target;
107
+ // Add rel for external links
108
+ if (external || target === '_blank') {
109
+ link.rel = 'noopener noreferrer';
110
+ }
111
+ // Mark as external link for router to ignore
112
+ if (external) {
113
+ link.dataset.router = 'false';
114
+ }
115
+ // Icon (left position)
116
+ if (icon && iconPosition === 'left') {
117
+ const iconEl = document.createElement('span');
118
+ iconEl.className = 'jux-link-icon jux-link-icon-left';
119
+ iconEl.appendChild(renderIcon(icon));
120
+ link.appendChild(iconEl);
121
+ }
122
+ // Text
123
+ const textEl = document.createElement('span');
124
+ textEl.className = 'jux-link-text';
125
+ textEl.textContent = text;
126
+ link.appendChild(textEl);
127
+ // Icon (right position)
128
+ if (icon && iconPosition === 'right') {
129
+ const iconEl = document.createElement('span');
130
+ iconEl.className = 'jux-link-icon jux-link-icon-right';
131
+ iconEl.appendChild(renderIcon(icon));
132
+ link.appendChild(iconEl);
133
+ }
134
+ // Wire events
135
+ this._wireStandardEvents(link);
136
+ // Fire click callback
137
+ link.addEventListener('click', (e) => {
138
+ if (disabled) {
139
+ e.preventDefault();
140
+ return;
141
+ }
142
+ this._triggerCallback('click', href);
143
+ });
144
+ // Sync href changes
145
+ const hrefSync = this._syncBindings.find(b => b.property === 'href');
146
+ if (hrefSync) {
147
+ const transform = hrefSync.toComponent || ((v) => String(v));
148
+ hrefSync.stateObj.subscribe((val) => {
149
+ this.href(transform(val));
150
+ });
151
+ }
152
+ // Sync text changes
153
+ const textSync = this._syncBindings.find(b => b.property === 'text');
154
+ if (textSync) {
155
+ const transform = textSync.toComponent || ((v) => String(v));
156
+ textSync.stateObj.subscribe((val) => {
157
+ this.text(transform(val));
158
+ });
159
+ }
160
+ container.appendChild(link);
161
+ requestAnimationFrame(() => {
162
+ if (window.lucide) {
163
+ window.lucide.createIcons();
164
+ }
165
+ });
166
+ return this;
167
+ }
168
+ update(prop, value) {
169
+ if (!this.container)
170
+ return;
171
+ const link = this.container.querySelector(`#${this._id}`);
172
+ if (!link)
173
+ return;
174
+ switch (prop) {
175
+ case 'href':
176
+ link.href = value;
177
+ break;
178
+ case 'text':
179
+ const textNode = link.querySelector('.jux-link-text');
180
+ if (textNode)
181
+ textNode.textContent = value;
182
+ break;
183
+ case 'active':
184
+ link.classList.toggle('jux-link-active', value);
185
+ break;
186
+ case 'disabled':
187
+ link.classList.toggle('jux-link-disabled', value);
188
+ break;
189
+ case 'target':
190
+ link.target = value;
191
+ break;
192
+ default:
193
+ super.update(prop, value);
194
+ break;
195
+ }
196
+ }
197
+ }
198
+ export function link(id, options = {}) {
199
+ return new Link(id, options);
200
+ }
201
+ // Convenience helpers
202
+ export function navLink(id, text) {
203
+ return new Link(id, {
204
+ href: `/${id}`,
205
+ text: text || formatIdAsLabel(id)
206
+ });
207
+ }
208
+ export function externalLink(id, href, text) {
209
+ return new Link(id, {
210
+ href,
211
+ text: text || formatIdAsLabel(id),
212
+ external: true,
213
+ icon: 'external-link',
214
+ iconPosition: 'right'
215
+ });
216
+ }
@@ -0,0 +1,268 @@
1
+ import { BaseComponent, BaseState } from './base/BaseComponent.js';
2
+ import { renderIcon } from './icons.js';
3
+ import { formatIdAsLabel } from '../utils/formatId.js';
4
+
5
+ // Event definitions
6
+ const TRIGGER_EVENTS = [] as const;
7
+ const CALLBACK_EVENTS = ['click'] as const;
8
+
9
+ export interface LinkOptions {
10
+ href?: string;
11
+ text?: string;
12
+ icon?: string;
13
+ iconPosition?: 'left' | 'right';
14
+ target?: '_self' | '_blank' | '_parent' | '_top';
15
+ external?: boolean;
16
+ active?: boolean;
17
+ disabled?: boolean;
18
+ style?: string;
19
+ class?: string;
20
+ }
21
+
22
+ interface LinkState extends BaseState {
23
+ href: string;
24
+ text: string;
25
+ icon: string;
26
+ iconPosition: 'left' | 'right';
27
+ target: string;
28
+ external: boolean;
29
+ active: boolean;
30
+ }
31
+
32
+ export class Link extends BaseComponent<LinkState> {
33
+ constructor(id: string, options: LinkOptions = {}) {
34
+ super(id, {
35
+ visible: true,
36
+ disabled: options.disabled ?? false,
37
+ loading: false,
38
+ class: options.class ?? '',
39
+ style: options.style ?? '',
40
+ attributes: {},
41
+ href: options.href ?? `/${id}`,
42
+ text: options.text ?? formatIdAsLabel(id),
43
+ icon: options.icon ?? '',
44
+ iconPosition: options.iconPosition ?? 'left',
45
+ target: options.target ?? '_self',
46
+ external: options.external ?? false,
47
+ active: options.active ?? false
48
+ });
49
+ }
50
+
51
+ protected getTriggerEvents(): readonly string[] {
52
+ return TRIGGER_EVENTS;
53
+ }
54
+
55
+ protected getCallbackEvents(): readonly string[] {
56
+ return CALLBACK_EVENTS;
57
+ }
58
+
59
+ /* ═════════════════════════════════════════════════════════════════
60
+ * FLUENT API
61
+ * ═════════════════════════════════════════════════════════════════ */
62
+
63
+ href(value: string): this {
64
+ this.state.href = value;
65
+ if (this.container) {
66
+ const link = this.container.querySelector(`#${this._id}`) as HTMLAnchorElement;
67
+ if (link) link.href = value;
68
+ }
69
+ return this;
70
+ }
71
+
72
+ text(value: string): this {
73
+ this.state.text = value;
74
+ if (this.container) {
75
+ const link = this.container.querySelector(`#${this._id}`) as HTMLAnchorElement;
76
+ if (link) {
77
+ const textNode = link.querySelector('.jux-link-text');
78
+ if (textNode) textNode.textContent = value;
79
+ }
80
+ }
81
+ return this;
82
+ }
83
+
84
+ icon(value: string): this {
85
+ this.state.icon = value;
86
+ return this;
87
+ }
88
+
89
+ iconPosition(value: 'left' | 'right'): this {
90
+ this.state.iconPosition = value;
91
+ return this;
92
+ }
93
+
94
+ target(value: '_self' | '_blank' | '_parent' | '_top'): this {
95
+ this.state.target = value;
96
+ if (this.container) {
97
+ const link = this.container.querySelector(`#${this._id}`) as HTMLAnchorElement;
98
+ if (link) link.target = value;
99
+ }
100
+ return this;
101
+ }
102
+
103
+ external(value: boolean = true): this {
104
+ this.state.external = value;
105
+ if (value) {
106
+ this.state.target = '_blank';
107
+ }
108
+ return this;
109
+ }
110
+
111
+ active(value: boolean = true): this {
112
+ this.state.active = value;
113
+ if (this.container) {
114
+ const link = this.container.querySelector(`#${this._id}`) as HTMLAnchorElement;
115
+ if (link) link.classList.toggle('jux-link-active', value);
116
+ }
117
+ return this;
118
+ }
119
+
120
+ /* ═════════════════════════════════════════════════════════════════
121
+ * RENDER
122
+ * ═════════════════════════════════════════════════════════════════ */
123
+
124
+ render(targetId?: string | HTMLElement | BaseComponent<any>): this {
125
+ const container = this._setupContainer(targetId);
126
+
127
+ const { href, text, icon, iconPosition, target, external, active, disabled, style, class: className } = this.state;
128
+
129
+ const link = document.createElement('a');
130
+ link.id = this._id;
131
+ link.className = 'jux-link';
132
+ if (active) link.classList.add('jux-link-active');
133
+ if (disabled) link.classList.add('jux-link-disabled');
134
+ if (className) link.className += ` ${className}`;
135
+ if (style) link.setAttribute('style', style);
136
+
137
+ link.href = href;
138
+ link.target = target;
139
+
140
+ // Add rel for external links
141
+ if (external || target === '_blank') {
142
+ link.rel = 'noopener noreferrer';
143
+ }
144
+
145
+ // Mark as external link for router to ignore
146
+ if (external) {
147
+ link.dataset.router = 'false';
148
+ }
149
+
150
+ // Icon (left position)
151
+ if (icon && iconPosition === 'left') {
152
+ const iconEl = document.createElement('span');
153
+ iconEl.className = 'jux-link-icon jux-link-icon-left';
154
+ iconEl.appendChild(renderIcon(icon));
155
+ link.appendChild(iconEl);
156
+ }
157
+
158
+ // Text
159
+ const textEl = document.createElement('span');
160
+ textEl.className = 'jux-link-text';
161
+ textEl.textContent = text;
162
+ link.appendChild(textEl);
163
+
164
+ // Icon (right position)
165
+ if (icon && iconPosition === 'right') {
166
+ const iconEl = document.createElement('span');
167
+ iconEl.className = 'jux-link-icon jux-link-icon-right';
168
+ iconEl.appendChild(renderIcon(icon));
169
+ link.appendChild(iconEl);
170
+ }
171
+
172
+ // Wire events
173
+ this._wireStandardEvents(link);
174
+
175
+ // Fire click callback
176
+ link.addEventListener('click', (e) => {
177
+ if (disabled) {
178
+ e.preventDefault();
179
+ return;
180
+ }
181
+ this._triggerCallback('click', href);
182
+ });
183
+
184
+ // Sync href changes
185
+ const hrefSync = this._syncBindings.find(b => b.property === 'href');
186
+ if (hrefSync) {
187
+ const transform = hrefSync.toComponent || ((v: any) => String(v));
188
+ hrefSync.stateObj.subscribe((val: any) => {
189
+ this.href(transform(val));
190
+ });
191
+ }
192
+
193
+ // Sync text changes
194
+ const textSync = this._syncBindings.find(b => b.property === 'text');
195
+ if (textSync) {
196
+ const transform = textSync.toComponent || ((v: any) => String(v));
197
+ textSync.stateObj.subscribe((val: any) => {
198
+ this.text(transform(val));
199
+ });
200
+ }
201
+
202
+ container.appendChild(link);
203
+
204
+ requestAnimationFrame(() => {
205
+ if ((window as any).lucide) {
206
+ (window as any).lucide.createIcons();
207
+ }
208
+ });
209
+
210
+ return this;
211
+ }
212
+
213
+ update(prop: string, value: any): void {
214
+ if (!this.container) return;
215
+
216
+ const link = this.container.querySelector(`#${this._id}`) as HTMLAnchorElement;
217
+ if (!link) return;
218
+
219
+ switch (prop) {
220
+ case 'href':
221
+ link.href = value;
222
+ break;
223
+
224
+ case 'text':
225
+ const textNode = link.querySelector('.jux-link-text');
226
+ if (textNode) textNode.textContent = value;
227
+ break;
228
+
229
+ case 'active':
230
+ link.classList.toggle('jux-link-active', value);
231
+ break;
232
+
233
+ case 'disabled':
234
+ link.classList.toggle('jux-link-disabled', value);
235
+ break;
236
+
237
+ case 'target':
238
+ link.target = value;
239
+ break;
240
+
241
+ default:
242
+ super.update(prop, value);
243
+ break;
244
+ }
245
+ }
246
+ }
247
+
248
+ export function link(id: string, options: LinkOptions = {}): Link {
249
+ return new Link(id, options);
250
+ }
251
+
252
+ // Convenience helpers
253
+ export function navLink(id: string, text?: string): Link {
254
+ return new Link(id, {
255
+ href: `/${id}`,
256
+ text: text || formatIdAsLabel(id)
257
+ });
258
+ }
259
+
260
+ export function externalLink(id: string, href: string, text?: string): Link {
261
+ return new Link(id, {
262
+ href,
263
+ text: text || formatIdAsLabel(id),
264
+ external: true,
265
+ icon: 'external-link',
266
+ iconPosition: 'right'
267
+ });
268
+ }
@@ -0,0 +1,158 @@
1
+ /* ═══════════════════════════════════════════════════════════════════
2
+ * LINK COMPONENT STYLES
3
+ * ═══════════════════════════════════════════════════════════════════ */
4
+
5
+ .jux-link {
6
+ display: inline-flex;
7
+ align-items: center;
8
+ gap: 0.375rem;
9
+ color: #3b82f6;
10
+ text-decoration: none;
11
+ font-size: 0.875rem;
12
+ font-weight: 500;
13
+ transition: color 0.15s ease, opacity 0.15s ease;
14
+ cursor: pointer;
15
+ }
16
+
17
+ .jux-link:hover {
18
+ color: #2563eb;
19
+ text-decoration: underline;
20
+ }
21
+
22
+ .jux-link:focus-visible {
23
+ outline: 2px solid #3b82f6;
24
+ outline-offset: 2px;
25
+ border-radius: 0.25rem;
26
+ }
27
+
28
+ /* Active state */
29
+ .jux-link-active {
30
+ color: #1e40af;
31
+ font-weight: 600;
32
+ }
33
+
34
+ /* Disabled state */
35
+ .jux-link-disabled {
36
+ color: #9ca3af;
37
+ cursor: not-allowed;
38
+ pointer-events: none;
39
+ opacity: 0.6;
40
+ }
41
+
42
+ .jux-link-disabled:hover {
43
+ text-decoration: none;
44
+ }
45
+
46
+ /* Icon positioning */
47
+ .jux-link-icon {
48
+ display: inline-flex;
49
+ align-items: center;
50
+ font-size: 1rem;
51
+ }
52
+
53
+ .jux-link-icon-left {
54
+ margin-right: -0.125rem;
55
+ }
56
+
57
+ .jux-link-icon-right {
58
+ margin-left: -0.125rem;
59
+ }
60
+
61
+ /* Text */
62
+ .jux-link-text {
63
+ line-height: 1;
64
+ }
65
+
66
+ /* ═══════════════════════════════════════════════════════════════════
67
+ * LINK VARIANTS
68
+ * ═══════════════════════════════════════════════════════════════════ */
69
+
70
+ /* Subtle variant */
71
+ .jux-link-subtle {
72
+ color: #6b7280;
73
+ }
74
+
75
+ .jux-link-subtle:hover {
76
+ color: #374151;
77
+ }
78
+
79
+ /* Muted variant */
80
+ .jux-link-muted {
81
+ color: #9ca3af;
82
+ font-weight: 400;
83
+ }
84
+
85
+ .jux-link-muted:hover {
86
+ color: #6b7280;
87
+ }
88
+
89
+ /* Underline variant */
90
+ .jux-link-underline {
91
+ text-decoration: underline;
92
+ }
93
+
94
+ .jux-link-underline:hover {
95
+ text-decoration: none;
96
+ }
97
+
98
+ /* Button-like variant */
99
+ .jux-link-button {
100
+ padding: 0.5rem 1rem;
101
+ border-radius: 0.375rem;
102
+ background-color: #3b82f6;
103
+ color: #ffffff;
104
+ font-weight: 500;
105
+ }
106
+
107
+ .jux-link-button:hover {
108
+ background-color: #2563eb;
109
+ text-decoration: none;
110
+ }
111
+
112
+ /* ═══════════════════════════════════════════════════════════════════
113
+ * NAVIGATION SPECIFIC
114
+ * ═══════════════════════════════════════════════════════════════════ */
115
+
116
+ /* Nav link styling */
117
+ .jux-nav-link {
118
+ padding: 0.5rem 0.75rem;
119
+ border-radius: 0.375rem;
120
+ color: #4b5563;
121
+ transition: background-color 0.15s ease, color 0.15s ease;
122
+ }
123
+
124
+ .jux-nav-link:hover {
125
+ background-color: #f3f4f6;
126
+ color: #111827;
127
+ text-decoration: none;
128
+ }
129
+
130
+ .jux-nav-link.jux-link-active {
131
+ background-color: #eff6ff;
132
+ color: #1e40af;
133
+ }
134
+
135
+ /* Breadcrumb link */
136
+ .jux-breadcrumb-link {
137
+ color: #6b7280;
138
+ font-size: 0.875rem;
139
+ }
140
+
141
+ .jux-breadcrumb-link:hover {
142
+ color: #111827;
143
+ }
144
+
145
+ .jux-breadcrumb-link.jux-link-active {
146
+ color: #111827;
147
+ font-weight: 600;
148
+ }
149
+
150
+ /* Footer link */
151
+ .jux-footer-link {
152
+ color: #9ca3af;
153
+ font-size: 0.875rem;
154
+ }
155
+
156
+ .jux-footer-link:hover {
157
+ color: #d1d5db;
158
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.1.113",
3
+ "version": "1.1.115",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "index.js",