@dpa-id-components/dpa-shared-components 22.0.0-next.5 → 22.0.0-next.7
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/dist/components/UiBadge/UiBadge.vue.d.ts +1 -1
- package/dist/components/UiInput/UiInput.vue.d.ts +35 -32
- package/dist/components/UiListItem/UiListItem.vue.d.ts +0 -1
- package/dist/components/UiMenu/UiMenu.vue.d.ts +0 -2
- package/dist/dpa-shared-components.js +3189 -3171
- package/dist/src/components/UiBadge/UiBadge.stories.ts +1 -1
- package/dist/src/components/UiBadge/UiBadge.vue +3 -8
- package/dist/src/components/UiButton/UiButton.stories.ts +17 -0
- package/dist/src/components/UiCheckbox/README.md +9 -9
- package/dist/src/components/UiDatePicker/UiDatePicker.spec.ts +2 -2
- package/dist/src/components/UiDatePicker/UiDatePicker.vue +20 -20
- package/dist/src/components/UiIcon/UiIconLoading.vue +8 -1
- package/dist/src/components/UiInput/README.md +28 -17
- package/dist/src/components/UiInput/UiInput.spec.ts +20 -0
- package/dist/src/components/UiInput/UiInput.stories.ts +15 -1
- package/dist/src/components/UiInput/UiInput.vue +7 -4
- package/dist/src/components/UiListItem/README.md +0 -1
- package/dist/src/components/UiListItem/UiListItem.vue +2 -5
- package/dist/src/components/UiMediaTypeIcon/UiMediaTypeIcon.vue +1 -1
- package/dist/src/components/UiMenu/README.md +0 -2
- package/dist/src/components/UiMenu/UiMenu.stories.ts +0 -3
- package/dist/src/components/UiMenu/UiMenu.vue +4 -9
- package/dist/src/components/UiPopover/UiPopover.stories.ts +1 -1
- package/dist/src/components/UiPopover/UiPopover.vue +18 -15
- package/dist/src/components/UiSelect/UiSelect.vue +14 -2
- package/dist/src/components/UiSpinner/UiSpinner.spec.ts +1 -1
- package/dist/src/components/UiSpinner/UiSpinner.stories.ts +1 -1
- package/dist/src/components/UiSpinner/UiSpinner.vue +31 -32
- package/dist/style.css +1 -1
- package/package.json +15 -8
- package/src/components/UiBadge/UiBadge.vue +3 -8
- package/src/components/UiCheckbox/README.md +9 -9
- package/src/components/UiDatePicker/UiDatePicker.vue +20 -20
- package/src/components/UiIcon/UiIconLoading.vue +8 -1
- package/src/components/UiInput/README.md +28 -17
- package/src/components/UiInput/UiInput.vue +7 -4
- package/src/components/UiListItem/README.md +0 -1
- package/src/components/UiListItem/UiListItem.vue +2 -5
- package/src/components/UiMediaTypeIcon/UiMediaTypeIcon.vue +1 -1
- package/src/components/UiMenu/README.md +0 -2
- package/src/components/UiMenu/UiMenu.vue +4 -9
- package/src/components/UiPopover/UiPopover.vue +18 -15
- package/src/components/UiSelect/UiSelect.vue +14 -2
- package/src/components/UiSpinner/UiSpinner.vue +31 -32
|
@@ -16,31 +16,26 @@ import UiIcon, { type UiIconName } from "../UiIcon/UiIcon.vue";
|
|
|
16
16
|
const { appearance = "accent-red", iconName = undefined } = defineProps<{
|
|
17
17
|
appearance?:
|
|
18
18
|
| "accent-red"
|
|
19
|
-
| "accent-red-dark"
|
|
20
19
|
| "accent-orange"
|
|
21
20
|
| "accent-purple"
|
|
22
21
|
| "accent-green"
|
|
23
22
|
| "primary"
|
|
24
23
|
| "neutral-primary"
|
|
25
|
-
| "neutral-emphasis"
|
|
26
24
|
| "neutral-medium"
|
|
27
25
|
| "neutral-faint";
|
|
28
26
|
iconName?: UiIconName;
|
|
29
27
|
}>();
|
|
30
28
|
|
|
31
29
|
const colorClass = computed(() => {
|
|
32
|
-
|
|
30
|
+
return {
|
|
33
31
|
"accent-red": "bg-accent-red text-neutral",
|
|
34
|
-
"accent-red-dark": "bg-accent-red-dark text-neutral",
|
|
35
32
|
"accent-orange": "bg-accent-orange text-neutral",
|
|
36
33
|
"accent-purple": "bg-accent-purple text-neutral",
|
|
37
34
|
"accent-green": "bg-accent-green text-neutral",
|
|
38
35
|
primary: "bg-primary text-neutral",
|
|
39
36
|
"neutral-primary": "bg-neutral-primary text-neutral",
|
|
40
|
-
"neutral-emphasis": "bg-neutral-emphasis text-neutral",
|
|
41
37
|
"neutral-medium": "bg-neutral-medium text-neutral",
|
|
42
|
-
"neutral-faint": "bg-neutral-faint text-neutral-
|
|
43
|
-
};
|
|
44
|
-
return colorClasses[appearance];
|
|
38
|
+
"neutral-faint": "bg-neutral-faint text-neutral-subtle",
|
|
39
|
+
}[appearance];
|
|
45
40
|
});
|
|
46
41
|
</script>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/vue3-vite";
|
|
2
|
+
import { ref } from "vue";
|
|
2
3
|
|
|
3
4
|
import UiIcon from "../UiIcon/UiIcon.vue";
|
|
4
5
|
|
|
@@ -76,3 +77,19 @@ export const IconOnlyAndAriaLabel: Story = {
|
|
|
76
77
|
`,
|
|
77
78
|
}),
|
|
78
79
|
};
|
|
80
|
+
|
|
81
|
+
export const ToggleIcon: Story = {
|
|
82
|
+
render: (args) => ({
|
|
83
|
+
setup() {
|
|
84
|
+
const isVisible = ref(false);
|
|
85
|
+
|
|
86
|
+
return { args, isVisible };
|
|
87
|
+
},
|
|
88
|
+
components: { UiButton, UiIcon },
|
|
89
|
+
template: /*html*/ `
|
|
90
|
+
<UiButton v-bind="args" aria-label="Is visible" @click="isVisible = !isVisible">
|
|
91
|
+
<UiIcon :name="isVisible ? 'view' : 'view-off'" />
|
|
92
|
+
</UiButton>
|
|
93
|
+
`,
|
|
94
|
+
}),
|
|
95
|
+
};
|
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
## Usage
|
|
4
4
|
|
|
5
5
|
```vue
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
</UiCheckbox>
|
|
10
|
-
</template>
|
|
11
|
-
|
|
12
|
-
<script setup lang="ts">
|
|
13
|
-
import { UiCheckbox } from "@dpa-id-components/dpa-shared-components";
|
|
14
|
-
</script>
|
|
6
|
+
<UiCheckbox required name="terms" appearance="secondary">
|
|
7
|
+
Accept terms and conditions
|
|
8
|
+
</UiCheckbox>
|
|
15
9
|
```
|
|
16
10
|
|
|
17
11
|
## API
|
|
18
12
|
|
|
13
|
+
### Models
|
|
14
|
+
|
|
15
|
+
| Name | Type | Default | Description |
|
|
16
|
+
|-----------|--------------------|-------------|----------------------|
|
|
17
|
+
| _default_ | `string[] \| string \| boolean` | `undefined` | Sets the input value |
|
|
18
|
+
|
|
19
19
|
### Props
|
|
20
20
|
|
|
21
21
|
**Note**: This component binds all non-prop attributes (apart from `class`) on its principal element (`input[type="checkbox"]`) instead of the root element. This allows you to add arbitrary HTML attributes (and event listeners) on the principal element without them being explicitly supported by the component.
|
|
@@ -71,7 +71,7 @@ describe("UiDatePicker", () => {
|
|
|
71
71
|
inline: true,
|
|
72
72
|
});
|
|
73
73
|
await flushPromises();
|
|
74
|
-
expect(wrapper.find(".
|
|
74
|
+
expect(wrapper.find(".dp--sidebar-left").exists()).toBe(true);
|
|
75
75
|
expect(wrapper.html()).toContain("Schnellfilter");
|
|
76
76
|
for (const range of quickFilterRanges) {
|
|
77
77
|
expect(wrapper.find(`[data-testid="${range.label}"]`).exists()).toBe(
|
|
@@ -134,7 +134,7 @@ describe("UiDatePicker", () => {
|
|
|
134
134
|
test("should be empty when neither prop nor slot is set", async () => {
|
|
135
135
|
const wrapper = createWrapper({ inline: true });
|
|
136
136
|
|
|
137
|
-
const actionExtra = wrapper.find(".
|
|
137
|
+
const actionExtra = wrapper.find(".dp--action-extra");
|
|
138
138
|
if (actionExtra.exists()) {
|
|
139
139
|
expect(actionExtra.text().trim()).toBe("");
|
|
140
140
|
}
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
<UiIcon class="text-neutral-subtle" name="chevron-right" size="sm" />
|
|
131
131
|
</template>
|
|
132
132
|
<template #arrow>
|
|
133
|
-
<div ref="menuArrow" class="
|
|
133
|
+
<div ref="menuArrow" class="dp--arrow-top"></div>
|
|
134
134
|
</template>
|
|
135
135
|
</VueDatePicker>
|
|
136
136
|
</div>
|
|
@@ -306,17 +306,17 @@ function formatInput(date: Date | [Date, Date]): string {
|
|
|
306
306
|
<style>
|
|
307
307
|
@reference "../../tailwindPreset.css";
|
|
308
308
|
|
|
309
|
-
.
|
|
309
|
+
.dp--arrow-top {
|
|
310
310
|
left: 10%;
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
.
|
|
313
|
+
.dp--menu {
|
|
314
314
|
border-radius: var(--radius-2xl);
|
|
315
315
|
box-shadow: var(--shadow-lg);
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
.dp--year-select,
|
|
319
|
-
.
|
|
319
|
+
.dp--month-year-select {
|
|
320
320
|
border-radius: var(--radius-2xl);
|
|
321
321
|
}
|
|
322
322
|
|
|
@@ -325,45 +325,45 @@ function formatInput(date: Date | [Date, Date]): string {
|
|
|
325
325
|
padding: 0.25rem;
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
.
|
|
328
|
+
.dp--flex-display {
|
|
329
329
|
gap: 2rem;
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
-
.
|
|
332
|
+
.dp--sidebar-left {
|
|
333
333
|
padding: 0;
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
-
.
|
|
336
|
+
.dp--cell-inner {
|
|
337
337
|
border-radius: calc(infinity * 1px);
|
|
338
338
|
}
|
|
339
339
|
|
|
340
|
-
.
|
|
340
|
+
.dp--cell-inner:hover {
|
|
341
341
|
border-radius: calc(infinity * 1px);
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
.
|
|
344
|
+
.dp--today {
|
|
345
345
|
border: 1px solid var(--color-neutral-primary);
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
.
|
|
349
|
-
.
|
|
350
|
-
.
|
|
348
|
+
.dp--cell-auto-range,
|
|
349
|
+
.dp--cell-auto-range-start,
|
|
350
|
+
.dp--cell-auto-range-end {
|
|
351
351
|
border: none;
|
|
352
352
|
color: var(--color-neutral-primary);
|
|
353
353
|
background-color: var(--color-neutral-faint);
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
-
.
|
|
356
|
+
.dp--month-year-select {
|
|
357
357
|
font-size: var(--text-base);
|
|
358
358
|
font-weight: var(--font-weight-semibold);
|
|
359
359
|
color: var(--color-neutral-primary);
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
-
.
|
|
362
|
+
.dp--calendar-header-separator {
|
|
363
363
|
display: none;
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
-
.
|
|
366
|
+
.dp--calendar-header {
|
|
367
367
|
gap: 0.25rem;
|
|
368
368
|
align-items: center;
|
|
369
369
|
font-size: var(--text-xs);
|
|
@@ -371,26 +371,26 @@ function formatInput(date: Date | [Date, Date]): string {
|
|
|
371
371
|
font-weight: var(--font-weight-semibold);
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
-
.
|
|
374
|
+
.dp--calendar-header-item {
|
|
375
375
|
display: flex;
|
|
376
376
|
align-items: center;
|
|
377
377
|
justify-content: center;
|
|
378
378
|
color: var(--color-neutral-subtle);
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
-
.
|
|
381
|
+
.dp--calendar-row {
|
|
382
382
|
gap: 0.25rem;
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
.
|
|
386
|
-
.
|
|
385
|
+
.dp--action-row,
|
|
386
|
+
.dp--action-extra {
|
|
387
387
|
justify-content: end;
|
|
388
388
|
gap: 1rem;
|
|
389
389
|
border-top: 1px solid var(--color-neutral-faint);
|
|
390
390
|
padding: 0.5rem 1rem;
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
.
|
|
393
|
+
.dp--theme-light {
|
|
394
394
|
--dp-font-family: var(--font-sans);
|
|
395
395
|
--dp-month-year-row-height: 2rem; /*Height of the month-year select row*/
|
|
396
396
|
--dp-button-icon-height: 1.5rem; /*Icon sizing in buttons*/
|
|
@@ -3,29 +3,40 @@
|
|
|
3
3
|
## Usage
|
|
4
4
|
|
|
5
5
|
```vue
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
<UiInput
|
|
7
|
+
id="postal-code"
|
|
8
|
+
name="postal_code"
|
|
9
|
+
value="04277"
|
|
10
|
+
required
|
|
11
|
+
placeholder="12345"
|
|
12
|
+
>
|
|
13
|
+
Postal code
|
|
14
|
+
</UiInput>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Using `v-model`**:
|
|
18
|
+
|
|
19
|
+
```vue
|
|
20
|
+
<UiInput v-model="postalCode">
|
|
21
|
+
Postal code
|
|
22
|
+
</UiInput>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**With `number` value**:
|
|
26
|
+
|
|
27
|
+
```vue
|
|
28
|
+
<UiInput v-model="count" type="number">
|
|
29
|
+
Count
|
|
30
|
+
</UiInput>
|
|
20
31
|
```
|
|
21
32
|
|
|
22
33
|
## API
|
|
23
34
|
|
|
24
35
|
### Models
|
|
25
36
|
|
|
26
|
-
| Name | Type
|
|
27
|
-
|
|
28
|
-
| _default_ | `string` | `undefined` | Sets the input value |
|
|
37
|
+
| Name | Type | Default | Description |
|
|
38
|
+
|-----------|--------------------|-------------|----------------------|
|
|
39
|
+
| _default_ | `string \| number` | `undefined` | Sets the input value |
|
|
29
40
|
|
|
30
41
|
### Props
|
|
31
42
|
|
|
@@ -205,4 +205,24 @@ describe("UiInput", () => {
|
|
|
205
205
|
await wrapper.setProps({ modelValue: "" });
|
|
206
206
|
expect(input.element.value).toBe("");
|
|
207
207
|
});
|
|
208
|
+
|
|
209
|
+
test("works with number model", async () => {
|
|
210
|
+
const wrapper = mount(UiInput, {
|
|
211
|
+
props: {
|
|
212
|
+
type: "number",
|
|
213
|
+
modelValue: 1,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const input = wrapper.find("input");
|
|
218
|
+
expect(input.element.value).toBe("1");
|
|
219
|
+
|
|
220
|
+
await input.setValue(2);
|
|
221
|
+
expect(input.element.value).toBe("2");
|
|
222
|
+
expect((wrapper.emitted("update:modelValue") ?? []).at(-1)).toEqual([2]);
|
|
223
|
+
|
|
224
|
+
await input.setValue(3);
|
|
225
|
+
expect(input.element.value).toBe("3");
|
|
226
|
+
expect((wrapper.emitted("update:modelValue") ?? []).at(-1)).toEqual([3]);
|
|
227
|
+
});
|
|
208
228
|
});
|
|
@@ -17,6 +17,7 @@ type PropsAndCustomArgs = ComponentPropsAndSlots<typeof UiInput> & {
|
|
|
17
17
|
|
|
18
18
|
const meta = {
|
|
19
19
|
title: "forms/UiInput",
|
|
20
|
+
// @ts-expect-error generic components seem to cause type issues here that aren't easy to solve
|
|
20
21
|
component: UiInput,
|
|
21
22
|
args: {
|
|
22
23
|
// Attributes
|
|
@@ -84,7 +85,7 @@ export const Placeholder: Story = {
|
|
|
84
85
|
},
|
|
85
86
|
};
|
|
86
87
|
|
|
87
|
-
export const
|
|
88
|
+
export const StringValue: Story = {
|
|
88
89
|
args: {
|
|
89
90
|
// Props
|
|
90
91
|
modelValue: "Text value",
|
|
@@ -94,6 +95,19 @@ export const Value: Story = {
|
|
|
94
95
|
},
|
|
95
96
|
};
|
|
96
97
|
|
|
98
|
+
export const NumberValue: Story = {
|
|
99
|
+
args: {
|
|
100
|
+
// Attributes
|
|
101
|
+
type: "number",
|
|
102
|
+
|
|
103
|
+
// Props
|
|
104
|
+
modelValue: 2,
|
|
105
|
+
|
|
106
|
+
// Slots
|
|
107
|
+
default: "Count",
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
97
111
|
export const Errors: Story = {
|
|
98
112
|
args: {
|
|
99
113
|
// Props
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
data-testid="input-value"
|
|
35
35
|
v-bind="{ ...$attrs, class: null }"
|
|
36
36
|
:data-is-label-raised="
|
|
37
|
-
$attrs.placeholder || isFocused ||
|
|
37
|
+
$attrs.placeholder || isFocused || hasInput ? '' : undefined
|
|
38
38
|
"
|
|
39
39
|
@focus="isFocused = true"
|
|
40
40
|
@blur="isFocused = false"
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
data-testid="input-value"
|
|
56
56
|
v-bind="{ ...$attrs, class: null }"
|
|
57
57
|
:data-is-label-raised="
|
|
58
|
-
$attrs.placeholder || isFocused ||
|
|
58
|
+
$attrs.placeholder || isFocused || hasInput ? '' : undefined
|
|
59
59
|
"
|
|
60
60
|
@focus="isFocused = true"
|
|
61
61
|
@blur="isFocused = false"
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
</div>
|
|
83
83
|
</template>
|
|
84
84
|
|
|
85
|
-
<script setup lang="ts">
|
|
85
|
+
<script setup lang="ts" generic="ModelValue extends string | number">
|
|
86
86
|
import { computed, ref, useId } from "vue";
|
|
87
87
|
|
|
88
88
|
import { cn } from "../../utils/cn.ts";
|
|
@@ -130,8 +130,11 @@ const {
|
|
|
130
130
|
inputStatus?: "info" | "warning" | "error";
|
|
131
131
|
}>();
|
|
132
132
|
|
|
133
|
-
const model = defineModel<
|
|
133
|
+
const model = defineModel<ModelValue>();
|
|
134
134
|
|
|
135
|
+
const hasInput = computed(
|
|
136
|
+
() => model.value !== undefined && model.value !== "",
|
|
137
|
+
);
|
|
135
138
|
const isFocused = ref(false);
|
|
136
139
|
|
|
137
140
|
const defaultId = useId();
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
| `imageSrc` | `String` | `""` | Image to be displayed at the beginning of the list item. |
|
|
32
32
|
| `imageShape` | `"rounded" | "square"` | `"square"` | Shape pf the image to be displayed. |
|
|
33
33
|
| `checkboxColor` | `"blue" | "gray"` | `"blue"` | Checkbox color style. |
|
|
34
|
-
| `checkboxSize` | `"small" | "medium"` | `"medium"` | Checkbox size style. |
|
|
35
34
|
|
|
36
35
|
### Events
|
|
37
36
|
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
<li
|
|
3
3
|
:class="
|
|
4
4
|
cn(
|
|
5
|
-
'flex cursor-pointer list-none items-center gap-2 px-4 py-
|
|
5
|
+
'flex cursor-pointer list-none items-center gap-2 px-4 py-1.5 text-sm/normal text-neutral-emphasis select-none hover:text-primary focus:outline-hidden focus-visible:focus-outline focus-visible:-outline-offset-2',
|
|
6
6
|
{
|
|
7
7
|
'cursor-default text-neutral-medium': disabled,
|
|
8
8
|
'is-selected': selected,
|
|
9
|
-
'py-3': checkboxSize === 'md',
|
|
10
9
|
},
|
|
11
10
|
overrideClasses,
|
|
12
11
|
$attrs.class,
|
|
@@ -20,7 +19,7 @@
|
|
|
20
19
|
:appearance="checkboxAppearance"
|
|
21
20
|
:model-value="isChecked"
|
|
22
21
|
:disabled="disabled"
|
|
23
|
-
|
|
22
|
+
size="sm"
|
|
24
23
|
@click.stop="$emit('list-item-click', value)"
|
|
25
24
|
>
|
|
26
25
|
<span class="sr-only"><slot /></span>
|
|
@@ -65,7 +64,6 @@ const {
|
|
|
65
64
|
imageSrc = undefined,
|
|
66
65
|
imageShape = "rounded",
|
|
67
66
|
checkboxAppearance = "primary",
|
|
68
|
-
checkboxSize = "md",
|
|
69
67
|
isChecked = false,
|
|
70
68
|
disabled = false,
|
|
71
69
|
} = defineProps<{
|
|
@@ -79,7 +77,6 @@ const {
|
|
|
79
77
|
imageShape?: "rounded" | "square";
|
|
80
78
|
iconSize?: "sm" | "md" | "lg";
|
|
81
79
|
checkboxAppearance?: "primary" | "secondary";
|
|
82
|
-
checkboxSize?: "sm" | "md";
|
|
83
80
|
isChecked?: boolean;
|
|
84
81
|
disabled?: boolean;
|
|
85
82
|
}>();
|
|
@@ -89,7 +89,6 @@ const options = ref([
|
|
|
89
89
|
| `buttonAppearance` | `"primary"`, `"secondary"`, `"secondary-alt"`, or `"ghost"` | `"secondary-alt"` | |
|
|
90
90
|
| `listVariant` | `"checkbox" | "selectable" | "blank"` | `"blank"` | Menu style. |
|
|
91
91
|
| `checkboxColor` | `"blue" | "gray"` | `"blue"` | Checkbox color style. |
|
|
92
|
-
| `checkboxSize` | `"small" | "medium"` | `"medium"` | Checkbox size style. |
|
|
93
92
|
| `imageShape` | `"rounded" | "square"` | `"square"` | shape of image. |
|
|
94
93
|
| `hasResetOption` | `boolean` | `false` | Toggles option for a reset button |
|
|
95
94
|
| `resetLabel` | `string` | `""` | Sets text of reset button. |
|
|
@@ -142,7 +141,6 @@ Wraps the UiListItem and uses the same settings as in the original UiMenu, helps
|
|
|
142
141
|
| `listVariant?` | `"checkbox" | "selectable" | "blank"` | `blank` | Provide the list variant, same as in UiMenu.vue |
|
|
143
142
|
| `iconSize?` | `"small" | "medium" | "large"` | `small` | Provide the icon size, same as in UiMenu.vue |
|
|
144
143
|
| `imageShape?` | `"rounded" | "square"` | `square` | Provide the imageShape, same as in UiMenu.vue |
|
|
145
|
-
| `checkboxSize?` | `"small" | "medium"` | `medium` | Provide the checkboxSize, same as in UiMenu.vue |
|
|
146
144
|
| `checkboxColor?` | `"blue" | "gray"` | `blue` | Provide the checkboxColor, same as in UiMenu.vue |
|
|
147
145
|
|
|
148
146
|
#### Slots
|
|
@@ -48,7 +48,6 @@ const meta = {
|
|
|
48
48
|
// Menu
|
|
49
49
|
iconSize: "sm",
|
|
50
50
|
imageShape: "square",
|
|
51
|
-
checkboxSize: "md",
|
|
52
51
|
checkboxAppearance: "primary",
|
|
53
52
|
listVariant: "blank",
|
|
54
53
|
},
|
|
@@ -137,7 +136,6 @@ export const GroupedOptions: Story = {
|
|
|
137
136
|
searchPlaceholder: "Suchen",
|
|
138
137
|
buttonAppearance: "secondary-alt",
|
|
139
138
|
listVariant: "checkbox",
|
|
140
|
-
checkboxSize: "sm",
|
|
141
139
|
defaultTitle: "Optionen",
|
|
142
140
|
hasAutoFocus: true,
|
|
143
141
|
},
|
|
@@ -325,6 +323,5 @@ export const WithImages: Story = {
|
|
|
325
323
|
}),
|
|
326
324
|
args: {
|
|
327
325
|
listVariant: "checkbox",
|
|
328
|
-
checkboxSize: "sm",
|
|
329
326
|
},
|
|
330
327
|
};
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
</template>
|
|
27
27
|
|
|
28
28
|
<div
|
|
29
|
-
class="block w-max max-w-full divide-y overflow-hidden rounded-
|
|
29
|
+
class="block w-max max-w-full divide-y overflow-hidden rounded-lg border border-neutral-faint bg-neutral text-base/6 shadow-md focus:outline-hidden sm:text-sm/5"
|
|
30
30
|
>
|
|
31
31
|
<div
|
|
32
32
|
v-if="hasSearch"
|
|
33
|
-
class="flex items-center gap-2 rounded-t-
|
|
33
|
+
class="flex items-center gap-2 rounded-t-lg px-4 pt-2.5 pb-1.5 text-neutral-primary [&:has(>input:focus-visible)]:focus-outline [&:has(>input:focus-visible)]:-outline-offset-2"
|
|
34
34
|
>
|
|
35
35
|
<UiIcon
|
|
36
36
|
class="shrink-0 text-neutral-emphasis"
|
|
@@ -51,7 +51,6 @@
|
|
|
51
51
|
<slot
|
|
52
52
|
v-bind="{
|
|
53
53
|
checkboxAppearance,
|
|
54
|
-
checkboxSize,
|
|
55
54
|
iconSize,
|
|
56
55
|
imageShape,
|
|
57
56
|
listVariant,
|
|
@@ -71,7 +70,7 @@
|
|
|
71
70
|
<template v-if="group.options.length > 0">
|
|
72
71
|
<li
|
|
73
72
|
v-if="group.groupLabel"
|
|
74
|
-
class="flex h-6 items-center bg-neutral-
|
|
73
|
+
class="flex h-6 items-center bg-neutral-faint px-4 text-xs font-semibold tracking-wider text-neutral-subtle uppercase"
|
|
75
74
|
>
|
|
76
75
|
{{ group.groupLabel }}
|
|
77
76
|
</li>
|
|
@@ -87,7 +86,6 @@
|
|
|
87
86
|
:image-shape="imageShape"
|
|
88
87
|
:image-src="option.imageSrc"
|
|
89
88
|
:icon-name="option.iconName"
|
|
90
|
-
:checkbox-size="checkboxSize"
|
|
91
89
|
:checkbox-appearance="checkboxAppearance"
|
|
92
90
|
class="hover:bg-neutral-whisper focus:bg-neutral-faint"
|
|
93
91
|
:class="{
|
|
@@ -102,7 +100,7 @@
|
|
|
102
100
|
</ul>
|
|
103
101
|
</slot>
|
|
104
102
|
|
|
105
|
-
<div v-if="hasResetOption" class="px-
|
|
103
|
+
<div v-if="hasResetOption" class="px-2 pt-1.5 pb-2 text-neutral-primary">
|
|
106
104
|
<UiButton
|
|
107
105
|
appearance="secondary"
|
|
108
106
|
:disabled="disabledReset"
|
|
@@ -154,7 +152,6 @@ export type UiMenuGroupedOption<Value = unknown> = {
|
|
|
154
152
|
defineSlots<{
|
|
155
153
|
default?: (props: {
|
|
156
154
|
checkboxAppearance: typeof checkboxAppearance;
|
|
157
|
-
checkboxSize: typeof checkboxSize;
|
|
158
155
|
iconSize: typeof iconSize;
|
|
159
156
|
imageShape: typeof imageShape;
|
|
160
157
|
listVariant: typeof listVariant;
|
|
@@ -192,7 +189,6 @@ const {
|
|
|
192
189
|
// Menu
|
|
193
190
|
iconSize = "sm",
|
|
194
191
|
imageShape = "square",
|
|
195
|
-
checkboxSize = "md",
|
|
196
192
|
checkboxAppearance = "primary",
|
|
197
193
|
listVariant = "blank",
|
|
198
194
|
} = defineProps<{
|
|
@@ -222,7 +218,6 @@ const {
|
|
|
222
218
|
// Menu
|
|
223
219
|
iconSize?: "sm" | "md" | "lg";
|
|
224
220
|
imageShape?: "rounded" | "square";
|
|
225
|
-
checkboxSize?: "sm" | "md";
|
|
226
221
|
checkboxAppearance?: "primary" | "secondary";
|
|
227
222
|
listVariant?: "checkbox" | "selectable" | "blank";
|
|
228
223
|
}>();
|
|
@@ -29,7 +29,7 @@ const meta = {
|
|
|
29
29
|
</template>
|
|
30
30
|
|
|
31
31
|
<template #default="{ close }">
|
|
32
|
-
<div class="space-y-2 rounded-
|
|
32
|
+
<div class="space-y-2 rounded-lg border border-neutral-faint bg-neutral p-2 shadow-md">
|
|
33
33
|
<p>Popover content</p>
|
|
34
34
|
|
|
35
35
|
<UiButton @click="close">
|
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
ref="reference"
|
|
4
|
-
v-click-away="
|
|
5
|
-
() => {
|
|
6
|
-
if (isOpen) {
|
|
7
|
-
close();
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
"
|
|
11
|
-
class="w-fit"
|
|
12
|
-
@click="update"
|
|
13
|
-
>
|
|
2
|
+
<div ref="reference" class="w-fit" @click="update">
|
|
14
3
|
<slot name="button" v-bind="{ open, close, toggle, isOpen }" />
|
|
15
4
|
|
|
16
5
|
<Transition :name="animate ? 'fade-up' : 'none'">
|
|
@@ -18,7 +7,7 @@
|
|
|
18
7
|
v-show="isOpen"
|
|
19
8
|
ref="floating"
|
|
20
9
|
:style="floatingStyles"
|
|
21
|
-
class="z-10 w-fit
|
|
10
|
+
class="z-10 w-fit [text-align:initial] [--transition-close-duration:100ms] [--transition-duration:200ms]"
|
|
22
11
|
:data-side="placement"
|
|
23
12
|
>
|
|
24
13
|
<slot v-bind="{ close }" />
|
|
@@ -36,10 +25,9 @@ import {
|
|
|
36
25
|
shift,
|
|
37
26
|
useFloating,
|
|
38
27
|
} from "@floating-ui/vue";
|
|
28
|
+
import { onClickOutside } from "@vueuse/core";
|
|
39
29
|
import { ref, useTemplateRef, watch } from "vue";
|
|
40
30
|
|
|
41
|
-
import { vClickAway } from "../../directives/vClickAway.ts";
|
|
42
|
-
|
|
43
31
|
defineSlots<{
|
|
44
32
|
button: (props: {
|
|
45
33
|
open: typeof open;
|
|
@@ -103,6 +91,21 @@ function toggle() {
|
|
|
103
91
|
isOpen.value = !isOpen.value;
|
|
104
92
|
}
|
|
105
93
|
|
|
94
|
+
onClickOutside(
|
|
95
|
+
floating,
|
|
96
|
+
() => {
|
|
97
|
+
if (isOpen.value) {
|
|
98
|
+
close();
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
ignore: [
|
|
103
|
+
// Ignore clicks on the reference element
|
|
104
|
+
reference,
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
);
|
|
108
|
+
|
|
106
109
|
defineExpose({ open, close });
|
|
107
110
|
</script>
|
|
108
111
|
|