@cosxai/ui 0.7.0 → 0.8.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/package.json
CHANGED
|
@@ -568,12 +568,19 @@ const overlayStyle: React.CSSProperties = {
|
|
|
568
568
|
zIndex: 0,
|
|
569
569
|
};
|
|
570
570
|
|
|
571
|
+
// chipStyle must NOT add any horizontal or vertical space (no
|
|
572
|
+
// padding, no margin, no border) — the textarea's underlying
|
|
573
|
+
// `@Ben Zhang` glyphs occupy the natural text width, and any extra
|
|
574
|
+
// width on the overlay chip would shift every character after it
|
|
575
|
+
// out of alignment with the textarea's caret. Instead we lean on
|
|
576
|
+
// background + color + a tight border-radius to convey "chip"
|
|
577
|
+
// without adding layout. `font-weight` stays at the inherited
|
|
578
|
+
// value for the same reason: heavier weight changes glyph advance
|
|
579
|
+
// widths and drifts the trailing text by a sub-pixel per character.
|
|
571
580
|
const chipStyle: React.CSSProperties = {
|
|
572
|
-
|
|
573
|
-
borderRadius: 4,
|
|
581
|
+
borderRadius: 3,
|
|
574
582
|
background: "var(--ck-accent-soft, rgba(37, 99, 235, 0.12))",
|
|
575
583
|
color: "var(--ck-accent, #2563eb)",
|
|
576
|
-
fontWeight: 500,
|
|
577
584
|
};
|
|
578
585
|
|
|
579
586
|
const listboxStyle: React.CSSProperties = {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { cn } from "../lib/cn";
|
|
2
|
+
|
|
3
|
+
// Custom-styled radio — accent-bordered circle that becomes filled
|
|
4
|
+
// accent + white dot when checked. Paired with Checkbox: same
|
|
5
|
+
// disabled/label/suffix contract, same 16px hit target size. Use
|
|
6
|
+
// this anywhere you'd reach for a `<input type="radio">` — the
|
|
7
|
+
// native control renders as the OS accent (blue on macOS by
|
|
8
|
+
// default) which doesn't respect --ck-accent per workspace, and the
|
|
9
|
+
// unstyled defaults look inconsistent alongside our Checkbox.
|
|
10
|
+
//
|
|
11
|
+
// Radio is a single option in a group; the caller owns the group's
|
|
12
|
+
// selection state and passes `checked` + `onChange` per option.
|
|
13
|
+
// Radios with the same `name` still get the browser's native "one
|
|
14
|
+
// selected at a time" behaviour if you need form-post semantics; we
|
|
15
|
+
// forward it to a hidden native input so aria-pressed on the visual
|
|
16
|
+
// button doesn't drift from the actual form value.
|
|
17
|
+
|
|
18
|
+
export interface RadioProps {
|
|
19
|
+
checked: boolean;
|
|
20
|
+
onChange: (next: boolean) => void;
|
|
21
|
+
label?: React.ReactNode;
|
|
22
|
+
suffix?: React.ReactNode;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Native radio-group name. Optional but recommended: browsers
|
|
26
|
+
* enforce "only one checked at a time" for same-name radios, so
|
|
27
|
+
* passing a shared name is a belt-and-braces guard against a
|
|
28
|
+
* stale onChange handler leaving two visually-checked radios.
|
|
29
|
+
*/
|
|
30
|
+
name?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Value that lands in the form-post payload when this radio is
|
|
33
|
+
* checked. Only meaningful when `name` is also set.
|
|
34
|
+
*/
|
|
35
|
+
value?: string;
|
|
36
|
+
className?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function Radio({
|
|
40
|
+
checked,
|
|
41
|
+
onChange,
|
|
42
|
+
label,
|
|
43
|
+
suffix,
|
|
44
|
+
disabled,
|
|
45
|
+
name,
|
|
46
|
+
value,
|
|
47
|
+
className,
|
|
48
|
+
}: RadioProps) {
|
|
49
|
+
return (
|
|
50
|
+
<label
|
|
51
|
+
className={cn("ck-radio", className)}
|
|
52
|
+
style={{
|
|
53
|
+
display: "inline-flex",
|
|
54
|
+
alignItems: "center",
|
|
55
|
+
gap: 8,
|
|
56
|
+
font: "400 13px/1 var(--ck-font-sans)",
|
|
57
|
+
color: "var(--ck-text-secondary)",
|
|
58
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
59
|
+
opacity: disabled ? 0.5 : 1,
|
|
60
|
+
userSelect: "none",
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
<button
|
|
64
|
+
type="button"
|
|
65
|
+
role="radio"
|
|
66
|
+
aria-checked={checked}
|
|
67
|
+
disabled={disabled}
|
|
68
|
+
onClick={() => !disabled && !checked && onChange(true)}
|
|
69
|
+
style={{
|
|
70
|
+
width: 16,
|
|
71
|
+
height: 16,
|
|
72
|
+
borderRadius: "50%",
|
|
73
|
+
border: "1.5px solid var(--ck-accent)",
|
|
74
|
+
background: "transparent",
|
|
75
|
+
display: "inline-flex",
|
|
76
|
+
alignItems: "center",
|
|
77
|
+
justifyContent: "center",
|
|
78
|
+
padding: 0,
|
|
79
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
80
|
+
flexShrink: 0,
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
{checked && (
|
|
84
|
+
<span
|
|
85
|
+
aria-hidden
|
|
86
|
+
style={{
|
|
87
|
+
width: 8,
|
|
88
|
+
height: 8,
|
|
89
|
+
borderRadius: "50%",
|
|
90
|
+
background: "var(--ck-accent)",
|
|
91
|
+
display: "inline-block",
|
|
92
|
+
}}
|
|
93
|
+
/>
|
|
94
|
+
)}
|
|
95
|
+
</button>
|
|
96
|
+
{/* Hidden native input keeps the browser's same-name enforcement
|
|
97
|
+
+ lets consumers use the surrounding <form> for post payload. */}
|
|
98
|
+
{name && (
|
|
99
|
+
<input
|
|
100
|
+
type="radio"
|
|
101
|
+
name={name}
|
|
102
|
+
value={value}
|
|
103
|
+
checked={checked}
|
|
104
|
+
onChange={(e) => !disabled && onChange(e.target.checked)}
|
|
105
|
+
disabled={disabled}
|
|
106
|
+
tabIndex={-1}
|
|
107
|
+
aria-hidden
|
|
108
|
+
style={{
|
|
109
|
+
position: "absolute",
|
|
110
|
+
width: 1,
|
|
111
|
+
height: 1,
|
|
112
|
+
padding: 0,
|
|
113
|
+
margin: -1,
|
|
114
|
+
overflow: "hidden",
|
|
115
|
+
clip: "rect(0,0,0,0)",
|
|
116
|
+
whiteSpace: "nowrap",
|
|
117
|
+
border: 0,
|
|
118
|
+
}}
|
|
119
|
+
/>
|
|
120
|
+
)}
|
|
121
|
+
{label}
|
|
122
|
+
{suffix && (
|
|
123
|
+
<span style={{ color: "var(--ck-text-tertiary)" }}>{suffix}</span>
|
|
124
|
+
)}
|
|
125
|
+
</label>
|
|
126
|
+
);
|
|
127
|
+
}
|
package/src/primitives/index.ts
CHANGED
|
@@ -18,6 +18,8 @@ export { Textarea } from "./Textarea";
|
|
|
18
18
|
export type { TextareaProps } from "./Textarea";
|
|
19
19
|
export { Checkbox } from "./Checkbox";
|
|
20
20
|
export type { CheckboxProps } from "./Checkbox";
|
|
21
|
+
export { Radio } from "./Radio";
|
|
22
|
+
export type { RadioProps } from "./Radio";
|
|
21
23
|
export { ToggleSwitch } from "./ToggleSwitch";
|
|
22
24
|
export type { ToggleSwitchProps } from "./ToggleSwitch";
|
|
23
25
|
export { Tooltip } from "./Tooltip";
|