ruler-components 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/app/docs/[slug]/page.tsx +147 -0
- package/app/docs/layout.tsx +26 -0
- package/app/docs/page.tsx +148 -0
- package/app/favicon.ico +0 -0
- package/app/globals.css +168 -0
- package/app/icon.png +0 -0
- package/app/layout.tsx +90 -0
- package/app/opengraph-image.tsx +10 -0
- package/app/page.tsx +34 -0
- package/app/twitter-image.tsx +10 -0
- package/components/docs/accordion-doc-page.tsx +352 -0
- package/components/docs/alert-doc-page.tsx +293 -0
- package/components/docs/allinput-doc-page.tsx +183 -0
- package/components/docs/avatar-doc-page.tsx +424 -0
- package/components/docs/badge-doc-page.tsx +363 -0
- package/components/docs/button-doc-page.tsx +406 -0
- package/components/docs/card-doc-page.tsx +364 -0
- package/components/docs/checkbox-doc-page.tsx +277 -0
- package/components/docs/colors-doc-page.tsx +430 -0
- package/components/docs/dialog-doc-page.tsx +364 -0
- package/components/docs/docs-footer.tsx +11 -0
- package/components/docs/docs-mobile-menu-bar.tsx +22 -0
- package/components/docs/docs-mobile-nav-context.tsx +27 -0
- package/components/docs/docs-page.tsx +263 -0
- package/components/docs/docs-search.tsx +303 -0
- package/components/docs/docs-sidebar.tsx +165 -0
- package/components/docs/docs-topbar.tsx +32 -0
- package/components/docs/dropdown-doc-page.tsx +522 -0
- package/components/docs/getting-started-doc-page.tsx +205 -0
- package/components/docs/label-doc-page.tsx +173 -0
- package/components/docs/loaders-doc-page.tsx +244 -0
- package/components/docs/menu-doc-page.tsx +373 -0
- package/components/docs/modal-doc-page.tsx +436 -0
- package/components/docs/next-steps.tsx +53 -0
- package/components/docs/pagination-doc-page.tsx +316 -0
- package/components/docs/progress-doc-page.tsx +387 -0
- package/components/docs/radio-doc-page.tsx +270 -0
- package/components/docs/skeleton-doc-page.tsx +230 -0
- package/components/docs/stepper-doc-page.tsx +309 -0
- package/components/docs/switch-doc-page.tsx +264 -0
- package/components/docs/table-doc-page.tsx +689 -0
- package/components/docs/tabs-doc-page.tsx +359 -0
- package/components/docs/theming-doc-page.tsx +243 -0
- package/components/docs/tooltip-doc-page.tsx +357 -0
- package/components/docs/usage-section.tsx +21 -0
- package/components/icons/discord.tsx +9 -0
- package/components/icons/github.tsx +9 -0
- package/components/icons/x.tsx +9 -0
- package/components/installation-section.tsx +34 -0
- package/components/landing/feature-highlights.tsx +105 -0
- package/components/landing/footer-strip.tsx +45 -0
- package/components/landing/hero-card.tsx +14 -0
- package/components/landing/hero-spotlight.tsx +126 -0
- package/components/landing/hero.tsx +64 -0
- package/components/landing/navbar.tsx +44 -0
- package/components/landing/quick-start-section.tsx +59 -0
- package/components/landing/site-footer.tsx +55 -0
- package/components/theme-provider.tsx +60 -0
- package/components/ui/accordion.tsx +174 -0
- package/components/ui/alert.tsx +103 -0
- package/components/ui/allinput.tsx +210 -0
- package/components/ui/avatar.tsx +179 -0
- package/components/ui/badge.tsx +52 -0
- package/components/ui/button.tsx +75 -0
- package/components/ui/card.tsx +105 -0
- package/components/ui/checkbox.tsx +130 -0
- package/components/ui/code-block.tsx +60 -0
- package/components/ui/data-table.tsx +235 -0
- package/components/ui/dialog.tsx +173 -0
- package/components/ui/dropdown.tsx +78 -0
- package/components/ui/feature-card.tsx +38 -0
- package/components/ui/input.tsx +44 -0
- package/components/ui/label.tsx +110 -0
- package/components/ui/loaders.tsx +139 -0
- package/components/ui/menu.tsx +118 -0
- package/components/ui/modal.tsx +399 -0
- package/components/ui/package-manager-tabs.tsx +40 -0
- package/components/ui/pagination.tsx +200 -0
- package/components/ui/progress.tsx +134 -0
- package/components/ui/radio.tsx +262 -0
- package/components/ui/skeleton.tsx +102 -0
- package/components/ui/steppers.tsx +309 -0
- package/components/ui/switch.tsx +153 -0
- package/components/ui/table.tsx +58 -0
- package/components/ui/tabs.tsx +166 -0
- package/components/ui/theme-toggle.tsx +60 -0
- package/components/ui/tooltip.tsx +238 -0
- package/data/color-palette.ts +35 -0
- package/data/docs-nav.ts +84 -0
- package/eslint.config.mjs +18 -0
- package/index.ts +8 -0
- package/lib/cn.ts +4 -0
- package/lib/color.ts +85 -0
- package/lib/og-image.tsx +138 -0
- package/lib/theme.ts +33 -0
- package/next.config.ts +7 -0
- package/package.json +30 -0
- package/postcss.config.mjs +7 -0
- package/public/dark.png +0 -0
- package/public/dark1.png +0 -0
- package/public/dark2.png +0 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/light.png +0 -0
- package/public/light1.png +0 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/video/hero-demo.mp4 +0 -0
- package/public/window.svg +1 -0
- package/tsconfig.json +34 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { useState } from "react";
|
|
4
|
+
import { Check, Copy, ToggleLeft } from "lucide-react";
|
|
5
|
+
import { Switch } from "@/components/ui/switch";
|
|
6
|
+
import { Tooltip } from "@/components/ui/tooltip";
|
|
7
|
+
import {
|
|
8
|
+
DocsAccessibility,
|
|
9
|
+
DocsApiSection,
|
|
10
|
+
DocsApiTable,
|
|
11
|
+
DocsPage,
|
|
12
|
+
DocsPageHeader,
|
|
13
|
+
DocsSection,
|
|
14
|
+
DocsSectionGrid,
|
|
15
|
+
DocsSubsection,
|
|
16
|
+
} from "@/components/docs/docs-page";
|
|
17
|
+
import { cn } from "@/lib/cn";
|
|
18
|
+
|
|
19
|
+
type Size = "sm" | "md" | "lg";
|
|
20
|
+
|
|
21
|
+
const SIZES: Size[] = ["sm", "md", "lg"];
|
|
22
|
+
|
|
23
|
+
function codeFor(size: Size, disabled: boolean, withDescription: boolean, checked: boolean) {
|
|
24
|
+
const props = [
|
|
25
|
+
size !== "md" && `size="${size}"`,
|
|
26
|
+
checked && "defaultChecked",
|
|
27
|
+
disabled && "disabled",
|
|
28
|
+
]
|
|
29
|
+
.filter(Boolean)
|
|
30
|
+
.join(" ");
|
|
31
|
+
const descriptionLine = withDescription
|
|
32
|
+
? '\n description="Receive alerts on your device."'
|
|
33
|
+
: "";
|
|
34
|
+
const labelLine = `\n label="Enable notifications"`;
|
|
35
|
+
return `<Switch${labelLine}${descriptionLine}${props ? `\n ${props}` : ""}\n/>`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const API_ROWS = [
|
|
39
|
+
{ prop: "checked", type: "boolean", default: "—", description: "Controlled checked state" },
|
|
40
|
+
{ prop: "defaultChecked", type: "boolean", default: "false", description: "Initial checked state (uncontrolled)" },
|
|
41
|
+
{ prop: "onCheckedChange", type: "(checked: boolean) => void", default: "—", description: "Called when the switch is toggled" },
|
|
42
|
+
{ prop: "disabled", type: "boolean", default: "false", description: "Disables interaction" },
|
|
43
|
+
{ prop: "size", type: '"sm" | "md" | "lg"', default: '"md"', description: "Size of the switch track and thumb" },
|
|
44
|
+
{ prop: "label", type: "string", default: "—", description: "Label text beside the switch" },
|
|
45
|
+
{ prop: "description", type: "string", default: "—", description: "Supporting text below the label" },
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const ACCESSIBILITY_ITEMS = [
|
|
49
|
+
"Uses role=\"switch\" with aria-checked for screen readers.",
|
|
50
|
+
"Supports keyboard interaction with Space to toggle.",
|
|
51
|
+
"Provides a visible focus ring for keyboard users.",
|
|
52
|
+
"Pair with a label for all settings controls.",
|
|
53
|
+
"Use disabled state when a setting cannot be changed.",
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
export function SwitchDocPage() {
|
|
57
|
+
const [notifications, setNotifications] = React.useState(true);
|
|
58
|
+
const [marketing, setMarketing] = React.useState(false);
|
|
59
|
+
|
|
60
|
+
const [size, setSize] = useState<Size>("md");
|
|
61
|
+
const [disabled, setDisabled] = useState(false);
|
|
62
|
+
const [withDescription, setWithDescription] = useState(false);
|
|
63
|
+
const [checked, setChecked] = useState(true);
|
|
64
|
+
const [copied, setCopied] = useState(false);
|
|
65
|
+
|
|
66
|
+
const snippet = codeFor(size, disabled, withDescription, checked);
|
|
67
|
+
|
|
68
|
+
function copySnippet() {
|
|
69
|
+
navigator.clipboard.writeText(snippet).catch(() => {});
|
|
70
|
+
setCopied(true);
|
|
71
|
+
setTimeout(() => setCopied(false), 1200);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<DocsPage>
|
|
76
|
+
<DocsPageHeader
|
|
77
|
+
icon={ToggleLeft}
|
|
78
|
+
title="Switch"
|
|
79
|
+
description="A toggle control for binary on/off settings — ideal for preferences and feature flags."
|
|
80
|
+
/>
|
|
81
|
+
|
|
82
|
+
<DocsSection
|
|
83
|
+
first
|
|
84
|
+
title="Playground"
|
|
85
|
+
description="Build a switch and copy the exact markup — every combination, live."
|
|
86
|
+
>
|
|
87
|
+
<div className="overflow-hidden rounded-2xl border border-zinc-200 shadow-[0_2px_8px_rgba(0,0,0,0.04)] dark:border-zinc-800 dark:shadow-[0_2px_8px_rgba(0,0,0,0.2)]">
|
|
88
|
+
<div className="relative flex min-h-[11rem] items-center justify-center overflow-hidden bg-zinc-50 p-8 dark:bg-zinc-900/40">
|
|
89
|
+
<div
|
|
90
|
+
aria-hidden
|
|
91
|
+
className="pointer-events-none absolute inset-0 opacity-[0.4] dark:opacity-[0.15]"
|
|
92
|
+
style={{
|
|
93
|
+
backgroundImage:
|
|
94
|
+
"linear-gradient(to right, rgb(161 161 170 / 0.35) 1px, transparent 1px), linear-gradient(to bottom, rgb(161 161 170 / 0.35) 1px, transparent 1px)",
|
|
95
|
+
backgroundSize: "24px 24px",
|
|
96
|
+
}}
|
|
97
|
+
/>
|
|
98
|
+
<div
|
|
99
|
+
className="relative w-full max-w-xs animate-[pagination-pop_0.25s_ease-out]"
|
|
100
|
+
key={`${size}-${disabled}-${withDescription}-${checked}`}
|
|
101
|
+
>
|
|
102
|
+
<Switch
|
|
103
|
+
size={size}
|
|
104
|
+
disabled={disabled}
|
|
105
|
+
checked={checked}
|
|
106
|
+
onCheckedChange={setChecked}
|
|
107
|
+
label="Enable notifications"
|
|
108
|
+
description={withDescription ? "Receive alerts on your device." : undefined}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<div className="flex flex-col gap-5 border-t border-zinc-200 p-5 dark:border-zinc-800">
|
|
114
|
+
<div className="flex flex-wrap items-start justify-between gap-6">
|
|
115
|
+
<div>
|
|
116
|
+
<p className="mb-2 text-xs font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
|
117
|
+
Size
|
|
118
|
+
</p>
|
|
119
|
+
<div className="flex flex-wrap items-center gap-1 rounded-lg border border-zinc-200 bg-zinc-50 p-1 dark:border-zinc-800 dark:bg-zinc-900/60">
|
|
120
|
+
{SIZES.map((s) => (
|
|
121
|
+
<button
|
|
122
|
+
key={s}
|
|
123
|
+
type="button"
|
|
124
|
+
onClick={() => setSize(s)}
|
|
125
|
+
className={cn(
|
|
126
|
+
"rounded-md px-3 py-1.5 text-xs font-medium uppercase tracking-wide transition-colors",
|
|
127
|
+
size === s
|
|
128
|
+
? "bg-white text-zinc-900 shadow-sm dark:bg-zinc-800 dark:text-white"
|
|
129
|
+
: "text-zinc-500 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-200"
|
|
130
|
+
)}
|
|
131
|
+
>
|
|
132
|
+
{s}
|
|
133
|
+
</button>
|
|
134
|
+
))}
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div>
|
|
139
|
+
<p className="mb-2 text-xs font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
|
140
|
+
Description
|
|
141
|
+
</p>
|
|
142
|
+
<button
|
|
143
|
+
type="button"
|
|
144
|
+
onClick={() => setWithDescription((v) => !v)}
|
|
145
|
+
className={cn(
|
|
146
|
+
"flex h-[2.125rem] items-center gap-2 rounded-lg border px-3 text-xs font-medium transition-colors",
|
|
147
|
+
withDescription
|
|
148
|
+
? "border-zinc-900 bg-zinc-900 text-white dark:border-white dark:bg-white dark:text-zinc-900"
|
|
149
|
+
: "border-zinc-200 text-zinc-500 hover:border-zinc-300 dark:border-zinc-700 dark:text-zinc-400"
|
|
150
|
+
)}
|
|
151
|
+
>
|
|
152
|
+
<ToggleLeft className="h-3.5 w-3.5" />
|
|
153
|
+
{withDescription ? "Shown" : "Hidden"}
|
|
154
|
+
</button>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div>
|
|
158
|
+
<p className="mb-2 text-xs font-medium uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
|
|
159
|
+
State
|
|
160
|
+
</p>
|
|
161
|
+
<button
|
|
162
|
+
type="button"
|
|
163
|
+
onClick={() => setDisabled((v) => !v)}
|
|
164
|
+
className={cn(
|
|
165
|
+
"flex h-[2.125rem] items-center gap-2 rounded-lg border px-3 text-xs font-medium transition-colors",
|
|
166
|
+
disabled
|
|
167
|
+
? "border-zinc-900 bg-zinc-900 text-white dark:border-white dark:bg-white dark:text-zinc-900"
|
|
168
|
+
: "border-zinc-200 text-zinc-500 hover:border-zinc-300 dark:border-zinc-700 dark:text-zinc-400"
|
|
169
|
+
)}
|
|
170
|
+
>
|
|
171
|
+
<ToggleLeft className="h-3.5 w-3.5" />
|
|
172
|
+
{disabled ? "Disabled" : "Enabled"}
|
|
173
|
+
</button>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
<div className="flex items-center justify-between gap-3 rounded-xl bg-zinc-900 px-4 py-3 dark:bg-black">
|
|
178
|
+
<pre className="overflow-x-auto font-mono text-[13px] leading-relaxed text-zinc-100">
|
|
179
|
+
<code>{snippet}</code>
|
|
180
|
+
</pre>
|
|
181
|
+
<Tooltip content={copied ? "Copied!" : "Copy code"}>
|
|
182
|
+
<button
|
|
183
|
+
type="button"
|
|
184
|
+
onClick={copySnippet}
|
|
185
|
+
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-zinc-400 transition-colors hover:bg-white/10 hover:text-white"
|
|
186
|
+
>
|
|
187
|
+
{copied ? <Check className="h-4 w-4 text-emerald-400" /> : <Copy className="h-4 w-4" />}
|
|
188
|
+
</button>
|
|
189
|
+
</Tooltip>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</DocsSection>
|
|
194
|
+
|
|
195
|
+
<DocsSection
|
|
196
|
+
title="Basic Usage"
|
|
197
|
+
contentClassName="flex flex-wrap items-center gap-8"
|
|
198
|
+
>
|
|
199
|
+
<Switch />
|
|
200
|
+
<Switch defaultChecked />
|
|
201
|
+
</DocsSection>
|
|
202
|
+
|
|
203
|
+
<DocsSection title="With Label">
|
|
204
|
+
<div className="max-w-sm">
|
|
205
|
+
<Switch label="Notifications" defaultChecked />
|
|
206
|
+
</div>
|
|
207
|
+
</DocsSection>
|
|
208
|
+
|
|
209
|
+
<DocsSection title="With Description">
|
|
210
|
+
<div className="max-w-md">
|
|
211
|
+
<Switch
|
|
212
|
+
label="Dark mode"
|
|
213
|
+
description="Use the dark appearance throughout the application."
|
|
214
|
+
/>
|
|
215
|
+
</div>
|
|
216
|
+
</DocsSection>
|
|
217
|
+
|
|
218
|
+
<DocsSection>
|
|
219
|
+
<DocsSectionGrid>
|
|
220
|
+
<DocsSubsection title="Sizes">
|
|
221
|
+
<div className="flex flex-col gap-4">
|
|
222
|
+
<Switch size="sm" label="Small" defaultChecked />
|
|
223
|
+
<Switch size="md" label="Medium" defaultChecked />
|
|
224
|
+
<Switch size="lg" label="Large" defaultChecked />
|
|
225
|
+
</div>
|
|
226
|
+
</DocsSubsection>
|
|
227
|
+
<DocsSubsection title="Disabled">
|
|
228
|
+
<div className="flex flex-col gap-4">
|
|
229
|
+
<Switch label="Disabled off" disabled />
|
|
230
|
+
<Switch label="Disabled on" defaultChecked disabled />
|
|
231
|
+
</div>
|
|
232
|
+
</DocsSubsection>
|
|
233
|
+
</DocsSectionGrid>
|
|
234
|
+
</DocsSection>
|
|
235
|
+
|
|
236
|
+
<DocsSection
|
|
237
|
+
title="Notification Settings"
|
|
238
|
+
description="Interactive example with controlled state."
|
|
239
|
+
>
|
|
240
|
+
<div className="max-w-md rounded-xl border border-zinc-200 p-5 dark:border-zinc-800">
|
|
241
|
+
<div className="flex flex-col gap-5">
|
|
242
|
+
<Switch
|
|
243
|
+
label="Push notifications"
|
|
244
|
+
description="Receive alerts on your device."
|
|
245
|
+
checked={notifications}
|
|
246
|
+
onCheckedChange={setNotifications}
|
|
247
|
+
/>
|
|
248
|
+
<Switch
|
|
249
|
+
label="Marketing emails"
|
|
250
|
+
description="Get product updates and announcements."
|
|
251
|
+
checked={marketing}
|
|
252
|
+
onCheckedChange={setMarketing}
|
|
253
|
+
/>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
</DocsSection>
|
|
257
|
+
|
|
258
|
+
<DocsApiSection>
|
|
259
|
+
<DocsApiTable title="API Reference" rows={API_ROWS} />
|
|
260
|
+
<DocsAccessibility items={ACCESSIBILITY_ITEMS} />
|
|
261
|
+
</DocsApiSection>
|
|
262
|
+
</DocsPage>
|
|
263
|
+
);
|
|
264
|
+
}
|