From 9384f5399da39e53855beb8e7f8ded1aa56bf72e Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Tue, 27 Dec 2022 14:36:33 +0900
Subject: rename: client -> frontend

---
 .../frontend/src/components/MkObjectView.value.vue | 160 +++++++++++++++++++++
 1 file changed, 160 insertions(+)
 create mode 100644 packages/frontend/src/components/MkObjectView.value.vue

(limited to 'packages/frontend/src/components/MkObjectView.value.vue')

diff --git a/packages/frontend/src/components/MkObjectView.value.vue b/packages/frontend/src/components/MkObjectView.value.vue
new file mode 100644
index 0000000000..0c7230d783
--- /dev/null
+++ b/packages/frontend/src/components/MkObjectView.value.vue
@@ -0,0 +1,160 @@
+<template>
+<div class="igpposuu _monospace">
+	<div v-if="value === null" class="null">null</div>
+	<div v-else-if="typeof value === 'boolean'" class="boolean" :class="{ true: value, false: !value }">{{ value ? 'true' : 'false' }}</div>
+	<div v-else-if="typeof value === 'string'" class="string">"{{ value }}"</div>
+	<div v-else-if="typeof value === 'number'" class="number">{{ number(value) }}</div>
+	<div v-else-if="isArray(value) && isEmpty(value)" class="array empty">[]</div>
+	<div v-else-if="isArray(value)" class="array">
+		<div v-for="i in value.length" class="element">
+			{{ i }}: <XValue :value="value[i - 1]" collapsed/>
+		</div>
+	</div>
+	<div v-else-if="isObject(value) && isEmpty(value)" class="object empty">{}</div>
+	<div v-else-if="isObject(value)" class="object">
+		<div v-for="k in Object.keys(value)" class="kv">
+			<button class="toggle _button" :class="{ visible: collapsable(value[k]) }" @click="collapsed[k] = !collapsed[k]">{{ collapsed[k] ? '+' : '-' }}</button>
+			<div class="k">{{ k }}:</div>
+			<div v-if="collapsed[k]" class="v">
+				<button class="_button" @click="collapsed[k] = !collapsed[k]">
+					<template v-if="typeof value[k] === 'string'">"..."</template>
+					<template v-else-if="isArray(value[k])">[...]</template>
+					<template v-else-if="isObject(value[k])">{...}</template>
+				</button>
+			</div>
+			<div v-else class="v"><XValue :value="value[k]"/></div>
+		</div>
+	</div>
+</div>
+</template>
+
+<script lang="ts">
+import { computed, defineComponent, reactive, ref } from 'vue';
+import number from '@/filters/number';
+
+export default defineComponent({
+	name: 'XValue',
+
+	props: {
+		value: {
+			required: true,
+		},
+	},
+
+	setup(props) {
+		const collapsed = reactive({});
+
+		if (isObject(props.value)) {
+			for (const key in props.value) {
+				collapsed[key] = collapsable(props.value[key]);
+			}
+		}
+
+		function isObject(v): boolean {
+			return typeof v === 'object' && !Array.isArray(v) && v !== null;
+		}
+
+		function isArray(v): boolean {
+			return Array.isArray(v);
+		}
+
+		function isEmpty(v): boolean {
+			return (isArray(v) && v.length === 0) || (isObject(v) && Object.keys(v).length === 0);
+		}
+
+		function collapsable(v): boolean {
+			return (isObject(v) || isArray(v)) && !isEmpty(v);
+		}
+
+		return {
+			number,
+			collapsed,
+			isObject,
+			isArray,
+			isEmpty,
+			collapsable,
+		};
+	},
+});
+</script>
+
+<style lang="scss" scoped>
+.igpposuu {
+	display: inline;
+
+	> .null {
+		display: inline;
+		opacity: 0.7;
+	}
+
+	> .boolean {
+		display: inline;
+		color: var(--codeBoolean);
+
+		&.true {
+			font-weight: bold;
+		}
+
+		&.false {
+			opacity: 0.7;
+		}
+	}
+
+	> .string {
+		display: inline;
+		color: var(--codeString);
+	}
+
+	> .number {
+		display: inline;
+		color: var(--codeNumber);
+	}
+
+	> .array.empty {
+		display: inline;
+		opacity: 0.7;
+	}
+
+	> .array:not(.empty) {
+		display: inline;
+
+		> .element {
+			display: block;
+			padding-left: 16px;
+		}
+	}
+
+	> .object.empty {
+		display: inline;
+		opacity: 0.7;
+	}
+
+	> .object:not(.empty) {
+		display: inline;
+
+		> .kv {
+			display: block;
+			padding-left: 16px;
+
+			> .toggle {
+				width: 16px;
+				color: var(--accent);
+				visibility: hidden;
+
+				&.visible {
+					visibility: visible;
+				}
+			}
+
+			> .k {
+				display: inline;
+				margin-right: 8px;
+			}
+
+			> .v {
+				display: inline;
+			}
+		}
+	}
+}
+</style>
-- 
cgit v1.2.3-freya

