@ktbsh/ui 0.2.0 → 0.3.0

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.
Files changed (36) hide show
  1. package/dist/custom-elements.json +155 -0
  2. package/dist/react/preset-toggle.d.ts +18 -0
  3. package/dist/react/preset-toggle.js +30 -0
  4. package/dist/react/scroll-top.d.ts +20 -0
  5. package/dist/react/scroll-top.js +30 -0
  6. package/dist/react/theme-toggle.d.ts +18 -0
  7. package/dist/react/theme-toggle.js +30 -0
  8. package/dist/react/toggle-group.d.ts +17 -0
  9. package/dist/react/toggle-group.js +30 -0
  10. package/dist/vanilla/checkbox.js +53 -9
  11. package/dist/vanilla/checkbox.src.js +1 -1
  12. package/dist/vanilla/input.js +6 -0
  13. package/dist/vanilla/input.src.js +1 -1
  14. package/dist/vanilla/preset-toggle.d.ts +2 -0
  15. package/dist/vanilla/preset-toggle.js +72 -0
  16. package/dist/vanilla/preset-toggle.src.js +271 -0
  17. package/dist/vanilla/radio.js +44 -10
  18. package/dist/vanilla/radio.src.js +1 -1
  19. package/dist/vanilla/scroll-top.d.ts +2 -0
  20. package/dist/vanilla/scroll-top.js +69 -0
  21. package/dist/vanilla/scroll-top.src.js +251 -0
  22. package/dist/vanilla/select.js +42 -3
  23. package/dist/vanilla/select.src.js +1 -1
  24. package/dist/vanilla/skeleton.js +8 -3
  25. package/dist/vanilla/skeleton.src.js +1 -1
  26. package/dist/vanilla/switch.js +57 -19
  27. package/dist/vanilla/switch.src.js +1 -1
  28. package/dist/vanilla/textarea.js +6 -0
  29. package/dist/vanilla/textarea.src.js +1 -1
  30. package/dist/vanilla/theme-toggle.d.ts +2 -0
  31. package/dist/vanilla/theme-toggle.js +72 -0
  32. package/dist/vanilla/theme-toggle.src.js +242 -0
  33. package/dist/vanilla/toggle-group.d.ts +2 -0
  34. package/dist/vanilla/toggle-group.js +19 -0
  35. package/dist/vanilla/toggle-group.src.js +215 -0
  36. package/package.json +1 -1
@@ -207,6 +207,45 @@
207
207
  }
208
208
  ]
209
209
  },
210
+ {
211
+ "kind": "javascript-module",
212
+ "path": "vanilla/preset-toggle.js",
213
+ "declarations": [
214
+ {
215
+ "kind": "class",
216
+ "description": "",
217
+ "name": "KitbashPresetToggle",
218
+ "customElement": true,
219
+ "tagName": "kitbash-preset-toggle",
220
+ "attributes": [
221
+ {
222
+ "name": "value",
223
+ "type": {
224
+ "text": "String"
225
+ },
226
+ "default": "\"\""
227
+ },
228
+ {
229
+ "name": "storageKey",
230
+ "type": {
231
+ "text": "String"
232
+ },
233
+ "default": "\"ui-mode\""
234
+ }
235
+ ]
236
+ }
237
+ ],
238
+ "exports": [
239
+ {
240
+ "kind": "custom-element-definition",
241
+ "name": "kitbash-preset-toggle",
242
+ "declaration": {
243
+ "name": "KitbashPresetToggle",
244
+ "module": "vanilla/preset-toggle.js"
245
+ }
246
+ }
247
+ ]
248
+ },
210
249
  {
211
250
  "kind": "javascript-module",
212
251
  "path": "vanilla/toast.js",
@@ -564,6 +603,98 @@
564
603
  }
565
604
  ]
566
605
  },
606
+ {
607
+ "kind": "javascript-module",
608
+ "path": "vanilla/theme-toggle.js",
609
+ "declarations": [
610
+ {
611
+ "kind": "class",
612
+ "description": "",
613
+ "name": "KitbashThemeToggle",
614
+ "customElement": true,
615
+ "tagName": "kitbash-theme-toggle",
616
+ "attributes": [
617
+ {
618
+ "name": "value",
619
+ "type": {
620
+ "text": "String"
621
+ },
622
+ "default": "\"\""
623
+ },
624
+ {
625
+ "name": "storageKey",
626
+ "type": {
627
+ "text": "String"
628
+ },
629
+ "default": "\"theme\""
630
+ }
631
+ ]
632
+ }
633
+ ],
634
+ "exports": [
635
+ {
636
+ "kind": "custom-element-definition",
637
+ "name": "kitbash-theme-toggle",
638
+ "declaration": {
639
+ "name": "KitbashThemeToggle",
640
+ "module": "vanilla/theme-toggle.js"
641
+ }
642
+ }
643
+ ]
644
+ },
645
+ {
646
+ "kind": "javascript-module",
647
+ "path": "vanilla/scroll-top.js",
648
+ "declarations": [
649
+ {
650
+ "kind": "class",
651
+ "description": "",
652
+ "name": "KitbashScrollTop",
653
+ "customElement": true,
654
+ "tagName": "kitbash-scroll-top",
655
+ "attributes": [
656
+ {
657
+ "name": "visible",
658
+ "type": {
659
+ "text": "Boolean"
660
+ },
661
+ "default": "false"
662
+ },
663
+ {
664
+ "name": "label",
665
+ "type": {
666
+ "text": "String"
667
+ },
668
+ "default": "\"Scroll to top\""
669
+ },
670
+ {
671
+ "name": "caption",
672
+ "type": {
673
+ "text": "String"
674
+ },
675
+ "default": "\"$ top\""
676
+ },
677
+ {
678
+ "name": "behavior",
679
+ "type": {
680
+ "text": "String"
681
+ },
682
+ "default": "\"smooth\""
683
+ }
684
+ ]
685
+ }
686
+ ],
687
+ "exports": [
688
+ {
689
+ "kind": "custom-element-definition",
690
+ "name": "kitbash-scroll-top",
691
+ "declaration": {
692
+ "name": "KitbashScrollTop",
693
+ "module": "vanilla/scroll-top.js"
694
+ }
695
+ }
696
+ ]
697
+ },
567
698
  {
568
699
  "kind": "javascript-module",
569
700
  "path": "vanilla/switch.js",
@@ -744,6 +875,30 @@
744
875
  }
