Skip to content

feat(lynx): extract useControllableState/usePressTap into headless packages#1645

Open
junghyeonsu wants to merge 3 commits into
devfrom
lynx-headless-hooks-split
Open

feat(lynx): extract useControllableState/usePressTap into headless packages#1645
junghyeonsu wants to merge 3 commits into
devfrom
lynx-headless-hooks-split

Conversation

@junghyeonsu

@junghyeonsu junghyeonsu commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Extracts useControllableState and usePressTap from @seed-design/lynx-react into standalone headless packages under packages/lynx-headless/*, mirroring the react-headless convention. This is the base of a 4-PR Lynx ImageFrame stack.

Changes

  • New packages (hook + tests + bunchee build):
    • @seed-design/lynx-use-controllable-state
    • @seed-design/lynx-use-press-tap
  • usePressTap: LynxTouchProps dependency inlined via @lynx-js/types (decoupled from lynx-react)
  • lynx-react: components (ActionButton/Checkbox/RadioGroup/Switch) import the new packages directly; hooks/index.ts re-exports them so existing @seed-design/lynx-react imports keep working (non-breaking)
  • Root workspaces now includes packages/lynx-headless/* + packages/lynx-headless/AGENTS.md

Verification

  • new packages: build + typecheck + tests (9 + 12 passing)
  • lynx-react: typecheck + 25 tests + build all green
  • lynx-spa: typecheck green (re-export compatibility)

Stack (base: dev) — merge in order

  1. headless hooks split ← this PR
  2. lynx-image
  3. lynx-toggle (depends on this)
  4. AspectRatio

Note: changeset to be added before merge.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor

    • 내부 훅을 별도 패키지로 분리해 모듈화했습니다. 기존 컴포넌트의 동작 및 API는 변경되지 않습니다.
  • Documentation

    • 패키지 구성, 책임 범위, 코드 작성 컨벤션 및 신규 패키지 등록 체크리스트를 담은 개발자 가이드를 추가했습니다.
  • Chores

    • 패키지별 TypeScript 및 테스트 설정이 정비되어 빌드·검증 환경이 향상되었습니다.

…ckages

Move the two hooks out of @seed-design/lynx-react into standalone headless
packages so they can be reused and versioned independently:
- @seed-design/lynx-use-controllable-state
- @seed-design/lynx-use-press-tap

lynx-react re-exports them from hooks/index (backwards compatible) and the
components (ActionButton/Checkbox/RadioGroup/Switch) import them directly.
usePressTap's LynxTouchProps dependency is inlined via @lynx-js/types.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 689fe3a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@seed-design/lynx-use-controllable-state Minor
@seed-design/lynx-use-press-tap Minor
@seed-design/lynx-react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: de3e511d-2fe9-48e9-ac40-bdfd214292d3

📥 Commits

Reviewing files that changed from the base of the PR and between efe9281 and 689fe3a.

⛔ Files ignored due to path filters (6)
  • bun.lock is excluded by !**/*.lock
  • examples/lynx-spa/package.json is excluded by !**/package.json
  • packages/lynx-headless/use-controllable-state/package.json is excluded by !**/package.json
  • packages/lynx-headless/use-press-tap/package.json is excluded by !**/package.json
  • packages/lynx-react/package.json is excluded by !**/package.json
  • packages/lynx-vitest-config/package.json is excluded by !**/package.json
📒 Files selected for processing (12)
  • .changeset/lynx-headless-hooks-split.md
  • examples/lynx-spa/src/pages/UseControllableStatePage.tsx
  • examples/lynx-spa/src/pages/UsePressTapPage.tsx
  • packages/lynx-headless/use-controllable-state/tsconfig.json
  • packages/lynx-headless/use-controllable-state/vitest.config.ts
  • packages/lynx-headless/use-press-tap/tsconfig.json
  • packages/lynx-headless/use-press-tap/vitest.config.ts
  • packages/lynx-react/src/hooks/index.ts
  • packages/lynx-react/tsconfig.json
  • packages/lynx-react/vitest.config.ts
  • packages/lynx-vitest-config/src/index.ts
  • tsconfig.lynx.json
💤 Files with no reviewable changes (1)
  • packages/lynx-react/src/hooks/index.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/lynx-react/vitest.config.ts

