@codelitdev/design-system 0.1.0-alpha.6 → 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/README.md +15 -15
- package/package.json +7 -7
- package/src/assets/logo-codelit.svg +1 -1
- package/src/assets/logo-courselit.svg +1 -1
- package/src/assets/logo-frontlit.svg +1 -1
- package/src/assets/logo-medialit.svg +1 -1
- package/src/assets/logo-sendlit.svg +1 -1
- package/src/components/actions/Button.tsx +10 -2
- package/src/components/actions/IconButton.tsx +9 -2
- package/src/components/display/Badge.tsx +1 -1
- package/src/components/display/Card.tsx +1 -1
- package/src/components/display/Tabs.tsx +21 -3
- package/src/components/feedback/Dialog.tsx +20 -3
- package/src/components/feedback/Loader.tsx +57 -15
- package/src/components/feedback/Toast.tsx +51 -4
- package/src/components/feedback/Tooltip.tsx +5 -1
- package/src/components/forms/Checkbox.tsx +30 -4
- package/src/components/forms/Input.tsx +2 -1
- package/src/components/forms/Radio.tsx +21 -3
- package/src/components/forms/Select.tsx +22 -5
- package/src/components/forms/Switch.tsx +18 -3
- package/src/components.css +489 -134
- package/src/index.ts +1 -1
- package/src/tokens/fonts.css +1 -1
- package/src/tokens/layout.css +4 -4
- package/src/tokens/products.css +8 -4
- package/src/tokens/typography.css +24 -13
package/README.md
CHANGED
|
@@ -16,17 +16,17 @@ under the `alpha` dist-tag.
|
|
|
16
16
|
> `latest` on a package's first-ever publish, regardless of `--tag` — this is
|
|
17
17
|
> unavoidable until a real stable version is cut, at which point publishing it
|
|
18
18
|
> moves `latest` forward automatically. Until then, **always pin the exact
|
|
19
|
-
> version** — do not `
|
|
19
|
+
> version** — do not `bun add @codelitdev/design-system` bare, and do not
|
|
20
20
|
> use a caret/tilde range (`^0.1.0-alpha.0` would still resolve to a
|
|
21
21
|
> prerelease, which is at least explicit — but a bare install with no version
|
|
22
22
|
> silently means "whatever `latest` is," which right now is this alpha).
|
|
23
23
|
|
|
24
24
|
```sh
|
|
25
|
-
|
|
25
|
+
bun add @codelitdev/design-system@0.1.0-alpha.6
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
Platform examples consume the package as `workspace:*`. Product repositories
|
|
29
|
+
consume an exact published version.
|
|
30
30
|
|
|
31
31
|
## Use in a shadcn app
|
|
32
32
|
|
|
@@ -85,7 +85,7 @@ Add the registry namespace to your app's `components.json`:
|
|
|
85
85
|
```jsonc
|
|
86
86
|
{
|
|
87
87
|
"registries": {
|
|
88
|
-
"@codelit": "https://raw.githubusercontent.com/codelitdev/design-system/
|
|
88
|
+
"@codelit": "https://raw.githubusercontent.com/codelitdev/platform/main/packages/design-system/public/r/{name}.json"
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
```
|
|
@@ -93,13 +93,13 @@ Add the registry namespace to your app's `components.json`:
|
|
|
93
93
|
Then install components like any other shadcn component:
|
|
94
94
|
|
|
95
95
|
```sh
|
|
96
|
-
|
|
96
|
+
bunx shadcn@latest add @codelit/button @codelit/badge @codelit/card
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
Or install a single component directly by URL, no config:
|
|
100
100
|
|
|
101
101
|
```sh
|
|
102
|
-
|
|
102
|
+
bunx shadcn@latest add https://raw.githubusercontent.com/codelitdev/platform/main/packages/design-system/public/r/button.json
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
### Available components
|
|
@@ -126,28 +126,28 @@ npx shadcn@latest add https://raw.githubusercontent.com/codelitdev/design-system
|
|
|
126
126
|
Install everything at once:
|
|
127
127
|
|
|
128
128
|
```sh
|
|
129
|
-
|
|
129
|
+
bunx shadcn@latest add @codelit/button @codelit/icon-button @codelit/badge @codelit/card \
|
|
130
130
|
@codelit/input @codelit/textarea @codelit/label @codelit/checkbox @codelit/radio-group \
|
|
131
131
|
@codelit/switch @codelit/select @codelit/tabs @codelit/dialog @codelit/dropdown-menu \
|
|
132
132
|
@codelit/tooltip @codelit/toast
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
**Maintainers:** component sources live in `registry/codelit/ui/`. After changing
|
|
136
|
-
one, rebuild the served JSON with `
|
|
136
|
+
one, rebuild the served JSON with `bun run registry:build` (→ `public/r/*.json`) and
|
|
137
137
|
commit it — the raw-URL install serves those committed files.
|
|
138
138
|
|
|
139
139
|
## Publishing
|
|
140
140
|
|
|
141
|
-
Prereleases go under the `alpha` dist-tag so a plain `
|
|
142
|
-
one.
|
|
143
|
-
|
|
141
|
+
Prereleases go under the `alpha` dist-tag so a plain `bun add` never grabs
|
|
142
|
+
one. Releases are driven from the Platform root through Changesets; do not run
|
|
143
|
+
`bun publish` from this package directory:
|
|
144
144
|
|
|
145
145
|
```sh
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
bun run changeset
|
|
147
|
+
bun run release:alpha
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
-
Verify: `
|
|
150
|
+
Verify: `bun info @codelitdev/design-system --json` should show the
|
|
151
151
|
prerelease under `alpha` and leave `latest` untouched.
|
|
152
152
|
|
|
153
153
|
## License
|
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codelitdev/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
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",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/codelitdev/
|
|
9
|
+
"url": "git+https://github.com/codelitdev/platform.git",
|
|
10
|
+
"directory": "packages/design-system"
|
|
10
11
|
},
|
|
11
|
-
"homepage": "https://github.com/codelitdev/design-system#readme",
|
|
12
|
+
"homepage": "https://github.com/codelitdev/platform/tree/main/packages/design-system#readme",
|
|
12
13
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/codelitdev/
|
|
14
|
+
"url": "https://github.com/codelitdev/platform/issues"
|
|
14
15
|
},
|
|
15
16
|
"main": "src/index.ts",
|
|
16
17
|
"types": "src/index.ts",
|
|
17
18
|
"scripts": {
|
|
18
19
|
"check": "tsc --noEmit && esbuild src/index.ts --bundle --platform=browser --format=esm --jsx=automatic --external:react --external:react-dom --outfile=/tmp/design-system-check.js",
|
|
19
|
-
"release:alpha": "npm run check && npm publish --tag alpha",
|
|
20
20
|
"registry:build": "shadcn build"
|
|
21
21
|
},
|
|
22
22
|
"exports": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public",
|
|
34
|
-
"tag": "
|
|
34
|
+
"tag": "latest"
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"src",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
],
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/react": "^19.2.17",
|
|
44
|
-
"@types/react-dom": "^19.2.
|
|
44
|
+
"@types/react-dom": "^19.2.5",
|
|
45
45
|
"esbuild": "^0.28.1",
|
|
46
46
|
"lucide-react": "^0.544.0",
|
|
47
47
|
"react": "^19.2.8",
|
|
@@ -1 +1 @@
|
|
|
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
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><title>CodeLit logo</title><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"><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
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><title>CourseLit logo</title><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"><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
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><title>FrontLit logo</title><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"><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
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><title>MediaLit logo</title><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"><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>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><title>SendLit logo</title><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>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React from "react";
|
|
3
|
+
import type React from "react";
|
|
4
4
|
|
|
5
5
|
export interface ButtonProps {
|
|
6
6
|
/** Visual style. `soft` is the accent-wash variant unique to CodeLit. */
|
|
@@ -14,7 +14,15 @@ export interface ButtonProps {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/** Primary action affordance. Variants: primary, secondary, outline, ghost, soft, destructive. */
|
|
17
|
-
export function Button({
|
|
17
|
+
export function Button({
|
|
18
|
+
variant = "primary",
|
|
19
|
+
size = "md",
|
|
20
|
+
disabled,
|
|
21
|
+
children,
|
|
22
|
+
style,
|
|
23
|
+
onClick,
|
|
24
|
+
type = "button",
|
|
25
|
+
}: ButtonProps) {
|
|
18
26
|
return (
|
|
19
27
|
<button
|
|
20
28
|
type={type}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React from "react";
|
|
3
|
+
import type React from "react";
|
|
4
4
|
|
|
5
5
|
export interface IconButtonProps {
|
|
6
6
|
variant?: "ghost" | "outline";
|
|
@@ -14,7 +14,14 @@ export interface IconButtonProps {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/** Square icon-only button for toolbars, table rows, headers. */
|
|
17
|
-
export function IconButton({
|
|
17
|
+
export function IconButton({
|
|
18
|
+
variant = "ghost",
|
|
19
|
+
size = "md",
|
|
20
|
+
label,
|
|
21
|
+
children,
|
|
22
|
+
style,
|
|
23
|
+
onClick,
|
|
24
|
+
}: IconButtonProps) {
|
|
18
25
|
return (
|
|
19
26
|
<button
|
|
20
27
|
type="button"
|
|
@@ -14,7 +14,14 @@ export interface TabsProps {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/** Tab bar. Controlled via value/onChange or uncontrolled via defaultValue. */
|
|
17
|
-
export function Tabs({
|
|
17
|
+
export function Tabs({
|
|
18
|
+
tabs = [],
|
|
19
|
+
value,
|
|
20
|
+
defaultValue,
|
|
21
|
+
onChange,
|
|
22
|
+
variant = "segmented",
|
|
23
|
+
style,
|
|
24
|
+
}: TabsProps) {
|
|
18
25
|
const [internal, setInternal] = React.useState(defaultValue ?? tabs[0]);
|
|
19
26
|
const active = value ?? internal;
|
|
20
27
|
const pick = (t: string) => {
|
|
@@ -22,9 +29,20 @@ export function Tabs({ tabs = [], value, defaultValue, onChange, variant = "segm
|
|
|
22
29
|
if (onChange) onChange(t);
|
|
23
30
|
};
|
|
24
31
|
return (
|
|
25
|
-
<div
|
|
32
|
+
<div
|
|
33
|
+
className={`cl-tabs__list ${variant === "underline" ? "cl-tabs__list--underline" : ""}`}
|
|
34
|
+
role="tablist"
|
|
35
|
+
style={style}
|
|
36
|
+
>
|
|
26
37
|
{tabs.map((t) => (
|
|
27
|
-
<button
|
|
38
|
+
<button
|
|
39
|
+
key={t}
|
|
40
|
+
type="button"
|
|
41
|
+
role="tab"
|
|
42
|
+
className="cl-tabs__trigger"
|
|
43
|
+
data-active={String(t === active)}
|
|
44
|
+
onClick={() => pick(t)}
|
|
45
|
+
>
|
|
28
46
|
{t}
|
|
29
47
|
</button>
|
|
30
48
|
))}
|
|
@@ -12,21 +12,38 @@ export interface DialogProps {
|
|
|
12
12
|
style?: React.CSSProperties;
|
|
13
13
|
children?: React.ReactNode;
|
|
14
14
|
}
|
|
15
|
+
|
|
15
16
|
import { Button } from "../actions/Button";
|
|
16
17
|
|
|
17
18
|
/** Modal dialog with scrim. Controlled: open + onClose. */
|
|
18
|
-
export function Dialog({
|
|
19
|
+
export function Dialog({
|
|
20
|
+
open,
|
|
21
|
+
onClose,
|
|
22
|
+
title,
|
|
23
|
+
description,
|
|
24
|
+
footer,
|
|
25
|
+
children,
|
|
26
|
+
style,
|
|
27
|
+
}: DialogProps) {
|
|
19
28
|
if (!open) return null;
|
|
20
29
|
return (
|
|
21
30
|
<div className="cl-dialog__scrim" onClick={onClose}>
|
|
22
|
-
<div
|
|
31
|
+
<div
|
|
32
|
+
className="cl-dialog"
|
|
33
|
+
role="dialog"
|
|
34
|
+
aria-modal="true"
|
|
35
|
+
style={style}
|
|
36
|
+
onClick={(e) => e.stopPropagation()}
|
|
37
|
+
>
|
|
23
38
|
{title ? <h2 className="cl-dialog__title">{title}</h2> : null}
|
|
24
39
|
{description ? <p className="cl-dialog__description">{description}</p> : null}
|
|
25
40
|
{children}
|
|
26
41
|
<div className="cl-dialog__footer">
|
|
27
42
|
{footer ?? (
|
|
28
43
|
<React.Fragment>
|
|
29
|
-
<Button variant="outline" onClick={onClose}>
|
|
44
|
+
<Button variant="outline" onClick={onClose}>
|
|
45
|
+
Cancel
|
|
46
|
+
</Button>
|
|
30
47
|
<Button onClick={onClose}>Confirm</Button>
|
|
31
48
|
</React.Fragment>
|
|
32
49
|
)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import type React from "react";
|
|
2
2
|
|
|
3
3
|
export interface LoaderProps {
|
|
4
4
|
/** Which product mark to draw. Omit for the CodeLit house mark (amber). */
|
|
@@ -10,9 +10,18 @@ export interface LoaderProps {
|
|
|
10
10
|
|
|
11
11
|
const PATHS: Record<string, { d: string; transform?: string }[]> = {
|
|
12
12
|
codelit: [
|
|
13
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
{
|
|
14
|
+
d: "M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z",
|
|
15
|
+
transform: "translate(0,4.5)",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
d: "M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z",
|
|
19
|
+
transform: "translate(0,4.5) rotate(120 32 32)",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
d: "M32,23 C27.8,19 27,12.4 32,9 C37,12.4 36.2,19 32,23 Z",
|
|
23
|
+
transform: "translate(0,4.5) rotate(240 32 32)",
|
|
24
|
+
},
|
|
16
25
|
],
|
|
17
26
|
courselit: [
|
|
18
27
|
{ d: "M32,10 L38,28 L32,34 L26,28 Z" },
|
|
@@ -22,20 +31,47 @@ const PATHS: Record<string, { d: string; transform?: string }[]> = {
|
|
|
22
31
|
],
|
|
23
32
|
medialit: [
|
|
24
33
|
{ d: "M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z" },
|
|
25
|
-
{
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
{
|
|
35
|
+
d: "M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z",
|
|
36
|
+
transform: "rotate(90 32 32)",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
d: "M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z",
|
|
40
|
+
transform: "rotate(180 32 32)",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
d: "M32,24 C28.8,19 28.8,13.5 32,10 C35.2,13.5 35.2,19 32,24 Z",
|
|
44
|
+
transform: "rotate(270 32 32)",
|
|
45
|
+
},
|
|
28
46
|
],
|
|
29
47
|
sendlit: [
|
|
30
48
|
{ d: "M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5" },
|
|
31
|
-
{
|
|
32
|
-
|
|
49
|
+
{
|
|
50
|
+
d: "M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5",
|
|
51
|
+
transform: "rotate(120 32 32)",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
d: "M32,32 C23,29.5 18.5,20.5 23,12.5 C26.5,17 26.5,24 31,26.5",
|
|
55
|
+
transform: "rotate(240 32 32)",
|
|
56
|
+
},
|
|
33
57
|
],
|
|
34
58
|
frontlit: [
|
|
35
|
-
{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
59
|
+
{
|
|
60
|
+
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",
|
|
61
|
+
transform: "translate(41.19,22.81) rotate(45)",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
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",
|
|
65
|
+
transform: "translate(41.19,41.19) rotate(135)",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
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",
|
|
69
|
+
transform: "translate(22.81,41.19) rotate(225)",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
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",
|
|
73
|
+
transform: "translate(22.81,22.81) rotate(315)",
|
|
74
|
+
},
|
|
39
75
|
],
|
|
40
76
|
};
|
|
41
77
|
|
|
@@ -72,8 +108,14 @@ export function Loader({ product = "codelit", size = 40, style }: LoaderProps) {
|
|
|
72
108
|
strokeLinecap={joined ? undefined : "round"}
|
|
73
109
|
transform={product === "sendlit" ? "translate(-2,0)" : undefined}
|
|
74
110
|
>
|
|
75
|
-
{paths.map((p
|
|
76
|
-
<path
|
|
111
|
+
{paths.map((p) => (
|
|
112
|
+
<path
|
|
113
|
+
key={`${p.d}:${p.transform ?? ""}`}
|
|
114
|
+
d={p.d}
|
|
115
|
+
transform={p.transform}
|
|
116
|
+
strokeDasharray={200}
|
|
117
|
+
className="cl-loader__path"
|
|
118
|
+
/>
|
|
77
119
|
))}
|
|
78
120
|
</g>
|
|
79
121
|
</svg>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import type React from "react";
|
|
2
2
|
|
|
3
3
|
export interface ToastProps {
|
|
4
4
|
variant?: "default" | "success" | "destructive";
|
|
@@ -8,9 +8,56 @@ export interface ToastProps {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const icons = {
|
|
11
|
-
default:
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
default: (
|
|
12
|
+
<svg
|
|
13
|
+
aria-hidden="true"
|
|
14
|
+
width="16"
|
|
15
|
+
height="16"
|
|
16
|
+
viewBox="0 0 24 24"
|
|
17
|
+
fill="none"
|
|
18
|
+
stroke="currentColor"
|
|
19
|
+
strokeWidth="2"
|
|
20
|
+
strokeLinecap="round"
|
|
21
|
+
strokeLinejoin="round"
|
|
22
|
+
>
|
|
23
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
24
|
+
<path d="M12 16v-4"></path>
|
|
25
|
+
<path d="M12 8h.01"></path>
|
|
26
|
+
</svg>
|
|
27
|
+
),
|
|
28
|
+
success: (
|
|
29
|
+
<svg
|
|
30
|
+
aria-hidden="true"
|
|
31
|
+
width="16"
|
|
32
|
+
height="16"
|
|
33
|
+
viewBox="0 0 24 24"
|
|
34
|
+
fill="none"
|
|
35
|
+
stroke="currentColor"
|
|
36
|
+
strokeWidth="2"
|
|
37
|
+
strokeLinecap="round"
|
|
38
|
+
strokeLinejoin="round"
|
|
39
|
+
>
|
|
40
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
41
|
+
<path d="m9 12 2 2 4-4"></path>
|
|
42
|
+
</svg>
|
|
43
|
+
),
|
|
44
|
+
destructive: (
|
|
45
|
+
<svg
|
|
46
|
+
aria-hidden="true"
|
|
47
|
+
width="16"
|
|
48
|
+
height="16"
|
|
49
|
+
viewBox="0 0 24 24"
|
|
50
|
+
fill="none"
|
|
51
|
+
stroke="currentColor"
|
|
52
|
+
strokeWidth="2"
|
|
53
|
+
strokeLinecap="round"
|
|
54
|
+
strokeLinejoin="round"
|
|
55
|
+
>
|
|
56
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
57
|
+
<path d="M12 8v4"></path>
|
|
58
|
+
<path d="M12 16h.01"></path>
|
|
59
|
+
</svg>
|
|
60
|
+
),
|
|
14
61
|
};
|
|
15
62
|
|
|
16
63
|
/** Notification card. Render inside a fixed bottom-right stack in real apps. */
|
|
@@ -22,7 +22,11 @@ export function Tooltip({ label, open, children, style }: TooltipProps) {
|
|
|
22
22
|
onMouseLeave={() => setHover(false)}
|
|
23
23
|
>
|
|
24
24
|
{children}
|
|
25
|
-
{show ?
|
|
25
|
+
{show ? (
|
|
26
|
+
<span className="cl-tooltip" role="tooltip">
|
|
27
|
+
{label}
|
|
28
|
+
</span>
|
|
29
|
+
) : null}
|
|
26
30
|
</span>
|
|
27
31
|
);
|
|
28
32
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React from "react";
|
|
3
|
+
import type React from "react";
|
|
4
4
|
|
|
5
5
|
export interface CheckboxProps {
|
|
6
6
|
label?: React.ReactNode;
|
|
@@ -14,12 +14,38 @@ export interface CheckboxProps {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/** Checkbox with label and optional sub-description. */
|
|
17
|
-
export function Checkbox({
|
|
17
|
+
export function Checkbox({
|
|
18
|
+
label,
|
|
19
|
+
description,
|
|
20
|
+
checked,
|
|
21
|
+
defaultChecked,
|
|
22
|
+
disabled,
|
|
23
|
+
onChange,
|
|
24
|
+
style,
|
|
25
|
+
}: CheckboxProps) {
|
|
18
26
|
return (
|
|
19
27
|
<label className={`cl-check ${disabled ? "cl-check--disabled" : ""}`} style={style}>
|
|
20
|
-
<input
|
|
28
|
+
<input
|
|
29
|
+
type="checkbox"
|
|
30
|
+
checked={checked}
|
|
31
|
+
defaultChecked={defaultChecked}
|
|
32
|
+
disabled={disabled}
|
|
33
|
+
onChange={onChange}
|
|
34
|
+
/>
|
|
21
35
|
<span className="cl-check__box">
|
|
22
|
-
<svg
|
|
36
|
+
<svg
|
|
37
|
+
aria-hidden="true"
|
|
38
|
+
width="12"
|
|
39
|
+
height="12"
|
|
40
|
+
viewBox="0 0 24 24"
|
|
41
|
+
fill="none"
|
|
42
|
+
stroke="currentColor"
|
|
43
|
+
strokeWidth="3.5"
|
|
44
|
+
strokeLinecap="round"
|
|
45
|
+
strokeLinejoin="round"
|
|
46
|
+
>
|
|
47
|
+
<path d="M20 6 9 17l-5-5"></path>
|
|
48
|
+
</svg>
|
|
23
49
|
</span>
|
|
24
50
|
{label ? (
|
|
25
51
|
<span className="cl-check__label">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React from "react";
|
|
3
|
+
import type React from "react";
|
|
4
4
|
|
|
5
5
|
export interface InputProps {
|
|
6
6
|
label?: React.ReactNode;
|
|
@@ -29,6 +29,7 @@ export function Input({ label, hint, error, multiline, style, ...rest }: InputPr
|
|
|
29
29
|
);
|
|
30
30
|
if (!label && !hint && !error) return control;
|
|
31
31
|
return (
|
|
32
|
+
/* biome-ignore lint/a11y/noLabelWithoutControl: the control is rendered inside this label. */
|
|
32
33
|
<label className="cl-field" style={style}>
|
|
33
34
|
{label ? <span className="cl-field__label">{label}</span> : null}
|
|
34
35
|
{control}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React from "react";
|
|
3
|
+
import type React from "react";
|
|
4
4
|
|
|
5
5
|
export interface RadioProps {
|
|
6
6
|
label?: React.ReactNode;
|
|
@@ -15,10 +15,28 @@ export interface RadioProps {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/** Radio button; group by sharing `name`. */
|
|
18
|
-
export function Radio({
|
|
18
|
+
export function Radio({
|
|
19
|
+
label,
|
|
20
|
+
description,
|
|
21
|
+
name,
|
|
22
|
+
value,
|
|
23
|
+
checked,
|
|
24
|
+
defaultChecked,
|
|
25
|
+
disabled,
|
|
26
|
+
onChange,
|
|
27
|
+
style,
|
|
28
|
+
}: RadioProps) {
|
|
19
29
|
return (
|
|
20
30
|
<label className={`cl-check ${disabled ? "cl-check--disabled" : ""}`} style={style}>
|
|
21
|
-
<input
|
|
31
|
+
<input
|
|
32
|
+
type="radio"
|
|
33
|
+
name={name}
|
|
34
|
+
value={value}
|
|
35
|
+
checked={checked}
|
|
36
|
+
defaultChecked={defaultChecked}
|
|
37
|
+
disabled={disabled}
|
|
38
|
+
onChange={onChange}
|
|
39
|
+
/>
|
|
22
40
|
<span className="cl-check__box cl-check__box--radio">
|
|
23
41
|
<span className="cl-check__radio-dot"></span>
|
|
24
42
|
</span>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React from "react";
|
|
3
|
+
import type React from "react";
|
|
4
4
|
|
|
5
5
|
export interface SelectProps {
|
|
6
6
|
label?: React.ReactNode;
|
|
@@ -21,19 +21,36 @@ export function Select({ label, hint, options = [], style, ...rest }: SelectProp
|
|
|
21
21
|
<select {...rest}>
|
|
22
22
|
{options.map((o) =>
|
|
23
23
|
typeof o === "string" ? (
|
|
24
|
-
<option key={o} value={o}>
|
|
24
|
+
<option key={o} value={o}>
|
|
25
|
+
{o}
|
|
26
|
+
</option>
|
|
25
27
|
) : (
|
|
26
|
-
<option key={o.value} value={o.value}>
|
|
27
|
-
|
|
28
|
+
<option key={o.value} value={o.value}>
|
|
29
|
+
{o.label}
|
|
30
|
+
</option>
|
|
31
|
+
),
|
|
28
32
|
)}
|
|
29
33
|
</select>
|
|
30
34
|
<span className="cl-select__chevron">
|
|
31
|
-
<svg
|
|
35
|
+
<svg
|
|
36
|
+
aria-hidden="true"
|
|
37
|
+
width="14"
|
|
38
|
+
height="14"
|
|
39
|
+
viewBox="0 0 24 24"
|
|
40
|
+
fill="none"
|
|
41
|
+
stroke="currentColor"
|
|
42
|
+
strokeWidth="2"
|
|
43
|
+
strokeLinecap="round"
|
|
44
|
+
strokeLinejoin="round"
|
|
45
|
+
>
|
|
46
|
+
<path d="m6 9 6 6 6-6"></path>
|
|
47
|
+
</svg>
|
|
32
48
|
</span>
|
|
33
49
|
</span>
|
|
34
50
|
);
|
|
35
51
|
if (!label && !hint) return <span style={style}>{control}</span>;
|
|
36
52
|
return (
|
|
53
|
+
/* biome-ignore lint/a11y/noLabelWithoutControl: the select control is rendered inside this label. */
|
|
37
54
|
<label className="cl-field" style={style}>
|
|
38
55
|
{label ? <span className="cl-field__label">{label}</span> : null}
|
|
39
56
|
{control}
|