@classic-homes/theme-svelte 1.13.0 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,36 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { render, screen } from '@testing-library/svelte';
3
+ import PageHeader from '../lib/components/PageHeader.svelte';
4
+ /**
5
+ * The title must carry its own type scale. Tailwind preflight resets heading
6
+ * size/weight and outranks the theme's layered base rule in consumer apps, so
7
+ * a bare <h1> is body-sized there - PageHeader cannot lean on it.
8
+ */
9
+ describe('PageHeader title typography', () => {
10
+ it('sets the Spectral display scale on the default h1', () => {
11
+ render(PageHeader, { props: { title: 'All Available Homes' } });
12
+ const h1 = screen.getByRole('heading', { level: 1 });
13
+ expect(h1).toHaveClass('text-h1', 'font-serif', 'italic');
14
+ });
15
+ it('follows the `as` level: h2 is Figtree at the h2 scale', () => {
16
+ render(PageHeader, { props: { title: 'Flying Horse', as: 'h2' } });
17
+ const h2 = screen.getByRole('heading', { level: 2 });
18
+ expect(h2).toHaveClass('text-h2', 'font-sans', 'not-italic');
19
+ expect(h2).not.toHaveClass('text-h1', 'italic');
20
+ });
21
+ it('applies the same scale to the centered variant', () => {
22
+ render(PageHeader, { props: { title: 'About', variant: 'centered' } });
23
+ expect(screen.getByRole('heading', { level: 1 })).toHaveClass('text-h1', 'font-serif');
24
+ });
25
+ it('leaves the hero and form display styles alone', () => {
26
+ const { unmount } = render(PageHeader, { props: { title: 'Ship', variant: 'hero' } });
27
+ const hero = screen.getByRole('heading', { level: 1 });
28
+ expect(hero).toHaveClass('text-5xl', 'font-black');
29
+ expect(hero).not.toHaveClass('text-h1', 'font-serif');
30
+ unmount();
31
+ render(PageHeader, { props: { title: 'Sign in', variant: 'form' } });
32
+ const form = screen.getByRole('heading', { level: 1 });
33
+ expect(form).toHaveClass('font-light');
34
+ expect(form).not.toHaveClass('text-h1');
35
+ });
36
+ });
@@ -10,9 +10,12 @@
10
10
  * - Optional subtitle with branded styling
11
11
  * - Optional actions slot for CTA buttons
12
12
  * - Consistent typography using design tokens: `default` and `centered`
13
- * inherit the theme heading styles for the rendered level (h1 = Spectral
14
- * 500 italic, h2-h6 = Figtree 600); `hero` and `form` are display styles
15
- * that opt out of them.
13
+ * set the theme heading scale for the rendered level explicitly (h1 =
14
+ * Spectral 500 italic via `text-h1`, h2-h6 = Figtree 600 via `text-h2`..
15
+ * `text-h6`). They do not lean on the bare-element styles: Tailwind
16
+ * preflight outranks the theme's `@layer` heading rules in consumer apps,
17
+ * which left the title at body size. `hero` and `form` are display styles
18
+ * with their own scale.
16
19
  */
17
20
  import type { Snippet } from 'svelte';
18
21
  import { cn } from '../utils.js';
@@ -92,10 +95,26 @@
92
95
  }: Props = $props();
93
96
 
94
97
  const styles = $derived(pageHeaderVariants({ variant }));
98
+
99
+ /** Theme type style per heading level; `hero`/`form` carry their own */
100
+ const levelTypeClass: Record<NonNullable<Props['as']>, string> = {
101
+ h1: 'font-serif italic text-h1',
102
+ h2: 'font-sans not-italic text-h2',
103
+ h3: 'font-sans not-italic text-h3',
104
+ h4: 'font-sans not-italic text-h4',
105
+ h5: 'font-sans not-italic text-h5',
106
+ h6: 'font-sans not-italic text-h6',
107
+ };
108
+ const titleClass = $derived(
109
+ cn(
110
+ styles.title(),
111
+ variant === 'default' || variant === 'centered' ? levelTypeClass[as] : undefined
112
+ )
113
+ );
95
114
  </script>
96
115
 
97
116
  <header class={cn(styles.container(), className)} {...restProps}>
98
- <svelte:element this={as} class={styles.title()}>{title}</svelte:element>
117
+ <svelte:element this={as} class={titleClass}>{title}</svelte:element>
99
118
  {#if subtitle}
100
119
  <p class={styles.subtitle()}>{subtitle}</p>
101
120
  {/if}
@@ -9,9 +9,12 @@
9
9
  * - Optional subtitle with branded styling
10
10
  * - Optional actions slot for CTA buttons
11
11
  * - Consistent typography using design tokens: `default` and `centered`
12
- * inherit the theme heading styles for the rendered level (h1 = Spectral
13
- * 500 italic, h2-h6 = Figtree 600); `hero` and `form` are display styles
14
- * that opt out of them.
12
+ * set the theme heading scale for the rendered level explicitly (h1 =
13
+ * Spectral 500 italic via `text-h1`, h2-h6 = Figtree 600 via `text-h2`..
14
+ * `text-h6`). They do not lean on the bare-element styles: Tailwind
15
+ * preflight outranks the theme's `@layer` heading rules in consumer apps,
16
+ * which left the title at body size. `hero` and `form` are display styles
17
+ * with their own scale.
15
18
  */
16
19
  import type { Snippet } from 'svelte';
17
20
  declare const PageHeader: import("svelte").Component<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/theme-svelte",
3
- "version": "1.13.0",
3
+ "version": "1.13.1",
4
4
  "description": "Svelte components for the Classic theme system",
5
5
  "type": "module",
6
6
  "svelte": "./dist/lib/index.js",