@ktfth/stickjs 3.0.0 → 3.0.2

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/bin/registry.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "components": {
3
- "accordion": { "html": "components/accordion.html", "plugin": null },
4
- "tabs": { "html": "components/tabs.html", "plugin": null },
5
- "toggle": { "html": "components/toggle.html", "plugin": null },
6
- "notification": { "html": "components/notification.html", "plugin": null },
7
- "copy-button": { "html": "components/copy-button.html", "plugin": null },
8
- "skeleton": { "html": "components/skeleton.html", "plugin": null },
9
- "dialog": { "html": "components/dialog.html", "plugin": null },
10
- "toast": { "html": "components/toast.html", "plugin": "plugins/toast.js" },
11
- "dropdown": { "html": "components/dropdown.html", "plugin": "plugins/dropdown.js" },
12
- "tooltip": { "html": "components/tooltip.html", "plugin": "plugins/tooltip.js" },
13
- "toggle-group": { "html": "components/toggle-group.html", "plugin": null },
14
- "command-palette": { "html": "components/command-palette.html", "plugin": "plugins/command-palette.js" },
15
- "data-table": { "html": "components/data-table.html", "plugin": "plugins/data-table.js" },
16
- "stepper": { "html": "components/stepper.html", "plugin": "plugins/stepper.js" },
17
- "autocomplete": { "html": "components/autocomplete.html", "plugin": "plugins/autocomplete.js" }
3
+ "accordion": { "html": "components/accordion.html", "plugin": null, "template": "templates/accordion.html" },
4
+ "tabs": { "html": "components/tabs.html", "plugin": null, "template": "templates/tabs.html" },
5
+ "toggle": { "html": "components/toggle.html", "plugin": null, "template": "templates/toggle.html" },
6
+ "notification": { "html": "components/notification.html", "plugin": null, "template": "templates/notification.html" },
7
+ "copy-button": { "html": "components/copy-button.html", "plugin": null, "template": "templates/copy-button.html" },
8
+ "skeleton": { "html": "components/skeleton.html", "plugin": null, "template": "templates/skeleton.html" },
9
+ "dialog": { "html": "components/dialog.html", "plugin": null, "template": "templates/dialog.html" },
10
+ "toast": { "html": "components/toast.html", "plugin": "plugins/toast.js", "template": "templates/toast.html" },
11
+ "dropdown": { "html": "components/dropdown.html", "plugin": "plugins/dropdown.js", "template": "templates/dropdown.html" },
12
+ "tooltip": { "html": "components/tooltip.html", "plugin": "plugins/tooltip.js", "template": "templates/tooltip.html" },
13
+ "toggle-group": { "html": "components/toggle-group.html", "plugin": null, "template": "templates/toggle-group.html" },
14
+ "command-palette": { "html": "components/command-palette.html", "plugin": "plugins/command-palette.js", "template": "templates/command-palette.html" },
15
+ "data-table": { "html": "components/data-table.html", "plugin": "plugins/data-table.js", "template": "templates/data-table.html" },
16
+ "stepper": { "html": "components/stepper.html", "plugin": "plugins/stepper.js", "template": "templates/stepper.html" },
17
+ "autocomplete": { "html": "components/autocomplete.html", "plugin": "plugins/autocomplete.js", "template": "templates/autocomplete.html" }
18
18
  },
19
19
  "css": "stick-ui.css"
20
20
  }
package/bin/stickjs.js CHANGED
@@ -50,15 +50,19 @@ ${bold('Usage:')}
50
50
  npx stickjs ${cyan('add')} <name> [name...] Add component(s) to ./stick-ui/
51
51
  npx stickjs ${cyan('add')} ${dim('--all')} Add all components
52
52
  npx stickjs ${cyan('add')} <name> ${dim('--force')} Overwrite existing files
53
+ npx stickjs ${cyan('add')} <name> ${dim('--template')} Add full-page template instead of snippet
53
54
 
54
55
  ${bold('Options:')}
55
56
  ${dim('--help, -h')} Show this help message
