domma-cms 0.75.0 → 0.77.0
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/CLAUDE.md +1 -1
- package/admin/js/api.js +1 -1
- package/admin/js/app.js +4 -4
- package/admin/js/lib/action-editor-arrange.js +1 -0
- package/admin/js/lib/api-endpoint-editor-arrange.js +2 -0
- package/admin/js/lib/api-tokens-arrange.js +3 -0
- package/admin/js/lib/block-editor-arrange.js +2 -0
- package/admin/js/lib/collection-editor-arrange.js +3 -0
- package/admin/js/lib/collection-entries-arrange.js +1 -0
- package/admin/js/lib/component-editor-arrange.js +27 -0
- package/admin/js/lib/context-menu-editor-arrange.js +1 -0
- package/admin/js/lib/dashboard-arrange.js +1 -0
- package/admin/js/lib/effects-arrange.js +3 -0
- package/admin/js/lib/form-editor-arrange.js +1 -0
- package/admin/js/lib/form-submissions-arrange.js +2 -0
- package/admin/js/lib/layouts-arrange.js +1 -0
- package/admin/js/lib/menu-editor-arrange.js +2 -0
- package/admin/js/lib/my-profile-arrange.js +1 -0
- package/admin/js/lib/notifications-arrange.js +1 -0
- package/admin/js/lib/page-editor-arrange.js +1 -0
- package/admin/js/lib/plugin-code-arrange.js +1 -0
- package/admin/js/lib/plugins-arrange.js +2 -0
- package/admin/js/lib/project-page-arrange.js +1 -0
- package/admin/js/lib/role-editor-arrange.js +3 -0
- package/admin/js/lib/roles-arrange.js +1 -0
- package/admin/js/lib/search-settings-arrange.js +1 -0
- package/admin/js/lib/sidebar-renderer.js +2 -2
- package/admin/js/lib/site-settings-arrange.js +1 -0
- package/admin/js/lib/user-editor-arrange.js +1 -0
- package/admin/js/lib/users-arrange.js +1 -0
- package/admin/js/lib/view-editor-arrange.js +14 -0
- package/admin/js/templates/action-editor.html +223 -147
- package/admin/js/templates/api-endpoint-editor.html +172 -117
- package/admin/js/templates/api-tokens.html +83 -10
- package/admin/js/templates/block-editor.html +194 -203
- package/admin/js/templates/collection-editor.html +191 -113
- package/admin/js/templates/collection-entries.html +99 -36
- package/admin/js/templates/component-editor.html +128 -126
- package/admin/js/templates/context-menu-editor.html +208 -148
- package/admin/js/templates/dashboard.html +184 -22
- package/admin/js/templates/effects.html +155 -72
- package/admin/js/templates/form-editor.html +41 -26
- package/admin/js/templates/form-submissions.html +78 -26
- package/admin/js/templates/layouts.html +126 -43
- package/admin/js/templates/menu-editor.html +57 -17
- package/admin/js/templates/menu-locations.html +54 -11
- package/admin/js/templates/my-profile.html +100 -12
- package/admin/js/templates/notifications.html +70 -10
- package/admin/js/templates/page-editor.html +47 -26
- package/admin/js/templates/plugin-code.html +91 -73
- package/admin/js/templates/plugins.html +100 -28
- package/admin/js/templates/project-detail.html +83 -145
- package/admin/js/templates/project-settings.html +88 -53
- package/admin/js/templates/role-editor.html +158 -83
- package/admin/js/templates/roles.html +78 -7
- package/admin/js/templates/search.html +193 -216
- package/admin/js/templates/settings.html +404 -472
- package/admin/js/templates/user-editor.html +150 -14
- package/admin/js/templates/users.html +69 -9
- package/admin/js/templates/view-editor.html +203 -180
- package/admin/js/templates/view-preview.html +45 -45
- package/admin/js/views/action-editor.js +7 -1
- package/admin/js/views/api-endpoint-editor.js +2 -3
- package/admin/js/views/api-tokens.js +62 -8
- package/admin/js/views/block-editor.js +14 -8
- package/admin/js/views/collection-editor.js +64 -5
- package/admin/js/views/collection-entries.js +50 -1
- package/admin/js/views/component-editor.js +2 -28
- package/admin/js/views/context-menu-editor.js +54 -55
- package/admin/js/views/dashboard.js +7 -1
- package/admin/js/views/effects.js +31 -1
- package/admin/js/views/form-editor.js +7 -7
- package/admin/js/views/form-submissions.js +11 -1
- package/admin/js/views/index.js +1 -1
- package/admin/js/views/layouts.js +81 -1
- package/admin/js/views/login.js +2 -2
- package/admin/js/views/menu-editor.js +21 -43
- package/admin/js/views/menu-locations.js +16 -1
- package/admin/js/views/my-profile.js +1 -1
- package/admin/js/views/notifications.js +18 -1
- package/admin/js/views/page-editor.js +26 -26
- package/admin/js/views/plugin-code.js +23 -4
- package/admin/js/views/plugins.js +97 -39
- package/admin/js/views/project-detail.js +9 -1
- package/admin/js/views/project-settings.js +1 -1
- package/admin/js/views/role-editor.js +11 -3
- package/admin/js/views/roles.js +49 -4
- package/admin/js/views/search.js +7 -1
- package/admin/js/views/settings.js +13 -3
- package/admin/js/views/user-editor.js +1 -1
- package/admin/js/views/users.js +13 -4
- package/admin/js/views/view-editor.js +1 -1
- package/admin/js/views/view-preview.js +1 -1
- package/package.json +1 -1
- package/plugins/_lib/admin/mail/compose-window.js +97 -40
- package/plugins/_lib/admin/mail/contacts.js +4 -1
- package/plugins/_lib/admin/mail/diagnostics-section.js +4 -1
- package/plugins/_lib/admin/mail/folder-tree.js +1 -1
- package/plugins/_lib/admin/mail/image-senders-section.js +69 -90
- package/plugins/_lib/admin/mail/mail.css +1 -1
- package/plugins/_lib/admin/mail/mail.html +1 -1
- package/plugins/_lib/admin/mail/reader-view.js +303 -44
- package/plugins/_lib/admin/mail/when-closed.js +26 -0
- package/plugins/_lib/mail/readRoutes.js +43 -1
- package/plugins/_lib/mail/unreadBadge.js +42 -0
- package/plugins/free-tier.lock.json +5 -5
- package/plugins/mail-reader/CLAUDE.md +1 -0
- package/plugins/mail-reader/plugin.js +3 -1
- package/plugins/mail-reader/plugin.json +5 -4
- package/server/routes/api/api-tokens.js +56 -0
- package/server/routes/api/auth.js +7 -1
- package/server/routes/api/collections.js +13 -1
- package/server/routes/api/dashboard.js +32 -4
- package/server/routes/api/effects.js +68 -13
- package/server/routes/api/forms.js +104 -13
- package/server/routes/api/layouts.js +93 -2
- package/server/routes/api/notifications.js +140 -14
- package/server/routes/api/plugins.js +135 -4
- package/server/routes/api/roles.js +111 -0
- package/server/routes/api/search.js +38 -4
- package/server/routes/api/settings.js +52 -0
- package/server/routes/api/users.js +65 -3
- package/server/routes/api/views.js +55 -1
- package/server/server.js +12 -0
- package/server/services/components.js +9 -0
- package/server/services/plugins.js +7 -0
- package/server/services/roles.js +3 -0
- package/server/services/search.js +58 -0
- package/server/services/users.js +16 -2
- package/server/services/views.js +14 -0
- package/admin/js/templates/dashboard/activity-feed.html +0 -3
- package/admin/js/templates/dashboard/cache.html +0 -32
- package/admin/js/templates/dashboard/health-detail.html +0 -2
- package/admin/js/templates/dashboard/journeys.html +0 -17
- package/admin/js/templates/dashboard/kpi-strip.html +0 -34
- package/admin/js/templates/dashboard/spike-feed.html +0 -3
- package/admin/js/templates/dashboard/top-pages.html +0 -3
- package/admin/js/templates/dashboard/traffic-chart.html +0 -3
- package/admin/js/templates/plugin-marketplace.html +0 -29
- package/admin/js/views/block-editor-enhance.js +0 -1
- package/admin/js/views/dashboard/lib/escape.js +0 -1
- package/admin/js/views/dashboard/widgets/activity-feed.js +0 -1
- package/admin/js/views/dashboard/widgets/cache.js +0 -1
- package/admin/js/views/dashboard/widgets/health-detail.js +0 -1
- package/admin/js/views/dashboard/widgets/journeys.js +0 -1
- package/admin/js/views/dashboard/widgets/kpi-strip.js +0 -1
- package/admin/js/views/dashboard/widgets/spike-feed.js +0 -6
- package/admin/js/views/dashboard/widgets/top-pages.js +0 -1
- package/admin/js/views/dashboard/widgets/traffic-chart.js +0 -1
- package/admin/js/views/plugin-marketplace.js +0 -1
|
@@ -1,241 +1,218 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
|
|
1
|
+
<!-- System › Search. Bound with M.applyBindings - see admin/js/views/search.js, which also inserts the
|
|
2
|
+
preview row template (the router renders a templateUrl through _.render, eating any {{…}}).
|
|
3
|
+
No page heading: the Tool banner above is the heading; Save and View site are banner actions. -->
|
|
4
|
+
<div class="ssx">
|
|
5
|
+
<p class="ssx-alert is-dirty" data-bind-hidden="!dirty.value">
|
|
6
|
+
<span data-icon="edit-3" data-icon-size="16"></span>
|
|
7
|
+
<span>Unsaved changes - Save (Ctrl+S) to apply them. Leave and they are kept as a draft for next time.</span>
|
|
8
|
+
<span class="ssx-spacer"></span>
|
|
9
|
+
<button type="button" class="btn btn-sm btn-ghost" data-on-click="discard">Discard</button>
|
|
10
|
+
<button type="button" class="btn btn-sm btn-primary" data-on-click="save" data-bind-disabled="saving.value">Save</button></p>
|
|
11
|
+
<p class="ssx-alert" data-bind-hidden="!clampText.value">
|
|
12
|
+
<span data-icon="alert-triangle" data-icon-size="16"></span>
|
|
13
|
+
<span data-bind-text="clampText.value"></span></p>
|
|
14
|
+
|
|
15
|
+
<div class="tabs ssx-tabs">
|
|
16
|
+
<div class="tab-list">
|
|
17
|
+
<button type="button" class="tab-item active">Search</button>
|
|
18
|
+
<button type="button" class="tab-item">Trigger & position</button>
|
|
19
|
+
<button type="button" class="tab-item">Try it</button>
|
|
20
|
+
<button type="button" class="tab-item">How it works</button>
|
|
21
|
+
</div>
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
23
|
+
<!-- Search -->
|
|
24
|
+
<div class="tab-panel active">
|
|
25
|
+
<div class="ssx-card">
|
|
26
|
+
<div class="ssx-card-title">Live now
|
|
27
|
+
<span data-help-title="Live now" data-help="What visitors get at the moment - the saved settings, not what you are editing. Searchable pages are the published, public ones; drafts and private pages never appear in results."></span></div>
|
|
28
|
+
<div class="ssx-chips" data-each="chips.value key=text"></div>
|
|
29
|
+
</div>
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
<div class="ssx-card">
|
|
32
|
+
<div class="ssx-card-title">Search on the site</div>
|
|
33
|
+
<div class="ssx-setting">
|
|
34
|
+
<label class="form-label" for="ssx-enabled">Enable search on the public site
|
|
35
|
+
<span data-help="Off removes search completely - no trigger, stylesheet or script is added to public pages. Context menus offering Site search do nothing while it is off."></span></label>
|
|
36
|
+
<input id="ssx-enabled" type="checkbox" class="form-switch" data-model="enabled.value">
|
|
37
|
+
</div>
|
|
38
|
+
<div class="ssx-grid">
|
|
39
|
+
<div class="ssx-wide">
|
|
40
|
+
<label class="form-label" for="ssx-placeholder">Placeholder text
|
|
41
|
+
<span data-help="Shown inside the search box while it is empty. Up to 120 characters."></span></label>
|
|
42
|
+
<input id="ssx-placeholder" type="text" class="form-input" maxlength="120" placeholder="Search pages..." data-model="placeholder.value">
|
|
39
43
|
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="ssx-setting">
|
|
46
|
+
<label class="form-label" for="ssx-shortcut">Keyboard shortcut (Ctrl+K / ⌘K)
|
|
47
|
+
<span data-help="Lets visitors open search from anywhere on a page with Ctrl+K (⌘K on a Mac), as well as by clicking the trigger."></span></label>
|
|
48
|
+
<input id="ssx-shortcut" type="checkbox" class="form-switch" data-model="keyboardShortcut.value">
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
40
51
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
</div>
|
|
52
|
+
<div class="ssx-card">
|
|
53
|
+
<div class="ssx-card-title">Results</div>
|
|
54
|
+
<div class="ssx-grid ssx-grid-3">
|
|
55
|
+
<div>
|
|
56
|
+
<label class="form-label" for="ssx-max">Max results
|
|
57
|
+
<span data-help="The most results one search shows (1-50). They are ranked: a title match counts most, then tags, the description, and the page's text."></span></label>
|
|
58
|
+
<input id="ssx-max" type="number" class="form-input" min="1" max="50" data-model="maxResults.value">
|
|
49
59
|
</div>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<input id="field-max-results" type="number" class="form-input" min="1" max="50"
|
|
55
|
-
placeholder="10">
|
|
56
|
-
<span class="form-hint">Maximum number of results to return per search (1-50).</span>
|
|
57
|
-
</div>
|
|
58
|
-
<div class="col-6">
|
|
59
|
-
<label class="form-label">Minimum query length</label>
|
|
60
|
-
<input id="field-min-query-length" type="number" class="form-input" min="1" max="5"
|
|
61
|
-
placeholder="2">
|
|
62
|
-
<span class="form-hint">Minimum characters required before searching (1-5).</span>
|
|
63
|
-
</div>
|
|
60
|
+
<div>
|
|
61
|
+
<label class="form-label" for="ssx-min">Minimum query length
|
|
62
|
+
<span data-help="How many characters a visitor types before searching starts (1-5). 1 searches on every keystroke; 2 or 3 avoids a flood of weak matches."></span></label>
|
|
63
|
+
<input id="ssx-min" type="number" class="form-input" min="1" max="5" data-model="minQueryLength.value">
|
|
64
64
|
</div>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<input id="field-debounce-ms" type="number" class="form-input" min="100" max="1000"
|
|
70
|
-
placeholder="300">
|
|
71
|
-
<span class="form-hint">Delay after typing stops before search fires (100-1000ms).</span>
|
|
72
|
-
</div>
|
|
65
|
+
<div>
|
|
66
|
+
<label class="form-label" for="ssx-debounce">Debounce delay (ms)
|
|
67
|
+
<span data-help="How long after the last keystroke the search runs (100-1000 ms). Shorter feels more instant; longer sends fewer searches while someone is still typing."></span></label>
|
|
68
|
+
<input id="ssx-debounce" type="number" class="form-input" min="100" max="1000" step="50" data-model="debounceMs.value">
|
|
73
69
|
</div>
|
|
74
|
-
|
|
75
70
|
</div>
|
|
76
71
|
</div>
|
|
77
72
|
</div>
|
|
78
73
|
|
|
79
|
-
<!-- Trigger &
|
|
80
|
-
<div class="tab-panel"
|
|
81
|
-
<div class="card
|
|
82
|
-
<div class="card-
|
|
74
|
+
<!-- Trigger & position -->
|
|
75
|
+
<div class="tab-panel">
|
|
76
|
+
<div class="ssx-card">
|
|
77
|
+
<div class="ssx-card-title">How visitors open it
|
|
78
|
+
<span data-help-title="Trigger" data-help="Navbar adds a search icon to the site's navigation bar. Floating button puts a fixed button on every page, in the corner or side you choose - useful when the navigation is busy or hidden on small screens."></span></div>
|
|
79
|
+
<div class="ssx-seg" role="group" aria-label="Display mode">
|
|
80
|
+
<button type="button" data-on-click="useNavbar" data-bind-class="displayMode.value === 'navbar' && 'is-on'">
|
|
81
|
+
<span data-icon="menu" data-icon-size="14"></span> Navbar</button>
|
|
82
|
+
<button type="button" data-on-click="useFloating" data-bind-class="displayMode.value === 'floating' && 'is-on'">
|
|
83
|
+
<span data-icon="search" data-icon-size="14"></span> Floating button</button>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
<span
|
|
98
|
-
|
|
87
|
+
<div class="ssx-card" data-bind-hidden="displayMode.value !== 'floating'">
|
|
88
|
+
<div class="ssx-card-title">The floating button</div>
|
|
89
|
+
<div class="ssx-setting">
|
|
90
|
+
<label class="form-label" for="ssx-icononly">Icon only
|
|
91
|
+
<span data-help="On: a round or square icon button. Off: a pill with a Search label beside the icon (size and corners then follow the label)."></span></label>
|
|
92
|
+
<input id="ssx-icononly" type="checkbox" class="form-switch" data-model="iconOnly.value">
|
|
93
|
+
</div>
|
|
94
|
+
<div class="ssx-button-row" data-bind-hidden="!iconOnly.value">
|
|
95
|
+
<div class="ssx-sliders">
|
|
96
|
+
<label class="form-label" for="ssx-size">Size <span class="ssx-readout" data-bind-text="sizeText.value"></span>
|
|
97
|
+
<span data-help="How big the button is (32-96 px). The glyph inside scales with it. 44 px and up is comfortable to tap on a phone."></span></label>
|
|
98
|
+
<input id="ssx-size" type="range" min="32" max="96" step="2" data-model="iconSize.value">
|
|
99
|
+
<label class="form-label" for="ssx-radius">Corners <span class="ssx-readout" data-bind-text="radiusText.value"></span>
|
|
100
|
+
<span data-help="0 is a square; the top of the range is a circle, and it is always half the size - so it moves when the size does."></span></label>
|
|
101
|
+
<input id="ssx-radius" type="range" min="0" step="1" data-model="iconRadius.value">
|
|
99
102
|
</div>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
<div style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap;">
|
|
117
|
-
<input id="field-icon-size" type="range" min="32" max="96" step="2" value="52"
|
|
118
|
-
style="flex:1 1 200px;max-width:260px;">
|
|
119
|
-
<span id="ss-size-value" class="text-sm font-mono" style="min-width:3.5rem;">52px</span>
|
|
120
|
-
</div>
|
|
121
|
-
<span class="form-hint">How big the floating button is, in pixels (32-96). The search glyph inside
|
|
122
|
-
scales with it. 44px and up is the comfortable range for tapping on a phone.</span>
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
<div class="row mb-3" id="ss-radius-row">
|
|
127
|
-
<div class="col">
|
|
128
|
-
<label class="form-label" for="field-icon-radius">Icon corner radius</label>
|
|
129
|
-
<div style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap;">
|
|
130
|
-
<input id="field-icon-radius" type="range" min="0" max="26" step="1" value="26"
|
|
131
|
-
style="flex:1 1 200px;max-width:260px;">
|
|
132
|
-
<span id="ss-radius-value" class="text-sm font-mono" style="min-width:3.5rem;">26px</span>
|
|
133
|
-
<span id="ss-radius-preview" aria-hidden="true"
|
|
134
|
-
style="width:52px;height:52px;display:inline-flex;align-items:center;justify-content:center;
|
|
135
|
-
background:var(--dm-surface);color:var(--dm-text);
|
|
136
|
-
border:1px solid var(--dm-border);border-radius:26px;
|
|
137
|
-
box-shadow:0 4px 16px rgba(0,0,0,.14);flex:0 0 auto;transition:border-radius .12s;">
|
|
138
|
-
<span data-icon="search" style="width:20px;height:20px;"></span>
|
|
139
|
-
</span>
|
|
140
|
-
</div>
|
|
141
|
-
<span class="form-hint">0 is a square, <span id="ss-radius-max-hint">26</span> a circle - the top of the
|
|
142
|
-
range is always half the icon size, so it moves when you change the size above. The preview is the real
|
|
143
|
-
button at its real size. Applies to the floating button in icon mode only - the navbar icon has no
|
|
144
|
-
surface to round, and the labelled variant is a pill by definition.</span>
|
|
145
|
-
</div>
|
|
103
|
+
<span class="ssx-button-preview" aria-hidden="true" title="The button at its real size"
|
|
104
|
+
data-bind-style-width="sizePx.value" data-bind-style-height="sizePx.value" data-bind-style-border-radius="radiusPx.value">
|
|
105
|
+
<span class="ssx-glyph" data-bind-style-width="glyphPx.value" data-bind-style-height="glyphPx.value"><span data-icon="search"></span></span>
|
|
106
|
+
</span>
|
|
107
|
+
</div>
|
|
108
|
+
<div>
|
|
109
|
+
<div class="ssx-card-title ssx-sub">Where it sits
|
|
110
|
+
<span data-help="Click a spot on the little screen. The offsets are the distance from the edges it sits against."></span></div>
|
|
111
|
+
<div class="ssx-where">
|
|
112
|
+
<div class="ssx-screen" role="group" aria-label="Position">
|
|
113
|
+
<button type="button" class="ssx-spot" style="top:6px;left:6px" data-on-click="setPos('top-left')" data-bind-class="position.value === 'top-left' && 'is-on'" title="Top left"></button>
|
|
114
|
+
<button type="button" class="ssx-spot" style="top:6px;right:6px" data-on-click="setPos('top-right')" data-bind-class="position.value === 'top-right' && 'is-on'" title="Top right"></button>
|
|
115
|
+
<button type="button" class="ssx-spot" style="top:calc(50% - 9px);left:6px" data-on-click="setPos('left-center')" data-bind-class="position.value === 'left-center' && 'is-on'" title="Left side"></button>
|
|
116
|
+
<button type="button" class="ssx-spot" style="top:calc(50% - 9px);right:6px" data-on-click="setPos('right-center')" data-bind-class="position.value === 'right-center' && 'is-on'" title="Right side"></button>
|
|
117
|
+
<button type="button" class="ssx-spot" style="bottom:6px;left:6px" data-on-click="setPos('bottom-left')" data-bind-class="position.value === 'bottom-left' && 'is-on'" title="Bottom left"></button>
|
|
118
|
+
<button type="button" class="ssx-spot" style="bottom:6px;right:6px" data-on-click="setPos('bottom-right')" data-bind-class="position.value === 'bottom-right' && 'is-on'" title="Bottom right"></button>
|
|
146
119
|
</div>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
style="display:grid;grid-template-columns:1fr 1fr;gap:2px;border:1px solid var(--border-color,rgba(255,255,255,.1));border-radius:10px;overflow:hidden;background:var(--border-color,rgba(255,255,255,.07));width:fit-content;">
|
|
154
|
-
|
|
155
|
-
<div class="ss-pos-btn" data-pos="top-left"
|
|
156
|
-
style="display:flex;flex-direction:column;align-items:flex-start;padding:.55rem .8rem;cursor:pointer;font-size:.78rem;color:var(--text-muted,#888);border-right:1px solid var(--border-color,rgba(255,255,255,.08));border-bottom:1px solid var(--border-color,rgba(255,255,255,.08));gap:.05rem;user-select:none;transition:background .15s,color .15s;min-width:84px;">
|
|
157
|
-
<span style="font-size:.6rem;opacity:.55;letter-spacing:.06em;text-transform:uppercase;line-height:1.2;">Top</span>
|
|
158
|
-
<span style="font-weight:600;">↖ Left</span>
|
|
159
|
-
</div>
|
|
160
|
-
<div class="ss-pos-btn" data-pos="top-right"
|
|
161
|
-
style="display:flex;flex-direction:column;align-items:flex-end;padding:.55rem .8rem;cursor:pointer;font-size:.78rem;color:var(--text-muted,#888);border-bottom:1px solid var(--border-color,rgba(255,255,255,.08));gap:.05rem;user-select:none;transition:background .15s,color .15s;min-width:84px;">
|
|
162
|
-
<span style="font-size:.6rem;opacity:.55;letter-spacing:.06em;text-transform:uppercase;line-height:1.2;">Top</span>
|
|
163
|
-
<span style="font-weight:600;">Right ↗</span>
|
|
164
|
-
</div>
|
|
165
|
-
|
|
166
|
-
<div class="ss-pos-btn" data-pos="left-center"
|
|
167
|
-
style="display:flex;flex-direction:column;align-items:flex-start;padding:.55rem .8rem;cursor:pointer;font-size:.78rem;color:var(--text-muted,#888);border-right:1px solid var(--border-color,rgba(255,255,255,.08));border-bottom:1px solid var(--border-color,rgba(255,255,255,.08));gap:.05rem;user-select:none;transition:background .15s,color .15s;min-width:84px;">
|
|
168
|
-
<span style="font-size:.6rem;opacity:.55;letter-spacing:.06em;text-transform:uppercase;line-height:1.2;">Side</span>
|
|
169
|
-
<span style="font-weight:600;">← Left</span>
|
|
170
|
-
</div>
|
|
171
|
-
<div class="ss-pos-btn" data-pos="right-center"
|
|
172
|
-
style="display:flex;flex-direction:column;align-items:flex-end;padding:.55rem .8rem;cursor:pointer;font-size:.78rem;color:var(--text-muted,#888);border-bottom:1px solid var(--border-color,rgba(255,255,255,.08));gap:.05rem;user-select:none;transition:background .15s,color .15s;min-width:84px;">
|
|
173
|
-
<span style="font-size:.6rem;opacity:.55;letter-spacing:.06em;text-transform:uppercase;line-height:1.2;">Side</span>
|
|
174
|
-
<span style="font-weight:600;">Right →</span>
|
|
175
|
-
</div>
|
|
176
|
-
|
|
177
|
-
<div class="ss-pos-btn" data-pos="bottom-left"
|
|
178
|
-
style="display:flex;flex-direction:column;align-items:flex-start;padding:.55rem .8rem;cursor:pointer;font-size:.78rem;color:var(--text-muted,#888);border-right:1px solid var(--border-color,rgba(255,255,255,.08));gap:.05rem;user-select:none;transition:background .15s,color .15s;min-width:84px;">
|
|
179
|
-
<span style="font-weight:600;">↙ Left</span>
|
|
180
|
-
<span style="font-size:.6rem;opacity:.55;letter-spacing:.06em;text-transform:uppercase;line-height:1.2;">Bottom</span>
|
|
181
|
-
</div>
|
|
182
|
-
<div class="ss-pos-btn" data-pos="bottom-right"
|
|
183
|
-
style="display:flex;flex-direction:column;align-items:flex-end;padding:.55rem .8rem;cursor:pointer;font-size:.78rem;color:var(--text-muted,#888);gap:.05rem;user-select:none;transition:background .15s,color .15s;min-width:84px;">
|
|
184
|
-
<span style="font-weight:600;">Right ↘</span>
|
|
185
|
-
<span style="font-size:.6rem;opacity:.55;letter-spacing:.06em;text-transform:uppercase;line-height:1.2;">Bottom</span>
|
|
186
|
-
</div>
|
|
187
|
-
|
|
188
|
-
</div>
|
|
189
|
-
<input type="hidden" id="field-position" value="bottom-right">
|
|
190
|
-
</div>
|
|
191
|
-
|
|
192
|
-
<div class="col-sm-3">
|
|
193
|
-
<label class="form-label">Edge offset</label>
|
|
194
|
-
<div style="display:flex;flex-direction:column;gap:.55rem;">
|
|
195
|
-
<div style="display:flex;align-items:center;gap:.4rem;">
|
|
196
|
-
<span style="font-size:.75rem;color:var(--text-muted,#888);width:22px;">H</span>
|
|
197
|
-
<input id="field-offset-x" type="number" class="form-input" min="0" max="500"
|
|
198
|
-
placeholder="32" style="max-width:80px;">
|
|
199
|
-
<span class="text-muted" style="font-size:.8rem;">px</span>
|
|
200
|
-
</div>
|
|
201
|
-
<div style="display:flex;align-items:center;gap:.4rem;">
|
|
202
|
-
<span style="font-size:.75rem;color:var(--text-muted,#888);width:22px;">V</span>
|
|
203
|
-
<input id="field-offset-y" type="number" class="form-input" min="0" max="500"
|
|
204
|
-
placeholder="32" style="max-width:80px;">
|
|
205
|
-
<span class="text-muted" style="font-size:.8rem;">px</span>
|
|
206
|
-
</div>
|
|
207
|
-
</div>
|
|
208
|
-
<p class="form-hint text-muted" style="margin-top:.35rem;font-size:.75rem;">Distance
|
|
209
|
-
from the screen edge.</p>
|
|
210
|
-
</div>
|
|
211
|
-
|
|
120
|
+
<div class="ssx-offsets">
|
|
121
|
+
<strong data-bind-text="positionText.value"></strong>
|
|
122
|
+
<label class="form-label" for="ssx-offx">From the side (px)</label>
|
|
123
|
+
<input id="ssx-offx" type="number" class="form-input" min="0" max="500" data-model="offsetX.value">
|
|
124
|
+
<label class="form-label" for="ssx-offy">From the top or bottom (px)</label>
|
|
125
|
+
<input id="ssx-offy" type="number" class="form-input" min="0" max="500" data-model="offsetY.value">
|
|
212
126
|
</div>
|
|
213
127
|
</div>
|
|
214
|
-
|
|
215
128
|
</div>
|
|
216
129
|
</div>
|
|
217
130
|
</div>
|
|
218
131
|
|
|
219
|
-
<!--
|
|
220
|
-
<div class="tab-panel"
|
|
221
|
-
<div class="card
|
|
222
|
-
<div class="card-
|
|
223
|
-
<
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
</li>
|
|
230
|
-
<li>Draft pages and private pages are excluded from results.</li>
|
|
231
|
-
<li>An authored context menu can offer "Site search" as an action, which opens the same overlay.</li>
|
|
232
|
-
<li>Use <kbd>↑</kbd> <kbd>↓</kbd> to navigate results, <kbd>↵</kbd> to open, <kbd>Esc</kbd> to
|
|
233
|
-
close.
|
|
234
|
-
</li>
|
|
235
|
-
</ul>
|
|
236
|
-
</div>
|
|
132
|
+
<!-- Try it -->
|
|
133
|
+
<div class="tab-panel">
|
|
134
|
+
<div class="ssx-card">
|
|
135
|
+
<div class="ssx-card-title">Try a search
|
|
136
|
+
<span data-help-title="Try it" data-help="Runs the site's own search as a visitor would - published, public pages only, ranked the same way - using the Max results you are editing, before you Save. Right-click a result (or ⋮) to open or edit the page."></span></div>
|
|
137
|
+
<input type="search" class="form-input ssx-q" placeholder="Search your pages…" aria-label="Try a search" data-model="query.value">
|
|
138
|
+
<p class="ssx-note" data-bind-hidden="!previewNote.value" data-bind-text="previewNote.value"></p>
|
|
139
|
+
<p class="ssx-note is-bad" data-bind-hidden="!previewError.value" data-bind-text="previewError.value"></p>
|
|
140
|
+
<p class="ssx-note" data-bind-hidden="!previewMeta.value" data-bind-text="previewMeta.value"></p>
|
|
141
|
+
<div class="ssx-list" data-each="results.value key=id"></div>
|
|
237
142
|
</div>
|
|
238
143
|
</div>
|
|
239
144
|
|
|
145
|
+
<!-- How it works -->
|
|
146
|
+
<div class="tab-panel">
|
|
147
|
+
<div class="ssx-card">
|
|
148
|
+
<div class="ssx-card-title">How search works</div>
|
|
149
|
+
<ul class="ssx-how">
|
|
150
|
+
<li>Visitors click the trigger (or press the shortcut) and get a full-screen overlay with live results.</li>
|
|
151
|
+
<li>Results are ranked: a title match scores highest, then tags, the description, and the page's text.</li>
|
|
152
|
+
<li>Draft and private pages never appear in results.</li>
|
|
153
|
+
<li>An authored context menu can offer "Site search" as an action; it opens the same overlay.</li>
|
|
154
|
+
<li>In the overlay: <kbd>↑</kbd> <kbd>↓</kbd> move, <kbd>↵</kbd> opens, <kbd>Esc</kbd> closes.</li>
|
|
155
|
+
</ul>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
240
158
|
</div>
|
|
241
159
|
</div>
|
|
160
|
+
|
|
161
|
+
<style>
|
|
162
|
+
.ssx { display: flex; flex-direction: column; gap: .75rem; }
|
|
163
|
+
.ssx [hidden] { display: none !important; }
|
|
164
|
+
.ssx-alert { margin: 0; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; padding: .6rem .8rem; border-radius: var(--dm-radius-md);
|
|
165
|
+
background: color-mix(in srgb, var(--dm-warning) 16%, transparent); color: var(--dm-text); }
|
|
166
|
+
.ssx-alert.is-dirty { background: color-mix(in srgb, var(--dm-primary) 12%, transparent); }
|
|
167
|
+
.ssx-spacer { flex: 1; }
|
|
168
|
+
.ssx-card { border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); padding: .75rem .9rem; display: flex; flex-direction: column; gap: .7rem; margin-top: .75rem; }
|
|
169
|
+
.ssx-card-title { display: flex; align-items: center; gap: .35rem; font-weight: 600; }
|
|
170
|
+
.ssx-sub { font-size: var(--dm-text-sm); }
|
|
171
|
+
.ssx-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem 1rem; }
|
|
172
|
+
.ssx-grid-3 { grid-template-columns: 1fr 1fr 1fr; }
|
|
173
|
+
.ssx-wide { grid-column: 1 / -1; }
|
|
174
|
+
.ssx .form-label { display: flex; align-items: center; gap: .3rem; }
|
|
175
|
+
.ssx-setting { display: flex; align-items: center; justify-content: space-between; gap: .75rem; }
|
|
176
|
+
.ssx-setting .form-label { margin: 0; }
|
|
177
|
+
.ssx-note { margin: 0; color: var(--dm-text-muted); font-size: var(--dm-text-sm); }
|
|
178
|
+
.ssx-note.is-bad { color: var(--dm-danger); }
|
|
179
|
+
.ssx-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
|
|
180
|
+
.ssx-chip { display: inline-flex; align-items: center; font-size: var(--dm-text-xs); font-weight: 600; padding: .15rem .55rem; border-radius: 999px; white-space: nowrap;
|
|
181
|
+
background: color-mix(in srgb, var(--dm-text) 10%, transparent); color: var(--dm-text-muted); }
|
|
182
|
+
.ssx-chip.is-ok { background: color-mix(in srgb, var(--dm-success) 16%, transparent); color: var(--dm-success); }
|
|
183
|
+
.ssx-chip.is-warn { background: color-mix(in srgb, var(--dm-warning) 18%, transparent); color: var(--dm-warning); }
|
|
184
|
+
.ssx-seg { display: inline-flex; border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); overflow: hidden; align-self: flex-start; }
|
|
185
|
+
.ssx-seg button { display: inline-flex; align-items: center; gap: .35rem; border: 0; background: none; color: var(--dm-text); padding: .35rem .8rem; cursor: pointer; font: inherit; font-size: var(--dm-text-sm); }
|
|
186
|
+
.ssx-seg button + button { border-left: 1px solid var(--dm-border); }
|
|
187
|
+
.ssx-seg button:hover { background: var(--dm-table-hover-bg, color-mix(in srgb, var(--dm-text) 6%, transparent)); }
|
|
188
|
+
.ssx-seg button.is-on { background: var(--dm-primary); color: var(--dm-primary-text); }
|
|
189
|
+
.ssx-button-row { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; }
|
|
190
|
+
.ssx-sliders { display: flex; flex-direction: column; gap: .35rem; flex: 1 1 240px; max-width: 320px; }
|
|
191
|
+
.ssx-readout { font-family: var(--dm-font-mono, monospace); color: var(--dm-text-muted); font-weight: 400; }
|
|
192
|
+
.ssx-button-preview { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
|
|
193
|
+
background: var(--dm-surface); color: var(--dm-text); border: 1px solid var(--dm-border);
|
|
194
|
+
box-shadow: 0 4px 16px color-mix(in srgb, var(--dm-text) 14%, transparent); transition: border-radius .12s; }
|
|
195
|
+
.ssx-glyph { display: inline-flex; }
|
|
196
|
+
.ssx-glyph svg { width: 100%; height: 100%; }
|
|
197
|
+
.ssx-where { display: flex; gap: 1.25rem; align-items: flex-start; flex-wrap: wrap; }
|
|
198
|
+
.ssx-screen { position: relative; width: 180px; height: 120px; border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md);
|
|
199
|
+
background: color-mix(in srgb, var(--dm-text) 4%, transparent); flex: 0 0 auto; }
|
|
200
|
+
.ssx-spot { position: absolute; width: 18px; height: 18px; border-radius: 50%; border: 1px dashed var(--dm-border); background: var(--dm-surface); cursor: pointer; padding: 0; }
|
|
201
|
+
.ssx-spot:hover { border-color: var(--dm-primary); }
|
|
202
|
+
.ssx-spot.is-on { background: var(--dm-primary); border: 1px solid var(--dm-primary); }
|
|
203
|
+
.ssx-offsets { display: flex; flex-direction: column; gap: .3rem; min-width: 12rem; }
|
|
204
|
+
.ssx-offsets .form-input { max-width: 8rem; }
|
|
205
|
+
.ssx-q { max-width: 32rem; }
|
|
206
|
+
.ssx-list { display: flex; flex-direction: column; }
|
|
207
|
+
.ssx-row { display: flex; align-items: flex-start; gap: .75rem; padding: .55rem .35rem; border-bottom: 1px solid var(--dm-border); cursor: pointer; }
|
|
208
|
+
.ssx-row:last-child { border-bottom: 0; }
|
|
209
|
+
.ssx-row:hover, .ssx-row:focus-visible { background: var(--dm-table-hover-bg, color-mix(in srgb, var(--dm-text) 6%, transparent)); outline: none; }
|
|
210
|
+
.ssx-rank { min-width: 1.5rem; color: var(--dm-text-muted); font-variant-numeric: tabular-nums; padding-top: .1rem; }
|
|
211
|
+
.ssx-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .1rem; }
|
|
212
|
+
.ssx-main small { color: var(--dm-text-muted); font-size: var(--dm-text-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
213
|
+
.ssx-snippet { color: var(--dm-text); font-size: var(--dm-text-sm); opacity: .85; }
|
|
214
|
+
.ssx-kebab { border: 0; background: none; cursor: pointer; font-size: var(--dm-text-lg); color: var(--dm-text-muted); border-radius: var(--dm-radius-sm); padding: 0 .3rem; }
|
|
215
|
+
.ssx-kebab:hover { color: var(--dm-primary); }
|
|
216
|
+
.ssx-how { margin: 0; padding-left: 1.25rem; line-height: 1.8; color: var(--dm-text-muted); }
|
|
217
|
+
@media (max-width: 720px) { .ssx-grid, .ssx-grid-3 { grid-template-columns: 1fr; } }
|
|
218
|
+
</style>
|