@xleddyl/443-components-vue 0.9.2 → 0.9.3
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
CHANGED
|
@@ -509,7 +509,7 @@ A large dialog (60rem) with a section nav on the left and the content on the rig
|
|
|
509
509
|
- Built-in sections, used when no `#section-<id>` slot fills them: `account` (profile card, your `#account-fields`, a sign out button) and `appearance` (`AppearanceSettings`: theme cards light, dark, system and preset cards; `presets` limits or hides them).
|
|
510
510
|
- `@sign-out` adds a Sign out item at the bottom of the nav and in the account section.
|
|
511
511
|
- Labels: `title` (accessible name of the dialog, default `Settings`), `closeLabel`, `navLabel`, `signOutLabel`, `accountLabel`, `accountText`, `appearanceLabel`, `appearanceText`, `sessionLabel`, `sessionText`, `themeLabel`, `themeText`, `presetLabel`, `presetText`.
|
|
512
|
-
- Subpages: `#section-<id>` and `#actions-<id>` get `page`, `pages`, `openPage({ id, label })` and `back()`. With a page open,
|
|
512
|
+
- Subpages: `#section-<id>` and `#actions-<id>` get `page`, `pages`, `openPage({ id, label })` and `back()`. With a page open, the header title becomes the path (`Members > Grace Hopper`, same size, only the last part in the text color, earlier parts are buttons that go back to them), the section description stays, and a Back button (`backLabel`, default `common.back`) shows on the right before `#actions-<id>`. `v-model:pages` binds the stack (it also works unbound). Changing section clears it. Render the detail when `page` is set, the list otherwise.
|
|
513
513
|
- `hide-session` hides the Session group (sign out) in the account section; the Sign out item in the nav stays. `beforeClose` works as on Modal.
|
|
514
514
|
- Accessibility: native modal `<dialog>` (focus trap, Escape, focus returns to the trigger), the nav is a labelled `nav` of buttons with `aria-current` and `aria-controls`, the content is a `section` labelled by its heading.
|
|
515
515
|
|
|
@@ -99,21 +99,44 @@
|
|
|
99
99
|
<header class="k-settings-modal-header">
|
|
100
100
|
<div class="k-settings-modal-heading">
|
|
101
101
|
<h2 :id="`${baseId}-title`" class="k-settings-modal-title">
|
|
102
|
-
|
|
102
|
+
<template v-if="currentPage">
|
|
103
|
+
<template v-for="(crumb, index) in trail" :key="index">
|
|
104
|
+
<button
|
|
105
|
+
type="button"
|
|
106
|
+
class="k-settings-modal-crumb"
|
|
107
|
+
@click="goTo(index)"
|
|
108
|
+
>
|
|
109
|
+
{{ crumb }}
|
|
110
|
+
</button>
|
|
111
|
+
<Icon name="chevron-right" class="k-settings-modal-crumb-separator" />
|
|
112
|
+
</template>
|
|
113
|
+
<span class="k-settings-modal-crumb is-current">
|
|
114
|
+
{{ currentPage.label }}
|
|
115
|
+
</span>
|
|
116
|
+
</template>
|
|
117
|
+
<template v-else>{{ active.label }}</template>
|
|
103
118
|
</h2>
|
|
104
119
|
<p v-if="active.description" class="k-settings-modal-description">
|
|
105
120
|
{{ active.description }}
|
|
106
121
|
</p>
|
|
107
122
|
</div>
|
|
108
|
-
<div
|
|
123
|
+
<div
|
|
124
|
+
v-if="currentPage || $slots[`actions-${active.id}`]"
|
|
125
|
+
class="k-settings-modal-actions"
|
|
126
|
+
>
|
|
127
|
+
<Button
|
|
128
|
+
v-if="currentPage"
|
|
129
|
+
variant="ghost"
|
|
130
|
+
tone="neutral"
|
|
131
|
+
size="sm"
|
|
132
|
+
icon="arrow-left"
|
|
133
|
+
@click="back"
|
|
134
|
+
>
|
|
135
|
+
{{ backText }}
|
|
136
|
+
</Button>
|
|
109
137
|
<slot :name="`actions-${active.id}`" v-bind="slotProps(active, close)" />
|
|
110
138
|
</div>
|
|
111
139
|
</header>
|
|
112
|
-
<Breadcrumbs
|
|
113
|
-
v-if="currentPage"
|
|
114
|
-
class="k-settings-modal-breadcrumbs"
|
|
115
|
-
:items="breadcrumbItems"
|
|
116
|
-
/>
|
|
117
140
|
<div
|
|
118
141
|
ref="contentBody"
|
|
119
142
|
class="k-settings-modal-body"
|
|
@@ -186,7 +209,6 @@ import Icon from "../core/Icon.vue";
|
|
|
186
209
|
import Avatar from "../data/Avatar.vue";
|
|
187
210
|
import Badge from "../data/Badge.vue";
|
|
188
211
|
import Modal from "../overlays/Modal.vue";
|
|
189
|
-
import Breadcrumbs from "../layout/Breadcrumbs.vue";
|
|
190
212
|
import AppearanceSettings from "./AppearanceSettings.vue";
|
|
191
213
|
import SettingsGroup from "./SettingsGroup.vue";
|
|
192
214
|
const props = defineProps({
|
|
@@ -195,6 +217,7 @@ const props = defineProps({
|
|
|
195
217
|
presets: { type: [Array, Boolean], required: false, default: () => THEME_PRESETS },
|
|
196
218
|
title: { type: String, required: false },
|
|
197
219
|
closeLabel: { type: String, required: false },
|
|
220
|
+
backLabel: { type: String, required: false },
|
|
198
221
|
navLabel: { type: String, required: false },
|
|
199
222
|
signOutLabel: { type: String, required: false },
|
|
200
223
|
sessionLabel: { type: String, required: false },
|
|
@@ -219,6 +242,7 @@ const pages = defineModel("pages", { type: Array, ...{ default: () => [] } });
|
|
|
219
242
|
const { t } = useLocale();
|
|
220
243
|
const titleText = computed(() => props.title ?? t("settings.title"));
|
|
221
244
|
const closeText = computed(() => props.closeLabel ?? t("settings.close"));
|
|
245
|
+
const backText = computed(() => props.backLabel ?? t("common.back"));
|
|
222
246
|
const navText = computed(() => props.navLabel ?? t("settings.sections"));
|
|
223
247
|
const signOutText = computed(() => props.signOutLabel ?? t("settings.signOut"));
|
|
224
248
|
const sessionLabelText = computed(() => props.sessionLabel ?? t("settings.session"));
|
|
@@ -276,12 +300,9 @@ function openPage(page) {
|
|
|
276
300
|
function back() {
|
|
277
301
|
goTo(pages.value.length - 1);
|
|
278
302
|
}
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
...pages.value.map((page
|
|
282
|
-
label: page.label,
|
|
283
|
-
onClick: index < pages.value.length - 1 ? () => goTo(index + 1) : void 0
|
|
284
|
-
}))
|
|
303
|
+
const trail = computed(() => [
|
|
304
|
+
active.value?.label ?? "",
|
|
305
|
+
...pages.value.slice(0, -1).map((page) => page.label)
|
|
285
306
|
]);
|
|
286
307
|
function slotProps(item, close) {
|
|
287
308
|
return { section: item, close, page: currentPage.value, pages: pages.value, openPage, back };
|
|
@@ -16,6 +16,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
16
16
|
presets?: readonly ThemePreset[] | false;
|
|
17
17
|
title?: string | undefined;
|
|
18
18
|
closeLabel?: string;
|
|
19
|
+
backLabel?: string;
|
|
19
20
|
navLabel?: string;
|
|
20
21
|
signOutLabel?: string;
|
|
21
22
|
sessionLabel?: string;
|
|
@@ -257,6 +258,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
257
258
|
presets?: readonly ThemePreset[] | false;
|
|
258
259
|
title?: string | undefined;
|
|
259
260
|
closeLabel?: string;
|
|
261
|
+
backLabel?: string;
|
|
260
262
|
navLabel?: string;
|
|
261
263
|
signOutLabel?: string;
|
|
262
264
|
sessionLabel?: string;
|
|
@@ -161,11 +161,6 @@
|
|
|
161
161
|
min-width: 0;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
.k-settings-modal-breadcrumbs {
|
|
165
|
-
flex: none;
|
|
166
|
-
padding: 0 1.5rem 0.75rem;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
164
|
.k-settings-modal-title {
|
|
170
165
|
font-size: 0.9375rem;
|
|
171
166
|
font-weight: var(--k-font-weight-strong, 600);
|
|
@@ -174,6 +169,44 @@
|
|
|
174
169
|
color: var(--k-text);
|
|
175
170
|
}
|
|
176
171
|
|
|
172
|
+
.k-settings-modal-title:has(> .k-settings-modal-crumb) {
|
|
173
|
+
display: flex;
|
|
174
|
+
flex-wrap: wrap;
|
|
175
|
+
align-items: center;
|
|
176
|
+
gap: 0.25rem;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.k-settings-modal-crumb {
|
|
180
|
+
padding: 0;
|
|
181
|
+
font: inherit;
|
|
182
|
+
letter-spacing: inherit;
|
|
183
|
+
color: var(--k-text-muted);
|
|
184
|
+
background: none;
|
|
185
|
+
border: 0;
|
|
186
|
+
border-radius: var(--k-radius-xs);
|
|
187
|
+
cursor: pointer;
|
|
188
|
+
transition: color var(--k-duration) var(--k-ease);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.k-settings-modal-crumb:hover {
|
|
192
|
+
color: var(--k-text);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.k-settings-modal-crumb:focus-visible {
|
|
196
|
+
outline: 2px solid var(--k-ring);
|
|
197
|
+
outline-offset: 2px;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.k-settings-modal-crumb.is-current {
|
|
201
|
+
color: var(--k-text);
|
|
202
|
+
cursor: default;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.k-settings-modal-crumb-separator {
|
|
206
|
+
--k-icon-size: 0.875rem;
|
|
207
|
+
color: var(--k-text-dimmed);
|
|
208
|
+
}
|
|
209
|
+
|
|
177
210
|
.k-settings-modal-description {
|
|
178
211
|
font-size: 0.8125rem;
|
|
179
212
|
line-height: 1.4;
|
|
@@ -478,10 +511,6 @@
|
|
|
478
511
|
padding: 1rem 1rem 0.75rem;
|
|
479
512
|
}
|
|
480
513
|
|
|
481
|
-
.k-settings-modal-breadcrumbs {
|
|
482
|
-
padding-inline: 1rem;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
514
|
.k-settings-modal-body {
|
|
486
515
|
padding: 1rem;
|
|
487
516
|
}
|
package/package.json
CHANGED