745
876
  ]
746
877
  },
878
+ {
879
+ "kind": "javascript-module",
880
+ "path": "vanilla/toggle-group.js",
881
+ "declarations": [
882
+ {
883
+ "kind": "class",
884
+ "description": "",
885
+ "name": "KitbashToggleGroup",
886
+ "customElement": true,
887
+ "tagName": "kitbash-toggle-group",
888
+ "attributes": []
889
+ }
890
+ ],
891
+ "exports": [
892
+ {
893
+ "kind": "custom-element-definition",
894
+ "name": "kitbash-toggle-group",
895
+ "declaration": {
896
+ "name": "KitbashToggleGroup",
897
+ "module": "vanilla/toggle-group.js"
898
+ }
899
+ }
900
+ ]
901
+ },
747
902
  {
748
903
  "kind": "javascript-module",
749
904
  "path": "vanilla/stack.js",
@@ -0,0 +1,18 @@
1
+
2
+ import * as React from 'react';
3
+
4
+ export interface KitbashPresetToggleProps extends React.HTMLAttributes<HTMLElement> {
5
+ 'value'?: string;
6
+ 'storageKey'?: string;
7
+ onKitbashChange?: (event: CustomEvent<{ props: Record<string, unknown>; state: Record<string, unknown> }>) => void;
8
+ }
9
+
10
+ declare global {
11
+ namespace JSX {
12
+ interface IntrinsicElements {
13
+ 'kitbash-preset-toggle': KitbashPresetToggleProps & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
14
+ }
15
+ }
16
+ }
17
+
18
+ export declare const KitbashPresetToggle: React.ForwardRefExoticComponent<KitbashPresetToggleProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,30 @@
1
+
2
+ import * as React from 'react';
3
+ import '../vanilla/preset-toggle.js';
4
+
5
+ export const KitbashPresetToggle = React.forwardRef(({ children, onKitbashChange, ...props }, ref) => {
6
+ const innerRef = React.useRef(null);
7
+
8
+ // kitbash-change is a CustomEvent — bridge manually. Native events (onClick, etc.)
9
+ // stay on ...props so React 19 binds them once (no double-fire).
10
+ React.useEffect(() => {
11
+ const el = innerRef.current;
12
+ if (!el || !onKitbashChange) return;
13
+
14
+ const handleCustomChange = (e) => onKitbashChange(e);
15
+ el.addEventListener('kitbash-change', handleCustomChange);
16
+ return () => el.removeEventListener('kitbash-change', handleCustomChange);
17
+ }, [onKitbashChange]);
18
+
19
+ // Callback ref: assign + clear on unmount / ref change (object + function refs).
20
+ const setRefs = React.useCallback((node) => {
21
+ innerRef.current = node;
22
+ if (typeof ref === 'function') {
23
+ ref(node);
24
+ } else if (ref && typeof ref === 'object') {
25
+ ref.current = node;
26
+ }
27
+ }, [ref]);
28
+
29
+ return React.createElement('kitbash-preset-toggle', { ref: setRefs, ...props }, children);
30
+ });
@@ -0,0 +1,20 @@
1
+
2
+ import * as React from 'react';
3
+
4
+ export interface KitbashScrollTopProps extends React.HTMLAttributes<HTMLElement> {
5
+ 'visible'?: boolean;
6
+ 'label'?: string;
7
+ 'caption'?: string;
8
+ 'behavior'?: string;
9
+ onKitbashChange?: (event: CustomEvent<{ props: Record<string, unknown>; state: Record<string, unknown> }>) => void;
10
+ }
11
+
12
+ declare global {
13
+ namespace JSX {
14
+ interface IntrinsicElements {
15
+ 'kitbash-scroll-top': KitbashScrollTopProps & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
16
+ }
17
+ }
18
+ }
19
+
20
+ export declare const KitbashScrollTop: React.ForwardRefExoticComponent<KitbashScrollTopProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,30 @@
1
+
2
+ import * as React from 'react';
3
+ import '../vanilla/scroll-top.js';
4
+
5
+ export const KitbashScrollTop = React.forwardRef(({ children, onKitbashChange, ...props }, ref) => {
6
+ const innerRef = React.useRef(null);
7
+
8
+ // kitbash-change is a CustomEvent — bridge manually. Native events (onClick, etc.)
9
+ // stay on ...props so React 19 binds them once (no double-fire).
10
+ React.useEffect(() => {
11
+ const el = innerRef.current;
12
+ if (!el || !onKitbashChange) return;
13
+
14
+ const handleCustomChange = (e) => onKitbashChange(e);
15
+ el.addEventListener('kitbash-change', handleCustomChange);
16
+ return () => el.removeEventListener('kitbash-change', handleCustomChange);
17
+ }, [onKitbashChange]);
18
+
19
+ // Callback ref: assign + clear on unmount / ref change (object + function refs).
20
+ const setRefs = React.useCallback((node) => {
21
+ innerRef.current = node;
22
+ if (typeof ref === 'function') {
23
+ ref(node);
24
+ } else if (ref && typeof ref === 'object') {
25
+ ref.current = node;
26
+ }
27
+ }, [ref]);
28
+
29
+ return React.createElement('kitbash-scroll-top', { ref: setRefs, ...props }, children);
30
+ });
@@ -0,0 +1,18 @@
1
+
2
+ import * as React from 'react';
3
+
4
+ export interface KitbashThemeToggleProps extends React.HTMLAttributes<HTMLElement> {
5
+ 'value'?: string;
6
+ 'storageKey'?: string;
7
+ onKitbashChange?: (event: CustomEvent<{ props: Record<string, unknown>; state: Record<string, unknown> }>) => void;
8
+ }
9
+
10
+ declare global {
11
+ namespace JSX {
12
+ interface IntrinsicElements {
13
+ 'kitbash-theme-toggle': KitbashThemeToggleProps & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
14
+ }
15
+ }
16
+ }
17
+
18
+ export declare const KitbashThemeToggle: React.ForwardRefExoticComponent<KitbashThemeToggleProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,30 @@
1
+
2
+ import * as React from 'react';
3
+ import '../vanilla/theme-toggle.js';
4
+
5
+ export const KitbashThemeToggle = React.forwardRef(({ children, onKitbashChange, ...props }, ref) => {
6
+ const innerRef = React.useRef(null);
7
+
8
+ // kitbash-change is a CustomEvent — bridge manually. Native events (onClick, etc.)
9
+ // stay on ...props so React 19 binds them once (no double-fire).
10
+ React.useEffect(() => {
11
+ const el = innerRef.current;
12
+ if (!el || !onKitbashChange) return;
13
+
14
+ const handleCustomChange = (e) => onKitbashChange(e);
15
+ el.addEventListener('kitbash-change', handleCustomChange);
16
+ return () => el.removeEventListener('kitbash-change', handleCustomChange);
17
+ }, [onKitbashChange]);
18
+
19
+ // Callback ref: assign + clear on unmount / ref change (object + function refs).
20
+ const setRefs = React.useCallback((node) => {
21
+ innerRef.current = node;
22
+ if (typeof ref === 'function') {
23
+ ref(node);
24
+ } else if (ref && typeof ref === 'object') {
25
+ ref.current = node;
26
+ }
27
+ }, [ref]);
28
+
29
+ return React.createElement('kitbash-theme-toggle', { ref: setRefs, ...props }, children);
30
+ });
@@ -0,0 +1,17 @@
1
+
2
+ import * as React from 'react';
3
+
4
+ export interface KitbashToggleGroupProps extends React.HTMLAttributes<HTMLElement> {
5
+
6
+ onKitbashChange?: (event: CustomEvent<{ props: Record<string, unknown>; state: Record<string, unknown> }>) => void;
7
+ }
8
+
9
+ declare global {
10
+ namespace JSX {
11
+ interface IntrinsicElements {
12
+ 'kitbash-toggle-group': KitbashToggleGroupProps & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
13
+ }
14
+ }
15
+ }
16
+
17
+ export declare const KitbashToggleGroup: React.ForwardRefExoticComponent<KitbashToggleGroupProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,30 @@
1
+
2
+ import * as React from 'react';
3
+ import '../vanilla/toggle-group.js';
4
+
5
+ export const KitbashToggleGroup = React.forwardRef(({ children, onKitbashChange, ...props }, ref) => {
6
+ const innerRef = React.useRef(null);
7
+
8
+ // kitbash-change is a CustomEvent — bridge manually. Native events (onClick, etc.)
9
+ // stay on ...props so React 19 binds them once (no double-fire).
10
+ React.useEffect(() => {
11
+ const el = innerRef.current;
12
+ if (!el || !onKitbashChange) return;
13
+
14
+ const handleCustomChange = (e) => onKitbashChange(e);
15
+ el.addEventListener('kitbash-change', handleCustomChange);
16
+ return () => el.removeEventListener('kitbash-change', handleCustomChange);
17
+ }, [onKitbashChange]);
18
+
19
+ // Callback ref: assign + clear on unmount / ref change (object + function refs).
20
+ const setRefs = React.useCallback((node) => {
21
+ innerRef.current = node;
22
+ if (typeof ref === 'function') {
23
+ ref(node);
24
+ } else if (ref && typeof ref === 'object') {
25
+ ref.current = node;
26
+ }
27
+ }, [ref]);
28
+
29
+ return React.createElement('kitbash-toggle-group', { ref: setRefs, ...props }, children);
30
+ });
@@ -9,29 +9,73 @@ var d=(_,U,B,Y,I)=>{let W=B.length,J=U.length,z=W,O=0,$=0,X=null;while(O<J||$<z)
9
9
  color: var(--kb-color-fg-default);
10
10
  }
11
11
  input {
12
- width: 1.125rem;
13
- height: 1.125rem;
14
- min-width: 1.125rem;
15
- min-height: 1.125rem;
12
+ appearance: none;
13
+ -webkit-appearance: none;
14
+ box-sizing: border-box;
15
+ width: 1.15em;
16
+ height: 1.15em;
17
+ min-width: 1.15em;
18
+ min-height: 1.15em;
16
19
  margin: 0;
17
- accent-color: var(--kb-color-accent-default);
20
+ flex-shrink: 0;
21
+ display: grid;
22
+ place-content: center;
23
+ border: 2px solid var(--kb-color-border-default);
24
+ border-radius: var(--kb-radius-sm);
25
+ background: var(--kb-color-bg-canvas);
26
+ color: var(--kb-color-fg-on-accent);
18
27
  cursor: pointer;
28
+ transition:
29
+ background-color 0.12s ease,
30
+ border-color 0.12s ease,
31
+ box-shadow 0.12s ease;
32
+ }
33
+ input::before {
34
+ content: '';
35
+ width: 0.65em;
36
+ height: 0.65em;
37
+ transform: scale(0);
38
+ transition: transform 0.12s ease;
39
+ box-shadow: inset 1em 1em currentColor;
40
+ clip-path: polygon(
41
+ 14% 44%,
42
+ 0 65%,
43
+ 50% 100%,
44
+ 100% 16%,
45
+ 80% 0%,
46
+ 43% 62%
47
+ );
48
+ }
49
+ input:hover:not(:disabled) {
50
+ border-color: var(--kb-color-border-focus);
51
+ }
52
+ input:checked {
53
+ background: var(--kb-color-accent-default);
54
+ border-color: var(--kb-color-accent-default);
55
+ }
56
+ input:checked::before {
57
+ transform: scale(1);
19
58
  }
20
59
  input:focus-visible {
21
60
  outline: none;
22
61
  box-shadow: var(--kb-focus-ring);
23
- border-radius: var(--kb-radius-sm);
24
62
  }
25
63
  input:disabled {
26
64
  cursor: not-allowed;
27
- opacity: 0.55;
65
+ opacity: 0.5;
28
66
  }
29
- input[aria-invalid="true"] {
30
- outline: 1px solid var(--kb-color-danger-default);
67
+ input[aria-invalid='true'] {
68
+ border-color: var(--kb-color-danger-default);
31
69
  }
32
70
  .label {
33
71
  line-height: var(--kb-line-height-normal);
34
72
  }
73
+ @media (prefers-reduced-motion: reduce) {
74
+ input,
75
+ input::before {
76
+ transition: none;
77
+ }
78
+ }
35
79
  `);class L1 extends HTMLElement{static formAssociated=!0;static get observedAttributes(){return["name","value","checked","disabled","required","invalid"]}static get propTypes(){return{name:"String",value:"String",checked:"Boolean",disabled:"Boolean",required:"Boolean",invalid:"Boolean"}}get name(){return this._props.name}set name(_){this._assignProp("name",_),this.update()}get value(){return this._props.value}set value(_){this._assignProp("value",_),this.update()}get checked(){return this._props.checked}set checked(_){this._assignProp("checked",_),this.update()}get disabled(){return this._props.disabled}set disabled(_){this._assignProp("disabled",_),this.update()}get required(){return this._props.required}set required(_){this._assignProp("required",_),this.update()}get invalid(){return this._props.invalid}set invalid(_){this._assignProp("invalid",_),this.update()}constructor(){super();this.attachShadow({mode:"open",delegatesFocus:!0}),this._internals=this.attachInternals(),this.shadowRoot.adoptedStyleSheets=[G1],this._defaults={name:"",value:"on",checked:!1,disabled:!1,required:!1,invalid:!1},this._state={},this._props={...this._defaults},this._eventHandlers={"change input":function(_,{commit:U}){let B=_.target;U({props:{checked:B.checked}})}},this._eventCleanup=[],this._renderFn=function({props:_,html:U}){return U`
36
80
  <input
37
81
  part="checkbox-root"
@@ -2,7 +2,7 @@
2
2
  import { render, html } from 'uhtml';
3
3
 
4
4
  const sheet = new CSSStyleSheet();
5
- sheet.replaceSync("\n\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kb-space-sm);\n font-family: var(--kb-font-family-sans);\n font-size: var(--kb-font-size-md);\n color: var(--kb-color-fg-default);\n }\n input {\n width: 1.125rem;\n height: 1.125rem;\n min-width: 1.125rem;\n min-height: 1.125rem;\n margin: 0;\n accent-color: var(--kb-color-accent-default);\n cursor: pointer;\n }\n input:focus-visible {\n outline: none;\n box-shadow: var(--kb-focus-ring);\n border-radius: var(--kb-radius-sm);\n }\n input:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n input[aria-invalid=\"true\"] {\n outline: 1px solid var(--kb-color-danger-default);\n }\n .label {\n line-height: var(--kb-line-height-normal);\n }\n ");
5
+ sheet.replaceSync("\n\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kb-space-sm);\n font-family: var(--kb-font-family-sans);\n font-size: var(--kb-font-size-md);\n color: var(--kb-color-fg-default);\n }\n input {\n appearance: none;\n -webkit-appearance: none;\n box-sizing: border-box;\n width: 1.15em;\n height: 1.15em;\n min-width: 1.15em;\n min-height: 1.15em;\n margin: 0;\n flex-shrink: 0;\n display: grid;\n place-content: center;\n border: 2px solid var(--kb-color-border-default);\n border-radius: var(--kb-radius-sm);\n background: var(--kb-color-bg-canvas);\n color: var(--kb-color-fg-on-accent);\n cursor: pointer;\n transition:\n background-color 0.12s ease,\n border-color 0.12s ease,\n box-shadow 0.12s ease;\n }\n input::before {\n content: '';\n width: 0.65em;\n height: 0.65em;\n transform: scale(0);\n transition: transform 0.12s ease;\n box-shadow: inset 1em 1em currentColor;\n clip-path: polygon(\n 14% 44%,\n 0 65%,\n 50% 100%,\n 100% 16%,\n 80% 0%,\n 43% 62%\n );\n }\n input:hover:not(:disabled) {\n border-color: var(--kb-color-border-focus);\n }\n input:checked {\n background: var(--kb-color-accent-default);\n border-color: var(--kb-color-accent-default);\n }\n input:checked::before {\n transform: scale(1);\n }\n input:focus-visible {\n outline: none;\n box-shadow: var(--kb-focus-ring);\n }\n input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n input[aria-invalid='true'] {\n border-color: var(--kb-color-danger-default);\n }\n .label {\n line-height: var(--kb-line-height-normal);\n }\n @media (prefers-reduced-motion: reduce) {\n input,\n input::before {\n transition: none;\n }\n }\n ");
6
6
 
7
7
  export class KitbashCheckbox extends HTMLElement {
8
8
  static formAssociated = true;
@@ -38,6 +38,12 @@ var p=(_,U,B,Y,z)=>{let X=B.length,O=U.length,J=X,Q=0,Z=0,$=null;while(Q<O||Z<J)
38
38
  outline: none;
39
39
  font-family: inherit;
40
40
  line-height: var(--kb-line-height-normal);
41
+ transition:
42
+ border-color 0.12s ease,
43
+ box-shadow 0.12s ease;
44
+ }
45
+ input:hover:not(:disabled):not(:read-only) {
46
+ border-color: var(--kitbash-input-border-focus);
41
47
  }
42
48
  :host([size="sm"]) input {
43
49
  min-height: 2rem;
@@ -2,7 +2,7 @@
2
2
  import { render, html } from 'uhtml';
3
3
 
4
4
  const sheet = new CSSStyleSheet();
5
- sheet.replaceSync("\n\n :host {\n display: inline-block;\n width: 100%;\n --kitbash-input-border: var(--kb-color-border-default);\n --kitbash-input-border-focus: var(--kb-color-border-focus);\n --kitbash-input-border-invalid: var(--kb-color-danger-default);\n --kitbash-input-padding-y: var(--kb-space-sm);\n --kitbash-input-padding-x: var(--kb-space-md);\n --kitbash-input-radius: var(--kb-radius-sm);\n --kitbash-input-bg: var(--kb-color-bg-canvas);\n --kitbash-input-fg: var(--kb-color-fg-default);\n --kitbash-input-focus-ring: var(--kb-focus-ring);\n --kitbash-input-font: var(--kb-font-size-md);\n font-family: var(--kb-font-family-sans);\n }\n :host([size=\"sm\"]) {\n --kitbash-input-padding-y: var(--kb-space-xs);\n --kitbash-input-padding-x: var(--kb-space-sm);\n --kitbash-input-font: var(--kb-font-size-sm);\n }\n :host([size=\"lg\"]) {\n --kitbash-input-padding-y: var(--kb-space-md);\n --kitbash-input-padding-x: var(--kb-space-md);\n --kitbash-input-font: var(--kb-font-size-lg);\n }\n input {\n box-sizing: border-box;\n width: 100%;\n min-height: 2.25rem;\n padding: var(--kitbash-input-padding-y) var(--kitbash-input-padding-x);\n border: 1px solid var(--kitbash-input-border);\n border-radius: var(--kitbash-input-radius);\n background-color: var(--kitbash-input-bg);\n color: var(--kitbash-input-fg);\n font-size: var(--kitbash-input-font);\n outline: none;\n font-family: inherit;\n line-height: var(--kb-line-height-normal);\n }\n :host([size=\"sm\"]) input {\n min-height: 2rem;\n }\n :host([size=\"lg\"]) input {\n min-height: 2.75rem;\n }\n input::placeholder {\n color: var(--kb-color-fg-subtle);\n }\n input:focus {\n border-color: var(--kitbash-input-border-focus);\n box-shadow: var(--kitbash-input-focus-ring);\n }\n input:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n }\n input[aria-invalid=\"true\"] {\n border-color: var(--kitbash-input-border-invalid);\n }\n ");
5
+ sheet.replaceSync("\n\n :host {\n display: inline-block;\n width: 100%;\n --kitbash-input-border: var(--kb-color-border-default);\n --kitbash-input-border-focus: var(--kb-color-border-focus);\n --kitbash-input-border-invalid: var(--kb-color-danger-default);\n --kitbash-input-padding-y: var(--kb-space-sm);\n --kitbash-input-padding-x: var(--kb-space-md);\n --kitbash-input-radius: var(--kb-radius-sm);\n --kitbash-input-bg: var(--kb-color-bg-canvas);\n --kitbash-input-fg: var(--kb-color-fg-default);\n --kitbash-input-focus-ring: var(--kb-focus-ring);\n --kitbash-input-font: var(--kb-font-size-md);\n font-family: var(--kb-font-family-sans);\n }\n :host([size=\"sm\"]) {\n --kitbash-input-padding-y: var(--kb-space-xs);\n --kitbash-input-padding-x: var(--kb-space-sm);\n --kitbash-input-font: var(--kb-font-size-sm);\n }\n :host([size=\"lg\"]) {\n --kitbash-input-padding-y: var(--kb-space-md);\n --kitbash-input-padding-x: var(--kb-space-md);\n --kitbash-input-font: var(--kb-font-size-lg);\n }\n input {\n box-sizing: border-box;\n width: 100%;\n min-height: 2.25rem;\n padding: var(--kitbash-input-padding-y) var(--kitbash-input-padding-x);\n border: 1px solid var(--kitbash-input-border);\n border-radius: var(--kitbash-input-radius);\n background-color: var(--kitbash-input-bg);\n color: var(--kitbash-input-fg);\n font-size: var(--kitbash-input-font);\n outline: none;\n font-family: inherit;\n line-height: var(--kb-line-height-normal);\n transition:\n border-color 0.12s ease,\n box-shadow 0.12s ease;\n }\n input:hover:not(:disabled):not(:read-only) {\n border-color: var(--kitbash-input-border-focus);\n }\n :host([size=\"sm\"]) input {\n min-height: 2rem;\n }\n :host([size=\"lg\"]) input {\n min-height: 2.75rem;\n }\n input::placeholder {\n color: var(--kb-color-fg-subtle);\n }\n input:focus {\n border-color: var(--kitbash-input-border-focus);\n box-shadow: var(--kitbash-input-focus-ring);\n }\n input:disabled {\n opacity: 0.55;\n cursor: not-allowed;\n }\n input[aria-invalid=\"true\"] {\n border-color: var(--kitbash-input-border-invalid);\n }\n ");
6
6
 
7
7
  export class KitbashInput extends HTMLElement {
8
8
  static formAssociated = true;
@@ -0,0 +1,2 @@
1
+ /** Side-effect import — registers the custom element. */
2
+ export {};
@@ -0,0 +1,72 @@
1
+ var u=(_,U,B,Y,z)=>{let O=B.length,J=U.length,I=O,Q=0,$=0,X=null;while(Q<J||$<I)if(J===Q){let W=I<O?$?Y(B[$-1],-0).nextSibling:Y(B[I],0):z;while($<I)_.insertBefore(Y(B[$++],1),W)}else if(I===$)while(Q<J){if(!X||!X.has(U[Q]))_.removeChild(Y(U[Q],-1));Q++}else if(U[Q]===B[$])Q++,$++;else if(U[J-1]===B[I-1])J--,I--;else if(U[Q]===B[I-1]&&B[$]===U[J-1]){let W=Y(U[--J],-0).nextSibling;_.insertBefore(Y(B[$++],1),Y(U[Q++],-0).nextSibling),_.insertBefore(Y(B[--I],1),W),U[J]=B[I]}else{if(!X){X=new Map;let W=$;while(W<I)X.set(B[W],W++)}if(X.has(U[Q])){let W=X.get(U[Q]);if($<W&&W<I){let Z=Q,K=1;while(++Z<J&&Z<I&&X.get(U[Z])===W+K)K++;if(K>W-$){let M=Y(U[Q],0);while($<W)_.insertBefore(Y(B[$++],1),M)}else _.replaceChild(Y(B[$++],1),Y(U[Q++],-1))}else Q++}else _.removeChild(Y(U[Q++],-1))}return B};var{isArray:E}=Array,{getPrototypeOf:D1,getOwnPropertyDescriptor:M1}=Object;var i="http://www.w3.org/2000/svg",q=[],N=()=>document.createRange(),R=(_,U,B)=>{return _.set(U,B),B},m=(_,U)=>{let B;do B=M1(_,U);while(!B&&(_=D1(_)));return B},o=(_,U)=>U.reduceRight(R1,_),R1=(_,U)=>_.childNodes[U];var s=1;var l=8;var r=11;var{setPrototypeOf:T1}=Object,n=(_)=>{function U(B){return T1(B,new.target.prototype)}return U.prototype=_.prototype,U};var T,V=(_,U,B)=>{if(!T)T=N();if(B)T.setStartAfter(_);else T.setStartBefore(_);return T.setEndAfter(U),T.deleteContents(),_};var w=({firstChild:_,lastChild:U},B)=>V(_,U,B),t=!1,j=(_,U)=>t&&_.nodeType===r?1/U<0?U?w(_,!0):_.lastChild:U?_.valueOf():_.firstChild:_,a=(_)=>document.createComment(_);class x extends n(DocumentFragment){#U=a("<>");#B=a("</>");#_=q;constructor(_){super(_);this.replaceChildren(...[this.#U,..._.childNodes,this.#B]),t=!0}get firstChild(){return this.#U}get lastChild(){return this.#B}get parentNode(){return this.#U.parentNode}remove(){w(this,!1)}replaceWith(_){w(this,!0).replaceWith(_)}valueOf(){let{parentNode:_}=this;if(_===this){if(this.#_===q)this.#_=[...this.childNodes]}else{if(_){let{firstChild:U,lastChild:B}=this;this.#_=[U];while(U!==B)this.#_.push(U=U.nextSibling)}this.replaceChildren(...this.#_)}return this}}var e=(_,U,B)=>_.setAttribute(U,B),F=(_,U)=>_.removeAttribute(U),H1=(_,U)=>{for(let B in U){let Y=U[B],z=B==="role"?B:`aria-${B}`;if(Y==null)F(_,z);else e(_,z,Y)}return U},C,F1=(_,U,B)=>{if(B=B.slice(1),!C)C=new WeakMap;let Y=C.get(_)||R(C,_,{}),z=Y[B];if(z&&z[0])_.removeEventListener(B,...z);if(z=E(U)?U:[U,!1],Y[B]=z,z[0])_.addEventListener(B,...z);return U};var G=(_,U)=>{let{t:B,n:Y}=_,z=!1;switch(typeof U){case"object":if(U!==null){(Y||B).replaceWith(_.n=U.valueOf());break}case"undefined":z=!0;default:if(B.data=z?"":U,Y)_.n=null,Y.replaceWith(B);break}return U},P1=(_,U)=>f(_,U,U==null?"class":"className"),A1=(_,U)=>{let{dataset:B}=_;for(let Y in U)if(U[Y]==null)delete B[Y];else B[Y]=U[Y];return U},k=(_,U,B)=>_[B]=U,E1=(_,U,B)=>k(_,U,B.slice(1)),f=(_,U,B)=>U==null?(F(_,B),U):k(_,U,B),_1=(_,U)=>(typeof U==="function"?U(_):U.current=_,U),y=(_,U,B)=>(U==null?F(_,B):e(_,B,U),U),N1=(_,U)=>U==null?f(_,U,"style"):k(_.style,U,"cssText"),V1=(_,U,B)=>(_.toggleAttribute(B.slice(1),U),U),D=(_,U,B)=>{let{length:Y}=U;if(_.data=`[${Y}]`,Y)return u(_.parentNode,B,U,j,_);switch(B.length){case 1:B[0].remove();case 0:break;default:V(j(B[0],0),j(B.at(-1),-0),!1);break}return q},U1=new Map([["aria",H1],["class",P1],["data",A1],["ref",_1],["style",N1]]),B1=(_,U,B)=>{switch(U[0]){case".":return E1;case"?":return V1;case"@":return F1;default:return B||"ownerSVGElement"in _?U==="ref"?_1:y:U1.get(U)||(U in _?U.startsWith("on")?k:m(_,U)?.set?f:y:y)}},Y1=(_,U)=>(_.textContent=U==null?"":U,U);var H=(_,U,B)=>({a:_,b:U,c:B}),z1=(_,U)=>({b:_,c:U}),I1=(_,U,B,Y)=>({v:q,u:_,t:U,n:B,c:Y}),L=()=>H(null,null,q);var b=(_)=>(U,B)=>{let{a:Y,b:z,c:O}=_(U,B),J=document.importNode(Y,!0),I=q;if(z!==q){I=[];for(let Q,$,X=0;X<z.length;X++){let{a:W,b:Z,c:K}=z[X],M=W===$?Q:Q=o(J,$=W);I[X]=I1(Z,M,K,Z===D?[]:Z===G?L():null)}}return z1(O?J.firstChild:new x(J),I)};var J1=/^(?:plaintext|script|style|textarea|title|xmp)$/i,O1=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;var j1=/<([a-zA-Z0-9]+[a-zA-Z0-9:._-]*)([^>]*?)(\/?)>/g,C1=/([^\s\\>"'=]+)\s*=\s*(['"]?)\x01/g,k1=/[\x01\x02]/g,Q1=(_,U,B)=>{let Y=0;return _.join("\x01").trim().replace(j1,(z,O,J,I)=>`<${O}${J.replace(C1,"\x02=$2$1").trimEnd()}${I?B||O1.test(O)?" /":`></${O}`:""}>`).replace(k1,(z)=>z==="\x01"?`<!--${U+Y++}-->`:U+Y++)};var S=document.createElement("template"),g,h,W1=(_,U)=>{if(U){if(!g)g=document.createElementNS(i,"svg"),h=N(),h.selectNodeContents(g);return h.createContextualFragment(_)}S.innerHTML=_;let{content:B}=S;return S=S.cloneNode(!1),B};var c=(_)=>{let U=[],B;while(B=_.parentNode)U.push(U.indexOf.call(B.childNodes,_)),_=B;return U},X1=()=>document.createTextNode(""),S1=(_,U,B)=>{let Y=W1(Q1(_,P,B),B),{length:z}=_,O=q;if(z>1){let Q=[],$=document.createTreeWalker(Y,129),X=0,W=`${P}${X++}`;O=[];while(X<z){let Z=$.nextNode();if(Z.nodeType===l){if(Z.data===W){let K=E(U[X-1])?D:G;if(K===G)Q.push(Z);O.push(H(c(Z),K,null)),W=`${P}${X++}`}}else{let K;while(Z.hasAttribute(W)){if(!K)K=c(Z);let M=Z.getAttribute(W);O.push(H(K,B1(Z,M,B),M)),F(Z,W),W=`${P}${X++}`}if(!B&&J1.test(Z.localName)&&Z.textContent.trim()===`<!--${W}-->`)O.push(H(K||c(Z),Y1,null)),W=`${P}${X++}`}}for(X=0;X<Q.length;X++)Q[X].replaceWith(X1())}let{childNodes:J}=Y,{length:I}=J;if(I<1)I=1,Y.appendChild(X1());else if(I===1&&z!==1&&J[0].nodeType!==s)I=0;return R($1,_,H(Y,O,I===1))},$1=new WeakMap,P="isµ",v=(_)=>(U,B)=>$1.get(U)||S1(U,B,_);var w1=b(v(!1)),x1=b(v(!0)),p=(_,{s:U,t:B,v:Y})=>{if(_.a!==B){let{b:z,c:O}=(U?x1:w1)(B,Y);_.a=B,_.b=z,_.c=O}for(let{c:z}=_,O=0;O<z.length;O++){let J=Y[O],I=z[O];switch(I.u){case D:I.v=D(I.t,y1(I.c,J),I.v);break;case G:let Q=J instanceof A?p(I.c||(I.c=L()),J):(I.c=null,J);if(Q!==I.v)I.v=G(I,Q);break;default:if(J!==I.v)I.v=I.u(I.t,J,I.n,I.v);break}}return _.b},y1=(_,U)=>{let B=0,{length:Y}=U;if(Y<_.length)_.splice(Y);for(;B<Y;B++){let z=U[B];if(z instanceof A)U[B]=p(_[B]||(_[B]=L()),z);else _[B]=null}return U};class A{constructor(_,U,B){this.s=_,this.t=U,this.v=B}toDOM(_=L()){return p(_,this)}}var Z1=new WeakMap,d=(_,U)=>{let B=Z1.get(_)||R(Z1,_,L()),{b:Y}=B;if(Y!==(typeof U==="function"?U():U).toDOM(B))_.replaceChildren(B.b.valueOf());return _};/*! (c) Andrea Giammarchi - MIT */var K1=(_)=>(U,...B)=>new A(_,U,B),q1=K1(!1),C_=K1(!0);var G1=new CSSStyleSheet;G1.replaceSync(`
2
+
3
+ :host {
4
+ display: inline-block;
5
+ font-family: var(--kb-font-family-sans);
6
+ }
7
+ button {
8
+ box-sizing: border-box;
9
+ margin: 0;
10
+ min-height: 2.25rem;
11
+ padding: 0.45rem 0.8rem;
12
+ border: 1px solid var(--kb-color-border-default);
13
+ border-radius: var(--kb-radius-sm);
14
+ background: var(--kb-color-bg-subtle);
15
+ color: var(--kb-color-accent-default);
16
+ font: inherit;
17
+ font-size: var(--kb-font-size-sm);
18
+ font-weight: var(--kb-font-weight-medium);
19
+ line-height: 1;
20
+ letter-spacing: 0.08em;
21
+ text-transform: lowercase;
22
+ cursor: pointer;
23
+ transition:
24
+ color 0.2s ease,
25
+ background-color 0.2s ease,
26
+ border-color 0.2s ease;
27
+ }
28
+ button:hover {
29
+ color: var(--kb-color-fg-default);
30
+ background: var(--kb-color-bg-surface);
31
+ border-color: var(--kb-color-border-focus);
32
+ }
33
+ button:focus-visible {
34
+ outline: 2px solid var(--kb-color-border-focus);
35
+ outline-offset: 2px;
36
+ color: var(--kb-color-fg-default);
37
+ background: var(--kb-color-bg-surface);
38
+ }
39
+ :host([data-group-pos="start"]) button {
40
+ border-top-right-radius: 0;
41
+ border-bottom-right-radius: 0;
42
+ border-right-width: 0;
43
+ }
44
+ :host([data-group-pos="end"]) button {
45
+ border-top-left-radius: 0;
46
+ border-bottom-left-radius: 0;
47
+ }
48
+ :host([data-group-pos="mid"]) button {
49
+ border-radius: 0;
50
+ border-right-width: 0;
51
+ }
52
+ :host([data-group-pos]:hover),
53
+ :host([data-group-pos]:focus-within) {
54
+ position: relative;
55
+ z-index: 1;
56
+ }
57
+ @media (prefers-reduced-motion: reduce) {
58
+ button {
59
+ transition: none;
60
+ }
61
+ }
62
+ `);class L1 extends HTMLElement{static get observedAttributes(){return["value","storageKey"]}static get propTypes(){return{value:"String",storageKey:"String"}}get value(){return this._props.value}set value(_){this._assignProp("value",_),this.update()}get storageKey(){return this._props.storageKey}set storageKey(_){this._assignProp("storageKey",_),this.update()}constructor(){super();this.attachShadow({mode:"open",delegatesFocus:!0}),this.shadowRoot.adoptedStyleSheets=[G1],this._defaults={value:"",storageKey:"ui-mode"},this._state={},this._props={...this._defaults},this._eventHandlers={"click button":function(_,{props:U,commit:B}){let Y=U.value==="default"||U.value==="terminal"?U.value:"";if(!Y&&typeof document<"u"){let J=document.documentElement;if(J.dataset.kbPreset==="terminal")Y="terminal";else if(J.dataset.uiMode==="terminal")Y="terminal";else Y="default"}if(!Y)Y="default";let z=Y==="terminal"?"default":"terminal";if(typeof document<"u"){let J=document.documentElement;if(z==="terminal")J.dataset.kbPreset="terminal",J.dataset.uiMode="terminal";else delete J.dataset.kbPreset,J.dataset.uiMode="regular"}let O=typeof U.storageKey==="string"?U.storageKey:"ui-mode";if(O&&typeof localStorage<"u")try{let J=O==="ui-mode"?z==="terminal"?"terminal":"regular":z;localStorage.setItem(O,J)}catch{}B({props:{value:z}})}},this._eventCleanup=[],this._renderFn=function({props:_,html:U}){let B=_.value==="default"||_.value==="terminal"?_.value:"";if(!B&&typeof document<"u"){let z=document.documentElement;if(z.dataset.kbPreset==="terminal")B="terminal";else if(z.dataset.uiMode==="terminal")B="terminal";else B="default"}if(!B)B="default";let Y=B==="default";return U`
63
+ <button
64
+ part="toggle-root"
65
+ type="button"
66
+ aria-pressed=${Y?"true":"false"}
67
+ aria-label=${Y?"Switch to terminal UI preset":"Switch to regular UI preset"}
68
+ title="Toggle UI mode"
69
+ >
70
+ ${Y?"ui=regular":"ui=terminal"}
71
+ </button>
72
+ `},this._reflecting=!1}connectedCallback(){this.update()}disconnectedCallback(){this.cleanupEvents()}attributeChangedCallback(_,U,B){if(this._reflecting)return;if(U===B)return;let Y=this.constructor.propTypes[_],z=B;if(B===null||B===void 0)z=this._defaults[_];else if(Y==="Number"&&B!=="")z=Number(B);else if(Y==="Boolean")z=B!==null&&B!=="false";this._props[_]=z,this.update()}_assignProp(_,U){let B=this.constructor.propTypes[_],Y=U;if(B==="Boolean")Y=U===!0||U==="";else if(B==="Number"&&U!==null&&U!==void 0&&U!=="")Y=Number(U);this._props[_]=Y;let z=Y===null||Y===void 0||typeof Y==="string"||typeof Y==="number"||typeof Y==="boolean";this._reflecting=!0;try{if(B==="Boolean")if(Y)this.setAttribute(_,"");else this.removeAttribute(_);else if(!z)this.removeAttribute(_);else if(Y===null||Y===void 0)this.removeAttribute(_);else this.setAttribute(_,String(Y))}finally{this._reflecting=!1}}_emitChange(){this.dispatchEvent(new CustomEvent("kitbash-change",{detail:{state:{...this._state},props:{...this._props}},bubbles:!0,composed:!0}))}commit(_){let U=_||{};if(U.props){let B=this.constructor.propTypes||{};for(let Y of Object.keys(U.props)){if(!Object.prototype.hasOwnProperty.call(B,Y))continue;this._assignProp(Y,U.props[Y])}}if(U.state)this._state={...this._state,...U.state};this.update(),this._emitChange()}setState(_){this.commit({state:_})}setProps(_){this.commit({props:_})}_handlerCtx(){return{props:{...this._props},state:{...this._state},setState:this.setState.bind(this),setProps:this.setProps.bind(this),commit:this.commit.bind(this)}}cleanupEvents(){this._eventCleanup.forEach((_)=>_()),this._eventCleanup=[]}update(){d(this.shadowRoot,this._renderFn({...this._handlerCtx(),html:q1})),this.cleanupEvents(),this.bindEvents()}bindEvents(){Object.keys(this._eventHandlers).forEach((_)=>{let U=_.split(" "),B=U[0],Y=U.slice(1).join(" ");(Y?this.shadowRoot.querySelectorAll(Y):[this]).forEach((O)=>{let J=(I)=>{this._eventHandlers[_](I,this._handlerCtx())};O.addEventListener(B,J),this._eventCleanup.push(()=>O.removeEventListener(B,J))})})}}if(!customElements.get("kitbash-preset-toggle"))customElements.define("kitbash-preset-toggle",L1);export{L1 as KitbashPresetToggle};