rimecms 0.27.3 → 0.27.4

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.
@@ -17,6 +17,7 @@ declare namespace _default {
17
17
  export let delete_dialog_title: string;
18
18
  export let delete_dialog_text: string;
19
19
  export let duplicate: string;
20
+ export let duplicate_success: string;
20
21
  export let doc_deleted: string;
21
22
  export let doc_created: string;
22
23
  export let doc_updated: string;
@@ -17,6 +17,7 @@ export default {
17
17
  delete_dialog_title: 'Delete $1',
18
18
  delete_dialog_text: 'You are about to delete $1, press delete to confirm the operation.',
19
19
  duplicate: 'Duplicate',
20
+ duplicate_success: 'Duplicated successfully',
20
21
  doc_deleted: 'Document deleted',
21
22
  doc_created: 'Document created',
22
23
  doc_updated: 'Document updated',
@@ -16,6 +16,7 @@ declare namespace _default {
16
16
  export let delete_dialog_title: string;
17
17
  export let delete_dialog_text: string;
18
18
  export let duplicate: string;
19
+ export let duplicate_success: string;
19
20
  export let doc_deleted: string;
20
21
  export let doc_created: string;
21
22
  export let doc_updated: string;
@@ -17,6 +17,7 @@ export default {
17
17
  delete_dialog_text:
18
18
  "Vous êtes sur le point de supprimer $1, appuyez sur supprimer pour confirmer l'opération.",
19
19
  duplicate: 'Dupliquer',
20
+ duplicate_success: 'Dupliqué avec succès',
20
21
  doc_deleted: 'Document supprimé',
21
22
  doc_created: 'Document enregistré',
22
23
  doc_updated: 'Document mis à jour',
@@ -4,6 +4,7 @@
4
4
  import { Editor, type JSONContent } from '@tiptap/core';
5
5
  import { onMount } from 'svelte';
6
6
  import { buildEditorConfig } from '../core/build-editor-config.js';
7
+ import { defaultFeatures } from '../core/features/index.js';
7
8
  import type { RichTextFeature } from '../core/types';
8
9
  import { hasSuggestion } from '../util.js';
9
10
  import EditorBubbleMenu from './bubble-menu/bubble-menu.svelte';
@@ -26,11 +27,13 @@
26
27
  setRichTextContext(path);
27
28
  });
28
29
 
29
- const withSuggestion = $derived(hasSuggestion(config.features || []));
30
+ const withSuggestion = $derived(hasSuggestion(config.features || defaultFeatures));
30
31
 
31
32
  onMount(() => {
32
33
  // Build editor configuration
33
- const richTextEditorConfig = buildEditorConfig({ features: config.features });
34
+ const richTextEditorConfig = buildEditorConfig({
35
+ features: config.features || defaultFeatures
36
+ });
34
37
 
35
38
  features = richTextEditorConfig.features;
36
39
  editor = new Editor({
@@ -36,7 +36,7 @@
36
36
  /** All editor > node */
37
37
  .ProseMirror > *:not(.ProseMirror-gapcursor) {
38
38
  background-color: hsl(var(--rz-input-bg));
39
- padding: var(--rz-size-4) var(--rz-size-3) var(--rz-size-4);
39
+ padding: var(--rz-size-3) var(--rz-size-3);
40
40
  margin-left: var(--left-spacing);
41
41
  width: calc(100% - var(--left-spacing));
42
42
  min-height: var(--rz-size-11);
@@ -1,6 +1,6 @@
1
1
  import type { RichTextEditorConfig, RichTextFeature } from './types.js';
2
2
  type BuildEditorConfigArgs = {
3
- features?: Array<RichTextFeature>;
3
+ features: Array<RichTextFeature>;
4
4
  standAlone?: boolean;
5
5
  };
6
6
  /**
@@ -12,14 +12,12 @@ import { getLocaleContext, LOCALE_CTX } from '../../../panel/context/locale.svel
12
12
  import { getUserContext, USER_CTX } from '../../../panel/context/user.svelte.js';
13
13
  import { hasSuggestion } from '../util.js';
14
14
  import { CurrentNodeAttribute } from './extensions/current-node/current-node.js';
15
- import { defaultFeatures } from './features/index.js';
16
15
  import { ParagraphFeature } from './features/paragraph.js';
17
16
  /**
18
17
  * Builds a rich text editor configuration based on the provided features
19
18
  */
20
19
  export function buildEditorConfig(args) {
21
- const { features: incommingFeatures = [] } = args;
22
- const features = incommingFeatures.length === 0 ? defaultFeatures : incommingFeatures;
20
+ const { features } = args;
23
21
  const withSuggestion = hasSuggestion(features);
24
22
  // Add mandatory paragraph feature if not provided
25
23
  const hasParagraph = features
@@ -86,6 +86,6 @@
86
86
  }
87
87
 
88
88
  .rz-panel-root__right--navCollapsed {
89
- margin-left: var(--rz-size-20);
89
+ margin-left: var(--rz-size-14);
90
90
  }
91
91
  </style>
@@ -73,6 +73,7 @@
73
73
  }
74
74
 
75
75
  async function duplicate() {
76
+ form.reset();
76
77
  const url = `${apiUrl(form.config.kebab, form.values.id)}/duplicate`;
77
78
 
78
79
  const [error, success] = await trycatchFetch(url, {
@@ -1,5 +1,4 @@
1
1
  <script lang="ts">
2
- import { page } from '$app/state';
3
2
  import { getConfigContext } from '../../../context/config.svelte.js';
4
3
  import type { Route } from '../../../types';
5
4
  import { panelUrl } from '../../../util/url.js';
@@ -43,25 +42,23 @@
43
42
 
44
43
  <div class="rz-nav__body">
45
44
  <ScrollArea>
46
- {#key page.url}
47
- <nav class="rz-nav__nav">
48
- {#each Object.entries(routesGroups) as [groupName, routes], index (index)}
49
- {#if groupName !== 'none'}
50
- {@const icon = getGroupIcon(groupName)}
51
- <NavGroup name={groupName} {icon} navCollapsed={isCollapsed}>
52
- {#each routes as route (route.url)}
53
- <NavItem href={route.url} {isCollapsed} {route} />
54
- {/each}
55
- </NavGroup>
56
- {/if}
57
- {/each}
58
- {#each routesGroups.none as route (route.url)}
59
- <div class="rz-nav__group-none">
60
- <NavItem href={route.url} {isCollapsed} {route} />
61
- </div>
62
- {/each}
63
- </nav>
64
- {/key}
45
+ <nav class="rz-nav__nav">
46
+ {#each Object.entries(routesGroups) as [groupName, routes], index (index)}
47
+ {#if groupName !== 'none'}
48
+ {@const icon = getGroupIcon(groupName)}
49
+ <NavGroup name={groupName} {icon} navCollapsed={isCollapsed}>
50
+ {#each routes as route (route.url)}
51
+ <NavItem href={route.url} {isCollapsed} {route} />
52
+ {/each}
53
+ </NavGroup>
54
+ {/if}
55
+ {/each}
56
+ {#each routesGroups.none as route (route.url)}
57
+ <div class="rz-nav__group-none">
58
+ <NavItem href={route.url} {isCollapsed} {route} />
59
+ </div>
60
+ {/each}
61
+ </nav>
65
62
  </ScrollArea>
66
63
 
67
64
  <div class="rz-nav__user">
@@ -119,7 +116,7 @@
119
116
  }
120
117
  }
121
118
  .rz-nav--collapsed {
122
- width: var(--rz-size-20);
119
+ width: var(--rz-size-14);
123
120
  padding: var(--rz-size-3);
124
121
  :global(.rz-button-nav) {
125
122
  justify-content: start;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { ChevronDown, ChevronUp, type IconProps } from '@lucide/svelte';
2
+ import { ChevronUp, type IconProps } from '@lucide/svelte';
3
3
  import type { Component, Snippet } from 'svelte';
4
4
 
5
5
  type Props = {
@@ -35,18 +35,15 @@
35
35
  {/if}
36
36
  {name}
37
37
  </span>
38
- {#if groupCollapsed}
39
- <ChevronDown size="12" />
40
- {:else}
41
- <ChevronUp size="12" />
42
- {/if}
38
+ <ChevronUp class="rz-nav-group__chevron" size="12" />
43
39
  </button>
44
40
  {/if}
45
- {#if !groupCollapsed || navCollapsed}
46
- <div class="rz-nav-group__content">
41
+
42
+ <div class="rz-nav-group__content">
43
+ <div class="rz-nav-group__content-inner">
47
44
  {@render children()}
48
45
  </div>
49
- {/if}
46
+ </div>
50
47
  </div>
51
48
 
52
49
  <style global>
@@ -58,14 +55,27 @@
58
55
  margin-bottom: var(--rz-size-2);
59
56
  background-color: var(--rz-nav-button-bg);
60
57
  border-radius: var(--rz-radius-lg);
58
+
59
+ :global {
60
+ .rz-nav-group__chevron {
61
+ transition: transform 0.3s var(--ease-in-out-quart);
62
+ }
63
+ }
61
64
  }
62
65
 
63
66
  .rz-nav-group__content {
64
67
  display: grid;
68
+ grid-template-rows: 1fr;
65
69
  padding: 0 var(--rz-size-4);
66
70
  background-color: var(--rz-nav-group-bg);
67
71
  border-bottom-left-radius: var(--rz-radius-lg);
68
72
  border-bottom-right-radius: var(--rz-radius-lg);
73
+ transition: grid-template-rows 0.3s var(--ease-in-out-quart);
74
+ }
75
+
76
+ .rz-nav-group__content-inner {
77
+ overflow: hidden;
78
+ display: grid;
69
79
  }
70
80
 
71
81
  .rz-nav-group__trigger {
@@ -79,6 +89,7 @@
79
89
  justify-content: space-between;
80
90
  text-align: left;
81
91
  border-bottom: 1px solid var(--rz-nav-group-border-color);
92
+ transition: border-color 0.3s var(--ease-in-out-quart);
82
93
 
83
94
  span {
84
95
  display: flex;
@@ -87,17 +98,26 @@
87
98
  }
88
99
  }
89
100
 
90
- .rz-nav-group--collapsed {
101
+ .rz-nav-group.rz-nav-group--collapsed:not(.rz-nav-group--nav-collapsed) {
91
102
  .rz-nav-group__trigger {
92
103
  border-color: transparent;
93
104
  }
105
+
106
+ .rz-nav-group__content {
107
+ grid-template-rows: 0fr;
108
+ }
109
+ :global {
110
+ .rz-nav-group__chevron {
111
+ transform: rotate(180deg);
112
+ }
113
+ }
94
114
  }
95
115
 
96
116
  .rz-nav-group--nav-collapsed {
97
- /*padding-top: var(--rz-size-2);*/
117
+ background-color: transparent;
98
118
  .rz-nav-group__content {
99
119
  background-color: transparent;
100
- padding: 0 var(--rz-size-5);
120
+ padding: 0 var(--rz-size-2);
101
121
  }
102
122
  }
103
123
  </style>
@@ -19,7 +19,7 @@
19
19
  typeof route.icon === 'function' ? route.icon : config.raw.icons[route.icon] || File
20
20
  );
21
21
 
22
- let pathname = page.url.pathname;
22
+ let pathname = $derived(page.url.pathname);
23
23
 
24
24
  let active = $derived.by(() => {
25
25
  const routePathname = new URL(route.url).pathname;
@@ -25,8 +25,13 @@
25
25
  {@render children?.()}
26
26
  </a>
27
27
 
28
- <style>
29
- .rz-button-nav {
28
+ <style>/**************************************/
29
+
30
+ /* Font */
31
+
32
+ /**************************************/
33
+
34
+ .rz-button-nav {
30
35
  position: relative;
31
36
  display: inline-flex;
32
37
  align-items: center;
@@ -46,7 +51,7 @@
46
51
  }
47
52
  }
48
53
 
49
- .rz-button-nav--active {
54
+ .rz-button-nav--active {
50
55
  text-decoration: underline;
51
56
  position: relative;
52
57
  }
@@ -69,6 +69,7 @@ export declare function setDocumentFormContext<T extends WithOptional<GenericDoc
69
69
  none?: string | undefined;
70
70
  };
71
71
  readonly isLive: boolean;
72
+ reset(): void;
72
73
  setFocusedField(path: string): void;
73
74
  };
74
75
  export declare function getDocumentFormContext<T extends WithOptional<GenericDoc, 'id'> = WithOptional<GenericDoc, 'id'>>(key?: string): {
@@ -138,6 +139,7 @@ export declare function getDocumentFormContext<T extends WithOptional<GenericDoc
138
139
  none?: string | undefined;
139
140
  };
140
141
  readonly isLive: boolean;
142
+ reset(): void;
141
143
  setFocusedField(path: string): void;
142
144
  };
143
145
  export type DocumentFormContext<T extends WithOptional<GenericDoc, 'id'> = WithOptional<GenericDoc, 'id'>> = ReturnType<typeof setDocumentFormContext<T>>;
@@ -678,6 +678,9 @@ function createDocumentFormState({ initial, config, readOnly, key, onNestedDocum
678
678
  get isLive() {
679
679
  return isLiveEdit;
680
680
  },
681
+ reset() {
682
+ doc = initialDoc;
683
+ },
681
684
  setFocusedField(path) {
682
685
  if (isLiveEdit && onFieldFocus) {
683
686
  onFieldFocus(path);
@@ -1,4 +1,5 @@
1
1
  @import '@bienbien/css-reset';
2
+ @import '@bienbien/css-easing';
2
3
  @import './size.css';
3
4
  @import './font.css';
4
5
  @import './radius.css';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rimecms",
3
- "version": "0.27.3",
3
+ "version": "0.27.4",
4
4
  "homepage": "https://github.com/bienbiendev/rime",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -175,6 +175,7 @@
175
175
  "dependencies": {
176
176
  "@babel/generator": "^7.28.3",
177
177
  "@babel/types": "^7.28.4",
178
+ "@bienbien/css-easing": "^0.1.1",
178
179
  "@bienbien/css-reset": "^0.1.2",
179
180
  "@floating-ui/dom": "^1.7.4",
180
181
  "@internationalized/date": "^3.8.2",
@@ -1,12 +0,0 @@
1
- <span aria-hidden="true" class="button-nav__caret"></span>
2
-
3
- <style>
4
- .button-nav__caret {
5
- background-color: hsl(var(--rz-color-spot));
6
- position: absolute;
7
- left: calc(-1 * var(--rz-size-4));
8
- bottom: 0;
9
- top: 0;
10
- width: var(--rz-size-1);
11
- }
12
- </style>
@@ -1,26 +0,0 @@
1
- export default NavItemButtonCaret;
2
- type NavItemButtonCaret = SvelteComponent<{
3
- [x: string]: never;
4
- }, {
5
- [evt: string]: CustomEvent<any>;
6
- }, {}> & {
7
- $$bindings?: string | undefined;
8
- };
9
- declare const NavItemButtonCaret: $$__sveltets_2_IsomorphicComponent<{
10
- [x: string]: never;
11
- }, {
12
- [evt: string]: CustomEvent<any>;
13
- }, {}, {}, string>;
14
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
- new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
- $$bindings?: Bindings;
17
- } & Exports;
18
- (internal: unknown, props: {
19
- $$events?: Events;
20
- $$slots?: Slots;
21
- }): Exports & {
22
- $set?: any;
23
- $on?: any;
24
- };
25
- z_$$bindings?: Bindings;
26
- }