kmcom-nuxt-layers 5.0.8 → 6.0.0

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.
Files changed (47) hide show
  1. package/docs/adr/0001-grid-replaces-layout-swiss-grid.md +30 -0
  2. package/docs/adr/0002-content-config-is-app-owned.md +27 -0
  3. package/layers/core/app/components/Element.vue +2 -66
  4. package/layers/core/app/components/ElementTw.vue +2 -66
  5. package/layers/core/app/composables/useElementStyle.ts +5 -59
  6. package/layers/core/app/composables/useLayoutAttrs.ts +20 -20
  7. package/layers/core/app/types/element.ts +41 -18
  8. package/layers/core/app/utils/resolveElementStyle.test.ts +99 -0
  9. package/layers/core/app/utils/resolveElementStyle.ts +52 -0
  10. package/layers/data/metadata/providers/comicvine/server/utils/metadata-comicvine/client.ts +1 -0
  11. package/layers/data/metadata/providers/comicvine/server/utils/metadata-comicvine/provider.ts +0 -10
  12. package/layers/data/metadata/providers/google-books/server/utils/metadata-google-books/client.ts +12 -11
  13. package/layers/data/metadata/providers/google-books/server/utils/metadata-google-books/provider.ts +0 -7
  14. package/layers/data/metadata/providers/openlibrary/server/utils/metadata-openlibrary/client.ts +12 -23
  15. package/layers/data/metadata/providers/openlibrary/server/utils/metadata-openlibrary/provider.ts +0 -10
  16. package/layers/data/metadata/providers/themoviedb/server/utils/metadata-tmdb/client.ts +4 -7
  17. package/layers/data/metadata/providers/themoviedb/server/utils/metadata-tmdb/provider.ts +0 -6
  18. package/layers/data/metadata/server/api/metadata/lookup.get.ts +7 -42
  19. package/layers/data/metadata/server/api/metadata/sync.post.ts +4 -49
  20. package/layers/data/metadata/server/utils/metadata/provider-fetch.test.ts +27 -0
  21. package/layers/data/metadata/server/utils/metadata/provider-fetch.ts +14 -0
  22. package/layers/data/metadata/server/utils/metadata/resolve-record.test.ts +87 -0
  23. package/layers/data/metadata/server/utils/metadata/resolve-record.ts +60 -0
  24. package/layers/data/metadata/shared/types/providers.ts +3 -2
  25. package/layers/design-system/theming/nuxt.config.ts +1 -1
  26. package/layers/design-system/typography/app/components/Typography/CodeBlock.vue +1 -1
  27. package/layers/design-system/typography/app/components/Typography/Headline.vue +1 -1
  28. package/layers/design-system/typography/app/components/Typography/QuoteBlock.vue +1 -1
  29. package/layers/design-system/typography/app/components/Typography/index.vue +1 -1
  30. package/layers/design-system/typography/app/composables/color.test.ts +30 -0
  31. package/layers/design-system/typography/app/composables/color.ts +9 -2
  32. package/layers/design-system/visual/app/composables/tint.test.ts +22 -0
  33. package/layers/design-system/visual/app/composables/tint.ts +6 -7
  34. package/layers/render/shader/nuxt.config.ts +1 -1
  35. package/layers/structure/navigation/app/components/Links/Named.vue +1 -1
  36. package/package.json +5 -4
  37. package/layers/core/app/composables/useElementGrid.test.ts +0 -33
  38. package/layers/core/app/composables/useElementGrid.ts +0 -29
  39. package/layers/core/app/composables/useElementInteraction.test.ts +0 -27
  40. package/layers/core/app/composables/useElementInteraction.ts +0 -17
  41. package/layers/core/app/composables/useElementLayout.test.ts +0 -41
  42. package/layers/core/app/composables/useElementLayout.ts +0 -26
  43. package/layers/core/app/composables/useElementSizing.test.ts +0 -39
  44. package/layers/core/app/composables/useElementSizing.ts +0 -25
  45. package/layers/core/app/composables/useElementSurface.test.ts +0 -33
  46. package/layers/core/app/composables/useElementSurface.ts +0 -21
  47. package/layers/design-system/theming/app/composables/useThemePreferences.ts +0 -5
