@nexxtmove/ui 2.5.0 → 2.7.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/editor/molecules/EditorBorder/EditorBorder.vue.d.ts +12 -0
- package/dist/components/editor/molecules/EditorColor/_ThemeRoleSwatches.vue.d.ts +16 -0
- package/dist/index.js +1094 -1135
- package/dist/nuxt.js +0 -1
- package/package.json +38 -36
- package/src/attribute-contract.test.ts +151 -0
- package/src/components/atoms/AnimatedNumber/AnimatedNumber.stories.ts +36 -0
- package/src/components/atoms/AnimatedNumber/AnimatedNumber.test.ts +21 -0
- package/src/components/atoms/Avatar/Avatar.stories.ts +122 -0
- package/src/components/atoms/Avatar/Avatar.test.ts +134 -0
- package/src/components/atoms/Button/Button.stories.ts +290 -0
- package/src/components/atoms/Button/Button.test.ts +406 -0
- package/src/components/atoms/Card/Card.stories.ts +45 -0
- package/src/components/atoms/Card/Card.test.ts +46 -0
- package/src/components/atoms/Checkbox/Checkbox.stories.ts +35 -0
- package/src/components/atoms/Checkbox/Checkbox.test.ts +55 -0
- package/src/components/atoms/Chip/Chip.stories.ts +274 -0
- package/src/components/atoms/Chip/Chip.test.ts +230 -0
- package/src/components/atoms/EnergyLabel/EnergyLabel.stories.ts +189 -0
- package/src/components/atoms/EnergyLabel/EnergyLabel.test.ts +100 -0
- package/src/components/atoms/FloatingPanel/FloatingPanel.stories.ts +677 -0
- package/src/components/atoms/FloatingPanel/FloatingPanel.test.ts +864 -0
- package/src/components/atoms/Icon/Icon.stories.ts +63 -0
- package/src/components/atoms/Icon/Icon.test.ts +89 -0
- package/src/components/atoms/Loader/Loader.stories.ts +36 -0
- package/src/components/atoms/Loader/Loader.test.ts +40 -0
- package/src/components/atoms/PickerItem/PickerItem.stories.ts +172 -0
- package/src/components/atoms/PickerItem/PickerItem.test.ts +142 -0
- package/src/components/atoms/PickerPreview/PickerPreview.stories.ts +183 -0
- package/src/components/atoms/PickerPreview/PickerPreview.test.ts +137 -0
- package/src/components/atoms/PresenceIndicator/PresenceIndicator.stories.ts +21 -0
- package/src/components/atoms/PropertyListing/PropertyListing.stories.ts +38 -0
- package/src/components/atoms/PropertyListing/PropertyListing.test.ts +46 -0
- package/src/components/atoms/SelectableOption/SelectableOption.stories.ts +131 -0
- package/src/components/atoms/SelectableOption/SelectableOption.test.ts +96 -0
- package/src/components/atoms/Skeleton/Skeleton.stories.ts +27 -0
- package/src/components/atoms/Skeleton/Skeleton.test.ts +28 -0
- package/src/components/atoms/Slider/Slider.stories.ts +151 -0
- package/src/components/atoms/Slider/Slider.test.ts +191 -0
- package/src/components/atoms/Squircle/Squircle.stories.ts +114 -0
- package/src/components/atoms/Squircle/Squircle.test.ts +70 -0
- package/src/components/atoms/Switch/Switch.stories.ts +91 -0
- package/src/components/atoms/Switch/Switch.test.ts +183 -0
- package/src/components/atoms/Tooltip/Tooltip.stories.ts +158 -0
- package/src/components/atoms/Tooltip/Tooltip.test.ts +134 -0
- package/src/components/editor/atoms/EditorDimensionField/EditorDimensionField.stories.ts +124 -0
- package/src/components/editor/atoms/EditorDimensionField/EditorDimensionField.test.ts +464 -0
- package/src/components/editor/atoms/EditorSettingsBlock/EditorSettingsBlock.stories.ts +266 -0
- package/src/components/editor/atoms/EditorSettingsBlock/EditorSettingsBlock.test.ts +421 -0
- package/src/components/editor/atoms/EditorSettingsGroup/EditorSettingsGroup.stories.ts +365 -0
- package/src/components/editor/atoms/EditorSettingsGroup/EditorSettingsGroup.test.ts +484 -0
- package/src/components/editor/composables/useRadioGrid.test.ts +261 -0
- package/src/components/editor/molecules/EditorAlignItems/EditorAlignItems.stories.ts +73 -0
- package/src/components/editor/molecules/EditorAlignItems/EditorAlignItems.test.ts +189 -0
- package/src/components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.stories.ts +309 -0
- package/src/components/editor/molecules/EditorAlignmentGrid/EditorAlignmentGrid.test.ts +359 -0
- package/src/components/editor/molecules/EditorAnchor/EditorAnchor.stories.ts +138 -0
- package/src/components/editor/molecules/EditorAnchor/EditorAnchor.test.ts +344 -0
- package/src/components/editor/molecules/EditorBackgroundSize/EditorBackgroundSize.stories.ts +87 -0
- package/src/components/editor/molecules/EditorBackgroundSize/EditorBackgroundSize.test.ts +262 -0
- package/src/components/editor/molecules/EditorBlur/EditorBlur.stories.ts +115 -0
- package/src/components/editor/molecules/EditorBlur/EditorBlur.test.ts +243 -0
- package/src/components/editor/molecules/EditorBorder/EditorBorder.stories.ts +187 -0
- package/src/components/editor/molecules/EditorBorder/EditorBorder.test.ts +456 -0
- package/src/components/editor/molecules/EditorBorder/EditorBorder.vue +58 -2
- package/src/components/editor/molecules/EditorColor/EditorColor.stories.ts +563 -0
- package/src/components/editor/molecules/EditorColor/EditorColor.test.ts +689 -0
- package/src/components/editor/molecules/EditorColor/EditorColorGradient.test.ts +793 -0
- package/src/components/editor/molecules/EditorColor/_ColorField.vue +7 -29
- package/src/components/editor/molecules/EditorColor/_ThemeRoleSwatches.vue +57 -0
- package/src/components/editor/molecules/EditorColor/gradientClass.test.ts +303 -0
- package/src/components/editor/molecules/EditorDashPattern/EditorDashPattern.stories.ts +72 -0
- package/src/components/editor/molecules/EditorDashPattern/EditorDashPattern.test.ts +124 -0
- package/src/components/editor/molecules/EditorFlexDirection/EditorFlexDirection.stories.ts +46 -0
- package/src/components/editor/molecules/EditorFlexDirection/EditorFlexDirection.test.ts +97 -0
- package/src/components/editor/molecules/EditorFontSize/EditorFontSize.stories.ts +248 -0
- package/src/components/editor/molecules/EditorFontSize/EditorFontSize.test.ts +288 -0
- package/src/components/editor/molecules/EditorGap/EditorGap.stories.ts +129 -0
- package/src/components/editor/molecules/EditorGap/EditorGap.test.ts +253 -0
- package/src/components/editor/molecules/EditorHeadingType/EditorHeadingType.stories.ts +68 -0
- package/src/components/editor/molecules/EditorHeadingType/EditorHeadingType.test.ts +150 -0
- package/src/components/editor/molecules/EditorJustifyContent/EditorJustifyContent.stories.ts +71 -0
- package/src/components/editor/molecules/EditorJustifyContent/EditorJustifyContent.test.ts +161 -0
- package/src/components/editor/molecules/EditorLetterSpacing/EditorLetterSpacing.stories.ts +204 -0
- package/src/components/editor/molecules/EditorLetterSpacing/EditorLetterSpacing.test.ts +238 -0
- package/src/components/editor/molecules/EditorLineHeight/EditorLineHeight.stories.ts +257 -0
- package/src/components/editor/molecules/EditorLineHeight/EditorLineHeight.test.ts +286 -0
- package/src/components/editor/molecules/EditorLineStyle/EditorLineStyle.stories.ts +135 -0
- package/src/components/editor/molecules/EditorLineStyle/EditorLineStyle.test.ts +230 -0
- package/src/components/editor/molecules/EditorMaxWidth/EditorMaxWidth.stories.ts +154 -0
- package/src/components/editor/molecules/EditorMaxWidth/EditorMaxWidth.test.ts +112 -0
- package/src/components/editor/molecules/EditorOverrideStatus/EditorOverrideStatus.stories.ts +206 -0
- package/src/components/editor/molecules/EditorOverrideStatus/EditorOverrideStatus.test.ts +332 -0
- package/src/components/editor/molecules/EditorPadding/EditorPadding.stories.ts +374 -0
- package/src/components/editor/molecules/EditorPadding/EditorPadding.test.ts +712 -0
- package/src/components/editor/molecules/EditorRadius/EditorRadius.stories.ts +64 -0
- package/src/components/editor/molecules/EditorRadius/EditorRadius.test.ts +137 -0
- package/src/components/editor/molecules/EditorShadow/EditorShadow.stories.ts +103 -0
- package/src/components/editor/molecules/EditorShadow/EditorShadow.test.ts +168 -0
- package/src/components/editor/molecules/EditorSize/EditorSize.stories.ts +84 -0
- package/src/components/editor/molecules/EditorSize/EditorSize.test.ts +253 -0
- package/src/components/editor/molecules/EditorSizeLimit/EditorSizeLimit.stories.ts +49 -0
- package/src/components/editor/molecules/EditorSizeLimit/EditorSizeLimit.test.ts +43 -0
- package/src/components/editor/molecules/EditorTextAlign/EditorTextAlign.stories.ts +69 -0
- package/src/components/editor/molecules/EditorTextAlign/EditorTextAlign.test.ts +155 -0
- package/src/components/molecules/Announcement/Announcement.stories.ts +224 -0
- package/src/components/molecules/Announcement/Announcement.test.ts +161 -0
- package/src/components/molecules/ContactInfoCard/ContactInfoCard.stories.ts +99 -0
- package/src/components/molecules/ContactInfoCard/ContactInfoCard.test.ts +70 -0
- package/src/components/molecules/CustomerJourneyTile/CustomerJourneyTile.stories.ts +148 -0
- package/src/components/molecules/CustomerJourneyTile/CustomerJourneyTile.test.ts +271 -0
- package/src/components/molecules/DoughnutChart/DoughnutChart.stories.ts +45 -0
- package/src/components/molecules/DoughnutChart/DoughnutChart.test.ts +205 -0
- package/src/components/molecules/InfoBlock/InfoBlock.stories.ts +84 -0
- package/src/components/molecules/InfoBlock/InfoBlock.test.ts +101 -0
- package/src/components/molecules/InputField/InputField.stories.ts +117 -0
- package/src/components/molecules/InputField/InputField.test.ts +138 -0
- package/src/components/molecules/InputSelect/InputSelect.stories.ts +116 -0
- package/src/components/molecules/InputSelect/InputSelect.test.ts +127 -0
- package/src/components/molecules/ModalFooter/ModalFooter.stories.ts +204 -0
- package/src/components/molecules/ModalFooter/ModalFooter.test.ts +276 -0
- package/src/components/molecules/PageCard/PageCard.stories.ts +100 -0
- package/src/components/molecules/PageCard/PageCard.test.ts +91 -0
- package/src/components/molecules/PageContainer/PageContainer.stories.ts +90 -0
- package/src/components/molecules/PageContainer/PageContainer.test.ts +50 -0
- package/src/components/molecules/PageMockup/PageMockup.stories.ts +38 -0
- package/src/components/molecules/PageMockup/PageMockup.test.ts +20 -0
- package/src/components/molecules/PageTypeTile/PageTypeTile.stories.ts +63 -0
- package/src/components/molecules/PageTypeTile/PageTypeTile.test.ts +41 -0
- package/src/components/molecules/Pagination/Pagination.stories.ts +72 -0
- package/src/components/molecules/Pagination/Pagination.test.ts +130 -0
- package/src/components/molecules/PickerGroup/PickerGroup.stories.ts +90 -0
- package/src/components/molecules/PickerGroup/PickerGroup.test.ts +145 -0
- package/src/components/molecules/PickerList/PickerList.stories.ts +436 -0
- package/src/components/molecules/PickerList/PickerList.test.ts +870 -0
- package/src/components/molecules/PlaceholderInput/PlaceholderInput.stories.ts +48 -0
- package/src/components/molecules/PlaceholderInput/PlaceholderInput.test.ts +107 -0
- package/src/components/molecules/PropertyCard/PropertyCard.stories.ts +46 -0
- package/src/components/molecules/PropertyCard/PropertyCard.test.ts +59 -0
- package/src/components/molecules/Select/Select.stories.ts +264 -0
- package/src/components/molecules/Select/Select.test.ts +315 -0
- package/src/components/molecules/SidebarMenuItem/SidebarMenuItem.stories.ts +84 -0
- package/src/components/molecules/SidebarMenuItem/SidebarMenuItem.test.ts +103 -0
- package/src/components/molecules/SkeletonPropertyCard/SkeletonPropertyCard.stories.ts +11 -0
- package/src/components/molecules/SkeletonPropertyCard/SkeletonPropertyCard.test.ts +38 -0
- package/src/components/molecules/SocialIcons/SocialIcons.stories.ts +28 -0
- package/src/components/molecules/SocialIcons/SocialIcons.test.ts +58 -0
- package/src/components/molecules/SocialMediaCustomTemplate/SocialMediaCustomTemplate.stories.ts +11 -0
- package/src/components/molecules/SocialMediaCustomTemplate/SocialMediaCustomTemplate.test.ts +116 -0
- package/src/components/molecules/SocialMediaType/SocialMediaType.stories.ts +37 -0
- package/src/components/molecules/SocialMediaType/SocialMediaType.test.ts +126 -0
- package/src/components/molecules/Source/Source.stories.ts +35 -0
- package/src/components/molecules/Source/Source.test.ts +45 -0
- package/src/components/molecules/TabbedContent/TabbedContent.stories.ts +96 -0
- package/src/components/molecules/TabbedContent/TabbedContent.test.ts +109 -0
- package/src/components/molecules/Tabs/Tabs.stories.ts +230 -0
- package/src/components/molecules/Tabs/Tabs.test.ts +280 -0
- package/src/components/molecules/TemplateCard/TemplateCard.stories.ts +327 -0
- package/src/components/molecules/TemplateCard/TemplateCard.test.ts +339 -0
- package/src/components/molecules/Textarea/Textarea.stories.ts +216 -0
- package/src/components/molecules/Textarea/Textarea.test.ts +191 -0
- package/src/components/molecules/TimelineEvent/TimelineEvent.stories.ts +319 -0
- package/src/components/molecules/TimelineEvent/TimelineEvent.test.ts +224 -0
- package/src/components/molecules/TimelineLanes/TimelineLanes.stories.ts +29 -0
- package/src/components/molecules/TimelineLanes/TimelineLanes.test.ts +30 -0
- package/src/components/molecules/Toast/Toast.stories.ts +110 -0
- package/src/components/molecules/Toast/Toast.test.ts +103 -0
- package/src/components/molecules/ToggleGroup/ToggleGroup.stories.ts +297 -0
- package/src/components/molecules/ToggleGroup/ToggleGroup.test.ts +578 -0
- package/src/components/molecules/Tree/Tree.stories.ts +884 -0
- package/src/components/molecules/Tree/Tree.test.ts +1247 -0
- package/src/components/molecules/Tree/tree-drop.test.ts +223 -0
- package/src/components/organisms/Calendar/Calendar.stories.ts +108 -0
- package/src/components/organisms/Calendar/Calendar.test.ts +279 -0
- package/src/components/organisms/Calendar/_CalendarDayView.test.ts +104 -0
- package/src/components/organisms/Calendar/_CalendarHeader.test.ts +86 -0
- package/src/components/organisms/Calendar/_CalendarMonthView.test.ts +52 -0
- package/src/components/organisms/Calendar/_CalendarTimePicker.test.ts +89 -0
- package/src/components/organisms/Calendar/_CalendarYearView.test.ts +56 -0
- package/src/components/organisms/ColorPicker/ColorPicker.stories.ts +229 -0
- package/src/components/organisms/ColorPicker/ColorPicker.test.ts +638 -0
- package/src/components/organisms/ColorPicker/gradient.test.ts +67 -0
- package/src/components/organisms/ColorPicker/gradientGeometry.test.ts +206 -0
- package/src/components/organisms/Combobox/Combobox.stories.ts +234 -0
- package/src/components/organisms/Combobox/Combobox.test.ts +512 -0
- package/src/components/organisms/Combobox/Combobox.vue +1 -1
- package/src/components/organisms/ComboboxPanel/ComboboxPanel.stories.ts +158 -0
- package/src/components/organisms/ComboboxPanel/ComboboxPanel.test.ts +524 -0
- package/src/components/organisms/ComboboxPanel/ComboboxPanel.vue +1 -1
- package/src/components/organisms/CountrySelect/CountrySelect.stories.ts +139 -0
- package/src/components/organisms/CountrySelect/CountrySelect.test.ts +149 -0
- package/src/components/organisms/DatePicker/DatePicker.stories.ts +163 -0
- package/src/components/organisms/DatePicker/DatePicker.test.ts +214 -0
- package/src/components/organisms/DropdownButton/DropdownButton.stories.ts +123 -0
- package/src/components/organisms/DropdownButton/DropdownButton.test.ts +379 -0
- package/src/components/organisms/FontPicker/FontPicker.stories.ts +476 -0
- package/src/components/organisms/FontPicker/FontPicker.test.ts +873 -0
- package/src/components/organisms/Header/Header.stories.ts +75 -0
- package/src/components/organisms/Header/Header.test.ts +233 -0
- package/src/components/organisms/IconPicker/IconPicker.stories.ts +734 -0
- package/src/components/organisms/IconPicker/IconPicker.test.ts +669 -0
- package/src/components/organisms/IconPicker/_IconPickerGrid.test.ts +184 -0
- package/src/components/organisms/IconPicker/_IconPickerRail.test.ts +102 -0
- package/src/components/organisms/IconPicker/useIconPickerNavigation.test.ts +215 -0
- package/src/components/organisms/Modal/Modal.stories.ts +350 -0
- package/src/components/organisms/Modal/Modal.test.ts +275 -0
- package/src/components/organisms/PickerPanel/PickerPanel.stories.ts +452 -0
- package/src/components/organisms/PickerPanel/PickerPanel.test.ts +358 -0
- package/src/components/organisms/ProgressBar/ProgressBar.stories.ts +100 -0
- package/src/components/organisms/ProgressBar/ProgressBar.test.ts +417 -0
- package/src/components/organisms/ReferenceCard/ReferenceCard.stories.ts +191 -0
- package/src/components/organisms/ReferenceCard/ReferenceCard.test.ts +165 -0
- package/src/components/organisms/SocialMediaTemplate/SocialMediaTemplate.stories.ts +65 -0
- package/src/components/organisms/SocialMediaTemplate/SocialMediaTemplate.test.ts +466 -0
- package/src/components/organisms/StepperHeader/StepperHeader.stories.ts +91 -0
- package/src/components/organisms/StepperHeader/StepperHeader.test.ts +279 -0
- package/src/components/organisms/Table/Table.stories.ts +332 -0
- package/src/components/organisms/Table/Table.test.ts +320 -0
- package/src/components/organisms/TimelinePhaseblock/TimelinePhaseblock.stories.ts +198 -0
- package/src/components/organisms/TimelinePhaseblock/TimelinePhaseblock.test.ts +283 -0
- package/src/components/organisms/TimelineTrack/TimelineTrack.stories.ts +120 -0
- package/src/components/organisms/TimelineTrack/TimelineTrack.test.ts +91 -0
- package/src/components/organisms/Toaster/Toaster.stories.ts +51 -0
- package/src/components/organisms/Toaster/Toaster.test.ts +75 -0
- package/src/components/organisms/VideoControls/VideoControls.stories.ts +792 -0
- package/src/components/organisms/VideoControls/VideoControls.test.ts +1056 -0
- package/src/components/organisms/VideoPlayer/VideoPlayer.stories.ts +327 -0
- package/src/components/organisms/VideoPlayer/VideoPlayer.test.ts +439 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { expect, userEvent, waitFor, within } from 'storybook/test'
|
|
4
|
+
import EditorSettingsGroup from './EditorSettingsGroup.vue'
|
|
5
|
+
import EditorSettingsBlock from '../EditorSettingsBlock/EditorSettingsBlock.vue'
|
|
6
|
+
import EditorPadding from '../../molecules/EditorPadding/EditorPadding.vue'
|
|
7
|
+
import EditorLineStyle from '../../molecules/EditorLineStyle/EditorLineStyle.vue'
|
|
8
|
+
import EditorJustifyContent from '../../molecules/EditorJustifyContent/EditorJustifyContent.vue'
|
|
9
|
+
import type { EditorLineStyleValue } from '../../molecules/EditorLineStyle/EditorLineStyle.vue'
|
|
10
|
+
import type { EditorJustifyContentValue } from '../../molecules/EditorJustifyContent/EditorJustifyContent.vue'
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
title: 'Components/Editor Components/Atoms/Editor Settings Group',
|
|
14
|
+
component: EditorSettingsGroup,
|
|
15
|
+
parameters: {
|
|
16
|
+
docs: {
|
|
17
|
+
description: {
|
|
18
|
+
component:
|
|
19
|
+
'A section of an editor settings panel: the settings about the same thing. Draws the divider above itself and owns the vertical space. Without a label, the label of the one setting inside is promoted to group weight.',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
// The settings panel's content width: `w-92` with `p-7` leaves 312px.
|
|
24
|
+
decorators: [() => ({ template: '<div class="mx-auto w-78"><story /></div>' })],
|
|
25
|
+
argTypes: {
|
|
26
|
+
label: { control: 'text' },
|
|
27
|
+
headingLevel: { control: 'select', options: [2, 3, 4, 5, 6] },
|
|
28
|
+
},
|
|
29
|
+
} satisfies Meta<typeof EditorSettingsGroup>
|
|
30
|
+
|
|
31
|
+
type Story = StoryObj<typeof EditorSettingsGroup>
|
|
32
|
+
|
|
33
|
+
/** A labelled group: the heading names the group for assistive technology too. */
|
|
34
|
+
export const Labelled: Story = {
|
|
35
|
+
args: { label: 'Achtergrond' },
|
|
36
|
+
render: (args) => ({
|
|
37
|
+
components: { EditorSettingsGroup, EditorSettingsBlock },
|
|
38
|
+
setup: () => ({ args }),
|
|
39
|
+
template: `
|
|
40
|
+
<EditorSettingsGroup v-bind="args">
|
|
41
|
+
<EditorSettingsBlock label="Kleur">
|
|
42
|
+
<p class="small-normal text-gray-700">Kleurkiezer</p>
|
|
43
|
+
</EditorSettingsBlock>
|
|
44
|
+
<EditorSettingsBlock label="Afbeelding">
|
|
45
|
+
<p class="small-normal text-gray-700">Afbeeldingkiezer</p>
|
|
46
|
+
</EditorSettingsBlock>
|
|
47
|
+
</EditorSettingsGroup>
|
|
48
|
+
`,
|
|
49
|
+
}),
|
|
50
|
+
play: ({ canvasElement }) => {
|
|
51
|
+
const canvas = within(canvasElement)
|
|
52
|
+
|
|
53
|
+
expect(canvas.getByRole('group', { name: 'Achtergrond' })).toBeInTheDocument()
|
|
54
|
+
expect(canvas.getByRole('heading', { level: 3, name: 'Achtergrond' })).toBeInTheDocument()
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** No label: the one setting inside carries the group's weight, as a heading. */
|
|
59
|
+
export const Unlabelled: Story = {
|
|
60
|
+
render: (args) => ({
|
|
61
|
+
components: { EditorSettingsGroup, EditorPadding },
|
|
62
|
+
setup() {
|
|
63
|
+
const padding = ref('py-6')
|
|
64
|
+
return { args, padding }
|
|
65
|
+
},
|
|
66
|
+
template: `
|
|
67
|
+
<EditorSettingsGroup v-bind="args">
|
|
68
|
+
<EditorPadding v-model="padding" sides="vertical" label="Witruimte" />
|
|
69
|
+
</EditorSettingsGroup>
|
|
70
|
+
`,
|
|
71
|
+
}),
|
|
72
|
+
play: ({ canvasElement }) => {
|
|
73
|
+
const canvas = within(canvasElement)
|
|
74
|
+
|
|
75
|
+
expect(canvas.queryByRole('group')).toBeNull()
|
|
76
|
+
expect(canvas.getByRole('heading', { level: 3, name: 'Witruimte' })).toBeInTheDocument()
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The divider panel from the pattern spec: a promoted Witruimte and the group
|
|
82
|
+
* Lijn. Measured: 24px from a line to the heading under it in both groups and
|
|
83
|
+
* from the last visible control to the next line or the group's end, 16px from
|
|
84
|
+
* the group heading to the first setting and between two settings.
|
|
85
|
+
*/
|
|
86
|
+
export const DividerPanel: Story = {
|
|
87
|
+
render: () => ({
|
|
88
|
+
components: { EditorSettingsGroup, EditorPadding, EditorLineStyle, EditorJustifyContent },
|
|
89
|
+
setup() {
|
|
90
|
+
const padding = ref('py-6')
|
|
91
|
+
const lineStyle = ref<EditorLineStyleValue>('solid')
|
|
92
|
+
const thickness = ref<1 | 2 | 3 | 4 | 6 | 8>(2)
|
|
93
|
+
const align = ref<EditorJustifyContentValue>('justify-center')
|
|
94
|
+
return { padding, lineStyle, thickness, align }
|
|
95
|
+
},
|
|
96
|
+
template: `
|
|
97
|
+
<div class="flex flex-col">
|
|
98
|
+
<EditorSettingsGroup>
|
|
99
|
+
<EditorPadding v-model="padding" sides="vertical" label="Witruimte" />
|
|
100
|
+
</EditorSettingsGroup>
|
|
101
|
+
<EditorSettingsGroup label="Lijn">
|
|
102
|
+
<EditorLineStyle v-model="lineStyle" v-model:thickness="thickness" label="Stijl" />
|
|
103
|
+
<EditorJustifyContent
|
|
104
|
+
v-model="align"
|
|
105
|
+
:options="['justify-start', 'justify-center', 'justify-end']"
|
|
106
|
+
:messages="{ start: 'Links', center: 'Midden', end: 'Rechts' }"
|
|
107
|
+
/>
|
|
108
|
+
</EditorSettingsGroup>
|
|
109
|
+
</div>
|
|
110
|
+
`,
|
|
111
|
+
}),
|
|
112
|
+
play: async ({ canvasElement }) => {
|
|
113
|
+
const canvas = within(canvasElement)
|
|
114
|
+
await document.fonts.ready
|
|
115
|
+
|
|
116
|
+
const [first, second] = canvasElement.querySelectorAll<HTMLElement>('.border-t')
|
|
117
|
+
const witruimte = canvas.getByRole('heading', { name: 'Witruimte' })
|
|
118
|
+
const lijn = canvas.getByRole('heading', { name: 'Lijn' })
|
|
119
|
+
const stijl = canvas.getByText('Stijl')
|
|
120
|
+
const uitlijning = canvas.getByText('Uitlijning')
|
|
121
|
+
|
|
122
|
+
// Both headings sit 24px under their own line, promoted or not.
|
|
123
|
+
const gapUnderLine = (group: HTMLElement, heading: HTMLElement) =>
|
|
124
|
+
heading.getBoundingClientRect().top - group.getBoundingClientRect().top - 1
|
|
125
|
+
expect(gapUnderLine(first, witruimte)).toBe(24)
|
|
126
|
+
expect(gapUnderLine(second, lijn)).toBe(24)
|
|
127
|
+
|
|
128
|
+
// Last visible control to the next group's line: 24px, the same as line
|
|
129
|
+
// to heading. Here the control is the padding field.
|
|
130
|
+
const lastControl = first.querySelector('input')!.parentElement!
|
|
131
|
+
expect(second.getBoundingClientRect().top - lastControl.getBoundingClientRect().bottom).toBe(24)
|
|
132
|
+
|
|
133
|
+
// The last setting of the second group (Uitlijning, stacked) ends 24px
|
|
134
|
+
// above the group's bottom too.
|
|
135
|
+
const alignOptions = canvas.getByRole('button', { name: 'Links' }).parentElement!
|
|
136
|
+
expect(
|
|
137
|
+
second.getBoundingClientRect().bottom - alignOptions.getBoundingClientRect().bottom,
|
|
138
|
+
).toBe(24)
|
|
139
|
+
|
|
140
|
+
// Group heading to the first setting: 16px.
|
|
141
|
+
expect(stijl.getBoundingClientRect().top - lijn.getBoundingClientRect().bottom).toBe(16)
|
|
142
|
+
|
|
143
|
+
// Setting to setting: 16px between the blocks (Stijl to Uitlijning).
|
|
144
|
+
const stijlBlock = stijl.parentElement!.parentElement!
|
|
145
|
+
expect(uitlijning.getBoundingClientRect().top - stijlBlock.getBoundingClientRect().bottom).toBe(
|
|
146
|
+
16,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
// The two promoted and labelled headings weigh the same.
|
|
150
|
+
expect(getComputedStyle(witruimte).fontWeight).toBe(getComputedStyle(lijn).fontWeight)
|
|
151
|
+
expect(getComputedStyle(stijl).fontWeight).not.toBe(getComputedStyle(lijn).fontWeight)
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The divider panel with "Lijn" collapsible, the open state shown under it.
|
|
157
|
+
* `lastFocusable` adds a mobile marker with a link as the last item of the
|
|
158
|
+
* group, to check that the clip box does not cut off its focus ring.
|
|
159
|
+
*/
|
|
160
|
+
const collapsiblePanel =
|
|
161
|
+
(initiallyOpen: boolean, lastFocusable = false) =>
|
|
162
|
+
() => ({
|
|
163
|
+
components: { EditorSettingsGroup, EditorPadding, EditorLineStyle, EditorJustifyContent },
|
|
164
|
+
setup() {
|
|
165
|
+
const padding = ref('py-6')
|
|
166
|
+
const lineStyle = ref<EditorLineStyleValue>('solid')
|
|
167
|
+
const thickness = ref<1 | 2 | 3 | 4 | 6 | 8>(2)
|
|
168
|
+
const align = ref<EditorJustifyContentValue>('justify-center')
|
|
169
|
+
const open = ref(initiallyOpen)
|
|
170
|
+
return { padding, lineStyle, thickness, align, open, lastFocusable }
|
|
171
|
+
},
|
|
172
|
+
template: `
|
|
173
|
+
<div class="flex flex-col">
|
|
174
|
+
<EditorSettingsGroup>
|
|
175
|
+
<EditorPadding v-model="padding" sides="vertical" label="Witruimte" />
|
|
176
|
+
</EditorSettingsGroup>
|
|
177
|
+
<EditorSettingsGroup v-model:open="open" label="Lijn" collapsible>
|
|
178
|
+
<EditorLineStyle v-model="lineStyle" v-model:thickness="thickness" label="Stijl" />
|
|
179
|
+
<EditorJustifyContent
|
|
180
|
+
v-model="align"
|
|
181
|
+
:options="['justify-start', 'justify-center', 'justify-end']"
|
|
182
|
+
:messages="{ start: 'Links', center: 'Midden', end: 'Rechts' }"
|
|
183
|
+
/>
|
|
184
|
+
<div v-if="lastFocusable" class="flex items-center justify-between pt-2">
|
|
185
|
+
<span class="small-normal text-gray-700">Aangepast voor mobiel</span>
|
|
186
|
+
<a
|
|
187
|
+
href="#"
|
|
188
|
+
data-testid="marker-link"
|
|
189
|
+
class="small-normal text-gray-900 underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-cornflower-blue-600"
|
|
190
|
+
@click.prevent
|
|
191
|
+
>Terug naar desktop</a>
|
|
192
|
+
</div>
|
|
193
|
+
</EditorSettingsGroup>
|
|
194
|
+
<p data-testid="open-state" class="pt-4 small-normal text-gray-700">open: {{ open }}</p>
|
|
195
|
+
</div>
|
|
196
|
+
`,
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
const lijnGroup = (canvasElement: HTMLElement) =>
|
|
200
|
+
canvasElement.querySelectorAll<HTMLElement>('.border-t')[1]
|
|
201
|
+
|
|
202
|
+
const groupContent = (canvasElement: HTMLElement) =>
|
|
203
|
+
canvasElement.querySelector<HTMLElement>('[data-testid="editor-settings-group-content"]')!
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Open, pixel-equal to DividerPanel: the same 24px under the line, 16px to the
|
|
207
|
+
* first setting, and a 20px title row. Click closes it (content inert, the
|
|
208
|
+
* group folds to line + 24 + title + 24); Space opens it again with focus
|
|
209
|
+
* staying on the button.
|
|
210
|
+
*/
|
|
211
|
+
export const Collapsible: Story = {
|
|
212
|
+
render: collapsiblePanel(true),
|
|
213
|
+
play: async ({ canvasElement }) => {
|
|
214
|
+
const canvas = within(canvasElement)
|
|
215
|
+
await document.fonts.ready
|
|
216
|
+
|
|
217
|
+
const group = lijnGroup(canvasElement)
|
|
218
|
+
const heading = canvas.getByRole('heading', { name: 'Lijn' })
|
|
219
|
+
const button = canvas.getByRole('button', { name: 'Lijn' })
|
|
220
|
+
const content = groupContent(canvasElement)
|
|
221
|
+
|
|
222
|
+
// Parity with a group that does not collapse.
|
|
223
|
+
expect(heading.getBoundingClientRect().top - group.getBoundingClientRect().top - 1).toBe(24)
|
|
224
|
+
expect(heading.getBoundingClientRect().height).toBe(20)
|
|
225
|
+
expect(
|
|
226
|
+
canvas.getByText('Stijl').getBoundingClientRect().top -
|
|
227
|
+
heading.getBoundingClientRect().bottom,
|
|
228
|
+
).toBe(16)
|
|
229
|
+
|
|
230
|
+
// The whole row is the hit area, at least 24px tall.
|
|
231
|
+
expect(button.getBoundingClientRect().height).toBeGreaterThanOrEqual(24)
|
|
232
|
+
expect(button.getBoundingClientRect().width).toBeGreaterThanOrEqual(
|
|
233
|
+
heading.getBoundingClientRect().width,
|
|
234
|
+
)
|
|
235
|
+
expect(button).toHaveAttribute('aria-controls', content.id)
|
|
236
|
+
|
|
237
|
+
await userEvent.click(button)
|
|
238
|
+
await waitFor(() => expect(button).toHaveAttribute('aria-expanded', 'false'))
|
|
239
|
+
expect(content).toHaveAttribute('inert')
|
|
240
|
+
expect(canvas.getByTestId('open-state')).toHaveTextContent('open: false')
|
|
241
|
+
|
|
242
|
+
// Closed, the chevron points up: a half turn from pointing down.
|
|
243
|
+
const chevron = button.querySelector<HTMLElement>('span[aria-hidden="true"]')!
|
|
244
|
+
await waitFor(() => expect(getComputedStyle(chevron).rotate).toBe('180deg'))
|
|
245
|
+
|
|
246
|
+
// Closed: line + 24 + title + 24, nothing left of the first block.
|
|
247
|
+
await waitFor(() => expect(group.getBoundingClientRect().height).toBe(1 + 24 + 20 + 24))
|
|
248
|
+
expect(group.getBoundingClientRect().bottom - heading.getBoundingClientRect().bottom).toBe(24)
|
|
249
|
+
|
|
250
|
+
button.focus()
|
|
251
|
+
await userEvent.keyboard(' ')
|
|
252
|
+
await waitFor(() => expect(button).toHaveAttribute('aria-expanded', 'true'))
|
|
253
|
+
expect(content).not.toHaveAttribute('inert')
|
|
254
|
+
expect(document.activeElement).toBe(button)
|
|
255
|
+
await waitFor(() => expect(['0deg', 'none']).toContain(getComputedStyle(chevron).rotate))
|
|
256
|
+
|
|
257
|
+
// Open again: 24px from the last visible control to the group's bottom.
|
|
258
|
+
const alignOptions = canvas.getByRole('button', { name: 'Links' }).parentElement!
|
|
259
|
+
await waitFor(() =>
|
|
260
|
+
expect(
|
|
261
|
+
group.getBoundingClientRect().bottom - alignOptions.getBoundingClientRect().bottom,
|
|
262
|
+
).toBe(24),
|
|
263
|
+
)
|
|
264
|
+
},
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** Starts closed: no animation on the first render, Tab skips the content. */
|
|
268
|
+
export const CollapsibleStartsClosed: Story = {
|
|
269
|
+
render: collapsiblePanel(false),
|
|
270
|
+
play: async ({ canvasElement }) => {
|
|
271
|
+
const canvas = within(canvasElement)
|
|
272
|
+
const button = canvas.getByRole('button', { name: 'Lijn' })
|
|
273
|
+
|
|
274
|
+
expect(button).toHaveAttribute('aria-expanded', 'false')
|
|
275
|
+
expect(groupContent(canvasElement)).toHaveAttribute('inert')
|
|
276
|
+
|
|
277
|
+
// Keyboard focus shows a real ring: a stray `focus:outline-none` would set
|
|
278
|
+
// the outline style to none under `focus-visible:outline-2` and hide it.
|
|
279
|
+
button.focus()
|
|
280
|
+
expect(button.matches(':focus-visible')).toBe(true)
|
|
281
|
+
expect(getComputedStyle(button).outlineStyle).not.toBe('none')
|
|
282
|
+
expect(getComputedStyle(button).outlineWidth).toBe('2px')
|
|
283
|
+
|
|
284
|
+
await userEvent.keyboard('{Enter}')
|
|
285
|
+
await waitFor(() => expect(button).toHaveAttribute('aria-expanded', 'true'))
|
|
286
|
+
expect(document.activeElement).toBe(button)
|
|
287
|
+
},
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* A focusable mobile marker as the last item: its focus ring (2px outline,
|
|
292
|
+
* 2px offset) must fit inside the clip box on every side, the bottom too.
|
|
293
|
+
*/
|
|
294
|
+
export const CollapsibleLastFocusable: Story = {
|
|
295
|
+
render: collapsiblePanel(true, true),
|
|
296
|
+
play: async ({ canvasElement }) => {
|
|
297
|
+
const canvas = within(canvasElement)
|
|
298
|
+
await document.fonts.ready
|
|
299
|
+
|
|
300
|
+
const link = canvas.getByTestId('marker-link')
|
|
301
|
+
const clip = groupContent(canvasElement).firstElementChild!.getBoundingClientRect()
|
|
302
|
+
const ring = link.getBoundingClientRect()
|
|
303
|
+
|
|
304
|
+
expect(clip.bottom).toBeGreaterThanOrEqual(ring.bottom + 4)
|
|
305
|
+
expect(clip.right).toBeGreaterThanOrEqual(ring.right + 4)
|
|
306
|
+
expect(clip.left).toBeLessThanOrEqual(ring.left - 4)
|
|
307
|
+
|
|
308
|
+
// And it is reachable by keyboard while open.
|
|
309
|
+
link.focus()
|
|
310
|
+
expect(document.activeElement).toBe(link)
|
|
311
|
+
},
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* A tall group (~330px of settings), where the closing curve shows most. Closing
|
|
316
|
+
* on ease-in-out-strong starts gently: about 40ms in, well over half the height
|
|
317
|
+
* is still there (a strong ease-out would already have taken most of it). Fully
|
|
318
|
+
* closed, the content wrapper is exactly 0px and the group is line + 24 + title
|
|
319
|
+
* + 24.
|
|
320
|
+
*/
|
|
321
|
+
export const CollapsibleTall: Story = {
|
|
322
|
+
render: () => ({
|
|
323
|
+
components: { EditorSettingsGroup, EditorSettingsBlock },
|
|
324
|
+
setup() {
|
|
325
|
+
const open = ref(true)
|
|
326
|
+
return { open }
|
|
327
|
+
},
|
|
328
|
+
template: `
|
|
329
|
+
<EditorSettingsGroup v-model:open="open" label="Achtergrond" collapsible>
|
|
330
|
+
<EditorSettingsBlock v-for="name in ['Kleur', 'Afbeelding', 'Vulling']" :key="name" :label="name">
|
|
331
|
+
<div class="h-16 rounded-lg bg-gray-100" />
|
|
332
|
+
</EditorSettingsBlock>
|
|
333
|
+
</EditorSettingsGroup>
|
|
334
|
+
`,
|
|
335
|
+
}),
|
|
336
|
+
play: async ({ canvasElement }) => {
|
|
337
|
+
const canvas = within(canvasElement)
|
|
338
|
+
const group = canvasElement.querySelector<HTMLElement>('.border-t')!
|
|
339
|
+
const button = canvas.getByRole('button', { name: 'Achtergrond' })
|
|
340
|
+
const content = groupContent(canvasElement)
|
|
341
|
+
|
|
342
|
+
const openHeight = content.getBoundingClientRect().height
|
|
343
|
+
expect(openHeight).toBeGreaterThan(300)
|
|
344
|
+
|
|
345
|
+
// Sample frame by frame from the click until 40ms have passed.
|
|
346
|
+
const start = performance.now()
|
|
347
|
+
button.click()
|
|
348
|
+
const sample = await new Promise<{ height: number; elapsed: number }>((resolve) => {
|
|
349
|
+
const tick = () => {
|
|
350
|
+
const elapsed = performance.now() - start
|
|
351
|
+
if (elapsed >= 40) resolve({ height: content.getBoundingClientRect().height, elapsed })
|
|
352
|
+
else requestAnimationFrame(tick)
|
|
353
|
+
}
|
|
354
|
+
requestAnimationFrame(tick)
|
|
355
|
+
})
|
|
356
|
+
expect(sample.elapsed).toBeLessThan(80)
|
|
357
|
+
expect(sample.height).toBeGreaterThan(openHeight / 2)
|
|
358
|
+
|
|
359
|
+
// Fully closed: no height left behind by the content or the clip box.
|
|
360
|
+
await waitFor(() => expect(content.getBoundingClientRect().height).toBe(0))
|
|
361
|
+
await waitFor(() => expect(group.getBoundingClientRect().height).toBe(1 + 24 + 20 + 24))
|
|
362
|
+
const heading = canvas.getByRole('heading', { name: 'Achtergrond' })
|
|
363
|
+
expect(group.getBoundingClientRect().bottom - heading.getBoundingClientRect().bottom).toBe(24)
|
|
364
|
+
},
|
|
365
|
+
}
|