Text Format Improvements (#10655)

- changes the font to match JSON viz
- changes colour of symbols to #df8800
- shows selected formatting option as button icon
![text-format-imp-1](https://github.com/user-attachments/assets/81a74837-5ae1-44c2-a78e-c351d7f67736)


- removes grid toolbar for single item visualizations
<img width="320" alt="image" src="https://github.com/user-attachments/assets/b6de6f80-0222-40bf-bd74-4e70e8ad1c31">

- sort styling for narrow components
-
![image](https://github.com/user-attachments/assets/2fb8b1f0-0071-4d9f-86b2-f15b0638f64b)
This commit is contained in:
marthasharkey 2024-07-25 17:01:31 +01:00 committed by GitHub
parent 5366dd384f
commit 6189eb3a1c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 66 deletions

View File

@ -3,7 +3,7 @@ import DropdownMenu from '@/components/DropdownMenu.vue'
import MenuButton from '@/components/MenuButton.vue' import MenuButton from '@/components/MenuButton.vue'
import SvgButton from '@/components/SvgButton.vue' import SvgButton from '@/components/SvgButton.vue'
import SvgIcon from '@/components/SvgIcon.vue' import SvgIcon from '@/components/SvgIcon.vue'
import { ref, watch } from 'vue' import { computed, ref, watch } from 'vue'
import { TextFormatOptions } from './visualizations/TableVisualization.vue' import { TextFormatOptions } from './visualizations/TableVisualization.vue'
const emit = defineEmits<{ const emit = defineEmits<{
@ -13,18 +13,40 @@ const emit = defineEmits<{
const textFormatterSelected = ref(TextFormatOptions.Partial) const textFormatterSelected = ref(TextFormatOptions.Partial)
watch(textFormatterSelected, (selected) => emit('changeFormat', selected)) watch(textFormatterSelected, (selected) => emit('changeFormat', selected))
const buttonClass = computed(() => {
return {
full: isFormatOptionSelected(TextFormatOptions.On),
partial: isFormatOptionSelected(TextFormatOptions.Partial),
strikethrough: isFormatOptionSelected(TextFormatOptions.Off),
}
})
const isFormatOptionSelected = (option: TextFormatOptions): boolean =>
option === textFormatterSelected.value
const open = ref(false) const open = ref(false)
const toggleOpen = () => {
open.value = !open.value
}
const changeFormat = (option: TextFormatOptions) => {
textFormatterSelected.value = option
toggleOpen()
}
</script> </script>
<template> <template>
<DropdownMenu v-model:open="open" class="TextFormattingSelector"> <DropdownMenu v-model:open="open" class="TextFormattingSelector">
<template #button><SvgIcon name="paragraph" title="Text Display Options" /> </template> <template #button
><div :class="buttonClass">
<SvgIcon name="paragraph" title="Text Display Options" /></div
></template>
<template #entries> <template #entries>
<MenuButton <MenuButton
class="full-format" class="full"
:title="`Text displayed in monospace font and all whitespace characters displayed as symbols`" :title="`Text displayed in monospace font and all whitespace characters displayed as symbols`"
@click="() => emit('changeFormat', TextFormatOptions.On)" @click="() => changeFormat(TextFormatOptions.On)"
> >
<SvgIcon name="paragraph" /> <SvgIcon name="paragraph" />
<div class="title">Full whitespace rendering</div> <div class="title">Full whitespace rendering</div>
@ -33,7 +55,7 @@ const open = ref(false)
<MenuButton <MenuButton
class="partial" class="partial"
:title="`Text displayed in monospace font, only multiple spaces displayed with &#183;`" :title="`Text displayed in monospace font, only multiple spaces displayed with &#183;`"
@click="() => emit('changeFormat', TextFormatOptions.Partial)" @click="() => changeFormat(TextFormatOptions.Partial)"
> >
<SvgIcon name="paragraph" /> <SvgIcon name="paragraph" />
<div class="title">Partial whitespace rendering</div> <div class="title">Partial whitespace rendering</div>
@ -41,7 +63,7 @@ const open = ref(false)
<MenuButton <MenuButton
class="off" class="off"
@click="() => emit('changeFormat', TextFormatOptions.Off)" @click="() => changeFormat(TextFormatOptions.Off)"
title="`No formatting applied to text`" title="`No formatting applied to text`"
> >
<div class="strikethrough"> <div class="strikethrough">
@ -99,7 +121,7 @@ const open = ref(false)
justify-content: flex-start; justify-content: flex-start;
} }
.full-format { .full {
stroke: black; stroke: black;
fill: #000000; fill: #000000;
justify-content: flex-start; justify-content: flex-start;

View File

@ -16,6 +16,7 @@ const props = defineProps<{
belowNode?: boolean belowNode?: boolean
/** If true, the visualization should display below the toolbar buttons. */ /** If true, the visualization should display below the toolbar buttons. */
belowToolbar?: boolean belowToolbar?: boolean
toolbarOverflow?: boolean
}>() }>()
const config = useVisualizationConfig() const config = useVisualizationConfig()
@ -87,6 +88,12 @@ const contentStyle = computed(() => {
height: config.fullscreen ? undefined : `${config.height}px`, height: config.fullscreen ? undefined : `${config.height}px`,
} }
}) })
const overFlowStyle = computed(() => {
return {
overflow: props.toolbarOverflow ? 'visible' : 'hidden',
}
})
</script> </script>
<template> <template>
@ -160,10 +167,13 @@ const contentStyle = computed(() => {
</Suspense> </Suspense>
</div> </div>
</div> </div>
<div v-if="$slots.toolbar && !config.isPreview" class="visualization-defined-toolbars"> <div
<div class="toolbar-wrapper"> v-if="$slots.toolbar && !config.isPreview"
<div class="inner-toolbar"><slot name="toolbar"></slot></div> id="visualization-defined-toolbar"
</div> class="visualization-defined-toolbars"
:style="overFlowStyle"
>
<div class="toolbar"><slot name="toolbar"></slot></div>
</div> </div>
<div <div
class="after-toolbars node-type" class="after-toolbars node-type"
@ -252,6 +262,7 @@ const contentStyle = computed(() => {
.after-toolbars { .after-toolbars {
margin-left: auto; margin-left: auto;
margin-right: 8px; margin-right: 8px;
overflow: hidden;
} }
.node-type { .node-type {
@ -289,28 +300,7 @@ const contentStyle = computed(() => {
} }
.visualization-defined-toolbars { .visualization-defined-toolbars {
min-width: calc(100% - var(--permanent-toolbar-width)); max-width: calc(100% - var(--permanent-toolbar-width));
max-width: 100%;
overflow-x: clip;
overflow-y: visible;
}
.toolbar-wrapper {
position: relative;
display: flex;
border-radius: var(--radius-full);
z-index: 20;
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
border-radius: var(--radius-full);
}
} }
.invisible { .invisible {
@ -328,26 +318,4 @@ const contentStyle = computed(() => {
.VisualizationContainer :deep(> .toolbars > .toolbar > *) { .VisualizationContainer :deep(> .toolbars > .toolbar > *) {
position: relative; position: relative;
} }
.inner-toolbar {
position: relative;
display: flex;
border-radius: var(--radius-full);
gap: 12px;
padding: 8px;
z-index: 20;
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
border-radius: var(--radius-full);
background: var(--color-app-bg);
backdrop-filter: var(--blur-app-bg);
}
}
</style> </style>

View File

@ -260,31 +260,31 @@ function formatText(params: ICellRendererParams) {
return params.value return params.value
} }
const partialMappings = { const partialMappings = {
'\r': '<span style="color: lightgrey">␍</span> <br>', '\r': '<span style="color: #df8800">␍</span> <br>',
'\n': '<span style="color: lightgrey;">␊</span> <br>', '\n': '<span style="color: #df8800;">␊</span> <br>',
'\t': '<span style="white-space: break-spaces;"> </span>', '\t': '<span style="white-space: break-spaces;"> </span>',
} }
const fullMappings = { const fullMappings = {
'\r': '<span style="color: lightgrey">␍</span> <br>', '\r': '<span style="color: #df8800">␍</span> <br>',
'\n': '<span style="color: lightgrey">␊</span> <br>', '\n': '<span style="color: #df8800">␊</span> <br>',
'\t': '<span style="color: lightgrey; white-space: break-spaces;">&#8594; </span>', '\t': '<span style="color: #df8800; white-space: break-spaces;">&#8594; </span>',
} }
const replaceSpaces = const replaceSpaces =
textFormatterSelected.value === TextFormatOptions.On ? textFormatterSelected.value === TextFormatOptions.On ?
params.value.replaceAll(' ', '<span style="color: lightgrey">&#183;</span>') params.value.replaceAll(' ', '<span style="color: #df8800">&#183;</span>')
: params.value.replace(/ {2,}/g, function (match: string) { : params.value.replace(/ {2,}/g, function (match: string) {
return `<span style="color: lightgrey">${'&#183;'.repeat(match.length)}</span>` return `<span style="color: #df8800">${'&#183;'.repeat(match.length)}</span>`
}) })
const replaceReturns = replaceSpaces.replace( const replaceReturns = replaceSpaces.replace(
/\r\n/g, /\r\n/g,
'<span style="color: lightgrey">␍␊</span> <br>', '<span style="color: #df8800">␍␊</span> <br>',
) )
const renderOtherWhitespace = (match: string) => { const renderOtherWhitespace = (match: string) => {
return textFormatterSelected.value === TextFormatOptions.On && match != ' ' ? return textFormatterSelected.value === TextFormatOptions.On && match != ' ' ?
'<span style="color: lightgrey">&#9744;</span>' '<span style="color: #df8800">&#9744;</span>'
: match : match
} }
const newString = replaceReturns.replace(/[\s]/g, function (match: string) { const newString = replaceReturns.replace(/[\s]/g, function (match: string) {
@ -719,7 +719,7 @@ onUnmounted(() => {
</script> </script>
<template> <template>
<VisualizationContainer :belowToolbar="true" :overflow="true"> <VisualizationContainer :belowToolbar="true" :overflow="true" :toolbarOverflow="true">
<template #toolbar> <template #toolbar>
<TextFormattingSelector @changeFormat="(i) => updateTextFormat(i)" /> <TextFormattingSelector @changeFormat="(i) => updateTextFormat(i)" />
</template> </template>
@ -763,7 +763,7 @@ onUnmounted(() => {
--ag-grid-size: 3px; --ag-grid-size: 3px;
--ag-list-item-height: 20px; --ag-list-item-height: 20px;
flex-grow: 1; flex-grow: 1;
font-family: monospace; font-family: var(--font-mono);
} }
.table-visualization-status-bar { .table-visualization-status-bar {