@@ -1,33 +0,0 @@
1
- import { describe, expect, it } from 'vite-plus/test'
2
-
3
- import { useElementGrid } from './useElementGrid'
4
-
5
- describe('useElementGrid container axis', () => {
6
- it('returns no grid-template properties when grid is not set', () => {
7
- const result = useElementGrid({ cols: 12 })
8
- expect(result.gridTemplateColumns).toBeUndefined()
9
- expect(result.gridTemplateRows).toBeUndefined()
10
- })
11
-
12
- it('converts a numeric cols to a repeat() track when grid is set', () => {
13
- const result = useElementGrid({ grid: true, cols: 12 })
14
- expect(result.gridTemplateColumns).toBe('repeat(12, 1fr)')
15
- })
16
-
17
- it('converts a numeric rows to a repeat() track when grid is set', () => {
18
- const result = useElementGrid({ grid: true, rows: 4 })
19
- expect(result.gridTemplateRows).toBe('repeat(4, 1fr)')
20
- })
21
-
22
- it('passes a string cols track through unchanged', () => {
23
- const result = useElementGrid({ grid: true, cols: '1fr 2fr 1fr' })
24
- expect(result.gridTemplateColumns).toBe('1fr 2fr 1fr')
25
- })
26
-
27
- // display is intentionally NOT set by useElementGrid — useElementLayout owns
28
- // the hidden > grid > flex > block display priority.
29
- it('never sets display, even when grid is true', () => {
30
- const result = useElementGrid({ grid: true, cols: 12 })
31
- expect(result.display).toBeUndefined()
32
- })
33
- })
@@ -1,29 +0,0 @@
1
- import type { CSSProperties } from 'vue'
2
-
3
- // `| undefined` on each is explicit (not just `?`) so component prop objects
4
- // — which have it too, under exactOptionalPropertyTypes — are assignable here.
5
- export type ElementGridProps = {
6
- grid?: boolean | undefined
7
- cols?: number | string | undefined
8
- rows?: number | string | undefined
9
- }
10
-
11
- function track(value: number | string | undefined): string | undefined {
12
- return typeof value === 'number' ? `repeat(${value}, 1fr)` : value
13
- }
14
-
15
- // Container axis only ("I am a grid"). Item placement (colStart/colSpan/rowStart/
16
- // rowSpan) is deliberately out of scope here — that engine (buildGridPlacementStyle,
17
- // layers/structure/layout) lives in the layout layer, and Element itself lives in
18
- // core (used across every layer) so it can't depend on layout. Use LayoutGridItem
19
- // directly for item placement inside a grid built with Element.
20
- export function useElementGrid(props: ElementGridProps): Partial<CSSProperties> {
21
- return {
22
- // `display` is intentionally NOT set here — useElementLayout already maps
23
- // grid: true -> display: 'grid' and owns the hidden > grid > flex > block priority.
24
- ...(props.grid && {
25
- gridTemplateColumns: track(props.cols),
26
- gridTemplateRows: track(props.rows),
27
- }),
28
- }
29
- }
@@ -1,27 +0,0 @@
1
- import { describe, expect, it } from 'vite-plus/test'
2
-
3
- import { useElementInteraction } from './useElementInteraction'
4
-
5
- describe('useElementInteraction', () => {
6
- it('returns all-undefined style when no props are set', () => {
7
- expect(useElementInteraction({})).toEqual({
8
- cursor: undefined,
9
- userSelect: undefined,
10
- pointerEvents: undefined,
11
- })
12
- })
13
-
14
- it('maps every prop to its CSS property 1:1', () => {
15
- expect(
16
- useElementInteraction({
17
- cursor: 'pointer',
18
- select: 'none',
19
- pointer: 'none',
20
- })
21
- ).toEqual({
22
- cursor: 'pointer',
23
- userSelect: 'none',
24
- pointerEvents: 'none',
25
- })
26
- })
27
- })
@@ -1,17 +0,0 @@
1
- import type { CSSProperties } from 'vue'
2
-
3
- // `| undefined` on each is explicit (not just `?`) so component prop objects
4
- // — which have it too, under exactOptionalPropertyTypes — are assignable here.
5
- export type ElementInteractionProps = {
6
- cursor?: CSSProperties['cursor'] | undefined
7
- select?: CSSProperties['userSelect'] | undefined
8
- pointer?: CSSProperties['pointerEvents'] | undefined
9
- }
10
-
11
- export function useElementInteraction(props: ElementInteractionProps): Partial<CSSProperties> {
12
- return {
13
- cursor: props.cursor,
14
- userSelect: props.select,
15
- pointerEvents: props.pointer,
16
- }
17
- }
@@ -1,41 +0,0 @@
1
- import { describe, expect, it } from 'vite-plus/test'
2
-
3
- import { useElementLayout } from './useElementLayout'
4
-
5
- describe('useElementLayout', () => {
6
- it('returns no display when no mode prop is set', () => {
7
- expect(useElementLayout({})).toEqual({ display: undefined })
8
- })
9
-
10
- it('resolves block to display: block', () => {
11
- expect(useElementLayout({ block: true })).toEqual({ display: 'block' })
12
- })
13
-
14
- it('resolves flex to display: flex', () => {
15
- expect(useElementLayout({ flex: true })).toEqual({ display: 'flex' })
16
- })
17
-
18
- it('resolves grid to display: grid', () => {
19
- expect(useElementLayout({ grid: true })).toEqual({ display: 'grid' })
20
- })
21
-
22
- it('resolves hidden to display: none', () => {
23
- expect(useElementLayout({ hidden: true })).toEqual({ display: 'none' })
24
- })
25
-
26
- it('prioritizes hidden over grid, flex, and block when multiple are set', () => {
27
- expect(useElementLayout({ hidden: true, grid: true, flex: true, block: true })).toEqual({
28
- display: 'none',
29
- })
30
- })
31
-
32
- it('prioritizes grid over flex and block', () => {
33
- expect(useElementLayout({ grid: true, flex: true, block: true })).toEqual({
34
- display: 'grid',
35
- })
36
- })
37
-
38
- it('prioritizes flex over block', () => {
39
- expect(useElementLayout({ flex: true, block: true })).toEqual({ display: 'flex' })
40
- })
41
- })
@@ -1,26 +0,0 @@
1
- import type { CSSProperties } from 'vue'
2
-
3
- // `| undefined` on each is explicit (not just `?`) so component prop objects
4
- // — which have it too, under exactOptionalPropertyTypes — are assignable here.
5
- export type ElementLayoutProps = {
6
- block?: boolean | undefined
7
- flex?: boolean | undefined
8
- grid?: boolean | undefined
9
- hidden?: boolean | undefined
10
- }
11
-
12
- type Mode = 'hidden' | 'grid' | 'flex' | 'block'
13
-
14
- const DISPLAY_FOR: Record<Mode, CSSProperties['display']> = {
15
- hidden: 'none',
16
- grid: 'grid',
17
- flex: 'flex',
18
- block: 'block',
19
- }
20
-
21
- export function useElementLayout(props: ElementLayoutProps): Partial<CSSProperties> {
22
- const mode = (['hidden', 'grid', 'flex', 'block'] as const).find((m) => props[m])
23
- return {
24
- display: mode && DISPLAY_FOR[mode],
25
- }
26
- }
@@ -1,39 +0,0 @@
1
- import { describe, expect, it } from 'vite-plus/test'
2
-
3
- import { useElementSizing } from './useElementSizing'
4
-
5
- describe('useElementSizing', () => {
6
- it('returns all-undefined style when no props are set', () => {
7
- expect(useElementSizing({})).toEqual({
8
- width: undefined,
9
- height: undefined,
10
- minWidth: undefined,
11
- maxWidth: undefined,
12
- minHeight: undefined,
13
- maxHeight: undefined,
14
- aspectRatio: undefined,
15
- })
16
- })
17
-
18
- it('maps every prop to its CSS property 1:1', () => {
19
- expect(
20
- useElementSizing({
21
- w: '80px',
22
- h: '40px',
23
- minW: '10rem',
24
- maxW: '20rem',
25
- minH: '5rem',
26
- maxH: '15rem',
27
- aspect: '16 / 9',
28
- })
29
- ).toEqual({
30
- width: '80px',
31
- height: '40px',
32
- minWidth: '10rem',
33
- maxWidth: '20rem',
34
- minHeight: '5rem',
35
- maxHeight: '15rem',
36
- aspectRatio: '16 / 9',
37
- })
38
- })
39
- })
@@ -1,25 +0,0 @@
1
- import type { CSSProperties } from 'vue'
2
-
3
- // `| undefined` on each is explicit (not just `?`) so component prop objects
4
- // — which have it too, under exactOptionalPropertyTypes — are assignable here.
5
- export type ElementSizingProps = {
6
- w?: CSSProperties['width'] | undefined
7
- h?: CSSProperties['height'] | undefined
8
- minW?: CSSProperties['minWidth'] | undefined
9
- maxW?: CSSProperties['maxWidth'] | undefined
10
- minH?: CSSProperties['minHeight'] | undefined
11
- maxH?: CSSProperties['maxHeight'] | undefined
12
- aspect?: CSSProperties['aspectRatio'] | undefined
13
- }
14
-
15
- export function useElementSizing(props: ElementSizingProps): Partial<CSSProperties> {
16
- return {
17
- width: props.w,
18
- height: props.h,
19
- minWidth: props.minW,
20
- maxWidth: props.maxW,
21
- minHeight: props.minH,
22
- maxHeight: props.maxH,
23
- aspectRatio: props.aspect,
24
- }
25
- }
@@ -1,33 +0,0 @@
1
- import { describe, expect, it } from 'vite-plus/test'
2
-
3
- import { useElementSurface } from './useElementSurface'
4
-
5
- describe('useElementSurface', () => {
6
- it('returns all-undefined style when no props are set', () => {
7
- expect(useElementSurface({})).toEqual({
8
- background: undefined,
9
- color: undefined,
10
- border: undefined,
11
- borderRadius: undefined,
12
- boxShadow: undefined,
13
- })
14
- })
15
-
16
- it('maps every prop to its CSS property 1:1', () => {
17
- expect(
18
- useElementSurface({
19
- bg: 'var(--ui-bg-elevated)',
20
- color: 'var(--ui-text)',
21
- border: '1px solid var(--ui-border)',
22
- radius: '0.5rem',
23
- shadow: '0 4px 12px rgb(0 0 0 / 0.15)',
24
- })
25
- ).toEqual({
26
- background: 'var(--ui-bg-elevated)',
27
- color: 'var(--ui-text)',
28
- border: '1px solid var(--ui-border)',
29
- borderRadius: '0.5rem',
30
- boxShadow: '0 4px 12px rgb(0 0 0 / 0.15)',
31
- })
32
- })
33
- })
@@ -1,21 +0,0 @@
1
- import type { CSSProperties } from 'vue'
2
-
3
- // `| undefined` on each is explicit (not just `?`) so component prop objects
4
- // — which have it too, under exactOptionalPropertyTypes — are assignable here.
5
- export type ElementSurfaceProps = {
6
- bg?: CSSProperties['background'] | undefined
7
- color?: CSSProperties['color'] | undefined
8
- border?: CSSProperties['border'] | undefined
9
- radius?: CSSProperties['borderRadius'] | undefined
10
- shadow?: CSSProperties['boxShadow'] | undefined
11
- }
12
-
13
- export function useElementSurface(props: ElementSurfaceProps): Partial<CSSProperties> {
14
- return {
15
- background: props.bg,
16
- color: props.color,
17
- border: props.border,
18
- borderRadius: props.radius,
19
- boxShadow: props.shadow,
20
- }
21
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * @deprecated Use `useTheme()` instead.
3
- * Kept as a backward-compatible alias.
4
- */
5
- export const useThemePreferences = useTheme