diff options
Diffstat (limited to 'packages/frontend/src/components')
| -rw-r--r-- | packages/frontend/src/components/MkAsUi.vue | 107 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkButton.vue | 40 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkChartLegend.vue | 2 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkFlashPreview.vue | 112 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkLaunchPad.vue | 2 | ||||
| -rw-r--r-- | packages/frontend/src/components/MkPagePreview.vue | 19 | ||||
| -rw-r--r-- | packages/frontend/src/components/form/select.vue | 2 |
7 files changed, 267 insertions, 17 deletions
diff --git a/packages/frontend/src/components/MkAsUi.vue b/packages/frontend/src/components/MkAsUi.vue new file mode 100644 index 0000000000..bc1e25957b --- /dev/null +++ b/packages/frontend/src/components/MkAsUi.vue @@ -0,0 +1,107 @@ +<template> +<div> + <div v-if="c.type === 'root'" :class="$style.root"> + <template v-for="child in c.children" :key="child"> + <MkAsUi v-if="!g(child).hidden" :component="g(child)" :components="props.components" :size="size"/> + </template> + </div> + <span v-else-if="c.type === 'text'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, fontWeight: c.bold ? 'bold' : null, color: c.color ?? null }">{{ c.text }}</span> + <Mfm v-else-if="c.type === 'mfm'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, color: c.color ?? null }" :text="c.text"/> + <MkButton v-else-if="c.type === 'button'" :primary="c.primary" :rounded="c.rounded" :small="size === 'small'" @click="c.onClick">{{ c.text }}</MkButton> + <div v-else-if="c.type === 'buttons'" style="display: flex; gap: 8px; flex-wrap: wrap;"> + <MkButton v-for="button in c.buttons" :primary="button.primary" :rounded="button.rounded" :small="size === 'small'" @click="button.onClick">{{ button.text }}</MkButton> + </div> + <MkSwitch v-else-if="c.type === 'switch'" :model-value="valueForSwitch" @update:model-value="onSwitchUpdate"> + <template v-if="c.label" #label>{{ c.label }}</template> + <template v-if="c.caption" #caption>{{ c.caption }}</template> + </MkSwitch> + <MkTextarea v-else-if="c.type === 'textarea'" :model-value="c.default" @update:model-value="c.onInput"> + <template v-if="c.label" #label>{{ c.label }}</template> + <template v-if="c.caption" #caption>{{ c.caption }}</template> + </MkTextarea> + <MkInput v-else-if="c.type === 'textInput'" :small="size === 'small'" :model-value="c.default" @update:model-value="c.onInput"> + <template v-if="c.label" #label>{{ c.label }}</template> + <template v-if="c.caption" #caption>{{ c.caption }}</template> + </MkInput> + <MkInput v-else-if="c.type === 'numberInput'" :small="size === 'small'" :model-value="c.default" type="number" @update:model-value="c.onInput"> + <template v-if="c.label" #label>{{ c.label }}</template> + <template v-if="c.caption" #caption>{{ c.caption }}</template> + </MkInput> + <MkSelect v-else-if="c.type === 'select'" :small="size === 'small'" :model-value="c.default" @update:model-value="c.onChange"> + <template v-if="c.label" #label>{{ c.label }}</template> + <template v-if="c.caption" #caption>{{ c.caption }}</template> + <option v-for="item in c.items" :key="item.value" :value="item.value">{{ item.text }}</option> + </MkSelect> + <MkButton v-else-if="c.type === 'postFormButton'" :primary="c.primary" :rounded="c.rounded" :small="size === 'small'" @click="openPostForm">{{ c.text }}</MkButton> + <div v-else-if="c.type === 'container'" :class="[$style.container, { [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace', [$style.containerCenter]: c.align === 'center' }]" :style="{ backgroundColor: c.bgColor ?? null, color: c.fgColor ?? null, borderWidth: c.borderWidth ? `${c.borderWidth}px` : 0, borderColor: c.borderColor ?? 'var(--divider)', padding: c.padding ? `${c.padding}px` : 0, borderRadius: c.rounded ? '8px' : 0 }"> + <template v-for="child in c.children" :key="child"> + <MkAsUi v-if="!g(child).hidden" :component="g(child)" :components="props.components" :size="size"/> + </template> + </div> +</div> +</template> + +<script lang="ts" setup> +import { computed, defineAsyncComponent, onMounted, onUnmounted, Ref } from 'vue'; +import * as os from '@/os'; +import MkButton from '@/components/MkButton.vue'; +import MkInput from '@/components/form/input.vue'; +import MkSwitch from '@/components/form/switch.vue'; +import MkTextarea from '@/components/form/textarea.vue'; +import MkSelect from '@/components/form/select.vue'; +import { AsUiComponent } from '@/scripts/aiscript/ui'; + +const props = withDefaults(defineProps<{ + component: AsUiComponent; + components: Ref<AsUiComponent>[]; + size: 'small' | 'medium' | 'large'; +}>(), { + size: 'medium', +}); + +const c = props.component; + +function g(id) { + return props.components.find(x => x.value.id === id).value; +} + +let valueForSwitch = $ref(c.default ?? false); + +function onSwitchUpdate(v) { + valueForSwitch = v; + if (c.onChange) c.onChange(v); +} + +function openPostForm() { + os.post({ + initialText: c.form.text, + instant: true, + }); +} +</script> + +<style lang="scss" module> +.root { + display: flex; + flex-direction: column; + gap: 12px; +} + +.container { + display: flex; + flex-direction: column; + gap: 12px; +} + +.containerCenter { + text-align: center; +} + +.fontSerif { + font-family: serif; +} + +.fontMonospace { + font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace; +} +</style> diff --git a/packages/frontend/src/components/MkButton.vue b/packages/frontend/src/components/MkButton.vue index daf47e12d4..f9602de787 100644 --- a/packages/frontend/src/components/MkButton.vue +++ b/packages/frontend/src/components/MkButton.vue @@ -2,7 +2,7 @@ <button v-if="!link" ref="el" class="bghgjjyj _button" - :class="{ inline, primary, gradate, danger, rounded, full, small }" + :class="{ inline, primary, gradate, danger, rounded, full, small, large, asLike }" :type="type" @click="emit('click', $event)" @mousedown="onMousedown" @@ -41,6 +41,8 @@ const props = defineProps<{ danger?: boolean; full?: boolean; small?: boolean; + large?: boolean; + asLike?: boolean; }>(); const emit = defineEmits<{ @@ -131,6 +133,11 @@ function onMousedown(evt: MouseEvent): void { padding: 6px 12px; } + &.large { + font-size: 100%; + padding: 8px 16px; + } + &.full { width: 100%; } @@ -153,6 +160,37 @@ function onMousedown(evt: MouseEvent): void { } } + &.asLike { + background: rgba(255, 86, 125, 0.07); + color: #ff002f; + + &:not(:disabled):hover { + background: rgba(255, 74, 116, 0.11); + } + + &:not(:disabled):active { + background: rgba(224, 57, 96, 0.125); + } + + > .ripples { + ::v-deep(div) { + background: rgba(255, 60, 106, 0.15); + } + } + + &.primary { + background: rgb(241 97 132); + + &:not(:disabled):hover { + background: rgb(241 92 128); + } + + &:not(:disabled):active { + background: rgb(241 92 128); + } + } + } + &.gradate { font-weight: bold; color: var(--fgOnAccent) !important; diff --git a/packages/frontend/src/components/MkChartLegend.vue b/packages/frontend/src/components/MkChartLegend.vue index f33f753723..8d2a2be8e8 100644 --- a/packages/frontend/src/components/MkChartLegend.vue +++ b/packages/frontend/src/components/MkChartLegend.vue @@ -59,7 +59,7 @@ defineExpose({ &.disabled { text-decoration: line-through; - opacity: 0.6; + opacity: 0.5; } > .box { diff --git a/packages/frontend/src/components/MkFlashPreview.vue b/packages/frontend/src/components/MkFlashPreview.vue new file mode 100644 index 0000000000..1a82ffe5ab --- /dev/null +++ b/packages/frontend/src/components/MkFlashPreview.vue @@ -0,0 +1,112 @@ +<template> +<MkA :to="`/play/${flash.id}`" class="vhpxefrk _block" tabindex="-1"> + <article> + <header> + <h1 :title="flash.title">{{ flash.title }}</h1> + </header> + <p v-if="flash.summary" :title="flash.summary">{{ flash.summary.length > 85 ? flash.summary.slice(0, 85) + '…' : flash.summary }}</p> + <footer> + <img class="icon" :src="flash.user.avatarUrl"/> + <p>{{ userName(flash.user) }}</p> + </footer> + </article> +</MkA> +</template> + +<script lang="ts" setup> +import { } from 'vue'; +import * as misskey from 'misskey-js'; +import { userName } from '@/filters/user'; +import * as os from '@/os'; + +const props = defineProps<{ + //flash: misskey.entities.Flash; + flash: any; +}>(); +</script> + +<style lang="scss" scoped> +.vhpxefrk { + display: block; + + &:hover { + text-decoration: none; + color: var(--accent); + } + + > article { + padding: 16px; + + > header { + margin-bottom: 8px; + + > h1 { + margin: 0; + font-size: 1em; + color: var(--urlPreviewTitle); + } + } + + > p { + margin: 0; + color: var(--urlPreviewText); + font-size: 0.8em; + } + + > footer { + margin-top: 8px; + height: 16px; + + > img { + display: inline-block; + width: 16px; + height: 16px; + margin-right: 4px; + vertical-align: top; + } + + > p { + display: inline-block; + margin: 0; + color: var(--urlPreviewInfo); + font-size: 0.8em; + line-height: 16px; + vertical-align: top; + } + } + } + + @media (max-width: 700px) { + } + + @media (max-width: 550px) { + font-size: 12px; + + > article { + padding: 12px; + } + } + + @media (max-width: 500px) { + font-size: 10px; + + > article { + padding: 8px; + + > header { + margin-bottom: 4px; + } + + > footer { + margin-top: 4px; + + > img { + width: 12px; + height: 12px; + } + } + } + } +} + +</style> diff --git a/packages/frontend/src/components/MkLaunchPad.vue b/packages/frontend/src/components/MkLaunchPad.vue index 3ea90712a0..aab7631e36 100644 --- a/packages/frontend/src/components/MkLaunchPad.vue +++ b/packages/frontend/src/components/MkLaunchPad.vue @@ -50,7 +50,7 @@ const menu = defaultStore.state.menu; const items = Object.keys(navbarItemDef).filter(k => !menu.includes(k)).map(k => navbarItemDef[k]).filter(def => def.show == null ? true : def.show).map(def => ({ type: def.to ? 'link' : 'button', - text: i18n.ts[def.title], + text: def.title, icon: def.icon, to: def.to, action: def.action, diff --git a/packages/frontend/src/components/MkPagePreview.vue b/packages/frontend/src/components/MkPagePreview.vue index 009582e540..1eb61d4344 100644 --- a/packages/frontend/src/components/MkPagePreview.vue +++ b/packages/frontend/src/components/MkPagePreview.vue @@ -14,22 +14,15 @@ </MkA> </template> -<script lang="ts"> -import { defineComponent } from 'vue'; +<script lang="ts" setup> +import { } from 'vue'; +import * as misskey from 'misskey-js'; import { userName } from '@/filters/user'; import * as os from '@/os'; -export default defineComponent({ - props: { - page: { - type: Object, - required: true, - }, - }, - methods: { - userName, - }, -}); +const props = defineProps<{ + page: misskey.entities.Page; +}>(); </script> <style lang="scss" scoped> diff --git a/packages/frontend/src/components/form/select.vue b/packages/frontend/src/components/form/select.vue index c8cdd9e508..068ca2ebc6 100644 --- a/packages/frontend/src/components/form/select.vue +++ b/packages/frontend/src/components/form/select.vue @@ -126,7 +126,7 @@ const onClick = (ev: MouseEvent) => { const pushOption = (option: VNode) => { menu.push({ text: option.children, - active: v.value === option.props.value, + active: computed(() => v.value === option.props.value), action: () => { v.value = option.props.value; }, |