@bendyline/squisq-react 2.0.1 → 2.2.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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +20 -0
  3. package/README.md +6 -0
  4. package/dist/index.d.ts +101 -96
  5. package/dist/index.js +1483 -782
  6. package/dist/squisq-player.full.global.js +4165 -0
  7. package/dist/squisq-player.global.js +561 -168
  8. package/dist/standalone-source.d.ts +1 -0
  9. package/dist/standalone-source.js +1 -1
  10. package/dist/styles/index.css +64 -0
  11. package/package.json +8 -4
  12. package/dist/index.js.map +0 -1
  13. package/dist/squisq-player.css +0 -2
  14. package/dist/squisq-player.css.map +0 -1
  15. package/dist/squisq-player.global.js.map +0 -1
  16. package/src/BlockRenderer.tsx +0 -194
  17. package/src/CaptionOverlay.tsx +0 -111
  18. package/src/DocControlsBottom.tsx +0 -109
  19. package/src/DocControlsOverlay.tsx +0 -190
  20. package/src/DocControlsSidebar.tsx +0 -113
  21. package/src/DocControlsSlideshow.tsx +0 -360
  22. package/src/DocPlayer.tsx +0 -1528
  23. package/src/DocPlayerWithSidebar.tsx +0 -155
  24. package/src/DocProgressBar.tsx +0 -257
  25. package/src/InlineAudioPlayer.tsx +0 -46
  26. package/src/InlineVideoPlayer.tsx +0 -70
  27. package/src/LinearDocView.tsx +0 -569
  28. package/src/MarkdownRenderer.tsx +0 -624
  29. package/src/MediaClipLayer.tsx +0 -145
  30. package/src/SocialCaptionOverlay.tsx +0 -255
  31. package/src/__tests__/BlockRenderer.test.tsx +0 -235
  32. package/src/__tests__/DocControlsSlideshow.test.tsx +0 -221
  33. package/src/__tests__/DocPlayer.test.tsx +0 -635
  34. package/src/__tests__/DocPlayerStylesSentinel.test.tsx +0 -41
  35. package/src/__tests__/DocProgressBar.test.tsx +0 -102
  36. package/src/__tests__/JsonView.test.tsx +0 -111
  37. package/src/__tests__/LinearDocView.test.tsx +0 -426
  38. package/src/__tests__/MapLayer.test.tsx +0 -63
  39. package/src/__tests__/MarkdownRenderer.test.tsx +0 -357
  40. package/src/__tests__/MediaClipLayer.test.tsx +0 -70
  41. package/src/__tests__/MediaContext.test.tsx +0 -51
  42. package/src/__tests__/PathLayer.test.tsx +0 -84
  43. package/src/__tests__/TableLayer.test.tsx +0 -142
  44. package/src/__tests__/VideoLayer.test.tsx +0 -94
  45. package/src/__tests__/exports.test.ts +0 -55
  46. package/src/__tests__/fillStyle.test.tsx +0 -160
  47. package/src/__tests__/standaloneEntry.test.tsx +0 -103
  48. package/src/__tests__/transitionStyles.test.ts +0 -125
  49. package/src/__tests__/useAudioSync.test.ts +0 -49
  50. package/src/__tests__/useDocPlayback.transition.test.ts +0 -113
  51. package/src/__tests__/useJsonViewTokens.test.ts +0 -41
  52. package/src/__tests__/useSlideSwipe.test.ts +0 -81
  53. package/src/__tests__/useViewportOrientation.test.ts +0 -22
  54. package/src/hooks/AudioController.ts +0 -114
  55. package/src/hooks/MediaContext.tsx +0 -97
  56. package/src/hooks/index.ts +0 -11
  57. package/src/hooks/useAudioSync.ts +0 -456
  58. package/src/hooks/useAutoSurface.ts +0 -33
  59. package/src/hooks/useDocPlayback.ts +0 -265
  60. package/src/hooks/useMediaSchedule.ts +0 -39
  61. package/src/hooks/useSlideSwipe.ts +0 -265
  62. package/src/hooks/useViewportOrientation.ts +0 -115
  63. package/src/index.ts +0 -70
  64. package/src/jsonView/JsonView.tsx +0 -51
  65. package/src/jsonView/RenderNode.tsx +0 -51
  66. package/src/jsonView/index.ts +0 -2
  67. package/src/jsonView/json-view.css +0 -206
  68. package/src/jsonView/useJsonViewTokens.ts +0 -32
  69. package/src/jsonView/viewers.tsx +0 -343
  70. package/src/layers/ImageLayer.tsx +0 -297
  71. package/src/layers/MapLayer.tsx +0 -185
  72. package/src/layers/PathLayer.tsx +0 -155
  73. package/src/layers/ShapeLayer.tsx +0 -158
  74. package/src/layers/TableLayer.tsx +0 -129
  75. package/src/layers/TextLayer.tsx +0 -571
  76. package/src/layers/TreeLayer.tsx +0 -167
  77. package/src/layers/VideoLayer.tsx +0 -171
  78. package/src/layers/index.ts +0 -6
  79. package/src/standalone-entry.tsx +0 -337
  80. package/src/standalone-source.d.ts +0 -10
  81. package/src/styles/doc-animations.css +0 -2431
  82. package/src/styles/index.css +0 -7
  83. package/src/types.ts +0 -183
  84. package/src/utils/animationUtils.ts +0 -13
  85. package/src/utils/fillStyle.tsx +0 -148
  86. package/src/utils/layerUtils.ts +0 -42
  87. package/src/utils/mapTileUtils.ts +0 -375
