rimelight-components 2.1.14 → 2.1.16

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.
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rimelight-components",
3
- "version": "2.1.14",
3
+ "version": "2.1.16",
4
4
  "docs": "https://rimelight.com/tools/rimelight-components",
5
5
  "configKey": "rimelightComponents",
6
6
  "compatibility": {
package/dist/module.mjs CHANGED
@@ -4,7 +4,7 @@ import { readdirSync } from 'node:fs';
4
4
  import { basename } from 'node:path';
5
5
 
6
6
  const name = "rimelight-components";
7
- const version = "2.1.14";
7
+ const version = "2.1.16";
8
8
  const homepage = "https://rimelight.com/tools/rimelight-components";
9
9
 
10
10
  const defaultOptions = {
@@ -2,7 +2,7 @@
2
2
  import { tv } from "tailwind-variants";
3
3
  const header = tv({
4
4
  slots: {
5
- root: "sticky top-0 z-50 h-(--ui-header-height)",
5
+ root: "h-(--ui-header-height)",
6
6
  container: "h-full flex flex-row items-center p-sm",
7
7
  left: "hidden lg:flex flex-1 justify-start",
8
8
  center: "hidden lg:flex flex-none",
@@ -0,0 +1,18 @@
1
+ type __VLS_Props = {
2
+ id: string;
3
+ order?: number;
4
+ hideOnScroll?: boolean;
5
+ };
6
+ declare var __VLS_1: {};
7
+ type __VLS_Slots = {} & {
8
+ default?: (props: typeof __VLS_1) => any;
9
+ };
10
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
14
+ type __VLS_WithSlots<T, S> = T & {
15
+ new (): {
16
+ $slots: S;
17
+ };
18
+ };
@@ -0,0 +1,71 @@
1
+ <script setup>
2
+ import { ref, onMounted, onUnmounted, watch, computed, nextTick } from "vue";
3
+ import { useHeaderStack } from "../../composables";
4
+ import { useWindowScroll } from "@vueuse/core";
5
+ const props = defineProps({
6
+ id: { type: String, required: true },
7
+ order: { type: Number, required: false },
8
+ hideOnScroll: { type: Boolean, required: false }
9
+ });
10
+ const { registerHeader, unregisterHeader, getOffsetFor } = useHeaderStack();
11
+ const { y: scrollY } = useWindowScroll();
12
+ const contentRef = ref(null);
13
+ const isVisible = ref(true);
14
+ const lastScrollY = ref(0);
15
+ const naturalHeight = ref(0);
16
+ const topOffset = computed(() => getOffsetFor(props.id));
17
+ watch(scrollY, (current) => {
18
+ if (!props.hideOnScroll) return;
19
+ const diff = current - lastScrollY.value;
20
+ if (Math.abs(diff) < 10) return;
21
+ if (current <= 50) {
22
+ isVisible.value = true;
23
+ } else isVisible.value = diff <= 0;
24
+ lastScrollY.value = current;
25
+ });
26
+ const updateStack = () => {
27
+ const heightToRegister = isVisible.value ? naturalHeight.value : 0;
28
+ registerHeader(props.id, heightToRegister, props.order);
29
+ };
30
+ watch(isVisible, updateStack);
31
+ let observer = null;
32
+ onMounted(() => {
33
+ nextTick(() => {
34
+ if (contentRef.value) {
35
+ naturalHeight.value = contentRef.value.getBoundingClientRect().height;
36
+ updateStack();
37
+ observer = new ResizeObserver((entries) => {
38
+ const entry = entries[0];
39
+ if (entry) {
40
+ const height = entry.contentRect.height;
41
+ if (height > 0) {
42
+ naturalHeight.value = height;
43
+ updateStack();
44
+ }
45
+ }
46
+ });
47
+ observer.observe(contentRef.value);
48
+ }
49
+ });
50
+ });
51
+ onUnmounted(() => {
52
+ unregisterHeader(props.id);
53
+ observer?.disconnect();
54
+ });
55
+ </script>
56
+
57
+ <template>
58
+ <div
59
+ class="fixed left-0 right-0 z-50 overflow-hidden transition-[top,height,opacity] duration-200 ease-in-out"
60
+ :style="{
61
+ top: `${topOffset}px`,
62
+ height: isVisible ? `${naturalHeight}px` : '0px',
63
+ opacity: isVisible ? 1 : 0,
64
+ pointerEvents: isVisible ? 'auto' : 'none'
65
+ }"
66
+ >
67
+ <div ref="contentRef" class="w-full">
68
+ <slot />
69
+ </div>
70
+ </div>
71
+ </template>
@@ -0,0 +1,18 @@
1
+ type __VLS_Props = {
2
+ id: string;
3
+ order?: number;
4
+ hideOnScroll?: boolean;
5
+ };
6
+ declare var __VLS_1: {};
7
+ type __VLS_Slots = {} & {
8
+ default?: (props: typeof __VLS_1) => any;
9
+ };
10
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
14
+ type __VLS_WithSlots<T, S> = T & {
15
+ new (): {
16
+ $slots: S;
17
+ };
18
+ };
@@ -97,78 +97,81 @@ const handleDeleteConfirm = async () => {
97
97
  </script>
98
98
 
99
99
  <template>
100
- <UHeader class="fixed mt-16 top-0 left-0 z-50 h-12 w-full bg-muted">
101
- <template #left>
102
- <div class="flex items-center gap-xs">
103
- <UButton
104
- icon="lucide:rotate-ccw"
105
- variant="outline"
106
- color="neutral"
107
- size="xs"
108
- :disabled="!canUndo"
109
- @click="undo"
110
- />
111
- <UButton
112
- icon="lucide:rotate-cw"
113
- variant="outline"
114
- color="neutral"
115
- size="xs"
116
- :disabled="!canRedo"
117
- @click="redo"
118
- />
119
- </div>
120
- </template>
100
+ <RCHeaderLayer id="editor-header" :order="3">
101
+ <UHeader class="h-12 w-full bg-muted">
102
+ <template #left>
103
+ <div class="flex items-center gap-xs">
104
+ <UButton
105
+ icon="lucide:rotate-ccw"
106
+ variant="outline"
107
+ color="neutral"
108
+ size="xs"
109
+ :disabled="!canUndo"
110
+ @click="undo"
111
+ />
112
+ <UButton
113
+ icon="lucide:rotate-cw"
114
+ variant="outline"
115
+ color="neutral"
116
+ size="xs"
117
+ :disabled="!canRedo"
118
+ @click="redo"
119
+ />
120
+ </div>
121
+ </template>
121
122
 
122
- <template #right>
123
- <div class="flex items-center gap-xs">
124
- <UButton
125
- :icon="showPreview ? 'lucide:eye-off' : 'lucide:eye'"
126
- label="Preview"
127
- variant="outline"
128
- color="neutral"
129
- size="xs"
130
- @click="showPreview = !showPreview"
131
- />
132
- <UButton
133
- icon="lucide:save"
134
- label="Save"
135
- color="primary"
136
- size="xs"
137
- :loading="isSaving"
138
- @click="handleSave"
139
- />
140
- <RCCreatePageModal
141
- :is-open="isCreateModalOpen"
142
- :definitions="pageDefinitions"
143
- :loading="isCreating"
144
- @close="isCreateModalOpen = false"
145
- @confirm="handleCreateConfirm"
146
- >
123
+ <template #right>
124
+ <div class="flex items-center gap-xs">
147
125
  <UButton
148
- icon="lucide:file-plus"
149
- label="Create Page"
150
- color="primary"
126
+ :icon="showPreview ? 'lucide:eye-off' : 'lucide:eye'"
127
+ label="Preview"
128
+ variant="outline"
129
+ color="neutral"
151
130
  size="xs"
131
+ @click="showPreview = !showPreview"
152
132
  />
153
- </RCCreatePageModal>
154
- <RCDeletePageModal
155
- :is-open="isDeleteModalOpen"
156
- :loading="isDeleting"
157
- :page-title="getLocalizedContent(page.title, locale)"
158
- @close="isDeleteModalOpen = false"
159
- @confirm="handleDeleteConfirm"
160
- >
161
133
  <UButton
162
- icon="lucide:file-plus"
163
- label="Delete Page"
164
- color="error"
134
+ icon="lucide:save"
135
+ label="Save"
136
+ color="primary"
165
137
  size="xs"
138
+ :loading="isSaving"
139
+ @click="handleSave"
166
140
  />
167
- </RCDeletePageModal>
168
- </div>
169
- </template>
170
- </UHeader>
171
- <main
141
+ <RCCreatePageModal
142
+ :is-open="isCreateModalOpen"
143
+ :definitions="pageDefinitions"
144
+ :loading="isCreating"
145
+ @close="isCreateModalOpen = false"
146
+ @confirm="handleCreateConfirm"
147
+ >
148
+ <UButton
149
+ icon="lucide:file-plus"
150
+ label="Create Page"
151
+ color="primary"
152
+ size="xs"
153
+ />
154
+ </RCCreatePageModal>
155
+ <RCDeletePageModal
156
+ :is-open="isDeleteModalOpen"
157
+ :loading="isDeleting"
158
+ :page-title="getLocalizedContent(page.title, locale)"
159
+ @close="isDeleteModalOpen = false"
160
+ @confirm="handleDeleteConfirm"
161
+ >
162
+ <UButton
163
+ icon="lucide:file-plus"
164
+ label="Delete Page"
165
+ color="error"
166
+ size="xs"
167
+ />
168
+ </RCDeletePageModal>
169
+ </div>
170
+ </template>
171
+ </UHeader>
172
+ </RCHeaderLayer>
173
+
174
+ <div
172
175
  ref="split-container"
173
176
  class="flex w-full overflow-hidden"
174
177
  >
@@ -301,5 +304,5 @@ const handleDeleteConfirm = async () => {
301
304
  >
302
305
  <RCPageRenderer v-model="page" :resolve-page="resolvePage" />
303
306
  </div>
304
- </main>
307
+ </div>
305
308
  </template>
@@ -1,3 +1,4 @@
1
+ export * from "./useHeaderStack.js";
1
2
  export * from "./useDateRange.js";
2
3
  export * from "./usePageEditor.js";
3
4
  export * from "./useBlockEditor.js";
@@ -1,3 +1,4 @@
1
+ export * from "./useHeaderStack.js";
1
2
  export * from "./useDateRange.js";
2
3
  export * from "./usePageEditor.js";
3
4
  export * from "./useBlockEditor.js";
@@ -1,3 +1,4 @@
1
+ export * from "./useHeaderStack.mjs";
1
2
  export * from "./useDateRange.mjs";
2
3
  export * from "./usePageEditor.mjs";
3
4
  export * from "./useBlockEditor.mjs";
@@ -0,0 +1,13 @@
1
+ interface HeaderLayer {
2
+ id: string;
3
+ height: number;
4
+ order: number;
5
+ }
6
+ export declare const useHeaderStack: () => {
7
+ registerHeader: (id: string, height: number, order?: number) => void;
8
+ unregisterHeader: (id: string) => void;
9
+ totalOffset: import("vue").ComputedRef<number>;
10
+ getOffsetFor: (id: string) => number;
11
+ layers: import("vue").ComputedRef<HeaderLayer[]>;
12
+ };
13
+ export {};
@@ -0,0 +1,34 @@
1
+ import { computed } from "vue";
2
+ import { useState } from "#app";
3
+ export const useHeaderStack = () => {
4
+ const layers = useState("header-layers", () => []);
5
+ const registerHeader = (id, height, order = 10) => {
6
+ const existingLayer = layers.value.find((l) => l.id === id);
7
+ if (existingLayer) {
8
+ if (existingLayer.height !== height) {
9
+ existingLayer.height = height;
10
+ }
11
+ } else {
12
+ layers.value.push({ id, height, order });
13
+ layers.value.sort((a, b) => a.order - b.order);
14
+ }
15
+ };
16
+ const unregisterHeader = (id) => {
17
+ layers.value = layers.value.filter((l) => l.id !== id);
18
+ };
19
+ const totalOffset = computed(
20
+ () => layers.value.reduce((acc, l) => acc + l.height, 0)
21
+ );
22
+ const getOffsetFor = (id) => {
23
+ const index = layers.value.findIndex((l) => l.id === id);
24
+ if (index === -1) return 0;
25
+ return layers.value.slice(0, index).reduce((acc, l) => acc + l.height, 0);
26
+ };
27
+ return {
28
+ registerHeader,
29
+ unregisterHeader,
30
+ totalOffset,
31
+ getOffsetFor,
32
+ layers: computed(() => layers.value)
33
+ };
34
+ };
@@ -0,0 +1,34 @@
1
+ import { computed } from "vue";
2
+ import { useState } from "#app";
3
+ export const useHeaderStack = () => {
4
+ const layers = useState("header-layers", () => []);
5
+ const registerHeader = (id, height, order = 10) => {
6
+ const existingLayer = layers.value.find((l) => l.id === id);
7
+ if (existingLayer) {
8
+ if (existingLayer.height !== height) {
9
+ existingLayer.height = height;
10
+ }
11
+ } else {
12
+ layers.value.push({ id, height, order });
13
+ layers.value.sort((a, b) => a.order - b.order);
14
+ }
15
+ };
16
+ const unregisterHeader = (id) => {
17
+ layers.value = layers.value.filter((l) => l.id !== id);
18
+ };
19
+ const totalOffset = computed(
20
+ () => layers.value.reduce((acc, l) => acc + l.height, 0)
21
+ );
22
+ const getOffsetFor = (id) => {
23
+ const index = layers.value.findIndex((l) => l.id === id);
24
+ if (index === -1) return 0;
25
+ return layers.value.slice(0, index).reduce((acc, l) => acc + l.height, 0);
26
+ };
27
+ return {
28
+ registerHeader,
29
+ unregisterHeader,
30
+ totalOffset,
31
+ getOffsetFor,
32
+ layers: computed(() => layers.value)
33
+ };
34
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rimelight-components",
3
- "version": "2.1.14",
3
+ "version": "2.1.16",
4
4
  "description": "A component library by Rimelight Entertainment.",
5
5
  "keywords": [
6
6
  "nuxt",