diff --git a/.changeset/crazy-ads-appear.md b/.changeset/crazy-ads-appear.md deleted file mode 100644 index 2b29de706..000000000 --- a/.changeset/crazy-ads-appear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'layerchart': patch ---- - -fix(TooltipContext): Fix `band` mode regression when both x/y are scaleBand (ex. punchcard chart) diff --git a/.changeset/empty-buses-flash.md b/.changeset/empty-buses-flash.md deleted file mode 100644 index f1820437d..000000000 --- a/.changeset/empty-buses-flash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'layerchart': patch ---- - -docs: Add examples for standalone, daisyUI v5, shadcn-svelte v1, Skeleton v3, and Svelte UX v2 (next) (including light/dark theming) diff --git a/.changeset/weak-donuts-tan.md b/.changeset/weak-donuts-tan.md index f8fd495d0..aafa65f7f 100644 --- a/.changeset/weak-donuts-tan.md +++ b/.changeset/weak-donuts-tan.md @@ -2,4 +2,4 @@ 'layerchart': patch --- -feat: Simplify daisyUI, shadcn-svelte, and Skeleton integrations with single line `@import 'layerchart/{library}.css'` added to `app.css` +feat: Simplify Skeleton integration with `@import 'layerchart/skeleton.css'` diff --git a/.changeset/whole-women-listen.md b/.changeset/whole-women-listen.md index 71e1b7576..279e554f1 100644 --- a/.changeset/whole-women-listen.md +++ b/.changeset/whole-women-listen.md @@ -2,4 +2,4 @@ 'layerchart': minor --- -feat: Support css-only usage (no Tailwind required) while retaining first-class Tailwind support +feat: Support css-only usage (no Tailwind required) while still providing first-class Tailwind support diff --git a/.github/workflows/build-preview.yml b/.github/workflows/build-preview.yml index f12ab9899..7949f4e60 100644 --- a/.github/workflows/build-preview.yml +++ b/.github/workflows/build-preview.yml @@ -24,7 +24,7 @@ jobs: run: pnpm install - name: Build site - run: pnpm build:packages + run: pnpm build - name: Upload build artifact uses: actions/upload-artifact@v4 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 219ffa361..be23b0291 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,18 +27,12 @@ jobs: - run: pnpm install --frozen-lockfile - - run: pnpm check:packages + - run: pnpm check - - run: pnpm lint:packages + - run: pnpm lint - run: pnpm test:unit env: CI: true - - run: pnpm build:packages - - - run: pnpm build:examples - - # Run after building to ensure svelte-package is ran - - run: pnpm check:examples - - run: pnpm lint:examples + - run: pnpm build diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index 7623b3057..e39ec1cf2 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -26,7 +26,7 @@ jobs: run: pnpm install - name: Build site - run: pnpm build:packages + run: pnpm build - name: Deploy to Cloudflare Pages uses: AdrianGonz97/refined-cf-pages-action@v1 diff --git a/.github/workflows/pkg-pr-new.yml b/.github/workflows/pkg-pr-new.yml index a848291e4..6fb7199d0 100644 --- a/.github/workflows/pkg-pr-new.yml +++ b/.github/workflows/pkg-pr-new.yml @@ -16,7 +16,7 @@ jobs: - run: pnpm install --frozen-lockfile - - run: pnpm build:packages + - run: pnpm build - run: pnpm package diff --git a/examples/daisyui-5/src/app.css b/examples/daisyui-5/src/app.css index fff201615..0347798e4 100644 --- a/examples/daisyui-5/src/app.css +++ b/examples/daisyui-5/src/app.css @@ -1,3 +1,3 @@ @import 'tailwindcss'; @plugin "daisyui"; -@import 'layerchart/daisyui-5.css'; +@import 'layerchart/daisyui.css'; diff --git a/examples/shadcn-svelte-1/.prettierignore b/examples/shadcn-svelte-1/.prettierignore index 233d50048..7d74fe246 100644 --- a/examples/shadcn-svelte-1/.prettierignore +++ b/examples/shadcn-svelte-1/.prettierignore @@ -7,7 +7,3 @@ bun.lockb # Miscellaneous /static/ - -# Ignore shadcn/ui components and utils -src/lib/components/ui/ -src/lib/utils.ts diff --git a/examples/skeleton-3/src/app.css b/examples/skeleton-3/src/app.css index 23f3e94c8..dede6d7bb 100644 --- a/examples/skeleton-3/src/app.css +++ b/examples/skeleton-3/src/app.css @@ -4,7 +4,7 @@ @import '@skeletonlabs/skeleton/optional/presets'; @import '@skeletonlabs/skeleton/themes/cerberus'; -@import 'layerchart/skeleton-3.css'; +@import 'layerchart/skeleton.css'; @source '../node_modules/@skeletonlabs/skeleton-svelte/dist'; diff --git a/examples/svelte-ux-2/package.json b/examples/svelte-ux-2/package.json index 22922152b..0d585e44b 100644 --- a/examples/svelte-ux-2/package.json +++ b/examples/svelte-ux-2/package.json @@ -19,7 +19,7 @@ "@sveltejs/kit": "^2.22.0", "@sveltejs/vite-plugin-svelte": "^6.0.0", "@tailwindcss/vite": "^4.0.0", - "layerchart": "workspace:*", + "layerchart": "workspace:2.0.0-next.38", "prettier": "^3.4.2", "prettier-plugin-svelte": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.11", diff --git a/package.json b/package.json index 60059423c..6ce551594 100644 --- a/package.json +++ b/package.json @@ -4,17 +4,13 @@ "author": "Sean Lynch ", "license": "MIT", "type": "module", - "homepage": "https://layerchart.com", "scripts": { "dev": "pnpm -r dev", "test:unit": "pnpm -r test:unit", - "build:packages": "rimraf packages/*/dist && pnpm --filter './packages/*' build", - "build:examples": "rimraf packages/*/dist && pnpm --filter './packages/*' package && pnpm --filter './examples/*' build", - "package": "pnpm --filter './packages/*' package", - "check:packages": "pnpm --filter './packages/*' check", - "check:examples": "pnpm --filter './examples/*' check", - "lint:packages": "pnpm --filter './packages/*' lint", - "lint:examples": "pnpm --filter './examples/*' lint", + "build": "rimraf packages/*/dist && pnpm -r build", + "package": "pnpm -r package", + "check": "pnpm -r check", + "lint": "pnpm -r lint", "format": "pnpm -r format", "changeset": "changeset", "changeset:version": "changeset version", @@ -33,4 +29,4 @@ "esbuild" ] } -} +} \ No newline at end of file diff --git a/packages/layerchart/src/lib/components/Grid.svelte b/packages/layerchart/src/lib/components/Grid.svelte index eec7034be..f72db00e5 100644 --- a/packages/layerchart/src/lib/components/Grid.svelte +++ b/packages/layerchart/src/lib/components/Grid.svelte @@ -182,7 +182,6 @@ {#if isScaleBand(ctx.xScale) && bandAlign === 'between' && !ctx.radial && xTickVals.length} - {@const x = ctx.xScale(xTickVals[xTickVals.length - 1])! + ctx.xScale.step() + xBandOffset} {/if} {:else} - {:else} - {@const y = - ctx.yScale(yTickVals[yTickVals.length - 1])! + ctx.yScale.step() + yBandOffset} - {/if} - - diff --git a/packages/layerchart/src/lib/components/Legend.svelte b/packages/layerchart/src/lib/components/Legend.svelte index 998b78360..70f573998 100644 --- a/packages/layerchart/src/lib/components/Legend.svelte +++ b/packages/layerchart/src/lib/components/Legend.svelte @@ -435,57 +435,56 @@ right: 0; } } + } - :where(.lc-legend-title) { - font-size: 10px; - font-weight: 600; - } + :where(.lc-legend-title) { + font-size: 10px; + font-weight: 600; + } - :where(.lc-legend-ramp-svg) { - overflow: visible; - } + :where(.lc-legend-ramp-svg) { + overflow: visible; + } - :where(.lc-legend-tick-text) { - font-size: 10px; - fill: var(--color-surface-content, currentColor); - } + :where(.lc-legend-tick-text) { + font-size: 10px; + fill: var(--color-surface-content, currentColor); + } - :where(.lc-legend-tick-line) { - stroke: var(--color-surface-content, currentColor); - } + :where(.lc-legend-tick-line) { + stroke: var(--color-surface-content, currentColor); + } - :where(.lc-legend-swatch-group) { - display: flex; - gap: 0.25rem 1rem; + :where(.lc-legend-swatch-group) { + display: flex; + gap: 0.25rem 1rem; - &[data-orientation='vertical'] { - flex-direction: column; - } + &[data-orientation='vertical'] { + flex-direction: column; } + } - :where(.lc-legend-swatch-button) { - display: flex; - align-items: center; - gap: 0.25rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } + :where(.lc-legend-swatch-button) { + display: flex; + align-items: center; + gap: 0.25rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } - :where(.lc-legend-swatch) { - width: 16px; - height: 16px; - flex-shrink: 0; - border-radius: 9999px; /* full */ - } + :where(.lc-legend-swatch) { + width: 16px; + height: 16px; + flex-shrink: 0; + border-radius: 9999px; /* full */ + } - :where(.lc-legend-swatch-label) { - font-size: 0.75rem; /* text-xs */ - line-height: calc(1 / 0.75); - color: var(--color-surface-content, currentColor); - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } + :where(.lc-legend-swatch-label) { + font-size: 0.75rem; /* text-xs */ + color: var(--color-surface-content, currentColor); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } diff --git a/packages/layerchart/src/lib/components/Rule.svelte b/packages/layerchart/src/lib/components/Rule.svelte index 1361cdde1..22e452ba1 100644 --- a/packages/layerchart/src/lib/components/Rule.svelte +++ b/packages/layerchart/src/lib/components/Rule.svelte @@ -223,16 +223,7 @@ diff --git a/packages/layerchart/src/lib/components/charts/ArcChart.svelte b/packages/layerchart/src/lib/components/charts/ArcChart.svelte index a23b2b55f..56bfcb0cd 100644 --- a/packages/layerchart/src/lib/components/charts/ArcChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ArcChart.svelte @@ -251,6 +251,10 @@ const item = chartData.find((d) => keyAccessor(d) === tick); return item ? (labelAccessor(item) ?? tick) : tick; }, + onclick: (e, item) => { + // Select data keys instead of series value + seriesState.selectedKeys.toggle(item.value); + }, ...props.legend, ...getObjectOrNull(legend), }, diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index a86af3147..ae7f55310 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -178,11 +178,11 @@ x: isVertical ? (s.value ?? (s.data ? undefined : s.key)) : undefined, y: !isVertical ? (s.value ?? (s.data ? undefined : s.key)) : undefined, stroke: s.color, + ...props.spline, + ...s.props, opacity: // Checking `visibleSeries.length <= 1` fixes re-animated tweened areas on hover seriesState.visibleSeries.length <= 1 || seriesState.isHighlighted(s.key, true) ? 1 : 0.1, - ...props.spline, - ...s.props, class: cls(props.spline?.class, s.props?.class), }; diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index 201647a37..b2adf647b 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -265,6 +265,10 @@ const item = chartData.find((d) => keyAccessor(d) === tick); return item ? (labelAccessor(item) ?? tick) : tick; }, + onclick: (e, item) => { + // Select data keys instead of series value + seriesState.selectedKeys.toggle(item.value); + }, ...props.legend, ...getObjectOrNull(legend), }, @@ -415,8 +419,7 @@ {@render marks(snippetProps)} {:else} - - {#each series as s, seriesIdx (s.key)} + {#each seriesState.visibleSeries as s, seriesIdx (s.key)} {#if typeof pie === 'function'} {@render pie({ ...snippetProps, diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte index 6525024bb..c270da658 100644 --- a/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte @@ -505,16 +505,16 @@ // full band width/height regardless of value return { x: x - xOffset, - y: isScaleBand(ctx.yScale) ? y - yOffset : min(ctx.yRange), + y: min(ctx.yRange), width: ctx.xScale.step(), - height: isScaleBand(ctx.yScale) ? ctx.yScale.step() : fullHeight, + height: fullHeight, data: d, }; } else if (isScaleBand(ctx.yScale)) { return { - x: isScaleBand(ctx.xScale) ? x - xOffset : min(ctx.xRange), + x: min(ctx.xRange), y: y - yOffset, - width: isScaleBand(ctx.xScale) ? ctx.xScale.step() : fullWidth, + width: fullWidth, height: ctx.yScale.step(), data: d, }; @@ -530,9 +530,9 @@ return { x: x - xOffset, - y: isScaleBand(ctx.yScale) ? y - yOffset : min(ctx.yRange), + y: min(ctx.yRange), width: (ctx.xScale(nextDataPoint) ?? 0) - (xValue ?? 0), - height: isScaleBand(ctx.yScale) ? ctx.yScale.step() : fullHeight, + height: fullHeight, data: d, }; } else if (isScaleTime(ctx.yScale)) { @@ -546,9 +546,9 @@ : ctx.y(ctx.flatData[index + 1]); return { - x: isScaleBand(ctx.xScale) ? x - xOffset : min(ctx.xRange), + x: min(ctx.xRange), y: y - yOffset, - width: isScaleBand(ctx.xScale) ? ctx.xScale.step() : fullWidth, + width: fullWidth, height: (ctx.yScale(nextDataPoint) ?? 0) - (yValue ?? 0), data: d, }; diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte index 9ab2f9aab..69582cd4a 100644 --- a/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte @@ -112,8 +112,7 @@ :where(.lc-tooltip-header) { font-weight: 600; white-space: nowrap; - border-bottom: 1px solid - color-mix(in oklab, var(--color-surface-content, currentColor) 20%, transparent); + border-bottom-width: 1px; margin-bottom: 4px; padding-bottom: 4px; display: flex; diff --git a/packages/layerchart/src/lib/states/series.svelte.ts b/packages/layerchart/src/lib/states/series.svelte.ts index 8cbe491be..a7a8d7ca7 100644 --- a/packages/layerchart/src/lib/states/series.svelte.ts +++ b/packages/layerchart/src/lib/states/series.svelte.ts @@ -13,6 +13,7 @@ class HighlightKey { export class SeriesState { #series = $state.raw[]>([]); + selectedSeries = new SelectionState(); selectedKeys = new SelectionState(); highlightKey = new HighlightKey(); @@ -41,7 +42,7 @@ export class SeriesState { * Check if series is visible */ isVisible(seriesKey: SeriesData['key']) { - return this.selectedKeys.isEmpty() || this.selectedKeys.isSelected(seriesKey); + return this.selectedSeries.isEmpty() || this.selectedSeries.isSelected(seriesKey); } /** diff --git a/packages/layerchart/src/lib/styles/daisyui-5.css b/packages/layerchart/src/lib/styles/daisyui.css similarity index 100% rename from packages/layerchart/src/lib/styles/daisyui-5.css rename to packages/layerchart/src/lib/styles/daisyui.css diff --git a/packages/layerchart/src/lib/styles/skeleton-3.css b/packages/layerchart/src/lib/styles/skeleton.css similarity index 100% rename from packages/layerchart/src/lib/styles/skeleton-3.css rename to packages/layerchart/src/lib/styles/skeleton.css diff --git a/packages/layerchart/src/routes/docs/components/Issue/+page.svelte b/packages/layerchart/src/routes/docs/components/Issue/+page.svelte new file mode 100644 index 000000000..9636b2a3f --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/Issue/+page.svelte @@ -0,0 +1,149 @@ + + + + + +

Examples

+ +

Series

+ + +
+ +
+
+ +

Series (separate data)

+ + +
+ { + return { ...s, data: multiSeriesDataByFruit.get(s.key) }; + })} + {renderContext} + {debug} + /> +
+
+ +

Stack series

+ + +
+ +
+
+ +

Stack series (expand)

+ + +
+ +
+
+ +

Stack series (diverging)

+ + +
+ { + if (s.key === 'apples') { + // @ts-expect-error + return { ...s, value: (d) => -d.apples }; + } + return s; + })} + seriesLayout="stackDiverging" + {renderContext} + {debug} + /> +
+
+ +

Stack series (separate data)

+ + +
+ { + return { ...s, data: multiSeriesDataByFruit.get(s.key) }; + })} + seriesLayout="stack" + {renderContext} + {debug} + /> +
+
diff --git a/packages/layerchart/src/routes/docs/components/Issue/+page.ts b/packages/layerchart/src/routes/docs/components/Issue/+page.ts new file mode 100644 index 000000000..d1bce4dc2 --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/Issue/+page.ts @@ -0,0 +1,16 @@ +import api from '$lib/components/charts/AreaChart.svelte?raw&sveld'; +import source from '$lib/components/charts/AreaChart.svelte?raw'; +import pageSource from './+page.svelte?raw'; + +export async function load({ fetch }) { + return { + meta: { + api, + source, + pageSource, + description: 'Streamlined Chart configuration for Area charts', + supportedContexts: ['svg', 'canvas'], + related: ['components/Chart', 'components/Area', 'examples/Area'], + }, + }; +} diff --git a/packages/layerchart/src/routes/docs/examples/PunchCard/+page.svelte b/packages/layerchart/src/routes/docs/examples/PunchCard/+page.svelte index 4a1064252..4f8366d81 100644 --- a/packages/layerchart/src/routes/docs/examples/PunchCard/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/PunchCard/+page.svelte @@ -40,7 +40,6 @@ tooltip: { context: { mode: 'band' } }, }} {renderContext} - debug={shared.debug} > {#snippet highlight()} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e99c12151..1538b7dd7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -249,7 +249,7 @@ importers: specifier: ^4.0.0 version: 4.1.12(vite@7.1.2(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.1)) layerchart: - specifier: workspace:* + specifier: workspace:2.0.0-next.38 version: link:../../packages/layerchart prettier: specifier: ^3.4.2