Skip to content

Commit

Permalink
Implement framework overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
NoelDeMartin committed Jun 9, 2024
1 parent 460e233 commit 5039113
Show file tree
Hide file tree
Showing 36 changed files with 339 additions and 32 deletions.
5 changes: 3 additions & 2 deletions cypress/e2e/tasks.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ describe('Tasks', () => {

// Act
cy.ariaLabel('Select task \\"Cook Ramen\\"').click();
cy.ariaLabel('Remove').click();
cy.press('Ok');
cy.ariaLabel('Delete').click();
cy.see('This will delete your task Cook Ramen');
cy.press('Delete');

// Assert
cy.dontSee('Cook Ramen');
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/workspaces.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('Workspaces', () => {
cy.ariaInput('Name').type('Groceries{enter}');

// Act
cy.ariaLabel('Edit Groceries list').click({ force: true });
cy.ariaLabel('Groceries list settings').click({ force: true });
cy.ariaInput('Name').clear().type('Learning{enter}');

// Assert
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"test:serve-pod": "community-solid-server -l warn"
},
"dependencies": {
"@aerogel/core": "0.0.0-next.9f9564ab9f8da05f60d7868db361edbc5601ee39",
"@aerogel/core": "0.0.0-next.7eac6e53dcf9fe93d7abdc4bc97e5ce69970efa7",
"@aerogel/plugin-i18n": "0.0.0-next.464f8d4bc58710df35b52ea396ccd8c40b73c664",
"@aerogel/plugin-offline-first": "0.0.0-next.9f9564ab9f8da05f60d7868db361edbc5601ee39",
"@aerogel/plugin-routing": "next",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ const colorClasses = computed(() => {
case Colors.Clear:
return 'hover:bg-gray-100 focus-visible:outline-gray-700';
case Colors.Danger:
return '';
return [
'bg-red-600 text-white shadow-sm',
'hover:bg-red-500',
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600',
].join(' ');
case Colors.Primary:
default:
return [
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { UIComponents } from '@aerogel/core';

import AlertModal from './overrides/AlertModal.vue';
import ConfirmModal from './overrides/ConfirmModal.vue';
import ErrorReportModal from './overrides/ErrorReportModal.vue';
import LoadingModal from './overrides/LoadingModal.vue';
import PromptModal from './overrides/PromptModal.vue';
import SnackbarNotification from './overrides/SnackbarNotification.vue';

export const components = {
[UIComponents.AlertModal]: AlertModal,
[UIComponents.ConfirmModal]: ConfirmModal,
[UIComponents.ErrorReportModal]: ErrorReportModal,
[UIComponents.LoadingModal]: LoadingModal,
[UIComponents.PromptModal]: PromptModal,
[UIComponents.Snackbar]: SnackbarNotification,
};
File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions src/components/overrides/AlertModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<FloatingModal :title="title" close-hidden>
<AGMarkdown :text="message" />
</FloatingModal>
</template>

<script setup lang="ts">
import { useAlertModalProps } from '@aerogel/core';
defineProps(useAlertModalProps());
</script>
20 changes: 20 additions & 0 deletions src/components/overrides/ConfirmModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<template>
<FloatingModal v-slot="{ close }" :title="title || message" :cancellable="false">
<AGMarkdown v-if="title" :text="message" />
<div class="mt-4 flex flex-row-reverse">
<TextButton :color="acceptColor" @click="close(true)">
{{ renderedAcceptText }}
</TextButton>
<TextButton :color="cancelColor" class="mr-2" @click="close(false)">
{{ renderedCancelText }}
</TextButton>
</div>
</FloatingModal>
</template>

<script setup lang="ts">
import { useConfirmModal, useConfirmModalProps } from '@aerogel/core';
const props = defineProps(useConfirmModalProps());
const { renderedAcceptText, renderedCancelText } = useConfirmModal(props);
</script>
56 changes: 56 additions & 0 deletions src/components/overrides/ErrorReportModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<FloatingModal close-hidden>
<div class="flex items-center">
<AGErrorReportModalTitle
class="text-lg font-semibold leading-6 text-gray-900"
:report="report"
:current-report="activeReportIndex + 1"
:total-reports="reports.length"
/>
<IconButton
v-if="reports.length > 1"
class="ml-1"
:title="previousReportText"
:aria-label="previousReportText"
:disabled="activeReportIndex === 0"
@click="activeReportIndex--"
>
<i-zondicons-cheveron-left class="h-5 w-5" />
</IconButton>
<IconButton
v-if="reports.length > 1"
:title="nextReportText"
:aria-label="nextReportText"
:disabled="activeReportIndex === reports.length - 1"
@click="activeReportIndex++"
>
<i-zondicons-cheveron-right class="h-5 w-5" />
</IconButton>
<div class="flex-1" />
<AGErrorReportModalButtons :report="report">
<template
#default="{ url, handler, iconComponent, description }: IAGErrorReportModalButtonsDefaultSlotProps"
>
<IconButton
:url="url"
:title="description"
:aria-label="description"
@click="handler"
>
<component :is="iconComponent" class="h-5 w-5" />
</IconButton>
</template>
</AGErrorReportModalButtons>
</div>
<AGMarkdown v-if="report.description" :text="report.description" />
<pre class="mt-4 max-h-[80vh] overflow-auto rounded-lg bg-red-50 p-2 text-sm text-red-900" v-text="details" />
</FloatingModal>
</template>

<script setup lang="ts">
import { useErrorReportModal, useErrorReportModalProps } from '@aerogel/core';
import type { IAGErrorReportModalButtonsDefaultSlotProps } from '@aerogel/core';
const props = defineProps(useErrorReportModalProps());
const { activeReportIndex, details, nextReportText, previousReportText, report } = useErrorReportModal(props);
</script>
15 changes: 15 additions & 0 deletions src/components/overrides/LoadingModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<FloatingModal :cancellable="false">
<div class="flex items-center">
<i-svg-spinners-ring-resize class="mr-2 h-6 w-6 text-[--primary-600]" />
<AGMarkdown :text="renderedMessage" />
</div>
</FloatingModal>
</template>

<script setup lang="ts">
import { useLoadingModal, useLoadingModalProps } from '@aerogel/core';
const props = defineProps(useLoadingModalProps());
const { renderedMessage } = useLoadingModal(props);
</script>
97 changes: 97 additions & 0 deletions src/components/overrides/Overrides.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<template>
<Story :layout="{ type: 'grid', width: '90%' }">
<Variant title="Playground">
<div class="flex space-x-3">
<TextButton @click="$ui.alert(alertTitle, alertMessage)">
Alert
</TextButton>
<TextButton @click="$ui.confirm(confirmTitle, confirmMessage)">
Confirm
</TextButton>
<TextButton @click="$ui.prompt(promptTitle, promptMessage)">
Prompt
</TextButton>
<TextButton @click="$ui.loading(loadingMessage, after({ seconds: loadingDuration }))">
Loading
</TextButton>
<TextButton @click="$ui.showSnackbar(snackbarMessage, snackbarOptions)">
Snackbar
</TextButton>
<TextButton @click="$errors.inspect(errorReports)">
Error Report
</TextButton>
</div>

<AGAppOverlays />

<template #controls>
<HstSelect v-model="themeColor" title="Theme Color" :options="themeColorOptions" />
<HstText v-model="alertTitle" title="Alert Title" />
<HstText v-model="alertMessage" title="Alert Message" />
<HstText v-model="confirmTitle" title="Confirm Title" />
<HstText v-model="confirmMessage" title="Confirm Message" />
<HstText v-model="promptTitle" title="Prompt Title" />
<HstText v-model="promptMessage" title="Prompt Message" />
<HstText v-model="loadingMessage" title="Loading Message" />
<HstNumber v-model="loadingDuration" title="Loading Duration" />
<HstText v-model="snackbarMessage" title="Snackbar Message" />
<HstSelect v-model="snackbarColor" title="Snackbar Color" :options="snackbarColors" />
<HstText v-model="snackbarAction" title="Snackbar Action" />
<HstText v-model="errorReportTitle" title="Error Report Title" />
<HstText v-model="errorReportDescription" title="Error Report Description" />
</template>
</Variant>
</Story>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { after, invert } from '@noeldemartin/utils';
import { Colors, SnackbarColors } from '@aerogel/core';
import type { ErrorReport, ShowSnackbarOptions } from '@aerogel/core';
import { useThemeColor } from '@/utils/histoire';
const [themeColor, themeColorOptions] = useThemeColor();
const alertTitle = ref('Something important happened');
const alertMessage = ref('And here you can read the details...');
const confirmTitle = ref('Confirmation');
const confirmMessage = ref('Are you sure?');
const promptTitle = ref('Prompt');
const promptMessage = ref('How old are you?');
const loadingMessage = ref('Loading...');
const loadingDuration = ref(3);
const snackbarMessage = ref('Something happened');
const snackbarColor = ref(Colors.Secondary);
const snackbarColors = invert(SnackbarColors);
const snackbarAction = ref('Ok');
const snackbarOptions = computed((): ShowSnackbarOptions => {
if (!snackbarAction.value) {
return {};
}
return {
color: snackbarColor.value,
actions: [
{
text: snackbarAction.value,
dismiss: true,
},
],
};
});
const errorReportTitle = ref('Error');
const errorReportDescription = ref('Something went wrong!');
const errorReports = computed((): ErrorReport[] => [
{
title: errorReportTitle.value,
description: errorReportDescription.value,
details: new Error().stack,
},
{
title: errorReportTitle.value,
description: errorReportDescription.value,
details: new Error().stack,
},
]);
</script>
24 changes: 24 additions & 0 deletions src/components/overrides/PromptModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<FloatingModal v-slot="{ close }" :title="title || message" :cancellable="false">
<AGMarkdown v-if="title" :text="message" />
<AGForm :form="form" class="mt-2" @submit="close(form.draft)">
<TextInput name="draft" :placeholder="placeholder" :label="label" />
<div class="mt-4 flex flex-row-reverse">
<TextButton :color="acceptColor" @click="close(true)">
{{ renderedAcceptText }}
</TextButton>
<TextButton :color="cancelColor" class="mr-2" @click="close(false)">
{{ renderedCancelText }}
</TextButton>
</div>
</AGForm>
</FloatingModal>
</template>

<script setup lang="ts">
import { requiredStringInput, useForm, usePromptModal, usePromptModalProps } from '@aerogel/core';
const props = defineProps(usePromptModalProps());
const form = useForm({ draft: requiredStringInput(props.defaultValue ?? '') });
const { renderedAcceptText, renderedCancelText } = usePromptModal(props);
</script>
34 changes: 34 additions & 0 deletions src/components/overrides/SnackbarNotification.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<AGHeadlessSnackbar class="flex items-center gap-2 rounded-lg p-2 shadow-lg ring-1" :class="colorClasses">
<AGMarkdown :text="message" inline />

<TextButton
v-for="(action, i) of actions"
:key="i"
:color="color"
:class="color === 'secondary' && 'hover:bg-gray-800 focus-visible:outline-gray-700'"
class="rounded-md"
@click="activate(action)"
>
{{ action.text }}
</TextButton>
</AGHeadlessSnackbar>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { Colors, useSnackbar, useSnackbarProps } from '@aerogel/core';
const props = defineProps(useSnackbarProps());
const { activate } = useSnackbar(props);
const colorClasses = computed(() => {
switch (props.color) {
case Colors.Danger:
return 'bg-red-50 text-red-900 ring-red-100 ring-opacity-50';
case Colors.Secondary:
default:
return 'bg-gray-900 text-white ring-black';
}
});
</script>
Loading

0 comments on commit 5039113

Please sign in to comment.