📝 Walkthrough

Walkthrough

두 훅(useControllableState, usePressTap)을 독립 패키지로 분리하고 관련 문서(AGENTS.md), 패키지별 tsconfig 및 Vitest 엔트리를 추가했으며, lynx-react 컴포넌트와 예제의 훅 import를 새 패키지로 갱신했습니다. usePressTap의 타입은 IntrinsicElements 기반으로 조정되었습니다.

Changes

훅 패키지 추출 및 통합

Layer / File(s) Summary
Package Documentation and Conventions
packages/lynx-headless/AGENTS.md
lynx-headless 패키지의 책임 경계, 코드 컨벤션, 신규 패키지 점검 항목을 정의합니다.
useControllableState Standalone Package
packages/lynx-headless/use-controllable-state/src/index.ts, packages/lynx-headless/use-controllable-state/tsconfig.json, packages/lynx-headless/use-controllable-state/vitest.config.ts
useControllableState 훅을 독립 패키지로 분리하고 배럴 export, TypeScript 컴파일 설정 및 Vitest 구성을 추가합니다.
usePressTap Standalone Package and Type Updates
packages/lynx-headless/use-press-tap/src/index.ts, packages/lynx-headless/use-press-tap/src/usePressTap.ts, packages/lynx-headless/use-press-tap/tsconfig.json, packages/lynx-headless/use-press-tap/vitest.config.ts
usePressTap 훅을 독립 패키지로 분리하고 main-thread:bindtap 타입을 IntrinsicElements 기반 로컬 타입으로 변경하며, TypeScript 및 Vitest 설정을 추가합니다.
공유 Vitest 설정 유틸
packages/lynx-vitest-config/src/index.ts
createLynxVitestConfig()를 추가해 공통 Vitest 설정(테스트 include, optimizeDeps.exclude, ssr.noExternal)을 중앙화합니다.
TypeScript 공통 설정 및 패키지 상속 전환
tsconfig.lynx.json, packages/lynx-react/tsconfig.json
루트 tsconfig(ESNext/ESM, strict 등)를 추가하고 packages/lynx-react의 tsconfig를 상속 기반으로 전환합니다.
Component and Hook Index Migration
packages/lynx-react/src/components/ActionButton/ActionButton.tsx, packages/lynx-react/src/components/Checkbox/Checkbox.tsx, packages/lynx-react/src/components/RadioGroup/RadioGroup.tsx, packages/lynx-react/src/components/Switch/Switch.tsx, packages/lynx-react/src/hooks/index.ts, examples/lynx-spa/src/pages/UseControllableStatePage.tsx, examples/lynx-spa/src/pages/UsePressTapPage.tsx
컴포넌트와 예제에서 로컬 훅 import를 @seed-design/lynx-use-controllable-state@seed-design/lynx-use-press-tap로 변경하고 훅 인덱스의 re-export를 제거합니다.
Changeset
.changeset/lynx-headless-hooks-split.md
패키지 분리 및 관련 패키지들의 버전 범위를 기록합니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 훅 하나 둘 나뉘어 길을 떠나네,
작은 패키지에 담긴 부드러운 약속,
컴포넌트는 새 주소로 고개를 돌리고,
테스트와 설정은 한곳에 모여 춤추네,
당근 한 뭉텅이, 재사용의 밭에 심었어요.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 주요 변경 사항을 명확하게 요약합니다. useControllableStateusePressTap 훅을 headless 패키지로 추출하는 것이 정확히 무엇인지 잘 설명하고 있습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lynx-headless-hooks-split

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@junghyeonsu junghyeonsu self-assigned this Jun 8, 2026
- Add root tsconfig.lynx.json; lynx-react and lynx-headless/* extend it
  (matches react-headless's tsconfig.headless.json pattern).
- Add @seed-design/lynx-vitest-config (private) exposing createLynxVitestConfig;
  lynx-react and the headless packages consume it instead of duplicating config.
- Drop useControllableState/usePressTap re-exports from lynx-react's hooks barrel
  (matches @seed-design/react not re-exporting util hooks); lynx-spa imports them
  directly from their packages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@junghyeonsu junghyeonsu force-pushed the lynx-headless-hooks-split branch from 244c067 to 689fe3a Compare June 8, 2026 10:00
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