Skip to content

Commit

Permalink
Merge pull request #409 from gordlin/redesign-toc
Browse files Browse the repository at this point in the history
Implement ToC redesign/refactor, both-language previews
  • Loading branch information
yileifeng authored Nov 22, 2024
2 parents 273c2e5 + 6b809c4 commit 9205ee2
Show file tree
Hide file tree
Showing 13 changed files with 1,634 additions and 282 deletions.
12 changes: 7 additions & 5 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 @@ -27,7 +27,7 @@
"nouislider": "^15.5.0",
"ramp-config-editor_editeur-config-pcar": "^3.6.0",
"ramp-pcar": "^4.8.0",
"ramp-storylines_demo-scenarios-pcar": "^3.2.4",
"ramp-storylines_demo-scenarios-pcar": "^3.2.8",
"throttle-debounce": "^5.0.0",
"url": "^0.11.3",
"uuid": "^9.0.0",
Expand Down
2 changes: 2 additions & 0 deletions src/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export default class App extends Vue {
}
}
}
</script>

<style lang="scss">
Expand Down
565 changes: 462 additions & 103 deletions src/components/editor.vue

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions src/components/helpers/action-modal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<template>
<vue-final-modal
:modalId="name"
content-class="flex flex-col max-h-full overflow-y-auto max-w-xl mx-4 p-4 bg-white border rounded-lg space-y-2"
class="flex justify-center items-center"
>
<div class="mx-5 my-2">
<h2 slot="header" class="text-2xl font-bold mb-1">{{ title }}</h2>
<p>{{ message }}</p>
<div class="w-full flex justify-end mt-3">
<button class="editor-button bg-black text-white hover:bg-gray-800" @click="onOk">
{{ $t('editor.slides.continue') }}
</button>
<button class="editor-button hover:bg-gray-800" @click="onCancel">
{{ $t('editor.cancel') }}
</button>
</div>
</div>
</vue-final-modal>
</template>

<script lang="ts">
import { Options, Prop, Vue } from 'vue-property-decorator';
import { VueFinalModal } from 'vue-final-modal';
// import { Options } from 'vue-property-decorator';
@Options({
components: {
'vue-final-modal': VueFinalModal
}
})
export default class MetadataEditorV extends Vue {
@Prop() name!: string;
@Prop() title!: string;
@Prop() message!: string;
onOk(): void {
this.$emit('ok');
this.$vfm.close(this.name);
}
onCancel(): void {
this.$emit('Cancel');
this.$vfm.close(this.name);
}
}
</script>

<style scoped lang="css">
h2 {
line-height: 1.3;
border-bottom: 0px;
}
button {
border-radius: 3px;
padding: 5px 12px;
margin: 0px 10px;
font-weight: 600;
transition-duration: 0.2s;
}
.vfm__content button:hover:enabled {
background-color: #dbdbdb;
color: black;
}
.vfm__content button:disabled {
border: 1px solid gray;
color: gray;
cursor: not-allowed;
}
</style>
201 changes: 201 additions & 0 deletions src/components/helpers/dropdown-menu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
<template>
<div ref="el">
<button
type="button"
class="text-gray-500 hover:text-black dropdown-button"
@click="toggleDropdown"
:content="tooltip"
:aria-label="ariaLabel ? String(ariaLabel) : String(tooltip)"
v-tippy="{
placement: tooltipPlacement,
appendTo: 'parent',
trigger: 'manual',
delay: '200',
touch: ['hold', 500]
}"
ref="dropdownTrigger"
>
<slot name="header"></slot>
</button>
<div
v-show="open"
@click="
popper.update();
open = false;
"
class="rv-dropdown shadow-md border border-gray:200 py-1 bg-white rounded z-10"
:class="{ 'text-center': centered }"
ref="dropdown"
>
<slot v-bind:close="() => (open = !open)"></slot>
</div>
</div>
</template>

