@thewhateverapp/tile-sdk 0.13.31 → 0.13.33
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/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/spec/host/OverlayHost.d.ts +68 -0
- package/dist/spec/host/OverlayHost.d.ts.map +1 -0
- package/dist/spec/host/OverlayHost.js +143 -0
- package/dist/spec/host/index.d.ts +7 -0
- package/dist/spec/host/index.d.ts.map +1 -0
- package/dist/spec/host/index.js +6 -0
- package/dist/spec/index.d.ts +29 -0
- package/dist/spec/index.d.ts.map +1 -0
- package/dist/spec/index.js +81 -0
- package/dist/spec/registry/ComponentRegistry.d.ts +208 -0
- package/dist/spec/registry/ComponentRegistry.d.ts.map +1 -0
- package/dist/spec/registry/ComponentRegistry.js +227 -0
- package/dist/spec/registry/composites/BottomSheet.d.ts +33 -0
- package/dist/spec/registry/composites/BottomSheet.d.ts.map +1 -0
- package/dist/spec/registry/composites/BottomSheet.js +98 -0
- package/dist/spec/registry/composites/CountdownCTA.d.ts +35 -0
- package/dist/spec/registry/composites/CountdownCTA.d.ts.map +1 -0
- package/dist/spec/registry/composites/CountdownCTA.js +91 -0
- package/dist/spec/registry/composites/Poll.d.ts +39 -0
- package/dist/spec/registry/composites/Poll.d.ts.map +1 -0
- package/dist/spec/registry/composites/Poll.js +76 -0
- package/dist/spec/registry/composites/Prediction.d.ts +37 -0
- package/dist/spec/registry/composites/Prediction.d.ts.map +1 -0
- package/dist/spec/registry/composites/Prediction.js +116 -0
- package/dist/spec/registry/composites/index.d.ts +33 -0
- package/dist/spec/registry/composites/index.d.ts.map +1 -0
- package/dist/spec/registry/composites/index.js +36 -0
- package/dist/spec/registry/index.d.ts +15 -0
- package/dist/spec/registry/index.d.ts.map +1 -0
- package/dist/spec/registry/index.js +24 -0
- package/dist/spec/registry/primitives/Button.d.ts +30 -0
- package/dist/spec/registry/primitives/Button.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Button.js +62 -0
- package/dist/spec/registry/primitives/Divider.d.ts +22 -0
- package/dist/spec/registry/primitives/Divider.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Divider.js +56 -0
- package/dist/spec/registry/primitives/Image.d.ts +27 -0
- package/dist/spec/registry/primitives/Image.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Image.js +36 -0
- package/dist/spec/registry/primitives/ProgressBar.d.ts +28 -0
- package/dist/spec/registry/primitives/ProgressBar.d.ts.map +1 -0
- package/dist/spec/registry/primitives/ProgressBar.js +50 -0
- package/dist/spec/registry/primitives/Row.d.ts +26 -0
- package/dist/spec/registry/primitives/Row.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Row.js +50 -0
- package/dist/spec/registry/primitives/Spacer.d.ts +18 -0
- package/dist/spec/registry/primitives/Spacer.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Spacer.js +25 -0
- package/dist/spec/registry/primitives/Stack.d.ts +22 -0
- package/dist/spec/registry/primitives/Stack.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Stack.js +41 -0
- package/dist/spec/registry/primitives/Text.d.ts +26 -0
- package/dist/spec/registry/primitives/Text.d.ts.map +1 -0
- package/dist/spec/registry/primitives/Text.js +33 -0
- package/dist/spec/registry/primitives/index.d.ts +45 -0
- package/dist/spec/registry/primitives/index.d.ts.map +1 -0
- package/dist/spec/registry/primitives/index.js +55 -0
- package/dist/spec/renderer/BindingResolver.d.ts +35 -0
- package/dist/spec/renderer/BindingResolver.d.ts.map +1 -0
- package/dist/spec/renderer/BindingResolver.js +131 -0
- package/dist/spec/renderer/CaptionTrack.d.ts +22 -0
- package/dist/spec/renderer/CaptionTrack.d.ts.map +1 -0
- package/dist/spec/renderer/CaptionTrack.js +83 -0
- package/dist/spec/renderer/LayoutRenderer.d.ts +24 -0
- package/dist/spec/renderer/LayoutRenderer.d.ts.map +1 -0
- package/dist/spec/renderer/LayoutRenderer.js +66 -0
- package/dist/spec/renderer/OverlayCue.d.ts +20 -0
- package/dist/spec/renderer/OverlayCue.d.ts.map +1 -0
- package/dist/spec/renderer/OverlayCue.js +161 -0
- package/dist/spec/renderer/index.d.ts +10 -0
- package/dist/spec/renderer/index.d.ts.map +1 -0
- package/dist/spec/renderer/index.js +13 -0
- package/dist/spec/runtime/ActionRouter.d.ts +33 -0
- package/dist/spec/runtime/ActionRouter.d.ts.map +1 -0
- package/dist/spec/runtime/ActionRouter.js +84 -0
- package/dist/spec/runtime/OverlayRuntime.d.ts +84 -0
- package/dist/spec/runtime/OverlayRuntime.d.ts.map +1 -0
- package/dist/spec/runtime/OverlayRuntime.js +216 -0
- package/dist/spec/runtime/StateManager.d.ts +31 -0
- package/dist/spec/runtime/StateManager.d.ts.map +1 -0
- package/dist/spec/runtime/StateManager.js +60 -0
- package/dist/spec/runtime/TimeSync.d.ts +47 -0
- package/dist/spec/runtime/TimeSync.d.ts.map +1 -0
- package/dist/spec/runtime/TimeSync.js +140 -0
- package/dist/spec/runtime/index.d.ts +10 -0
- package/dist/spec/runtime/index.d.ts.map +1 -0
- package/dist/spec/runtime/index.js +13 -0
- package/dist/spec/schema.d.ts +889 -0
- package/dist/spec/schema.d.ts.map +1 -0
- package/dist/spec/schema.js +284 -0
- package/dist/spec/theme/ThemeProvider.d.ts +151 -0
- package/dist/spec/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/spec/theme/ThemeProvider.js +227 -0
- package/dist/spec/theme/index.d.ts +7 -0
- package/dist/spec/theme/index.d.ts.map +1 -0
- package/dist/spec/theme/index.js +12 -0
- package/dist/spec/types.d.ts +322 -0
- package/dist/spec/types.d.ts.map +1 -0
- package/dist/spec/types.js +36 -0
- package/package.json +8 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prediction Component
|
|
3
|
+
*
|
|
4
|
+
* Binary choice prediction with countdown and outcome reveal.
|
|
5
|
+
*/
|
|
6
|
+
import React, { useState, useCallback, useEffect } from 'react';
|
|
7
|
+
const colorClasses = {
|
|
8
|
+
primary: { bg: 'bg-purple-500', hover: 'hover:bg-purple-600', ring: 'ring-purple-500' },
|
|
9
|
+
secondary: { bg: 'bg-gray-500', hover: 'hover:bg-gray-600', ring: 'ring-gray-500' },
|
|
10
|
+
success: { bg: 'bg-green-500', hover: 'hover:bg-green-600', ring: 'ring-green-500' },
|
|
11
|
+
warning: { bg: 'bg-yellow-500', hover: 'hover:bg-yellow-600', ring: 'ring-yellow-500' },
|
|
12
|
+
error: { bg: 'bg-red-500', hover: 'hover:bg-red-600', ring: 'ring-red-500' },
|
|
13
|
+
muted: { bg: 'bg-gray-400', hover: 'hover:bg-gray-500', ring: 'ring-gray-400' },
|
|
14
|
+
white: { bg: 'bg-white', hover: 'hover:bg-gray-100', ring: 'ring-white' },
|
|
15
|
+
black: { bg: 'bg-black', hover: 'hover:bg-gray-900', ring: 'ring-black' },
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Normalizes options to a consistent format.
|
|
19
|
+
*/
|
|
20
|
+
function normalizeOptions(options) {
|
|
21
|
+
return options.map((opt, index) => {
|
|
22
|
+
if (typeof opt === 'string') {
|
|
23
|
+
return { id: String(index), label: opt };
|
|
24
|
+
}
|
|
25
|
+
return opt;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Formats remaining time.
|
|
30
|
+
*/
|
|
31
|
+
function formatTimeRemaining(ms) {
|
|
32
|
+
if (ms <= 0)
|
|
33
|
+
return '0:00';
|
|
34
|
+
const seconds = Math.floor(ms / 1000);
|
|
35
|
+
const minutes = Math.floor(seconds / 60);
|
|
36
|
+
const hours = Math.floor(minutes / 60);
|
|
37
|
+
if (hours > 0) {
|
|
38
|
+
return `${hours}:${String(minutes % 60).padStart(2, '0')}:${String(seconds % 60).padStart(2, '0')}`;
|
|
39
|
+
}
|
|
40
|
+
return `${minutes}:${String(seconds % 60).padStart(2, '0')}`;
|
|
41
|
+
}
|
|
42
|
+
export function Prediction({ question, options: rawOptions, status = 'open', winnerId, userPredictionId, locksAt, onPredict, colors = ['primary', 'error'], className = '', }) {
|
|
43
|
+
const [selectedId, setSelectedId] = useState(null);
|
|
44
|
+
const [timeRemaining, setTimeRemaining] = useState(null);
|
|
45
|
+
const options = normalizeOptions(rawOptions);
|
|
46
|
+
// Countdown timer
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (!locksAt || status !== 'open') {
|
|
49
|
+
setTimeRemaining(null);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const endTime = typeof locksAt === 'string' ? new Date(locksAt).getTime() : locksAt;
|
|
53
|
+
const update = () => {
|
|
54
|
+
const remaining = endTime - Date.now();
|
|
55
|
+
setTimeRemaining(remaining > 0 ? remaining : 0);
|
|
56
|
+
};
|
|
57
|
+
update();
|
|
58
|
+
const interval = setInterval(update, 1000);
|
|
59
|
+
return () => clearInterval(interval);
|
|
60
|
+
}, [locksAt, status]);
|
|
61
|
+
// Handle option click
|
|
62
|
+
const handleOptionClick = useCallback((optionId) => {
|
|
63
|
+
if (status !== 'open' || userPredictionId)
|
|
64
|
+
return;
|
|
65
|
+
setSelectedId(optionId);
|
|
66
|
+
onPredict?.(optionId);
|
|
67
|
+
}, [status, userPredictionId, onPredict]);
|
|
68
|
+
const isOpen = status === 'open';
|
|
69
|
+
const isLocked = status === 'locked';
|
|
70
|
+
const isResolved = status === 'resolved';
|
|
71
|
+
const hasPredicted = !!userPredictionId;
|
|
72
|
+
return (React.createElement("div", { className: `prediction-component bg-gray-800/90 backdrop-blur rounded-xl p-4 ${className}` },
|
|
73
|
+
React.createElement("div", { className: "flex items-center justify-between mb-2" },
|
|
74
|
+
React.createElement("span", { className: `
|
|
75
|
+
text-xs font-medium px-2 py-0.5 rounded-full
|
|
76
|
+
${isOpen ? 'bg-green-500/20 text-green-400' : ''}
|
|
77
|
+
${isLocked ? 'bg-yellow-500/20 text-yellow-400' : ''}
|
|
78
|
+
${isResolved ? 'bg-purple-500/20 text-purple-400' : ''}
|
|
79
|
+
` },
|
|
80
|
+
isOpen && 'OPEN',
|
|
81
|
+
isLocked && 'LOCKED',
|
|
82
|
+
isResolved && 'RESOLVED'),
|
|
83
|
+
timeRemaining !== null && timeRemaining > 0 && (React.createElement("span", { className: "text-gray-400 text-sm" }, formatTimeRemaining(timeRemaining)))),
|
|
84
|
+
React.createElement("h3", { className: "text-white font-semibold mb-4" }, question),
|
|
85
|
+
React.createElement("div", { className: "flex gap-2" }, options.map((option, index) => {
|
|
86
|
+
const color = colors[index];
|
|
87
|
+
const colorStyle = colorClasses[color];
|
|
88
|
+
const isSelected = option.id === selectedId;
|
|
89
|
+
const isUserPrediction = option.id === userPredictionId;
|
|
90
|
+
const isWinner = option.id === winnerId;
|
|
91
|
+
const canClick = isOpen && !hasPredicted;
|
|
92
|
+
return (React.createElement("button", { key: option.id, onClick: () => handleOptionClick(option.id), disabled: !canClick, className: `
|
|
93
|
+
flex-1 py-3 px-4 rounded-lg font-medium text-white
|
|
94
|
+
transition-all duration-200
|
|
95
|
+
${canClick ? `${colorStyle.bg} ${colorStyle.hover}` : 'bg-gray-700'}
|
|
96
|
+
${isSelected || isUserPrediction ? `ring-2 ${colorStyle.ring}` : ''}
|
|
97
|
+
${isWinner ? 'ring-2 ring-green-400' : ''}
|
|
98
|
+
${isResolved && !isWinner ? 'opacity-50' : ''}
|
|
99
|
+
` },
|
|
100
|
+
React.createElement("div", { className: "text-center" },
|
|
101
|
+
React.createElement("div", { className: "font-semibold" }, option.label),
|
|
102
|
+
option.percentage !== undefined && (React.createElement("div", { className: "text-sm opacity-80 mt-1" },
|
|
103
|
+
Math.round(option.percentage),
|
|
104
|
+
"%")),
|
|
105
|
+
option.odds !== undefined && (React.createElement("div", { className: "text-xs opacity-60 mt-0.5" },
|
|
106
|
+
option.odds.toFixed(2),
|
|
107
|
+
"x"))),
|
|
108
|
+
isUserPrediction && (React.createElement("div", { className: "text-xs mt-2 opacity-80" }, "Your pick")),
|
|
109
|
+
isWinner && isResolved && (React.createElement("div", { className: "text-xs mt-2 text-green-300" }, "Winner!"))));
|
|
110
|
+
})),
|
|
111
|
+
isResolved && userPredictionId && (React.createElement("div", { className: `
|
|
112
|
+
mt-3 text-center text-sm font-medium
|
|
113
|
+
${userPredictionId === winnerId ? 'text-green-400' : 'text-red-400'}
|
|
114
|
+
` }, userPredictionId === winnerId ? 'You predicted correctly!' : 'Better luck next time!'))));
|
|
115
|
+
}
|
|
116
|
+
export default Prediction;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composite Components Index
|
|
3
|
+
*
|
|
4
|
+
* Exports all composite components and registers them with the global registry.
|
|
5
|
+
*/
|
|
6
|
+
import { type PollProps } from './Poll';
|
|
7
|
+
import { type PredictionProps } from './Prediction';
|
|
8
|
+
import { type CountdownCTAProps } from './CountdownCTA';
|
|
9
|
+
import { type BottomSheetProps } from './BottomSheet';
|
|
10
|
+
export { Poll, type PollProps, type PollOption } from './Poll';
|
|
11
|
+
export { Prediction, type PredictionProps, type PredictionOption, type PredictionStatus } from './Prediction';
|
|
12
|
+
export { CountdownCTA, type CountdownCTAProps } from './CountdownCTA';
|
|
13
|
+
export { BottomSheet, type BottomSheetProps } from './BottomSheet';
|
|
14
|
+
/**
|
|
15
|
+
* Register all composite components with the global registry.
|
|
16
|
+
* This function should be called once at app initialization.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerComposites(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Component type to props mapping for type safety
|
|
21
|
+
*/
|
|
22
|
+
export interface CompositePropsMap {
|
|
23
|
+
'ui.poll': PollProps;
|
|
24
|
+
'ui.prediction': PredictionProps;
|
|
25
|
+
'ui.countdown': CountdownCTAProps;
|
|
26
|
+
'ui.bottomSheet': BottomSheetProps;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* All composite component type IDs
|
|
30
|
+
*/
|
|
31
|
+
export declare const COMPOSITE_TYPES: readonly ["ui.poll", "ui.prediction", "ui.countdown", "ui.bottomSheet"];
|
|
32
|
+
export type CompositeType = (typeof COMPOSITE_TYPES)[number];
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/spec/registry/composites/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAQ,KAAK,SAAS,EAAmB,MAAM,QAAQ,CAAC;AAC/D,OAAO,EAAc,KAAK,eAAe,EAAgD,MAAM,cAAc,CAAC;AAC9G,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGnE,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9G,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEnE;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,eAAe,CAAC;IACjC,cAAc,EAAE,iBAAiB,CAAC;IAClC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,yEAKlB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composite Components Index
|
|
3
|
+
*
|
|
4
|
+
* Exports all composite components and registers them with the global registry.
|
|
5
|
+
*/
|
|
6
|
+
import { registerComponent } from '../ComponentRegistry';
|
|
7
|
+
// Import all composites
|
|
8
|
+
import { Poll } from './Poll';
|
|
9
|
+
import { Prediction } from './Prediction';
|
|
10
|
+
import { CountdownCTA } from './CountdownCTA';
|
|
11
|
+
import { BottomSheet } from './BottomSheet';
|
|
12
|
+
// Re-export components
|
|
13
|
+
export { Poll } from './Poll';
|
|
14
|
+
export { Prediction } from './Prediction';
|
|
15
|
+
export { CountdownCTA } from './CountdownCTA';
|
|
16
|
+
export { BottomSheet } from './BottomSheet';
|
|
17
|
+
/**
|
|
18
|
+
* Register all composite components with the global registry.
|
|
19
|
+
* This function should be called once at app initialization.
|
|
20
|
+
*/
|
|
21
|
+
export function registerComposites() {
|
|
22
|
+
// Interactive composites
|
|
23
|
+
registerComponent('ui.poll', Poll);
|
|
24
|
+
registerComponent('ui.prediction', Prediction);
|
|
25
|
+
registerComponent('ui.countdown', CountdownCTA);
|
|
26
|
+
registerComponent('ui.bottomSheet', BottomSheet);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* All composite component type IDs
|
|
30
|
+
*/
|
|
31
|
+
export const COMPOSITE_TYPES = [
|
|
32
|
+
'ui.poll',
|
|
33
|
+
'ui.prediction',
|
|
34
|
+
'ui.countdown',
|
|
35
|
+
'ui.bottomSheet',
|
|
36
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Registry Index
|
|
3
|
+
*
|
|
4
|
+
* Exports registry utilities and all component categories.
|
|
5
|
+
*/
|
|
6
|
+
export { ComponentRegistry, globalRegistry, registerComponent, getComponent, hasComponent, getAllComponentIds, type RegistryComponentProps, type ComponentWithAction, } from './ComponentRegistry';
|
|
7
|
+
export { sizeClasses, colorClasses, weightClasses, alignClasses, justifyClasses, paddingClasses, gapClasses, } from './ComponentRegistry';
|
|
8
|
+
export * from './primitives';
|
|
9
|
+
export * from './composites';
|
|
10
|
+
/**
|
|
11
|
+
* Register all components (primitives + composites) with the global registry.
|
|
12
|
+
* This function should be called once at app initialization.
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerAllComponents(): void;
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/spec/registry/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,UAAU,GACX,MAAM,qBAAqB,CAAC;AAG7B,cAAc,cAAc,CAAC;AAG7B,cAAc,cAAc,CAAC;AAM7B;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Registry Index
|
|
3
|
+
*
|
|
4
|
+
* Exports registry utilities and all component categories.
|
|
5
|
+
*/
|
|
6
|
+
// Core registry
|
|
7
|
+
export { ComponentRegistry, globalRegistry, registerComponent, getComponent, hasComponent, getAllComponentIds, } from './ComponentRegistry';
|
|
8
|
+
// Design tokens
|
|
9
|
+
export { sizeClasses, colorClasses, weightClasses, alignClasses, justifyClasses, paddingClasses, gapClasses, } from './ComponentRegistry';
|
|
10
|
+
// Primitives
|
|
11
|
+
export * from './primitives';
|
|
12
|
+
// Composites
|
|
13
|
+
export * from './composites';
|
|
14
|
+
// Import for combined registration
|
|
15
|
+
import { registerPrimitives } from './primitives';
|
|
16
|
+
import { registerComposites } from './composites';
|
|
17
|
+
/**
|
|
18
|
+
* Register all components (primitives + composites) with the global registry.
|
|
19
|
+
* This function should be called once at app initialization.
|
|
20
|
+
*/
|
|
21
|
+
export function registerAllComponents() {
|
|
22
|
+
registerPrimitives();
|
|
23
|
+
registerComposites();
|
|
24
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Button Component
|
|
3
|
+
*
|
|
4
|
+
* Interactive button with variant styling and action support.
|
|
5
|
+
*/
|
|
6
|
+
import type { RegistryComponentProps } from '../ComponentRegistry';
|
|
7
|
+
import type { Size, Variant, Action } from '../../types';
|
|
8
|
+
export interface ButtonProps extends RegistryComponentProps {
|
|
9
|
+
/** Button label */
|
|
10
|
+
label: string;
|
|
11
|
+
/** Button variant */
|
|
12
|
+
variant?: Variant;
|
|
13
|
+
/** Button size */
|
|
14
|
+
size?: Size;
|
|
15
|
+
/** Disabled state */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Full width */
|
|
18
|
+
fullWidth?: boolean;
|
|
19
|
+
/** Icon (left side) */
|
|
20
|
+
icon?: string;
|
|
21
|
+
/** Loading state */
|
|
22
|
+
loading?: boolean;
|
|
23
|
+
/** Action to trigger on press */
|
|
24
|
+
onPress?: Action;
|
|
25
|
+
/** Additional CSS classes */
|
|
26
|
+
className?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function Button({ label, variant, size, disabled, fullWidth, icon, loading, onPress, onAction, className, }: ButtonProps): JSX.Element;
|
|
29
|
+
export default Button;
|
|
30
|
+
//# sourceMappingURL=Button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../../src/spec/registry/primitives/Button.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,WAAY,SAAQ,sBAAsB;IACzD,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IAEd,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,kBAAkB;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IAEZ,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,iBAAiB;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8BD,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,OAAiB,EACjB,IAAW,EACX,QAAgB,EAChB,SAAiB,EACjB,IAAI,EACJ,OAAe,EACf,OAAO,EACP,QAAQ,EACR,SAAc,GACf,EAAE,WAAW,GAAG,GAAG,CAAC,OAAO,CA2D3B;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Button Component
|
|
3
|
+
*
|
|
4
|
+
* Interactive button with variant styling and action support.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
const sizeStyles = {
|
|
8
|
+
xs: 'px-2 py-1 text-xs',
|
|
9
|
+
sm: 'px-3 py-1.5 text-sm',
|
|
10
|
+
md: 'px-4 py-2 text-base',
|
|
11
|
+
lg: 'px-6 py-3 text-lg',
|
|
12
|
+
xl: 'px-8 py-4 text-xl',
|
|
13
|
+
'2xl': 'px-10 py-5 text-2xl',
|
|
14
|
+
};
|
|
15
|
+
const variantStyles = {
|
|
16
|
+
solid: {
|
|
17
|
+
base: 'bg-purple-500 text-white hover:bg-purple-600 active:bg-purple-700',
|
|
18
|
+
disabled: 'bg-gray-600 text-gray-400 cursor-not-allowed',
|
|
19
|
+
},
|
|
20
|
+
outline: {
|
|
21
|
+
base: 'border-2 border-purple-500 text-purple-500 hover:bg-purple-500/10 active:bg-purple-500/20',
|
|
22
|
+
disabled: 'border-gray-500 text-gray-500 cursor-not-allowed',
|
|
23
|
+
},
|
|
24
|
+
ghost: {
|
|
25
|
+
base: 'text-purple-500 hover:bg-purple-500/10 active:bg-purple-500/20',
|
|
26
|
+
disabled: 'text-gray-500 cursor-not-allowed',
|
|
27
|
+
},
|
|
28
|
+
link: {
|
|
29
|
+
base: 'text-purple-500 underline hover:text-purple-400',
|
|
30
|
+
disabled: 'text-gray-500 cursor-not-allowed no-underline',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
export function Button({ label, variant = 'solid', size = 'md', disabled = false, fullWidth = false, icon, loading = false, onPress, onAction, className = '', }) {
|
|
34
|
+
const isDisabled = disabled || loading;
|
|
35
|
+
const handleClick = () => {
|
|
36
|
+
if (isDisabled)
|
|
37
|
+
return;
|
|
38
|
+
if (onPress && onAction) {
|
|
39
|
+
onAction(onPress);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const variantStyle = variantStyles[variant];
|
|
43
|
+
const classes = [
|
|
44
|
+
'inline-flex items-center justify-center',
|
|
45
|
+
'rounded-lg font-medium',
|
|
46
|
+
'transition-colors duration-150',
|
|
47
|
+
'focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 focus:ring-offset-black',
|
|
48
|
+
sizeStyles[size],
|
|
49
|
+
isDisabled ? variantStyle.disabled : variantStyle.base,
|
|
50
|
+
fullWidth ? 'w-full' : '',
|
|
51
|
+
className,
|
|
52
|
+
]
|
|
53
|
+
.filter(Boolean)
|
|
54
|
+
.join(' ');
|
|
55
|
+
return (React.createElement("button", { type: "button", className: classes, onClick: handleClick, disabled: isDisabled, "aria-disabled": isDisabled },
|
|
56
|
+
loading && (React.createElement("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" },
|
|
57
|
+
React.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
58
|
+
React.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }))),
|
|
59
|
+
icon && !loading && React.createElement("span", { className: "mr-2" }, icon),
|
|
60
|
+
label));
|
|
61
|
+
}
|
|
62
|
+
export default Button;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider Component
|
|
3
|
+
*
|
|
4
|
+
* Horizontal or vertical divider line.
|
|
5
|
+
*/
|
|
6
|
+
import type { RegistryComponentProps } from '../ComponentRegistry';
|
|
7
|
+
import type { Color } from '../../types';
|
|
8
|
+
export interface DividerProps extends RegistryComponentProps {
|
|
9
|
+
/** Divider orientation */
|
|
10
|
+
orientation?: 'horizontal' | 'vertical';
|
|
11
|
+
/** Line color */
|
|
12
|
+
color?: Color;
|
|
13
|
+
/** Line thickness */
|
|
14
|
+
thickness?: 'thin' | 'medium' | 'thick';
|
|
15
|
+
/** Spacing around divider */
|
|
16
|
+
spacing?: 'none' | 'sm' | 'md' | 'lg';
|
|
17
|
+
/** Additional CSS classes */
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function Divider({ orientation, color, thickness, spacing, className, }: DividerProps): JSX.Element;
|
|
21
|
+
export default Divider;
|
|
22
|
+
//# sourceMappingURL=Divider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Divider.d.ts","sourceRoot":"","sources":["../../../../src/spec/registry/primitives/Divider.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,YAAa,SAAQ,sBAAsB;IAC1D,0BAA0B;IAC1B,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IAExC,iBAAiB;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAExC,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAEtC,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAyCD,wBAAgB,OAAO,CAAC,EACtB,WAA0B,EAC1B,KAAe,EACf,SAAkB,EAClB,OAAc,EACd,SAAc,GACf,EAAE,YAAY,GAAG,GAAG,CAAC,OAAO,CAc5B;AAED,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider Component
|
|
3
|
+
*
|
|
4
|
+
* Horizontal or vertical divider line.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
const colorClasses = {
|
|
8
|
+
primary: 'bg-purple-500',
|
|
9
|
+
secondary: 'bg-gray-500',
|
|
10
|
+
success: 'bg-green-500',
|
|
11
|
+
warning: 'bg-yellow-500',
|
|
12
|
+
error: 'bg-red-500',
|
|
13
|
+
muted: 'bg-gray-600',
|
|
14
|
+
white: 'bg-white',
|
|
15
|
+
black: 'bg-black',
|
|
16
|
+
};
|
|
17
|
+
const thicknessClasses = {
|
|
18
|
+
horizontal: {
|
|
19
|
+
thin: 'h-px',
|
|
20
|
+
medium: 'h-0.5',
|
|
21
|
+
thick: 'h-1',
|
|
22
|
+
},
|
|
23
|
+
vertical: {
|
|
24
|
+
thin: 'w-px',
|
|
25
|
+
medium: 'w-0.5',
|
|
26
|
+
thick: 'w-1',
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const spacingClasses = {
|
|
30
|
+
horizontal: {
|
|
31
|
+
none: '',
|
|
32
|
+
sm: 'my-2',
|
|
33
|
+
md: 'my-4',
|
|
34
|
+
lg: 'my-6',
|
|
35
|
+
},
|
|
36
|
+
vertical: {
|
|
37
|
+
none: '',
|
|
38
|
+
sm: 'mx-2',
|
|
39
|
+
md: 'mx-4',
|
|
40
|
+
lg: 'mx-6',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export function Divider({ orientation = 'horizontal', color = 'muted', thickness = 'thin', spacing = 'md', className = '', }) {
|
|
44
|
+
const isHorizontal = orientation === 'horizontal';
|
|
45
|
+
const classes = [
|
|
46
|
+
colorClasses[color],
|
|
47
|
+
thicknessClasses[orientation][thickness],
|
|
48
|
+
spacingClasses[orientation][spacing],
|
|
49
|
+
isHorizontal ? 'w-full' : 'h-full',
|
|
50
|
+
className,
|
|
51
|
+
]
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
.join(' ');
|
|
54
|
+
return React.createElement("div", { className: classes, role: "separator", "aria-orientation": orientation });
|
|
55
|
+
}
|
|
56
|
+
export default Divider;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Component
|
|
3
|
+
*
|
|
4
|
+
* Image display with fit and rounded options.
|
|
5
|
+
*/
|
|
6
|
+
import type { RegistryComponentProps } from '../ComponentRegistry';
|
|
7
|
+
export interface ImageProps extends RegistryComponentProps {
|
|
8
|
+
/** Image source URL */
|
|
9
|
+
src: string;
|
|
10
|
+
/** Alt text */
|
|
11
|
+
alt?: string;
|
|
12
|
+
/** Object fit */
|
|
13
|
+
fit?: 'cover' | 'contain' | 'fill' | 'none';
|
|
14
|
+
/** Border radius */
|
|
15
|
+
rounded?: 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
16
|
+
/** Width (CSS value or pixels) */
|
|
17
|
+
width?: string | number;
|
|
18
|
+
/** Height (CSS value or pixels) */
|
|
19
|
+
height?: string | number;
|
|
20
|
+
/** Aspect ratio */
|
|
21
|
+
aspectRatio?: string;
|
|
22
|
+
/** Additional CSS classes */
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function Image({ src, alt, fit, rounded, width, height, aspectRatio, className, }: ImageProps): JSX.Element;
|
|
26
|
+
export default Image;
|
|
27
|
+
//# sourceMappingURL=Image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../../src/spec/registry/primitives/Image.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAGnE,MAAM,WAAW,UAAW,SAAQ,sBAAsB;IACxD,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IAEZ,eAAe;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,iBAAiB;IACjB,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAE5C,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAE/C,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiBD,wBAAgB,KAAK,CAAC,EACpB,GAAG,EACH,GAAQ,EACR,GAAa,EACb,OAAgB,EAChB,KAAK,EACL,MAAM,EACN,WAAW,EACX,SAAc,GACf,EAAE,UAAU,GAAG,GAAG,CAAC,OAAO,CAoB1B;AAED,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Component
|
|
3
|
+
*
|
|
4
|
+
* Image display with fit and rounded options.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
const fitClasses = {
|
|
8
|
+
cover: 'object-cover',
|
|
9
|
+
contain: 'object-contain',
|
|
10
|
+
fill: 'object-fill',
|
|
11
|
+
none: 'object-none',
|
|
12
|
+
};
|
|
13
|
+
const roundedClasses = {
|
|
14
|
+
none: 'rounded-none',
|
|
15
|
+
sm: 'rounded-sm',
|
|
16
|
+
md: 'rounded-md',
|
|
17
|
+
lg: 'rounded-lg',
|
|
18
|
+
full: 'rounded-full',
|
|
19
|
+
};
|
|
20
|
+
export function Image({ src, alt = '', fit = 'cover', rounded = 'none', width, height, aspectRatio, className = '', }) {
|
|
21
|
+
const classes = [fitClasses[fit], roundedClasses[rounded], className]
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.join(' ');
|
|
24
|
+
const style = {};
|
|
25
|
+
if (width !== undefined) {
|
|
26
|
+
style.width = typeof width === 'number' ? `${width}px` : width;
|
|
27
|
+
}
|
|
28
|
+
if (height !== undefined) {
|
|
29
|
+
style.height = typeof height === 'number' ? `${height}px` : height;
|
|
30
|
+
}
|
|
31
|
+
if (aspectRatio) {
|
|
32
|
+
style.aspectRatio = aspectRatio;
|
|
33
|
+
}
|
|
34
|
+
return React.createElement("img", { src: src, alt: alt, className: classes, style: style, loading: "lazy" });
|
|
35
|
+
}
|
|
36
|
+
export default Image;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProgressBar Component
|
|
3
|
+
*
|
|
4
|
+
* Animated progress bar with color variants.
|
|
5
|
+
*/
|
|
6
|
+
import type { RegistryComponentProps } from '../ComponentRegistry';
|
|
7
|
+
import type { Color, Size } from '../../types';
|
|
8
|
+
export interface ProgressBarProps extends RegistryComponentProps {
|
|
9
|
+
/** Current value */
|
|
10
|
+
value: number;
|
|
11
|
+
/** Maximum value */
|
|
12
|
+
max?: number;
|
|
13
|
+
/** Bar color */
|
|
14
|
+
color?: Color;
|
|
15
|
+
/** Bar height */
|
|
16
|
+
size?: Size;
|
|
17
|
+
/** Show percentage label */
|
|
18
|
+
showLabel?: boolean;
|
|
19
|
+
/** Animate the bar */
|
|
20
|
+
animated?: boolean;
|
|
21
|
+
/** Border radius */
|
|
22
|
+
rounded?: boolean;
|
|
23
|
+
/** Additional CSS classes */
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function ProgressBar({ value, max, color, size, showLabel, animated, rounded, className, }: ProgressBarProps): JSX.Element;
|
|
27
|
+
export default ProgressBar;
|
|
28
|
+
//# sourceMappingURL=ProgressBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["../../../../src/spec/registry/primitives/ProgressBar.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,gBAAiB,SAAQ,sBAAsB;IAC9D,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IAEd,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,gBAAgB;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd,iBAAiB;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IAEZ,4BAA4B;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,GAAS,EACT,KAAiB,EACjB,IAAW,EACX,SAAiB,EACjB,QAAe,EACf,OAAc,EACd,SAAc,GACf,EAAE,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAwChC;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProgressBar Component
|
|
3
|
+
*
|
|
4
|
+
* Animated progress bar with color variants.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
const colorClasses = {
|
|
8
|
+
primary: 'bg-purple-500',
|
|
9
|
+
secondary: 'bg-gray-500',
|
|
10
|
+
success: 'bg-green-500',
|
|
11
|
+
warning: 'bg-yellow-500',
|
|
12
|
+
error: 'bg-red-500',
|
|
13
|
+
muted: 'bg-gray-400',
|
|
14
|
+
white: 'bg-white',
|
|
15
|
+
black: 'bg-black',
|
|
16
|
+
};
|
|
17
|
+
const sizeClasses = {
|
|
18
|
+
xs: 'h-1',
|
|
19
|
+
sm: 'h-2',
|
|
20
|
+
md: 'h-3',
|
|
21
|
+
lg: 'h-4',
|
|
22
|
+
xl: 'h-6',
|
|
23
|
+
'2xl': 'h-8',
|
|
24
|
+
};
|
|
25
|
+
export function ProgressBar({ value, max = 100, color = 'primary', size = 'md', showLabel = false, animated = true, rounded = true, className = '', }) {
|
|
26
|
+
const percentage = Math.min(100, Math.max(0, (value / max) * 100));
|
|
27
|
+
const containerClasses = [
|
|
28
|
+
'w-full bg-gray-700 overflow-hidden',
|
|
29
|
+
sizeClasses[size],
|
|
30
|
+
rounded ? 'rounded-full' : '',
|
|
31
|
+
className,
|
|
32
|
+
]
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.join(' ');
|
|
35
|
+
const barClasses = [
|
|
36
|
+
colorClasses[color],
|
|
37
|
+
'h-full',
|
|
38
|
+
animated ? 'transition-all duration-500 ease-out' : '',
|
|
39
|
+
rounded ? 'rounded-full' : '',
|
|
40
|
+
]
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.join(' ');
|
|
43
|
+
return (React.createElement("div", { className: "w-full" },
|
|
44
|
+
React.createElement("div", { className: containerClasses },
|
|
45
|
+
React.createElement("div", { className: barClasses, style: { width: `${percentage}%` }, role: "progressbar", "aria-valuenow": value, "aria-valuemin": 0, "aria-valuemax": max })),
|
|
46
|
+
showLabel && (React.createElement("div", { className: "mt-1 text-center text-sm text-gray-400" },
|
|
47
|
+
Math.round(percentage),
|
|
48
|
+
"%"))));
|
|
49
|
+
}
|
|
50
|
+
export default ProgressBar;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Row Component
|
|
3
|
+
*
|
|
4
|
+
* Horizontal flex container with gap, alignment, and justify options.
|
|
5
|
+
*/
|
|
6
|
+
import type { RegistryComponentProps } from '../ComponentRegistry';
|
|
7
|
+
import type { Size, Align, Justify } from '../../types';
|
|
8
|
+
export interface RowProps extends RegistryComponentProps {
|
|
9
|
+
/** Gap between items */
|
|
10
|
+
gap?: Size;
|
|
11
|
+
/** Vertical alignment */
|
|
12
|
+
align?: Align;
|
|
13
|
+
/** Horizontal justification */
|
|
14
|
+
justify?: Justify;
|
|
15
|
+
/** Padding */
|
|
16
|
+
padding?: Size;
|
|
17
|
+
/** Full width */
|
|
18
|
+
fullWidth?: boolean;
|
|
19
|
+
/** Wrap items */
|
|
20
|
+
wrap?: boolean;
|
|
21
|
+
/** Additional CSS classes */
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function Row({ gap, align, justify, padding, fullWidth, wrap, className, children, }: RowProps): JSX.Element;
|
|
25
|
+
export default Row;
|
|
26
|
+
//# sourceMappingURL=Row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Row.d.ts","sourceRoot":"","sources":["../../../../src/spec/registry/primitives/Row.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,WAAW,QAAS,SAAQ,sBAAsB;IACtD,wBAAwB;IACxB,GAAG,CAAC,EAAE,IAAI,CAAC;IAEX,yBAAyB;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd,+BAA+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,cAAc;IACd,OAAO,CAAC,EAAE,IAAI,CAAC;IAEf,iBAAiB;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,iBAAiB;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkCD,wBAAgB,GAAG,CAAC,EAClB,GAAU,EACV,KAAgB,EAChB,OAAiB,EACjB,OAAO,EACP,SAAiB,EACjB,IAAY,EACZ,SAAc,EACd,QAAQ,GACT,EAAE,QAAQ,GAAG,GAAG,CAAC,OAAO,CAexB;AAED,eAAe,GAAG,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Row Component
|
|
3
|
+
*
|
|
4
|
+
* Horizontal flex container with gap, alignment, and justify options.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
const gapClasses = {
|
|
8
|
+
xs: 'gap-1',
|
|
9
|
+
sm: 'gap-2',
|
|
10
|
+
md: 'gap-4',
|
|
11
|
+
lg: 'gap-6',
|
|
12
|
+
xl: 'gap-8',
|
|
13
|
+
'2xl': 'gap-10',
|
|
14
|
+
};
|
|
15
|
+
const alignClasses = {
|
|
16
|
+
left: 'items-start',
|
|
17
|
+
center: 'items-center',
|
|
18
|
+
right: 'items-end',
|
|
19
|
+
};
|
|
20
|
+
const justifyClasses = {
|
|
21
|
+
start: 'justify-start',
|
|
22
|
+
center: 'justify-center',
|
|
23
|
+
end: 'justify-end',
|
|
24
|
+
between: 'justify-between',
|
|
25
|
+
around: 'justify-around',
|
|
26
|
+
};
|
|
27
|
+
const paddingClasses = {
|
|
28
|
+
xs: 'p-1',
|
|
29
|
+
sm: 'p-2',
|
|
30
|
+
md: 'p-4',
|
|
31
|
+
lg: 'p-6',
|
|
32
|
+
xl: 'p-8',
|
|
33
|
+
'2xl': 'p-10',
|
|
34
|
+
};
|
|
35
|
+
export function Row({ gap = 'md', align = 'center', justify = 'start', padding, fullWidth = false, wrap = false, className = '', children, }) {
|
|
36
|
+
const classes = [
|
|
37
|
+
'flex flex-row',
|
|
38
|
+
gapClasses[gap],
|
|
39
|
+
alignClasses[align],
|
|
40
|
+
justifyClasses[justify],
|
|
41
|
+
padding ? paddingClasses[padding] : '',
|
|
42
|
+
fullWidth ? 'w-full' : '',
|
|
43
|
+
wrap ? 'flex-wrap' : '',
|
|
44
|
+
className,
|
|
45
|
+
]
|
|
46
|
+
.filter(Boolean)
|
|
47
|
+
.join(' ');
|
|
48
|
+
return React.createElement("div", { className: classes }, children);
|
|
49
|
+
}
|
|
50
|
+
export default Row;
|