@codelitdev/design-system 0.1.0-alpha.2 → 0.1.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -64,6 +64,14 @@ module.exports = {
64
64
 
65
65
  6. Logos: `@codelitdev/design-system/assets/logo-<product>.svg`.
66
66
 
67
+ 7. Loaders — a drawn-from-the-logo spinner, not a static asset:
68
+ ```tsx
69
+ import { Loader } from "@codelitdev/design-system";
70
+ <Loader product="sendlit" size={32} />
71
+ ```
72
+ Renders in `currentColor`, same as an icon component — wrap it (or an ancestor) in
73
+ whatever sets the color you want, e.g. `className="text-primary"` for the product accent.
74
+
67
75
  ## Components (shadcn registry)
68
76
 
69
77
  The design system ships its components as a **shadcn registry** so every product
@@ -111,6 +119,7 @@ npx shadcn@latest add https://raw.githubusercontent.com/codelitdev/design-system
111
119
  | `select` | Trigger matches `input`; token-styled popover |
112
120
  | `tabs` | Segmented; active trigger lifts onto a card surface |
113
121
  | `dialog` | Warm scrim, 16px radius; full Radix parts |
122
+ | `dropdown-menu` | Matches `select`'s popover treatment; full Radix parts incl. checkbox/radio items and submenus |
114
123
  | `tooltip` | Dark chip; `TooltipProvider` included |
115
124
  | `toast` | Presentational card (`default`/`success`/`destructive`) — drive with your own queue |
116
125
 
@@ -119,7 +128,8 @@ Install everything at once:
119
128
  ```sh
120
129
  npx shadcn@latest add @codelit/button @codelit/icon-button @codelit/badge @codelit/card \
121
130
  @codelit/input @codelit/textarea @codelit/label @codelit/checkbox @codelit/radio-group \
122
- @codelit/switch @codelit/select @codelit/tabs @codelit/dialog @codelit/tooltip @codelit/toast
131
+ @codelit/switch @codelit/select @codelit/tabs @codelit/dialog @codelit/dropdown-menu \
132
+ @codelit/tooltip @codelit/toast
123
133
  ```
124
134
 
125
135
  **Maintainers:** component sources live in `registry/codelit/ui/`. After changing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codelitdev/design-system",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.4",
4
4
  "description": "Shared CodeLit design tokens, Tailwind preset, and React primitives for CourseLit, MediaLit, SendLit, and FrontLit.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "CodeLit",
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><rect width="64" height="64" rx="18" fill="oklch(0.66 0.14 60)"></rect><circle cx="30" cy="37" r="10.5" fill="white"></circle><circle cx="42" cy="20" r="5" fill="white"></circle></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><g fill="none" stroke="oklch(0.62 0.16 60)" stroke-width="2.6"><path d="M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z" transform="translate(0,4.5)"></path><path d="M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z" transform="translate(0,4.5) rotate(120 32 32)"></path><path d="M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z" transform="translate(0,4.5) rotate(240 32 32)"></path></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><rect width="64" height="64" rx="18" fill="oklch(0.6 0.14 30)"></rect><circle cx="30" cy="37" r="10.5" fill="white"></circle><circle cx="42" cy="20" r="5" fill="white"></circle></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><g fill="oklch(0.62 0.16 30 / 0.18)" stroke="oklch(0.62 0.16 30)" stroke-width="2.6" stroke-linejoin="round"><path d="M32,10 L38,28 L32,34 L26,28 Z"></path><path d="M32,10 L38,28 L32,34 L26,28 Z" transform="rotate(90 32 32)"></path><path d="M32,10 L38,28 L32,34 L26,28 Z" transform="rotate(180 32 32)"></path><path d="M32,10 L38,28 L32,34 L26,28 Z" transform="rotate(270 32 32)"></path></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><rect width="64" height="64" rx="18" fill="oklch(0.6 0.14 230)"></rect><circle cx="30" cy="37" r="10.5" fill="white"></circle><circle cx="42" cy="20" r="5" fill="white"></circle></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><g fill="oklch(0.62 0.16 230 / 0.15)" stroke="oklch(0.62 0.16 230)" stroke-width="2.4" stroke-linejoin="round"><path d="M0,-11 C5.5,-5.5 5.5,5.5 0,11 C-5.5,5.5 -5.5,-5.5 0,-11 Z" transform="translate(41.19,22.81) rotate(45)"></path><path d="M0,-11 C5.5,-5.5 5.5,5.5 0,11 C-5.5,5.5 -5.5,-5.5 0,-11 Z" transform="translate(41.19,41.19) rotate(135)"></path><path d="M0,-11 C5.5,-5.5 5.5,5.5 0,11 C-5.5,5.5 -5.5,-5.5 0,-11 Z" transform="translate(22.81,41.19) rotate(225)"></path><path d="M0,-11 C5.5,-5.5 5.5,5.5 0,11 C-5.5,5.5 -5.5,-5.5 0,-11 Z" transform="translate(22.81,22.81) rotate(315)"></path></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><rect width="64" height="64" rx="18" fill="oklch(0.6 0.14 300)"></rect><circle cx="30" cy="37" r="10.5" fill="white"></circle><circle cx="42" cy="20" r="5" fill="white"></circle></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><g fill="oklch(0.62 0.16 300 / 0.15)" stroke="oklch(0.62 0.16 300)" stroke-width="2.6" stroke-linejoin="round"><path d="M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z"></path><path d="M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z" transform="rotate(90 32 32)"></path><path d="M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z" transform="rotate(180 32 32)"></path><path d="M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z" transform="rotate(270 32 32)"></path></g></svg>
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><rect width="64" height="64" rx="18" fill="oklch(0.6 0.14 150)"></rect><circle cx="30" cy="37" r="10.5" fill="white"></circle><circle cx="42" cy="20" r="5" fill="white"></circle></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><g fill="none" stroke="oklch(0.62 0.16 150)" stroke-width="2.6" stroke-linecap="round" transform="translate(-2,0)"><path d="M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5"></path><path d="M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5" transform="rotate(120 32 32)"></path><path d="M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5" transform="rotate(240 32 32)"></path></g></svg>
@@ -0,0 +1,5 @@
1
+ Loading spinner, drawn from the product's own logo mark rather than a generic spinner. Petals draw in and out together, in sync.
2
+
3
+ ```jsx
4
+ <Loader product="sendlit" size={32} />
5
+ ```
@@ -0,0 +1,81 @@
1
+ import React from "react";
2
+
3
+ export interface LoaderProps {
4
+ /** Which product mark to draw. Omit for the CodeLit house mark (amber). */
5
+ product?: "codelit" | "courselit" | "medialit" | "sendlit" | "frontlit";
6
+ /** Pixel size, square. Default 40. */
7
+ size?: number;
8
+ style?: React.CSSProperties;
9
+ }
10
+
11
+ const PATHS: Record<string, { d: string; transform?: string }[]> = {
12
+ codelit: [
13
+ { d: "M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z", transform: "translate(0,4.5)" },
14
+ { d: "M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z", transform: "translate(0,4.5) rotate(120 32 32)" },
15
+ { d: "M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z", transform: "translate(0,4.5) rotate(240 32 32)" },
16
+ ],
17
+ courselit: [
18
+ { d: "M32,10 L38,28 L32,34 L26,28 Z" },
19
+ { d: "M32,10 L38,28 L32,34 L26,28 Z", transform: "rotate(90 32 32)" },
20
+ { d: "M32,10 L38,28 L32,34 L26,28 Z", transform: "rotate(180 32 32)" },
21
+ { d: "M32,10 L38,28 L32,34 L26,28 Z", transform: "rotate(270 32 32)" },
22
+ ],
23
+ medialit: [
24
+ { d: "M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z" },
25
+ { d: "M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z", transform: "rotate(90 32 32)" },
26
+ { d: "M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z", transform: "rotate(180 32 32)" },
27
+ { d: "M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z", transform: "rotate(270 32 32)" },
28
+ ],
29
+ sendlit: [
30
+ { d: "M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5" },
31
+ { d: "M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5", transform: "rotate(120 32 32)" },
32
+ { d: "M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5", transform: "rotate(240 32 32)" },
33
+ ],
34
+ frontlit: [
35
+ { d: "M0,-11 C5.5,-5.5 5.5,5.5 0,11 C-5.5,5.5 -5.5,-5.5 0,-11 Z", transform: "translate(41.19,22.81) rotate(45)" },
36
+ { d: "M0,-11 C5.5,-5.5 5.5,5.5 0,11 C-5.5,5.5 -5.5,-5.5 0,-11 Z", transform: "translate(41.19,41.19) rotate(135)" },
37
+ { d: "M0,-11 C5.5,-5.5 5.5,5.5 0,11 C-5.5,5.5 -5.5,-5.5 0,-11 Z", transform: "translate(22.81,41.19) rotate(225)" },
38
+ { d: "M0,-11 C5.5,-5.5 5.5,5.5 0,11 C-5.5,5.5 -5.5,-5.5 0,-11 Z", transform: "translate(22.81,22.81) rotate(315)" },
39
+ ],
40
+ };
41
+
42
+ const JOINED = new Set(["courselit", "medialit", "frontlit"]);
43
+ const SEND_STROKE_WIDTH = 2.6;
44
+
45
+ /**
46
+ * Loading spinner built from the product's own logo mark — petals draw in and
47
+ * out together, in sync, rather than one static SVG. Ships as a component
48
+ * (not `assets/loader-*.svg`) on purpose: the draw animation needs a real
49
+ * `@keyframes cl-draw` rule, and that can't be guaranteed to reach a
50
+ * standalone SVG asset through every consumption path (`<img src>` sandboxes
51
+ * out page CSS). `@keyframes cl-draw` lives in `components.css`; this
52
+ * component only sets the per-path `stroke-dasharray`/`animation`.
53
+ */
54
+ export function Loader({ product = "codelit", size = 40, style }: LoaderProps) {
55
+ const paths = PATHS[product] ?? PATHS.codelit;
56
+ const joined = JOINED.has(product);
57
+ return (
58
+ <svg
59
+ width={size}
60
+ height={size}
61
+ viewBox="0 0 64 64"
62
+ role="status"
63
+ aria-label="Loading"
64
+ className={`cl-loader cl-loader--${product}`}
65
+ style={style}
66
+ >
67
+ <g
68
+ fill="none"
69
+ stroke="currentColor"
70
+ strokeWidth={product === "frontlit" ? 2.4 : SEND_STROKE_WIDTH}
71
+ strokeLinejoin={joined ? "round" : undefined}
72
+ strokeLinecap={joined ? undefined : "round"}
73
+ transform={product === "sendlit" ? "translate(-2,0)" : undefined}
74
+ >
75
+ {paths.map((p, i) => (
76
+ <path key={i} d={p.d} transform={p.transform} strokeDasharray={200} className="cl-loader__path" />
77
+ ))}
78
+ </g>
79
+ </svg>
80
+ );
81
+ }
@@ -180,3 +180,15 @@ textarea.cl-input { height: auto; min-height: 80px; padding: 10px 12px; line-hei
180
180
  font: 500 0.75rem/1.3 var(--font-sans); padding: 6px 10px; border-radius: var(--radius-sm);
181
181
  white-space: nowrap; pointer-events: none; z-index: 60;
182
182
  }
183
+
184
+ /* ---------- Loader ---------- */
185
+ /* CodeLit — cl-loader: draw-in animation for <Loader> (src/components/feedback/Loader.tsx).
186
+ Each path sets stroke-dasharray:200 (safely larger than any real path length,
187
+ so it never falls back to a repeating dash pattern) and animation:cl-draw. */
188
+ @keyframes cl-draw {
189
+ 0%, 100% { stroke-dashoffset: 200; }
190
+ 50% { stroke-dashoffset: 0; }
191
+ }
192
+ .cl-loader__path {
193
+ animation: cl-draw 1.8s ease-in-out infinite;
194
+ }
package/src/index.ts CHANGED
@@ -4,6 +4,8 @@ export { Badge } from "./components/display/Badge";
4
4
  export { Card } from "./components/display/Card";
5
5
  export { Tabs } from "./components/display/Tabs";
6
6
  export { Dialog } from "./components/feedback/Dialog";
7
+ export { Loader } from "./components/feedback/Loader";
8
+ export type { LoaderProps } from "./components/feedback/Loader";
7
9
  export { Toast } from "./components/feedback/Toast";
8
10
  export { Tooltip } from "./components/feedback/Tooltip";
9
11
  export { Checkbox } from "./components/forms/Checkbox";