@cosxai/ui 0.25.0 → 1.0.0-alpha.1

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.
Files changed (165) hide show
  1. package/CHANGELOG.md +597 -0
  2. package/NOTICE +11 -0
  3. package/README.md +52 -0
  4. package/package.json +57 -7
  5. package/src/brand.css +13 -0
  6. package/src/components/Badge.tsx +68 -0
  7. package/src/components/Button.tsx +178 -0
  8. package/src/components/Card.tsx +42 -0
  9. package/src/components/Checkbox.tsx +67 -0
  10. package/src/components/Dialog.tsx +111 -0
  11. package/src/components/Field.tsx +66 -0
  12. package/src/components/Figure.tsx +30 -0
  13. package/src/components/Icon.tsx +32 -0
  14. package/src/components/IconButton.tsx +55 -0
  15. package/src/components/Input.tsx +74 -0
  16. package/src/components/Logo.tsx +62 -0
  17. package/src/components/Marker.tsx +26 -0
  18. package/src/components/MetaLabel.tsx +38 -0
  19. package/src/components/Radio.tsx +72 -0
  20. package/src/components/Select.tsx +351 -0
  21. package/src/components/Spinner.tsx +20 -0
  22. package/src/components/Switch.tsx +67 -0
  23. package/src/components/Table.tsx +196 -0
  24. package/src/components/Tabs.tsx +124 -0
  25. package/src/components/Tag.tsx +35 -0
  26. package/src/components/Textarea.tsx +46 -0
  27. package/src/components/ThemeProvider.tsx +80 -0
  28. package/src/components/Toast.tsx +159 -0
  29. package/src/components/Tooltip.tsx +57 -0
  30. package/src/components/core.test.tsx +242 -0
  31. package/src/components/forms-control.ts +36 -0
  32. package/src/components/forms.test.tsx +280 -0
  33. package/src/components/logo-art.ts +4 -0
  34. package/src/components/overlays.test.tsx +245 -0
  35. package/src/components/useButtonAction.ts +57 -0
  36. package/src/fonts.css +20 -0
  37. package/src/index.ts +34 -24
  38. package/src/lib/cn.ts +23 -6
  39. package/src/modes.css +10 -0
  40. package/src/styles.css +19 -0
  41. package/src/theme.css +143 -0
  42. package/src/tokens/colors.css +112 -0
  43. package/src/tokens/compat.css +36 -0
  44. package/src/tokens/elevation.css +14 -0
  45. package/src/tokens/motion.css +42 -0
  46. package/src/tokens/spacing.css +55 -0
  47. package/src/tokens/typography-cjk.css +42 -0
  48. package/src/tokens/typography.css +81 -0
  49. package/src/actionbar/ActionBar.tsx +0 -837
  50. package/src/actionbar/ActionBarButton.tsx +0 -111
  51. package/src/actionbar/ActionBarMenuGroup.tsx +0 -116
  52. package/src/actionbar/ActionBarModeHandle.tsx +0 -171
  53. package/src/actionbar/ActionBarProvider.tsx +0 -91
  54. package/src/actionbar/actionbar-context.ts +0 -45
  55. package/src/actionbar/index.ts +0 -28
  56. package/src/actionbar/types.ts +0 -147
  57. package/src/actionbar/useActionBarItems.ts +0 -60
  58. package/src/actionbar/useActionBarMode.ts +0 -144
  59. package/src/actionbar/useActionBarPanel.ts +0 -56
  60. package/src/actionbar/useActionBarStatusDot.ts +0 -49
  61. package/src/actionbar/useActionBarToast.ts +0 -33
  62. package/src/ambient/AmbientBackdrop.tsx +0 -74
  63. package/src/ambient/CommandInput.tsx +0 -107
  64. package/src/ambient/SuperbarStrip.tsx +0 -36
  65. package/src/ambient/index.ts +0 -6
  66. package/src/bento/BentoCell.tsx +0 -66
  67. package/src/bento/BentoGrid.tsx +0 -42
  68. package/src/bento/index.ts +0 -2
  69. package/src/command/CommandPalette.tsx +0 -329
  70. package/src/command/CommandProvider.tsx +0 -57
  71. package/src/command/command-context.ts +0 -12
  72. package/src/command/index.ts +0 -6
  73. package/src/command/rank.ts +0 -50
  74. package/src/command/types.ts +0 -37
  75. package/src/command/useCommandSource.ts +0 -37
  76. package/src/dialogs/DialogsProvider.tsx +0 -216
  77. package/src/dialogs/Modal.tsx +0 -260
  78. package/src/dialogs/Toast.tsx +0 -85
  79. package/src/dialogs/dialogs-context.ts +0 -6
  80. package/src/dialogs/index.ts +0 -10
  81. package/src/dialogs/types.ts +0 -37
  82. package/src/dialogs/useDialogs.ts +0 -8
  83. package/src/editorial/EditorialSpotlight.tsx +0 -63
  84. package/src/editorial/Folio.tsx +0 -52
  85. package/src/editorial/PlateMarker.tsx +0 -33
  86. package/src/editorial/RomanSection.tsx +0 -65
  87. package/src/editorial/RunningMarginalia.tsx +0 -65
  88. package/src/editorial/index.ts +0 -10
  89. package/src/hooks/index.ts +0 -5
  90. package/src/hooks/useKeyboardHotkey.ts +0 -93
  91. package/src/hooks/useReducedMotion.ts +0 -20
  92. package/src/hooks/useViewport.ts +0 -61
  93. package/src/layout/Breadcrumb.tsx +0 -74
  94. package/src/layout/LeftNavRail.tsx +0 -139
  95. package/src/layout/MobileTabBar.tsx +0 -101
  96. package/src/layout/NavItem.tsx +0 -128
  97. package/src/layout/NavSearchTrigger.tsx +0 -88
  98. package/src/layout/NavSection.tsx +0 -40
  99. package/src/layout/RightSidebarPanel.tsx +0 -111
  100. package/src/layout/Shell.tsx +0 -91
  101. package/src/layout/SidePanel.tsx +0 -316
  102. package/src/layout/StickyBanner.tsx +0 -83
  103. package/src/layout/Topbar.tsx +0 -68
  104. package/src/layout/index.ts +0 -24
  105. package/src/layout/useNavRailState.ts +0 -69
  106. package/src/lib/time-utils.ts +0 -44
  107. package/src/neobrutalism/Marquee.tsx +0 -81
  108. package/src/neobrutalism/Sticker.tsx +0 -71
  109. package/src/neobrutalism/index.ts +0 -4
  110. package/src/primitives/Avatar.tsx +0 -53
  111. package/src/primitives/Button.tsx +0 -67
  112. package/src/primitives/Card.tsx +0 -41
  113. package/src/primitives/Checkbox.tsx +0 -87
  114. package/src/primitives/Chip.tsx +0 -191
  115. package/src/primitives/Combobox.tsx +0 -507
  116. package/src/primitives/CopyField.tsx +0 -139
  117. package/src/primitives/CountBadge.tsx +0 -50
  118. package/src/primitives/Input.tsx +0 -204
  119. package/src/primitives/Kbd.tsx +0 -45
  120. package/src/primitives/MentionCombobox.tsx +0 -612
  121. package/src/primitives/MultiCombobox.tsx +0 -327
  122. package/src/primitives/PageHeader.tsx +0 -77
  123. package/src/primitives/Radio.tsx +0 -131
  124. package/src/primitives/SegmentedControl.tsx +0 -135
  125. package/src/primitives/Select.tsx +0 -779
  126. package/src/primitives/SignaturePad.tsx +0 -461
  127. package/src/primitives/Tag.tsx +0 -56
  128. package/src/primitives/Textarea.tsx +0 -62
  129. package/src/primitives/ToggleSwitch.tsx +0 -79
  130. package/src/primitives/Tooltip.tsx +0 -213
  131. package/src/primitives/index.ts +0 -53
  132. package/src/pwa/InstallPromptBanner.tsx +0 -132
  133. package/src/pwa/index.ts +0 -4
  134. package/src/pwa/manifest.template.json +0 -20
  135. package/src/pwa/registerSW.ts +0 -55
  136. package/src/riso/Halftone.tsx +0 -85
  137. package/src/riso/Misregister.tsx +0 -63
  138. package/src/riso/RisoStamp.tsx +0 -76
  139. package/src/riso/index.ts +0 -3
  140. package/src/sketch/HandUnderline.tsx +0 -53
  141. package/src/sketch/RoughArrow.tsx +0 -91
  142. package/src/sketch/RoughBox.tsx +0 -73
  143. package/src/sketch/StickyNote.tsx +0 -56
  144. package/src/sketch/index.ts +0 -4
  145. package/src/styles/base.css +0 -186
  146. package/src/styles/chrome-ambient.css +0 -235
  147. package/src/styles/chrome-bento.css +0 -192
  148. package/src/styles/chrome-editorial.css +0 -168
  149. package/src/styles/chrome-neobrutalism.css +0 -326
  150. package/src/styles/chrome-riso.css +0 -339
  151. package/src/styles/chrome-sketch.css +0 -362
  152. package/src/styles/chrome-swiss.css +0 -265
  153. package/src/styles/chrome-terminal.css +0 -272
  154. package/src/styles/fonts.css +0 -1034
  155. package/src/styles/index.css +0 -343
  156. package/src/styles/tokens.css +0 -941
  157. package/src/terminal/AsciiBox.tsx +0 -65
  158. package/src/terminal/BrailleSpinner.tsx +0 -46
  159. package/src/terminal/index.ts +0 -4
  160. package/src/theme/ThemeProvider.tsx +0 -99
  161. package/src/theme/index.ts +0 -6
  162. package/src/theme/inline-script.ts +0 -40
  163. package/src/theme/theme-context.ts +0 -7
  164. package/src/theme/types.ts +0 -39
  165. package/src/theme/useTheme.ts +0 -8
