@widgetic/design-system 0.5.14 → 0.5.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/README.md +167 -0
- package/dist/components/CopyableHeader.svelte +25 -11
- package/dist/components/CopyableHeader.svelte.d.ts +4 -0
- package/dist/components/EmptyState.svelte +1 -1
- package/dist/components/PasswordInput.svelte +2 -2
- package/dist/components/WScrollArea.svelte +2 -2
- package/dist/components/ic/browser/BrowserInputController.svelte +2 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/components/modals/ActionModal.svelte +7 -2
- package/dist/components/modals/ActionModal.svelte.d.ts +2 -0
- package/dist/components/modals/BaseModal.svelte +4 -2
- package/dist/components/modals/BaseModal.svelte.d.ts +1 -0
- package/dist/components/modals/NewItemDialog.svelte +48 -30
- package/dist/components/modals/NewItemDialog.svelte.d.ts +3 -0
- package/dist/components/modals/Portal.svelte +9 -1
- package/dist/components/modals/README.md +34 -1
- package/dist/components/modals/RenameDialog.svelte +29 -9
- package/dist/components/modals/RenameDialog.svelte.d.ts +3 -0
- package/dist/components/modals/messages.d.ts +39 -0
- package/dist/components/modals/messages.js +10 -0
- package/dist/components/navigation/Breadcrumbs.svelte +55 -50
- package/dist/components/navigation/Breadcrumbs.svelte.d.ts +4 -0
- package/dist/components/navigation/types.d.ts +8 -0
- package/dist/components/pdf/PDFViewer.svelte +17 -8
- package/dist/components/pdf/PDFViewer.svelte.d.ts +5 -0
- package/dist/components/search-input/SearchInput.svelte +3 -3
- package/dist/components/shad-editor/colorpicker.svelte +4 -1
- package/dist/components/shad-editor/custom/Extentions/ImageExtention.d.ts +20 -1
- package/dist/components/shad-editor/custom/Extentions/ImageExtention.js +4 -1
- package/dist/components/shad-editor/custom/code-extended.svelte +4 -2
- package/dist/components/shad-editor/custom/image-extended-component.svelte +54 -32
- package/dist/components/shad-editor/editor.css +5 -5
- package/dist/components/shad-editor/i18n/context.d.ts +6 -0
- package/dist/components/shad-editor/i18n/context.js +11 -0
- package/dist/components/shad-editor/i18n/index.d.ts +8 -0
- package/dist/components/shad-editor/i18n/index.js +11 -0
- package/dist/components/shad-editor/i18n/messages.d.ts +109 -0
- package/dist/components/shad-editor/i18n/messages.js +116 -0
- package/dist/components/shad-editor/icons/block-quote.svelte +3 -1
- package/dist/components/shad-editor/icons/bold.svelte +3 -1
- package/dist/components/shad-editor/icons/buttle-list.svelte +3 -1
- package/dist/components/shad-editor/icons/code.svelte +3 -1
- package/dist/components/shad-editor/icons/highlighter.svelte +5 -3
- package/dist/components/shad-editor/icons/image.svelte +7 -5
- package/dist/components/shad-editor/icons/italic.svelte +3 -1
- package/dist/components/shad-editor/icons/link.svelte +8 -6
- package/dist/components/shad-editor/icons/ordered-list.svelte +3 -1
- package/dist/components/shad-editor/icons/quickcolor.svelte +24 -22
- package/dist/components/shad-editor/icons/redo.svelte +3 -1
- package/dist/components/shad-editor/icons/search-replace.svelte +16 -14
- package/dist/components/shad-editor/icons/strikethrough.svelte +3 -1
- package/dist/components/shad-editor/icons/subscript.svelte +3 -1
- package/dist/components/shad-editor/icons/superscript.svelte +3 -1
- package/dist/components/shad-editor/icons/table.svelte +21 -19
- package/dist/components/shad-editor/icons/task-list.svelte +3 -1
- package/dist/components/shad-editor/icons/text.svelte +13 -11
- package/dist/components/shad-editor/icons/textalign.svelte +11 -9
- package/dist/components/shad-editor/icons/textcolor.svelte +5 -3
- package/dist/components/shad-editor/icons/underline.svelte +3 -1
- package/dist/components/shad-editor/icons/undo.svelte +3 -1
- package/dist/components/shad-editor/index.d.ts +1 -0
- package/dist/components/shad-editor/index.js +2 -0
- package/dist/components/shad-editor/shad-editor.svelte +32 -3
- package/dist/components/shad-editor/shad-editor.svelte.d.ts +12 -0
- package/dist/components/textDirection.d.ts +91 -0
- package/dist/components/textDirection.js +99 -0
- package/dist/components/toast/ToasterModal.svelte +49 -14
- package/dist/components/toast/ToasterModal.svelte.d.ts +9 -2
- package/dist/components/toast/toasterRoots.d.ts +23 -0
- package/dist/components/toast/toasterRoots.js +36 -0
- package/dist/components/ui/alert/index.d.ts +2 -2
- package/dist/components/ui/alert/index.js +1 -1
- package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte +1 -1
- package/dist/components/ui/calendar/calendar-next-button.svelte +21 -4
- package/dist/components/ui/calendar/calendar-next-button.svelte.d.ts +9 -2
- package/dist/components/ui/calendar/calendar-prev-button.svelte +21 -4
- package/dist/components/ui/calendar/calendar-prev-button.svelte.d.ts +9 -2
- package/dist/components/ui/calendar/calendar.svelte +18 -6
- package/dist/components/ui/calendar/calendar.svelte.d.ts +6 -1
- package/dist/components/ui/command/command-input.svelte +1 -1
- package/dist/components/ui/command/command-shortcut.svelte +1 -1
- package/dist/components/ui/dialog/dialog-content.svelte +5 -2
- package/dist/components/ui/dialog/dialog-content.svelte.d.ts +1 -0
- package/dist/components/ui/dialog/dialog-header.svelte +1 -1
- package/dist/components/ui/drawer/drawer-header.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +2 -2
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +6 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +2 -2
- package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +1 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +7 -1
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +2 -2
- package/dist/components/ui/hover-card/hover-card-content.svelte +6 -0
- package/dist/components/ui/input-otp/input-otp-slot.svelte +1 -1
- package/dist/components/ui/popover/popover-content.svelte +6 -0
- package/dist/components/ui/progress/progress.svelte +2 -2
- package/dist/components/ui/range-calendar/range-calendar-cell.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-next-button.svelte +21 -4
- package/dist/components/ui/range-calendar/range-calendar-next-button.svelte.d.ts +9 -2
- package/dist/components/ui/range-calendar/range-calendar-prev-button.svelte +21 -4
- package/dist/components/ui/range-calendar/range-calendar-prev-button.svelte.d.ts +9 -2
- package/dist/components/ui/range-calendar/range-calendar.svelte +18 -6
- package/dist/components/ui/range-calendar/range-calendar.svelte.d.ts +7 -2
- package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +1 -1
- package/dist/components/ui/scroll-area/scroll-area.svelte +6 -1
- package/dist/components/ui/select/select-content.svelte +6 -0
- package/dist/components/ui/select/select-group-heading.svelte +1 -1
- package/dist/components/ui/select/select-item.svelte +2 -2
- package/dist/components/ui/slider/slider.svelte +6 -0
- package/dist/components/ui/switch/switch.svelte +1 -1
- package/dist/components/ui/table/table-cell.svelte +1 -1
- package/dist/components/ui/table/table-head.svelte +1 -1
- package/dist/components/ui/tooltip/tooltip-content.svelte +6 -0
- package/dist/i18n/audit/catalogUsage.d.ts +36 -0
- package/dist/i18n/audit/catalogUsage.js +58 -0
- package/dist/i18n/audit/designSystemWords.d.ts +47 -0
- package/dist/i18n/audit/designSystemWords.js +137 -0
- package/dist/i18n/audit/hardCodedText.d.ts +40 -0
- package/dist/i18n/audit/hardCodedText.js +27 -0
- package/dist/i18n/audit/index.d.ts +19 -0
- package/dist/i18n/audit/index.js +19 -0
- package/dist/i18n/audit/messageCalls.d.ts +34 -0
- package/dist/i18n/audit/messageCalls.js +89 -0
- package/dist/i18n/audit/syntaxTree.d.ts +33 -0
- package/dist/i18n/audit/syntaxTree.js +90 -0
- package/dist/i18n/audit/visibleText.d.ts +57 -0
- package/dist/i18n/audit/visibleText.js +252 -0
- package/dist/i18n/createI18n.d.ts +63 -0
- package/dist/i18n/createI18n.js +72 -0
- package/dist/i18n/direction.d.ts +27 -0
- package/dist/i18n/direction.js +89 -0
- package/dist/i18n/index.d.ts +17 -0
- package/dist/i18n/index.js +16 -0
- package/dist/i18n/localeDate.d.ts +34 -0
- package/dist/i18n/localeDate.js +104 -0
- package/dist/i18n/splitMessages.d.ts +21 -0
- package/dist/i18n/splitMessages.js +33 -0
- package/dist/i18n/translator.d.ts +61 -0
- package/dist/i18n/translator.js +337 -0
- package/dist/rtl/audit/auditPhysicalPlacement.d.ts +36 -0
- package/dist/rtl/audit/auditPhysicalPlacement.js +58 -0
- package/dist/rtl/audit/index.d.ts +14 -0
- package/dist/rtl/audit/index.js +14 -0
- package/dist/rtl/audit/physicalPlacement.d.ts +64 -0
- package/dist/rtl/audit/physicalPlacement.js +444 -0
- package/dist/shad-editor/index.d.ts +1 -1
- package/dist/shad-editor/index.js +1 -1
- package/dist/styles/global.css +4 -4
- package/dist/utils/fillMessage.d.ts +8 -0
- package/dist/utils/fillMessage.js +10 -0
- package/dist/utils/itemName.d.ts +17 -0
- package/dist/utils/itemName.js +41 -0
- package/package.json +19 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<!-- Portal component for mounting elements outside their normal DOM hierarchy -->
|
|
2
2
|
<script lang="ts">
|
|
3
3
|
import { onMount, onDestroy } from 'svelte';
|
|
4
|
+
import { readable, type Readable } from 'svelte/store';
|
|
5
|
+
import { useOptionalTextDirection, type TextDirection } from '../textDirection.js';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Component props
|
|
@@ -26,6 +28,11 @@
|
|
|
26
28
|
// show logs
|
|
27
29
|
let showLogs = false;
|
|
28
30
|
|
|
31
|
+
// The content leaves the element that carries the direction of its screen, and a pop-up in a layer of the page would read
|
|
32
|
+
// the direction of the page instead. When a screen above gave one, the portal says it again on its own element (and says
|
|
33
|
+
// nothing on a page whose screens never did, so the page's own `dir` stays).
|
|
34
|
+
const screenDirection: Readable<TextDirection | undefined> = useOptionalTextDirection() ?? readable<TextDirection | undefined>(undefined);
|
|
35
|
+
|
|
29
36
|
onMount(() => {
|
|
30
37
|
// if(showLogs) console.log('DS Portal target:', target);
|
|
31
38
|
// If target is an HTML element, use it directly
|
|
@@ -85,6 +92,7 @@
|
|
|
85
92
|
<!-- Portal Container -->
|
|
86
93
|
<div bind:this={portal}
|
|
87
94
|
class="{className ? `${className} ` : ''}portal-contents{clickThrough ? ' click-through' : ''}"
|
|
95
|
+
dir={$screenDirection}
|
|
88
96
|
style={style}
|
|
89
97
|
bind:clientWidth
|
|
90
98
|
bind:clientHeight
|
|
@@ -97,7 +105,7 @@
|
|
|
97
105
|
.portal-contents {
|
|
98
106
|
position: absolute;
|
|
99
107
|
top: 0;
|
|
100
|
-
|
|
108
|
+
inset-inline-start: 0;
|
|
101
109
|
width: 100%;
|
|
102
110
|
height: 100%;
|
|
103
111
|
z-index: 99999999;
|
|
@@ -22,6 +22,7 @@ The `ActionModal` component is a reusable confirmation modal that can be used ac
|
|
|
22
22
|
| `message` | string | `''` | Custom message for the modal (autogenerated if empty) |
|
|
23
23
|
| `confirmLabel` | string | `'Confirm'` | Label for the confirm button |
|
|
24
24
|
| `cancelLabel` | string | `'Cancel'` | Label for the cancel button |
|
|
25
|
+
| `closeLabel` | string | `'Close modal'` | The words a screen reader says for the close button |
|
|
25
26
|
| `width` | string | `'410px'` | Width of the modal |
|
|
26
27
|
| `height` | string | `'168px'` | Height of the modal |
|
|
27
28
|
| `modalId` | string | `'delete-confirmation-modal'` | ID for targeting the modal |
|
|
@@ -96,4 +97,36 @@ You can provide custom title and message for specific contexts:
|
|
|
96
97
|
confirmLabel="Delete Permanently"
|
|
97
98
|
on:confirm={handleDelete}
|
|
98
99
|
/>
|
|
99
|
-
```
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Words in another language
|
|
103
|
+
|
|
104
|
+
Every word a visitor can see or hear is a prop with an English default, so a page that shows the components in
|
|
105
|
+
another language passes its own words and nothing else changes.
|
|
106
|
+
|
|
107
|
+
| Component | Props with words |
|
|
108
|
+
|-----------|------------------|
|
|
109
|
+
| `BaseModal`, `ActionModal`, `RenameDialog`, `NewItemDialog` | `closeLabel` (screen reader name of the close button) |
|
|
110
|
+
| `ActionModal`, `RenameDialog`, `NewItemDialog` | `confirmLabel`, `cancelLabel` |
|
|
111
|
+
| `RenameDialog` | `messages`: `invalidTitle`, `enterName`, `enterDifferentName`, `enterValidName`, `tooShort`, `tooLong` (`{max}`), `renamed` (`{name}`), `failed` |
|
|
112
|
+
| `NewItemDialog` | `messages`: `invalidTitle`, `required`, `invalidCharacters`, `tooLong` (`{max}`). The English defaults are built from `itemType` ("Folder name is required"). |
|
|
113
|
+
| `Breadcrumbs` | `backLabel`, `forwardLabel`, `rootLabel`, `breadcrumbLabel` |
|
|
114
|
+
| `PDFViewer` | `loadingLabel`, `failedLabel`, `pageLabel` (`{page}`, `{total}`), `previousPageLabel`, `nextPageLabel` |
|
|
115
|
+
| `ToasterModal` (`components/toast`) | `containerAriaLabel` (the region that holds the toasts, "Notifications"; the library adds the key that moves focus to it), `closeButtonAriaLabel` ("Close toast"). The title and description of a toast are the words of whoever calls `showToast`. |
|
|
116
|
+
|
|
117
|
+
A key of `messages` that is left out keeps its English text. A message can hold the values named next to it in
|
|
118
|
+
curly braces: `tooLong: 'Der Name darf höchstens {max} Zeichen haben'`.
|
|
119
|
+
|
|
120
|
+
```svelte
|
|
121
|
+
<RenameDialog
|
|
122
|
+
bind:isOpen
|
|
123
|
+
itemName="Reisefotos"
|
|
124
|
+
confirmLabel="Umbenennen"
|
|
125
|
+
cancelLabel="Abbrechen"
|
|
126
|
+
closeLabel="Dialog schließen"
|
|
127
|
+
messages={{ enterName: 'Bitte einen Namen eingeben', tooLong: 'Höchstens {max} Zeichen' }}
|
|
128
|
+
/>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`NewItemDialog` accepts names made of letters, numbers and spaces **of any script** ("Ordner für Müller",
|
|
132
|
+
"写真", "Фото 2024"). Punctuation and symbols are still refused.
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
// import { toast } from '../ui/sonner';
|
|
8
8
|
import { showToast } from '../toast';
|
|
9
9
|
import BaseModal from './BaseModal.svelte';
|
|
10
|
+
// Words of the dialog and the helper that puts values into them
|
|
11
|
+
import type { RenameDialogMessages } from './messages';
|
|
12
|
+
import { fillMessage } from '../../utils/fillMessage';
|
|
10
13
|
|
|
11
14
|
// Props
|
|
12
15
|
let className = '';
|
|
@@ -21,6 +24,10 @@
|
|
|
21
24
|
export let placeholder = '';
|
|
22
25
|
export let confirmLabel = 'Rename';
|
|
23
26
|
export let cancelLabel = 'Cancel';
|
|
27
|
+
// The words a screen reader says for the close button (see BaseModal)
|
|
28
|
+
export let closeLabel = 'Close modal';
|
|
29
|
+
// The words of the errors and toasts; a key that is left out keeps its English text (see ./messages)
|
|
30
|
+
export let messages: Partial<RenameDialogMessages> = {};
|
|
24
31
|
export let width = '410px';
|
|
25
32
|
export let height = '168px';
|
|
26
33
|
export let target: string = 'rename-dialog'; // target for Portal
|
|
@@ -59,6 +66,18 @@
|
|
|
59
66
|
// Computed placeholder based on itemType
|
|
60
67
|
$: computedPlaceholder = placeholder || `${itemType} name...`;
|
|
61
68
|
|
|
69
|
+
// The words of the errors and toasts: the page's own, or English
|
|
70
|
+
$: text = {
|
|
71
|
+
invalidTitle: messages.invalidTitle ?? 'Invalid name',
|
|
72
|
+
enterName: messages.enterName ?? 'Please enter a name',
|
|
73
|
+
enterDifferentName: messages.enterDifferentName ?? 'Please enter a different name',
|
|
74
|
+
enterValidName: messages.enterValidName ?? 'Please enter a valid name',
|
|
75
|
+
tooShort: messages.tooShort ?? 'Name must be at least 1 character long',
|
|
76
|
+
tooLong: fillMessage(messages.tooLong ?? 'Name must be {max} characters or less', { max: maxLength }),
|
|
77
|
+
renamed: messages.renamed ?? 'Successfully renamed to {name}',
|
|
78
|
+
failed: messages.failed ?? 'Failed to rename item'
|
|
79
|
+
};
|
|
80
|
+
|
|
62
81
|
// Function to focus and select the input text
|
|
63
82
|
async function focusAndSelectInput() {
|
|
64
83
|
// Wait for the DOM to update
|
|
@@ -95,17 +114,17 @@
|
|
|
95
114
|
try {
|
|
96
115
|
// Validate input
|
|
97
116
|
if (!inputValue.trim() || inputValue.length < 1) {
|
|
98
|
-
showToast('error',
|
|
117
|
+
showToast('error', text.invalidTitle, { description: text.tooShort });
|
|
99
118
|
return;
|
|
100
119
|
}
|
|
101
120
|
|
|
102
121
|
if (inputValue.length > maxLength) {
|
|
103
|
-
showToast('error',
|
|
122
|
+
showToast('error', text.invalidTitle, { description: text.tooLong });
|
|
104
123
|
return;
|
|
105
124
|
}
|
|
106
125
|
|
|
107
126
|
if (inputValue === itemName) {
|
|
108
|
-
showToast('error',
|
|
127
|
+
showToast('error', text.invalidTitle, { description: text.enterDifferentName });
|
|
109
128
|
return;
|
|
110
129
|
}
|
|
111
130
|
|
|
@@ -124,17 +143,17 @@
|
|
|
124
143
|
// with a more generic approach
|
|
125
144
|
try {
|
|
126
145
|
// Simulate success
|
|
127
|
-
showToast('success',
|
|
146
|
+
showToast('success', fillMessage(text.renamed, { name: inputValue }));
|
|
128
147
|
dispatch('rename', { itemId, newName: inputValue, oldName: itemName });
|
|
129
148
|
isOpen = false;
|
|
130
149
|
} catch (error) {
|
|
131
150
|
console.error('Error during rename:', error);
|
|
132
|
-
showToast('error',
|
|
151
|
+
showToast('error', text.failed);
|
|
133
152
|
}
|
|
134
153
|
}
|
|
135
154
|
} catch (error) {
|
|
136
155
|
console.error('Error during rename:', error);
|
|
137
|
-
showToast('error',
|
|
156
|
+
showToast('error', text.failed);
|
|
138
157
|
}
|
|
139
158
|
}
|
|
140
159
|
|
|
@@ -172,6 +191,7 @@
|
|
|
172
191
|
width={width}
|
|
173
192
|
height={height}
|
|
174
193
|
titlePadding="small"
|
|
194
|
+
{closeLabel}
|
|
175
195
|
{modalType}
|
|
176
196
|
{modalData}
|
|
177
197
|
on:restore={handleRestore}
|
|
@@ -224,9 +244,9 @@
|
|
|
224
244
|
/>
|
|
225
245
|
{#if !isValid && hasAttemptedSubmit}
|
|
226
246
|
<div class="text-xs text-[hsl(var(--error))] mt-1">
|
|
227
|
-
{inputValue.trim().length === 0 ?
|
|
228
|
-
inputValue === itemName ?
|
|
229
|
-
|
|
247
|
+
{inputValue.trim().length === 0 ? text.enterName :
|
|
248
|
+
inputValue === itemName ? text.enterDifferentName :
|
|
249
|
+
text.enterValidName}
|
|
230
250
|
</div>
|
|
231
251
|
{/if}
|
|
232
252
|
</div>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RenameDialogMessages } from './messages';
|
|
1
2
|
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> {
|
|
2
3
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
4
|
$$bindings?: Bindings;
|
|
@@ -22,6 +23,8 @@ declare const RenameDialog: $$__sveltets_2_IsomorphicComponent<{
|
|
|
22
23
|
placeholder?: string;
|
|
23
24
|
confirmLabel?: string;
|
|
24
25
|
cancelLabel?: string;
|
|
26
|
+
closeLabel?: string;
|
|
27
|
+
messages?: Partial<RenameDialogMessages>;
|
|
25
28
|
width?: string;
|
|
26
29
|
height?: string;
|
|
27
30
|
target?: string;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words the dialogs say besides their title, placeholder and button labels.
|
|
3
|
+
*
|
|
4
|
+
* Every key is optional: a key that is left out keeps its English text. A message can hold named values in curly
|
|
5
|
+
* braces, for example `Name must be {max} characters or less`; the dialog says which ones it fills in (see
|
|
6
|
+
* `fillMessage` in utils).
|
|
7
|
+
* A page that shows the dialogs in another language passes its own words, for example
|
|
8
|
+
* `<RenameDialog messages={{ enterName: 'Bitte einen Namen eingeben' }} />`.
|
|
9
|
+
*/
|
|
10
|
+
/** Words of RenameDialog. */
|
|
11
|
+
export interface RenameDialogMessages {
|
|
12
|
+
/** Heading of the toast shown for a name that cannot be used. */
|
|
13
|
+
invalidTitle: string;
|
|
14
|
+
/** Under the field when it is empty. */
|
|
15
|
+
enterName: string;
|
|
16
|
+
/** Under the field and in the toast when the name has not changed. */
|
|
17
|
+
enterDifferentName: string;
|
|
18
|
+
/** Under the field when the name cannot be used for another reason. */
|
|
19
|
+
enterValidName: string;
|
|
20
|
+
/** Toast text for an empty name. */
|
|
21
|
+
tooShort: string;
|
|
22
|
+
/** Toast text for a name that is too long. Values: `{max}`, the longest name allowed. */
|
|
23
|
+
tooLong: string;
|
|
24
|
+
/** Toast when the dialog did the rename itself. Values: `{name}`, the new name. */
|
|
25
|
+
renamed: string;
|
|
26
|
+
/** Toast when the dialog did the rename itself and it failed. */
|
|
27
|
+
failed: string;
|
|
28
|
+
}
|
|
29
|
+
/** Words of NewItemDialog. The English defaults are built from the dialog's `itemType` ("Folder name is required"). */
|
|
30
|
+
export interface NewItemDialogMessages {
|
|
31
|
+
/** Heading of the toast shown for a name that cannot be used. */
|
|
32
|
+
invalidTitle: string;
|
|
33
|
+
/** Under the field when it is empty. */
|
|
34
|
+
required: string;
|
|
35
|
+
/** Under the field when the name has a character the dialog does not accept. */
|
|
36
|
+
invalidCharacters: string;
|
|
37
|
+
/** Under the field and in the toast when the name is too long. Values: `{max}`, the longest name allowed. */
|
|
38
|
+
tooLong: string;
|
|
39
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words the dialogs say besides their title, placeholder and button labels.
|
|
3
|
+
*
|
|
4
|
+
* Every key is optional: a key that is left out keeps its English text. A message can hold named values in curly
|
|
5
|
+
* braces, for example `Name must be {max} characters or less`; the dialog says which ones it fills in (see
|
|
6
|
+
* `fillMessage` in utils).
|
|
7
|
+
* A page that shows the dialogs in another language passes its own words, for example
|
|
8
|
+
* `<RenameDialog messages={{ enterName: 'Bitte einen Namen eingeben' }} />`.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
import { IconArrowLeft, IconArrowRight } from '@tabler/icons-svelte';
|
|
13
13
|
|
|
14
14
|
// Types Import
|
|
15
|
-
import type { BreadcrumbsProps } from './types.
|
|
15
|
+
import type { BreadcrumbsProps } from './types.js';
|
|
16
|
+
import { dirForUserText, useTextDirection } from '../textDirection.js';
|
|
16
17
|
|
|
17
18
|
// Environment Import
|
|
18
19
|
// import { browser } from '$app/environment';
|
|
@@ -36,6 +37,11 @@
|
|
|
36
37
|
export let showNavigationButtons: BreadcrumbsProps['showNavigationButtons'] = true;
|
|
37
38
|
export let canGoBack: BreadcrumbsProps['canGoBack'] = false;
|
|
38
39
|
export let canGoForward: BreadcrumbsProps['canGoForward'] = false;
|
|
40
|
+
// words (tooltips and screen readers): a page that shows this in another language passes its own
|
|
41
|
+
export let backLabel: string = 'Back';
|
|
42
|
+
export let forwardLabel: string = 'Forward';
|
|
43
|
+
export let rootLabel: string = 'File browser';
|
|
44
|
+
export let breadcrumbLabel: string = 'breadcrumb';
|
|
39
45
|
// event handlers
|
|
40
46
|
export let onNavigate: BreadcrumbsProps['onNavigate'] = () => {};
|
|
41
47
|
export let onBack: BreadcrumbsProps['onBack'] = () => {};
|
|
@@ -43,6 +49,11 @@
|
|
|
43
49
|
// debug settings
|
|
44
50
|
export let showDebugVisualizer: boolean = false;
|
|
45
51
|
|
|
52
|
+
// A name a visitor wrote keeps a direction of its own on a right to left screen (a Latin folder name reads left to
|
|
53
|
+
// right inside it); on a left to right screen no attribute is written and nothing changes.
|
|
54
|
+
const textDirection = useTextDirection();
|
|
55
|
+
$: nameDirection = dirForUserText($textDirection);
|
|
56
|
+
|
|
46
57
|
/***
|
|
47
58
|
* COMPONENT STATE VARIABLES
|
|
48
59
|
**/
|
|
@@ -99,7 +110,7 @@
|
|
|
99
110
|
navButtons: showNavigationButtons
|
|
100
111
|
? navElement.querySelector('.nav-buttons')?.getBoundingClientRect()
|
|
101
112
|
: null,
|
|
102
|
-
rightContent: containerElement.querySelector('.pr-5, .right-content')?.getBoundingClientRect(),
|
|
113
|
+
rightContent: containerElement.querySelector('.pe-5, .pr-5, .right-content')?.getBoundingClientRect(),
|
|
103
114
|
breadcrumbs: breadcrumbsContainer.getBoundingClientRect()
|
|
104
115
|
};
|
|
105
116
|
|
|
@@ -179,7 +190,7 @@
|
|
|
179
190
|
<nav
|
|
180
191
|
bind:this={navElement}
|
|
181
192
|
bind:clientHeight
|
|
182
|
-
aria-label=
|
|
193
|
+
aria-label={breadcrumbLabel}
|
|
183
194
|
class="{className ? className + ' ' : ''}breadcrumbs-component flex items-center widgetic-colors h-[56px] bg-white border-b relative w-full"
|
|
184
195
|
style={style}
|
|
185
196
|
>
|
|
@@ -188,58 +199,52 @@
|
|
|
188
199
|
<Tooltip.Provider delayDuration={300}>
|
|
189
200
|
<div class="nav-buttons flex items-center shrink-0">
|
|
190
201
|
<Tooltip.Root open={showBackTooltip}>
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
/>
|
|
207
|
-
</div>
|
|
208
|
-
</Tooltip.Trigger>
|
|
202
|
+
<button
|
|
203
|
+
type="button"
|
|
204
|
+
class="breadcrumbs-nav-button inline-flex items-center justify-center w-6 h-6 border-0 bg-transparent p-0 focus:outline-none"
|
|
205
|
+
style="cursor: {canGoBack && !isLoading ? 'pointer' : 'default'}; opacity: {canGoBack && !isLoading ? 1 : 0.35};"
|
|
206
|
+
aria-label={backLabel}
|
|
207
|
+
aria-disabled={!canGoBack || isLoading}
|
|
208
|
+
on:mouseenter={() => { showBackTooltip = true; }}
|
|
209
|
+
on:mouseleave={() => { showBackTooltip = false; }}
|
|
210
|
+
on:click={() => { if (!isLoading) onBack(); }}
|
|
211
|
+
>
|
|
212
|
+
<IconArrowLeft
|
|
213
|
+
class="w-6 h-6 text-[hsl(var(--grey6))] rtl:-scale-x-100"
|
|
214
|
+
style="min-width: 24px; min-height: 24px;"
|
|
215
|
+
/>
|
|
216
|
+
</button>
|
|
209
217
|
{#if showBackTooltip}
|
|
210
218
|
<!-- Portaled to <body>: the header row around this nav is overflow-hidden, which
|
|
211
219
|
otherwise clips the tooltip at the header's bottom edge. -->
|
|
212
220
|
<Tooltip.Portal>
|
|
213
221
|
<Tooltip.Content side="bottom" sideOffset={6} class="bg-[hsl(var(--dark))] text-white caption px-2 py-1 rounded-md z-[200000]">
|
|
214
|
-
|
|
222
|
+
{backLabel}
|
|
215
223
|
</Tooltip.Content>
|
|
216
224
|
</Tooltip.Portal>
|
|
217
225
|
{/if}
|
|
218
226
|
</Tooltip.Root>
|
|
219
227
|
|
|
220
228
|
<Tooltip.Root open={showForwardTooltip}>
|
|
221
|
-
<
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
/>
|
|
237
|
-
</div>
|
|
238
|
-
</Tooltip.Trigger>
|
|
229
|
+
<button
|
|
230
|
+
type="button"
|
|
231
|
+
class="breadcrumbs-nav-button ms-4 inline-flex items-center justify-center w-6 h-6 border-0 bg-transparent p-0 focus:outline-none"
|
|
232
|
+
style="cursor: {canGoForward && !isLoading ? 'pointer' : 'default'}; opacity: {canGoForward && !isLoading ? 1 : 0.35};"
|
|
233
|
+
aria-label={forwardLabel}
|
|
234
|
+
aria-disabled={!canGoForward || isLoading}
|
|
235
|
+
on:mouseenter={() => { showForwardTooltip = true; }}
|
|
236
|
+
on:mouseleave={() => { showForwardTooltip = false; }}
|
|
237
|
+
on:click={() => { if (!isLoading) onForward(); }}
|
|
238
|
+
>
|
|
239
|
+
<IconArrowRight
|
|
240
|
+
class="w-6 h-6 text-[hsl(var(--grey6))] rtl:-scale-x-100"
|
|
241
|
+
style="min-width: 24px; min-height: 24px;"
|
|
242
|
+
/>
|
|
243
|
+
</button>
|
|
239
244
|
{#if showForwardTooltip}
|
|
240
245
|
<Tooltip.Portal>
|
|
241
246
|
<Tooltip.Content side="bottom" sideOffset={6} class="bg-[hsl(var(--dark))] text-white caption px-2 py-1 rounded-md z-[200000]">
|
|
242
|
-
|
|
247
|
+
{forwardLabel}
|
|
243
248
|
</Tooltip.Content>
|
|
244
249
|
</Tooltip.Portal>
|
|
245
250
|
{/if}
|
|
@@ -249,8 +254,8 @@
|
|
|
249
254
|
{/if}
|
|
250
255
|
|
|
251
256
|
<!-- BREADCRUMBS CONTAINER -->
|
|
252
|
-
<div bind:this={breadcrumbsContainer} class="flex-1
|
|
253
|
-
<Breadcrumb.Root>
|
|
257
|
+
<div bind:this={breadcrumbsContainer} class="flex-1 ps-[18px] overflow-hidden min-w-0">
|
|
258
|
+
<Breadcrumb.Root aria-label={breadcrumbLabel}>
|
|
254
259
|
<Breadcrumb.List class="inline-flex items-center min-w-0 breadcrumbs-list">
|
|
255
260
|
<div class="inline-flex items-center min-w-0 min-h-[24px]">
|
|
256
261
|
<!-- Root Breadcrumb Item -->
|
|
@@ -265,7 +270,7 @@
|
|
|
265
270
|
on:click={(e) => handleClick(e, -1)}
|
|
266
271
|
on:keydown={(e) => handleKeyDown(e, -1)}
|
|
267
272
|
>
|
|
268
|
-
|
|
273
|
+
{rootLabel}
|
|
269
274
|
</span>
|
|
270
275
|
</Breadcrumb.Item>
|
|
271
276
|
|
|
@@ -285,7 +290,7 @@
|
|
|
285
290
|
{#each currentPath.slice(0, -itemsToShow + 1) as _, index}
|
|
286
291
|
<DropdownMenu.Item>
|
|
287
292
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
288
|
-
<span
|
|
293
|
+
<span dir={nameDirection}
|
|
289
294
|
role="link"
|
|
290
295
|
tabindex="0"
|
|
291
296
|
class="block w-full cursor-pointer"
|
|
@@ -304,12 +309,12 @@
|
|
|
304
309
|
<Breadcrumb.Separator class="h5 text-[hsl(var(--grey6))] shrink-0">/</Breadcrumb.Separator>
|
|
305
310
|
<Breadcrumb.Item class="shrink-0">
|
|
306
311
|
{#if index === itemsToShow - 2}
|
|
307
|
-
<span class="h5 text-[hsl(var(--grey3))]">
|
|
312
|
+
<span dir={nameDirection} class="h5 text-[hsl(var(--grey3))]">
|
|
308
313
|
{currentPathNames[currentPath.length - 1]}
|
|
309
314
|
</span>
|
|
310
315
|
{:else}
|
|
311
316
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
312
|
-
<span
|
|
317
|
+
<span dir={nameDirection}
|
|
313
318
|
role="link"
|
|
314
319
|
tabindex="0"
|
|
315
320
|
class="h5 text-[hsl(var(--grey6))] transition-colors hover:text-[hsl(var(--grey7))] hover:underline hover:decoration-[hsl(var(--grey7))] cursor-pointer"
|
|
@@ -328,12 +333,12 @@
|
|
|
328
333
|
<Breadcrumb.Separator class="h5 text-[hsl(var(--grey6))] shrink-0">/</Breadcrumb.Separator>
|
|
329
334
|
<Breadcrumb.Item class="shrink-0">
|
|
330
335
|
{#if index === currentPath.length - 1}
|
|
331
|
-
<span class="h5 text-[hsl(var(--grey3))]">
|
|
336
|
+
<span dir={nameDirection} class="h5 text-[hsl(var(--grey3))]">
|
|
332
337
|
{currentPathNames[index]}
|
|
333
338
|
</span>
|
|
334
339
|
{:else}
|
|
335
340
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
336
|
-
<span
|
|
341
|
+
<span dir={nameDirection}
|
|
337
342
|
role="link"
|
|
338
343
|
tabindex="0"
|
|
339
344
|
class="h5 text-[hsl(var(--grey6))] transition-colors hover:text-[hsl(var(--grey7))] hover:underline hover:decoration-[hsl(var(--grey7))] cursor-pointer"
|
|
@@ -355,7 +360,7 @@
|
|
|
355
360
|
</div>
|
|
356
361
|
|
|
357
362
|
{#if showDebugVisualizer}
|
|
358
|
-
<div class="absolute bottom-1
|
|
363
|
+
<div class="absolute bottom-1 end-1 text-xs text-blue-600 bg-white px-1 rounded shadow-2xs">
|
|
359
364
|
Available width: {Math.round(availableWidth)}px
|
|
360
365
|
<br>
|
|
361
366
|
Items to show: {itemsToShow}
|
|
@@ -24,6 +24,10 @@ declare const Breadcrumbs: $$__sveltets_2_IsomorphicComponent<{
|
|
|
24
24
|
showNavigationButtons?: BreadcrumbsProps["showNavigationButtons"];
|
|
25
25
|
canGoBack?: BreadcrumbsProps["canGoBack"];
|
|
26
26
|
canGoForward?: BreadcrumbsProps["canGoForward"];
|
|
27
|
+
backLabel?: string;
|
|
28
|
+
forwardLabel?: string;
|
|
29
|
+
rootLabel?: string;
|
|
30
|
+
breadcrumbLabel?: string;
|
|
27
31
|
onNavigate?: BreadcrumbsProps["onNavigate"];
|
|
28
32
|
onBack?: BreadcrumbsProps["onBack"];
|
|
29
33
|
onForward?: BreadcrumbsProps["onForward"];
|
|
@@ -9,4 +9,12 @@ export interface BreadcrumbsProps {
|
|
|
9
9
|
onForward: () => void;
|
|
10
10
|
showNavigationButtons?: boolean;
|
|
11
11
|
showDebugVisualizer?: boolean;
|
|
12
|
+
/** Tooltip and screen reader name of the back button. Default: "Back". */
|
|
13
|
+
backLabel?: string;
|
|
14
|
+
/** Tooltip and screen reader name of the forward button. Default: "Forward". */
|
|
15
|
+
forwardLabel?: string;
|
|
16
|
+
/** Name of the first item of the path. Default: "File browser". */
|
|
17
|
+
rootLabel?: string;
|
|
18
|
+
/** Screen reader name of the navigation. Default: "breadcrumb". */
|
|
19
|
+
breadcrumbLabel?: string;
|
|
12
20
|
}
|
|
@@ -43,6 +43,9 @@
|
|
|
43
43
|
|
|
44
44
|
// Import PDF cache store
|
|
45
45
|
import { pdfCache } from '../../stores/pdfCache';
|
|
46
|
+
|
|
47
|
+
// Puts the page numbers into the words of the page counter
|
|
48
|
+
import { fillMessage } from '../../utils/fillMessage';
|
|
46
49
|
|
|
47
50
|
// Component props
|
|
48
51
|
// class and style props
|
|
@@ -52,6 +55,12 @@
|
|
|
52
55
|
// data props
|
|
53
56
|
export let url = '';
|
|
54
57
|
export let enableCacheClearing: boolean = true; // Flag to enable/disable cache clearing shortcut
|
|
58
|
+
// words: a page that shows the viewer in another language passes its own
|
|
59
|
+
export let loadingLabel: string = 'Loading PDF...';
|
|
60
|
+
export let failedLabel: string = 'Failed to load PDF';
|
|
61
|
+
export let pageLabel: string = 'Page {page} of {total}'; // {total} is "?" until the page count is known
|
|
62
|
+
export let previousPageLabel: string = 'Previous page';
|
|
63
|
+
export let nextPageLabel: string = 'Next page';
|
|
55
64
|
|
|
56
65
|
// Consts
|
|
57
66
|
const initialContainerWidth = 500; // Default width during loading
|
|
@@ -531,11 +540,11 @@
|
|
|
531
540
|
<!-- Always render loading or error state on top of content -->
|
|
532
541
|
{#if !mounted || loading || (!isCanvasReady && !error)}
|
|
533
542
|
<div class="text-[hsl(var(--grey5))] p-6 absolute z-10 widgetic-colors flex items-center justify-center inset-0">
|
|
534
|
-
|
|
543
|
+
{loadingLabel}
|
|
535
544
|
</div>
|
|
536
545
|
{:else if error}
|
|
537
546
|
<div class="pdf-error-overlay bg-[hsl(var(--grey1))] text-[hsl(var(--grey2))] inset-4 px-4 absolute z-10 flex flex-col items-center justify-center">
|
|
538
|
-
<p class="text-[hsl(var(--error))] mb-2">
|
|
547
|
+
<p class="text-[hsl(var(--error))] mb-2">{failedLabel}</p>
|
|
539
548
|
<p class="text-[hsl(var(--grey5))] text-sm">{error}</p>
|
|
540
549
|
</div>
|
|
541
550
|
{/if}
|
|
@@ -546,18 +555,18 @@
|
|
|
546
555
|
<!-- Page Navigation Bar -->
|
|
547
556
|
<div class="page-navigation-bar flex items-center justify-center h-[54px] widgetic-colors border-b border-[hsl(var(--grey2))] w-full">
|
|
548
557
|
<div class="flex items-center gap-3 w-full max-w-[200px] justify-between px-0">
|
|
549
|
-
<button class="pdf-nav-button h-9 w-9 flex items-center justify-center rounded-small bg-white border-[hsl(var(--grey2))] transition-colors group disabled:cursor-not-allowed" on:click={onPrevPage} disabled={pageNum <= 1}>
|
|
558
|
+
<button class="pdf-nav-button h-9 w-9 flex items-center justify-center rounded-small bg-white border-[hsl(var(--grey2))] transition-colors group disabled:cursor-not-allowed" on:click={onPrevPage} disabled={pageNum <= 1} aria-label={previousPageLabel}>
|
|
550
559
|
<IconChevronLeft
|
|
551
|
-
class="!text-[hsl(var(--grey5))] group-hover:!text-[hsl(var(--grey7))]"
|
|
560
|
+
class="!text-[hsl(var(--grey5))] group-hover:!text-[hsl(var(--grey7))] rtl:-scale-x-100"
|
|
552
561
|
style="height: 20px !important; min-width: 20px !important; max-width: 20px !important; max-height: 20px !important;"
|
|
553
562
|
/>
|
|
554
563
|
</button>
|
|
555
564
|
|
|
556
|
-
<span class="subtext text-[hsl(var(--grey7))]">
|
|
565
|
+
<span class="subtext text-[hsl(var(--grey7))]">{fillMessage(pageLabel, { page: pageNum, total: pageCount || '?' })}</span>
|
|
557
566
|
|
|
558
|
-
<button class="pdf-nav-button h-9 w-9 flex items-center justify-center rounded-small bg-white border-[hsl(var(--grey2))] transition-colors group disabled:cursor-not-allowed" on:click={onNextPage} disabled={pageNum >= pageCount}>
|
|
567
|
+
<button class="pdf-nav-button h-9 w-9 flex items-center justify-center rounded-small bg-white border-[hsl(var(--grey2))] transition-colors group disabled:cursor-not-allowed" on:click={onNextPage} disabled={pageNum >= pageCount} aria-label={nextPageLabel}>
|
|
559
568
|
<IconChevronRight
|
|
560
|
-
class="!text-[hsl(var(--grey5))] group-hover:!text-[hsl(var(--grey7))]"
|
|
569
|
+
class="!text-[hsl(var(--grey5))] group-hover:!text-[hsl(var(--grey7))] rtl:-scale-x-100"
|
|
561
570
|
style="height: 20px !important; min-width: 20px !important; max-width: 20px !important; max-height: 20px !important;"
|
|
562
571
|
/>
|
|
563
572
|
</button>
|
|
@@ -591,7 +600,7 @@
|
|
|
591
600
|
content: '';
|
|
592
601
|
position: absolute;
|
|
593
602
|
top: 0;
|
|
594
|
-
|
|
603
|
+
inset-inline-start: 0;
|
|
595
604
|
width: 100%;
|
|
596
605
|
height: 100%;
|
|
597
606
|
border: 1px solid hsl(var(--grey2));
|
|
@@ -16,6 +16,11 @@ declare const PDFViewer: $$__sveltets_2_IsomorphicComponent<{
|
|
|
16
16
|
style?: string;
|
|
17
17
|
url?: string;
|
|
18
18
|
enableCacheClearing?: boolean;
|
|
19
|
+
loadingLabel?: string;
|
|
20
|
+
failedLabel?: string;
|
|
21
|
+
pageLabel?: string;
|
|
22
|
+
previousPageLabel?: string;
|
|
23
|
+
nextPageLabel?: string;
|
|
19
24
|
}, {
|
|
20
25
|
error: CustomEvent<{
|
|
21
26
|
message: string;
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<div class="group relative w-full">
|
|
63
63
|
<div class="relative overflow-hidden rounded-small border border-[hsl(var(--grey2))] bg-[hsl(var(--grey1))] transition-colors duration-200 hover:border-[hsl(var(--grey2))]">
|
|
64
64
|
<div class="relative w-full flex items-center">
|
|
65
|
-
<div class="absolute
|
|
65
|
+
<div class="absolute start-2 flex items-center pointer-events-none">
|
|
66
66
|
<IconSearch class="h-5 w-5 text-[hsl(var(--grey5))] transition-colors duration-300 {value ? 'text-[hsl(var(--grey7))]' : 'group-hover:text-[hsl(var(--grey7))] group-focus-within:text-[hsl(var(--grey7))]'}" />
|
|
67
67
|
</div>
|
|
68
68
|
<input
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
onKeydown(e);
|
|
80
80
|
}}
|
|
81
81
|
onpaste={onPaste}
|
|
82
|
-
class="w-full h-[38px] border-0 bg-transparent focus:outline-hidden focus:ring-0 focus-visible:ring-0
|
|
82
|
+
class="w-full h-[38px] border-0 bg-transparent focus:outline-hidden focus:ring-0 focus-visible:ring-0 ps-9 pe-8 subtext
|
|
83
83
|
transition-all duration-300
|
|
84
84
|
{value ? 'text-[hsl(var(--grey7))]' : 'text-[hsl(var(--grey3))] placeholder:text-[hsl(var(--grey3))] placeholder:transition-colors placeholder:duration-300 group-hover:text-[hsl(var(--grey7))] group-hover:placeholder:text-[hsl(var(--grey7))] group-focus-within:text-[hsl(var(--grey7))] group-focus-within:placeholder:text-[hsl(var(--grey7)))'}
|
|
85
85
|
{inputClass}"
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
{#if value}
|
|
88
88
|
<button
|
|
89
89
|
type="button"
|
|
90
|
-
class="absolute
|
|
90
|
+
class="absolute end-2 h-6 w-6 inline-flex items-center justify-center rounded-full hover:bg-[hsl(var(--grey2))] transition-all duration-300 widgetic-colors"
|
|
91
91
|
onclick={onClear}
|
|
92
92
|
>
|
|
93
93
|
<X class="h-4 w-4 text-[hsl(var(--grey7))] transition-colors duration-300 hover:text-[hsl(var(--grey7))] widgetic-colors" />
|
|
@@ -7,13 +7,16 @@
|
|
|
7
7
|
import { mode } from 'mode-watcher';
|
|
8
8
|
let { hex = $bindable() }: ColorpickerProps = $props();
|
|
9
9
|
import ColorPicker from 'svelte-awesome-color-picker';
|
|
10
|
+
import { useI18n } from './i18n/context.js';
|
|
11
|
+
|
|
12
|
+
const { t } = useI18n();
|
|
10
13
|
</script>
|
|
11
14
|
|
|
12
15
|
<div class:dark={$mode === 'dark'}>
|
|
13
16
|
<ColorPicker
|
|
14
17
|
bind:hex
|
|
15
18
|
sliderDirection="vertical"
|
|
16
|
-
label=
|
|
19
|
+
label={$t('shadEditor.colorPicker.label')}
|
|
17
20
|
isTextInput={false}
|
|
18
21
|
isAlpha
|
|
19
22
|
--picker-indicator-size="1rem"
|
|
@@ -1 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ImageOptions } from '@tiptap/extension-image';
|
|
2
|
+
import type { Readable } from 'svelte/store';
|
|
3
|
+
import type { Translate } from '../../../../i18n/index.js';
|
|
4
|
+
import type { ShadEditorMessageKey } from '../../i18n/messages.js';
|
|
5
|
+
import type { TextDirection } from '../../../textDirection.js';
|
|
6
|
+
export interface ImageExtensionOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The words of the editor (`language.t` of the editor component). A node view is mounted by TipTap outside the
|
|
9
|
+
* editor's component tree, where Svelte's context does not reach, so the words travel in the options of the extension.
|
|
10
|
+
* English when left out.
|
|
11
|
+
*/
|
|
12
|
+
translate: Readable<Translate<ShadEditorMessageKey>> | null;
|
|
13
|
+
/**
|
|
14
|
+
* The way the screen around the editor is read (`textDirection` of the editor component). It travels in the options for
|
|
15
|
+
* the same reason as `translate`: the menu of the image bar is drawn by a component TipTap mounts outside the editor's
|
|
16
|
+
* tree, so it would not find the direction in Svelte's context. Left to right when left out.
|
|
17
|
+
*/
|
|
18
|
+
textDirection: Readable<TextDirection> | null;
|
|
19
|
+
}
|
|
20
|
+
export declare const ImageExtension: import("@tiptap/core").Node<ImageOptions & ImageExtensionOptions, any>;
|