@rlx-ui/mcp 0.0.15 → 0.0.17
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/data/registry.json +48 -1
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/data/registry.json
CHANGED
|
@@ -1396,6 +1396,27 @@
|
|
|
1396
1396
|
"utils/getShikiBgHex.ts": "import { BundledTheme, getSingletonHighlighter } from \"shiki\";\n\nexport const getThemeBackgroundHex = async (themeName: BundledTheme) => {\n const highlighter = await getSingletonHighlighter({\n themes: [themeName],\n });\n\n const theme = highlighter.getTheme(themeName);\n\n return theme.colors?.[\"editor.background\"] || null;\n};\n"
|
|
1397
1397
|
}
|
|
1398
1398
|
},
|
|
1399
|
+
{
|
|
1400
|
+
"name": "Collapsible Panel",
|
|
1401
|
+
"exportName": "CollapsiblePanel",
|
|
1402
|
+
"packageName": "@rlx-components/collapsible-panel",
|
|
1403
|
+
"version": "0.0.1",
|
|
1404
|
+
"slug": "collapsible-panel",
|
|
1405
|
+
"category": "component",
|
|
1406
|
+
"sourceCode": "\"use client\";\n\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { CollapsiblePanelContext, useCollapsiblePanel } from \"./contexts\";\nimport type {\n CollapsiblePanelProps,\n CollapsiblePanelHeaderProps,\n CollapsiblePanelContentProps,\n} from \"./types\";\n\nexport const CollapsiblePanel = ({\n isExpanded,\n onToggle,\n children,\n className,\n ...props\n}: CollapsiblePanelProps) => {\n return (\n <CollapsiblePanelContext.Provider value={{ isExpanded, onToggle }}>\n <div\n className={cn(\"border rounded-lg shadow-sm bg-background\", className)}\n data-slot=\"collapsible-panel\"\n {...props}\n >\n {children}\n </div>\n </CollapsiblePanelContext.Provider>\n );\n};\n\nexport const CollapsiblePanelHeader = ({\n children,\n className,\n ...props\n}: CollapsiblePanelHeaderProps) => {\n const { isExpanded, onToggle } = useCollapsiblePanel();\n\n return (\n <button\n onClick={onToggle}\n className={cn(\n \"w-full flex items-center justify-between p-4 hover:bg-muted/50 transition-colors rounded-t-lg cursor-pointer\",\n className\n )}\n aria-expanded={isExpanded}\n data-slot=\"collapsible-panel-header\"\n aria-controls=\"collapsible-panel-content\"\n type=\"button\"\n {...props}\n >\n {children}\n <ChevronDown\n className={cn(\n \"size-4 text-muted-foreground transition-transform duration-200\",\n !isExpanded && \"-rotate-90\"\n )}\n />\n </button>\n );\n};\n\nexport const CollapsiblePanelContent = ({\n children,\n className,\n ...props\n}: CollapsiblePanelContentProps) => {\n const { isExpanded } = useCollapsiblePanel();\n\n return (\n <div\n id=\"collapsible-panel-content\"\n data-slot=\"collapsible-panel-content\"\n className={cn(\n \"overflow-hidden transition-all duration-300 ease-in-out\",\n isExpanded ? \"max-h-[1000px] opacity-100\" : \"max-h-0 opacity-0\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n};\n",
|
|
1407
|
+
"demos": [
|
|
1408
|
+
{
|
|
1409
|
+
"name": "default",
|
|
1410
|
+
"code": "\"use client\";\n\nimport {\n CollapsiblePanel,\n CollapsiblePanelHeader,\n CollapsiblePanelContent,\n} from \"@rlx-components/collapsible-panel\";\nimport { useState } from \"react\";\n\nexport const Preview = () => {\n const [isExpanded1, setIsExpanded1] = useState(true);\n const [isExpanded2, setIsExpanded2] = useState(false);\n const [isExpanded3, setIsExpanded3] = useState(false);\n\n return (\n <div className=\"w-full max-w-2xl space-y-4\">\n <CollapsiblePanel\n isExpanded={isExpanded1}\n onToggle={() => setIsExpanded1(!isExpanded1)}\n >\n <CollapsiblePanelHeader>\n <span className=\"font-semibold\">Expanded by default</span>\n </CollapsiblePanelHeader>\n <CollapsiblePanelContent>\n <div className=\"p-4\">\n <p className=\"text-sm text-muted-foreground\">\n This panel starts expanded. Click the header to collapse it.\n </p>\n </div>\n </CollapsiblePanelContent>\n </CollapsiblePanel>\n\n <CollapsiblePanel\n isExpanded={isExpanded2}\n onToggle={() => setIsExpanded2(!isExpanded2)}\n >\n <CollapsiblePanelHeader>\n <span className=\"font-semibold\">Collapsed by default</span>\n </CollapsiblePanelHeader>\n <CollapsiblePanelContent>\n <div className=\"p-4\">\n <p className=\"text-sm text-muted-foreground\">\n This panel starts collapsed. Click the header to expand it and see\n this content.\n </p>\n </div>\n </CollapsiblePanelContent>\n </CollapsiblePanel>\n\n <CollapsiblePanel\n isExpanded={isExpanded3}\n onToggle={() => setIsExpanded3(!isExpanded3)}\n >\n <CollapsiblePanelHeader>\n <span className=\"font-semibold\">Panel with more content</span>\n </CollapsiblePanelHeader>\n <CollapsiblePanelContent>\n <div className=\"p-4 space-y-2\">\n <p className=\"text-sm text-muted-foreground\">\n This panel contains more content to demonstrate the smooth\n animation.\n </p>\n <ul className=\"list-disc list-inside text-sm text-muted-foreground space-y-1\">\n <li>Item one</li>\n <li>Item two</li>\n <li>Item three</li>\n </ul>\n </div>\n </CollapsiblePanelContent>\n </CollapsiblePanel>\n </div>\n );\n};\n\n"
|
|
1411
|
+
}
|
|
1412
|
+
],
|
|
1413
|
+
"sourceFiles": {
|
|
1414
|
+
"contexts/CollapsiblePanelContext.tsx": "\"use client\";\n\nimport { createContext, useContext } from \"react\";\n\ntype CollapsiblePanelContextValue = {\n isExpanded: boolean;\n onToggle: () => void;\n};\n\nconst CollapsiblePanelContext =\n createContext<CollapsiblePanelContextValue | null>(null);\n\nexport const useCollapsiblePanel = () => {\n const context = useContext(CollapsiblePanelContext);\n if (!context) {\n throw new Error(\n \"CollapsiblePanel components must be used within CollapsiblePanel\"\n );\n }\n return context;\n};\n\nexport { CollapsiblePanelContext };\n",
|
|
1415
|
+
"types/CollapsiblePanelContentProps.t.ts": "import { ComponentProps, ReactNode } from \"react\";\n\nexport type CollapsiblePanelContentProps = ComponentProps<\"div\"> & {\n children: ReactNode;\n};\n",
|
|
1416
|
+
"types/CollapsiblePanelHeaderProps.t.ts": "import { ComponentProps, ReactNode } from \"react\";\n\nexport type CollapsiblePanelHeaderProps = ComponentProps<\"button\"> & {\n children: ReactNode;\n};\n\n",
|
|
1417
|
+
"types/CollapsiblePanelProps.t.ts": "import { ComponentProps, ReactNode } from \"react\";\n\nexport type CollapsiblePanelProps = ComponentProps<\"div\"> & {\n isExpanded: boolean;\n onToggle: () => void;\n children: ReactNode;\n};\n\n"
|
|
1418
|
+
}
|
|
1419
|
+
},
|
|
1399
1420
|
{
|
|
1400
1421
|
"name": "Inline Code",
|
|
1401
1422
|
"exportName": "InlineCode",
|
|
@@ -1411,6 +1432,32 @@
|
|
|
1411
1432
|
}
|
|
1412
1433
|
]
|
|
1413
1434
|
},
|
|
1435
|
+
{
|
|
1436
|
+
"name": "Quiz Box",
|
|
1437
|
+
"exportName": "QuizBox",
|
|
1438
|
+
"packageName": "@rlx-components/quiz-box",
|
|
1439
|
+
"version": "0.0.1",
|
|
1440
|
+
"slug": "quiz-box",
|
|
1441
|
+
"category": "component",
|
|
1442
|
+
"sourceCode": "\"use client\";\n\nimport { Button } from \"@rlx-widgets/button\";\nimport { CheckCircle2, XCircle } from \"lucide-react\";\nimport { cn } from \"@rlx-widgets/base\";\nimport { ConfettiOverlay, QuizOptionButton } from \"./components\";\nimport { ConfettiPiece, QuizBoxProps } from \"./types\";\nimport { generateConfettis, getMessage } from \"./utils\";\nimport { Pill } from \"./components\";\nimport { useEffect, useState } from \"react\";\n\nexport function QuizBox({ quizzes }: QuizBoxProps) {\n const [currentIndex, setCurrentIndex] = useState<number>(0);\n const [selectedIndex, setSelectedIndex] = useState<number | null>(null);\n const [finished, setFinished] = useState<boolean>(false);\n const [numCorrect, setNumCorrect] = useState<number>(0);\n const [showConfetti, setShowConfetti] = useState<boolean>(false);\n const [confettiPieces, setConfettiPieces] = useState<Array<ConfettiPiece>>(\n []\n );\n const [correctAnswerFound, setCorrectAnswerFound] = useState<boolean>(false);\n\n const current = quizzes[currentIndex];\n const hasSelection = typeof selectedIndex === \"number\";\n const selectedIsCorrect =\n hasSelection && selectedIndex !== null\n ? !!current.options[selectedIndex].correct\n : false;\n\n const displayConfetti = (\n options?: Parameters<typeof generateConfettis>[0]\n ) => {\n setConfettiPieces(generateConfettis(options || {}));\n setShowConfetti(true);\n };\n\n const handleSelect = (optionIndex: number) => {\n // If correct answer was already found, prevent further selections\n if (correctAnswerFound) return;\n\n setSelectedIndex(optionIndex);\n if (current.options[optionIndex]?.correct) {\n setCorrectAnswerFound(true);\n setNumCorrect((n) => n + 1);\n displayConfetti();\n }\n };\n\n const handleAnother = () => {\n if (currentIndex + 1 < quizzes.length) {\n setCurrentIndex((idx) => idx + 1);\n setSelectedIndex(null);\n setCorrectAnswerFound(false);\n setShowConfetti(false);\n } else {\n setFinished(true);\n // Longer, denser confetti at the end\n displayConfetti({\n numPieces: 48,\n baseDurationMs: 2400,\n extraRandomMs: 2400,\n });\n }\n };\n\n const handleFinish = () => {\n setFinished(true);\n // Longer, denser confetti at the end\n displayConfetti({\n numPieces: 48,\n baseDurationMs: 2400,\n extraRandomMs: 2400,\n });\n };\n\n const handleRestart = () => {\n setCurrentIndex(0);\n setSelectedIndex(null);\n setFinished(false);\n setShowConfetti(false);\n setCorrectAnswerFound(false);\n setNumCorrect(0);\n };\n\n useEffect(() => {\n if (!showConfetti) return;\n const timeoutMs = finished ? 5200 : 2200;\n const t = setTimeout(() => setShowConfetti(false), timeoutMs);\n return () => clearTimeout(t);\n }, [showConfetti, finished]);\n\n if (finished) {\n const percentage = Math.round((numCorrect / quizzes.length) * 100);\n\n return (\n <div className=\"relative min-h-[400px] flex flex-col items-center justify-center space-y-6 py-8\">\n <ConfettiOverlay pieces={confettiPieces} />\n <div className=\"flex flex-col items-center gap-4 text-center\">\n <div className=\"flex items-center justify-center size-16 rounded-full bg-green-100\">\n <CheckCircle2 className=\"size-10 text-green-600\" />\n </div>\n <h3 className=\"text-2xl font-bold\">{getMessage(percentage)}</h3>\n <div className=\"space-y-2\">\n <div className=\"flex items-baseline justify-center gap-2\">\n <span className=\"text-5xl font-bold text-primary\">\n {numCorrect}\n </span>\n <span className=\"text-xl text-muted-foreground\">\n / {quizzes.length}\n </span>\n </div>\n <div className=\"flex items-center gap-2 justify-center\">\n <Pill className=\"text-sm font-semibold\">\n {percentage}% Correct\n </Pill>\n </div>\n </div>\n <p className=\"text-sm text-muted-foreground max-w-md\">\n Thanks for taking the quiz! You got{\" \"}\n <span className=\"font-semibold text-foreground\">{numCorrect}</span>{\" \"}\n {numCorrect === 1 ? \"question\" : \"questions\"} right out of{\" \"}\n {quizzes.length}.\n </p>\n </div>\n <div className=\"flex gap-3 pt-4\">\n <Button size=\"sm\" onClick={handleRestart}>\n Start over\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"min-h-[300px] space-y-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"inline-flex items-center gap-2 text-xs text-muted-foreground\">\n <Pill>\n Question {currentIndex + 1} of {quizzes.length}\n </Pill>\n <span className=\"hidden sm:inline\">•</span>\n <Pill>Score: {numCorrect}</Pill>\n </span>\n </div>\n <h4 className=\"font-medium\">{current.question}</h4>\n <div className=\"grid grid-cols-1 gap-3\">\n {current.options.map((opt, idx) => {\n const isSelected = selectedIndex === idx;\n const isCorrect = !!opt.correct;\n const showCorrect = hasSelection && isSelected && isCorrect;\n const showWrong = hasSelection && isSelected && !isCorrect;\n\n return (\n <QuizOptionButton\n key={idx}\n state={showCorrect ? \"correct\" : showWrong ? \"wrong\" : \"default\"}\n serial={String.fromCharCode(65 + idx)}\n disabled={correctAnswerFound}\n onClick={() => handleSelect(idx)}\n selected={isSelected}\n >\n {opt.text}\n </QuizOptionButton>\n );\n })}\n </div>\n\n <div className=\"space-y-3\">\n {hasSelection && (\n <div\n className={cn(\n \"flex items-center gap-2 rounded-md px-3 py-2\",\n selectedIsCorrect\n ? \"bg-green-50 text-green-800\"\n : \"bg-red-50 text-red-800\"\n )}\n >\n {selectedIsCorrect ? (\n <CheckCircle2 className=\"size-4\" />\n ) : (\n <XCircle className=\"size-4\" />\n )}\n <p className=\"text-sm\">\n {selectedIsCorrect\n ? \"Correct!\"\n : \"Not quite. Try again or skip to next question!\"}\n </p>\n </div>\n )}\n <div className=\"flex gap-3\">\n <Button size=\"sm\" onClick={handleAnother}>\n {hasSelection && !correctAnswerFound ? \"Skip\" : \"Next Question\"}\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={handleFinish}>\n Finish\n </Button>\n </div>\n </div>\n </div>\n );\n}\n",
|
|
1443
|
+
"demos": [
|
|
1444
|
+
{
|
|
1445
|
+
"name": "default",
|
|
1446
|
+
"code": "\"use client\";\n\nimport { QuizBox, QuizQuestion } from \"@rlx-components/quiz-box\";\n\nexport const Preview = () => {\n const quizzes: Array<QuizQuestion> = [\n {\n question: \"Which of the following is a JavaScript framework?\",\n options: [\n { text: \"React\", correct: true },\n { text: \"Python\" },\n { text: \"Java\" },\n { text: \"C++\" },\n ],\n },\n {\n question: \"What is the capital of France?\",\n options: [\n { text: \"London\" },\n { text: \"Berlin\" },\n { text: \"Paris\", correct: true },\n { text: \"Madrid\" },\n ],\n },\n {\n question: \"Which HTML tag is used for the largest heading?\",\n options: [\n { text: \"<h6>\" },\n { text: \"<h1>\", correct: true },\n { text: \"<heading>\" },\n { text: \"<head>\" },\n ],\n },\n ];\n\n return (\n <div className=\"w-full max-w-2xl\">\n <QuizBox quizzes={quizzes} />\n </div>\n );\n};\n\n"
|
|
1447
|
+
}
|
|
1448
|
+
],
|
|
1449
|
+
"sourceFiles": {
|
|
1450
|
+
"components/ConfettiOverlay/ConfettiOverlay.tsx": "\"use client\";\n\nimport { cn } from \"@rlx-widgets/base\";\nimport type { ConfettiOverlayProps } from \"./types\";\n\nconst ConfettiOverlay = ({ pieces, className }: ConfettiOverlayProps) => {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"pointer-events-none absolute inset-0 overflow-hidden\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t>\n\t\t\t{pieces.map((cfg, i) => (\n\t\t\t\t<span\n\t\t\t\t\tkey={i}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tleft: `${cfg.left}%`,\n\t\t\t\t\t\ttop: `${cfg.top}%`,\n\t\t\t\t\t\tanimationDelay: `${cfg.delayMs}ms`,\n\t\t\t\t\t\tanimationDuration: `${cfg.durationMs}ms`,\n\t\t\t\t\t\ttransform: `rotate(${cfg.rotate}deg)`,\n\t\t\t\t\t}}\n\t\t\t\t\tclassName=\"absolute top-0 inline-block\"\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tdisplay: \"inline-block\",\n\t\t\t\t\t\t\twidth: cfg.size,\n\t\t\t\t\t\t\theight: cfg.size * 2,\n\t\t\t\t\t\t\tbackgroundColor: cfg.color,\n\t\t\t\t\t\t\tborderRadius: 2,\n\t\t\t\t\t\t\tanimationName: \"confettiFall\",\n\t\t\t\t\t\t\tanimationTimingFunction:\n\t\t\t\t\t\t\t\t\"cubic-bezier(0.2, 0.6, 0.2, 1)\",\n\t\t\t\t\t\t\tanimationIterationCount: 1,\n\t\t\t\t\t\t\tanimationFillMode: \"forwards\",\n\t\t\t\t\t\t\tanimationDelay: `${cfg.delayMs}ms`,\n\t\t\t\t\t\t\tanimationDuration: `${cfg.durationMs}ms`,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</span>\n\t\t\t))}\n\t\t\t<style\n\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t__html: `\n\t\t\t\t@keyframes confettiFall {\n\t\t\t\t\t0% {\n\t\t\t\t\t\topacity: 0;\n\t\t\t\t\t\ttransform: translateY(-10px) rotate(0deg);\n\t\t\t\t\t}\n\t\t\t\t\t10% {\n\t\t\t\t\t\topacity: 1;\n\t\t\t\t\t}\n\t\t\t\t\t100% {\n\t\t\t\t\t\topacity: 0;\n\t\t\t\t\t\ttransform: translateY(110%) rotate(720deg);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\t}}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n\nexport { ConfettiOverlay };\n",
|
|
1451
|
+
"components/ConfettiOverlay/types/ConfettiOverlayProps.t.ts": "import { ConfettiPiece } from \"../../../types\";\n\nexport type ConfettiOverlayProps = {\n pieces: Array<ConfettiPiece>;\n className?: string;\n};\n\n",
|
|
1452
|
+
"components/Pill.tsx": "import { cn } from \"@rlx-widgets/base\";\nimport { ComponentProps } from \"react\";\n\nexport const Pill = ({\n\tchildren,\n\tclassName,\n\t...props\n}: ComponentProps<\"span\">) => {\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"inline-flex items-center rounded-full bg-secondary px-2 py-1\",\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</span>\n\t);\n};\n",
|
|
1453
|
+
"components/QuizOptionButton/QuizOptionButton.tsx": "\"use client\";\n\nimport { cn } from \"@rlx-widgets/base\";\nimport { ConfettiOverlay } from \"../ConfettiOverlay\";\nimport { cva, VariantProps } from \"class-variance-authority\";\nimport { generateConfettis } from \"../../utils\";\nimport { ComponentProps, useMemo } from \"react\";\n\nconst quizOptionButtonVariants = cva(\n \"relative rounded-lg border p-3 text-left transition-all hover:shadow-md active:scale-[0.99] cursor-pointer\",\n {\n variants: {\n state: {\n default: \"bg-muted/40 hover:bg-muted/60\",\n correct: \"bg-green-100 border-green-300 text-green-900\",\n wrong: \"bg-red-50 border-red-300 text-red-900\",\n },\n },\n defaultVariants: {\n state: \"default\",\n },\n }\n);\n\nexport type QuizOptionButtonProps = ComponentProps<\"button\"> &\n VariantProps<typeof quizOptionButtonVariants> & {\n selected?: boolean;\n serial: number | string;\n };\n\nexport const QuizOptionButton = ({\n className,\n state,\n selected = false,\n serial,\n children,\n ...props\n}: QuizOptionButtonProps) => {\n const confettiPieces = useMemo(() => {\n if (selected && state === \"correct\") {\n return generateConfettis();\n }\n return [];\n }, [selected, state]);\n\n return (\n <button\n data-slot=\"button\"\n className={cn(quizOptionButtonVariants({ state, className }))}\n type=\"button\"\n {...props}\n >\n {selected && state === \"correct\" && (\n <ConfettiOverlay pieces={confettiPieces} />\n )}\n <span className=\"flex items-center gap-3\">\n <span className=\"inline-flex size-6 items-center justify-center rounded-full text-xs font-semibold\">\n {serial}\n </span>\n <span className=\"text-sm font-medium\">{children}</span>\n </span>\n </button>\n );\n};\n",
|
|
1454
|
+
"types/ConfettiPiece.t.ts": "export type ConfettiPiece = {\n\tleft: number;\n\ttop: number;\n\tdelayMs: number;\n\tdurationMs: number;\n\trotate: number;\n\tsize: number;\n\tcolor: string;\n};\n",
|
|
1455
|
+
"types/QuizBoxProps.t.ts": "import { QuizQuestion } from \"./QuizQuestion.t\";\n\nexport type QuizBoxProps = {\n quizzes: Array<QuizQuestion>;\n};\n\n",
|
|
1456
|
+
"types/QuizQuestion.t.ts": "export type QuizQuestion = {\n\tquestion: string;\n\toptions: Array<{\n\t\ttext: string;\n\t\tcorrect?: boolean;\n\t}>;\n};\n",
|
|
1457
|
+
"utils/generateConfettis.ts": "export const generateConfettis = (options?: {\n\tnumPieces?: number;\n\tbaseDurationMs?: number;\n\textraRandomMs?: number;\n}) => {\n\tconst {\n\t\tnumPieces = 24,\n\t\tbaseDurationMs = 2000,\n\t\textraRandomMs = 900,\n\t} = options || {};\n\n\tconst colors = [\"#22c55e\", \"#3b82f6\", \"#eab308\", \"#ef4444\", \"#a855f7\"];\n\tconst pieces = Array.from({ length: numPieces }).map((_, i) => ({\n\t\tleft: Math.random() * 100,\n\t\ttop: Math.random() * 100,\n\t\tdelayMs: 0,\n\t\tdurationMs: baseDurationMs + Math.floor(Math.random() * extraRandomMs),\n\t\trotate: Math.floor(Math.random() * 360),\n\t\tsize: 8 + Math.floor(Math.random() * 8),\n\t\tcolor: colors[i % colors.length],\n\t}));\n\n\treturn pieces;\n};\n",
|
|
1458
|
+
"utils/getMessage.ts": "export const getMessage = (percentage: number): string => {\n if (percentage === 100) return \"Perfect Score! 🎉\";\n if (percentage >= 80) return \"Excellent Work! 🚀\";\n if (percentage >= 60) return \"Great Job! 👍\";\n return \"Nice Try! 💪\";\n};\n\n"
|
|
1459
|
+
}
|
|
1460
|
+
},
|
|
1414
1461
|
{
|
|
1415
1462
|
"name": "Selectable Button",
|
|
1416
1463
|
"exportName": "SelectableButton",
|
|
@@ -1627,5 +1674,5 @@
|
|
|
1627
1674
|
"sourceCode": "export const isValidDate = (date: Date) => {\n return !Number.isNaN(date.getTime());\n};\n\nexport default isValidDate;\n"
|
|
1628
1675
|
}
|
|
1629
1676
|
],
|
|
1630
|
-
"extractedAt": "2025-12-
|
|
1677
|
+
"extractedAt": "2025-12-08T04:24:14.975Z"
|
|
1631
1678
|
}
|
package/dist/package.json
CHANGED