Skip to content

Add Grove, a component kit grown from the Animal Island design language - #10

Open
maceip wants to merge 1 commit into
mainfrom
exp/island-components
Open

Add Grove, a component kit grown from the Animal Island design language#10
maceip wants to merge 1 commit into
mainfrom
exp/island-components

Conversation

@maceip

@maceip maceip commented Sep 6, 2026

Copy link
Copy Markdown
Owner

What

Grove, AXP's component kit, grown from the Animal Island design language (lifeodyssey/animal-island-ui-tailwind, MIT) and rebuilt as our own plain-CSS kit with thin React wrappers — no Tailwind, no Radix, nothing imported at runtime.

Kept because they are the point: capsule shapes everywhere, the flat game-button press shadow (5px rest / 6px hover with a lift / 1px pressed with a drop), chunky sage borders, the yellow focus ring, organic title radii, the blob clip-path on a native <dialog>. Ours: the palette (paper, warm charcoal, leaf green, dry-sage shadow), status tags mapped to the workspace's activity states, speech bubbles for turns, a vine divider, toasts.

  • ui/src/grove/grove.css + Grove.tsx: Button, Input, Textarea, Switch, Checkbox, Tag, Ribbon, Speech, BlobDialog, Vine, GroveDefs
  • "Start a contribution" now uses BlobDialog with Grove controls; the dialog fills the viewport with its own blur so the blob has no un-blurred rectangle behind it

Look at

Verification

npm run check and npm run test:ui pass.

Landing

Real overlap with the Liquid Leaf PR at the top of App.tsx (both add a defs component and an import); otherwise adjacent-line conflicts only.

Grove takes the Animal Island design system (lifeodyssey/animal-island-ui-
tailwind, MIT) as a foundation and rebuilds it as our own plain-CSS kit with
thin React wrappers: no Tailwind, no Radix, nothing imported at runtime.

Kept because they are the point: capsule shapes, the flat game-button press
shadow (5px rest, 6px hover with a lift, 1px pressed with a drop), chunky
sage borders, the yellow focus ring, organic title radii and the blob
clip-path on a native <dialog>. Ours: the palette (paper, warm charcoal,
leaf green, dry-sage shadow), status tags mapped to the workspace's activity
states, speech bubbles for turns, a vine divider, toasts.

- ui/src/grove: grove.css and Grove.tsx (Button, Input, Textarea, Switch,
  Checkbox, Tag, Ribbon, Speech, BlobDialog, Vine, GroveDefs)
- The "Start a contribution" dialog now uses BlobDialog with Grove controls;
  the dialog fills the viewport with its own blur so the blob has no
  un-blurred rectangle behind it
- docs/design/grove.html shows every component and the palette mapping;
  grove.md records what was kept, what is ours and where to apply it next
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-06T22:13:39.663074Z 365917e PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 365917e195

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Create contribution <ArrowRight size={15} />
</button>
</div>
<button type="submit" hidden />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Disable the hidden submitter when inputs are blank

When either field contains only whitespace, the visible Create button is disabled, but pressing Enter still activates this enabled hidden submit button. Native required validation accepts whitespace, so onSubmit calls submit() and sends a request that the trimmed server schema rejects (src/workspace-commands.ts:25-26), presenting an error despite the UI indicating submission is unavailable. Apply the same disabled condition to this submitter or guard trimmed values in the submit handler.

Useful? React with 👍 / 👎.

Comment thread ui/src/grove/Grove.tsx
]
.filter(Boolean)
.join(" ");
return <button type="button" {...rest} className={classes} />;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Disable loading buttons for keyboard activation

When loading is true without an explicit disabled prop, the CSS only suppresses pointer events; a focused button can still be activated with Enter or Space and invoke its handler again while the operation is pending. This can duplicate any action that adopts the kit's loading state, so the wrapper should make loading imply disabled (and preferably expose the busy state to assistive technology) rather than relying on pointer-events.

Useful? React with 👍 / 👎.

Comment thread ui/src/grove/grove.css
border: 0;
padding: 24px;
display: grid;
place-items: center;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep oversized dialogs aligned to a reachable scroll origin

When the available viewport is shorter than the blob, such as mobile landscape or after an onscreen keyboard opens, centering the oversized shell puts its top above the scroll container's origin. Because the full-screen dialog inherits overflow: auto from ui/src/style.css:1729-1738, users can scroll toward the overflowing bottom but cannot reach content laid out at a negative top offset, potentially hiding the heading and first field; use safe/start alignment for overflow or constrain the shell and scroll its contents.

Useful? React with 👍 / 👎.

Comment thread ui/src/grove/grove.css
Comment on lines +89 to +93
.grove-btn-primary {
background: var(--grove-leaf);
border-color: var(--grove-leaf);
color: #fff;
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.12);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Increase the primary button's text contrast

The enabled primary button renders 12px white text on #58aa72, which has only about a 2.83:1 contrast ratio; the #6dbb85 hover state drops to about 2.31:1. The newly surfaced Create contribution action is therefore below the 4.5:1 WCAG AA threshold for normal-sized text, making its label difficult to read for low-vision users; use a darker green or sufficiently contrasting text color in both states.

Useful? React with 👍 / 👎.

Comment thread ui/src/grove/grove.css
Comment on lines +209 to +212
.grove-input::placeholder,
.grove-textarea::placeholder {
color: var(--grove-ink-4);
font-weight: 400;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Raise the placeholder text contrast

Grove inputs render their 12px placeholder examples with #9aa59c on white, a contrast ratio of only about 2.55:1. Both fields in the new contribution dialog expose these placeholders, so low-vision users may be unable to read the examples even though this visible text is expected to meet the 4.5:1 normal-text threshold; use a darker placeholder token such as the already defined higher-contrast ink color.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant