Skip to content

Commit

Permalink
Svelte 5 docs (#436)
Browse files Browse the repository at this point in the history
* Update `svelte` and `vite-plugin-svelte` to latest next (svelte 5)

* Disable sveld until Svelte 5 compatible

* Work around action timing change in Svelte 5 by updating example to specific explicit `target: document.body`.  Resolves #437

* Update `svelte` and `vite-plugin-svelte` to latest next (`.201` and `.5` respectively)

* Update dependencies to latest

* fix(TextField): Type error

* fix(TableOfContents): Fix ssr support

* fix(SelectField): Fix ssr support by no longer nesting `<button>` instances

* Update to official Svelte 5

* Ignore warning

* docs: Remove API docs until can be extracted in Svelte 5 compatible way (sveld update, etc)

* Require official Svelte 5 (instead of `next` version).  Still supports Svelte 3/4

* Add missing changesets

* fix(AppLayout): Fix SSR drawer layout on mobile.  Resolves #22

* refactor: Use 'esm-env' for browser/dev conditionals
  • Loading branch information
techniq authored Oct 20, 2024
1 parent 4df82aa commit ebe86d0
Show file tree
Hide file tree
Showing 22 changed files with 510 additions and 425 deletions.
5 changes: 5 additions & 0 deletions .changeset/chatty-gorillas-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte-ux': patch
---

fix(TableOfContents): Fix ssr support
5 changes: 5 additions & 0 deletions .changeset/fast-dancers-invite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte-ux': patch
---

fix(AppLayout): Fix SSR drawer layout on mobile. Resolves #22
5 changes: 5 additions & 0 deletions .changeset/metal-garlics-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte-ux': patch
---

fix(SelectField): Fix Svelte 5 SSR compatibility
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
},
"devDependencies": {
"@changesets/cli": "2.27.9",
"@svitejs/changesets-changelog-github-compact": "^1.1.0",
"@svitejs/changesets-changelog-github-compact": "^1.2.0",
"rimraf": "6.0.1",
"wrangler": "^3.80.1"
"wrangler": "^3.81.0"
},
"packageManager": "pnpm@9.12.0"
}
2 changes: 1 addition & 1 deletion packages/create-svelte-ux/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"commander": "^12.1.0"
},
"devDependencies": {
"@types/node": "^22.7.5",
"@types/node": "^22.7.7",
"prettier": "^3.3.3"
},
"files": [
Expand Down
35 changes: 18 additions & 17 deletions packages/svelte-ux/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,34 @@
"@changesets/cli": "^2.27.9",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@skeletonlabs/tw-plugin": "^0.4.0",
"@sveltejs/adapter-cloudflare": "^4.7.2",
"@sveltejs/kit": "^2.6.3",
"@sveltejs/adapter-cloudflare": "^4.7.3",
"@sveltejs/kit": "^2.7.2",
"@sveltejs/package": "^2.3.5",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@sveltejs/vite-plugin-svelte": "4.0.0",
"@tailwindcss/typography": "^0.5.15",
"@types/culori": "^2.1.1",
"@types/d3-array": "^3.2.1",
"@types/d3-scale": "^4.0.8",
"@types/lodash-es": "^4.17.12",
"@types/prismjs": "^1.26.4",
"@vitest/coverage-v8": "^2.1.2",
"@vitest/coverage-v8": "^2.1.3",
"autoprefixer": "^10.4.20",
"daisyui": "^4.12.12",
"marked": "^14.1.2",
"daisyui": "^4.12.13",
"marked": "^14.1.3",
"mdsvex": "^0.12.3",
"posthog-js": "^1.167.0",
"posthog-js": "^1.174.2",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.7",
"rehype-slug": "^6.0.0",
"svelte": "^4.2.19",
"svelte-check": "^4.0.4",
"svelte2tsx": "^0.7.21",
"tailwindcss": "^3.4.13",
"tslib": "^2.7.0",
"typescript": "^5.6.2",
"svelte": "5.0.2",
"svelte-check": "^4.0.5",
"svelte2tsx": "^0.7.22",
"tailwindcss": "^3.4.14",
"tslib": "^2.8.0",
"typescript": "^5.6.3",
"unist-util-visit": "^5.0.0",
"vite": "^5.4.8",
"vitest": "^2.1.2"
"vite": "^5.4.9",
"vitest": "^2.1.3"
},
"type": "module",
"dependencies": {
Expand All @@ -61,17 +61,18 @@
"d3-array": "^3.2.4",
"d3-scale": "^4.0.2",
"date-fns": "^4.1.0",
"esm-env": "^1.0.0",
"immer": "^10.1.1",
"lodash-es": "^4.17.21",
"prism-svelte": "^0.5.0",
"prism-themes": "^1.9.0",
"prismjs": "^1.29.0",
"sveld": "^0.20.2",
"tailwind-merge": "^2.5.3",
"tailwind-merge": "^2.5.4",
"zod": "^3.23.8"
},
"peerDependencies": {
"svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120"
"svelte": "^3.56.0 || ^4.0.0 || ^5.0.0"
},
"main": "./dist/index.js",
"exports": {
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte-ux/src/lib/components/AppBar.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script lang="ts">
import { BROWSER } from 'esm-env';
import { mdiMenu } from '@mdi/js';
import Breadcrumb from './Breadcrumb.svelte';
import Button from './Button.svelte';
import { browser } from '../utils/env.js';
import { cls } from '../utils/styles.js';
import { getComponentClasses } from './theme.js';
import { getSettings } from './index.js';
Expand All @@ -23,7 +23,7 @@
$: titleString = Array.isArray(title) ? title.filter((x) => x).join('') : title.toString();
$: if (browser && head) {
$: if (BROWSER && head) {
// Appears to be needed for some reactive updates
document.title = titleString;
}
Expand Down
5 changes: 3 additions & 2 deletions packages/svelte-ux/src/lib/components/AppLayout.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import { BROWSER } from 'esm-env';
import Backdrop from './Backdrop.svelte';
import { mdScreen } from '../stores/matchMedia.js';
import { cls } from '../utils/styles.js';
import { getComponentClasses } from './theme.js';
import { browser } from '../utils/env.js';
import { getSettings } from './index.js';
export let navWidth = 240;
Expand All @@ -21,7 +21,7 @@
const settingsClasses = getComponentClasses('AppLayout');
const { showDrawer } = getSettings();
$: temporaryDrawer = browser ? !$mdScreen : false;
$: temporaryDrawer = BROWSER ? !$mdScreen : false;
</script>

<div
Expand Down Expand Up @@ -52,6 +52,7 @@
<aside
class={cls(
'fixed top-0 h-[calc(100%-var(--headerHeight))] w-[var(--drawerWidth)] transition-all duration-500 overflow-hidden',
!BROWSER && 'max-md:hidden', // hide drawer during SSR on <md viewports (which is same result once hydrated)
temporaryDrawer
? 'fixed h-full z-50 elevation-10'
: headerPosition === 'full'
Expand Down
9 changes: 5 additions & 4 deletions packages/svelte-ux/src/lib/components/SelectField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
// Elements
let inputEl: HTMLInputElement | null = null;
let menuOptionsEl: HTMLDivElement;
let selectFieldEl: HTMLButtonElement;
let selectFieldEl: HTMLDivElement;
function nextOptionIndex(currentIndex: number) {
// Find next non-disabled option
Expand Down Expand Up @@ -412,8 +412,9 @@
}
</script>

<button
type="button"
<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div
aria-haspopup={!inlineOptions ? 'listbox' : undefined}
class={cls(
'SelectField block w-full cursor-default text-left',
Expand Down Expand Up @@ -652,4 +653,4 @@
</SelectListOptions>
{/if}
{/if}
</button>
</div>
7 changes: 4 additions & 3 deletions packages/svelte-ux/src/lib/components/TableOfContents.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import { mdiCircleSmall } from '@mdi/js';
import { BROWSER } from 'esm-env';
import { buildTree, type TreeNode } from '../utils/array.js';
import { cls } from '../utils/styles.js';
Expand All @@ -9,7 +10,7 @@
import { getComponentClasses } from './theme.js';
export let element = 'main';
export let scrollContainer = window;
export let scrollContainer = BROWSER ? window : null;
export let scrollOffset = 0;
export let maxDepth = 6;
export let icon = mdiCircleSmall;
Expand Down Expand Up @@ -52,13 +53,13 @@
});
nodes = buildTree(headings);
scrollContainer.addEventListener('scroll', onScroll, { passive: true });
scrollContainer?.addEventListener('scroll', onScroll, { passive: true });
// set first heading until scrolled
activeHeadingId = headings[0]?.id;
});
onDestroy(() => {
scrollContainer.removeEventListener('scroll', onScroll);
scrollContainer?.removeEventListener('scroll', onScroll);
});
</script>

Expand Down
2 changes: 1 addition & 1 deletion packages/svelte-ux/src/lib/components/TextField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
export let placeholder: string | undefined = undefined;
export let error: string | string[] | boolean | undefined = '';
export let hint = '';
export let autocomplete = 'off'; // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
export let autocomplete: HTMLTextAreaElement['autocomplete'] = 'off'; // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
export let multiline = false;
export let required = false;
export let disabled = false;
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte-ux/src/lib/components/settings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getContext, setContext } from 'svelte';
import { writable, derived, type Readable, type Writable } from 'svelte/store';
import { BROWSER } from 'esm-env';

import {
type ComponentName,
Expand All @@ -19,7 +20,6 @@ import {
} from '$lib/utils/locale.js';
import { buildFormatters, type FormatFunctions } from '../utils/format.js';
import { breakpoints } from '../stores/matchMedia.js';
import { browser } from '../utils/env.js';

export interface DefaultProps {
labelPlacement: LabelPlacement;
Expand Down Expand Up @@ -97,7 +97,7 @@ function createLocaleStores(settings: SettingsInput) {
}

function createShowDrawer() {
return writable(browser ? window.innerWidth >= breakpoints.md : true);
return writable(BROWSER ? window.innerWidth >= breakpoints.md : true);
}

export function settings(settings: SettingsInput = {}): Settings {
Expand Down
6 changes: 3 additions & 3 deletions packages/svelte-ux/src/lib/stores/localStore.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { writable } from 'svelte/store';
import { isFunction } from 'lodash-es';
import { BROWSER } from 'esm-env';

import { parse, stringify } from '../utils/json.js';
import { expireObject } from '../utils/object.js';
import type { Expiry } from '../utils/object.js';
import { browser } from '../utils/env.js';

type LocalStoreOptions<Value> = {
expiry?: Expiry | ((previousExpiry: Expiry | undefined | null) => Expiry);
Expand All @@ -18,7 +18,7 @@ function localStore<Value>(key: string, initialValue: Value, options?: LocalStor
if (options?.override != null) {
value = options?.override;
} else {
const storedValue = browser ? localStorage.getItem(key) : null;
const storedValue = BROWSER ? localStorage.getItem(key) : null;
if (storedValue !== null) {
const decodedValue = parse(storedValue);
if (options?.expiry) {
Expand All @@ -34,7 +34,7 @@ function localStore<Value>(key: string, initialValue: Value, options?: LocalStor

const store = writable<Value>(value);

if (browser) {
if (BROWSER) {
store.subscribe((val) => {
if (options?.expiry) {
// Remove all expired expiry
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte-ux/src/lib/stores/matchMedia.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { readable, writable } from 'svelte/store';
import { browser } from '../utils/env.js';
import { BROWSER } from 'esm-env';

export function matchMedia(queryString: string) {
if (browser) {
if (BROWSER) {
const query = window.matchMedia(queryString);
return readable(query.matches, (set) => {
const listener = (e: MediaQueryListEvent | MediaQueryList) => set(e.matches);
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte-ux/src/lib/stores/themeStore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { writable, type Readable } from 'svelte/store';
import { browser } from '../utils/env.js';
import { BROWSER } from 'esm-env';

/** Information about the currently chosen theme. */
export class CurrentTheme {
Expand Down Expand Up @@ -35,7 +35,7 @@ export interface ThemeStoreOptions {
export function createThemeStore(options: ThemeStoreOptions): ThemeStore {
let store = writable<CurrentTheme>(new CurrentTheme(null, false));

if (!browser) {
if (!BROWSER) {
// Stub out most of the store when running SSR.
return {
subscribe: store.subscribe,
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte-ux/src/lib/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { browser } from './env.js';
import { BROWSER } from 'esm-env';

const logLevels = ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'] as const;
type LogLevel = (typeof logLevels)[number];
Expand Down Expand Up @@ -40,7 +40,7 @@ export class Logger {

log(level: LogLevel, ...message: any) {
// TODO: Consider checking `env` for SSR support?
const enabledLoggers = browser
const enabledLoggers = BROWSER
? (localStorage
.getItem('logger')
?.split(',')
Expand Down
4 changes: 2 additions & 2 deletions packages/svelte-ux/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
createLocaleSettings,
entries,
} from 'svelte-ux';
import { DEV } from 'esm-env';
import NavMenu from './_NavMenu.svelte';
import LanguageSelect from '$lib/components/LanguageSelect.svelte';
import { dev } from '$app/environment';
import { afterNavigate, goto } from '$app/navigation';
import { page } from '$app/stores';
Expand Down Expand Up @@ -164,7 +164,7 @@
}, 0);
// Posthog analytics
if (!dev) {
if (!DEV) {
const unsubscribePage = page.subscribe(($page) => {
if (currentPath && currentPath !== $page.url.pathname) {
// Page navigated away
Expand Down
5 changes: 2 additions & 3 deletions packages/svelte-ux/src/routes/+layout.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import posthog from 'posthog-js';

import { browser, dev } from '$app/environment';
import { BROWSER, DEV } from 'esm-env';

// Disable server-side rendering until AppLayout shift is fixed (issue #22)
export const ssr = false;

export const load = async ({ data }) => {
// Setup Posthog
if (browser && !dev) {
if (BROWSER && !DEV) {
// @ts-expect-error: `posthog.init()` is valid - https://posthog.com/docs/product-analytics/installation
posthog.init('phc_F78mUWQpKPpsXS1mamJFzDWM8bivZrwIx4Nm1cI8BSb', {
api_host: 'https://app.posthog.com',
Expand Down
5 changes: 3 additions & 2 deletions packages/svelte-ux/src/routes/docs/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,11 @@
</div>
{/if}

{#if api}
<!-- TODO: Re-enable once Svelte 5 compatibility replacement for sveld is add (issue #435) -->
<!-- {#if api}
<h1>API</h1>
<ApiDocs {api} />
{/if}
{/if} -->
</div>

{#if showTableOfContents && $xlScreen}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
<div class="relative">
<Toggle let:on={enabled} let:toggleOn let:toggleOff>
<Button on:click={toggleOn} class="border mt-4">Move to body</Button>
<div use:portal={enabled} class="portal-content">
<!-- Explicit "target: document.body" only needed because ".PortalTarget" exists other examples -->
<div use:portal={{ enabled, target: document.body }} class="portal-content">
<div>Portal content</div>
{#if enabled}
<Button on:click={toggleOff} class="border mt-4">Move back to parent</Button>
Expand Down
2 changes: 1 addition & 1 deletion packages/svelte-ux/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { sveltekit } from '@sveltejs/kit/vite';
import { sveld } from './src/lib/plugins/vite.js';

export default defineConfig({
plugins: [sveltekit(), sveld()],
plugins: [sveltekit() /*, sveld()*/],
test: {
include: ['src/**/*.{test,spec}.{js,ts}'],
deps: {
Expand Down
Loading

0 comments on commit ebe86d0

Please sign in to comment.