@ktbsh/ui 0.1.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.
- package/README.md +165 -0
- package/dist/custom-elements.json +1427 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +12 -0
- package/dist/react/alert.d.ts +20 -0
- package/dist/react/alert.js +30 -0
- package/dist/react/badge.d.ts +17 -0
- package/dist/react/badge.js +30 -0
- package/dist/react/box.d.ts +22 -0
- package/dist/react/box.js +30 -0
- package/dist/react/breadcrumb.d.ts +17 -0
- package/dist/react/breadcrumb.js +30 -0
- package/dist/react/button.d.ts +20 -0
- package/dist/react/button.js +30 -0
- package/dist/react/checkbox.d.ts +22 -0
- package/dist/react/checkbox.js +30 -0
- package/dist/react/container.d.ts +18 -0
- package/dist/react/container.js +30 -0
- package/dist/react/field.d.ts +20 -0
- package/dist/react/field.js +30 -0
- package/dist/react/heading.d.ts +19 -0
- package/dist/react/heading.js +30 -0
- package/dist/react/input.d.ts +25 -0
- package/dist/react/input.js +30 -0
- package/dist/react/label.d.ts +18 -0
- package/dist/react/label.js +30 -0
- package/dist/react/link.d.ts +21 -0
- package/dist/react/link.js +30 -0
- package/dist/react/modal.d.ts +18 -0
- package/dist/react/modal.js +30 -0
- package/dist/react/nav.d.ts +17 -0
- package/dist/react/nav.js +30 -0
- package/dist/react/pagination.d.ts +19 -0
- package/dist/react/pagination.js +30 -0
- package/dist/react/progress.d.ts +19 -0
- package/dist/react/progress.js +30 -0
- package/dist/react/radio.d.ts +22 -0
- package/dist/react/radio.js +30 -0
- package/dist/react/select.d.ts +22 -0
- package/dist/react/select.js +30 -0
- package/dist/react/skeleton.d.ts +19 -0
- package/dist/react/skeleton.js +30 -0
- package/dist/react/spinner.d.ts +18 -0
- package/dist/react/spinner.js +30 -0
- package/dist/react/stack.d.ts +21 -0
- package/dist/react/stack.js +30 -0
- package/dist/react/switch.d.ts +21 -0
- package/dist/react/switch.js +30 -0
- package/dist/react/tab-panel.d.ts +18 -0
- package/dist/react/tab-panel.js +30 -0
- package/dist/react/tab.d.ts +19 -0
- package/dist/react/tab.js +30 -0
- package/dist/react/tabs.d.ts +17 -0
- package/dist/react/tabs.js +30 -0
- package/dist/react/text.d.ts +19 -0
- package/dist/react/text.js +30 -0
- package/dist/react/textarea.d.ts +24 -0
- package/dist/react/textarea.js +30 -0
- package/dist/react/toast.d.ts +19 -0
- package/dist/react/toast.js +30 -0
- package/dist/themes/dark.css +52 -0
- package/dist/themes/light.css +53 -0
- package/dist/tokens/index.d.ts +7 -0
- package/dist/tokens/index.js +7 -0
- package/dist/tokens/semantic.d.ts +209 -0
- package/dist/tokens/semantic.js +102 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.js +2 -0
- package/dist/vanilla/alert.d.ts +2 -0
- package/dist/vanilla/alert.js +134 -0
- package/dist/vanilla/alert.src.js +257 -0
- package/dist/vanilla/badge.d.ts +2 -0
- package/dist/vanilla/badge.js +89 -0
- package/dist/vanilla/badge.src.js +212 -0
- package/dist/vanilla/box.d.ts +2 -0
- package/dist/vanilla/box.js +100 -0
- package/dist/vanilla/box.src.js +270 -0
- package/dist/vanilla/breadcrumb.d.ts +2 -0
- package/dist/vanilla/breadcrumb.js +93 -0
- package/dist/vanilla/breadcrumb.src.js +255 -0
- package/dist/vanilla/button.d.ts +2 -0
- package/dist/vanilla/button.js +135 -0
- package/dist/vanilla/button.src.js +260 -0
- package/dist/vanilla/checkbox.d.ts +2 -0
- package/dist/vanilla/checkbox.js +96 -0
- package/dist/vanilla/checkbox.src.js +296 -0
- package/dist/vanilla/container.d.ts +2 -0
- package/dist/vanilla/container.js +79 -0
- package/dist/vanilla/container.src.js +222 -0
- package/dist/vanilla/field.d.ts +2 -0
- package/dist/vanilla/field.js +113 -0
- package/dist/vanilla/field.src.js +278 -0
- package/dist/vanilla/heading.d.ts +2 -0
- package/dist/vanilla/heading.js +75 -0
- package/dist/vanilla/heading.src.js +241 -0
- package/dist/vanilla/input.d.ts +2 -0
- package/dist/vanilla/input.js +121 -0
- package/dist/vanilla/input.src.js +326 -0
- package/dist/vanilla/label.d.ts +2 -0
- package/dist/vanilla/label.js +75 -0
- package/dist/vanilla/label.src.js +232 -0
- package/dist/vanilla/link.d.ts +2 -0
- package/dist/vanilla/link.js +96 -0
- package/dist/vanilla/link.src.js +272 -0
- package/dist/vanilla/modal.d.ts +2 -0
- package/dist/vanilla/modal.js +125 -0
- package/dist/vanilla/modal.src.js +251 -0
- package/dist/vanilla/nav.d.ts +2 -0
- package/dist/vanilla/nav.js +94 -0
- package/dist/vanilla/nav.src.js +214 -0
- package/dist/vanilla/pagination.d.ts +2 -0
- package/dist/vanilla/pagination.js +114 -0
- package/dist/vanilla/pagination.src.js +262 -0
- package/dist/vanilla/progress.d.ts +2 -0
- package/dist/vanilla/progress.js +108 -0
- package/dist/vanilla/progress.src.js +244 -0
- package/dist/vanilla/radio.d.ts +2 -0
- package/dist/vanilla/radio.js +104 -0
- package/dist/vanilla/radio.src.js +326 -0
- package/dist/vanilla/select.d.ts +2 -0
- package/dist/vanilla/select.js +104 -0
- package/dist/vanilla/select.src.js +332 -0
- package/dist/vanilla/skeleton.d.ts +2 -0
- package/dist/vanilla/skeleton.js +99 -0
- package/dist/vanilla/skeleton.src.js +240 -0
- package/dist/vanilla/spinner.d.ts +2 -0
- package/dist/vanilla/spinner.js +108 -0
- package/dist/vanilla/spinner.src.js +222 -0
- package/dist/vanilla/stack.d.ts +2 -0
- package/dist/vanilla/stack.js +83 -0
- package/dist/vanilla/stack.src.js +259 -0
- package/dist/vanilla/switch.d.ts +2 -0
- package/dist/vanilla/switch.js +166 -0
- package/dist/vanilla/switch.src.js +299 -0
- package/dist/vanilla/tab-panel.d.ts +2 -0
- package/dist/vanilla/tab-panel.js +80 -0
- package/dist/vanilla/tab-panel.src.js +227 -0
- package/dist/vanilla/tab.d.ts +2 -0
- package/dist/vanilla/tab.js +99 -0
- package/dist/vanilla/tab.src.js +253 -0
- package/dist/vanilla/tabs.d.ts +2 -0
- package/dist/vanilla/tabs.js +66 -0
- package/dist/vanilla/tabs.src.js +237 -0
- package/dist/vanilla/text.d.ts +2 -0
- package/dist/vanilla/text.js +74 -0
- package/dist/vanilla/text.src.js +232 -0
- package/dist/vanilla/textarea.d.ts +2 -0
- package/dist/vanilla/textarea.js +97 -0
- package/dist/vanilla/textarea.src.js +316 -0
- package/dist/vanilla/toast.d.ts +2 -0
- package/dist/vanilla/toast.js +120 -0
- package/dist/vanilla/toast.src.js +245 -0
- package/package.json +111 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import '../vanilla/tabs.js';
|
|
4
|
+
|
|
5
|
+
export const KitbashTabs = 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-tabs', { ref: setRefs, ...props }, children);
|
|
30
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
export interface KitbashTextProps extends React.HTMLAttributes<HTMLElement> {
|
|
5
|
+
'size'?: string;
|
|
6
|
+
'tone'?: string;
|
|
7
|
+
'weight'?: string;
|
|
8
|
+
onKitbashChange?: (event: CustomEvent<{ props: Record<string, unknown>; state: Record<string, unknown> }>) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare global {
|
|
12
|
+
namespace JSX {
|
|
13
|
+
interface IntrinsicElements {
|
|
14
|
+
'kitbash-text': KitbashTextProps & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export declare const KitbashText: React.ForwardRefExoticComponent<KitbashTextProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import '../vanilla/text.js';
|
|
4
|
+
|
|
5
|
+
export const KitbashText = 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-text', { ref: setRefs, ...props }, children);
|
|
30
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
export interface KitbashTextareaProps extends React.HTMLAttributes<HTMLElement> {
|
|
5
|
+
'name'?: string;
|
|
6
|
+
'value'?: string;
|
|
7
|
+
'placeholder'?: string;
|
|
8
|
+
'rows'?: number;
|
|
9
|
+
'required'?: boolean;
|
|
10
|
+
'invalid'?: boolean;
|
|
11
|
+
'disabled'?: boolean;
|
|
12
|
+
'readonly'?: boolean;
|
|
13
|
+
onKitbashChange?: (event: CustomEvent<{ props: Record<string, unknown>; state: Record<string, unknown> }>) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare global {
|
|
17
|
+
namespace JSX {
|
|
18
|
+
interface IntrinsicElements {
|
|
19
|
+
'kitbash-textarea': KitbashTextareaProps & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export declare const KitbashTextarea: React.ForwardRefExoticComponent<KitbashTextareaProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import '../vanilla/textarea.js';
|
|
4
|
+
|
|
5
|
+
export const KitbashTextarea = 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-textarea', { ref: setRefs, ...props }, children);
|
|
30
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
export interface KitbashToastProps extends React.HTMLAttributes<HTMLElement> {
|
|
5
|
+
'open'?: boolean;
|
|
6
|
+
'tone'?: string;
|
|
7
|
+
'title'?: string;
|
|
8
|
+
onKitbashChange?: (event: CustomEvent<{ props: Record<string, unknown>; state: Record<string, unknown> }>) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare global {
|
|
12
|
+
namespace JSX {
|
|
13
|
+
interface IntrinsicElements {
|
|
14
|
+
'kitbash-toast': KitbashToastProps & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export declare const KitbashToast: React.ForwardRefExoticComponent<KitbashToastProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import '../vanilla/toast.js';
|
|
4
|
+
|
|
5
|
+
export const KitbashToast = 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-toast', { ref: setRefs, ...props }, children);
|
|
30
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED FILE — do not edit by hand.
|
|
3
|
+
* Source: src/tokens/semantic.ts
|
|
4
|
+
* Regenerate: bun run tokens:build
|
|
5
|
+
*/
|
|
6
|
+
:root[data-theme="dark"] {
|
|
7
|
+
--kb-color-bg-canvas: #0d1117;
|
|
8
|
+
--kb-color-bg-surface: #161b22;
|
|
9
|
+
--kb-color-bg-subtle: #21262d;
|
|
10
|
+
--kb-color-bg-inverse: #e6edf3;
|
|
11
|
+
--kb-color-fg-default: #e6edf3;
|
|
12
|
+
--kb-color-fg-muted: #8b949e;
|
|
13
|
+
--kb-color-fg-subtle: #6e7681;
|
|
14
|
+
--kb-color-fg-on-accent: #ffffff;
|
|
15
|
+
--kb-color-fg-on-inverse: #0d1117;
|
|
16
|
+
--kb-color-border-default: #30363d;
|
|
17
|
+
--kb-color-border-muted: #21262d;
|
|
18
|
+
--kb-color-border-focus: #2f81f7;
|
|
19
|
+
--kb-color-accent-default: #2f81f7;
|
|
20
|
+
--kb-color-accent-hover: #58a6ff;
|
|
21
|
+
--kb-color-accent-subtle: #121d2f;
|
|
22
|
+
--kb-color-danger-default: #f85149;
|
|
23
|
+
--kb-color-danger-subtle: #2d1214;
|
|
24
|
+
--kb-color-success-default: #3fb950;
|
|
25
|
+
--kb-color-success-subtle: #12261e;
|
|
26
|
+
--kb-color-warning-default: #d29922;
|
|
27
|
+
--kb-color-warning-subtle: #2a2111;
|
|
28
|
+
--kb-space-2xs: 2px;
|
|
29
|
+
--kb-space-xs: 4px;
|
|
30
|
+
--kb-space-sm: 8px;
|
|
31
|
+
--kb-space-md: 16px;
|
|
32
|
+
--kb-space-lg: 24px;
|
|
33
|
+
--kb-space-xl: 32px;
|
|
34
|
+
--kb-space-2xl: 48px;
|
|
35
|
+
--kb-radius-sm: 4px;
|
|
36
|
+
--kb-radius-md: 8px;
|
|
37
|
+
--kb-radius-lg: 12px;
|
|
38
|
+
--kb-radius-full: 9999px;
|
|
39
|
+
--kb-font-family-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
40
|
+
--kb-font-size-sm: 0.875rem;
|
|
41
|
+
--kb-font-size-md: 1rem;
|
|
42
|
+
--kb-font-size-lg: 1.125rem;
|
|
43
|
+
--kb-font-size-xl: 1.25rem;
|
|
44
|
+
--kb-font-weight-regular: 400;
|
|
45
|
+
--kb-font-weight-medium: 500;
|
|
46
|
+
--kb-font-weight-semibold: 600;
|
|
47
|
+
--kb-line-height-tight: 1.25;
|
|
48
|
+
--kb-line-height-normal: 1.5;
|
|
49
|
+
--kb-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
50
|
+
--kb-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
|
|
51
|
+
--kb-focus-ring: 0 0 0 3px rgba(47, 129, 247, 0.45);
|
|
52
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED FILE — do not edit by hand.
|
|
3
|
+
* Source: src/tokens/semantic.ts
|
|
4
|
+
* Regenerate: bun run tokens:build
|
|
5
|
+
*/
|
|
6
|
+
:root,
|
|
7
|
+
:root[data-theme="light"] {
|
|
8
|
+
--kb-color-bg-canvas: #ffffff;
|
|
9
|
+
--kb-color-bg-surface: #f6f8fa;
|
|
10
|
+
--kb-color-bg-subtle: #eef1f4;
|
|
11
|
+
--kb-color-bg-inverse: #1f2328;
|
|
12
|
+
--kb-color-fg-default: #1f2328;
|
|
13
|
+
--kb-color-fg-muted: #656d76;
|
|
14
|
+
--kb-color-fg-subtle: #8c959f;
|
|
15
|
+
--kb-color-fg-on-accent: #ffffff;
|
|
16
|
+
--kb-color-fg-on-inverse: #ffffff;
|
|
17
|
+
--kb-color-border-default: #d0d7de;
|
|
18
|
+
--kb-color-border-muted: #e6ebf0;
|
|
19
|
+
--kb-color-border-focus: #0969da;
|
|
20
|
+
--kb-color-accent-default: #0969da;
|
|
21
|
+
--kb-color-accent-hover: #0860ca;
|
|
22
|
+
--kb-color-accent-subtle: #ddf4ff;
|
|
23
|
+
--kb-color-danger-default: #cf222e;
|
|
24
|
+
--kb-color-danger-subtle: #ffebe9;
|
|
25
|
+
--kb-color-success-default: #1a7f37;
|
|
26
|
+
--kb-color-success-subtle: #dafbe1;
|
|
27
|
+
--kb-color-warning-default: #9a6700;
|
|
28
|
+
--kb-color-warning-subtle: #fff8c5;
|
|
29
|
+
--kb-space-2xs: 2px;
|
|
30
|
+
--kb-space-xs: 4px;
|
|
31
|
+
--kb-space-sm: 8px;
|
|
32
|
+
--kb-space-md: 16px;
|
|
33
|
+
--kb-space-lg: 24px;
|
|
34
|
+
--kb-space-xl: 32px;
|
|
35
|
+
--kb-space-2xl: 48px;
|
|
36
|
+
--kb-radius-sm: 4px;
|
|
37
|
+
--kb-radius-md: 8px;
|
|
38
|
+
--kb-radius-lg: 12px;
|
|
39
|
+
--kb-radius-full: 9999px;
|
|
40
|
+
--kb-font-family-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
41
|
+
--kb-font-size-sm: 0.875rem;
|
|
42
|
+
--kb-font-size-md: 1rem;
|
|
43
|
+
--kb-font-size-lg: 1.125rem;
|
|
44
|
+
--kb-font-size-xl: 1.25rem;
|
|
45
|
+
--kb-font-weight-regular: 400;
|
|
46
|
+
--kb-font-weight-medium: 500;
|
|
47
|
+
--kb-font-weight-semibold: 600;
|
|
48
|
+
--kb-line-height-tight: 1.25;
|
|
49
|
+
--kb-line-height-normal: 1.5;
|
|
50
|
+
--kb-shadow-sm: 0 1px 2px rgba(31, 35, 40, 0.08);
|
|
51
|
+
--kb-shadow-md: 0 4px 12px rgba(31, 35, 40, 0.1);
|
|
52
|
+
--kb-focus-ring: 0 0 0 3px rgba(9, 105, 218, 0.35);
|
|
53
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public token / theme API for @ktbsh/ui consumers and docs.
|
|
3
|
+
* Import theme CSS in the app (or Storybook) so variables resolve:
|
|
4
|
+
* import '@ktbsh/ui/themes/light.css'
|
|
5
|
+
* import '@ktbsh/ui/themes/dark.css'
|
|
6
|
+
*/
|
|
7
|
+
export { applyTheme, cssVar, cssVarName, getTheme, type KitbashTheme, type SemanticTokenName, semanticTokens, type TokenValue, } from './semantic.ts';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public token / theme API for @ktbsh/ui consumers and docs.
|
|
3
|
+
* Import theme CSS in the app (or Storybook) so variables resolve:
|
|
4
|
+
* import '@ktbsh/ui/themes/light.css'
|
|
5
|
+
* import '@ktbsh/ui/themes/dark.css'
|
|
6
|
+
*/
|
|
7
|
+
export { applyTheme, cssVar, cssVarName, getTheme, semanticTokens, } from "./semantic.js";
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens — single source of truth for names and light/dark values.
|
|
3
|
+
* CSS themes + kitbash `tokens.json` are generated from this module.
|
|
4
|
+
*
|
|
5
|
+
* CSS custom property for key `color-bg-canvas` → `--kb-color-bg-canvas`
|
|
6
|
+
*/
|
|
7
|
+
export type KitbashTheme = 'light' | 'dark';
|
|
8
|
+
export type TokenValue = {
|
|
9
|
+
readonly light: string;
|
|
10
|
+
readonly dark: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Flat semantic map. Keys are stable public IDs (kebab after `--kb-`).
|
|
14
|
+
* Prefer semantic roles over raw brand names in components.
|
|
15
|
+
*/
|
|
16
|
+
export declare const semanticTokens: {
|
|
17
|
+
readonly 'color-bg-canvas': {
|
|
18
|
+
readonly light: "#ffffff";
|
|
19
|
+
readonly dark: "#0d1117";
|
|
20
|
+
};
|
|
21
|
+
readonly 'color-bg-surface': {
|
|
22
|
+
readonly light: "#f6f8fa";
|
|
23
|
+
readonly dark: "#161b22";
|
|
24
|
+
};
|
|
25
|
+
readonly 'color-bg-subtle': {
|
|
26
|
+
readonly light: "#eef1f4";
|
|
27
|
+
readonly dark: "#21262d";
|
|
28
|
+
};
|
|
29
|
+
readonly 'color-bg-inverse': {
|
|
30
|
+
readonly light: "#1f2328";
|
|
31
|
+
readonly dark: "#e6edf3";
|
|
32
|
+
};
|
|
33
|
+
readonly 'color-fg-default': {
|
|
34
|
+
readonly light: "#1f2328";
|
|
35
|
+
readonly dark: "#e6edf3";
|
|
36
|
+
};
|
|
37
|
+
readonly 'color-fg-muted': {
|
|
38
|
+
readonly light: "#656d76";
|
|
39
|
+
readonly dark: "#8b949e";
|
|
40
|
+
};
|
|
41
|
+
readonly 'color-fg-subtle': {
|
|
42
|
+
readonly light: "#8c959f";
|
|
43
|
+
readonly dark: "#6e7681";
|
|
44
|
+
};
|
|
45
|
+
readonly 'color-fg-on-accent': {
|
|
46
|
+
readonly light: "#ffffff";
|
|
47
|
+
readonly dark: "#ffffff";
|
|
48
|
+
};
|
|
49
|
+
readonly 'color-fg-on-inverse': {
|
|
50
|
+
readonly light: "#ffffff";
|
|
51
|
+
readonly dark: "#0d1117";
|
|
52
|
+
};
|
|
53
|
+
readonly 'color-border-default': {
|
|
54
|
+
readonly light: "#d0d7de";
|
|
55
|
+
readonly dark: "#30363d";
|
|
56
|
+
};
|
|
57
|
+
readonly 'color-border-muted': {
|
|
58
|
+
readonly light: "#e6ebf0";
|
|
59
|
+
readonly dark: "#21262d";
|
|
60
|
+
};
|
|
61
|
+
readonly 'color-border-focus': {
|
|
62
|
+
readonly light: "#0969da";
|
|
63
|
+
readonly dark: "#2f81f7";
|
|
64
|
+
};
|
|
65
|
+
readonly 'color-accent-default': {
|
|
66
|
+
readonly light: "#0969da";
|
|
67
|
+
readonly dark: "#2f81f7";
|
|
68
|
+
};
|
|
69
|
+
readonly 'color-accent-hover': {
|
|
70
|
+
readonly light: "#0860ca";
|
|
71
|
+
readonly dark: "#58a6ff";
|
|
72
|
+
};
|
|
73
|
+
readonly 'color-accent-subtle': {
|
|
74
|
+
readonly light: "#ddf4ff";
|
|
75
|
+
readonly dark: "#121d2f";
|
|
76
|
+
};
|
|
77
|
+
readonly 'color-danger-default': {
|
|
78
|
+
readonly light: "#cf222e";
|
|
79
|
+
readonly dark: "#f85149";
|
|
80
|
+
};
|
|
81
|
+
readonly 'color-danger-subtle': {
|
|
82
|
+
readonly light: "#ffebe9";
|
|
83
|
+
readonly dark: "#2d1214";
|
|
84
|
+
};
|
|
85
|
+
readonly 'color-success-default': {
|
|
86
|
+
readonly light: "#1a7f37";
|
|
87
|
+
readonly dark: "#3fb950";
|
|
88
|
+
};
|
|
89
|
+
readonly 'color-success-subtle': {
|
|
90
|
+
readonly light: "#dafbe1";
|
|
91
|
+
readonly dark: "#12261e";
|
|
92
|
+
};
|
|
93
|
+
readonly 'color-warning-default': {
|
|
94
|
+
readonly light: "#9a6700";
|
|
95
|
+
readonly dark: "#d29922";
|
|
96
|
+
};
|
|
97
|
+
readonly 'color-warning-subtle': {
|
|
98
|
+
readonly light: "#fff8c5";
|
|
99
|
+
readonly dark: "#2a2111";
|
|
100
|
+
};
|
|
101
|
+
readonly 'space-2xs': {
|
|
102
|
+
readonly light: "2px";
|
|
103
|
+
readonly dark: "2px";
|
|
104
|
+
};
|
|
105
|
+
readonly 'space-xs': {
|
|
106
|
+
readonly light: "4px";
|
|
107
|
+
readonly dark: "4px";
|
|
108
|
+
};
|
|
109
|
+
readonly 'space-sm': {
|
|
110
|
+
readonly light: "8px";
|
|
111
|
+
readonly dark: "8px";
|
|
112
|
+
};
|
|
113
|
+
readonly 'space-md': {
|
|
114
|
+
readonly light: "16px";
|
|
115
|
+
readonly dark: "16px";
|
|
116
|
+
};
|
|
117
|
+
readonly 'space-lg': {
|
|
118
|
+
readonly light: "24px";
|
|
119
|
+
readonly dark: "24px";
|
|
120
|
+
};
|
|
121
|
+
readonly 'space-xl': {
|
|
122
|
+
readonly light: "32px";
|
|
123
|
+
readonly dark: "32px";
|
|
124
|
+
};
|
|
125
|
+
readonly 'space-2xl': {
|
|
126
|
+
readonly light: "48px";
|
|
127
|
+
readonly dark: "48px";
|
|
128
|
+
};
|
|
129
|
+
readonly 'radius-sm': {
|
|
130
|
+
readonly light: "4px";
|
|
131
|
+
readonly dark: "4px";
|
|
132
|
+
};
|
|
133
|
+
readonly 'radius-md': {
|
|
134
|
+
readonly light: "8px";
|
|
135
|
+
readonly dark: "8px";
|
|
136
|
+
};
|
|
137
|
+
readonly 'radius-lg': {
|
|
138
|
+
readonly light: "12px";
|
|
139
|
+
readonly dark: "12px";
|
|
140
|
+
};
|
|
141
|
+
readonly 'radius-full': {
|
|
142
|
+
readonly light: "9999px";
|
|
143
|
+
readonly dark: "9999px";
|
|
144
|
+
};
|
|
145
|
+
readonly 'font-family-sans': {
|
|
146
|
+
readonly light: "ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif";
|
|
147
|
+
readonly dark: "ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif";
|
|
148
|
+
};
|
|
149
|
+
readonly 'font-size-sm': {
|
|
150
|
+
readonly light: "0.875rem";
|
|
151
|
+
readonly dark: "0.875rem";
|
|
152
|
+
};
|
|
153
|
+
readonly 'font-size-md': {
|
|
154
|
+
readonly light: "1rem";
|
|
155
|
+
readonly dark: "1rem";
|
|
156
|
+
};
|
|
157
|
+
readonly 'font-size-lg': {
|
|
158
|
+
readonly light: "1.125rem";
|
|
159
|
+
readonly dark: "1.125rem";
|
|
160
|
+
};
|
|
161
|
+
readonly 'font-size-xl': {
|
|
162
|
+
readonly light: "1.25rem";
|
|
163
|
+
readonly dark: "1.25rem";
|
|
164
|
+
};
|
|
165
|
+
readonly 'font-weight-regular': {
|
|
166
|
+
readonly light: "400";
|
|
167
|
+
readonly dark: "400";
|
|
168
|
+
};
|
|
169
|
+
readonly 'font-weight-medium': {
|
|
170
|
+
readonly light: "500";
|
|
171
|
+
readonly dark: "500";
|
|
172
|
+
};
|
|
173
|
+
readonly 'font-weight-semibold': {
|
|
174
|
+
readonly light: "600";
|
|
175
|
+
readonly dark: "600";
|
|
176
|
+
};
|
|
177
|
+
readonly 'line-height-tight': {
|
|
178
|
+
readonly light: "1.25";
|
|
179
|
+
readonly dark: "1.25";
|
|
180
|
+
};
|
|
181
|
+
readonly 'line-height-normal': {
|
|
182
|
+
readonly light: "1.5";
|
|
183
|
+
readonly dark: "1.5";
|
|
184
|
+
};
|
|
185
|
+
readonly 'shadow-sm': {
|
|
186
|
+
readonly light: "0 1px 2px rgba(31, 35, 40, 0.08)";
|
|
187
|
+
readonly dark: "0 1px 2px rgba(0, 0, 0, 0.4)";
|
|
188
|
+
};
|
|
189
|
+
readonly 'shadow-md': {
|
|
190
|
+
readonly light: "0 4px 12px rgba(31, 35, 40, 0.1)";
|
|
191
|
+
readonly dark: "0 4px 16px rgba(0, 0, 0, 0.45)";
|
|
192
|
+
};
|
|
193
|
+
readonly 'focus-ring': {
|
|
194
|
+
readonly light: "0 0 0 3px rgba(9, 105, 218, 0.35)";
|
|
195
|
+
readonly dark: "0 0 0 3px rgba(47, 129, 247, 0.45)";
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
export type SemanticTokenName = keyof typeof semanticTokens;
|
|
199
|
+
/** CSS custom property name, e.g. `--kb-color-bg-canvas`. */
|
|
200
|
+
export declare function cssVarName(token: SemanticTokenName): `--kb-${SemanticTokenName}`;
|
|
201
|
+
/** `var(--kb-…)` reference for use in component styles. */
|
|
202
|
+
export declare function cssVar(token: SemanticTokenName): string;
|
|
203
|
+
/**
|
|
204
|
+
* Apply theme on an element (default: document root in browsers).
|
|
205
|
+
* No-op without a DOM root (SSR) unless `root` is passed explicitly.
|
|
206
|
+
*/
|
|
207
|
+
export declare function applyTheme(theme: KitbashTheme, root?: HTMLElement): void;
|
|
208
|
+
/** Defaults to `light` when no DOM / no data-theme (SSR-safe). */
|
|
209
|
+
export declare function getTheme(root?: HTMLElement): KitbashTheme;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens — single source of truth for names and light/dark values.
|
|
3
|
+
* CSS themes + kitbash `tokens.json` are generated from this module.
|
|
4
|
+
*
|
|
5
|
+
* CSS custom property for key `color-bg-canvas` → `--kb-color-bg-canvas`
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Flat semantic map. Keys are stable public IDs (kebab after `--kb-`).
|
|
9
|
+
* Prefer semantic roles over raw brand names in components.
|
|
10
|
+
*/
|
|
11
|
+
export const semanticTokens = {
|
|
12
|
+
/* Color — surfaces */
|
|
13
|
+
'color-bg-canvas': { light: '#ffffff', dark: '#0d1117' },
|
|
14
|
+
'color-bg-surface': { light: '#f6f8fa', dark: '#161b22' },
|
|
15
|
+
'color-bg-subtle': { light: '#eef1f4', dark: '#21262d' },
|
|
16
|
+
'color-bg-inverse': { light: '#1f2328', dark: '#e6edf3' },
|
|
17
|
+
/* Color — foreground */
|
|
18
|
+
'color-fg-default': { light: '#1f2328', dark: '#e6edf3' },
|
|
19
|
+
'color-fg-muted': { light: '#656d76', dark: '#8b949e' },
|
|
20
|
+
'color-fg-subtle': { light: '#8c959f', dark: '#6e7681' },
|
|
21
|
+
'color-fg-on-accent': { light: '#ffffff', dark: '#ffffff' },
|
|
22
|
+
'color-fg-on-inverse': { light: '#ffffff', dark: '#0d1117' },
|
|
23
|
+
/* Color — border */
|
|
24
|
+
'color-border-default': { light: '#d0d7de', dark: '#30363d' },
|
|
25
|
+
'color-border-muted': { light: '#e6ebf0', dark: '#21262d' },
|
|
26
|
+
'color-border-focus': { light: '#0969da', dark: '#2f81f7' },
|
|
27
|
+
/* Color — accent / status */
|
|
28
|
+
'color-accent-default': { light: '#0969da', dark: '#2f81f7' },
|
|
29
|
+
'color-accent-hover': { light: '#0860ca', dark: '#58a6ff' },
|
|
30
|
+
'color-accent-subtle': { light: '#ddf4ff', dark: '#121d2f' },
|
|
31
|
+
'color-danger-default': { light: '#cf222e', dark: '#f85149' },
|
|
32
|
+
'color-danger-subtle': { light: '#ffebe9', dark: '#2d1214' },
|
|
33
|
+
'color-success-default': { light: '#1a7f37', dark: '#3fb950' },
|
|
34
|
+
'color-success-subtle': { light: '#dafbe1', dark: '#12261e' },
|
|
35
|
+
'color-warning-default': { light: '#9a6700', dark: '#d29922' },
|
|
36
|
+
'color-warning-subtle': { light: '#fff8c5', dark: '#2a2111' },
|
|
37
|
+
/* Space */
|
|
38
|
+
'space-2xs': { light: '2px', dark: '2px' },
|
|
39
|
+
'space-xs': { light: '4px', dark: '4px' },
|
|
40
|
+
'space-sm': { light: '8px', dark: '8px' },
|
|
41
|
+
'space-md': { light: '16px', dark: '16px' },
|
|
42
|
+
'space-lg': { light: '24px', dark: '24px' },
|
|
43
|
+
'space-xl': { light: '32px', dark: '32px' },
|
|
44
|
+
'space-2xl': { light: '48px', dark: '48px' },
|
|
45
|
+
/* Radius */
|
|
46
|
+
'radius-sm': { light: '4px', dark: '4px' },
|
|
47
|
+
'radius-md': { light: '8px', dark: '8px' },
|
|
48
|
+
'radius-lg': { light: '12px', dark: '12px' },
|
|
49
|
+
'radius-full': { light: '9999px', dark: '9999px' },
|
|
50
|
+
/* Typography */
|
|
51
|
+
'font-family-sans': {
|
|
52
|
+
light: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
53
|
+
dark: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
54
|
+
},
|
|
55
|
+
'font-size-sm': { light: '0.875rem', dark: '0.875rem' },
|
|
56
|
+
'font-size-md': { light: '1rem', dark: '1rem' },
|
|
57
|
+
'font-size-lg': { light: '1.125rem', dark: '1.125rem' },
|
|
58
|
+
'font-size-xl': { light: '1.25rem', dark: '1.25rem' },
|
|
59
|
+
'font-weight-regular': { light: '400', dark: '400' },
|
|
60
|
+
'font-weight-medium': { light: '500', dark: '500' },
|
|
61
|
+
'font-weight-semibold': { light: '600', dark: '600' },
|
|
62
|
+
'line-height-tight': { light: '1.25', dark: '1.25' },
|
|
63
|
+
'line-height-normal': { light: '1.5', dark: '1.5' },
|
|
64
|
+
/* Elevation / focus */
|
|
65
|
+
'shadow-sm': {
|
|
66
|
+
light: '0 1px 2px rgba(31, 35, 40, 0.08)',
|
|
67
|
+
dark: '0 1px 2px rgba(0, 0, 0, 0.4)',
|
|
68
|
+
},
|
|
69
|
+
'shadow-md': {
|
|
70
|
+
light: '0 4px 12px rgba(31, 35, 40, 0.1)',
|
|
71
|
+
dark: '0 4px 16px rgba(0, 0, 0, 0.45)',
|
|
72
|
+
},
|
|
73
|
+
'focus-ring': {
|
|
74
|
+
light: '0 0 0 3px rgba(9, 105, 218, 0.35)',
|
|
75
|
+
dark: '0 0 0 3px rgba(47, 129, 247, 0.45)',
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
/** CSS custom property name, e.g. `--kb-color-bg-canvas`. */
|
|
79
|
+
export function cssVarName(token) {
|
|
80
|
+
return `--kb-${token}`;
|
|
81
|
+
}
|
|
82
|
+
/** `var(--kb-…)` reference for use in component styles. */
|
|
83
|
+
export function cssVar(token) {
|
|
84
|
+
return `var(${cssVarName(token)})`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Apply theme on an element (default: document root in browsers).
|
|
88
|
+
* No-op without a DOM root (SSR) unless `root` is passed explicitly.
|
|
89
|
+
*/
|
|
90
|
+
export function applyTheme(theme, root) {
|
|
91
|
+
const el = root ??
|
|
92
|
+
(typeof document !== 'undefined' ? document.documentElement : undefined);
|
|
93
|
+
if (el) {
|
|
94
|
+
el.dataset.theme = theme;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Defaults to `light` when no DOM / no data-theme (SSR-safe). */
|
|
98
|
+
export function getTheme(root) {
|
|
99
|
+
const el = root ??
|
|
100
|
+
(typeof document !== 'undefined' ? document.documentElement : undefined);
|
|
101
|
+
return el?.dataset.theme === 'dark' ? 'dark' : 'light';
|
|
102
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Shared public unions for @ktbsh/ui components and consumer DX. */
|
|
2
|
+
export type KitbashSize = 'sm' | 'md' | 'lg';
|
|
3
|
+
export type KitbashButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';
|
|
4
|
+
export type KitbashBadgeTone = 'neutral' | 'accent' | 'success' | 'warning' | 'danger';
|
|
5
|
+
export type KitbashLinkTone = 'default' | 'muted' | 'accent';
|
|
6
|
+
/** Spacing token keys used by layout (maps to --kb-space-*). */
|
|
7
|
+
export type KitbashSpace = 'none' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
|
8
|
+
export type KitbashStackDirection = 'row' | 'column';
|
|
9
|
+
export type KitbashStackAlign = 'start' | 'center' | 'end' | 'stretch';
|
|
10
|
+
export type KitbashStackJustify = 'start' | 'center' | 'end' | 'between' | 'around';
|
|
11
|
+
export type KitbashTextTone = 'default' | 'muted' | 'subtle' | 'accent' | 'danger';
|
|
12
|
+
export type KitbashHeadingLevel = '1' | '2' | '3' | '4' | '5' | '6';
|
|
13
|
+
export type KitbashContainerWidth = 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
14
|
+
export type KitbashFeedbackTone = 'info' | 'success' | 'warning' | 'danger';
|
|
15
|
+
export type KitbashSkeletonVariant = 'text' | 'rect' | 'circle';
|