<script setup lang="ts">
import { ref, reactive, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';
import type { Placement, Modifier, State } from '@popperjs/core';
import { createPopper, detectOverflow } from '@popperjs/core';
const open = ref<boolean>(false);
const popper = ref<any>(null);
const watchers = reactive<Array<Function>>([]);
const el = ref();
const dropdown = ref<HTMLElement>();
const dropdownTrigger = ref<Element>();
const props = defineProps({
position: {
type: String,
default: 'top-start'
},
popperOptions: {
type: Object,
default() {
return {};
}
},
tooltip: { type: String },
tooltipPlacement: { type: String, default: 'bottom' },
tooltipPlacementAlt: { type: String, default: 'top' },
centered: { type: Boolean, default: true },
ariaLabel: { type: String }
});
watchers.push(
watch(open, () => {
popper.value.update();
})
);
const toggleDropdown = () => {
open.value = !open.value;
(dropdownTrigger.value as any)._tippy.hide();
};
const focusDropdownTrigger = () => {
(dropdownTrigger.value as any)._tippy.setProps({
placement: open.value ? props.tooltipPlacementAlt : props.tooltipPlacement
});
(dropdownTrigger.value as any)._tippy.show();
};
const blurDropdownTrigger = () => {
(dropdownTrigger.value as any)._tippy.hide();
};
onMounted(() => {
window.addEventListener(
'click',
(event) => {
if (!el.value || !el.value.contains(event.target)) {
open.value = false;
}
},
{ capture: true }
);
window.addEventListener('blur', () => {
open.value = false;
});
window.addEventListener('focusin', (event) => {
if (!el.value || !el.value.contains(event.target)) {
open.value = false;
}
});
dropdownTrigger.value!.addEventListener('focus', focusDropdownTrigger);
dropdownTrigger.value!.addEventListener('blur', blurDropdownTrigger);
dropdownTrigger.value!.addEventListener('mouseover', focusDropdownTrigger);
dropdownTrigger.value!.addEventListener('mouseleave', blurDropdownTrigger);
// nextTick should prevent any race conditions by letting the child elements render before trying to place them using popper
nextTick(() => {
const overflowScrollModifier: Modifier<'overflowScroll', {}> = {
name: 'overflowScroll',
enabled: true,
phase: 'main',
fn({ state }: { state: State }) {
const { bottom } = detectOverflow(state);
if (bottom > 0) {
state.styles.popper.overflowY = bottom > 100 ? 'auto' : undefined;
state.styles.popper.overflowX = 'hidden';
state.styles.popper.height = `${state.rects.popper.height - bottom - 8}px`;
} else {
state.styles.popper.height = 'auto';
}
}
};
if (dropdownTrigger.value && dropdown.value) {
popper.value = createPopper(dropdownTrigger.value as Element, dropdown.value as HTMLElement, {
placement: (props.position || 'bottom') as Placement,
modifiers: [
overflowScrollModifier,
{
name: 'offset',
options: {
offset: [0, 5]
}
}
],
...props.popperOptions
});
}
});
});
onBeforeUnmount(() => {
watchers.forEach((unwatch) => unwatch());
window.removeEventListener(
'click',
(event) => {
if (!el.value || !el.value.contains(event.target)) {
open.value = false;
}
},
{ capture: true }
);
window.removeEventListener('blur', () => {
open.value = false;
});
window.removeEventListener('focusin', (event) => {
if (!el.value || !el.value.contains(event.target)) {
open.value = false;
}
});
dropdownTrigger.value!.removeEventListener('focus', focusDropdownTrigger);
dropdownTrigger.value!.removeEventListener('blur', blurDropdownTrigger);
dropdownTrigger.value!.removeEventListener('mouseover', focusDropdownTrigger);
dropdownTrigger.value!.removeEventListener('mouseleave', blurDropdownTrigger);
open.value = false;
});
</script>

<style lang="scss">
.rv-dropdown > * {
padding: 0.5rem 1rem;
display: block !important;
text-decoration: none !important;
}
.rv-dropdown > :not(.disabled) {
color: #2d3748 !important;
}
.rv-dropdown > *:hover:not(.disabled) {
background-color: #eee;
}
</style>
Loading

0 comments on commit 9205ee2

Please sign in to comment.