@@ -1,204 +0,0 @@
1
- import { forwardRef, useId, type InputHTMLAttributes, type ReactNode } from "react";
2
- import { cn } from "../lib/cn";
3
-
4
- // Styled text input with optional label + error + helper text.
5
- // Three states: idle / focused / invalid. Focus ring + invalid border
6
- // both via :focus-visible / aria-invalid CSS — no JS branching.
7
- //
8
- // Optional `prefix` / `suffix` slots render INSIDE the bordered
9
- // field, separated from the input by a subtle hairline divider.
10
- // Common patterns:
11
- // <Input prefix="https://" …/> → `https://[ acme ]`
12
- // <Input suffix=".cosx.dev" …/> → `[ acme ].cosx.dev`
13
- // Both can be set together. Prefer plain strings; ReactNode is
14
- // supported (e.g. icons) but inherits the muted helper colour.
15
-
16
- // We Omit "size" (HTMLInputElement's number-of-visible-chars attr;
17
- // conflicts with our absent layout-size prop and is rarely needed in
18
- // CSS-styled inputs) AND "prefix" (HTML's RDFa metadata attr —
19
- // taking that prop name here lets us expose an addon slot with the
20
- // most intuitive name; consumers needing the rare RDFa attr can
21
- // drop down to a native <input>).
22
- export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "prefix"> {
23
- label?: ReactNode;
24
- helper?: ReactNode;
25
- // Validation error message. When set, the input renders an
26
- // invalid border + colour and the helper slot is replaced by
27
- // the error text.
28
- error?: string | null;
29
- // Width preset — full, fixed, or auto (default full).
30
- fit?: "full" | "auto";
31
- // Inline addons rendered inside the bordered field. Use for
32
- // protocol prefixes ("https://"), domain suffixes (".cosx.dev"),
33
- // currency symbols, unit labels, search icons, etc.
34
- prefix?: ReactNode;
35
- suffix?: ReactNode;
36
- // Bare mode: render ONLY the <input> — no wrapper, label, helper,
37
- // error text, or field chrome (border / background / height). For
38
- // hosts that draw the field themselves (MultiCombobox's inline
39
- // layout, where chips and the input share one frame). `label`,
40
- // `helper`, `error` text, `prefix`, `suffix` and `fit` are ignored;
41
- // `aria-invalid` is still set from `error` so the host can react.
42
- // Default false.
43
- bare?: boolean;
44
- }
45
-
46
- const ADDON_STYLE = {
47
- display: "inline-flex",
48
- alignItems: "center",
49
- padding: "0 12px",
50
- font: "400 13px/1 var(--ck-font-mono, var(--ck-font-sans))",
51
- color: "var(--ck-text-secondary)",
52
- // `--ck-bg-muted` is the canonical "slightly recessed slab"
53
- // background — gives the addon visible separation from the input
54
- // (`--ck-bg-surface`) without needing a hard divider line. The
55
- // bg shift carries across all chromes; tokens.css defines a
56
- // muted tone per chrome (light + dark).
57
- background: "var(--ck-bg-muted)",
58
- whiteSpace: "nowrap" as const,
59
- userSelect: "none" as const,
60
- };
61
-
62
- export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
63
- { label, helper, error, fit = "full", prefix, suffix, bare = false, className, id, style, ...rest },
64
- ref,
65
- ) {
66
- const autoId = useId();
67
- const inputId = id ?? autoId;
68
- const hasAddon = !bare && (prefix != null || suffix != null);
69
- // `...rest` is spread FIRST so the `error`-derived aria-invalid (and,
70
- // non-bare, the helper/error text association) stays authoritative;
71
- // a consumer aria-describedby is merged with ours, not replaced.
72
- const ownDescribedBy = !bare && (helper || error) ? `${inputId}-helper` : undefined;
73
- const describedBy =
74
- [rest["aria-describedby"], ownDescribedBy].filter(Boolean).join(" ") || undefined;
75
-
76
- if (bare) {
77
- // Chrome presets restyle .ck-input with !important; the matching
78
- // .ck-input--bare rule in styles/index.css strips that again.
79
- return (
80
- <input
81
- ref={ref}
82
- id={inputId}
83
- {...rest}
84
- aria-invalid={error ? true : undefined}
85
- aria-describedby={describedBy}
86
- className={cn("ck-input", "ck-input--bare", className)}
87
- style={{
88
- minWidth: 0,
89
- width: "100%",
90
- height: 28,
91
- padding: "0 4px",
92
- font: "400 13px/1 var(--ck-font-sans)",
93
- background: "transparent",
94
- color: "var(--ck-text-primary)",
95
- border: "none",
96
- borderRadius: 0,
97
- boxShadow: "none",
98
- outline: "none",
99
- ...(style ?? {}),
100
- }}
101
- />
102
- );
103
- }
104
-
105
- // Border / radius live on the WRAPPER when there's an addon so the
106
- // addon + input share one continuous frame. Otherwise the input
107
- // itself carries the border (preserves the prior visual contract).
108
- const fieldBorder = `1px solid ${error ? "var(--ck-critical)" : "var(--ck-border-strong)"}`;
109
- const fieldRadius = "var(--ck-radius-sm)";
110
-
111
- const inputEl = (
112
- <input
113
- ref={ref}
114
- id={inputId}
115
- {...rest}
116
- aria-invalid={error ? true : undefined}
117
- aria-describedby={describedBy}
118
- className={cn("ck-input", hasAddon ? "ck-input--with-addon" : undefined)}
119
- style={{
120
- flex: hasAddon ? "1 1 auto" : undefined,
121
- minWidth: 0,
122
- height: hasAddon ? "100%" : 36,
123
- padding: "0 12px",
124
- font: "400 13px/1 var(--ck-font-sans)",
125
- background: "var(--ck-bg-surface)",
126
- color: "var(--ck-text-primary)",
127
- border: hasAddon ? "none" : fieldBorder,
128
- borderRadius: hasAddon ? 0 : fieldRadius,
129
- outline: "none",
130
- transition: "border-color var(--ck-dur-fast) var(--ck-ease)",
131
- ...(style ?? {}),
132
- }}
133
- />
134
- );
135
-
136
- return (
137
- <div
138
- className={cn("ck-input-field", className)}
139
- style={{
140
- display: "flex",
141
- flexDirection: "column",
142
- gap: 6,
143
- width: fit === "full" ? "100%" : undefined,
144
- // minWidth: 0 lets a parent flex container shrink this
145
- // wrapper past the inner addon-wrap's nowrap suffix content.
146
- // Without it, a long suffix (e.g. ".meta.test.cosx.dev")
147
- // sets a min-content floor that pushes the form wider than
148
- // its mobile viewport. Per-page CSS workarounds in consumer
149
- // apps only cover their own scope; fixing it at the primitive
150
- // catches every page.
151
- minWidth: 0,
152
- }}
153
- >
154
- {label && (
155
- <label
156
- htmlFor={inputId}
157
- className="ck-eyebrow"
158
- style={{ color: "var(--ck-text-secondary)" }}
159
- >
160
- {label}
161
- </label>
162
- )}
163
- {hasAddon ? (
164
- <div
165
- className="ck-input-addon-wrap"
166
- style={{
167
- display: "flex",
168
- alignItems: "stretch",
169
- height: 36,
170
- background: "var(--ck-bg-surface)",
171
- border: fieldBorder,
172
- borderRadius: fieldRadius,
173
- overflow: "hidden",
174
- }}
175
- >
176
- {prefix != null && (
177
- <span className="ck-input-addon ck-input-addon--prefix" style={ADDON_STYLE}>
178
- {prefix}
179
- </span>
180
- )}
181
- {inputEl}
182
- {suffix != null && (
183
- <span className="ck-input-addon ck-input-addon--suffix" style={ADDON_STYLE}>
184
- {suffix}
185
- </span>
186
- )}
187
- </div>
188
- ) : (
189
- inputEl
190
- )}
191
- {(helper || error) && (
192
- <div
193
- id={`${inputId}-helper`}
194
- style={{
195
- font: "400 11px/1.4 var(--ck-font-sans)",
196
- color: error ? "var(--ck-critical)" : "var(--ck-text-tertiary)",
197
- }}
198
- >
199
- {error ?? helper}
200
- </div>
201
- )}
202
- </div>
203
- );
204
- });
@@ -1,45 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import { cn } from "../lib/cn";
3
-
4
- // Keyboard hint pill — ⌘K, ⌃K, Shift, etc. Auto-translates "Mod"
5
- // to ⌘ on Mac and Ctrl elsewhere so docs strings can stay portable.
6
-
7
- export interface KbdProps {
8
- // "Mod" is replaced by ⌘ on Mac, Ctrl elsewhere. Otherwise rendered
9
- // verbatim — pass "Shift", "Enter", "↑", "K", etc.
10
- children: ReactNode;
11
- className?: string;
12
- }
13
-
14
- const isMac =
15
- typeof navigator !== "undefined" &&
16
- /Mac|iPhone|iPad|iPod/.test(navigator.platform);
17
-
18
- function renderChild(c: ReactNode): ReactNode {
19
- if (typeof c !== "string") return c;
20
- if (c === "Mod") return isMac ? "⌘" : "Ctrl";
21
- return c;
22
- }
23
-
24
- export function Kbd({ children, className }: KbdProps) {
25
- return (
26
- <kbd
27
- className={cn("ck-kbd", className)}
28
- style={{
29
- display: "inline-flex",
30
- alignItems: "center",
31
- justifyContent: "center",
32
- minWidth: 18,
33
- height: 18,
34
- padding: "0 5px",
35
- background: "var(--ck-bg-muted)",
36
- border: "1px solid var(--ck-border-subtle)",
37
- color: "var(--ck-text-secondary)",
38
- font: "500 11px/1 var(--ck-font-mono)",
39
- borderRadius: "var(--ck-radius-xs)",
40
- }}
41
- >
42
- {renderChild(children)}
43
- </kbd>
44
- );
45
- }