rimelight-components 2.2.2 → 2.2.6

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.2.2",
3
+ "version": "2.2.6",
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.2.2";
7
+ const version = "2.2.6";
8
8
  const homepage = "https://rimelight.com/tools/rimelight-components";
9
9
 
10
10
  const defaultOptions = {
@@ -1,9 +1,10 @@
1
1
  <script setup>
2
- import { ref, computed } from "vue";
2
+ import { ref, computed, inject } from "vue";
3
3
  import { BLOCK_DEFINITIONS, CATEGORY_ORDER } from "../../utils/blocks";
4
4
  import { useRC } from "../../composables";
5
5
  import { useI18n } from "vue-i18n";
6
6
  import { tv } from "../../internal/tv";
7
+ import { SECTION_LEVEL_KEY } from "../../internal/injectionKeys";
7
8
  const open = defineModel("open", { type: Boolean, ...{ default: false } });
8
9
  const { rc: rcProp } = defineProps({
9
10
  open: { type: Boolean, required: false },
@@ -45,10 +46,15 @@ const {
45
46
  } = addBlockModalStyles();
46
47
  const { t } = useI18n();
47
48
  const searchQuery = ref("");
49
+ const sectionLevel = inject(SECTION_LEVEL_KEY, computed(() => 1));
48
50
  const filteredBlocks = computed(() => {
49
- if (!searchQuery.value) return BLOCK_DEFINITIONS;
51
+ let blocks = BLOCK_DEFINITIONS;
52
+ if (sectionLevel.value >= 6) {
53
+ blocks = blocks.filter((b) => b.type !== "SectionBlock");
54
+ }
55
+ if (!searchQuery.value) return blocks;
50
56
  const query = searchQuery.value.toLowerCase();
51
- return BLOCK_DEFINITIONS.filter(
57
+ return blocks.filter(
52
58
  (block) => block.label.toLowerCase().includes(query) || block.type.toLowerCase().includes(query) || block.category.toLowerCase().includes(query) || block.description?.toLowerCase().includes(query)
53
59
  );
54
60
  });
@@ -121,18 +127,18 @@ const handleSelect = (block) => {
121
127
  :class="blockItem({ class: rc.blockItem })"
122
128
  @click="handleSelect(block)"
123
129
  >
124
- <div :class="blockIcon({ class: rc.blockIcon })">
130
+ <span :class="blockIcon({ class: rc.blockIcon })">
125
131
  <UIcon :name="block.icon" size="20" />
126
- </div>
127
- <div class="flex-1">
128
- <div class="flex items-center justify-between gap-2">
132
+ </span>
133
+ <span class="flex-1 text-left">
134
+ <span class="flex items-center justify-between gap-2">
129
135
  <span :class="blockLabel({ class: rc.blockLabel })">{{ block.label }}</span>
130
- <span class="text-[10px] font-mono text-dimmed px-1.5 py-0.5 bg-neutral-100 dark:bg-neutral-900 rounded">{{ block.type }}</span>
131
- </div>
132
- <p v-if="block.description" :class="blockDescription({ class: rc.blockDescription })">
136
+ <span class="text-[10px] font-mono text-dimmed px-1.5 py-0.5 bg-neutral-100 dark:bg-neutral-900 rounded shrink-0">{{ block.type }}</span>
137
+ </span>
138
+ <span v-if="block.description" :class="blockDescription({ class: rc.blockDescription })" class="block">
133
139
  {{ block.description }}
134
- </p>
135
- </div>
140
+ </span>
141
+ </span>
136
142
  </button>
137
143
  </div>
138
144
  </div>
@@ -3,6 +3,7 @@ import { inject, ref, computed, watch, nextTick, shallowRef } from "vue";
3
3
  import {} from "../../../types";
4
4
  import { tv } from "../../../internal/tv";
5
5
  import { useRC } from "../../../composables";
6
+ import { SECTION_LEVEL_KEY } from "../../../internal/injectionKeys";
6
7
  const props = defineProps({
7
8
  id: { type: String, required: true },
8
9
  rc: { type: Object, required: false },
@@ -18,20 +19,21 @@ const { rc } = useRC("SectionBlockEditor", rcProp);
18
19
  const sectionBlockEditorStyles = tv({
19
20
  slots: {
20
21
  root: "flex flex-col gap-sm",
21
- headerContainer: "flex flex-row gap-xs",
22
+ headerContainer: "flex flex-row items-center gap-xs",
22
23
  titleInput: "w-full"
23
24
  }
24
25
  });
25
26
  const { root, headerContainer, titleInput } = sectionBlockEditorStyles();
26
27
  const editorApi = inject("block-editor-api");
27
- const localLevel = ref(props.level);
28
28
  const localTitle = ref(props.title);
29
29
  const localDescription = ref(props.description);
30
- const levelItems = [
31
- { label: "H1", value: 1 },
32
- { label: "H2", value: 2 },
33
- { label: "H3", value: 3 }
34
- ];
30
+ const parentLevel = inject(SECTION_LEVEL_KEY, computed(() => 1));
31
+ const currentLevel = computed(() => Math.min(6, parentLevel.value + 1));
32
+ watch(currentLevel, (newLevel) => {
33
+ if (editorApi && props.id && newLevel !== props.level) {
34
+ editorApi.updateBlockProps(props.id, { level: newLevel });
35
+ }
36
+ }, { immediate: true });
35
37
  const updateLocalTitle = (e) => {
36
38
  localTitle.value = e.target.value;
37
39
  };
@@ -48,11 +50,6 @@ const commitDescriptionOnBlur = () => {
48
50
  editorApi.updateBlockProps(props.id, { description: localDescription.value });
49
51
  }
50
52
  };
51
- watch(localLevel, (newLocalLevel) => {
52
- if (editorApi && props.id && newLocalLevel !== props.level) {
53
- editorApi.updateBlockProps(props.id, { level: newLocalLevel });
54
- }
55
- });
56
53
  watch(
57
54
  () => props.title,
58
55
  (newVal) => {
@@ -61,14 +58,6 @@ watch(
61
58
  }
62
59
  }
63
60
  );
64
- watch(
65
- () => props.level,
66
- (newVal) => {
67
- if (newVal !== localLevel.value) {
68
- localLevel.value = newVal;
69
- }
70
- }
71
- );
72
61
  watch(
73
62
  () => props.description,
74
63
  (newVal) => {
@@ -93,19 +82,12 @@ const handleChildrenMutation = () => {
93
82
 
94
83
  <template>
95
84
  <div :class="root({ class: rc.root })">
96
- <RCSection :level="localLevel" :title="localTitle" :description="description" is-editing>
85
+ <RCSection :title="localTitle" :description="description" is-editing>
97
86
  <template #title>
98
87
  <div :class="headerContainer({ class: rc.headerContainer })">
99
- <USelect
100
- v-model="localLevel"
101
- :items="levelItems"
102
- value-key="value"
103
- label-key="label"
104
- variant="ghost"
105
- placeholder="Select Heading Level"
106
- size="sm"
107
- color="neutral"
108
- />
88
+ <span class="text-xs font-mono text-dimmed shrink-0 leading-none">
89
+ H{{ currentLevel }}
90
+ </span>
109
91
  <UInput
110
92
  :model-value="localTitle"
111
93
  variant="ghost"
@@ -1,27 +1,31 @@
1
1
  <script setup>
2
2
  import { useRoute } from "#imports";
3
3
  import { useToast } from "@nuxt/ui/composables/useToast";
4
- import { computed } from "vue";
4
+ import { computed, inject, provide } from "vue";
5
5
  import { useClipboard } from "@vueuse/core";
6
6
  import { tv } from "../../internal/tv";
7
7
  import { useRC } from "../../composables";
8
8
  import { slugify } from "../../utils";
9
+ import { SECTION_LEVEL_KEY } from "../../internal/injectionKeys";
9
10
  defineOptions({
10
11
  name: "SectionComponent"
11
12
  });
12
- const {
13
- level = 1,
14
- title,
15
- description,
16
- isEditing = false,
17
- rc: rcProp
18
- } = defineProps({
13
+ const props = defineProps({
19
14
  level: { type: Number, required: false },
20
15
  title: { type: String, required: true },
21
16
  description: { type: String, required: false },
22
17
  isEditing: { type: Boolean, required: false },
23
18
  rc: { type: Object, required: false }
24
19
  });
20
+ const {
21
+ title,
22
+ description,
23
+ isEditing = false,
24
+ rc: rcProp
25
+ } = props;
26
+ const parentLevel = inject(SECTION_LEVEL_KEY, computed(() => 1));
27
+ const level = computed(() => Math.min(6, parentLevel.value + 1));
28
+ provide(SECTION_LEVEL_KEY, level);
25
29
  const emit = defineEmits([]);
26
30
  const slots = defineSlots();
27
31
  const { rc } = useRC("Section", rcProp);
@@ -87,14 +91,7 @@ const sectionStyles = tv({
87
91
  }
88
92
  }
89
93
  });
90
- const {
91
- section,
92
- link,
93
- heading,
94
- descriptionText,
95
- separator,
96
- content
97
- } = sectionStyles({ level });
94
+ const styles = computed(() => sectionStyles({ level: level.value }));
98
95
  const { copy } = useClipboard();
99
96
  const toast = useToast();
100
97
  const route = useRoute();
@@ -123,16 +120,16 @@ const fullSectionUrl = computed(() => {
123
120
  </script>
124
121
 
125
122
  <template>
126
- <section :id="sectionId" :class="section({ class: rc.section })" v-bind="$attrs">
123
+ <section :id="sectionId" :class="styles.section({ class: rc.section })" v-bind="$attrs">
127
124
  <component
128
125
  :id="`${sectionId}-heading`"
129
126
  :is="`h${level}`"
130
- :class="heading({ class: rc.heading })"
127
+ :class="styles.heading({ class: rc.heading })"
131
128
  >
132
129
  <NuxtLink
133
130
  v-if="!isEditing"
134
131
  :href="`#${sectionId}`"
135
- :class="link({ class: rc.link })"
132
+ :class="styles.link({ class: rc.link })"
136
133
  class="group relative lg:-ms-2 lg:ps-2 inline-block w-full"
137
134
  >
138
135
  <ClientOnly>
@@ -155,12 +152,12 @@ const fullSectionUrl = computed(() => {
155
152
  <slot v-else name="title">{{ title }}</slot>
156
153
  </component>
157
154
  <slot name="description">
158
- <p v-if="description" :class="descriptionText({ class: rc.descriptionText })">
155
+ <p v-if="description" :class="styles.descriptionText({ class: rc.descriptionText })">
159
156
  {{ description }}
160
157
  </p>
161
158
  </slot>
162
- <USeparator :class="separator({ class: rc.separator })" />
163
- <div :class="content({ class: rc.content })">
159
+ <USeparator :class="styles.separator({ class: rc.separator })" />
160
+ <div :class="styles.content({ class: rc.content })">
164
161
  <slot />
165
162
  </div>
166
163
  </section>
@@ -15,7 +15,6 @@ const state = reactive({
15
15
  labels: note?.labels?.map((l) => l.label.id) || []
16
16
  });
17
17
  const { data: fetchedLabels } = useApi("/api/notes/labels", {
18
- lazy: true,
19
18
  default: () => []
20
19
  });
21
20
  const allLabels = ref([]);
@@ -156,6 +155,18 @@ watch(open, (isOpen) => {
156
155
  emit("close");
157
156
  }
158
157
  });
158
+ const deleteNote = async () => {
159
+ if (!state.id) return;
160
+ try {
161
+ await $api(`/api/notes/${state.id}`, {
162
+ method: "DELETE"
163
+ });
164
+ open.value = false;
165
+ emit("saved", null);
166
+ } catch (e) {
167
+ console.error("Failed to delete note", e);
168
+ }
169
+ };
159
170
  onUnmounted(() => {
160
171
  if (saveTimeout.value) {
161
172
  clearTimeout(saveTimeout.value);
@@ -216,7 +227,7 @@ onUnmounted(() => {
216
227
  variant="ghost"
217
228
  @click="state.isArchived = !state.isArchived"
218
229
  />
219
- <UButton color="error" icon="lucide:trash-2" size="sm" variant="ghost" @click="" />
230
+ <UButton color="error" icon="lucide:trash-2" size="sm" variant="ghost" @click="deleteNote" />
220
231
  </div>
221
232
  </div>
222
233
  <div class="flex items-center justify-between">
@@ -15,7 +15,7 @@ const emit = defineEmits(["toggle", "archive", "restore", "delete"]);
15
15
  <template v-if="!todo.isArchived">
16
16
  <UCheckbox
17
17
  :model-value="todo.completed"
18
- @update:model-value="(val) => emit('toggle', val)"
18
+ @update:model-value="(val) => emit('toggle', val === true)"
19
19
  />
20
20
  </template>
21
21
  <template v-else>
@@ -0,0 +1,2 @@
1
+ import type { InjectionKey, ComputedRef } from 'vue';
2
+ export declare const SECTION_LEVEL_KEY: InjectionKey<ComputedRef<number>>;
@@ -0,0 +1 @@
1
+ export const SECTION_LEVEL_KEY = Symbol("SECTION_LEVEL");
@@ -0,0 +1 @@
1
+ export const SECTION_LEVEL_KEY = Symbol("SECTION_LEVEL");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rimelight-components",
3
- "version": "2.2.2",
3
+ "version": "2.2.6",
4
4
  "description": "A component library by Rimelight Entertainment.",
5
5
  "keywords": [
6
6
  "nuxt",