diff --git a/.changeset/camp-dev-rename.md b/.changeset/camp-dev-rename.md new file mode 100644 index 0000000..71eb6d2 --- /dev/null +++ b/.changeset/camp-dev-rename.md @@ -0,0 +1,5 @@ +--- +"@camp-dev/bones": minor +--- + +Rename `@lovo/bones` to `@camp-dev/bones` and split it into subpath exports: the framework-agnostic core at the package root (`boneAttributes`, `minMax`, `resolveLength`), the React API at `@camp-dev/bones/react`, and the stylesheet at `@camp-dev/bones/css`. Update imports: `@lovo/bones` → `@camp-dev/bones/react`, `@lovo/bones/css` → `@camp-dev/bones/css`. `react` and `react-dom` are now optional peer dependencies. diff --git a/.changeset/config.json b/.changeset/config.json index ba89546..4d6a1a2 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,6 +1,6 @@ { "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", - "changelog": ["@changesets/changelog-github", { "repo": "lovo-hq/bones" }], + "changelog": ["@changesets/changelog-github", { "repo": "campdotdev/bones" }], "commit": false, "fixed": [], "linked": [], diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6c7559..cb51e0b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ on: branches: - main +permissions: + contents: read + jobs: # ── Bones library ────────────────────────────────────────── bones-check: @@ -21,7 +24,7 @@ jobs: cache: true - name: Run lint, format, and type checks - run: vp run --filter @lovo/bones check + run: vp run --filter @camp-dev/bones check bones-build: name: "Bones: Build" @@ -36,7 +39,7 @@ jobs: cache: true - name: Build library - run: vp run --filter @lovo/bones build + run: vp run --filter @camp-dev/bones build bones-test: name: "Bones: Test" @@ -51,7 +54,7 @@ jobs: cache: true - name: Run tests - run: vp run --filter @lovo/bones test -- --run + run: vp run --filter @camp-dev/bones test -- --run # ── Demo app ─────────────────────────────────────────────── demo-check: @@ -67,7 +70,7 @@ jobs: cache: true - name: Build bones library - run: vp run --filter @lovo/bones build + run: vp run --filter @camp-dev/bones build - name: Run type check run: vp run --filter bones-demo check @@ -85,7 +88,7 @@ jobs: cache: true - name: Build bones library - run: vp run --filter @lovo/bones build + run: vp run --filter @camp-dev/bones build - name: Build demo app run: vp run --filter bones-demo build @@ -103,7 +106,7 @@ jobs: cache: true - name: Build bones library - run: vp run --filter @lovo/bones build + run: vp run --filter @camp-dev/bones build - name: Run tests run: vp run --filter bones-demo test -- --run @@ -122,7 +125,7 @@ jobs: cache: true - name: Build bones library - run: vp run --filter @lovo/bones build + run: vp run --filter @camp-dev/bones build - name: Run type check run: vp run --filter bones-docs check @@ -140,7 +143,7 @@ jobs: cache: true - name: Build bones library - run: vp run --filter @lovo/bones build + run: vp run --filter @camp-dev/bones build - name: Build docs site run: vp run --filter bones-docs build diff --git a/README.md b/README.md index 6bc195e..e66250d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bones -[![Bundle Size](https://deno.bundlejs.com/badge?q=@lovo/bones)](https://bundlejs.com/?q=%40lovo%2Fbones) +[![Bundle Size](https://deno.bundlejs.com/badge?q=@camp-dev/bones)](https://bundlejs.com/?q=%40camp-dev%2Fbones) Skeleton loaders designed for React Server Components and streaming. @@ -21,21 +21,31 @@ Bones skips the duplication. You write your markup once and it handles both stat ## Installation ```bash -npm install @lovo/bones +npm install @camp-dev/bones ``` Import the CSS once in your root layout or entry point: ```tsx -import "@lovo/bones/css"; +import "@camp-dev/bones/css"; ``` +## Entry points + +| Import | Contents | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------- | +| `@camp-dev/bones/react` | `createBones`, `readPromise`, `forceBones`, `minMax`, ``, `` | +| `@camp-dev/bones/css` | The skeleton stylesheet. Import once in your root layout. | +| `@camp-dev/bones` | The framework-agnostic core (`boneAttributes`, `minMax`). You only need this to build your own renderer or adapter. | + +React is an optional peer dependency: installing the package without React is supported and only the `/react` entry requires it. + ## Basic usage Pass data (or a promise of data) to `createBones`. Spread the `bone` function's return value onto elements that should show skeletons while loading. ```tsx -import { createBones } from "@lovo/bones"; +import { createBones } from "@camp-dev/bones/react"; function ProfileCard({ user }: { user: Promise | User }) { const { bone, data, lines } = createBones(user); @@ -55,7 +65,7 @@ function ProfileCard({ user }: { user: Promise | User }) { Wrap components that receive promises in ``. It creates a Suspense boundary and generates the skeleton fallback for you: ```tsx -import { Bones } from "@lovo/bones"; +import { Bones } from "@camp-dev/bones/react"; export default function Page() { return ( @@ -81,7 +91,7 @@ While the promise is pending, `` renders the same `` tree wi Use `forceBones` to see a component's skeleton state without setting up real data: ```tsx -import { createBones, forceBones } from "@lovo/bones"; +import { createBones, forceBones } from "@camp-dev/bones/react"; ; ``` @@ -89,7 +99,7 @@ import { createBones, forceBones } from "@lovo/bones"; To force an entire subtree into skeleton mode at once, wrap it with ``: ```tsx -import { BonesForce } from "@lovo/bones"; +import { BonesForce } from "@camp-dev/bones/react"; diff --git a/apps/demo/app/compare/page.tsx b/apps/demo/app/compare/page.tsx index a1ca2b4..2f1e166 100644 --- a/apps/demo/app/compare/page.tsx +++ b/apps/demo/app/compare/page.tsx @@ -1,4 +1,4 @@ -import { BonesForce } from "bones"; +import { BonesForce } from "bones/react"; import { HeroSection } from "@/components/hero-section/hero-section"; import { DemoSection } from "@/components/demo-section/demo-section"; import { PokemonGrid } from "@/components/pokemon-grid/pokemon-grid"; diff --git a/apps/demo/app/compare/pokemon/[id]/page.tsx b/apps/demo/app/compare/pokemon/[id]/page.tsx index bc66454..33b64d8 100644 --- a/apps/demo/app/compare/pokemon/[id]/page.tsx +++ b/apps/demo/app/compare/pokemon/[id]/page.tsx @@ -1,4 +1,4 @@ -import { BonesForce, forceBones } from "bones"; +import { BonesForce, forceBones } from "bones/react"; import Link from "next/link"; import { PokemonHero } from "@/components/pokemon-hero/pokemon-hero"; import { BaseStatsCard } from "@/components/base-stats-card/base-stats-card"; diff --git a/apps/demo/app/layout.tsx b/apps/demo/app/layout.tsx index 7afc538..a69f1a0 100644 --- a/apps/demo/app/layout.tsx +++ b/apps/demo/app/layout.tsx @@ -1,6 +1,6 @@ import type { Metadata } from "next"; import { cookies, headers } from "next/headers"; -import { BonesForce } from "bones"; +import { BonesForce } from "bones/react"; import { BonesDevTool } from "@/components/bones-devtool/bones-devtool"; import "bones/css"; import "./globals.css"; diff --git a/apps/demo/app/pokemon/[id]/page.tsx b/apps/demo/app/pokemon/[id]/page.tsx index 22ac8db..1b09f3e 100644 --- a/apps/demo/app/pokemon/[id]/page.tsx +++ b/apps/demo/app/pokemon/[id]/page.tsx @@ -1,4 +1,4 @@ -import { Bones } from "bones"; +import { Bones } from "bones/react"; import Link from "next/link"; import { cookies } from "next/headers"; import { delay } from "@/lib/delay"; diff --git a/apps/demo/app/pokemon/[id]/tabs-section.tsx b/apps/demo/app/pokemon/[id]/tabs-section.tsx index 518d4a4..47c7cdd 100644 --- a/apps/demo/app/pokemon/[id]/tabs-section.tsx +++ b/apps/demo/app/pokemon/[id]/tabs-section.tsx @@ -1,4 +1,4 @@ -import { Bones } from "bones"; +import { Bones } from "bones/react"; import type { PokemonMoveEntry, MoveDetail, EncounterLocation } from "@/lib/pokeapi"; import { DetailTabs } from "@/components/detail-tabs/detail-tabs"; import { MovesPanel } from "@/components/moves-panel/moves-panel"; diff --git a/apps/demo/components/animations-demo/animations-demo.tsx b/apps/demo/components/animations-demo/animations-demo.tsx index 9296d93..dd9ac0c 100644 --- a/apps/demo/components/animations-demo/animations-demo.tsx +++ b/apps/demo/components/animations-demo/animations-demo.tsx @@ -1,4 +1,4 @@ -import { BonesForce } from "bones"; +import { BonesForce } from "bones/react"; import { DemoSection } from "@/components/demo-section/demo-section"; import { PokemonCard } from "@/components/pokemon-card/pokemon-card"; import styles from "./styles.module.css"; diff --git a/apps/demo/components/article-preview/article-preview.tsx b/apps/demo/components/article-preview/article-preview.tsx index 792f3e1..7ef9afc 100644 --- a/apps/demo/components/article-preview/article-preview.tsx +++ b/apps/demo/components/article-preview/article-preview.tsx @@ -1,4 +1,4 @@ -import { createBones } from "bones"; +import { createBones } from "bones/react"; import styles from "./styles.module.css"; interface Article { diff --git a/apps/demo/components/base-stats-card/base-stats-card.tsx b/apps/demo/components/base-stats-card/base-stats-card.tsx index bbd2180..c8c79eb 100644 --- a/apps/demo/components/base-stats-card/base-stats-card.tsx +++ b/apps/demo/components/base-stats-card/base-stats-card.tsx @@ -1,4 +1,4 @@ -import { createBones } from "bones"; +import { createBones } from "bones/react"; import type { PokemonData } from "@/lib/pokeapi"; import styles from "./styles.module.css"; diff --git a/apps/demo/components/dex-entries-panel/dex-entries-panel.tsx b/apps/demo/components/dex-entries-panel/dex-entries-panel.tsx index cb4dae7..a3e1c4b 100644 --- a/apps/demo/components/dex-entries-panel/dex-entries-panel.tsx +++ b/apps/demo/components/dex-entries-panel/dex-entries-panel.tsx @@ -1,4 +1,4 @@ -import { createBones, minMax } from "bones"; +import { createBones, minMax } from "bones/react"; import styles from "./styles.module.css"; const VERSION_TO_GENERATION: Record = { diff --git a/apps/demo/components/evolution-chain-card/evolution-chain-card.tsx b/apps/demo/components/evolution-chain-card/evolution-chain-card.tsx index 1c190ed..8617d2c 100644 --- a/apps/demo/components/evolution-chain-card/evolution-chain-card.tsx +++ b/apps/demo/components/evolution-chain-card/evolution-chain-card.tsx @@ -1,5 +1,5 @@ import Image from "next/image"; -import { createBones } from "bones"; +import { createBones } from "bones/react"; import type { EvolutionChain } from "@/lib/pokeapi"; import styles from "./styles.module.css"; diff --git a/apps/demo/components/forced-skeletons-demo/forced-skeletons-demo.tsx b/apps/demo/components/forced-skeletons-demo/forced-skeletons-demo.tsx index affc26d..6bc1ef5 100644 --- a/apps/demo/components/forced-skeletons-demo/forced-skeletons-demo.tsx +++ b/apps/demo/components/forced-skeletons-demo/forced-skeletons-demo.tsx @@ -1,4 +1,4 @@ -import { BonesForce } from "bones"; +import { BonesForce } from "bones/react"; import { fetchPokemonList } from "@/lib/pokeapi"; import { DemoSection } from "@/components/demo-section/demo-section"; import { PokemonGrid } from "@/components/pokemon-grid/pokemon-grid"; diff --git a/apps/demo/components/hero-section/hero-section.test.tsx b/apps/demo/components/hero-section/hero-section.test.tsx index 9a79a76..75498be 100644 --- a/apps/demo/components/hero-section/hero-section.test.tsx +++ b/apps/demo/components/hero-section/hero-section.test.tsx @@ -20,6 +20,6 @@ describe("HeroSection", () => { const docsLink = screen.getByRole("link", { name: "Docs" }); const githubLink = screen.getByRole("link", { name: "GitHub" }); expect(docsLink.getAttribute("href")).toBe("https://bones.lovo.sh"); - expect(githubLink.getAttribute("href")).toBe("https://github.com/lovo-hq/bones"); + expect(githubLink.getAttribute("href")).toBe("https://github.com/campdotdev/bones"); }); }); diff --git a/apps/demo/components/hero-section/hero-section.tsx b/apps/demo/components/hero-section/hero-section.tsx index b91518c..2cedb33 100644 --- a/apps/demo/components/hero-section/hero-section.tsx +++ b/apps/demo/components/hero-section/hero-section.tsx @@ -13,7 +13,7 @@ export function HeroSection() {