Skip to content

Commit

Permalink
Create new window type for SpecCharInputDemo
Browse files Browse the repository at this point in the history
  • Loading branch information
Lev Z Király authored and Lev Z Király committed Nov 17, 2023
1 parent c70df5f commit 18556aa
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 9 deletions.
26 changes: 24 additions & 2 deletions components/app-header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ const titlestring = computed(() => {
return data.value?.projectConfig?.logo?.string;
});
function createWindowId(_item: ItemType) {
/**
* We intentionally do *not* use `item.target` for window id, because we don't want to
Expand All @@ -40,6 +38,16 @@ function createWindowTitle(item: ItemType) {
function onSelectMenuItem(item: ItemType) {
switch (item.componentName) {
case "SpecCharInputDemo": {
addWindow({
id: createWindowId(null),
title: "Special Character Input Demo",
kind: "spec-char-input-demo",
params: {},
});
break;
}
case "BiblioQuery": {
addWindow({
id: createWindowId(item),
Expand Down Expand Up @@ -166,6 +174,20 @@ function onSelectMenuItem(item: ItemType) {
@select-menu-item="onSelectMenuItem"
/>
</div>

<button
class="btn"
@click="
onSelectMenuItem({
id: 'SpecCharInputDemo',
type: 'item',
componentName: 'SpecCharInputDemo',
params: {},
})
"
>
Showtime
</button>
</div>
</header>
</template>
Expand Down
97 changes: 97 additions & 0 deletions components/input-extended.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<script setup lang="ts">
defineProps(["modelValue"]);
const emit = defineEmits(["update:modelValue"]);
const inputElement = ref();
const myString = ref("");
watch(myString, (val) => {
emit("update:modelValue", val);
});
const specChars = [
"&#x2019;",
"&#x0294;",
"&#x0101;",
"&#x1e05;",
"&#x0295;",
"&#x1e0f;",
"&#x1e0f;&#x0323;",
"&#x0113;",
"&#x0121;",
"&#x01e7;",
"&#x1e25;",
"&#x012b;",
"&#x1d35;",
"&#x1e37;",
"&#x1e43;",
"&#x014d;",
"&#x1e5b;",
"&#x1e63;",
"&#x0073;&#x0320;",
"&#x0161;",
"&#x1e6d;",
"&#x1e6f;",
"&#x016b;",
"&#x1e93;",
"&#x017e;",
];
let cursorPosition = 0;
const Type = (htmlChar: string): void => {
let decodedChar = parseHtmlEntities(htmlChar);
myString.value =
myString.value.substring(0, cursorPosition) +
decodedChar +
myString.value.substring(cursorPosition, myString.value.length);
cursorPosition += decodedChar.length;
setCursorPosition(cursorPosition);
};
const setCursorPosition = (pos: number) => {
if (inputElement.value.createTextRange) {
var range = inputElement.value.createTextRange();
range.move("character", pos);
range.select();
}
if (inputElement.value.selectionStart) {
inputElement.value.focus();
inputElement.value.setSelectionRange(pos, pos);
}
};
function parseHtmlEntities(str: string) {
return str.replace(/&#x([0-9a-f]{1,4});/gi, function (match, numStr) {
var num = parseInt(numStr, 16);
return String.fromCharCode(num);
});
}
const registerCursorPosition = (e: Event) => {
cursorPosition = e.target.selectionStart;
};
</script>

<template>
<div>
<!-- eslint-disable-next-line vue/no-v-html -->
<button
v-for="(c, i) in specChars"
:key="i"
class="bg-gray-300 px-4 py-2 font-bold text-gray-800 hover:bg-gray-400"
@click="Type(c)"
v-html="c"
></button>
</div>
<div>
<!-- eslint-disable-next-line vuejs-accessibility/form-control-has-label -->
<input
ref="inputElement"
v-model="myString"
type="text"
class="m-2 rounded border px-3 py-2 leading-tight shadow"
@keyup="registerCursorPosition"
@click="registerCursorPosition"
/>
</div>
</template>
14 changes: 14 additions & 0 deletions components/spec-char-input-demo-window-content.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup>
const myString = ref("");
</script>

<template>
<div>
<div>
<InputExtended v-model="myString" />
</div>
<div>
{{ myString }}
</div>
</div>
</template>
4 changes: 4 additions & 0 deletions components/window-content.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ const props = defineProps<Props>();
<template>
<GeoMapWindowContent v-if="props.item.kind === 'geo-map'" :params="props.item.params" />
<TextWindowContent v-if="props.item.kind === 'text'" :params="props.item.params" />
<SpecCharInputDemoWindowContent
v-if="props.item.kind === 'spec-char-input-demo'"
:params="props.item.params"
/>
<pre v-else>{{ props }}</pre>
</template>
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"is-ci": "^3.0.1",
"leaflet": "^1.9.4",
"lucide-vue-next": "^0.289.0",
"nanoid": "^5.0.3",
"npm-run-all2": "^6.1.1",
"nuxt": "^3.7.4",
"pinia": "^2.1.7",
Expand Down
23 changes: 16 additions & 7 deletions pnpm-lock.yaml

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

6 changes: 6 additions & 0 deletions stores/use-windows-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ export interface TextWindowItem extends WindowItemBase {
};
}

export interface SpecCharInputDemo extends WindowItemBase {
kind: "spec-char-input-demo";
params: object;
}

export type WindowItem =
| BibliographyQueryWindowItem
| CorpusQueryWindowItem
Expand All @@ -71,6 +76,7 @@ export type WindowItem =
| DictionaryQueryWindowItem
| GeoMapWindowItem
| SampleTextWindowItem
| SpecCharInputDemo
| TextWindowItem;

export type WindowItemKind = WindowItem["kind"];
Expand Down
1 change: 1 addition & 0 deletions utils/is-window-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const windowTypeMap: Record<WindowType, WindowItemKind> = {
SampleText: "sample-text",
Text: "text",
WMap: "geo-map",
SpecCharInputDemo: "spec-char-input-demo",
};

export function isWindowType(value: string | undefined): value is WindowType {
Expand Down

0 comments on commit 18556aa

Please sign in to comment.