56
57
  ${dim('--all')} Add every component
57
58
  ${dim('--force')} Overwrite existing files without warning
59
+ ${dim('--template')} Copy full-page HTML template (ready to open in browser)
58
60
 
59
61
  ${bold('Examples:')}
60
62
  npx stickjs add dialog toast
63
+ npx stickjs add dialog --template
61
64
  npx stickjs add --all --force
65
+ npx stickjs add --all --template
62
66
  `);
63
67
  }
64
68
 
@@ -67,15 +71,17 @@ function listComponents() {
67
71
  const maxLen = Math.max(...NAMES.map(n => n.length));
68
72
  for (const name of NAMES) {
69
73
  const entry = COMPONENTS[name];
70
- const plugin = entry.plugin ? yellow(' + plugin') : '';
71
- console.log(` ${cyan(name.padEnd(maxLen))} ${dim(entry.html)}${plugin}`);
74
+ const plugin = entry.plugin ? yellow(' + plugin') : '';
75
+ const tmpl = entry.template ? green(' + template') : '';
76
+ console.log(` ${cyan(name.padEnd(maxLen))} ${dim(entry.html)}${plugin}${tmpl}`);
72
77
  }
73
78
  console.log();
74
79
  }
75
80
 
76
81
  function addComponents(args) {
77
- const force = args.includes('--force');
78
- const all = args.includes('--all');
82
+ const force = args.includes('--force');
83
+ const all = args.includes('--all');
84
+ const template = args.includes('--template');
79
85
  const names = all
80
86
  ? NAMES
81
87
  : args.filter(a => !a.startsWith('--'));
@@ -97,6 +103,38 @@ function addComponents(args) {
97
103
  let added = 0;
98
104
  let skipped = 0;
99
105
 
106
+ if (template) {
107
+ // --template mode: copy full-page HTML templates
108
+ const templateDest = path.resolve(process.cwd(), 'stick-ui', 'templates');
109
+
110
+ for (const name of names) {
111
+ const entry = COMPONENTS[name];
112
+
113
+ if (!entry.template) {
114
+ console.log(yellow(' ~ ') + name + dim(' (no template available)'));
115
+ skipped++;
116
+ continue;
117
+ }
118
+
119
+ const src = path.join(PKG_ROOT, entry.template);
120
+ const dest = path.join(templateDest, name + '.html');
121
+
122
+ if (fs.existsSync(dest) && !force) {
123
+ console.log(yellow(' ~ ') + 'templates/' + name + '.html' + dim(' (exists, use --force to overwrite)'));
124
+ skipped++;
125
+ continue;
126
+ }
127
+
128
+ copyFile(src, dest);
129
+ console.log(green(' + ') + 'templates/' + name + '.html');
130
+ added++;
131
+ }
132
+
133
+ console.log(`\n${bold('Done:')} ${green(added + ' template(s) added')}, ${yellow(skipped + ' skipped')}\n`);
134
+ return;
135
+ }
136
+
137
+ // Default mode: copy component snippets
100
138
  // Copy CSS on first add (if not present)
101
139
  const cssSrc = path.join(PKG_ROOT, registry.css);
102
140
  const cssDest = path.join(DEST, registry.css);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ktfth/stickjs",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Declarative behavior for HTML elements. Zero dependencies.",
5
5
  "main": "stick.js",
6
6
  "types": "stick.d.ts",
@@ -28,11 +28,22 @@
28
28
  "test": "echo 'Open test/stick.test.html in a browser to run tests'",
29
29
  "release": "npm run minify && npm publish --access=public && vercel --prod ./docs"
30
30
  },
31
- "keywords": ["declarative", "html", "behavior", "htmx", "vanilla", "framework", "no-js", "components", "ui", "cli"],
31
+ "keywords": [
32
+ "declarative",
33
+ "html",
34
+ "behavior",
35
+ "htmx",
36
+ "vanilla",
37
+ "framework",
38
+ "no-js",
39
+ "components",
40
+ "ui",
41
+ "cli"
42
+ ],
32
43
  "author": "Kaique Silva <kaique.developer@gmail.com>",
33
44
  "license": "GPL-3.0",
34
45
  "repository": {
35
46
  "type": "git",
36
- "url": "https://github.com/kaiquekandykoga/Stickjs"
47
+ "url": "https://github.com/ktfth/Stickjs"
37
48
  }
38
49
  }
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * Stick UI — design tokens + component styles
3
- * https://github.com/kaiquekandykoga/Stickjs
3
+ * https://github.com/ktfth/Stickjs
4
4
  *
5
5
  * This file is OPTIONAL. Without it, data-stick behavior works identically.
6
6
  * Import for styled components. Customize by overriding --stk-* variables on :root.
@@ -9,21 +9,40 @@
9
9
 
10
10
  /* ── Tokens ─────────────────────────────────────────── */
11
11
  :root {
12
- /* Colors */
13
- --stk-bg: #ffffff;
14
- --stk-fg: #09090b;
15
- --stk-muted: #71717a;
16
- --stk-muted-fg: #f4f4f5;
17
- --stk-border: #e4e4e7;
18
- --stk-ring: #18181b;
19
- --stk-primary: #18181b;
20
- --stk-primary-fg: #fafafa;
21
- --stk-destructive: #ef4444;
22
- --stk-destructive-fg: #fafafa;
23
- --stk-success: #22c55e;
24
- --stk-success-fg: #fafafa;
25
- --stk-warning: #f59e0b;
26
- --stk-warning-fg: #09090b;
12
+ /* DARK FIX — semantic tokens (override --sui-* to theme your app) */
13
+ --sui-bg: #ffffff;
14
+ --sui-surface: #f4f4f5;
15
+ --sui-border: #e4e4e7;
16
+ --sui-text: #09090b;
17
+ --sui-text-muted: #71717a;
18
+ --sui-accent: #18181b;
19
+ --sui-accent-fg: #fafafa;
20
+ --sui-success: #22c55e;
21
+ --sui-success-fg: #fafafa;
22
+ --sui-warning: #f59e0b;
23
+ --sui-warning-fg: #09090b;
24
+ --sui-danger: #ef4444;
25
+ --sui-danger-fg: #fafafa;
26
+ --sui-info: #3b82f6;
27
+ --sui-info-fg: #fafafa;
28
+ --sui-ring: #18181b;
29
+ --sui-ring-shadow: rgba(24,24,27,0.1);
30
+
31
+ /* DARK FIX — backward-compatible aliases (--stk-* now reference --sui-*) */
32
+ --stk-bg: var(--sui-bg);
33
+ --stk-fg: var(--sui-text);
34
+ --stk-muted: var(--sui-text-muted);
35
+ --stk-muted-fg: var(--sui-surface);
36
+ --stk-border: var(--sui-border);
37
+ --stk-ring: var(--sui-ring);
38
+ --stk-primary: var(--sui-accent);
39
+ --stk-primary-fg: var(--sui-accent-fg);
40
+ --stk-destructive: var(--sui-danger);
41
+ --stk-destructive-fg: var(--sui-danger-fg);
42
+ --stk-success: var(--sui-success);
43
+ --stk-success-fg: var(--sui-success-fg);
44
+ --stk-warning: var(--sui-warning);
45
+ --stk-warning-fg: var(--sui-warning-fg);
27
46
 
28
47
  /* Radius */
29
48
  --stk-radius-sm: 4px;
@@ -67,31 +86,35 @@
67
86
  --stk-z-tooltip: 400;
68
87
  }
69
88
 
70
- /* ── Dark mode ──────────────────────────────────────── */
89
+ /* DARK FIX — dark mode tokens ──────────────────────── */
71
90
  @media (prefers-color-scheme: dark) {
72
91
  :root:not([data-theme="light"]) {
73
- --stk-bg: #09090b;
74
- --stk-fg: #fafafa;
75
- --stk-muted: #a1a1aa;
76
- --stk-muted-fg: #27272a;
77
- --stk-border: #27272a;
78
- --stk-ring: #d4d4d8;
79
- --stk-primary: #fafafa;
80
- --stk-primary-fg: #18181b;
92
+ --sui-bg: #09090b;
93
+ --sui-surface: #27272a;
94
+ --sui-border: #27272a;
95
+ --sui-text: #fafafa;
96
+ --sui-text-muted: #a1a1aa;
97
+ --sui-accent: #fafafa;
98
+ --sui-accent-fg: #18181b;
99
+ --sui-ring: #d4d4d8;
100
+ --sui-ring-shadow: rgba(212,212,216,0.2);
101
+ --sui-info: #60a5fa;
81
102
  --stk-shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
82
103
  --stk-shadow-md: 0 4px 6px -1px rgba(0,0,0,0.4);
83
104
  --stk-shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.5);
84
105
  }
85
106
  }
86
107
  [data-theme="dark"] {
87
- --stk-bg: #09090b;
88
- --stk-fg: #fafafa;
89
- --stk-muted: #a1a1aa;
90
- --stk-muted-fg: #27272a;
91
- --stk-border: #27272a;
92
- --stk-ring: #d4d4d8;
93
- --stk-primary: #fafafa;
94
- --stk-primary-fg: #18181b;
108
+ --sui-bg: #09090b;
109
+ --sui-surface: #27272a;
110
+ --sui-border: #27272a;
111
+ --sui-text: #fafafa;
112
+ --sui-text-muted: #a1a1aa;
113
+ --sui-accent: #fafafa;
114
+ --sui-accent-fg: #18181b;
115
+ --sui-ring: #d4d4d8;
116
+ --sui-ring-shadow: rgba(212,212,216,0.2);
117
+ --sui-info: #60a5fa;
95
118
  --stk-shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
96
119
  --stk-shadow-md: 0 4px 6px -1px rgba(0,0,0,0.4);
97
120
  --stk-shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.5);
@@ -145,14 +168,15 @@
145
168
  border: 1px solid var(--stk-border); background: var(--stk-bg); color: var(--stk-fg);
146
169
  text-decoration: none;
147
170
  }
148
- .stk-btn:hover { background: var(--stk-muted-fg); }
171
+ /* DARK FIX — explicit color on every :hover prevents dark-on-dark */
172
+ .stk-btn:hover { background: var(--stk-muted-fg); color: var(--stk-fg); }
149
173
  .stk-btn:focus-visible { outline: 2px solid var(--stk-ring); outline-offset: 2px; }
150
174
  .stk-btn-primary { background: var(--stk-primary); color: var(--stk-primary-fg); border-color: var(--stk-primary); }
151
- .stk-btn-primary:hover { background: var(--stk-primary); opacity: 0.9; }
175
+ .stk-btn-primary:hover { background: var(--stk-primary); color: var(--stk-primary-fg); opacity: 0.9; }
152
176
  .stk-btn-destructive { background: var(--stk-destructive); color: var(--stk-destructive-fg); border-color: var(--stk-destructive); }
153
- .stk-btn-destructive:hover { background: var(--stk-destructive); opacity: 0.9; }
177
+ .stk-btn-destructive:hover { background: var(--stk-destructive); color: var(--stk-destructive-fg); opacity: 0.9; }
154
178
  .stk-btn-ghost { background: transparent; border-color: transparent; }
155
- .stk-btn-ghost:hover { background: var(--stk-muted-fg); }
179
+ .stk-btn-ghost:hover { background: var(--stk-muted-fg); color: var(--stk-fg); }
156
180
  .stk-btn-sm { padding: var(--stk-space-1) var(--stk-space-2); font-size: var(--stk-text-xs); }
157
181
  .stk-btn-lg { padding: var(--stk-space-3) var(--stk-space-6); font-size: var(--stk-text-base); }
158
182
 
@@ -482,9 +506,11 @@
482
506
 
483
507
  .stk-table tbody tr:last-child td { border-bottom: none; }
484
508
 
509
+ /* DARK FIX — explicit color prevents dark text on dark hover bg */
485
510
  .stk-table tbody tr:hover {
486
511
  background: var(--stk-muted-fg);
487
- transition: background var(--stk-duration) var(--stk-easing);
512
+ color: var(--stk-fg);
513
+ transition: background var(--stk-duration) var(--stk-easing), color var(--stk-duration) var(--stk-easing);
488
514
  }
489
515
 
490
516
  /* Sortable headers */
@@ -539,7 +565,7 @@
539
565
  .stk-table-filter:focus {
540
566
  outline: none;
541
567
  border-color: var(--stk-ring);
542
- box-shadow: 0 0 0 2px rgba(24,24,27,0.1);
568
+ box-shadow: 0 0 0 2px var(--sui-ring-shadow); /* DARK FIX */
543
569
  }
544
570
 
545
571
  /* Pagination bar */
@@ -716,7 +742,7 @@
716
742
  .stk-stepper .stk-input:focus {
717
743
  outline: none;
718
744
  border-color: var(--stk-ring);
719
- box-shadow: 0 0 0 2px rgba(24,24,27,0.1);
745
+ box-shadow: 0 0 0 2px var(--sui-ring-shadow); /* DARK FIX */
720
746
  }
721
747
 
722
748
  .stk-stepper .stk-label {
@@ -750,7 +776,7 @@
750
776
  .stk-autocomplete-input:focus {
751
777
  outline: none;
752
778
  border-color: var(--stk-ring);
753
- box-shadow: 0 0 0 2px rgba(24,24,27,0.1);
779
+ box-shadow: 0 0 0 2px var(--sui-ring-shadow); /* DARK FIX */
754
780
  }
755
781
 
756
782
  .stk-autocomplete-dropdown {
@@ -795,6 +821,215 @@
795
821
  font-weight: 700;
796
822
  }
797
823
 
824
+ /* ══════════════════════════════════════════════════════
825
+ DARK FIX — Generic element styles & missing components
826
+ ══════════════════════════════════════════════════════ */
827
+
828
+ /* ── DARK FIX: Generic dialog base (BUG 4) ─────────── */
829
+ dialog {
830
+ margin: auto;
831
+ position: fixed;
832
+ inset: 0;
833
+ height: fit-content;
834
+ width: min(90%, 420px);
835
+ border: none;
836
+ border-radius: var(--stk-radius-lg, 12px);
837
+ padding: 0;
838
+ background: var(--sui-bg);
839
+ color: var(--sui-text);
840
+ box-shadow: var(--stk-shadow-lg);
841
+ z-index: var(--stk-z-modal, 200);
842
+ }
843
+ dialog::backdrop {
844
+ background: rgba(0,0,0,0.6);
845
+ }
846
+ dialog[open] {
847
+ animation: stk-dialog-in var(--stk-duration-slow, 300ms) var(--stk-easing);
848
+ }
849
+
850
+ /* ── DARK FIX: Generic form hover/focus (BUG 5) ────── */
851
+ input:hover,
852
+ select:hover,
853
+ textarea:hover {
854
+ color: var(--sui-text);
855
+ background-color: var(--sui-surface);
856
+ }
857
+ input:focus,
858
+ select:focus,
859
+ textarea:focus {
860
+ color: var(--sui-text);
861
+ outline: none;
862
+ border-color: var(--sui-ring);
863
+ box-shadow: 0 0 0 2px var(--sui-ring-shadow); /* DARK FIX */
864
+ }
865
+
866
+ /* ── DARK FIX: Generic .btn aliases (BUG 2 / BUG 3) ─ */
867
+ .btn {
868
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--stk-space-2, 8px);
869
+ padding: var(--stk-space-2, 8px) var(--stk-space-4, 16px);
870
+ border-radius: var(--stk-radius-md, 8px);
871
+ font-size: var(--stk-text-sm, 0.875rem); font-weight: 500;
872
+ cursor: pointer;
873
+ transition: all var(--stk-duration, 150ms) var(--stk-easing);
874
+ border: 1px solid var(--sui-border);
875
+ background: var(--sui-bg);
876
+ color: var(--sui-text);
877
+ text-decoration: none;
878
+ font-family: var(--stk-font);
879
+ }
880
+ .btn:hover {
881
+ background: var(--sui-surface);
882
+ color: var(--sui-text);
883
+ }
884
+ .btn:focus-visible {
885
+ outline: 2px solid var(--sui-ring);
886
+ outline-offset: 2px;
887
+ }
888
+
889
+ .btn-primary {
890
+ background: var(--sui-accent);
891
+ color: var(--sui-accent-fg);
892
+ border-color: var(--sui-accent);
893
+ }
894
+ .btn-primary:hover {
895
+ background: var(--sui-accent);
896
+ color: var(--sui-accent-fg);
897
+ opacity: 0.9;
898
+ }
899
+
900
+ .btn-danger {
901
+ background: var(--sui-danger);
902
+ color: var(--sui-danger-fg);
903
+ border-color: var(--sui-danger);
904
+ }
905
+ .btn-danger:hover {
906
+ background: var(--sui-danger);
907
+ color: var(--sui-danger-fg);
908
+ opacity: 0.9;
909
+ }
910
+
911
+ .btn-ghost {
912
+ background: transparent;
913
+ border-color: transparent;
914
+ color: var(--sui-text);
915
+ }
916
+ .btn-ghost:hover {
917
+ background: var(--sui-surface);
918
+ color: var(--sui-text);
919
+ }
920
+
921
+ .btn-sm { padding: var(--stk-space-1, 4px) var(--stk-space-2, 8px); font-size: var(--stk-text-xs, 0.75rem); }
922
+ .btn-lg { padding: var(--stk-space-3, 12px) var(--stk-space-6, 24px); font-size: var(--stk-text-base, 1rem); }
923
+
924
+ /* ── DARK FIX: Generic table row hover (BUG 1) ─────── */
925
+ table:not(.stk-table) tbody tr:hover td {
926
+ color: var(--sui-text);
927
+ }
928
+
929
+ /* ── DARK FIX: Badge component (BUG 6) ─────────────── */
930
+ .badge, .stk-badge {
931
+ display: inline-flex; align-items: center;
932
+ padding: var(--stk-space-1, 4px) var(--stk-space-2, 8px);
933
+ font-size: var(--stk-text-xs, 0.75rem); font-weight: 500;
934
+ border-radius: var(--stk-radius-full, 9999px);
935
+ line-height: 1.4;
936
+ background: var(--sui-surface);
937
+ color: var(--sui-text);
938
+ }
939
+ .badge-info, .stk-badge-info {
940
+ background: var(--sui-info);
941
+ color: var(--sui-info-fg);
942
+ }
943
+ .badge-success, .stk-badge-success {
944
+ background: var(--sui-success);
945
+ color: var(--sui-success-fg);
946
+ }
947
+ .badge-warning, .stk-badge-warning {
948
+ background: var(--sui-warning);
949
+ color: var(--sui-warning-fg);
950
+ }
951
+ .badge-danger, .stk-badge-danger {
952
+ background: var(--sui-danger);
953
+ color: var(--sui-danger-fg);
954
+ }
955
+
956
+ /* ── DARK FIX: Alert component (BUG 6) ─────────────── */
957
+ .alert, .stk-alert {
958
+ display: flex; align-items: flex-start; gap: var(--stk-space-3, 12px);
959
+ padding: var(--stk-space-3, 12px) var(--stk-space-4, 16px);
960
+ border-radius: var(--stk-radius-md, 8px);
961
+ font-size: var(--stk-text-sm, 0.875rem);
962
+ border: 1px solid var(--sui-border);
963
+ background: var(--sui-bg);
964
+ color: var(--sui-text);
965
+ }
966
+ .alert-success, .stk-alert-success {
967
+ border-left: 3px solid var(--sui-success);
968
+ }
969
+ .alert-danger, .stk-alert-danger {
970
+ border-left: 3px solid var(--sui-danger);
971
+ }
972
+ .alert-warning, .stk-alert-warning {
973
+ border-left: 3px solid var(--sui-warning);
974
+ }
975
+ .alert-info, .stk-alert-info {
976
+ border-left: 3px solid var(--sui-info);
977
+ }
978
+
979
+ /* ── DARK FIX: Form group component (BUG 6) ────────── */
980
+ .form-group, .stk-form-group {
981
+ display: flex; flex-direction: column;
982
+ gap: var(--stk-space-1, 4px);
983
+ margin-bottom: var(--stk-space-4, 16px);
984
+ }
985
+ .form-group label, .stk-form-group label {
986
+ font-size: var(--stk-text-sm, 0.875rem); font-weight: 500;
987
+ color: var(--sui-text);
988
+ }
989
+ .form-group input,
990
+ .form-group select,
991
+ .form-group textarea,
992
+ .stk-form-group input,
993
+ .stk-form-group select,
994
+ .stk-form-group textarea {
995
+ display: block; width: 100%;
996
+ padding: var(--stk-space-2, 8px) var(--stk-space-3, 12px);
997
+ border: 1px solid var(--sui-border);
998
+ border-radius: var(--stk-radius-md, 8px);
999
+ font-size: var(--stk-text-sm, 0.875rem);
1000
+ font-family: var(--stk-font);
1001
+ color: var(--sui-text);
1002
+ background: var(--sui-bg);
1003
+ transition: border-color var(--stk-duration, 150ms) var(--stk-easing),
1004
+ box-shadow var(--stk-duration, 150ms) var(--stk-easing);
1005
+ }
1006
+ .form-group input::placeholder,
1007
+ .form-group textarea::placeholder,
1008
+ .stk-form-group input::placeholder,
1009
+ .stk-form-group textarea::placeholder {
1010
+ color: var(--sui-text-muted);
1011
+ }
1012
+
1013
+ /* ── DARK FIX: Section header component (BUG 6) ────── */
1014
+ .section-header, .stk-section-header {
1015
+ display: flex; align-items: center; justify-content: space-between;
1016
+ gap: var(--stk-space-4, 16px);
1017
+ margin-bottom: var(--stk-space-4, 16px);
1018
+ padding-bottom: var(--stk-space-3, 12px);
1019
+ border-bottom: 1px solid var(--sui-border);
1020
+ }
1021
+ .section-header h1, .section-header h2, .section-header h3,
1022
+ .stk-section-header h1, .stk-section-header h2, .stk-section-header h3 {
1023
+ margin: 0;
1024
+ font-size: var(--stk-text-lg, 1.125rem); font-weight: 600;
1025
+ color: var(--sui-text);
1026
+ }
1027
+ .section-header p, .stk-section-header p {
1028
+ margin: 0;
1029
+ font-size: var(--stk-text-sm, 0.875rem);
1030
+ color: var(--sui-text-muted);
1031
+ }
1032
+
798
1033
  .stk-autocomplete-empty {
799
1034
  padding: var(--stk-space-4) var(--stk-space-3);
800
1035
  text-align: center;
@@ -0,0 +1,49 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Accordion — Stick.js Template</title>
7
+ <link rel="stylesheet" href="https://unpkg.com/@ktfth/stickjs/stick-ui/stick-ui.css">
8
+ <script src="https://unpkg.com/@ktfth/stickjs/stick.js"></script>
9
+ </head>
10
+ <body style="padding: 2rem; max-width: 600px; margin: 0 auto;">
11
+
12
+ <h1>Accordion</h1>
13
+ <p>Click a section to expand or collapse it.</p>
14
+
15
+ <div class="stk-accordion">
16
+ <div class="stk-accordion-item">
17
+ <button class="stk-accordion-trigger" aria-expanded="false"
18
+ data-stick="click:toggle" data-stick-target="next">
19
+ What is Stick.js?
20
+ </button>
21
+ <div class="stk-accordion-content" hidden>
22
+ <p>Stick.js is a declarative behavior framework for HTML elements.
23
+ Zero dependencies, zero build step — just add data attributes.</p>
24
+ </div>
25
+ </div>
26
+ <div class="stk-accordion-item">
27
+ <button class="stk-accordion-trigger" aria-expanded="false"
28
+ data-stick="click:toggle" data-stick-target="next">
29
+ How do I install it?
30
+ </button>
31
+ <div class="stk-accordion-content" hidden>
32
+ <p>Include the script tag:
33
+ <code>&lt;script src="https://unpkg.com/@ktfth/stickjs/stick.js"&gt;&lt;/script&gt;</code>
34
+ or install via npm: <code>npm install @ktfth/stickjs</code></p>
35
+ </div>
36
+ </div>
37
+ <div class="stk-accordion-item">
38
+ <button class="stk-accordion-trigger" aria-expanded="false"
39
+ data-stick="click:toggle" data-stick-target="next">
40
+ Does it require a build step?
41
+ </button>
42
+ <div class="stk-accordion-content" hidden>
43
+ <p>No. Stick.js works directly in the browser with zero configuration.</p>
44
+ </div>
45
+ </div>
46
+ </div>
47
+
48
+ </body>
49
+ </html>
@@ -0,0 +1,63 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Autocomplete — Stick.js Template</title>
7
+ <link rel="stylesheet" href="https://unpkg.com/@ktfth/stickjs/stick-ui/stick-ui.css">
8
+ <script src="https://unpkg.com/@ktfth/stickjs/stick.js"></script>
9
+ <script src="https://unpkg.com/@ktfth/stickjs/stick-ui/plugins/autocomplete.js"></script>
10
+ </head>
11
+ <body style="padding: 2rem; max-width: 600px; margin: 0 auto;">
12
+
13
+ <h1>Autocomplete</h1>
14
+ <p>Type to search and select from suggestions.</p>
15
+
16
+ <!-- Static options (from a hidden list) -->
17
+ <h3>Programming Language</h3>
18
+ <div class="stk-autocomplete" style="width: 300px;">
19
+ <label class="stk-label" for="lang-input">Choose a language</label>
20
+ <input id="lang-input"
21
+ class="stk-autocomplete-input"
22
+ type="text"
23
+ placeholder="Search languages..."
24
+ data-stick="input:autocomplete:#language-list"
25
+ data-stk-autocomplete-min="1">
26
+ <ul id="language-list" hidden>
27
+ <li data-value="javascript">JavaScript</li>
28
+ <li data-value="typescript">TypeScript</li>
29
+ <li data-value="python">Python</li>
30
+ <li data-value="rust">Rust</li>
31
+ <li data-value="go">Go</li>
32
+ <li data-value="java">Java</li>
33
+ <li data-value="csharp">C#</li>
34
+ <li data-value="cpp">C++</li>
35
+ <li data-value="ruby">Ruby</li>
36
+ <li data-value="swift">Swift</li>
37
+ <li data-value="kotlin">Kotlin</li>
38
+ <li data-value="php">PHP</li>
39
+ </ul>
40
+ </div>
41
+
42
+ <!-- Programmatic options -->
43
+ <h3 style="margin-top: 2rem;">City</h3>
44
+ <div class="stk-autocomplete" style="width: 300px;">
45
+ <label class="stk-label" for="city-input">Choose a city</label>
46
+ <input id="city-input"
47
+ class="stk-autocomplete-input"
48
+ type="text"
49
+ placeholder="Type a city name..."
50
+ data-stick="input:autocomplete"
51
+ data-stk-autocomplete-min="1">
52
+ </div>
53
+
54
+ <script>
55
+ stkAutocomplete.setOptions(document.getElementById('city-input'), [
56
+ 'New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix',
57
+ 'San Francisco', 'Seattle', 'Denver', 'Boston', 'Miami',
58
+ 'Austin', 'Portland'
59
+ ]);
60
+ </script>
61
+
62
+ </body>
63
+ </html>