@dumiflex/wp-kit 0.6.0 → 0.7.1

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.
@@ -0,0 +1,127 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * SettingRow: one setting, its label and hint on the left and its control on
4
+ * the right. Put it in a SettingGroup.
5
+ *
6
+ * <SettingRow label="Compact density" hint="Tighter rows and chips." for="density">
7
+ * <WpSwitch id="density" v-model="compact" size="md" />
8
+ * </SettingRow>
9
+ *
10
+ * `setting-key` is the row's id, so a settings search can jump to `#key`;
11
+ * `highlighted` flashes the row once (the app sets it when that hash is the
12
+ * target). `stacked` puts the control under the text, for a wide control (a
13
+ * colour picker, a path list); `form` lines rows up as a label column and a
14
+ * control column, like a form. `recommended` names the value most people
15
+ * should pick ("On"). `for` makes the label a real `<label for>`. Slots:
16
+ * `#badge` after the label, `#extra` under the hint (a status line).
17
+ */
18
+ const props = defineProps<{
19
+ label: string;
20
+ hint?: string | undefined;
21
+ settingKey?: string | undefined;
22
+ /** Flash the row once, as the target of a search or a link. */
23
+ highlighted?: boolean | undefined;
24
+ stacked?: boolean | undefined;
25
+ form?: boolean | undefined;
26
+ /** The control's id, so the label is a real <label for>. */
27
+ for?: string | undefined;
28
+ recommended?: string | undefined;
29
+ }>();
30
+ </script>
31
+
32
+ <template>
33
+ <div
34
+ :id="settingKey"
35
+ class="wp-set-row"
36
+ :class="{ 'wp-set-row--stacked': stacked, 'wp-set-row--form': form, 'wp-set-row--target': highlighted }"
37
+ :data-setting="settingKey"
38
+ >
39
+ <div class="wp-set-row__text">
40
+ <label v-if="props.for" class="wp-set-row__label" :for="props.for">{{ label }}<slot name="badge" /></label>
41
+ <span v-else class="wp-set-row__label">{{ label }}<slot name="badge" /></span>
42
+ <p v-if="hint" class="wp-set-row__hint">{{ hint }}</p>
43
+ <p v-if="recommended" class="wp-set-row__rec" data-test="setting-recommended">Recommended: {{ recommended }}</p>
44
+ <slot name="extra" />
45
+ </div>
46
+ <div class="wp-set-row__control">
47
+ <slot />
48
+ </div>
49
+ </div>
50
+ </template>
51
+
52
+ <style scoped>
53
+ .wp-set-row {
54
+ display: flex;
55
+ align-items: center;
56
+ gap: var(--wp-space-6);
57
+ padding: var(--wp-space-5) var(--wp-space-6);
58
+ border-top: 1px solid var(--wp-border);
59
+ scroll-margin-top: 80px;
60
+ }
61
+ .wp-set-row:first-child { border-top: 0; }
62
+ .wp-set-row--stacked { flex-direction: column; align-items: stretch; gap: var(--wp-space-4); }
63
+ .wp-set-row--target { animation: wp-set-row-flash 1.6s ease-out 1; }
64
+ @keyframes wp-set-row-flash {
65
+ 0%, 30% { background: color-mix(in oklab, var(--wp-accent-500) 18%, transparent); }
66
+ 100% { background: transparent; }
67
+ }
68
+ .wp-set-row__text { flex: 1; min-width: 0; }
69
+ .wp-set-row__label {
70
+ display: flex;
71
+ align-items: center;
72
+ gap: var(--wp-space-3);
73
+ font-size: var(--wp-text-sm);
74
+ font-weight: 600;
75
+ color: var(--wp-text);
76
+ }
77
+ .wp-set-row__hint {
78
+ margin: 3px 0 0;
79
+ font-size: var(--wp-text-sm);
80
+ line-height: 1.45;
81
+ color: var(--wp-text-dim);
82
+ }
83
+ .wp-set-row__rec {
84
+ margin: 3px 0 0;
85
+ font-size: var(--wp-text-sm);
86
+ color: var(--wp-accent-300);
87
+ }
88
+ .wp-set-row__control {
89
+ flex: none;
90
+ display: flex;
91
+ align-items: center;
92
+ gap: var(--wp-space-4);
93
+ max-width: 55%;
94
+ /* A long status next to a button wraps instead of pushing it out. */
95
+ flex-wrap: wrap;
96
+ justify-content: flex-end;
97
+ }
98
+ .wp-set-row--stacked .wp-set-row__control { max-width: none; justify-content: flex-start; }
99
+ .wp-set-row__control :deep(.wp-select) { min-width: 200px; }
100
+ .wp-set-row--form {
101
+ display: grid;
102
+ grid-template-columns: 150px minmax(0, 1fr);
103
+ column-gap: var(--wp-space-6);
104
+ row-gap: 4px;
105
+ align-items: center;
106
+ padding: var(--wp-space-4) var(--wp-space-6);
107
+ }
108
+ .wp-set-row--form .wp-set-row__text { display: contents; }
109
+ .wp-set-row--form .wp-set-row__label { grid-column: 1; grid-row: 1; font-weight: 500; color: var(--wp-text-muted); }
110
+ .wp-set-row--form .wp-set-row__control { grid-column: 2; grid-row: 1; max-width: none; justify-content: flex-start; }
111
+ .wp-set-row--form .wp-set-row__hint { grid-column: 2; grid-row: 2; margin: 0; }
112
+ .wp-set-row--form .wp-set-row__rec { grid-column: 2; grid-row: 3; margin: 0; }
113
+ .wp-set-row--form :deep(.wp-set-row__extra) { grid-column: 1 / -1; }
114
+ /* A narrow group (a phone, a page beside the chat) puts every row in one column. */
115
+ @container wp-set-group (max-width: 480px) {
116
+ .wp-set-row { flex-direction: column; align-items: stretch; }
117
+ .wp-set-row__control { max-width: none; justify-content: flex-start; }
118
+ .wp-set-row--form { grid-template-columns: minmax(0, 1fr); }
119
+ .wp-set-row--form .wp-set-row__label,
120
+ .wp-set-row--form .wp-set-row__control,
121
+ .wp-set-row--form .wp-set-row__hint,
122
+ .wp-set-row--form .wp-set-row__rec { grid-column: 1; grid-row: auto; }
123
+ }
124
+ @media (prefers-reduced-motion: reduce) {
125
+ .wp-set-row--target { animation: none; outline: 2px solid var(--wp-accent); outline-offset: -2px; }
126
+ }
127
+ </style>