@nexxtmove/ui 1.52.0 → 1.54.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/dist/components/atoms/EnergyLabel/EnergyLabel.vue.d.ts +16 -2
- package/dist/components/editor/composables/useRadioGrid.d.ts +48 -0
- package/dist/components/editor/molecules/EditorAlignItems/EditorAlignItems.vue.d.ts +2 -2
- package/dist/components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.vue.d.ts +101 -0
- package/dist/components/editor/molecules/EditorGap/EditorGap.vue.d.ts +32 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1568 -1196
- package/dist/nuxt.js +1 -0
- package/dist/ui.css +2 -1
- package/package.json +1 -1
- package/src/components/atoms/EnergyLabel/EnergyLabel.vue +50 -10
- package/src/components/editor/composables/useRadioGrid.ts +155 -0
- package/src/components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.vue +515 -0
- package/src/components/editor/molecules/EditorAnchor/EditorAnchor.vue +25 -41
- package/src/components/editor/molecules/EditorAnchor/__snapshots__/EditorAnchor.test.ts.snap +65 -0
- package/src/components/editor/molecules/EditorGap/EditorGap.vue +76 -2
- package/src/components/editor/molecules/EditorGap/__snapshots__/EditorGap.test.ts.snap +103 -0
- package/src/components.json +1 -0
- package/src/index.ts +10 -0
- package/src/nuxt.ts +6 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`EditorAnchor markup > renders unchanged with a chosen cell 1`] = `
|
|
4
|
+
"<!--v-if-->
|
|
5
|
+
<!--
|
|
6
|
+
\`w-fit\`: the grid columns are fractions, so in block flow the ring would
|
|
7
|
+
stretch to the full width of the parent.
|
|
8
|
+
-->
|
|
9
|
+
<div role="radiogroup" aria-label="Plek van de afbeelding" aria-describedby="hint" class="grid w-fit grid-cols-3 gap-1 rounded-lg p-1 ring ring-gray-200">
|
|
10
|
+
<!--
|
|
11
|
+
No \`focus:outline-none\` next to the focus-visible outline: in Tailwind v4
|
|
12
|
+
it sets the outline style to none, which the focus-visible variant does
|
|
13
|
+
not set back, so the ring would never show. The outline is -600, not
|
|
14
|
+
-500: -500 reaches 2.78:1 on white, short of the 3:1 for non-text.
|
|
15
|
+
--><button type="button" role="radio" aria-checked="false" aria-label="Linksboven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Boven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechtsboven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Links" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Midden" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechts" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Linksonder" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Onder" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="true" aria-label="Rechtsonder" tabindex="0" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none bg-cornflower-blue-600 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-2.5 bg-white"></span></button>
|
|
16
|
+
</div>"
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
exports[`EditorAnchor markup > renders unchanged with a visible label 1`] = `
|
|
20
|
+
"<p id="v-0" class="mb-1.5 small-normal text-gray-900">Plek van de afbeelding</p>
|
|
21
|
+
<!--
|
|
22
|
+
\`w-fit\`: the grid columns are fractions, so in block flow the ring would
|
|
23
|
+
stretch to the full width of the parent.
|
|
24
|
+
-->
|
|
25
|
+
<div role="radiogroup" aria-labelledby="v-0" aria-describedby="hint" class="grid w-fit grid-cols-3 gap-1 rounded-lg p-1 ring ring-gray-200">
|
|
26
|
+
<!--
|
|
27
|
+
No \`focus:outline-none\` next to the focus-visible outline: in Tailwind v4
|
|
28
|
+
it sets the outline style to none, which the focus-visible variant does
|
|
29
|
+
not set back, so the ring would never show. The outline is -600, not
|
|
30
|
+
-500: -500 reaches 2.78:1 on white, short of the 3:1 for non-text.
|
|
31
|
+
--><button type="button" role="radio" aria-checked="false" aria-label="Linksboven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Boven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechtsboven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Links" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="true" aria-label="Midden" tabindex="0" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none bg-cornflower-blue-600 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-2.5 bg-white"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechts" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Linksonder" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Onder" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechtsonder" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button>
|
|
32
|
+
</div>"
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
exports[`EditorAnchor markup > renders unchanged with disabled 1`] = `
|
|
36
|
+
"<!--v-if-->
|
|
37
|
+
<!--
|
|
38
|
+
\`w-fit\`: the grid columns are fractions, so in block flow the ring would
|
|
39
|
+
stretch to the full width of the parent.
|
|
40
|
+
-->
|
|
41
|
+
<div role="radiogroup" aria-label="Plek van de afbeelding" aria-describedby="hint" aria-disabled="true" class="grid w-fit grid-cols-3 gap-1 rounded-lg p-1 ring ring-gray-200 opacity-50">
|
|
42
|
+
<!--
|
|
43
|
+
No \`focus:outline-none\` next to the focus-visible outline: in Tailwind v4
|
|
44
|
+
it sets the outline style to none, which the focus-visible variant does
|
|
45
|
+
not set back, so the ring would never show. The outline is -600, not
|
|
46
|
+
-500: -500 reaches 2.78:1 on white, short of the 3:1 for non-text.
|
|
47
|
+
--><button type="button" role="radio" aria-checked="true" aria-label="Linksboven" tabindex="0" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none bg-cornflower-blue-600 cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-2.5 bg-white"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Boven" tabindex="-1" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechtsboven" tabindex="-1" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Links" tabindex="-1" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Midden" tabindex="-1" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechts" tabindex="-1" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Linksonder" tabindex="-1" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Onder" tabindex="-1" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechtsonder" tabindex="-1" disabled="" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none cursor-not-allowed"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button>
|
|
48
|
+
</div>"
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
exports[`EditorAnchor markup > renders unchanged with no choice 1`] = `
|
|
52
|
+
"<!--v-if-->
|
|
53
|
+
<!--
|
|
54
|
+
\`w-fit\`: the grid columns are fractions, so in block flow the ring would
|
|
55
|
+
stretch to the full width of the parent.
|
|
56
|
+
-->
|
|
57
|
+
<div role="radiogroup" aria-label="Plek van de afbeelding" aria-describedby="hint" class="grid w-fit grid-cols-3 gap-1 rounded-lg p-1 ring ring-gray-200">
|
|
58
|
+
<!--
|
|
59
|
+
No \`focus:outline-none\` next to the focus-visible outline: in Tailwind v4
|
|
60
|
+
it sets the outline style to none, which the focus-visible variant does
|
|
61
|
+
not set back, so the ring would never show. The outline is -600, not
|
|
62
|
+
-500: -500 reaches 2.78:1 on white, short of the 3:1 for non-text.
|
|
63
|
+
--><button type="button" role="radio" aria-checked="false" aria-label="Linksboven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Boven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechtsboven" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Links" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Midden" tabindex="0" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechts" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Linksonder" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Onder" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button><button type="button" role="radio" aria-checked="false" aria-label="Rechtsonder" tabindex="-1" class="flex size-7 items-center justify-center rounded-md outline-cornflower-blue-600 transition-colors duration-150 ease-out focus-visible:outline-2 motion-reduce:transition-none hover:bg-gray-100 cursor-pointer"><span aria-hidden="true" class="rounded-full transition-colors duration-150 ease-out motion-reduce:transition-none size-1.5 bg-gray-400"></span></button>
|
|
64
|
+
</div>"
|
|
65
|
+
`;
|
|
@@ -33,10 +33,25 @@ export const EDITOR_GAP_STEPS = [
|
|
|
33
33
|
*/
|
|
34
34
|
export type EditorGapValue = `gap-${(typeof EDITOR_GAP_STEPS)[number]['token']}`
|
|
35
35
|
|
|
36
|
-
/** Overridable copy
|
|
36
|
+
/** Overridable copy. Every key is optional. */
|
|
37
37
|
export interface EditorGapMessages {
|
|
38
38
|
/** Unit shown behind the value. Defaults to `'px'`. */
|
|
39
39
|
unit?: string
|
|
40
|
+
/** The fixed option, with the `auto` model bound. Defaults to `'Vast'`. */
|
|
41
|
+
fixed?: string
|
|
42
|
+
/** The auto option, with the `auto` model bound. Defaults to `'Auto'`. */
|
|
43
|
+
auto?: string
|
|
44
|
+
/**
|
|
45
|
+
* Name of the slider while Auto is on, when the gap is a minimum rather than
|
|
46
|
+
* the gap itself. Defaults to `'Tussenruimte, minimaal'`; on Vast the slider
|
|
47
|
+
* is named by `label`.
|
|
48
|
+
*/
|
|
49
|
+
minimumName?: string
|
|
50
|
+
/**
|
|
51
|
+
* Name of the Vast | Auto toolbar, so it is not named like the slider.
|
|
52
|
+
* Defaults to `'Soort tussenruimte'`.
|
|
53
|
+
*/
|
|
54
|
+
modeName?: string
|
|
40
55
|
}
|
|
41
56
|
|
|
42
57
|
export interface NexxtEditorGapProps {
|
|
@@ -55,6 +70,10 @@ export interface NexxtEditorGapProps {
|
|
|
55
70
|
|
|
56
71
|
const DEFAULT_MESSAGES = {
|
|
57
72
|
unit: 'px',
|
|
73
|
+
fixed: 'Vast',
|
|
74
|
+
auto: 'Auto',
|
|
75
|
+
minimumName: 'Tussenruimte, minimaal',
|
|
76
|
+
modeName: 'Soort tussenruimte',
|
|
58
77
|
} satisfies Required<EditorGapMessages>
|
|
59
78
|
</script>
|
|
60
79
|
|
|
@@ -62,6 +81,7 @@ const DEFAULT_MESSAGES = {
|
|
|
62
81
|
import { computed } from 'vue'
|
|
63
82
|
import NexxtEditorSettingsBlock from '../../atoms/EditorSettingsBlock/EditorSettingsBlock.vue'
|
|
64
83
|
import NexxtSlider from '../../../atoms/Slider/Slider.vue'
|
|
84
|
+
import NexxtToggleGroup from '../../../molecules/ToggleGroup/ToggleGroup.vue'
|
|
65
85
|
|
|
66
86
|
defineOptions({ name: 'NexxtEditorGap' })
|
|
67
87
|
|
|
@@ -70,6 +90,38 @@ const { label = 'Tussenruimte', messages } = defineProps<NexxtEditorGapProps>()
|
|
|
70
90
|
/** The selected gap, as the Tailwind class to apply. */
|
|
71
91
|
const model = defineModel<EditorGapValue>({ required: true })
|
|
72
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Optional: whether the main axis distributes the space (Auto). Only when it
|
|
95
|
+
* is bound does the block offer Vast | Auto above the slider; the slider then
|
|
96
|
+
* sets the minimum gap. The component writes nothing else for Auto, and the
|
|
97
|
+
* gap model does not change when it is switched.
|
|
98
|
+
*/
|
|
99
|
+
// `default: undefined` on purpose: a boolean prop without a default is cast to
|
|
100
|
+
// `false` when it is absent, and then an unbound model could not be told apart
|
|
101
|
+
// from Auto switched off.
|
|
102
|
+
const auto = defineModel<boolean>('auto', { default: undefined })
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Bound by the consumer: an unbound model stays `undefined`. The template
|
|
106
|
+
* renders two whole branches rather than `v-if`s inside one, so without it the
|
|
107
|
+
* markup is exactly what it always was, without even an empty comment node.
|
|
108
|
+
*/
|
|
109
|
+
const offersAuto = computed(() => auto.value !== undefined)
|
|
110
|
+
|
|
111
|
+
const autoOptions = computed(() => [
|
|
112
|
+
{ value: 'fixed', label: copy.value.fixed },
|
|
113
|
+
{ value: 'auto', label: copy.value.auto },
|
|
114
|
+
])
|
|
115
|
+
|
|
116
|
+
const autoChoice = computed({
|
|
117
|
+
get: () => (auto.value ? 'auto' : 'fixed'),
|
|
118
|
+
set: (value: string) => {
|
|
119
|
+
auto.value = value === 'auto'
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
const sliderName = computed(() => (auto.value ? copy.value.minimumName : label))
|
|
124
|
+
|
|
73
125
|
const copy = computed(() => ({ ...DEFAULT_MESSAGES, ...messages }))
|
|
74
126
|
|
|
75
127
|
const maxIndex = EDITOR_GAP_STEPS.length - 1
|
|
@@ -101,7 +153,29 @@ const displayValue = computed(() => `${EDITOR_GAP_STEPS[stepIndex.value].px} ${c
|
|
|
101
153
|
|
|
102
154
|
<template>
|
|
103
155
|
<NexxtEditorSettingsBlock :label="label">
|
|
104
|
-
<div class="flex
|
|
156
|
+
<div v-if="offersAuto" class="flex flex-col gap-3">
|
|
157
|
+
<NexxtToggleGroup v-model="autoChoice" :options="autoOptions" :aria-label="copy.modeName" />
|
|
158
|
+
|
|
159
|
+
<!--
|
|
160
|
+
The slider and readout exactly as below, see the notes there, so they
|
|
161
|
+
keep their width and place on Vast, on Auto and without the model. Only
|
|
162
|
+
the slider's name changes with Auto.
|
|
163
|
+
-->
|
|
164
|
+
<div class="flex items-center gap-4">
|
|
165
|
+
<NexxtSlider
|
|
166
|
+
v-model="sliderValue"
|
|
167
|
+
:min="0"
|
|
168
|
+
:max="maxIndex"
|
|
169
|
+
:step="1"
|
|
170
|
+
:aria-label="sliderName"
|
|
171
|
+
:aria-valuetext="displayValue"
|
|
172
|
+
/>
|
|
173
|
+
<span class="min-w-12 shrink-0 text-right small-normal whitespace-nowrap text-gray-700">
|
|
174
|
+
{{ displayValue }}
|
|
175
|
+
</span>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
<div v-else class="flex items-center gap-4">
|
|
105
179
|
<!--
|
|
106
180
|
Slider's own `showValue` prints its model, which here is the step index
|
|
107
181
|
rather than the gap, so the readout is rendered next to it instead. The
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`EditorGap markup without auto > renders unchanged with a value on the scale 1`] = `
|
|
4
|
+
"<div class="py-4">
|
|
5
|
+
<!--
|
|
6
|
+
Switch.vue sets \`inheritAttrs: false\` and binds \`$attrs\` on its sr-only
|
|
7
|
+
input, so a class on <Switch> never reaches its root <label>. The child
|
|
8
|
+
variant below styles that label from the header instead, which keeps the
|
|
9
|
+
whole row clickable and the accessible name on the real <label>. The gap
|
|
10
|
+
has to go on that label too: the header has a single child in both modes,
|
|
11
|
+
so its own \`gap\` would never apply and the spacing would silently fall
|
|
12
|
+
back to the \`gap-2\` that Switch.vue sets for itself.
|
|
13
|
+
-->
|
|
14
|
+
<div class="flex items-center [&>label]:flex [&>label]:w-full [&>label]:gap-3">
|
|
15
|
+
<p class="small-normal text-gray-900">Tussenruimte</p>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="grid grid-rows-[1fr]">
|
|
18
|
+
<!--
|
|
19
|
+
\`overflow-hidden\` is what makes the 0fr collapse clip, but it also clips
|
|
20
|
+
a focus ring on a full-width control in the slot, and the block has no
|
|
21
|
+
horizontal padding of its own. \`-mx-1\` widens the clipping box by 4px on
|
|
22
|
+
each side and the \`px-1\` below pushes the content back, so the ring has
|
|
23
|
+
room while the content keeps the same x position as the label.
|
|
24
|
+
-->
|
|
25
|
+
<div class="-mx-1 min-h-0 overflow-hidden opacity-100">
|
|
26
|
+
<!-- Padding sits on the inner element so nothing is left over at 0fr. -->
|
|
27
|
+
<div class="px-1 pt-1.5 pb-1">
|
|
28
|
+
<div class="flex items-center gap-4">
|
|
29
|
+
<!--
|
|
30
|
+
Slider's own \`showValue\` prints its model, which here is the step index
|
|
31
|
+
rather than the gap, so the readout is rendered next to it instead. The
|
|
32
|
+
thumb has the same problem in \`aria-valuenow\`, which \`aria-valuetext\`
|
|
33
|
+
overrides with the string the readout shows. The block label is a <p>,
|
|
34
|
+
not a <label>, so the name goes on the thumb explicitly.
|
|
35
|
+
-->
|
|
36
|
+
<div class="flex w-full flex-col gap-2">
|
|
37
|
+
<!--v-if-->
|
|
38
|
+
<div class="flex items-center gap-4"><span data-slider-impl="" dir="ltr" data-orientation="horizontal" style="--reka-slider-thumb-transform: translateX(-50%);" class="relative flex w-full touch-none items-center select-none cursor-pointer" aria-disabled="false"><span data-orientation="horizontal" class="relative w-full grow rounded-full bg-gray-200 h-1"><span data-orientation="horizontal" style="left: 0%; right: 57.14285714285714%;" class="absolute h-full rounded-full bg-cornflower-blue-500"></span></span><span data-reka-collection-item="" aria-label="Tussenruimte" aria-valuetext="24 px" class="block size-4 rounded-full border shadow-sm transition-colors border-gray-200 bg-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-cornflower-blue-500" role="slider" tabindex="0" data-orientation="horizontal" aria-valuemin="0" aria-valuemax="14" aria-orientation="horizontal" style="transform: var(--reka-slider-thumb-transform); position: absolute; left: calc(0% + 0px); display: none;"></span>
|
|
39
|
+
<!--v-if--></span>
|
|
40
|
+
<!--v-if-->
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<!--
|
|
44
|
+
gray-700, not the gray-500 Slider uses for its own readout: axe puts
|
|
45
|
+
gray-500 on white at 1.84:1, well under the 4.5:1 it needs at this size.
|
|
46
|
+
--><span class="min-w-12 shrink-0 text-right small-normal whitespace-nowrap text-gray-700">24 px</span>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>"
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
exports[`EditorGap markup without auto > renders unchanged with a value outside the scale 1`] = `
|
|
55
|
+
"<div class="py-4">
|
|
56
|
+
<!--
|
|
57
|
+
Switch.vue sets \`inheritAttrs: false\` and binds \`$attrs\` on its sr-only
|
|
58
|
+
input, so a class on <Switch> never reaches its root <label>. The child
|
|
59
|
+
variant below styles that label from the header instead, which keeps the
|
|
60
|
+
whole row clickable and the accessible name on the real <label>. The gap
|
|
61
|
+
has to go on that label too: the header has a single child in both modes,
|
|
62
|
+
so its own \`gap\` would never apply and the spacing would silently fall
|
|
63
|
+
back to the \`gap-2\` that Switch.vue sets for itself.
|
|
64
|
+
-->
|
|
65
|
+
<div class="flex items-center [&>label]:flex [&>label]:w-full [&>label]:gap-3">
|
|
66
|
+
<p class="small-normal text-gray-900">Tussenruimte</p>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="grid grid-rows-[1fr]">
|
|
69
|
+
<!--
|
|
70
|
+
\`overflow-hidden\` is what makes the 0fr collapse clip, but it also clips
|
|
71
|
+
a focus ring on a full-width control in the slot, and the block has no
|
|
72
|
+
horizontal padding of its own. \`-mx-1\` widens the clipping box by 4px on
|
|
73
|
+
each side and the \`px-1\` below pushes the content back, so the ring has
|
|
74
|
+
room while the content keeps the same x position as the label.
|
|
75
|
+
-->
|
|
76
|
+
<div class="-mx-1 min-h-0 overflow-hidden opacity-100">
|
|
77
|
+
<!-- Padding sits on the inner element so nothing is left over at 0fr. -->
|
|
78
|
+
<div class="px-1 pt-1.5 pb-1">
|
|
79
|
+
<div class="flex items-center gap-4">
|
|
80
|
+
<!--
|
|
81
|
+
Slider's own \`showValue\` prints its model, which here is the step index
|
|
82
|
+
rather than the gap, so the readout is rendered next to it instead. The
|
|
83
|
+
thumb has the same problem in \`aria-valuenow\`, which \`aria-valuetext\`
|
|
84
|
+
overrides with the string the readout shows. The block label is a <p>,
|
|
85
|
+
not a <label>, so the name goes on the thumb explicitly.
|
|
86
|
+
-->
|
|
87
|
+
<div class="flex w-full flex-col gap-2">
|
|
88
|
+
<!--v-if-->
|
|
89
|
+
<div class="flex items-center gap-4"><span data-slider-impl="" dir="ltr" data-orientation="horizontal" style="--reka-slider-thumb-transform: translateX(-50%);" class="relative flex w-full touch-none items-center select-none cursor-pointer" aria-disabled="false"><span data-orientation="horizontal" class="relative w-full grow rounded-full bg-gray-200 h-1"><span data-orientation="horizontal" style="left: 0%; right: 100%;" class="absolute h-full rounded-full bg-cornflower-blue-500"></span></span><span data-reka-collection-item="" aria-label="Tussenruimte" aria-valuetext="0 px" class="block size-4 rounded-full border shadow-sm transition-colors border-gray-200 bg-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-cornflower-blue-500" role="slider" tabindex="0" data-orientation="horizontal" aria-valuemin="0" aria-valuemax="14" aria-orientation="horizontal" style="transform: var(--reka-slider-thumb-transform); position: absolute; left: calc(0% + 0px); display: none;"></span>
|
|
90
|
+
<!--v-if--></span>
|
|
91
|
+
<!--v-if-->
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
<!--
|
|
95
|
+
gray-700, not the gray-500 Slider uses for its own readout: axe puts
|
|
96
|
+
gray-500 on white at 1.84:1, well under the 4.5:1 it needs at this size.
|
|
97
|
+
--><span class="min-w-12 shrink-0 text-right small-normal whitespace-nowrap text-gray-700">0 px</span>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>"
|
|
103
|
+
`;
|
package/src/components.json
CHANGED
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
"NexxtEditorSettingsBlock": "components/editor/atoms/EditorSettingsBlock/EditorSettingsBlock.vue",
|
|
78
78
|
"NexxtEditorSettingsGroup": "components/editor/atoms/EditorSettingsGroup/EditorSettingsGroup.vue",
|
|
79
79
|
"NexxtEditorAlignItems": "components/editor/molecules/EditorAlignItems/EditorAlignItems.vue",
|
|
80
|
+
"NexxtEditorAlignmentGrid": "components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.vue",
|
|
80
81
|
"NexxtEditorAnchor": "components/editor/molecules/EditorAnchor/EditorAnchor.vue",
|
|
81
82
|
"NexxtEditorBackgroundSize": "components/editor/molecules/EditorBackgroundSize/EditorBackgroundSize.vue",
|
|
82
83
|
"NexxtEditorBorder": "components/editor/molecules/EditorBorder/EditorBorder.vue",
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export type {
|
|
|
9
9
|
TimelinePhase,
|
|
10
10
|
TimelineResponse,
|
|
11
11
|
} from './components/molecules/TimelineEvent/TimelineTypes'
|
|
12
|
+
export { ENERGY_LABEL_COLORS } from './components/atoms/EnergyLabel/EnergyLabel.vue'
|
|
12
13
|
export type { EnergyLabelLetter } from './components/atoms/EnergyLabel/EnergyLabel.vue'
|
|
13
14
|
export type { IconType, NexxtIconName } from './components/atoms/Icon/Icon.vue'
|
|
14
15
|
export type { CustomIconName } from './components/atoms/Icon/customIcons'
|
|
@@ -34,6 +35,14 @@ export type {
|
|
|
34
35
|
NexxtPlaceholderInputMessages,
|
|
35
36
|
NexxtPlaceholderInputProps,
|
|
36
37
|
} from './components/molecules/PlaceholderInput/PlaceholderInput.vue'
|
|
38
|
+
export { EDITOR_ALIGNMENT_POSITIONS } from './components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.vue'
|
|
39
|
+
export type {
|
|
40
|
+
EditorAlignmentDirection,
|
|
41
|
+
EditorAlignmentGridMessages,
|
|
42
|
+
EditorAlignmentMode,
|
|
43
|
+
EditorAlignmentPosition,
|
|
44
|
+
EditorAlignmentValue,
|
|
45
|
+
} from './components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.vue'
|
|
37
46
|
export { EDITOR_ALIGN_ITEMS_OPTIONS } from './components/editor/molecules/EditorAlignItems/EditorAlignItems.vue'
|
|
38
47
|
export type {
|
|
39
48
|
EditorAlignItemsMessages,
|
|
@@ -211,6 +220,7 @@ export { default as NexxtDatePicker } from './components/organisms/DatePicker/Da
|
|
|
211
220
|
export { default as NexxtDoughnutChart } from './components/molecules/DoughnutChart/DoughnutChart.vue'
|
|
212
221
|
export { default as NexxtDropdownButton } from './components/organisms/DropdownButton/DropdownButton.vue'
|
|
213
222
|
export { default as NexxtEditorAlignItems } from './components/editor/molecules/EditorAlignItems/EditorAlignItems.vue'
|
|
223
|
+
export { default as NexxtEditorAlignmentGrid } from './components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.vue'
|
|
214
224
|
export { default as NexxtEditorAnchor } from './components/editor/molecules/EditorAnchor/EditorAnchor.vue'
|
|
215
225
|
export { default as NexxtEditorBackgroundSize } from './components/editor/molecules/EditorBackgroundSize/EditorBackgroundSize.vue'
|
|
216
226
|
export { default as NexxtEditorBorder } from './components/editor/molecules/EditorBorder/EditorBorder.vue'
|
package/src/nuxt.ts
CHANGED
|
@@ -144,8 +144,12 @@ const module: NuxtModule<ModuleOptions> = defineNuxtModule<ModuleOptions>({
|
|
|
144
144
|
|
|
145
145
|
// Compiled component `<style>` blocks (scoped rules, keyframes). Not
|
|
146
146
|
// covered by the Tailwind entry above — that only scans the .vue source
|
|
147
|
-
// for class names. Pushed
|
|
148
|
-
// Tailwind's layers
|
|
147
|
+
// for class names. Pushed after the Tailwind entry on purpose. Most rules
|
|
148
|
+
// are unlayered and beat Tailwind's layers, but EnergyLabel puts its
|
|
149
|
+
// sizing defaults in `@layer components`, so that classes passed to the
|
|
150
|
+
// component can override them. Because `@import "tailwindcss"` loads
|
|
151
|
+
// first, the layer order is already theme, base, components, utilities,
|
|
152
|
+
// and utilities win.
|
|
149
153
|
const componentCSS = resolve('./ui.css')
|
|
150
154
|
|
|
151
155
|
if (existsSync(componentCSS) && !hasComponentCSS(nuxt.options.css, componentCSS)) {
|