@jackbernnie/hiyf 0.1.0 → 0.1.2
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 +117 -0
- package/README.md +9 -0
- package/dist/components/Combobox.js +12 -9
- package/package.json +2 -1
package/AGENTS.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Building UI with `@jackbernnie/hiyf`
|
|
2
|
+
|
|
3
|
+
> Instructions for AI coding agents (Claude Code, Codex, Cursor, …). This project
|
|
4
|
+
> uses the **hiyf** design system with its **lockdown** lint. Build UI using
|
|
5
|
+
> **only** this system — off-system code fails the build on purpose.
|
|
6
|
+
|
|
7
|
+
## The three rules (these fail `npm run build`)
|
|
8
|
+
|
|
9
|
+
1. **No raw HTML elements** — never write `<div>`, `<span>`, `<p>`, `<h1>`–`<h6>`,
|
|
10
|
+
`<button>`, `<input>`, `<table>`, `<a>`, `<img>`, etc. Use `<Box>` / `<Text>`
|
|
11
|
+
or a component from `@jackbernnie/hiyf`. (`<pre>`/`<code>` are allowed for code.)
|
|
12
|
+
2. **No arbitrary Tailwind values** — never `p-[17px]`, `bg-[#abc]`, `w-[33%]`.
|
|
13
|
+
Use a design token. Standard utility classes (`flex`, `items-center`) are fine.
|
|
14
|
+
3. **No inline `style={{…}}`** — use a `<Box>` style prop or a component prop.
|
|
15
|
+
|
|
16
|
+
Also: never import the raw `@jackbernnie/hiyf/components/ui/*` layer — import the
|
|
17
|
+
closed wrapper from the package root.
|
|
18
|
+
|
|
19
|
+
## Setup (once per project)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @jackbernnie/hiyf
|
|
23
|
+
npm install -D hiyf-eslint-config
|
|
24
|
+
```
|
|
25
|
+
```css
|
|
26
|
+
/* global CSS — no StyleX/bundler plugin needed; styles are precompiled */
|
|
27
|
+
@import "tailwindcss";
|
|
28
|
+
@import "@jackbernnie/hiyf/theme.css";
|
|
29
|
+
@import "@jackbernnie/hiyf/styles.css";
|
|
30
|
+
@source "../node_modules/@jackbernnie/hiyf/dist";
|
|
31
|
+
```
|
|
32
|
+
```js
|
|
33
|
+
// eslint.config.mjs
|
|
34
|
+
import lockdown from 'hiyf-eslint-config'
|
|
35
|
+
export default [...lockdown]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Layout & text: `<Box>` and `<Text>`
|
|
39
|
+
|
|
40
|
+
`<Box>` is the layout primitive (defaults to `display:flex`). All style props take
|
|
41
|
+
**tokens only**, not raw CSS:
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import { Box, Text } from '@jackbernnie/hiyf'
|
|
45
|
+
|
|
46
|
+
<Box flexDirection="column" gap="m" padding="l"
|
|
47
|
+
backgroundColor="background-card" borderRadius="m" boxShadow="s">
|
|
48
|
+
<Text variant="heading-s">Title</Text>
|
|
49
|
+
<Text color="muted">Supporting copy</Text>
|
|
50
|
+
</Box>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`<Text>` renders all text. Pick a `variant` (a role), never a raw size.
|
|
54
|
+
|
|
55
|
+
## Token vocabulary (the entire allowed set)
|
|
56
|
+
|
|
57
|
+
| Prop | Tokens |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `padding` / `margin` / `gap` (and `p`/`m`/`px`/`py`/…) | `none` `xs`(4) `s`(8) `m`(12) `l`(16) `xl`(24) `2xl`(32) `3xl`(48) `4xl`(64) `5xl`(96) px |
|
|
60
|
+
| `borderRadius` | `none` `s`(8) `m`(12) `l`(16) `xl`(32) `full` |
|
|
61
|
+
| `backgroundColor` | `background-primary` `-secondary` `-card` `-inverse` `-success` `-warning` `-danger` `-pending` `-card-raised` |
|
|
62
|
+
| `color` (on Box) | `text-primary` `-secondary` `-tertiary` `-success` `-danger` `-warning` `-pending` |
|
|
63
|
+
| `borderColor` | `border-primary` `-secondary` `-warning` `-card` |
|
|
64
|
+
| `boxShadow` | `none` `s` `m` `l` `xl` |
|
|
65
|
+
| `transitionDuration` | `instant` `fast`(120) `base`(200) `slow`(320) `slower`(480) ms |
|
|
66
|
+
| `ease` | `standard` `decelerate` `accelerate` `spring` |
|
|
67
|
+
|
|
68
|
+
`<Text variant>`: `heading-2xl` `heading-xl` `heading-l` `heading-m` `heading-s`
|
|
69
|
+
`heading-xs` `heading-xxs` `body` `default` `label` `caption`.
|
|
70
|
+
`<Text color>`: `default` `muted` `disabled` `accent` `success` `warning` `danger`
|
|
71
|
+
`inverse` `white` `black` `inherit`. Also: `align`, `wrap`, `monospace`,
|
|
72
|
+
`truncate`, `tabularNums`, `formatter`.
|
|
73
|
+
|
|
74
|
+
Numeric `width`/`height` are allowed on `<Box>` for genuinely dynamic sizes
|
|
75
|
+
(`width={240}` → `240px`); reach for tokens for everything else.
|
|
76
|
+
|
|
77
|
+
## Components (import from `@jackbernnie/hiyf`)
|
|
78
|
+
|
|
79
|
+
Props are **intent-named and enumerated** — there is no `className`/`style` escape
|
|
80
|
+
hatch. A few key APIs:
|
|
81
|
+
|
|
82
|
+
- `Button` — `intent`: `primary | secondary | outline | ghost | danger`; `size`: `sm | md | lg`
|
|
83
|
+
- `Status` — `color`: `success | warning | danger | info | neutral`
|
|
84
|
+
- `Badge` — `tone`; `Alert` — `tone`: `neutral | info | success | warning | danger`
|
|
85
|
+
- `Card` (+ `CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`)
|
|
86
|
+
- `Select` / `Combobox` (`options`), `Table` (`columns`), `Tabs`/`Accordion` (item arrays)
|
|
87
|
+
|
|
88
|
+
Full catalog — actions: ButtonGroup, Input, InputGroup, InputOTP, Textarea, Select,
|
|
89
|
+
NativeSelect, Combobox, Checkbox, Switch, Slider, Toggle, ToggleGroup, RadioGroup,
|
|
90
|
+
Label, Field. Feedback/display: Status, Badge, Alert, Card, Progress, Skeleton,
|
|
91
|
+
Spinner, Avatar, Kbd, Empty, Toaster. Layout/data: Separator, AspectRatio,
|
|
92
|
+
ScrollArea, Table, Carousel, Grid, GridItem. Navigation: Tabs, Accordion,
|
|
93
|
+
Collapsible, Breadcrumb, Pagination, Command, NavigationMenu, Menubar. Overlays:
|
|
94
|
+
Dialog, AlertDialog, Sheet, Drawer, Popover, HoverCard, Tooltip, DropdownMenu,
|
|
95
|
+
ContextMenu. App shell & data viz: Sidebar, Resizable, Chart.
|
|
96
|
+
|
|
97
|
+
When unsure of a prop, check the component's TypeScript types — every prop is typed.
|
|
98
|
+
|
|
99
|
+
## When something you need doesn't exist
|
|
100
|
+
|
|
101
|
+
Work through this in order. **Don't get stuck, and don't expand the design system
|
|
102
|
+
for a single screen:**
|
|
103
|
+
|
|
104
|
+
1. **Express it with existing tokens/components first.** Most gaps aren't real.
|
|
105
|
+
2. **If it's clearly reusable**, add a token/variant/component to the design system.
|
|
106
|
+
3. **If it's a genuine one-off** — a dynamic value, a third-party integration, or a
|
|
107
|
+
single bespoke element — use the escape hatch: put
|
|
108
|
+
`// eslint-disable-next-line no-restricted-syntax` on that one line, with a short
|
|
109
|
+
comment explaining why.
|
|
110
|
+
|
|
111
|
+
List any escape hatches you used so they can be reviewed.
|
|
112
|
+
|
|
113
|
+
## Before you finish
|
|
114
|
+
|
|
115
|
+
Run `npm run lint` and `npm run build`. If either fails, fix the code until both
|
|
116
|
+
pass. **Green lint means the UI is on-system** — that is the actual guarantee, not
|
|
117
|
+
this document.
|
package/README.md
CHANGED
|
@@ -42,6 +42,15 @@ Ships compiled JS + types + CSS; works in Vite, Next.js (App Router — `'use cl
|
|
|
42
42
|
directives are preserved), and any bundler. Full setup: see the repository's
|
|
43
43
|
`USAGE.md`.
|
|
44
44
|
|
|
45
|
+
## For AI coding agents
|
|
46
|
+
|
|
47
|
+
This package ships an **`AGENTS.md`** with the complete rules, token vocabulary,
|
|
48
|
+
and component catalog. Point your agent at it:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
node_modules/@jackbernnie/hiyf/AGENTS.md
|
|
52
|
+
```
|
|
53
|
+
|
|
45
54
|
## Attribution
|
|
46
55
|
|
|
47
56
|
Forked from Polar's "Orbit" design system (Apache-2.0). See `LICENSE`/`NOTICE`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { Combobox as Combobox$1 } from '@base-ui/react';
|
|
5
|
-
import { ComboboxInput, ComboboxContent,
|
|
5
|
+
import { ComboboxInput, ComboboxContent, ComboboxEmpty, ComboboxList, ComboboxItem } from './ui/combobox.js';
|
|
6
6
|
|
|
7
7
|
function Combobox({
|
|
8
8
|
options,
|
|
@@ -12,9 +12,11 @@ function Combobox({
|
|
|
12
12
|
searchPlaceholder,
|
|
13
13
|
emptyText = "No results found."
|
|
14
14
|
}) {
|
|
15
|
+
const isControlled = value !== void 0;
|
|
16
|
+
const selected = options.find((o) => o.value === value) ?? null;
|
|
15
17
|
const handleValueChange = React.useCallback(
|
|
16
|
-
(
|
|
17
|
-
|
|
18
|
+
(item) => {
|
|
19
|
+
onValueChange?.(item ? item.value : "");
|
|
18
20
|
},
|
|
19
21
|
[onValueChange]
|
|
20
22
|
);
|
|
@@ -22,17 +24,18 @@ function Combobox({
|
|
|
22
24
|
return /* @__PURE__ */ jsxs(
|
|
23
25
|
Combobox$1.Root,
|
|
24
26
|
{
|
|
25
|
-
|
|
27
|
+
items: options,
|
|
28
|
+
value: isControlled ? selected : void 0,
|
|
26
29
|
onValueChange: onValueChange ? handleValueChange : void 0,
|
|
27
30
|
children: [
|
|
28
31
|
/* @__PURE__ */ jsx(ComboboxInput, { placeholder: inputPlaceholder, showTrigger: true, showClear: false }),
|
|
29
|
-
/* @__PURE__ */
|
|
32
|
+
/* @__PURE__ */ jsxs(ComboboxContent, { children: [
|
|
30
33
|
/* @__PURE__ */ jsx(ComboboxEmpty, { children: emptyText }),
|
|
31
|
-
|
|
34
|
+
/* @__PURE__ */ jsx(ComboboxList, { children: (item) => (
|
|
32
35
|
// ComboboxItem from ui/combobox already includes the ItemIndicator.
|
|
33
|
-
/* @__PURE__ */ jsx(ComboboxItem, { value:
|
|
34
|
-
))
|
|
35
|
-
] })
|
|
36
|
+
/* @__PURE__ */ jsx(ComboboxItem, { value: item, children: item.label }, item.value)
|
|
37
|
+
) })
|
|
38
|
+
] })
|
|
36
39
|
]
|
|
37
40
|
}
|
|
38
41
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jackbernnie/hiyf",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "human-in-your-face — a personal, LLM-safe design system. Forked from Polar's Orbit (Apache-2.0).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"files": [
|
|
17
17
|
"dist",
|
|
18
18
|
"src/theme.css",
|
|
19
|
+
"AGENTS.md",
|
|
19
20
|
"LICENSE",
|
|
20
21
|
"NOTICE"
|
|
21
22
|
],
|