@braedonsaunders/appkit-ui 0.2.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/LICENSE +661 -0
- package/README.md +11 -0
- package/account-menu.d.ts +49 -0
- package/account-menu.d.ts.map +1 -0
- package/account-menu.js +66 -0
- package/account-menu.js.map +1 -0
- package/alert.d.ts +13 -0
- package/alert.d.ts.map +1 -0
- package/alert.js +22 -0
- package/alert.js.map +1 -0
- package/animated-number.d.ts +13 -0
- package/animated-number.d.ts.map +1 -0
- package/animated-number.js +53 -0
- package/animated-number.js.map +1 -0
- package/api-reference.d.ts +44 -0
- package/api-reference.d.ts.map +1 -0
- package/api-reference.js +82 -0
- package/api-reference.js.map +1 -0
- package/app-shell.d.ts +39 -0
- package/app-shell.d.ts.map +1 -0
- package/app-shell.js +21 -0
- package/app-shell.js.map +1 -0
- package/app-sidebar.d.ts +22 -0
- package/app-sidebar.d.ts.map +1 -0
- package/app-sidebar.js +30 -0
- package/app-sidebar.js.map +1 -0
- package/avatar.d.ts +9 -0
- package/avatar.d.ts.map +1 -0
- package/avatar.js +18 -0
- package/avatar.js.map +1 -0
- package/badge.d.ts +9 -0
- package/badge.d.ts.map +1 -0
- package/badge.js +23 -0
- package/badge.js.map +1 -0
- package/button.d.ts +24 -0
- package/button.d.ts.map +1 -0
- package/button.js +50 -0
- package/button.js.map +1 -0
- package/card.d.ts +21 -0
- package/card.d.ts.map +1 -0
- package/card.js +36 -0
- package/card.js.map +1 -0
- package/checkbox.d.ts +4 -0
- package/checkbox.d.ts.map +1 -0
- package/checkbox.js +6 -0
- package/checkbox.js.map +1 -0
- package/confirm-dialog.d.ts +23 -0
- package/confirm-dialog.d.ts.map +1 -0
- package/confirm-dialog.js +67 -0
- package/confirm-dialog.js.map +1 -0
- package/context-menu.d.ts +47 -0
- package/context-menu.d.ts.map +1 -0
- package/context-menu.js +90 -0
- package/context-menu.js.map +1 -0
- package/dialog.d.ts +25 -0
- package/dialog.d.ts.map +1 -0
- package/dialog.js +89 -0
- package/dialog.js.map +1 -0
- package/document-title.d.ts +11 -0
- package/document-title.d.ts.map +1 -0
- package/document-title.js +17 -0
- package/document-title.js.map +1 -0
- package/drawer.d.ts +63 -0
- package/drawer.d.ts.map +1 -0
- package/drawer.js +188 -0
- package/drawer.js.map +1 -0
- package/empty-state.d.ts +10 -0
- package/empty-state.d.ts.map +1 -0
- package/empty-state.js +7 -0
- package/empty-state.js.map +1 -0
- package/file-uploader.d.ts +67 -0
- package/file-uploader.d.ts.map +1 -0
- package/file-uploader.js +156 -0
- package/file-uploader.js.map +1 -0
- package/filter-chips.d.ts +47 -0
- package/filter-chips.d.ts.map +1 -0
- package/filter-chips.js +62 -0
- package/filter-chips.js.map +1 -0
- package/global-search.d.ts +41 -0
- package/global-search.d.ts.map +1 -0
- package/global-search.js +116 -0
- package/global-search.js.map +1 -0
- package/index.d.ts +70 -0
- package/index.d.ts.map +1 -0
- package/index.js +70 -0
- package/index.js.map +1 -0
- package/input.d.ts +9 -0
- package/input.d.ts.map +1 -0
- package/input.js +11 -0
- package/input.js.map +1 -0
- package/label.d.ts +3 -0
- package/label.d.ts.map +1 -0
- package/label.js +6 -0
- package/label.js.map +1 -0
- package/line-grid.d.ts +48 -0
- package/line-grid.d.ts.map +1 -0
- package/line-grid.js +155 -0
- package/line-grid.js.map +1 -0
- package/link-context.d.ts +44 -0
- package/link-context.d.ts.map +1 -0
- package/link-context.js +32 -0
- package/link-context.js.map +1 -0
- package/list-nav.d.ts +28 -0
- package/list-nav.d.ts.map +1 -0
- package/list-nav.js +41 -0
- package/list-nav.js.map +1 -0
- package/list-pagination.d.ts +27 -0
- package/list-pagination.d.ts.map +1 -0
- package/list-pagination.js +43 -0
- package/list-pagination.js.map +1 -0
- package/list-params.d.ts +41 -0
- package/list-params.d.ts.map +1 -0
- package/list-params.js +84 -0
- package/list-params.js.map +1 -0
- package/list-search-input-state.d.ts +13 -0
- package/list-search-input-state.d.ts.map +1 -0
- package/list-search-input-state.js +27 -0
- package/list-search-input-state.js.map +1 -0
- package/list-search-input.d.ts +16 -0
- package/list-search-input.d.ts.map +1 -0
- package/list-search-input.js +51 -0
- package/list-search-input.js.map +1 -0
- package/mobile-tab-bar.d.ts +14 -0
- package/mobile-tab-bar.d.ts.map +1 -0
- package/mobile-tab-bar.js +25 -0
- package/mobile-tab-bar.js.map +1 -0
- package/multi-select.d.ts +32 -0
- package/multi-select.d.ts.map +1 -0
- package/multi-select.js +52 -0
- package/multi-select.js.map +1 -0
- package/nav-overflow.d.ts +12 -0
- package/nav-overflow.d.ts.map +1 -0
- package/nav-overflow.js +30 -0
- package/nav-overflow.js.map +1 -0
- package/navigation-config-editor.d.ts +26 -0
- package/navigation-config-editor.d.ts.map +1 -0
- package/navigation-config-editor.js +57 -0
- package/navigation-config-editor.js.map +1 -0
- package/navigation-config.d.ts +48 -0
- package/navigation-config.d.ts.map +1 -0
- package/navigation-config.js +75 -0
- package/navigation-config.js.map +1 -0
- package/navigation-mode.d.ts +16 -0
- package/navigation-mode.d.ts.map +1 -0
- package/navigation-mode.js +30 -0
- package/navigation-mode.js.map +1 -0
- package/notifications-bell.d.ts +22 -0
- package/notifications-bell.d.ts.map +1 -0
- package/notifications-bell.js +30 -0
- package/notifications-bell.js.map +1 -0
- package/org-chart.d.ts +85 -0
- package/org-chart.d.ts.map +1 -0
- package/org-chart.js +193 -0
- package/org-chart.js.map +1 -0
- package/package.json +61 -0
- package/page-header.d.ts +32 -0
- package/page-header.d.ts.map +1 -0
- package/page-header.js +14 -0
- package/page-header.js.map +1 -0
- package/page-layout.d.ts +29 -0
- package/page-layout.d.ts.map +1 -0
- package/page-layout.js +23 -0
- package/page-layout.js.map +1 -0
- package/page-transition.d.ts +13 -0
- package/page-transition.d.ts.map +1 -0
- package/page-transition.js +14 -0
- package/page-transition.js.map +1 -0
- package/paged-table.d.ts +54 -0
- package/paged-table.d.ts.map +1 -0
- package/paged-table.js +74 -0
- package/paged-table.js.map +1 -0
- package/popover.d.ts +16 -0
- package/popover.d.ts.map +1 -0
- package/popover.js +99 -0
- package/popover.js.map +1 -0
- package/progress.d.ts +7 -0
- package/progress.d.ts.map +1 -0
- package/progress.js +8 -0
- package/progress.js.map +1 -0
- package/prompt-dialog.d.ts +21 -0
- package/prompt-dialog.d.ts.map +1 -0
- package/prompt-dialog.js +109 -0
- package/prompt-dialog.js.map +1 -0
- package/record-list.d.ts +76 -0
- package/record-list.d.ts.map +1 -0
- package/record-list.js +51 -0
- package/record-list.js.map +1 -0
- package/search-select.d.ts +42 -0
- package/search-select.d.ts.map +1 -0
- package/search-select.js +194 -0
- package/search-select.js.map +1 -0
- package/select-options.d.ts +16 -0
- package/select-options.d.ts.map +1 -0
- package/select-options.js +119 -0
- package/select-options.js.map +1 -0
- package/select.d.ts +24 -0
- package/select.d.ts.map +1 -0
- package/select.js +65 -0
- package/select.js.map +1 -0
- package/separator.d.ts +6 -0
- package/separator.d.ts.map +1 -0
- package/separator.js +7 -0
- package/separator.js.map +1 -0
- package/settings-layout.d.ts +79 -0
- package/settings-layout.d.ts.map +1 -0
- package/settings-layout.js +74 -0
- package/settings-layout.js.map +1 -0
- package/sidebar-nav.d.ts +67 -0
- package/sidebar-nav.d.ts.map +1 -0
- package/sidebar-nav.js +291 -0
- package/sidebar-nav.js.map +1 -0
- package/signature-pad.d.ts +16 -0
- package/signature-pad.d.ts.map +1 -0
- package/signature-pad.js +355 -0
- package/signature-pad.js.map +1 -0
- package/skeleton.d.ts +9 -0
- package/skeleton.d.ts.map +1 -0
- package/skeleton.js +12 -0
- package/skeleton.js.map +1 -0
- package/slider.d.ts +13 -0
- package/slider.d.ts.map +1 -0
- package/slider.js +15 -0
- package/slider.js.map +1 -0
- package/sortable-th.d.ts +28 -0
- package/sortable-th.d.ts.map +1 -0
- package/sortable-th.js +35 -0
- package/sortable-th.js.map +1 -0
- package/sparkline.d.ts +16 -0
- package/sparkline.d.ts.map +1 -0
- package/sparkline.js +46 -0
- package/sparkline.js.map +1 -0
- package/spinner.d.ts +11 -0
- package/spinner.d.ts.map +1 -0
- package/spinner.js +11 -0
- package/spinner.js.map +1 -0
- package/styles.css +166 -0
- package/subtab-nav.d.ts +17 -0
- package/subtab-nav.d.ts.map +1 -0
- package/subtab-nav.js +11 -0
- package/subtab-nav.js.map +1 -0
- package/switch.d.ts +9 -0
- package/switch.d.ts.map +1 -0
- package/switch.js +11 -0
- package/switch.js.map +1 -0
- package/tab-content.d.ts +24 -0
- package/tab-content.d.ts.map +1 -0
- package/tab-content.js +26 -0
- package/tab-content.js.map +1 -0
- package/table.d.ts +28 -0
- package/table.d.ts.map +1 -0
- package/table.js +21 -0
- package/table.js.map +1 -0
- package/tabs.d.ts +18 -0
- package/tabs.d.ts.map +1 -0
- package/tabs.js +18 -0
- package/tabs.js.map +1 -0
- package/text-context.d.ts +9 -0
- package/text-context.d.ts.map +1 -0
- package/text-context.js +12 -0
- package/text-context.js.map +1 -0
- package/textarea.d.ts +4 -0
- package/textarea.d.ts.map +1 -0
- package/textarea.js +6 -0
- package/textarea.js.map +1 -0
- package/theme-script.d.ts +3 -0
- package/theme-script.d.ts.map +1 -0
- package/theme-script.js +6 -0
- package/theme-script.js.map +1 -0
- package/theme.d.ts +28 -0
- package/theme.d.ts.map +1 -0
- package/theme.js +92 -0
- package/theme.js.map +1 -0
- package/toast.d.ts +52 -0
- package/toast.d.ts.map +1 -0
- package/toast.js +178 -0
- package/toast.js.map +1 -0
- package/tooltip.d.ts +12 -0
- package/tooltip.d.ts.map +1 -0
- package/tooltip.js +14 -0
- package/tooltip.js.map +1 -0
- package/top-nav.d.ts +18 -0
- package/top-nav.d.ts.map +1 -0
- package/top-nav.js +160 -0
- package/top-nav.js.map +1 -0
- package/upload-limits.d.ts +4 -0
- package/upload-limits.d.ts.map +1 -0
- package/upload-limits.js +21 -0
- package/upload-limits.js.map +1 -0
- package/use-element-size.d.ts +7 -0
- package/use-element-size.d.ts.map +1 -0
- package/use-element-size.js +21 -0
- package/use-element-size.js.map +1 -0
- package/utils.d.ts +4 -0
- package/utils.d.ts.map +1 -0
- package/utils.js +7 -0
- package/utils.js.map +1 -0
- package/workspace-launcher.d.ts +50 -0
- package/workspace-launcher.d.ts.map +1 -0
- package/workspace-launcher.js +127 -0
- package/workspace-launcher.js.map +1 -0
package/sparkline.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from './utils.js';
|
|
3
|
+
const TONE_COLOR = {
|
|
4
|
+
up: 'var(--color-danger)',
|
|
5
|
+
down: 'var(--color-success)',
|
|
6
|
+
good: 'var(--color-success)',
|
|
7
|
+
bad: 'var(--color-danger)',
|
|
8
|
+
neutral: 'var(--color-fg-muted)',
|
|
9
|
+
};
|
|
10
|
+
export function Sparkline({ points, tone = 'neutral', auto, goodWhenRising = true, dots = false, stroke, area = false, strokeWidth = 1.5, className, ariaLabel, noTrendLabel = 'No trend data', }) {
|
|
11
|
+
let resolvedTone = tone;
|
|
12
|
+
if (auto && points.length >= 2) {
|
|
13
|
+
const first = points[0];
|
|
14
|
+
const last = points[points.length - 1];
|
|
15
|
+
if (last === first)
|
|
16
|
+
resolvedTone = 'neutral';
|
|
17
|
+
else if (last > first)
|
|
18
|
+
resolvedTone = goodWhenRising ? 'good' : 'bad';
|
|
19
|
+
else
|
|
20
|
+
resolvedTone = goodWhenRising ? 'bad' : 'good';
|
|
21
|
+
}
|
|
22
|
+
const strokeColor = stroke ?? TONE_COLOR[resolvedTone];
|
|
23
|
+
if (points.length < 2) {
|
|
24
|
+
return (_jsx("svg", { viewBox: "0 0 100 32", preserveAspectRatio: "none", role: "img", "aria-label": ariaLabel ?? noTrendLabel, className: cn('block', className), children: _jsx("line", { x1: "0", y1: "16", x2: "100", y2: "16", stroke: "var(--color-border)", strokeWidth: "1", strokeDasharray: "3,3" }) }));
|
|
25
|
+
}
|
|
26
|
+
const min = Math.min(...points);
|
|
27
|
+
const max = Math.max(...points);
|
|
28
|
+
const range = max - min || 1;
|
|
29
|
+
const minIndex = points.indexOf(min);
|
|
30
|
+
const maxIndex = points.indexOf(max);
|
|
31
|
+
const coordinates = points.map((point, index) => {
|
|
32
|
+
const x = (index / (points.length - 1)) * 100;
|
|
33
|
+
const y = 29 - ((point - min) / range) * 26;
|
|
34
|
+
return [x, y];
|
|
35
|
+
});
|
|
36
|
+
const path = `M ${coordinates.map(([x, y]) => `${x.toFixed(2)} ${y.toFixed(2)}`).join(' L ')}`;
|
|
37
|
+
const areaPath = `${path} L 100 32 L 0 32 Z`;
|
|
38
|
+
const label = ariaLabel ?? `Trend: ${points.length} points from ${points[0]} to ${points.at(-1)}`;
|
|
39
|
+
return (_jsxs("svg", { viewBox: "0 0 100 32", preserveAspectRatio: "none", role: "img", "aria-label": label, className: cn('block overflow-visible', className), children: [area ? _jsx("path", { d: areaPath, fill: `color-mix(in oklab, ${strokeColor} 12%, transparent)`, stroke: "none" }) : null, _jsx("path", { d: path, fill: "none", stroke: strokeColor, strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }), dots
|
|
40
|
+
? [minIndex, maxIndex].filter((index, position, all) => all.indexOf(index) === position).map((index) => {
|
|
41
|
+
const [x, y] = coordinates[index];
|
|
42
|
+
return _jsx("circle", { cx: x, cy: y, r: "1.75", fill: strokeColor, stroke: "var(--color-surface)", strokeWidth: "0.75" }, index);
|
|
43
|
+
})
|
|
44
|
+
: null] }));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=sparkline.js.map
|
package/sparkline.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sparkline.js","sourceRoot":"","sources":["../src/sparkline.tsx"],"names":[],"mappings":"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","sourcesContent":["import { cn } from './utils'\n\nexport type SparklineTone = 'up' | 'down' | 'good' | 'bad' | 'neutral'\n\nexport type SparklineProps = {\n points: number[]\n tone?: SparklineTone\n auto?: boolean\n goodWhenRising?: boolean\n dots?: boolean\n stroke?: string\n area?: boolean\n strokeWidth?: number\n className?: string\n ariaLabel?: string\n noTrendLabel?: string\n}\n\nconst TONE_COLOR: Record<SparklineTone, string> = {\n up: 'var(--color-danger)',\n down: 'var(--color-success)',\n good: 'var(--color-success)',\n bad: 'var(--color-danger)',\n neutral: 'var(--color-fg-muted)',\n}\n\nexport function Sparkline({\n points,\n tone = 'neutral',\n auto,\n goodWhenRising = true,\n dots = false,\n stroke,\n area = false,\n strokeWidth = 1.5,\n className,\n ariaLabel,\n noTrendLabel = 'No trend data',\n}: SparklineProps) {\n let resolvedTone = tone\n if (auto && points.length >= 2) {\n const first = points[0]!\n const last = points[points.length - 1]!\n if (last === first) resolvedTone = 'neutral'\n else if (last > first) resolvedTone = goodWhenRising ? 'good' : 'bad'\n else resolvedTone = goodWhenRising ? 'bad' : 'good'\n }\n const strokeColor = stroke ?? TONE_COLOR[resolvedTone]\n\n if (points.length < 2) {\n return (\n <svg viewBox=\"0 0 100 32\" preserveAspectRatio=\"none\" role=\"img\" aria-label={ariaLabel ?? noTrendLabel} className={cn('block', className)}>\n <line x1=\"0\" y1=\"16\" x2=\"100\" y2=\"16\" stroke=\"var(--color-border)\" strokeWidth=\"1\" strokeDasharray=\"3,3\" />\n </svg>\n )\n }\n\n const min = Math.min(...points)\n const max = Math.max(...points)\n const range = max - min || 1\n const minIndex = points.indexOf(min)\n const maxIndex = points.indexOf(max)\n const coordinates = points.map((point, index) => {\n const x = (index / (points.length - 1)) * 100\n const y = 29 - ((point - min) / range) * 26\n return [x, y] as const\n })\n const path = `M ${coordinates.map(([x, y]) => `${x.toFixed(2)} ${y.toFixed(2)}`).join(' L ')}`\n const areaPath = `${path} L 100 32 L 0 32 Z`\n const label = ariaLabel ?? `Trend: ${points.length} points from ${points[0]} to ${points.at(-1)}`\n\n return (\n <svg viewBox=\"0 0 100 32\" preserveAspectRatio=\"none\" role=\"img\" aria-label={label} className={cn('block overflow-visible', className)}>\n {area ? <path d={areaPath} fill={`color-mix(in oklab, ${strokeColor} 12%, transparent)`} stroke=\"none\" /> : null}\n <path d={path} fill=\"none\" stroke={strokeColor} strokeWidth={strokeWidth} strokeLinecap=\"round\" strokeLinejoin=\"round\" vectorEffect=\"non-scaling-stroke\" />\n {dots\n ? [minIndex, maxIndex].filter((index, position, all) => all.indexOf(index) === position).map((index) => {\n const [x, y] = coordinates[index]!\n return <circle key={index} cx={x} cy={y} r=\"1.75\" fill={strokeColor} stroke=\"var(--color-surface)\" strokeWidth=\"0.75\" />\n })\n : null}\n </svg>\n )\n}\n"]}
|
package/spinner.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type SpinnerProps = React.SVGAttributes<SVGSVGElement> & {
|
|
3
|
+
size?: number;
|
|
4
|
+
label?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Spinner — a token-colored, reduced-motion-aware loading indicator. Uses
|
|
8
|
+
* currentColor so it inherits the surrounding text color by default.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Spinner({ size, label, className, ...props }: SpinnerProps): React.JSX.Element;
|
|
11
|
+
//# sourceMappingURL=spinner.d.ts.map
|
package/spinner.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../src/spinner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,IAAS,EAAE,KAAiB,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,qBAqB1F"}
|
package/spinner.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { cn } from './utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Spinner — a token-colored, reduced-motion-aware loading indicator. Uses
|
|
6
|
+
* currentColor so it inherits the surrounding text color by default.
|
|
7
|
+
*/
|
|
8
|
+
export function Spinner({ size = 16, label = 'Loading', className, ...props }) {
|
|
9
|
+
return (_jsxs("svg", { role: "status", "aria-label": label, width: size, height: size, viewBox: "0 0 24 24", fill: "none", className: cn('animate-spin text-fg-muted motion-reduce:animate-none', className), ...props, children: [_jsx("circle", { cx: "12", cy: "12", r: "9", stroke: "currentColor", strokeOpacity: "0.2", strokeWidth: "3" }), _jsx("path", { d: "M21 12a9 9 0 0 0-9-9", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round" })] }));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=spinner.js.map
|
package/spinner.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../src/spinner.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAO5B;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,SAAS,EAAE,SAAS,EAAE,GAAG,KAAK,EAAgB;IACzF,OAAO,CACL,eACE,IAAI,EAAC,QAAQ,gBACD,KAAK,EACjB,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,EACZ,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,SAAS,EAAE,EAAE,CAAC,uDAAuD,EAAE,SAAS,CAAC,KAC7E,KAAK,aAET,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,GAAG,EAAC,MAAM,EAAC,cAAc,EAAC,aAAa,EAAC,KAAK,EAAC,WAAW,EAAC,GAAG,GAAG,EAC1F,eACE,CAAC,EAAC,sBAAsB,EACxB,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,GACrB,IACE,CACP,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\nimport { cn } from './utils'\n\nexport type SpinnerProps = React.SVGAttributes<SVGSVGElement> & {\n size?: number\n label?: string\n}\n\n/**\n * Spinner — a token-colored, reduced-motion-aware loading indicator. Uses\n * currentColor so it inherits the surrounding text color by default.\n */\nexport function Spinner({ size = 16, label = 'Loading', className, ...props }: SpinnerProps) {\n return (\n <svg\n role=\"status\"\n aria-label={label}\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className={cn('animate-spin text-fg-muted motion-reduce:animate-none', className)}\n {...props}\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" strokeOpacity=\"0.2\" strokeWidth=\"3\" />\n <path\n d=\"M21 12a9 9 0 0 0-9-9\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n />\n </svg>\n )\n}\n"]}
|
package/styles.css
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/* @braedonsaunders/appkit-ui styles — pull in the token foundation so an app can get the full
|
|
2
|
+
* system with a single import:
|
|
3
|
+
* @import '@braedonsaunders/appkit-ui/styles.css';
|
|
4
|
+
* (which transitively imports Tailwind v4 + @braedonsaunders/appkit-tokens). */
|
|
5
|
+
@import '@braedonsaunders/appkit-tokens/tokens.css';
|
|
6
|
+
|
|
7
|
+
/* Browser-native route handoff. Apps opt in by placing their changing page
|
|
8
|
+
boundary in React's ViewTransition with class `appkit-page-transition`.
|
|
9
|
+
The shell stays live and fixed; only the page canvas is snapshotted.
|
|
10
|
+
|
|
11
|
+
The choreography is a lift-and-settle crossfade: the outgoing canvas clears
|
|
12
|
+
quickly while the incoming one rises the last few pixels into place on the
|
|
13
|
+
decelerating token easing. Exit is deliberately shorter than entrance so the
|
|
14
|
+
two snapshots overlap only briefly — long enough to read as a crossfade,
|
|
15
|
+
short enough that text never ghosts against itself. */
|
|
16
|
+
::view-transition-old(root),
|
|
17
|
+
::view-transition-new(root) {
|
|
18
|
+
animation: none;
|
|
19
|
+
mix-blend-mode: normal;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
::view-transition-group(.appkit-page-transition) {
|
|
23
|
+
animation-duration: var(--duration-slow);
|
|
24
|
+
animation-timing-function: var(--ease-out);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
::view-transition-image-pair(.appkit-page-transition) {
|
|
28
|
+
isolation: isolate;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
::view-transition-old(.appkit-page-transition) {
|
|
32
|
+
animation: appkit-page-out var(--duration-fast) var(--ease-in-out) both;
|
|
33
|
+
mix-blend-mode: normal;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
::view-transition-new(.appkit-page-transition) {
|
|
37
|
+
animation: appkit-page-in var(--duration-slow) var(--ease-out) both;
|
|
38
|
+
mix-blend-mode: normal;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@keyframes appkit-page-out {
|
|
42
|
+
from {
|
|
43
|
+
opacity: 1;
|
|
44
|
+
translate: 0 0;
|
|
45
|
+
scale: 1;
|
|
46
|
+
}
|
|
47
|
+
to {
|
|
48
|
+
opacity: 0;
|
|
49
|
+
translate: 0 -4px;
|
|
50
|
+
scale: 0.995;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@keyframes appkit-page-in {
|
|
55
|
+
from {
|
|
56
|
+
opacity: 0;
|
|
57
|
+
translate: 0 12px;
|
|
58
|
+
scale: 0.99;
|
|
59
|
+
}
|
|
60
|
+
to {
|
|
61
|
+
opacity: 1;
|
|
62
|
+
translate: 0 0;
|
|
63
|
+
scale: 1;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@media (prefers-reduced-motion: reduce) {
|
|
68
|
+
::view-transition-old(*),
|
|
69
|
+
::view-transition-new(*),
|
|
70
|
+
::view-transition-group(*) {
|
|
71
|
+
animation-duration: 0.001ms !important;
|
|
72
|
+
animation-delay: 0ms !important;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* OrgChart connectors. The hierarchy is plain nested lists; the elbows between
|
|
77
|
+
a card and its reports are borders on pseudo-elements, so the whole chart
|
|
78
|
+
renders identically on the server and needs no measurement pass. Geometry:
|
|
79
|
+
the children list reserves `--appkit-org-drop` above each card, the sibling
|
|
80
|
+
rail sits halfway up that gap, and stems close the two halves. */
|
|
81
|
+
.appkit-org-canvas {
|
|
82
|
+
--appkit-org-drop: 2.5rem;
|
|
83
|
+
--appkit-org-gap: 1.25rem;
|
|
84
|
+
width: max-content;
|
|
85
|
+
min-width: 100%;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.appkit-org-children {
|
|
89
|
+
position: relative;
|
|
90
|
+
display: flex;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
gap: var(--appkit-org-gap);
|
|
93
|
+
margin: 0;
|
|
94
|
+
padding: var(--appkit-org-drop) 0 0;
|
|
95
|
+
list-style: none;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Stem down out of the parent card to the sibling rail. */
|
|
99
|
+
.appkit-org-children::before {
|
|
100
|
+
content: '';
|
|
101
|
+
position: absolute;
|
|
102
|
+
top: 0;
|
|
103
|
+
left: 50%;
|
|
104
|
+
height: calc(var(--appkit-org-drop) / 2);
|
|
105
|
+
border-left: 1px solid var(--color-border-strong);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.appkit-org-item {
|
|
109
|
+
position: relative;
|
|
110
|
+
display: flex;
|
|
111
|
+
flex-direction: column;
|
|
112
|
+
align-items: center;
|
|
113
|
+
list-style: none;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* The two halves of the rail joining this card to its siblings. */
|
|
117
|
+
.appkit-org-item::before,
|
|
118
|
+
.appkit-org-item::after {
|
|
119
|
+
content: '';
|
|
120
|
+
position: absolute;
|
|
121
|
+
top: calc(var(--appkit-org-drop) / -2);
|
|
122
|
+
width: 50%;
|
|
123
|
+
border-top: 1px solid var(--color-border-strong);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.appkit-org-item::before {
|
|
127
|
+
right: 50%;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.appkit-org-item::after {
|
|
131
|
+
left: 50%;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.appkit-org-item:first-child::before,
|
|
135
|
+
.appkit-org-item:last-child::after {
|
|
136
|
+
border-top: 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Stem from the rail down into this card. */
|
|
140
|
+
.appkit-org-stem {
|
|
141
|
+
position: absolute;
|
|
142
|
+
top: calc(var(--appkit-org-drop) / -2);
|
|
143
|
+
left: 50%;
|
|
144
|
+
height: calc(var(--appkit-org-drop) / 2);
|
|
145
|
+
border-left: 1px solid var(--color-border-strong);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* Top level: no parent above it, so no rail and no stems. */
|
|
149
|
+
.appkit-org-roots {
|
|
150
|
+
padding-top: 0;
|
|
151
|
+
gap: calc(var(--appkit-org-gap) * 2);
|
|
152
|
+
align-items: flex-start;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.appkit-org-roots::before,
|
|
156
|
+
.appkit-org-item--root::before,
|
|
157
|
+
.appkit-org-item--root::after {
|
|
158
|
+
content: none;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Ensure Tailwind scans the primitives for class usage even when the app's own
|
|
162
|
+
* content globs don't reach into node_modules. */
|
|
163
|
+
/* The package is built with its JS files at the publish root, while this file
|
|
164
|
+
lives beside them. Scanning the current directory works both in the source
|
|
165
|
+
tree and in the packed artifact. */
|
|
166
|
+
@source './';
|
package/subtab-nav.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface SubtabItem {
|
|
3
|
+
key: string;
|
|
4
|
+
label: React.ReactNode;
|
|
5
|
+
count?: number;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface SubtabNavProps {
|
|
9
|
+
tabs: SubtabItem[];
|
|
10
|
+
active: string;
|
|
11
|
+
onSelect?: (key: string) => void;
|
|
12
|
+
ariaLabel?: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Source detail/drawer subtab bar, tokenized and reusable across page shells. */
|
|
16
|
+
export declare function SubtabNav({ tabs, active, onSelect, ariaLabel, className, }: SubtabNavProps): React.JSX.Element;
|
|
17
|
+
//# sourceMappingURL=subtab-nav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subtab-nav.d.ts","sourceRoot":"","sources":["../src/subtab-nav.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,EAAE,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,SAAsB,EACtB,SAAS,GACV,EAAE,cAAc,qBAmBhB"}
|
package/subtab-nav.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from './utils.js';
|
|
5
|
+
/** Source detail/drawer subtab bar, tokenized and reusable across page shells. */
|
|
6
|
+
export function SubtabNav({ tabs, active, onSelect, ariaLabel = 'Sections', className, }) {
|
|
7
|
+
return _jsx("nav", { role: "tablist", className: cn('-mb-px flex gap-1 overflow-x-auto', className), "aria-label": ariaLabel, children: tabs.map((tab) => _jsxs("button", { type: "button", role: "tab", "aria-selected": active === tab.key, disabled: tab.disabled, onClick: () => onSelect?.(tab.key), className: cn('flex shrink-0 items-center gap-2 border-b-2 px-3 py-3 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40', active === tab.key
|
|
8
|
+
? 'border-primary text-primary'
|
|
9
|
+
: 'border-transparent text-fg-muted hover:border-border-strong hover:text-fg'), children: [tab.label, typeof tab.count === 'number' ? _jsx("span", { className: "rounded-full bg-bg-subtle px-1.5 text-[11px] text-fg-muted", children: tab.count }) : null] }, tab.key)) });
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=subtab-nav.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subtab-nav.js","sourceRoot":"","sources":["../src/subtab-nav.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAiB5B,kFAAkF;AAClF,MAAM,UAAU,SAAS,CAAC,EACxB,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,SAAS,GAAG,UAAU,EACtB,SAAS,GACM;IACf,OAAO,cACL,IAAI,EAAC,SAAS,EACd,SAAS,EAAE,EAAE,CAAC,mCAAmC,EAAE,SAAS,CAAC,gBACjD,SAAS,YACrB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kBAElB,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,MAAM,KAAK,GAAG,CAAC,GAAG,EACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ,EACtB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAClC,SAAS,EAAE,EAAE,CACX,6IAA6I,EAC7I,MAAM,KAAK,GAAG,CAAC,GAAG;gBAChB,CAAC,CAAC,6BAA6B;gBAC/B,CAAC,CAAC,2EAA2E,CAChF,aACD,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,4DAA4D,YAAE,GAAG,CAAC,KAAK,GAAQ,CAAC,CAAC,CAAC,IAAI,KAZ5I,GAAG,CAAC,GAAG,CAY+I,CAAC,GAAO,CAAA;AACvK,CAAC","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cn } from './utils'\n\nexport interface SubtabItem {\n key: string\n label: React.ReactNode\n count?: number\n disabled?: boolean\n}\n\nexport interface SubtabNavProps {\n tabs: SubtabItem[]\n active: string\n onSelect?: (key: string) => void\n ariaLabel?: string\n className?: string\n}\n\n/** Source detail/drawer subtab bar, tokenized and reusable across page shells. */\nexport function SubtabNav({\n tabs,\n active,\n onSelect,\n ariaLabel = 'Sections',\n className,\n}: SubtabNavProps) {\n return <nav\n role=\"tablist\"\n className={cn('-mb-px flex gap-1 overflow-x-auto', className)}\n aria-label={ariaLabel}\n >{tabs.map((tab) => <button\n key={tab.key}\n type=\"button\"\n role=\"tab\"\n aria-selected={active === tab.key}\n disabled={tab.disabled}\n onClick={() => onSelect?.(tab.key)}\n className={cn(\n 'flex shrink-0 items-center gap-2 border-b-2 px-3 py-3 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40',\n active === tab.key\n ? 'border-primary text-primary'\n : 'border-transparent text-fg-muted hover:border-border-strong hover:text-fg',\n )}\n >{tab.label}{typeof tab.count === 'number' ? <span className=\"rounded-full bg-bg-subtle px-1.5 text-[11px] text-fg-muted\">{tab.count}</span> : null}</button>)}</nav>\n}\n"]}
|
package/switch.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type SwitchProps = React.InputHTMLAttributes<HTMLInputElement>;
|
|
3
|
+
/**
|
|
4
|
+
* Switch — an accessible checkbox styled as a toggle. Pure CSS (peer), so it's
|
|
5
|
+
* server-renderable and works controlled or uncontrolled. The knob stays light
|
|
6
|
+
* in both themes by convention.
|
|
7
|
+
*/
|
|
8
|
+
export declare const Switch: React.ForwardRefExoticComponent<SwitchProps & React.RefAttributes<HTMLInputElement>>;
|
|
9
|
+
//# sourceMappingURL=switch.d.ts.map
|
package/switch.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../src/switch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,MAAM,WAAW,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAA;AAErE;;;;GAIG;AACH,eAAO,MAAM,MAAM,sFAclB,CAAA"}
|
package/switch.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { cn } from './utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Switch — an accessible checkbox styled as a toggle. Pure CSS (peer), so it's
|
|
6
|
+
* server-renderable and works controlled or uncontrolled. The knob stays light
|
|
7
|
+
* in both themes by convention.
|
|
8
|
+
*/
|
|
9
|
+
export const Switch = React.forwardRef(({ className, disabled, ...props }, ref) => (_jsxs("label", { className: cn('relative inline-flex h-6 w-11 shrink-0 items-center', disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer', className), children: [_jsx("input", { ref: ref, type: "checkbox", role: "switch", className: "peer sr-only", disabled: disabled, ...props }), _jsx("span", { className: "absolute inset-0 rounded-full bg-border-strong transition-colors duration-200 peer-checked:bg-primary peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-bg" }), _jsx("span", { className: "pointer-events-none absolute left-0.5 size-5 rounded-full bg-white shadow-sm transition-transform duration-200 ease-out peer-checked:translate-x-5 motion-reduce:transition-none" })] })));
|
|
10
|
+
Switch.displayName = 'Switch';
|
|
11
|
+
//# sourceMappingURL=switch.js.map
|
package/switch.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switch.js","sourceRoot":"","sources":["../src/switch.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAI5B;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CACpC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAC1C,iBACE,SAAS,EAAE,EAAE,CACX,qDAAqD,EACrD,QAAQ,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,gBAAgB,EAC7D,SAAS,CACV,aAED,gBAAO,GAAG,EAAE,GAAG,EAAE,IAAI,EAAC,UAAU,EAAC,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,cAAc,EAAC,QAAQ,EAAE,QAAQ,KAAM,KAAK,GAAI,EACzG,eAAM,SAAS,EAAC,oOAAoO,GAAG,EACvP,eAAM,SAAS,EAAC,kLAAkL,GAAG,IAC/L,CACT,CACF,CAAA;AACD,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAA","sourcesContent":["import * as React from 'react'\nimport { cn } from './utils'\n\nexport type SwitchProps = React.InputHTMLAttributes<HTMLInputElement>\n\n/**\n * Switch — an accessible checkbox styled as a toggle. Pure CSS (peer), so it's\n * server-renderable and works controlled or uncontrolled. The knob stays light\n * in both themes by convention.\n */\nexport const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(\n ({ className, disabled, ...props }, ref) => (\n <label\n className={cn(\n 'relative inline-flex h-6 w-11 shrink-0 items-center',\n disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer',\n className,\n )}\n >\n <input ref={ref} type=\"checkbox\" role=\"switch\" className=\"peer sr-only\" disabled={disabled} {...props} />\n <span className=\"absolute inset-0 rounded-full bg-border-strong transition-colors duration-200 peer-checked:bg-primary peer-focus-visible:ring-2 peer-focus-visible:ring-ring/50 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-bg\" />\n <span className=\"pointer-events-none absolute left-0.5 size-5 rounded-full bg-white shadow-sm transition-transform duration-200 ease-out peer-checked:translate-x-5 motion-reduce:transition-none\" />\n </label>\n ),\n)\nSwitch.displayName = 'Switch'\n"]}
|
package/tab-content.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Wraps tab-panel content so swapping between tabs crossfades the outgoing
|
|
4
|
+
* panel out and the incoming panel in. The `tabKey` prop is the
|
|
5
|
+
* discriminator — when it changes, AnimatePresence runs the exit/enter
|
|
6
|
+
* choreography.
|
|
7
|
+
*
|
|
8
|
+
* Usage (inside a detail page that already renders the active tab body
|
|
9
|
+
* based on URL state):
|
|
10
|
+
*
|
|
11
|
+
* <TabContent tabKey={active}>
|
|
12
|
+
* {active === 'overview' ? <OverviewPanel/> : null}
|
|
13
|
+
* {active === 'history' ? <HistoryPanel/> : null}
|
|
14
|
+
* </TabContent>
|
|
15
|
+
*
|
|
16
|
+
* Reduced-motion users get an instant swap.
|
|
17
|
+
*/
|
|
18
|
+
export declare function TabContent({ tabKey, children, className, duration, }: {
|
|
19
|
+
tabKey: string;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
className?: string;
|
|
22
|
+
duration?: number;
|
|
23
|
+
}): React.JSX.Element;
|
|
24
|
+
//# sourceMappingURL=tab-content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab-content.d.ts","sourceRoot":"","sources":["../src/tab-content.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,QAAQ,EACR,SAAS,EACT,QAAe,GAChB,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,qBAgBA"}
|
package/tab-content.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { AnimatePresence, motion, useReducedMotion } from 'framer-motion';
|
|
5
|
+
import { cn } from './utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* Wraps tab-panel content so swapping between tabs crossfades the outgoing
|
|
8
|
+
* panel out and the incoming panel in. The `tabKey` prop is the
|
|
9
|
+
* discriminator — when it changes, AnimatePresence runs the exit/enter
|
|
10
|
+
* choreography.
|
|
11
|
+
*
|
|
12
|
+
* Usage (inside a detail page that already renders the active tab body
|
|
13
|
+
* based on URL state):
|
|
14
|
+
*
|
|
15
|
+
* <TabContent tabKey={active}>
|
|
16
|
+
* {active === 'overview' ? <OverviewPanel/> : null}
|
|
17
|
+
* {active === 'history' ? <HistoryPanel/> : null}
|
|
18
|
+
* </TabContent>
|
|
19
|
+
*
|
|
20
|
+
* Reduced-motion users get an instant swap.
|
|
21
|
+
*/
|
|
22
|
+
export function TabContent({ tabKey, children, className, duration = 0.18, }) {
|
|
23
|
+
const reduce = useReducedMotion();
|
|
24
|
+
return (_jsx(AnimatePresence, { mode: "wait", initial: false, children: _jsx(motion.div, { initial: reduce ? false : { opacity: 0, y: 4 }, animate: { opacity: 1, y: 0 }, exit: reduce ? { opacity: 1 } : { opacity: 0, y: -2 }, transition: { duration, ease: [0.22, 0.61, 0.36, 1] }, className: cn(className), children: children }, tabKey) }));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=tab-content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tab-content.js","sourceRoot":"","sources":["../src/tab-content.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACzE,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAE5B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,MAAM,EACN,QAAQ,EACR,SAAS,EACT,QAAQ,GAAG,IAAI,GAMhB;IACC,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAA;IACjC,OAAO,CACL,KAAC,eAAe,IAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAE,KAAK,YACzC,KAAC,MAAM,CAAC,GAAG,IAET,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC9C,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAC7B,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EACrD,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EACrD,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,YAEvB,QAAQ,IAPJ,MAAM,CAQA,GACG,CACnB,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport { cn } from './utils'\n\n/**\n * Wraps tab-panel content so swapping between tabs crossfades the outgoing\n * panel out and the incoming panel in. The `tabKey` prop is the\n * discriminator — when it changes, AnimatePresence runs the exit/enter\n * choreography.\n *\n * Usage (inside a detail page that already renders the active tab body\n * based on URL state):\n *\n * <TabContent tabKey={active}>\n * {active === 'overview' ? <OverviewPanel/> : null}\n * {active === 'history' ? <HistoryPanel/> : null}\n * </TabContent>\n *\n * Reduced-motion users get an instant swap.\n */\nexport function TabContent({\n tabKey,\n children,\n className,\n duration = 0.18,\n}: {\n tabKey: string\n children: React.ReactNode\n className?: string\n duration?: number\n}) {\n const reduce = useReducedMotion()\n return (\n <AnimatePresence mode=\"wait\" initial={false}>\n <motion.div\n key={tabKey}\n initial={reduce ? false : { opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={reduce ? { opacity: 1 } : { opacity: 0, y: -2 }}\n transition={{ duration, ease: [0.22, 0.61, 0.36, 1] }}\n className={cn(className)}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n )\n}\n\n"]}
|
package/table.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type TableProps = React.HTMLAttributes<HTMLTableElement> & {
|
|
3
|
+
/**
|
|
4
|
+
* Classes for the table's scrolling surface. Use this to remove the default
|
|
5
|
+
* card treatment when the table already lives inside a bordered workspace.
|
|
6
|
+
*/
|
|
7
|
+
containerClassName?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const Table: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableElement> & {
|
|
10
|
+
/**
|
|
11
|
+
* Classes for the table's scrolling surface. Use this to remove the default
|
|
12
|
+
* card treatment when the table already lives inside a bordered workspace.
|
|
13
|
+
*/
|
|
14
|
+
containerClassName?: string;
|
|
15
|
+
} & React.RefAttributes<HTMLTableElement>>;
|
|
16
|
+
export declare const TableHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
17
|
+
export declare const TableBody: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
18
|
+
export type TableRowProps = React.HTMLAttributes<HTMLTableRowElement> & {
|
|
19
|
+
/** Disable the staggered entrance (e.g. header rows). */
|
|
20
|
+
noAnimate?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export declare const TableRow: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableRowElement> & {
|
|
23
|
+
/** Disable the staggered entrance (e.g. header rows). */
|
|
24
|
+
noAnimate?: boolean;
|
|
25
|
+
} & React.RefAttributes<HTMLTableRowElement>>;
|
|
26
|
+
export declare const TableHead: React.ForwardRefExoticComponent<React.ThHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>;
|
|
27
|
+
export declare const TableCell: React.ForwardRefExoticComponent<React.TdHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>;
|
|
28
|
+
//# sourceMappingURL=table.d.ts.map
|
package/table.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../src/table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC,GAAG;IAChE;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AAED,eAAO,MAAM,KAAK;IAPhB;;;OAGG;yBACkB,MAAM;0CAc5B,CAAA;AAGD,eAAO,MAAM,WAAW,+HAYtB,CAAA;AAGF,eAAO,MAAM,SAAS,+HAKpB,CAAA;AAGF,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,mBAAmB,CAAC,GAAG;IACtE,yDAAyD;IACzD,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,QAAQ;IAJnB,yDAAyD;gBAC7C,OAAO;6CAkBpB,CAAA;AAGD,eAAO,MAAM,SAAS,2HAYpB,CAAA;AAGF,eAAO,MAAM,SAAS,2HAKpB,CAAA"}
|
package/table.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from './utils.js';
|
|
5
|
+
export const Table = React.forwardRef(({ className, containerClassName, ...props }, ref) => (_jsx("div", { className: cn('w-full overflow-x-auto rounded-lg border border-border bg-surface shadow-sm', containerClassName), children: _jsx("table", { ref: ref, className: cn('w-full caption-bottom text-sm', className), ...props }) })));
|
|
6
|
+
Table.displayName = 'Table';
|
|
7
|
+
export const TableHeader = React.forwardRef(({ className, ...props }, ref) => (_jsx("thead", { ref: ref, className: cn('sticky top-0 z-10 bg-bg-subtle/95 backdrop-blur-sm [&_tr]:border-b [&_tr]:border-border', className), ...props })));
|
|
8
|
+
TableHeader.displayName = 'TableHeader';
|
|
9
|
+
export const TableBody = React.forwardRef(({ className, ...props }, ref) => (_jsx("tbody", { ref: ref, className: cn('[&_tr:last-child]:border-0', className), ...props })));
|
|
10
|
+
TableBody.displayName = 'TableBody';
|
|
11
|
+
export const TableRow = React.forwardRef(({ className, noAnimate, ...props }, ref) => (
|
|
12
|
+
// Staggered entrance is pure CSS (`.appkit-row` + nth-child delay in
|
|
13
|
+
// tokens.css) — no JS index, so it's StrictMode- and hydration-safe, and
|
|
14
|
+
// visible-by-default (@starting-style) so it never strands in a hidden tab.
|
|
15
|
+
_jsx("tr", { ref: ref, className: cn('border-b border-border-subtle transition-colors duration-150 hover:bg-surface-hover data-[state=selected]:bg-bg-subtle', !noAnimate && 'appkit-row', className), ...props })));
|
|
16
|
+
TableRow.displayName = 'TableRow';
|
|
17
|
+
export const TableHead = React.forwardRef(({ className, ...props }, ref) => (_jsx("th", { ref: ref, className: cn('h-10 px-3 text-left align-middle text-xs font-medium tracking-wide text-fg-muted uppercase', className), ...props })));
|
|
18
|
+
TableHead.displayName = 'TableHead';
|
|
19
|
+
export const TableCell = React.forwardRef(({ className, ...props }, ref) => (_jsx("td", { ref: ref, className: cn('px-3 py-3 align-middle', className), ...props })));
|
|
20
|
+
TableCell.displayName = 'TableCell';
|
|
21
|
+
//# sourceMappingURL=table.js.map
|
package/table.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAU5B,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CACnC,CAAC,EAAE,SAAS,EAAE,kBAAkB,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACpD,cACE,SAAS,EAAE,EAAE,CACX,6EAA6E,EAC7E,kBAAkB,CACnB,YAED,gBAAO,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,+BAA+B,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,GACrF,CACP,CACF,CAAA;AACD,KAAK,CAAC,WAAW,GAAG,OAAO,CAAA;AAE3B,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAGzC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,gBACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,yFAAyF,EACzF,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC,CAAA;AACF,WAAW,CAAC,WAAW,GAAG,aAAa,CAAA;AAEvC,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAGvC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,gBAAO,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CACvF,CAAC,CAAA;AACF,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA;AAOnC,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CACtC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;AAC3C,qEAAqE;AACrE,yEAAyE;AACzE,4EAA4E;AAC5E,aACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,wHAAwH,EACxH,CAAC,SAAS,IAAI,YAAY,EAC1B,SAAS,CACV,KACG,KAAK,GACT,CACH,CACF,CAAA;AACD,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAA;AAEjC,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAGvC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,aACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,4FAA4F,EAC5F,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAC,CAAA;AACF,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA;AAEnC,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAGvC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAClC,aAAI,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,wBAAwB,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAChF,CAAC,CAAA;AACF,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { cn } from './utils'\n\nexport type TableProps = React.HTMLAttributes<HTMLTableElement> & {\n /**\n * Classes for the table's scrolling surface. Use this to remove the default\n * card treatment when the table already lives inside a bordered workspace.\n */\n containerClassName?: string\n}\n\nexport const Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, containerClassName, ...props }, ref) => (\n <div\n className={cn(\n 'w-full overflow-x-auto rounded-lg border border-border bg-surface shadow-sm',\n containerClassName,\n )}\n >\n <table ref={ref} className={cn('w-full caption-bottom text-sm', className)} {...props} />\n </div>\n ),\n)\nTable.displayName = 'Table'\n\nexport const TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead\n ref={ref}\n className={cn(\n 'sticky top-0 z-10 bg-bg-subtle/95 backdrop-blur-sm [&_tr]:border-b [&_tr]:border-border',\n className,\n )}\n {...props}\n />\n))\nTableHeader.displayName = 'TableHeader'\n\nexport const TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tbody ref={ref} className={cn('[&_tr:last-child]:border-0', className)} {...props} />\n))\nTableBody.displayName = 'TableBody'\n\nexport type TableRowProps = React.HTMLAttributes<HTMLTableRowElement> & {\n /** Disable the staggered entrance (e.g. header rows). */\n noAnimate?: boolean\n}\n\nexport const TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(\n ({ className, noAnimate, ...props }, ref) => (\n // Staggered entrance is pure CSS (`.appkit-row` + nth-child delay in\n // tokens.css) — no JS index, so it's StrictMode- and hydration-safe, and\n // visible-by-default (@starting-style) so it never strands in a hidden tab.\n <tr\n ref={ref}\n className={cn(\n 'border-b border-border-subtle transition-colors duration-150 hover:bg-surface-hover data-[state=selected]:bg-bg-subtle',\n !noAnimate && 'appkit-row',\n className,\n )}\n {...props}\n />\n ),\n)\nTableRow.displayName = 'TableRow'\n\nexport const TableHead = React.forwardRef<\n HTMLTableCellElement,\n React.ThHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <th\n ref={ref}\n className={cn(\n 'h-10 px-3 text-left align-middle text-xs font-medium tracking-wide text-fg-muted uppercase',\n className,\n )}\n {...props}\n />\n))\nTableHead.displayName = 'TableHead'\n\nexport const TableCell = React.forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement>\n>(({ className, ...props }, ref) => (\n <td ref={ref} className={cn('px-3 py-3 align-middle', className)} {...props} />\n))\nTableCell.displayName = 'TableCell'\n"]}
|
package/tabs.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type TabItem = {
|
|
3
|
+
value: string;
|
|
4
|
+
label: React.ReactNode;
|
|
5
|
+
};
|
|
6
|
+
export type TabsProps = {
|
|
7
|
+
tabs: TabItem[];
|
|
8
|
+
value: string;
|
|
9
|
+
onValueChange: (value: string) => void;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Tabs — a segmented control with a spring-animated active indicator that
|
|
14
|
+
* slides between options (framer `layoutId`). Reduced-motion falls back to an
|
|
15
|
+
* instant swap.
|
|
16
|
+
*/
|
|
17
|
+
export declare function Tabs({ tabs, value, onValueChange, className }: TabsProps): React.JSX.Element;
|
|
18
|
+
//# sourceMappingURL=tabs.d.ts.map
|
package/tabs.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../src/tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,MAAM,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAA;AAE/D,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,SAAS,qBAmCxE"}
|
package/tabs.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { motion } from 'framer-motion';
|
|
5
|
+
import { cn } from './utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* Tabs — a segmented control with a spring-animated active indicator that
|
|
8
|
+
* slides between options (framer `layoutId`). Reduced-motion falls back to an
|
|
9
|
+
* instant swap.
|
|
10
|
+
*/
|
|
11
|
+
export function Tabs({ tabs, value, onValueChange, className }) {
|
|
12
|
+
const id = React.useId();
|
|
13
|
+
return (_jsx("div", { role: "tablist", className: cn('inline-flex gap-1 rounded-lg border border-border bg-bg-subtle p-1', className), children: tabs.map((tab) => {
|
|
14
|
+
const active = tab.value === value;
|
|
15
|
+
return (_jsxs("button", { type: "button", role: "tab", "aria-selected": active, onClick: () => onValueChange(tab.value), className: cn('relative rounded-md px-3 py-1.5 text-sm font-medium transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50', active ? 'text-fg' : 'text-fg-muted hover:text-fg'), children: [active ? (_jsx(motion.span, { layoutId: `appkit-tab-${id}`, className: "absolute inset-0 rounded-md bg-surface shadow-sm", transition: { type: 'spring', damping: 30, stiffness: 400 } })) : null, _jsx("span", { className: "relative z-10", children: tab.label })] }, tab.value));
|
|
16
|
+
}) }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=tabs.js.map
|
package/tabs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../src/tabs.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAW5B;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAa;IACvE,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAA;IACxB,OAAO,CACL,cACE,IAAI,EAAC,SAAS,EACd,SAAS,EAAE,EAAE,CAAC,oEAAoE,EAAE,SAAS,CAAC,YAE7F,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAChB,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,KAAK,KAAK,CAAA;YAClC,OAAO,CACL,kBAEE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,MAAM,EACrB,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EACvC,SAAS,EAAE,EAAE,CACX,uEAAuE,EACvE,4EAA4E,EAC5E,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,6BAA6B,CACnD,aAEA,MAAM,CAAC,CAAC,CAAC,CACR,KAAC,MAAM,CAAC,IAAI,IACV,QAAQ,EAAE,cAAc,EAAE,EAAE,EAC5B,SAAS,EAAC,kDAAkD,EAC5D,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,GAC3D,CACH,CAAC,CAAC,CAAC,IAAI,EACR,eAAM,SAAS,EAAC,eAAe,YAAE,GAAG,CAAC,KAAK,GAAQ,KAlB7C,GAAG,CAAC,KAAK,CAmBP,CACV,CAAA;QACH,CAAC,CAAC,GACE,CACP,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { cn } from './utils'\n\nexport type TabItem = { value: string; label: React.ReactNode }\n\nexport type TabsProps = {\n tabs: TabItem[]\n value: string\n onValueChange: (value: string) => void\n className?: string\n}\n\n/**\n * Tabs — a segmented control with a spring-animated active indicator that\n * slides between options (framer `layoutId`). Reduced-motion falls back to an\n * instant swap.\n */\nexport function Tabs({ tabs, value, onValueChange, className }: TabsProps) {\n const id = React.useId()\n return (\n <div\n role=\"tablist\"\n className={cn('inline-flex gap-1 rounded-lg border border-border bg-bg-subtle p-1', className)}\n >\n {tabs.map((tab) => {\n const active = tab.value === value\n return (\n <button\n key={tab.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => onValueChange(tab.value)}\n className={cn(\n 'relative rounded-md px-3 py-1.5 text-sm font-medium transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50',\n active ? 'text-fg' : 'text-fg-muted hover:text-fg',\n )}\n >\n {active ? (\n <motion.span\n layoutId={`appkit-tab-${id}`}\n className=\"absolute inset-0 rounded-md bg-surface shadow-sm\"\n transition={{ type: 'spring', damping: 30, stiffness: 400 }}\n />\n ) : null}\n <span className=\"relative z-10\">{tab.label}</span>\n </button>\n )\n })}\n </div>\n )\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export type UiTextTranslator = (value: string, values?: Readonly<Record<string, unknown>>) => string;
|
|
3
|
+
/** Injects the host application's exact-copy translator into framework-agnostic UI primitives. */
|
|
4
|
+
export declare function UiTextProvider({ translate, children, }: {
|
|
5
|
+
translate: UiTextTranslator;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
export declare function useUiText(): UiTextTranslator;
|
|
9
|
+
//# sourceMappingURL=text-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-context.d.ts","sourceRoot":"","sources":["../src/text-context.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjE,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,MAAM,CAAA;AAIpG,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,EAAE,gBAAgB,CAAA;IAC3B,QAAQ,EAAE,SAAS,CAAA;CACpB,+BAEA;AAED,wBAAgB,SAAS,IAAI,gBAAgB,CAE5C"}
|
package/text-context.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext } from 'react';
|
|
4
|
+
const UiTextContext = createContext((value) => value);
|
|
5
|
+
/** Injects the host application's exact-copy translator into framework-agnostic UI primitives. */
|
|
6
|
+
export function UiTextProvider({ translate, children, }) {
|
|
7
|
+
return _jsx(UiTextContext.Provider, { value: translate, children: children });
|
|
8
|
+
}
|
|
9
|
+
export function useUiText() {
|
|
10
|
+
return useContext(UiTextContext);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=text-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-context.js","sourceRoot":"","sources":["../src/text-context.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,OAAO,CAAA;AAIjE,MAAM,aAAa,GAAG,aAAa,CAAmB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAA;AAEvE,kGAAkG;AAClG,MAAM,UAAU,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,GAIT;IACC,OAAO,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,SAAS,YAAG,QAAQ,GAA0B,CAAA;AACtF,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,UAAU,CAAC,aAAa,CAAC,CAAA;AAClC,CAAC","sourcesContent":["'use client'\n\nimport { createContext, useContext, type ReactNode } from 'react'\n\nexport type UiTextTranslator = (value: string, values?: Readonly<Record<string, unknown>>) => string\n\nconst UiTextContext = createContext<UiTextTranslator>((value) => value)\n\n/** Injects the host application's exact-copy translator into framework-agnostic UI primitives. */\nexport function UiTextProvider({\n translate,\n children,\n}: {\n translate: UiTextTranslator\n children: ReactNode\n}) {\n return <UiTextContext.Provider value={translate}>{children}</UiTextContext.Provider>\n}\n\nexport function useUiText(): UiTextTranslator {\n return useContext(UiTextContext)\n}\n\n"]}
|
package/textarea.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;
|
|
3
|
+
export declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
4
|
+
//# sourceMappingURL=textarea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../src/textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,CAAA;AAE7E,eAAO,MAAM,QAAQ,2FAepB,CAAA"}
|
package/textarea.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { cn } from './utils.js';
|
|
4
|
+
export const Textarea = React.forwardRef(({ className, ...props }, ref) => (_jsx("textarea", { ref: ref, className: cn('flex min-h-20 w-full rounded-md border border-border bg-surface px-3 py-2 text-base text-fg placeholder:text-fg-subtle sm:text-sm', 'transition-shadow duration-150 ease-out', 'focus-visible:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40', 'disabled:cursor-not-allowed disabled:bg-bg-subtle disabled:opacity-50', 'aria-[invalid=true]:border-danger aria-[invalid=true]:focus-visible:ring-danger/30', className), ...props })));
|
|
5
|
+
Textarea.displayName = 'Textarea';
|
|
6
|
+
//# sourceMappingURL=textarea.js.map
|
package/textarea.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.js","sourceRoot":"","sources":["../src/textarea.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAI5B,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CACtC,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAChC,mBACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CACX,mIAAmI,EACnI,yCAAyC,EACzC,yGAAyG,EACzG,uEAAuE,EACvE,oFAAoF,EACpF,SAAS,CACV,KACG,KAAK,GACT,CACH,CACF,CAAA;AACD,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAA","sourcesContent":["import * as React from 'react'\nimport { cn } from './utils'\n\nexport type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>\n\nexport const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => (\n <textarea\n ref={ref}\n className={cn(\n 'flex min-h-20 w-full rounded-md border border-border bg-surface px-3 py-2 text-base text-fg placeholder:text-fg-subtle sm:text-sm',\n 'transition-shadow duration-150 ease-out',\n 'focus-visible:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40',\n 'disabled:cursor-not-allowed disabled:bg-bg-subtle disabled:opacity-50',\n 'aria-[invalid=true]:border-danger aria-[invalid=true]:focus-visible:ring-danger/30',\n className,\n )}\n {...props}\n />\n ),\n)\nTextarea.displayName = 'Textarea'\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-script.d.ts","sourceRoot":"","sources":["../src/theme-script.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,UAAU,SAAU,GAAG,MAAM,CAG3D"}
|
package/theme-script.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Script body for a framework's pre-hydration script facility (for example next/script). */
|
|
2
|
+
export function getThemeScript(storageKey = 'theme') {
|
|
3
|
+
const key = JSON.stringify(storageKey).replaceAll('<', '\\u003c');
|
|
4
|
+
return `(function(){try{var t=localStorage.getItem(${key});var d=document.documentElement;d.classList.toggle('dark',t==='dark');d.classList.toggle('light',t==='light')}catch(_){}})()`;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=theme-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-script.js","sourceRoot":"","sources":["../src/theme-script.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAAC,UAAU,GAAG,OAAO;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IACjE,OAAO,8CAA8C,GAAG,+HAA+H,CAAA;AACzL,CAAC","sourcesContent":["/** Script body for a framework's pre-hydration script facility (for example next/script). */\nexport function getThemeScript(storageKey = 'theme'): string {\n const key = JSON.stringify(storageKey).replaceAll('<', '\\\\u003c')\n return `(function(){try{var t=localStorage.getItem(${key});var d=document.documentElement;d.classList.toggle('dark',t==='dark');d.classList.toggle('light',t==='light')}catch(_){}})()`\n}\n"]}
|