package/src/index.ts DELETED
@@ -1,70 +0,0 @@
1
- // Main components
2
- export { DocPlayer } from './DocPlayer.js';
3
- export type { DocPlayerProps } from './DocPlayer.js';
4
- export type { MountOptions, SquisqPlayerHandle } from './standalone-entry.js';
5
- export { BlockRenderer } from './BlockRenderer.js';
6
- export { CaptionOverlay } from './CaptionOverlay.js';
7
- export { SocialCaptionOverlay } from './SocialCaptionOverlay.js';
8
- export { DocControlsOverlay } from './DocControlsOverlay.js';
9
- export { DocControlsBottom } from './DocControlsBottom.js';
10
- export { DocControlsSidebar } from './DocControlsSidebar.js';
11
- export { DocControlsSlideshow } from './DocControlsSlideshow.js';
12
- export { DocPlayerWithSidebar } from './DocPlayerWithSidebar.js';
13
- export { DocProgressBar } from './DocProgressBar.js';
14
- export { MarkdownRenderer } from './MarkdownRenderer.js';
15
- export { LinearDocView } from './LinearDocView.js';
16
- export type { LinearDocViewProps, ImageDisplayMode } from './LinearDocView.js';
17
- export { InlineVideoPlayer } from './InlineVideoPlayer.js';
18
- export type { InlineVideoPlayerProps } from './InlineVideoPlayer.js';
19
- export { InlineAudioPlayer } from './InlineAudioPlayer.js';
20
- export type { InlineAudioPlayerProps } from './InlineAudioPlayer.js';
21
-
22
- // Layer components
23
- export { ImageLayer } from './layers/ImageLayer.js';
24
- export { TextLayer } from './layers/TextLayer.js';
25
- export { ShapeLayer } from './layers/ShapeLayer.js';
26
- export { PathLayer } from './layers/PathLayer.js';
27
- export { VideoLayer } from './layers/VideoLayer.js';
28
- export { TableLayer } from './layers/TableLayer.js';
29
- export { TreeLayer } from './layers/TreeLayer.js';
30
- export { MapLayer } from './layers/MapLayer.js';
31
-
32
- // Timed media clips (block.media + doc.documentMedia playback)
33
- export { MediaClipLayer } from './MediaClipLayer.js';
34
- export type { MediaClipLayerProps } from './MediaClipLayer.js';
35
-
36
- // Hooks
37
- export { useAudioSync } from './hooks/useAudioSync.js';
38
- export { useMediaSchedule } from './hooks/useMediaSchedule.js';
39
- export type { MediaScheduleController } from './hooks/useMediaSchedule.js';
40
- export { useDocPlayback } from './hooks/useDocPlayback.js';
41
- export type { UseDocPlaybackOptions } from './hooks/useDocPlayback.js';
42
- export { useViewportOrientation } from './hooks/useViewportOrientation.js';
43
- export { MediaContext, useMediaProvider, useMediaUrl } from './hooks/MediaContext.js';
44
- export { useAutoSurface } from './hooks/useAutoSurface.js';
45
-
46
- // Types
47
- export type { AudioController, AudioState, AudioActions } from './hooks/AudioController.js';
48
- export type {
49
- PlaybackState,
50
- PlaybackActions,
51
- BlockMarker,
52
- ControlsLayout,
53
- DisplayMode,
54
- CaptionStyle,
55
- CaptionMode,
56
- SlideNavActions,
57
- SquisqRenderAPI,
58
- RenderBlockInfo,
59
- RenderAudioSegmentInfo,
60
- RenderCaptionInfo,
61
- RenderChapterInfo,
62
- } from './types.js';
63
- export { formatTime } from './types.js';
64
-
65
- // Utilities
66
- export { getAnimationStyle, getTransitionClass } from './utils/animationUtils.js';
67
-
68
- // JSON Form — read-only viewer
69
- export { JsonView } from './jsonView/index.js';
70
- export type { JsonViewProps } from './jsonView/index.js';
@@ -1,51 +0,0 @@
1
- /**
2
- * <JsonView>
3
- *
4
- * Read-only renderer for any JSON value bound to a JSON Schema (with
5
- * optional Squisq UI hints). Designed to look like a polished settings
6
- * summary or CRM record — not a disabled form. Themable via the
7
- * standard Theme + SurfaceScheme props used elsewhere in Squisq.
8
- */
9
-
10
- import type { SquisqAnnotatedSchema } from '@bendyline/squisq/jsonForm';
11
- import type { SurfaceScheme, Theme } from '@bendyline/squisq/schemas';
12
- import { useJsonViewTokens } from './useJsonViewTokens';
13
- import { RenderNode } from './RenderNode';
14
-
15
- export interface JsonViewProps {
16
- /** Schema describing the value's shape (with optional `squisq` UI hints). */
17
- schema: SquisqAnnotatedSchema;
18
- /** The value to display. */
19
- value: unknown;
20
- /** Optional theme. Defaults to `DEFAULT_THEME`. */
21
- theme?: Theme;
22
- /** Light/dark surface override; `'auto'` follows `prefers-color-scheme`. */
23
- surface?: SurfaceScheme | 'auto';
24
- /** Padding/gap density. Default: 'comfortable'. */
25
- density?: 'comfortable' | 'compact';
26
- /** Optional CSS class for the outer container. */
27
- className?: string;
28
- }
29
-
30
- export function JsonView(props: JsonViewProps) {
31
- const { schema, value, theme, surface, density = 'comfortable', className } = props;
32
- const { style } = useJsonViewTokens(theme, surface);
33
-
34
- const cls =
35
- 'squisq-json-view' +
36
- (density === 'compact' ? ' squisq-json-view--compact' : '') +
37
- (className ? ` ${className}` : '');
38
-
39
- return (
40
- <div className={cls} style={style}>
41
- <RenderNode
42
- value={value}
43
- schema={schema}
44
- rootSchema={schema}
45
- rootData={value}
46
- pointer=""
47
- density={density}
48
- />
49
- </div>
50
- );
51
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * Recursive dispatcher: looks at a schema node + value, chooses a
3
- * `ControlKind`, evaluates `hidden` rules, and renders the matching
4
- * read-only viewer.
5
- */
6
-
7
- import {
8
- chooseControl,
9
- resolveFlag,
10
- resolveRef,
11
- type SquisqAnnotatedSchema,
12
- } from '@bendyline/squisq/jsonForm';
13
- import { VIEWERS, type ViewerProps } from './viewers';
14
-
15
- export interface RenderNodeProps {
16
- value: unknown;
17
- schema: SquisqAnnotatedSchema;
18
- rootSchema: SquisqAnnotatedSchema;
19
- rootData: unknown;
20
- pointer: string;
21
- density: 'comfortable' | 'compact';
22
- /**
23
- * When a parent group already wrote its own card chrome (e.g. a
24
- * card-stack item), suppress the nested group's outer title so the
25
- * UI doesn't double up on labels.
26
- */
27
- suppressTopGroupTitle?: boolean;
28
- }
29
-
30
- export function RenderNode(props: RenderNodeProps): React.ReactElement | null {
31
- const resolved = resolveRef(props.schema, props.rootSchema) ?? props.schema;
32
-
33
- if (resolveFlag(resolved.squisq?.hidden, props.rootData)) return null;
34
-
35
- const kind = chooseControl(resolved);
36
- const Viewer = VIEWERS[kind];
37
- const viewerProps: ViewerProps = {
38
- value: props.value,
39
- schema: resolved,
40
- rootSchema: props.rootSchema,
41
- rootData: props.rootData,
42
- pointer: props.pointer,
43
- density: props.density,
44
- };
45
- if (kind === 'group' || kind === 'card') {
46
- // GroupViewer accepts an extra prop that RenderNode forwards.
47
- const Group = Viewer as React.ComponentType<ViewerProps & { suppressTitle?: boolean }>;
48
- return <Group {...viewerProps} suppressTitle={props.suppressTopGroupTitle} />;
49
- }
50
- return <Viewer {...viewerProps} />;
51
- }
@@ -1,2 +0,0 @@
1
- export { JsonView } from './JsonView';
2
- export type { JsonViewProps } from './JsonView';
@@ -1,206 +0,0 @@
1
- /**
2
- * <JsonView> — read-only viewer styles.
3
- *
4
- * All colors flow through scoped CSS custom properties on the root
5
- * element so the same component re-themes cleanly without re-render.
6
- */
7
-
8
- .squisq-json-view {
9
- font-family: var(--squisq-json-body-font, system-ui, sans-serif);
10
- color: var(--squisq-json-text);
11
- background: var(--squisq-json-bg);
12
- border-radius: var(--squisq-json-radius, 8px);
13
- padding: 16px;
14
- display: flex;
15
- flex-direction: column;
16
- gap: 16px;
17
- container-type: inline-size;
18
- }
19
-
20
- .squisq-json-view--compact {
21
- padding: 8px;
22
- gap: 8px;
23
- }
24
-
25
- .squisq-jv-group {
26
- display: flex;
27
- flex-direction: column;
28
- gap: 12px;
29
- background: color-mix(in srgb, var(--squisq-json-bg) 92%, var(--squisq-json-text) 8%);
30
- border: 1px solid var(--squisq-json-border);
31
- border-radius: var(--squisq-json-radius, 8px);
32
- padding: 14px 16px;
33
- }
34
-
35
- .squisq-jv-group__title {
36
- font-family: var(--squisq-json-title-font, inherit);
37
- font-size: 1.05em;
38
- font-weight: 600;
39
- color: var(--squisq-json-text);
40
- margin: 0;
41
- }
42
-
43
- .squisq-jv-group__help {
44
- font-size: 0.85em;
45
- color: var(--squisq-json-muted);
46
- margin: -6px 0 0 0;
47
- }
48
-
49
- .squisq-jv-row {
50
- display: grid;
51
- grid-template-columns: minmax(110px, 0.4fr) minmax(0, 1fr);
52
- gap: 12px;
53
- align-items: baseline;
54
- }
55
-
56
- .squisq-json-view--compact .squisq-jv-row {
57
- gap: 8px;
58
- }
59
-
60
- @container (max-width: 480px) {
61
- .squisq-jv-row {
62
- grid-template-columns: 1fr;
63
- gap: 2px;
64
- }
65
- }
66
-
67
- .squisq-jv-label {
68
- color: var(--squisq-json-muted);
69
- font-size: 0.85em;
70
- text-transform: uppercase;
71
- letter-spacing: 0.04em;
72
- font-weight: 500;
73
- }
74
-
75
- .squisq-jv-value {
76
- color: var(--squisq-json-text);
77
- word-break: break-word;
78
- }
79
-
80
- .squisq-jv-value--multiline {
81
- white-space: pre-wrap;
82
- }
83
-
84
- .squisq-jv-empty {
85
- color: var(--squisq-json-muted);
86
- font-style: italic;
87
- }
88
-
89
- .squisq-jv-chip-bin {
90
- display: flex;
91
- flex-wrap: wrap;
92
- gap: 6px;
93
- }
94
-
95
- .squisq-jv-chip {
96
- display: inline-flex;
97
- align-items: center;
98
- padding: 3px 10px;
99
- font-size: 0.85em;
100
- background: color-mix(in srgb, var(--squisq-json-primary) 16%, transparent);
101
- color: var(--squisq-json-text);
102
- border-radius: 999px;
103
- border: 1px solid color-mix(in srgb, var(--squisq-json-primary) 30%, transparent);
104
- }
105
-
106
- .squisq-jv-card-stack {
107
- display: flex;
108
- flex-direction: column;
109
- gap: 10px;
110
- }
111
-
112
- .squisq-jv-card {
113
- background: color-mix(in srgb, var(--squisq-json-bg) 95%, var(--squisq-json-text) 5%);
114
- border: 1px solid var(--squisq-json-border);
115
- border-radius: var(--squisq-json-radius, 6px);
116
- padding: 12px 14px;
117
- display: flex;
118
- flex-direction: column;
119
- gap: 8px;
120
- }
121
-
122
- .squisq-jv-card__title {
123
- font-family: var(--squisq-json-title-font, inherit);
124
- font-weight: 600;
125
- font-size: 0.95em;
126
- color: var(--squisq-json-text);
127
- margin: 0;
128
- }
129
-
130
- .squisq-jv-color {
131
- display: inline-flex;
132
- align-items: center;
133
- gap: 8px;
134
- }
135
-
136
- .squisq-jv-color__swatch {
137
- width: 18px;
138
- height: 18px;
139
- border-radius: 4px;
140
- border: 1px solid var(--squisq-json-border);
141
- display: inline-block;
142
- }
143
-
144
- .squisq-jv-color__hex {
145
- font-family: var(--squisq-json-mono-font, ui-monospace, Consolas, monospace);
146
- font-size: 0.9em;
147
- color: var(--squisq-json-muted);
148
- }
149
-
150
- .squisq-jv-toggle {
151
- display: inline-flex;
152
- align-items: center;
153
- gap: 6px;
154
- padding: 2px 10px;
155
- border-radius: 999px;
156
- font-size: 0.8em;
157
- font-weight: 500;
158
- }
159
-
160
- .squisq-jv-toggle--on {
161
- background: color-mix(in srgb, var(--squisq-json-primary) 18%, transparent);
162
- color: var(--squisq-json-primary);
163
- }
164
-
165
- .squisq-jv-toggle--off {
166
- background: color-mix(in srgb, var(--squisq-json-muted) 14%, transparent);
167
- color: var(--squisq-json-muted);
168
- }
169
-
170
- .squisq-jv-tabs {
171
- display: flex;
172
- flex-direction: column;
173
- gap: 8px;
174
- }
175
-
176
- .squisq-jv-tabs__discriminator {
177
- font-size: 0.8em;
178
- color: var(--squisq-json-muted);
179
- }
180
-
181
- .squisq-jv-richtext {
182
- color: var(--squisq-json-text);
183
- font-family: var(--squisq-json-body-font, inherit);
184
- line-height: 1.55;
185
- }
186
-
187
- .squisq-jv-richtext h1,
188
- .squisq-jv-richtext h2,
189
- .squisq-jv-richtext h3,
190
- .squisq-jv-richtext h4 {
191
- font-family: var(--squisq-json-title-font, inherit);
192
- margin: 0.6em 0 0.3em;
193
- font-weight: 600;
194
- }
195
-
196
- .squisq-jv-richtext p {
197
- margin: 0.4em 0;
198
- }
199
-
200
- .squisq-jv-richtext code {
201
- font-family: var(--squisq-json-mono-font, ui-monospace, Consolas, monospace);
202
- background: color-mix(in srgb, var(--squisq-json-text) 10%, transparent);
203
- padding: 1px 4px;
204
- border-radius: 3px;
205
- font-size: 0.92em;
206
- }
@@ -1,32 +0,0 @@
1
- /**
2
- * Derive the CSS custom-property bag for `<JsonView>` from a Theme + Surface.
3
- * Mirrors the pattern in LinearDocView so JsonView re-themes consistently
4
- * with the rest of Squisq.
5
- */
6
-
7
- import { useMemo } from 'react';
8
- import { type SurfaceScheme, type Theme } from '@bendyline/squisq/schemas';
9
- import { buildJsonFormTokens, resolveJsonFormTheme } from '@bendyline/squisq/jsonForm';
10
- import { useAutoSurface } from '../hooks/useAutoSurface';
11
-
12
- export interface JsonViewTokens {
13
- /** Inline style object to spread onto the root element. */
14
- style: React.CSSProperties;
15
- /** The effective theme (after surface application). */
16
- theme: Theme;
17
- }
18
-
19
- export function useJsonViewTokens(
20
- theme: Theme | undefined,
21
- surface: SurfaceScheme | 'auto' | undefined,
22
- ): JsonViewTokens {
23
- const auto = useAutoSurface(surface === 'auto');
24
- const effectiveSurface = surface === 'auto' ? auto : (surface ?? undefined);
25
-
26
- return useMemo(() => {
27
- const style = buildJsonFormTokens(theme, effectiveSurface, {
28
- prefix: '--squisq-json',
29
- }) as unknown as React.CSSProperties;
30
- return { style, theme: resolveJsonFormTheme(theme, effectiveSurface) };
31
- }, [theme, effectiveSurface]);
32
- }