glassrender-vue 0.0.0-stage → 0.1.1-beta

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,199 @@
1
+ /**
2
+ * @file Glass.ts
3
+ * @brief Vue component that tracks a DOM box with glass.
4
+ * @details Content inherits --glass-foreground and --glass-title. Group members contribute
5
+ * geometry; the group owns their material.
6
+ */
7
+ import { type PropType } from "vue";
8
+ import type { Appearance, CornerStyle, Preset, Radius, Rgba, ShownScheme, Transition } from "glassrender";
9
+ /**
10
+ * @brief Track the component's div with a glass shape.
11
+ * @details Inside a group, only geometry options apply; the group supplies the material.
12
+ */
13
+ export declare const Glass: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
14
+ /** @brief Built-in material: "standard" (default), "clear", "menu", "dock", ... */
15
+ preset: {
16
+ type: PropType<Preset | undefined>;
17
+ default: undefined;
18
+ };
19
+ /** @brief Surroundings (default: the canvas setting). */
20
+ appearance: {
21
+ type: PropType<Appearance | undefined>;
22
+ default: undefined;
23
+ };
24
+ /**
25
+ * @brief Corner radius in CSS pixels, or four radii (top-left, top-right, bottom-right,
26
+ * bottom-left).
27
+ * @details Default: half the short side.
28
+ */
29
+ radius: {
30
+ type: PropType<Radius | undefined>;
31
+ default: undefined;
32
+ };
33
+ /** @brief Corner construction (default "smooth"). */
34
+ corner: {
35
+ type: PropType<CornerStyle>;
36
+ default: string;
37
+ };
38
+ /**
39
+ * @brief Outline of any shape instead of a rounded rectangle: the alpha channel of an image
40
+ * or canvas, stretched over the box.
41
+ * @details It has to be there when the box is first drawn; later values replace the mask.
42
+ */
43
+ mask: {
44
+ type: PropType<TexImageSource | undefined>;
45
+ default: undefined;
46
+ };
47
+ /** @brief Small glass follows the luminance of the backdrop under it (default true). */
48
+ adaptive: {
49
+ type: BooleanConstructor;
50
+ default: boolean;
51
+ };
52
+ /** @brief Color laid over the glass; its alpha is the strength. */
53
+ tint: {
54
+ type: PropType<Rgba | null>;
55
+ default: null;
56
+ };
57
+ /** @brief Opacity of the glass with its shadow (default 1). */
58
+ opacity: {
59
+ type: NumberConstructor;
60
+ default: number;
61
+ };
62
+ /** @brief Color-separation multiplier (0..1); null inherits the canvas default. */
63
+ chromaticAberration: {
64
+ type: PropType<number | null>;
65
+ default: null;
66
+ };
67
+ /** @brief Shown (default) or hidden. */
68
+ visible: {
69
+ type: BooleanConstructor;
70
+ default: boolean;
71
+ };
72
+ /** @brief Pressed veil. */
73
+ pressed: {
74
+ type: BooleanConstructor;
75
+ default: boolean;
76
+ };
77
+ /** @brief Show the pressed veil while a pointer is down on the box. */
78
+ interactive: {
79
+ type: BooleanConstructor;
80
+ default: boolean;
81
+ };
82
+ /** @brief How visibility changes and removal look (default "materialize"). */
83
+ transition: {
84
+ type: PropType<Transition>;
85
+ default: string;
86
+ };
87
+ /**
88
+ * @brief Measure the box on every frame (for boxes moved by CSS animations or transforms).
89
+ */
90
+ everyFrame: {
91
+ type: BooleanConstructor;
92
+ default: boolean;
93
+ };
94
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
95
+ [key: string]: any;
96
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
97
+ /**
98
+ * @brief "dark" or "light" when the scheme the glass shows changes (and once at the start).
99
+ */
100
+ scheme: (_scheme: ShownScheme) => true;
101
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
102
+ /** @brief Built-in material: "standard" (default), "clear", "menu", "dock", ... */
103
+ preset: {
104
+ type: PropType<Preset | undefined>;
105
+ default: undefined;
106
+ };
107
+ /** @brief Surroundings (default: the canvas setting). */
108
+ appearance: {
109
+ type: PropType<Appearance | undefined>;
110
+ default: undefined;
111
+ };
112
+ /**
113
+ * @brief Corner radius in CSS pixels, or four radii (top-left, top-right, bottom-right,
114
+ * bottom-left).
115
+ * @details Default: half the short side.
116
+ */
117
+ radius: {
118
+ type: PropType<Radius | undefined>;
119
+ default: undefined;
120
+ };
121
+ /** @brief Corner construction (default "smooth"). */
122
+ corner: {
123
+ type: PropType<CornerStyle>;
124
+ default: string;
125
+ };
126
+ /**
127
+ * @brief Outline of any shape instead of a rounded rectangle: the alpha channel of an image
128
+ * or canvas, stretched over the box.
129
+ * @details It has to be there when the box is first drawn; later values replace the mask.
130
+ */
131
+ mask: {
132
+ type: PropType<TexImageSource | undefined>;
133
+ default: undefined;
134
+ };
135
+ /** @brief Small glass follows the luminance of the backdrop under it (default true). */
136
+ adaptive: {
137
+ type: BooleanConstructor;
138
+ default: boolean;
139
+ };
140
+ /** @brief Color laid over the glass; its alpha is the strength. */
141
+ tint: {
142
+ type: PropType<Rgba | null>;
143
+ default: null;
144
+ };
145
+ /** @brief Opacity of the glass with its shadow (default 1). */
146
+ opacity: {
147
+ type: NumberConstructor;
148
+ default: number;
149
+ };
150
+ /** @brief Color-separation multiplier (0..1); null inherits the canvas default. */
151
+ chromaticAberration: {
152
+ type: PropType<number | null>;
153
+ default: null;
154
+ };
155
+ /** @brief Shown (default) or hidden. */
156
+ visible: {
157
+ type: BooleanConstructor;
158
+ default: boolean;
159
+ };
160
+ /** @brief Pressed veil. */
161
+ pressed: {
162
+ type: BooleanConstructor;
163
+ default: boolean;
164
+ };
165
+ /** @brief Show the pressed veil while a pointer is down on the box. */
166
+ interactive: {
167
+ type: BooleanConstructor;
168
+ default: boolean;
169
+ };
170
+ /** @brief How visibility changes and removal look (default "materialize"). */
171
+ transition: {
172
+ type: PropType<Transition>;
173
+ default: string;
174
+ };
175
+ /**
176
+ * @brief Measure the box on every frame (for boxes moved by CSS animations or transforms).
177
+ */
178
+ everyFrame: {
179
+ type: BooleanConstructor;
180
+ default: boolean;
181
+ };
182
+ }>> & Readonly<{
183
+ onScheme?: ((_scheme: ShownScheme) => any) | undefined;
184
+ }>, {
185
+ preset: "menu" | "standard" | "clear" | "identity" | "notification" | "popover" | "sidebar" | "attachedSidebar" | "inspector" | "dock" | "controlPanel" | "keyboard" | "widget" | "icon" | "player" | "call" | "camera" | "control" | "loupe" | "slider" | "monogram" | "bubble" | "text" | "assistant" | "assistantCard" | "focusRing" | "focusBackground" | "vehicle" | undefined;
186
+ appearance: Appearance | undefined;
187
+ radius: Radius | undefined;
188
+ corner: CornerStyle;
189
+ mask: TexImageSource | undefined;
190
+ adaptive: boolean;
191
+ tint: Rgba | null;
192
+ opacity: number;
193
+ chromaticAberration: number | null;
194
+ visible: boolean;
195
+ pressed: boolean;
196
+ interactive: boolean;
197
+ transition: Transition;
198
+ everyFrame: boolean;
199
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
package/dist/Glass.js ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * @file Glass.ts
3
+ * @brief Vue component that tracks a DOM box with glass.
4
+ * @details Content inherits --glass-foreground and --glass-title. Group members contribute
5
+ * geometry; the group owns their material.
6
+ */
7
+ import { defineComponent, h, inject, mergeProps, onBeforeUnmount, ref, shallowRef, watch } from "vue";
8
+ import { CANVAS_KEY, GROUP_KEY } from "./context.js";
9
+ // Match DOM backgrounds and outlines to the glass corners.
10
+ function rounding(radius) {
11
+ return radius === undefined ? "9999px" : typeof radius === "number" ? radius + "px" : radius.map((r) => r + "px").join(" ");
12
+ }
13
+ function call(handler, e) {
14
+ const f = handler;
15
+ if (typeof f === "function")
16
+ f(e);
17
+ else if (Array.isArray(f))
18
+ for (const g of f)
19
+ g(e);
20
+ }
21
+ /**
22
+ * @brief Track the component's div with a glass shape.
23
+ * @details Inside a group, only geometry options apply; the group supplies the material.
24
+ */
25
+ export const Glass = defineComponent({
26
+ name: "Glass",
27
+ inheritAttrs: false,
28
+ props: {
29
+ /** @brief Built-in material: "standard" (default), "clear", "menu", "dock", ... */
30
+ preset: { type: String, default: undefined },
31
+ /** @brief Surroundings (default: the canvas setting). */
32
+ appearance: { type: String, default: undefined },
33
+ /**
34
+ * @brief Corner radius in CSS pixels, or four radii (top-left, top-right, bottom-right,
35
+ * bottom-left).
36
+ * @details Default: half the short side.
37
+ */
38
+ radius: { type: [Number, Array], default: undefined },
39
+ /** @brief Corner construction (default "smooth"). */
40
+ corner: { type: String, default: "smooth" },
41
+ /**
42
+ * @brief Outline of any shape instead of a rounded rectangle: the alpha channel of an image
43
+ * or canvas, stretched over the box.
44
+ * @details It has to be there when the box is first drawn; later values replace the mask.
45
+ */
46
+ mask: { type: Object, default: undefined },
47
+ /** @brief Small glass follows the luminance of the backdrop under it (default true). */
48
+ adaptive: { type: Boolean, default: true },
49
+ /** @brief Color laid over the glass; its alpha is the strength. */
50
+ tint: { type: Array, default: null },
51
+ /** @brief Opacity of the glass with its shadow (default 1). */
52
+ opacity: { type: Number, default: 1 },
53
+ /** @brief Color-separation multiplier (0..1); null inherits the canvas default. */
54
+ chromaticAberration: { type: Number, default: null },
55
+ /** @brief Shown (default) or hidden. */
56
+ visible: { type: Boolean, default: true },
57
+ /** @brief Pressed veil. */
58
+ pressed: { type: Boolean, default: false },
59
+ /** @brief Show the pressed veil while a pointer is down on the box. */
60
+ interactive: { type: Boolean, default: false },
61
+ /** @brief How visibility changes and removal look (default "materialize"). */
62
+ transition: { type: String, default: "materialize" },
63
+ /**
64
+ * @brief Measure the box on every frame (for boxes moved by CSS animations or transforms).
65
+ */
66
+ everyFrame: { type: Boolean, default: false }
67
+ },
68
+ emits: {
69
+ /**
70
+ * @brief "dark" or "light" when the scheme the glass shows changes (and once at the start).
71
+ */
72
+ scheme: (_scheme) => true
73
+ },
74
+ setup(props, { attrs, emit, slots }) {
75
+ const canvas = inject(CANVAS_KEY, undefined), group = inject(GROUP_KEY, undefined);
76
+ const box = shallowRef(null);
77
+ const down = ref(false);
78
+ let pressPointer = null;
79
+ let pressCleanup = null;
80
+ let shape = null, member = null;
81
+ onBeforeUnmount(() => { pressCleanup?.(); });
82
+ // Create the shape or group member after both the box and canvas are ready.
83
+ watch(() => [box.value, canvas === undefined ? null : canvas.glass, group === undefined ? null : group.group], ([el, glass, g], _old, onCleanup) => {
84
+ if (el === null)
85
+ return;
86
+ if (group !== undefined) {
87
+ if (g === null)
88
+ return;
89
+ const m = g.add({
90
+ x: 0, y: 0, width: 0, height: 0, corner: props.corner, ...(props.radius === undefined ? {} : { radius: props.radius }),
91
+ ...(props.mask === undefined ? {} : { mask: props.mask })
92
+ });
93
+ if (m === null)
94
+ return;
95
+ m.follow(el, props.everyFrame);
96
+ member = m;
97
+ onCleanup(() => {
98
+ member = null;
99
+ m.remove();
100
+ });
101
+ return;
102
+ }
103
+ if (glass === null)
104
+ return;
105
+ const s = glass.add({
106
+ x: 0, y: 0, width: 0, height: 0, corner: props.corner, tint: props.tint,
107
+ opacity: props.opacity, chromaticAberration: props.chromaticAberration, visible: props.visible, transition: props.transition, adaptive: props.adaptive,
108
+ pressed: props.pressed || down.value,
109
+ onScheme: (scheme) => emit("scheme", scheme),
110
+ ...(props.radius === undefined ? {} : { radius: props.radius }), ...(props.preset === undefined ? {} : { preset: props.preset }), ...(props.appearance === undefined ? {} : { appearance: props.appearance }),
111
+ ...(props.mask === undefined ? {} : { mask: props.mask })
112
+ });
113
+ s.follow(el, props.everyFrame);
114
+ shape = s;
115
+ onCleanup(() => {
116
+ shape = null;
117
+ s.remove();
118
+ });
119
+ }, { immediate: true, flush: "post" });
120
+ watch(() => props.everyFrame, (v) => {
121
+ const el = box.value;
122
+ if (el === null)
123
+ return;
124
+ shape?.follow(el, v);
125
+ member?.follow(el, v);
126
+ }, { flush: "post" });
127
+ watch(() => props.preset, (v) => { shape?.set({ preset: v ?? "standard" }); });
128
+ watch(() => props.appearance, (v) => { if (v !== undefined)
129
+ shape?.set({ appearance: v }); });
130
+ watch(() => (props.radius === undefined ? "" : typeof props.radius === "number" ? String(props.radius) : props.radius.join(" ")), () => {
131
+ const v = props.radius ?? null;
132
+ shape?.set({ radius: v });
133
+ member?.set({ radius: v });
134
+ });
135
+ watch(() => props.mask, (v) => {
136
+ if (v === undefined)
137
+ return;
138
+ shape?.set({ mask: v });
139
+ member?.set({ mask: v });
140
+ });
141
+ watch(() => props.adaptive, (v) => { shape?.set({ adaptive: v }); });
142
+ watch(() => props.corner, (v) => { shape?.set({ corner: v }); });
143
+ watch(() => (props.tint === null ? "" : props.tint.join(",")), () => { shape?.set({ tint: props.tint }); });
144
+ watch(() => props.opacity, (v) => { shape?.set({ opacity: v }); });
145
+ watch(() => props.chromaticAberration, (v) => { shape?.set({ chromaticAberration: v }); });
146
+ watch(() => props.visible, (v) => { shape?.set({ visible: v }); });
147
+ watch(() => props.transition, (v) => { shape?.set({ transition: v }); });
148
+ watch(() => props.pressed || down.value, (v) => { shape?.press(v); });
149
+ const releasePress = (pointerId) => {
150
+ if (pointerId !== undefined && pointerId !== pressPointer)
151
+ return;
152
+ pressCleanup?.();
153
+ down.value = false;
154
+ };
155
+ // Observe releases without capturing the pointer away from a child button or link.
156
+ const pointerdown = (e) => {
157
+ call(attrs.onPointerdown, e);
158
+ if (!props.interactive || e.defaultPrevented || pressPointer !== null)
159
+ return;
160
+ const doc = e.currentTarget.ownerDocument, win = doc.defaultView;
161
+ const finish = (event) => { releasePress(event.pointerId); };
162
+ const blur = () => { releasePress(); };
163
+ pressPointer = e.pointerId;
164
+ pressCleanup = () => {
165
+ doc.removeEventListener("pointerup", finish, true);
166
+ doc.removeEventListener("pointercancel", finish, true);
167
+ win?.removeEventListener("blur", blur);
168
+ pressPointer = null;
169
+ pressCleanup = null;
170
+ };
171
+ doc.addEventListener("pointerup", finish, true);
172
+ doc.addEventListener("pointercancel", finish, true);
173
+ win?.addEventListener("blur", blur);
174
+ down.value = true;
175
+ };
176
+ const pointerup = (e) => { call(attrs.onPointerup, e); releasePress(e.pointerId); };
177
+ const pointercancel = (e) => { call(attrs.onPointercancel, e); releasePress(e.pointerId); };
178
+ const lostcapture = (e) => { call(attrs.onLostpointercapture, e); releasePress(e.pointerId); };
179
+ return () => {
180
+ const { onPointerdown: _a, onPointerup: _b, onPointercancel: _c, onLostpointercapture: _d, ...rest } = attrs;
181
+ return h("div", mergeProps({ class: "glass-box", style: { borderRadius: rounding(props.radius) } }, rest, {
182
+ ref: box, onPointerdown: pointerdown, onPointerup: pointerup, onPointercancel: pointercancel, onLostpointercapture: lostcapture
183
+ }), slots.default === undefined ? undefined : slots.default());
184
+ };
185
+ }
186
+ });
@@ -0,0 +1,275 @@
1
+ /**
2
+ * @file GlassCanvas.ts
3
+ * @brief Vue canvas lifecycle and backdrop component.
4
+ * @details Descendant shapes share one renderer; the canvas sizes to the viewport or its container.
5
+ */
6
+ import { type PropType } from "vue";
7
+ import { type Appearance, type Fit, type Follow, type StackingMode } from "glassrender";
8
+ /** @brief Own the canvas and renderer shared by descendant glass components. */
9
+ export declare const GlassCanvas: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
10
+ /** @brief Picture behind the glass: a URL, or an image, canvas, video or bitmap. */
11
+ backdrop: {
12
+ type: PropType<string | TexImageSource | null>;
13
+ default: null;
14
+ };
15
+ /** @brief How a backdrop of another size is laid on the canvas (default "cover"). */
16
+ fit: {
17
+ type: PropType<Fit>;
18
+ default: string;
19
+ };
20
+ /** @brief Upload the backdrop on every frame (a playing video, an animated canvas). */
21
+ live: {
22
+ type: BooleanConstructor;
23
+ default: boolean;
24
+ };
25
+ /**
26
+ * @brief Default surroundings of the glass (default "auto": the page's color scheme).
27
+ */
28
+ appearance: {
29
+ type: PropType<Appearance>;
30
+ default: string;
31
+ };
32
+ /** @brief Glass over glass: "exact" (default) or "flat". */
33
+ stacking: {
34
+ type: PropType<StackingMode>;
35
+ default: string;
36
+ };
37
+ /** @brief Turn of the rim lights in radians, clockwise. */
38
+ lightAngle: {
39
+ type: NumberConstructor;
40
+ default: number;
41
+ };
42
+ /** @brief Default color-separation multiplier (0..1, default 0.25). */
43
+ chromaticAberration: {
44
+ type: NumberConstructor;
45
+ default: number;
46
+ };
47
+ /** @brief Upper limit of device pixels per CSS pixel (default 2). */
48
+ maxPixelRatio: {
49
+ type: NumberConstructor;
50
+ default: number;
51
+ };
52
+ /**
53
+ * @brief The window is the active one (default true). false gives the flatter glass of an
54
+ * inactive window; "auto" follows the focus of the page.
55
+ */
56
+ active: {
57
+ type: PropType<Follow>;
58
+ default: boolean;
59
+ };
60
+ /**
61
+ * @brief The more opaque, more saturated variant of the standard material (default false).
62
+ */
63
+ tinted: {
64
+ type: BooleanConstructor;
65
+ default: boolean;
66
+ };
67
+ /**
68
+ * @brief Nearly opaque glass without refraction; "auto" (default) follows
69
+ * `prefers-reduced-transparency`.
70
+ */
71
+ reduceTransparency: {
72
+ type: PropType<Follow>;
73
+ default: string;
74
+ };
75
+ /**
76
+ * @brief A stronger, more opaque tone; "auto" (default) follows `prefers-contrast: more`.
77
+ */
78
+ increaseContrast: {
79
+ type: PropType<Follow>;
80
+ default: string;
81
+ };
82
+ /**
83
+ * @brief No refraction inside the glass and more blur; "auto" (default) follows
84
+ * `prefers-reduced-motion: reduce`.
85
+ */
86
+ reduceMotion: {
87
+ type: PropType<Follow>;
88
+ default: string;
89
+ };
90
+ /**
91
+ * @brief Rim lights drawn as a plain outline instead of shaded bands (default false).
92
+ */
93
+ buttonShapes: {
94
+ type: BooleanConstructor;
95
+ default: boolean;
96
+ };
97
+ /**
98
+ * @brief Draw in extended range on screens that show values above the standard white
99
+ * (default false; "auto" follows `dynamic-range: high`).
100
+ * @details It can change later only when it was true or "auto" when the canvas was made.
101
+ */
102
+ extendedRange: {
103
+ type: PropType<Follow>;
104
+ default: boolean;
105
+ };
106
+ /**
107
+ * @brief Brightest value of the screen relative to the standard white, used with extended
108
+ * range (default 2).
109
+ */
110
+ headroom: {
111
+ type: NumberConstructor;
112
+ default: number;
113
+ };
114
+ /** @brief Preferred brightness multiplier name; overrides headroom when supplied. */
115
+ displayHeadroom: {
116
+ type: PropType<number | undefined>;
117
+ default: undefined;
118
+ };
119
+ /** @brief The canvas covers the viewport (default) or only this element. */
120
+ fixed: {
121
+ type: BooleanConstructor;
122
+ default: boolean;
123
+ };
124
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
125
+ [key: string]: any;
126
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
127
+ /** @brief The browser cannot draw the glass (no WebGL2). */
128
+ error: (_message: string) => true;
129
+ /**
130
+ * @brief The WebGL context is lost; the glass draws again on its own when it is back.
131
+ */
132
+ contextlost: () => true;
133
+ /**
134
+ * @brief The context is back: "" when the glass was rebuilt, else why it could not be.
135
+ */
136
+ contextrestored: (_error: string) => true;
137
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
138
+ /** @brief Picture behind the glass: a URL, or an image, canvas, video or bitmap. */
139
+ backdrop: {
140
+ type: PropType<string | TexImageSource | null>;
141
+ default: null;
142
+ };
143
+ /** @brief How a backdrop of another size is laid on the canvas (default "cover"). */
144
+ fit: {
145
+ type: PropType<Fit>;
146
+ default: string;
147
+ };
148
+ /** @brief Upload the backdrop on every frame (a playing video, an animated canvas). */
149
+ live: {
150
+ type: BooleanConstructor;
151
+ default: boolean;
152
+ };
153
+ /**
154
+ * @brief Default surroundings of the glass (default "auto": the page's color scheme).
155
+ */
156
+ appearance: {
157
+ type: PropType<Appearance>;
158
+ default: string;
159
+ };
160
+ /** @brief Glass over glass: "exact" (default) or "flat". */
161
+ stacking: {
162
+ type: PropType<StackingMode>;
163
+ default: string;
164
+ };
165
+ /** @brief Turn of the rim lights in radians, clockwise. */
166
+ lightAngle: {
167
+ type: NumberConstructor;
168
+ default: number;
169
+ };
170
+ /** @brief Default color-separation multiplier (0..1, default 0.25). */
171
+ chromaticAberration: {
172
+ type: NumberConstructor;
173
+ default: number;
174
+ };
175
+ /** @brief Upper limit of device pixels per CSS pixel (default 2). */
176
+ maxPixelRatio: {
177
+ type: NumberConstructor;
178
+ default: number;
179
+ };
180
+ /**
181
+ * @brief The window is the active one (default true). false gives the flatter glass of an
182
+ * inactive window; "auto" follows the focus of the page.
183
+ */
184
+ active: {
185
+ type: PropType<Follow>;
186
+ default: boolean;
187
+ };
188
+ /**
189
+ * @brief The more opaque, more saturated variant of the standard material (default false).
190
+ */
191
+ tinted: {
192
+ type: BooleanConstructor;
193
+ default: boolean;
194
+ };
195
+ /**
196
+ * @brief Nearly opaque glass without refraction; "auto" (default) follows
197
+ * `prefers-reduced-transparency`.
198
+ */
199
+ reduceTransparency: {
200
+ type: PropType<Follow>;
201
+ default: string;
202
+ };
203
+ /**
204
+ * @brief A stronger, more opaque tone; "auto" (default) follows `prefers-contrast: more`.
205
+ */
206
+ increaseContrast: {
207
+ type: PropType<Follow>;
208
+ default: string;
209
+ };
210
+ /**
211
+ * @brief No refraction inside the glass and more blur; "auto" (default) follows
212
+ * `prefers-reduced-motion: reduce`.
213
+ */
214
+ reduceMotion: {
215
+ type: PropType<Follow>;
216
+ default: string;
217
+ };
218
+ /**
219
+ * @brief Rim lights drawn as a plain outline instead of shaded bands (default false).
220
+ */
221
+ buttonShapes: {
222
+ type: BooleanConstructor;
223
+ default: boolean;
224
+ };
225
+ /**
226
+ * @brief Draw in extended range on screens that show values above the standard white
227
+ * (default false; "auto" follows `dynamic-range: high`).
228
+ * @details It can change later only when it was true or "auto" when the canvas was made.
229
+ */
230
+ extendedRange: {
231
+ type: PropType<Follow>;
232
+ default: boolean;
233
+ };
234
+ /**
235
+ * @brief Brightest value of the screen relative to the standard white, used with extended
236
+ * range (default 2).
237
+ */
238
+ headroom: {
239
+ type: NumberConstructor;
240
+ default: number;
241
+ };
242
+ /** @brief Preferred brightness multiplier name; overrides headroom when supplied. */
243
+ displayHeadroom: {
244
+ type: PropType<number | undefined>;
245
+ default: undefined;
246
+ };
247
+ /** @brief The canvas covers the viewport (default) or only this element. */
248
+ fixed: {
249
+ type: BooleanConstructor;
250
+ default: boolean;
251
+ };
252
+ }>> & Readonly<{
253
+ onContextlost?: (() => any) | undefined;
254
+ onContextrestored?: ((_error: string) => any) | undefined;
255
+ onError?: ((_message: string) => any) | undefined;
256
+ }>, {
257
+ appearance: Appearance;
258
+ chromaticAberration: number;
259
+ fixed: boolean;
260
+ backdrop: string | TexImageSource | null;
261
+ fit: Fit;
262
+ live: boolean;
263
+ stacking: StackingMode;
264
+ lightAngle: number;
265
+ maxPixelRatio: number;
266
+ active: Follow;
267
+ tinted: boolean;
268
+ reduceTransparency: Follow;
269
+ increaseContrast: Follow;
270
+ reduceMotion: Follow;
271
+ buttonShapes: boolean;
272
+ extendedRange: Follow;
273
+ headroom: number;
274
+ displayHeadroom: number | undefined;
275
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,148 @@
1
+ /**
2
+ * @file GlassCanvas.ts
3
+ * @brief Vue canvas lifecycle and backdrop component.
4
+ * @details Descendant shapes share one renderer; the canvas sizes to the viewport or its container.
5
+ */
6
+ import { defineComponent, h, onBeforeUnmount, onMounted, provide, shallowReactive, shallowRef, watch } from "vue";
7
+ import { createGlass, DEFAULT_CHROMATIC_ABERRATION } from "glassrender";
8
+ import { CANVAS_KEY, ensureStyle } from "./context.js";
9
+ const COVER = { position: "absolute", inset: "0", width: "100%", height: "100%", display: "block", zIndex: -1, pointerEvents: "none" };
10
+ const FIXED = { ...COVER, position: "fixed", width: "100vw", height: "100vh" };
11
+ /** @brief Own the canvas and renderer shared by descendant glass components. */
12
+ export const GlassCanvas = defineComponent({
13
+ name: "GlassCanvas",
14
+ props: {
15
+ /** @brief Picture behind the glass: a URL, or an image, canvas, video or bitmap. */
16
+ backdrop: { type: [String, Object], default: null },
17
+ /** @brief How a backdrop of another size is laid on the canvas (default "cover"). */
18
+ fit: { type: String, default: "cover" },
19
+ /** @brief Upload the backdrop on every frame (a playing video, an animated canvas). */
20
+ live: { type: Boolean, default: false },
21
+ /**
22
+ * @brief Default surroundings of the glass (default "auto": the page's color scheme).
23
+ */
24
+ appearance: { type: String, default: "auto" },
25
+ /** @brief Glass over glass: "exact" (default) or "flat". */
26
+ stacking: { type: String, default: "exact" },
27
+ /** @brief Turn of the rim lights in radians, clockwise. */
28
+ lightAngle: { type: Number, default: 0 },
29
+ /** @brief Default color-separation multiplier (0..1, default 0.25). */
30
+ chromaticAberration: { type: Number, default: DEFAULT_CHROMATIC_ABERRATION },
31
+ /** @brief Upper limit of device pixels per CSS pixel (default 2). */
32
+ maxPixelRatio: { type: Number, default: 2 },
33
+ /**
34
+ * @brief The window is the active one (default true). false gives the flatter glass of an
35
+ * inactive window; "auto" follows the focus of the page.
36
+ */
37
+ active: { type: [Boolean, String], default: true },
38
+ /**
39
+ * @brief The more opaque, more saturated variant of the standard material (default false).
40
+ */
41
+ tinted: { type: Boolean, default: false },
42
+ /**
43
+ * @brief Nearly opaque glass without refraction; "auto" (default) follows
44
+ * `prefers-reduced-transparency`.
45
+ */
46
+ reduceTransparency: { type: [Boolean, String], default: "auto" },
47
+ /**
48
+ * @brief A stronger, more opaque tone; "auto" (default) follows `prefers-contrast: more`.
49
+ */
50
+ increaseContrast: { type: [Boolean, String], default: "auto" },
51
+ /**
52
+ * @brief No refraction inside the glass and more blur; "auto" (default) follows
53
+ * `prefers-reduced-motion: reduce`.
54
+ */
55
+ reduceMotion: { type: [Boolean, String], default: "auto" },
56
+ /**
57
+ * @brief Rim lights drawn as a plain outline instead of shaded bands (default false).
58
+ */
59
+ buttonShapes: { type: Boolean, default: false },
60
+ /**
61
+ * @brief Draw in extended range on screens that show values above the standard white
62
+ * (default false; "auto" follows `dynamic-range: high`).
63
+ * @details It can change later only when it was true or "auto" when the canvas was made.
64
+ */
65
+ extendedRange: { type: [Boolean, String], default: false },
66
+ /**
67
+ * @brief Brightest value of the screen relative to the standard white, used with extended
68
+ * range (default 2).
69
+ */
70
+ headroom: { type: Number, default: 2 },
71
+ /** @brief Preferred brightness multiplier name; overrides headroom when supplied. */
72
+ displayHeadroom: { type: Number, default: undefined },
73
+ /** @brief The canvas covers the viewport (default) or only this element. */
74
+ fixed: { type: Boolean, default: true }
75
+ },
76
+ emits: {
77
+ /** @brief The browser cannot draw the glass (no WebGL2). */
78
+ error: (_message) => true,
79
+ /**
80
+ * @brief The WebGL context is lost; the glass draws again on its own when it is back.
81
+ */
82
+ contextlost: () => true,
83
+ /**
84
+ * @brief The context is back: "" when the glass was rebuilt, else why it could not be.
85
+ */
86
+ contextrestored: (_error) => true
87
+ },
88
+ setup(props, { emit, slots }) {
89
+ const state = shallowReactive({ glass: null, error: "" });
90
+ provide(CANVAS_KEY, state);
91
+ const canvas = shallowRef(null);
92
+ onMounted(() => {
93
+ const el = canvas.value;
94
+ if (el === null)
95
+ return;
96
+ ensureStyle();
97
+ const made = createGlass(el, {
98
+ appearance: props.appearance, stacking: props.stacking, lightAngle: props.lightAngle, chromaticAberration: props.chromaticAberration, maxPixelRatio: props.maxPixelRatio,
99
+ extendedRange: props.extendedRange, headroom: props.displayHeadroom ?? props.headroom,
100
+ environment: {
101
+ active: props.active, tinted: props.tinted, reduceTransparency: props.reduceTransparency,
102
+ increaseContrast: props.increaseContrast, reduceMotion: props.reduceMotion, buttonShapes: props.buttonShapes
103
+ },
104
+ onContextLost: () => emit("contextlost"),
105
+ onContextRestored: (error) => emit("contextrestored", error)
106
+ });
107
+ if (!made.ok) {
108
+ state.error = made.error;
109
+ emit("error", made.error);
110
+ return;
111
+ }
112
+ state.glass = made.value;
113
+ });
114
+ onBeforeUnmount(() => {
115
+ const g = state.glass;
116
+ state.glass = null;
117
+ if (g !== null)
118
+ g.destroy();
119
+ });
120
+ watch(() => props.appearance, (v) => { state.glass?.setAppearance(v); });
121
+ watch(() => props.stacking, (v) => { state.glass?.setStacking(v); });
122
+ watch(() => props.lightAngle, (v) => { state.glass?.setLightAngle(v); });
123
+ watch(() => props.chromaticAberration, (v) => { state.glass?.setChromaticAberration(v); });
124
+ watch(() => [props.active, props.tinted, props.reduceTransparency, props.increaseContrast, props.reduceMotion, props.buttonShapes], () => {
125
+ state.glass?.setEnvironment({
126
+ active: props.active, tinted: props.tinted, reduceTransparency: props.reduceTransparency,
127
+ increaseContrast: props.increaseContrast, reduceMotion: props.reduceMotion, buttonShapes: props.buttonShapes
128
+ });
129
+ });
130
+ watch(() => [props.extendedRange, props.headroom, props.displayHeadroom], () => { state.glass?.setExtendedRange(props.extendedRange, props.displayHeadroom ?? props.headroom); });
131
+ watch(() => [state.glass, props.backdrop, props.fit, props.live], ([glass, b, f, l]) => {
132
+ if (glass === null)
133
+ return;
134
+ if (typeof b === "string") {
135
+ const img = new Image();
136
+ img.crossOrigin = "anonymous";
137
+ img.src = b;
138
+ glass.setBackdrop(img, f, false);
139
+ }
140
+ else
141
+ glass.setBackdrop(b, f, l);
142
+ });
143
+ return () => h("div", { class: "glass-canvas", style: { position: "relative", isolation: "isolate" } }, [
144
+ h("canvas", { ref: canvas, style: props.fixed ? FIXED : COVER }),
145
+ slots.default === undefined ? null : slots.default()
146
+ ]);
147
+ }
148
+ });
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @file GlassGroup.ts
3
+ * @brief Vue provider for a shared glass material.
4
+ * @details Members contribute outlines that merge within spacing; material options belong to the
5
+ * group.
6
+ */
7
+ import { type PropType } from "vue";
8
+ import type { Appearance, Preset, Rgba, ShownScheme, Transition } from "glassrender";
9
+ /** @brief Own one shared glass material while descendant components supply its outlines. */
10
+ export declare const GlassGroup: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
11
+ /**
12
+ * @brief Distance in CSS pixels over which neighboring members merge (default 0: they only
13
+ * share the glass).
14
+ */
15
+ spacing: {
16
+ type: NumberConstructor;
17
+ default: number;
18
+ };
19
+ /** @brief Built-in material (default "standard"). */
20
+ preset: {
21
+ type: PropType<Preset | undefined>;
22
+ default: undefined;
23
+ };
24
+ /** @brief Surroundings (default: the canvas setting). */
25
+ appearance: {
26
+ type: PropType<Appearance | undefined>;
27
+ default: undefined;
28
+ };
29
+ /** @brief Color laid over the glass; its alpha is the strength. */
30
+ tint: {
31
+ type: PropType<Rgba | null>;
32
+ default: null;
33
+ };
34
+ /** @brief Opacity of the glass with its shadow (default 1). */
35
+ opacity: {
36
+ type: NumberConstructor;
37
+ default: number;
38
+ };
39
+ /** @brief Color-separation multiplier (0..1); null inherits the canvas default. */
40
+ chromaticAberration: {
41
+ type: PropType<number | null>;
42
+ default: null;
43
+ };
44
+ /** @brief Shown (default) or hidden. */
45
+ visible: {
46
+ type: BooleanConstructor;
47
+ default: boolean;
48
+ };
49
+ /** @brief How visibility changes look (default "materialize"). */
50
+ transition: {
51
+ type: PropType<Transition>;
52
+ default: string;
53
+ };
54
+ /** @brief Small glass follows the luminance of the backdrop under it (default true). */
55
+ adaptive: {
56
+ type: BooleanConstructor;
57
+ default: boolean;
58
+ };
59
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
60
+ [key: string]: any;
61
+ }>[] | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
62
+ /**
63
+ * @brief "dark" or "light" when the scheme the glass shows changes (and once at the start).
64
+ */
65
+ scheme: (_scheme: ShownScheme) => true;
66
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
67
+ /**
68
+ * @brief Distance in CSS pixels over which neighboring members merge (default 0: they only
69
+ * share the glass).
70
+ */
71
+ spacing: {
72
+ type: NumberConstructor;
73
+ default: number;
74
+ };
75
+ /** @brief Built-in material (default "standard"). */
76
+ preset: {
77
+ type: PropType<Preset | undefined>;
78
+ default: undefined;
79
+ };
80
+ /** @brief Surroundings (default: the canvas setting). */
81
+ appearance: {
82
+ type: PropType<Appearance | undefined>;
83
+ default: undefined;
84
+ };
85
+ /** @brief Color laid over the glass; its alpha is the strength. */
86
+ tint: {
87
+ type: PropType<Rgba | null>;
88
+ default: null;
89
+ };
90
+ /** @brief Opacity of the glass with its shadow (default 1). */
91
+ opacity: {
92
+ type: NumberConstructor;
93
+ default: number;
94
+ };
95
+ /** @brief Color-separation multiplier (0..1); null inherits the canvas default. */
96
+ chromaticAberration: {
97
+ type: PropType<number | null>;
98
+ default: null;
99
+ };
100
+ /** @brief Shown (default) or hidden. */
101
+ visible: {
102
+ type: BooleanConstructor;
103
+ default: boolean;
104
+ };
105
+ /** @brief How visibility changes look (default "materialize"). */
106
+ transition: {
107
+ type: PropType<Transition>;
108
+ default: string;
109
+ };
110
+ /** @brief Small glass follows the luminance of the backdrop under it (default true). */
111
+ adaptive: {
112
+ type: BooleanConstructor;
113
+ default: boolean;
114
+ };
115
+ }>> & Readonly<{
116
+ onScheme?: ((_scheme: ShownScheme) => any) | undefined;
117
+ }>, {
118
+ preset: "menu" | "standard" | "clear" | "identity" | "notification" | "popover" | "sidebar" | "attachedSidebar" | "inspector" | "dock" | "controlPanel" | "keyboard" | "widget" | "icon" | "player" | "call" | "camera" | "control" | "loupe" | "slider" | "monogram" | "bubble" | "text" | "assistant" | "assistantCard" | "focusRing" | "focusBackground" | "vehicle" | undefined;
119
+ appearance: Appearance | undefined;
120
+ adaptive: boolean;
121
+ tint: Rgba | null;
122
+ opacity: number;
123
+ chromaticAberration: number | null;
124
+ visible: boolean;
125
+ transition: Transition;
126
+ spacing: number;
127
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @file GlassGroup.ts
3
+ * @brief Vue provider for a shared glass material.
4
+ * @details Members contribute outlines that merge within spacing; material options belong to the
5
+ * group.
6
+ */
7
+ import { defineComponent, inject, provide, shallowReactive, watch } from "vue";
8
+ import { CANVAS_KEY, GROUP_KEY } from "./context.js";
9
+ /** @brief Own one shared glass material while descendant components supply its outlines. */
10
+ export const GlassGroup = defineComponent({
11
+ name: "GlassGroup",
12
+ props: {
13
+ /**
14
+ * @brief Distance in CSS pixels over which neighboring members merge (default 0: they only
15
+ * share the glass).
16
+ */
17
+ spacing: { type: Number, default: 0 },
18
+ /** @brief Built-in material (default "standard"). */
19
+ preset: { type: String, default: undefined },
20
+ /** @brief Surroundings (default: the canvas setting). */
21
+ appearance: { type: String, default: undefined },
22
+ /** @brief Color laid over the glass; its alpha is the strength. */
23
+ tint: { type: Array, default: null },
24
+ /** @brief Opacity of the glass with its shadow (default 1). */
25
+ opacity: { type: Number, default: 1 },
26
+ /** @brief Color-separation multiplier (0..1); null inherits the canvas default. */
27
+ chromaticAberration: { type: Number, default: null },
28
+ /** @brief Shown (default) or hidden. */
29
+ visible: { type: Boolean, default: true },
30
+ /** @brief How visibility changes look (default "materialize"). */
31
+ transition: { type: String, default: "materialize" },
32
+ /** @brief Small glass follows the luminance of the backdrop under it (default true). */
33
+ adaptive: { type: Boolean, default: true }
34
+ },
35
+ emits: {
36
+ /**
37
+ * @brief "dark" or "light" when the scheme the glass shows changes (and once at the start).
38
+ */
39
+ scheme: (_scheme) => true
40
+ },
41
+ setup(props, { emit, slots }) {
42
+ const canvas = inject(CANVAS_KEY, undefined);
43
+ const state = shallowReactive({ group: null });
44
+ provide(GROUP_KEY, state);
45
+ watch(() => (canvas === undefined ? null : canvas.glass), (glass, _old, onCleanup) => {
46
+ if (glass === null)
47
+ return;
48
+ const group = glass.addGroup({
49
+ spacing: props.spacing, tint: props.tint, opacity: props.opacity, chromaticAberration: props.chromaticAberration,
50
+ visible: props.visible, transition: props.transition, adaptive: props.adaptive,
51
+ onScheme: (scheme) => emit("scheme", scheme),
52
+ ...(props.preset === undefined ? {} : { preset: props.preset }), ...(props.appearance === undefined ? {} : { appearance: props.appearance })
53
+ });
54
+ state.group = group;
55
+ onCleanup(() => {
56
+ state.group = null;
57
+ group.remove();
58
+ });
59
+ }, { immediate: true });
60
+ watch(() => props.spacing, (v) => { state.group?.set({ spacing: v }); });
61
+ watch(() => props.preset, (v) => { state.group?.set({ preset: v ?? "standard" }); });
62
+ watch(() => props.appearance, (v) => { if (v !== undefined)
63
+ state.group?.set({ appearance: v }); });
64
+ watch(() => (props.tint === null ? "" : props.tint.join(",")), () => { state.group?.set({ tint: props.tint }); });
65
+ watch(() => props.opacity, (v) => { state.group?.set({ opacity: v }); });
66
+ watch(() => props.chromaticAberration, (v) => { state.group?.set({ chromaticAberration: v }); });
67
+ watch(() => props.visible, (v) => { state.group?.set({ visible: v }); });
68
+ watch(() => props.transition, (v) => { state.group?.set({ transition: v }); });
69
+ watch(() => props.adaptive, (v) => { state.group?.set({ adaptive: v }); });
70
+ return () => (slots.default === undefined ? null : slots.default());
71
+ }
72
+ });
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @file context.ts
3
+ * @brief Vue context for the nearest glass canvas and group.
4
+ */
5
+ import { type InjectionKey } from "vue";
6
+ import type { Glass, GlassGroup } from "glassrender";
7
+ /**
8
+ * @brief What a `GlassCanvas` shares with the components inside it.
9
+ * @details `glass` is null until the canvas is ready.
10
+ */
11
+ export interface CanvasState {
12
+ glass: Glass | null;
13
+ /** @brief Why the canvas could not be used ("" when it works). */
14
+ error: string;
15
+ }
16
+ /** @brief What a `GlassGroup` shares with its members. */
17
+ export interface GroupState {
18
+ group: GlassGroup | null;
19
+ }
20
+ export declare const CANVAS_KEY: InjectionKey<CanvasState>;
21
+ export declare const GROUP_KEY: InjectionKey<GroupState>;
22
+ /**
23
+ * @brief The state of the nearest `GlassCanvas`, for low-level calls from a component inside it
24
+ * (call it in `setup`).
25
+ * @details Its `glass` field is reactive.
26
+ */
27
+ export declare function useGlass(): CanvasState | undefined;
28
+ /**
29
+ * @brief Content takes the color for the glass it sits on.
30
+ * @details The rule has no specificity, so any rule of the page wins.
31
+ */
32
+ export declare function ensureStyle(): void;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @file context.ts
3
+ * @brief Vue context for the nearest glass canvas and group.
4
+ */
5
+ import { inject } from "vue";
6
+ export const CANVAS_KEY = Symbol("glass-canvas");
7
+ export const GROUP_KEY = Symbol("glass-group");
8
+ /**
9
+ * @brief The state of the nearest `GlassCanvas`, for low-level calls from a component inside it
10
+ * (call it in `setup`).
11
+ * @details Its `glass` field is reactive.
12
+ */
13
+ export function useGlass() {
14
+ return inject(CANVAS_KEY, undefined);
15
+ }
16
+ /**
17
+ * @brief Content takes the color for the glass it sits on.
18
+ * @details The rule has no specificity, so any rule of the page wins.
19
+ */
20
+ export function ensureStyle() {
21
+ if (typeof document === "undefined" || document.getElementById("glassrender-style") !== null)
22
+ return;
23
+ const s = document.createElement("style");
24
+ s.id = "glassrender-style";
25
+ s.textContent = ":where(.glass-box){color:var(--glass-foreground,inherit)}";
26
+ document.head.appendChild(s);
27
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @file index.ts
3
+ * @brief Vue adapter entry point.
4
+ */
5
+ export { GlassCanvas } from "./GlassCanvas.js";
6
+ export { Glass } from "./Glass.js";
7
+ export { GlassGroup } from "./GlassGroup.js";
8
+ export { useGlass, type CanvasState } from "./context.js";
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @file index.ts
3
+ * @brief Vue adapter entry point.
4
+ */
5
+ export { GlassCanvas } from "./GlassCanvas.js";
6
+ export { Glass } from "./Glass.js";
7
+ export { GlassGroup } from "./GlassGroup.js";
8
+ export { useGlass } from "./context.js";
package/package.json CHANGED
@@ -1,6 +1,39 @@
1
1
  {
2
- "name": "glassrender-vue",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "glassrender-vue",
3
+ "version": "0.1.1-beta",
4
+ "description": "Vue components for the GlassRender glass material renderer.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc -p tsconfig.build.json",
22
+ "prepack": "npm run build",
23
+ "check": "vue-tsc -p tsconfig.json --noEmit",
24
+ "demo": "vite --config vite.config.js",
25
+ "build:demo": "vite build --config vite.config.js"
26
+ },
27
+ "peerDependencies": {
28
+ "glassrender": "^0.1.1-beta",
29
+ "vue": "^3.4.0"
30
+ },
31
+ "devDependencies": {
32
+ "@vitejs/plugin-vue": "^6.0.0",
33
+ "glassrender": "file:../..",
34
+ "typescript": "^6.0.3",
35
+ "vite": "^8.3.2",
36
+ "vue": "^3.5.0",
37
+ "vue-tsc": "^3.0.0"
38
+ }
39
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.