test(storybook): add `components/MkC.*` stories

This commit is contained in:
zyoshoka 2024-05-18 18:33:14 +09:00
parent def7b8c55e
commit ca5b6e26ae
No known key found for this signature in database
GPG Key ID: 0C2CB8FBA309A5B8
24 changed files with 981 additions and 110 deletions

View File

@ -22,6 +22,66 @@ export function abuseUserReport() {
};
}
export function channel(id = 'somechannelid', name = 'Some Channel', bannerUrl: string | null = 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true'): entities.Channel {
return {
id,
createdAt: '2016-12-28T22:49:51.000Z',
lastNotedAt: '2016-12-28T22:49:51.000Z',
name,
description: null,
userId: null,
bannerUrl,
pinnedNoteIds: [],
color: '#000',
isArchived: false,
usersCount: 1,
notesCount: 1,
isSensitive: false,
allowRenoteToExternal: false,
};
}
export function clip(id = 'someclipid', name = 'Some Clip'): entities.Clip {
return {
id,
createdAt: '2016-12-28T22:49:51.000Z',
lastClippedAt: null,
userId: 'someuserid',
user: {
id: 'someuserid',
name: 'Misskey User',
username: 'miskist',
host: 'misskey-hub.net',
avatarUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/about-icon.png?raw=true',
avatarBlurhash: 'eQFRshof5NWBRi},juayfPju53WB?0ofs;s*a{ofjuay^SoMEJR%ay',
avatarDecorations: [],
emojis: {},
badgeRoles: [],
onlineStatus: 'unknown',
},
notesCount: undefined,
name,
description: 'Some clip description',
isPublic: false,
favoritedCount: 0,
};
}
export function emojiDetailed(id = 'someemojiid', name = 'some_emoji'): entities.EmojiDetailed {
return {
id,
aliases: ['alias1', 'alias2'],
name,
category: 'emojiCategory',
host: null,
url: '/client-assets/about-icon.png',
license: null,
isSensitive: false,
localOnly: false,
roleIdsThatCanBeUsedThisEmojiAsReaction: ['roleId1', 'roleId2'],
};
}
export function galleryPost(isSensitive = false) {
return {
id: 'somepostid',

View File

@ -397,7 +397,7 @@ function toStories(component: string): Promise<string> {
const globs = await Promise.all([
glob('src/components/global/Mk*.vue'),
glob('src/components/global/RouterView.vue'),
glob('src/components/Mk{A,B}*.vue'),
glob('src/components/Mk[A-C]*.vue'),
glob('src/components/MkDigitalClock.vue'),
glob('src/components/MkGalleryPostPreview.vue'),
glob('src/components/MkSignupServerRules.vue'),

View File

@ -104,6 +104,7 @@
"@types/node": "20.12.7",
"@types/punycode": "2.1.4",
"@types/sanitize-html": "2.11.0",
"@types/seedrandom": "3.0.8",
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@types/uuid": "9.0.8",
@ -128,6 +129,7 @@
"prettier": "3.2.5",
"react": "18.3.1",
"react-dom": "18.3.1",
"seedrandom": "3.0.5",
"start-server-and-test": "2.0.3",
"storybook": "8.0.9",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",

View File

@ -0,0 +1,55 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { HttpResponse, http } from 'msw';
import { action } from '@storybook/addon-actions';
import { channel } from '../../.storybook/fakes.js';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkChannelFollowButton from './MkChannelFollowButton.vue';
export const Default = {
render(args) {
return {
components: {
MkChannelFollowButton,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkChannelFollowButton v-bind="props" />',
};
},
args: {
channel: channel(),
full: true,
},
parameters: {
layout: 'centered',
msw: {
handlers: [
...commonHandlers,
http.post('/api/channels/follow', async ({ request }) => {
action('POST /api/channels/follow')(await request.json());
return HttpResponse.json({});
}),
http.post('/api/channels/unfollow', async ({ request }) => {
action('POST /api/channels/unfollow')(await request.json());
return HttpResponse.json({});
}),
],
},
},
} satisfies StoryObj<typeof MkChannelFollowButton>;

View File

@ -26,17 +26,18 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { ref } from 'vue';
import * as Misskey from 'misskey-js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { i18n } from '@/i18n.js';
const props = withDefaults(defineProps<{
channel: Record<string, any>;
channel: Misskey.entities.Channel;
full?: boolean;
}>(), {
full: false,
});
const isFollowing = ref<boolean>(props.channel.isFollowing);
const isFollowing = ref(props.channel.isFollowing);
const wait = ref(false);
async function onClick() {

View File

@ -0,0 +1,61 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { HttpResponse, http } from 'msw';
import { action } from '@storybook/addon-actions';
import { channel } from '../../.storybook/fakes.js';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkChannelList from './MkChannelList.vue';
export const Default = {
render(args) {
return {
components: {
MkChannelList,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkChannelList v-bind="props" />',
};
},
args: {
pagination: {
endpoint: 'channels/search',
limit: 10,
},
},
parameters: {
layout: 'fullscreen',
msw: {
handlers: [
...commonHandlers,
http.post('/api/channels/search', async ({ request, params }) => {
action('POST /api/channels/search')(await request.json());
return HttpResponse.json(params.untilId === 'lastchannel' ? [] : [
channel(),
channel('lastchannel', 'Last Channel', null),
]);
}),
],
},
},
decorators: [
() => ({
template: '<div style="display: flex; align-items: center; justify-content: center; height: 100vh"><div style="max-width: 700px; width: 100%; margin: 3rem"><story/></div></div>',
}),
],
} satisfies StoryObj<typeof MkChannelList>;

View File

@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { channel } from '../../.storybook/fakes.js';
import MkChannelPreview from './MkChannelPreview.vue';
export const Default = {
render(args) {
return {
components: {
MkChannelPreview,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkChannelPreview v-bind="props" />',
};
},
args: {
channel: channel(),
},
parameters: {
layout: 'fullscreen',
},
decorators: [
() => ({
template: '<div style="display: flex; align-items: center; justify-content: center; height: 100vh"><div style="max-width: 700px; width: 100%; margin: 3rem"><story/></div></div>',
}),
],
} satisfies StoryObj<typeof MkChannelPreview>;

View File

@ -0,0 +1,117 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { DefaultBodyType, HttpResponse, HttpResponseResolver, JsonBodyType, PathParams, http } from 'msw';
import seedrandom from 'seedrandom';
import { action } from '@storybook/addon-actions';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkChart from './MkChart.vue';
function getChartArray(seed: string, limit: number, option?: { accumulate?: boolean, mul?: number }): number[] {
const rng = seedrandom(seed);
const max = Math.floor(option?.mul ?? 250 * rng());
let accumulation = 0;
const array: number[] = [];
for (let i = 0; i < limit; i++) {
const num = Math.floor((max + 1) * rng());
if (option?.accumulate) {
accumulation += num;
array.unshift(accumulation);
} else {
array.push(num);
}
}
return array;
}
function getChartResolver(fields: string[], option?: { accumulate?: boolean, mulMap?: Record<string, number> }): HttpResponseResolver<PathParams, DefaultBodyType, JsonBodyType> {
return ({ request }) => {
action(`GET ${request.url}`)();
const limitParam = new URL(request.url).searchParams.get('limit');
const limit = limitParam ? parseInt(limitParam) : 30;
const res = {};
for (const field of fields) {
const layers = field.split('.');
let current = res;
while (layers.length > 1) {
const currentKey = layers.shift()!;
if (current[currentKey] == null) current[currentKey] = {};
current = current[currentKey];
}
current[layers[0]] = getChartArray(field, limit, {
accumulate: option?.accumulate,
mul: option?.mulMap != null && field in option.mulMap ? option.mulMap[field] : undefined,
});
}
return HttpResponse.json(res);
};
}
const Base = {
render(args) {
return {
components: {
MkChart,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkChart v-bind="props" />',
};
},
args: {
src: 'federation',
span: 'hour',
},
parameters: {
layout: 'centered',
msw: {
handlers: [
...commonHandlers,
http.get('/api/charts/federation', getChartResolver(
['deliveredInstances', 'inboxInstances', 'stalled', 'sub', 'pub', 'pubsub', 'subActive', 'pubActive'],
)),
http.get('/api/charts/notes', getChartResolver(
['local.total', 'remote.total'],
{ accumulate: true },
)),
http.get('/api/charts/drive', getChartResolver(
['local.incSize', 'local.decSize', 'remote.incSize', 'remote.decSize'],
{ mulMap: { 'local.incSize': 1e7, 'local.decSize': 5e6, 'remote.incSize': 1e6, 'remote.decSize': 5e5 } },
)),
],
},
},
} satisfies StoryObj<typeof MkChart>;
export const FederationChart = {
...Base,
args: {
src: 'federation',
},
} satisfies StoryObj<typeof MkChart>;
export const NotesTotalChart = {
...Base,
args: {
src: 'notes-total',
},
} satisfies StoryObj<typeof MkChart>;
export const DriveChart = {
...Base,
args: {
src: 'drive',
},
} satisfies StoryObj<typeof MkChart>;

View File

@ -19,8 +19,9 @@ SPDX-License-Identifier: AGPL-3.0-only
id-denylist violation when setting it. This is causing about 60+ lint issues.
As this is part of Chart.js's API it makes sense to disable the check here.
*/
import { onMounted, ref, shallowRef, watch, PropType } from 'vue';
import { onMounted, ref, shallowRef, watch } from 'vue';
import { Chart } from 'chart.js';
import * as Misskey from 'misskey-js';
import { misskeyApiGet } from '@/scripts/misskey-api.js';
import { defaultStore } from '@/store.js';
import { useChartTooltip } from '@/scripts/use-chart-tooltip.js';
@ -34,44 +35,55 @@ import MkChartLegend from '@/components/MkChartLegend.vue';
initChart();
const props = defineProps({
src: {
type: String,
required: true,
},
args: {
type: Object,
required: false,
},
limit: {
type: Number,
required: false,
default: 90,
},
span: {
type: String as PropType<'hour' | 'day'>,
required: true,
},
detailed: {
type: Boolean,
required: false,
default: false,
},
stacked: {
type: Boolean,
required: false,
default: false,
},
bar: {
type: Boolean,
required: false,
default: false,
},
aspectRatio: {
type: Number,
required: false,
default: null,
},
type ChartSrc =
| 'federation'
| 'ap-request'
| 'users'
| 'users-total'
| 'active-users'
| 'notes'
| 'local-notes'
| 'remote-notes'
| 'notes-total'
| 'drive'
| 'drive-files'
| 'instance-requests'
| 'instance-users'
| 'instance-users-total'
| 'instance-notes'
| 'instance-notes-total'
| 'instance-ff'
| 'instance-ff-total'
| 'instance-drive-usage'
| 'instance-drive-usage-total'
| 'instance-drive-files'
| 'instance-drive-files-total'
| 'per-user-notes'
| 'per-user-pv'
| 'per-user-following'
| 'per-user-followers'
| 'per-user-drive'
const props = withDefaults(defineProps<{
src: ChartSrc;
args?: {
host?: string;
user?: Misskey.entities.UserLite;
withoutAll?: boolean;
};
limit?: number;
span: 'hour' | 'day';
detailed?: boolean;
stacked?: boolean;
bar?: boolean;
aspectRatio?: number | null;
}>(), {
args: undefined,
limit: 90,
detailed: false,
stacked: false,
bar: false,
aspectRatio: null,
});
const legendEl = shallowRef<InstanceType<typeof MkChartLegend>>();

View File

@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import MkChartLegend from './MkChartLegend.vue';
void MkChartLegend;

View File

@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import MkChartTooltip from './MkChartTooltip.vue';
void MkChartTooltip;

View File

@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { HttpResponse, http } from 'msw';
import { action } from '@storybook/addon-actions';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkClickerGame from './MkClickerGame.vue';
export const Default = {
render(args) {
return {
components: {
MkClickerGame,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkClickerGame v-bind="props" />',
};
},
parameters: {
layout: 'centered',
msw: {
handlers: [
...commonHandlers,
http.post('/api/i/registry/get', async ({ request }) => {
action('POST /api/i/registry/get')(await request.json());
return HttpResponse.json({
error: {
message: 'No such key.',
code: 'NO_SUCH_KEY',
id: 'ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a',
},
}, {
status: 400,
});
}),
http.post('/api/i/registry/set', async ({ request }) => {
action('POST /api/i/registry/set')(await request.json());
return HttpResponse.json(undefined, { status: 204 });
}),
http.post('/api/i/claim-achievement', async ({ request }) => {
action('POST /api/i/claim-achievement')(await request.json());
return HttpResponse.json(undefined, { status: 204 });
}),
],
},
},
} satisfies StoryObj<typeof MkClickerGame>;

View File

@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { clip } from '../../.storybook/fakes.js';
import MkClipPreview from './MkClipPreview.vue';
export const Default = {
render(args) {
return {
components: {
MkClipPreview,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkClipPreview v-bind="props" />',
};
},
args: {
clip: clip(),
},
parameters: {
layout: 'fullscreen',
},
decorators: [
() => ({
template: '<div style="display: flex; align-items: center; justify-content: center; height: 100vh"><div style="max-width: 700px; width: 100%; margin: 3rem"><story/></div></div>',
}),
],
} satisfies StoryObj<typeof MkClipPreview>;

View File

@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import MkCode_core from './MkCode.core.vue';
void MkCode_core;

View File

@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import MkCode from './MkCode.vue';
const code = `for (let i, 100) {
<: if (i % 15 == 0) "FizzBuzz"
elif (i % 3 == 0) "Fizz"
elif (i % 5 == 0) "Buzz"
else i
}`;
export const Default = {
render(args) {
return {
components: {
MkCode,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkCode v-bind="props" />',
};
},
args: {
code,
lang: 'is',
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkCode>;

View File

@ -0,0 +1,62 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { action } from '@storybook/addon-actions';
import MkCodeEditor from './MkCodeEditor.vue';
const code = `for (let i, 100) {
<: if (i % 15 == 0) "FizzBuzz"
elif (i % 3 == 0) "Fizz"
elif (i % 5 == 0) "Buzz"
else i
}`;
export const Default = {
render(args) {
return {
components: {
MkCodeEditor,
},
data() {
return {
code,
};
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
events() {
return {
'change': action('change'),
'keydown': action('keydown'),
'enter': action('enter'),
'update:modelValue': action('update:modelValue'),
};
},
},
template: '<MkCodeEditor v-model="code" v-bind="props" v-on="events" />',
};
},
args: {
lang: 'aiscript',
},
parameters: {
layout: 'fullscreen',
},
decorators: [
() => ({
template: '<div style="display: flex; align-items: center; justify-content: center; height: 100vh"><div style="max-width: 800px; width: 100%; margin: 3rem"><Suspense><story/></Suspense></div></div>',
}),
],
} satisfies StoryObj<typeof MkCodeEditor>;

View File

@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import MkCodeInline from './MkCodeInline.vue';
export const Default = {
render(args) {
return {
components: {
MkCodeInline,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkCodeInline v-bind="props"/>',
};
},
args: {
code: '<: "Hello, world!"',
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkCodeInline>;

View File

@ -0,0 +1,50 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { action } from '@storybook/addon-actions';
import MkColorInput from './MkColorInput.vue';
export const Default = {
render(args) {
return {
components: {
MkColorInput,
},
data() {
return {
color: '#cccccc',
};
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
events() {
return {
'update:modelValue': action('update:modelValue'),
};
},
},
template: '<MkColorInput v-model="color" v-bind="props" v-on="events" />',
};
},
parameters: {
layout: 'fullscreen',
},
decorators: [
() => ({
template: '<div style="display: flex; align-items: center; justify-content: center; height: 100vh"><div style="max-width: 800px; width: 100%; margin: 3rem"><story/></div></div>',
}),
],
} satisfies StoryObj<typeof MkColorInput>;

View File

@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import MkContainer from './MkContainer.vue';
void MkContainer;

View File

@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import MkContextMenu from './MkContextMenu.vue';
import * as os from '@/os.js';
export const Empty = {
render(args) {
return {
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
methods: {
onContextmenu(ev: MouseEvent) {
os.contextMenu(args.items, ev);
},
},
template: '<div @contextmenu.stop="onContextmenu">Right Click Here</div>',
};
},
args: {
items: [],
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkContextMenu>;
export const SomeTabs = {
...Empty,
args: {
items: [
{
text: 'Home',
icon: 'ti ti-home',
action() {},
},
],
},
} satisfies StoryObj<typeof MkContextMenu>;

View File

@ -0,0 +1,66 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { HttpResponse, http } from 'msw';
import { action } from '@storybook/addon-actions';
import { file } from '../../.storybook/fakes.js';
import { commonHandlers } from '../../.storybook/mocks.js';
import MkCropperDialog from './MkCropperDialog.vue';
export const Default = {
render(args) {
return {
components: {
MkCropperDialog,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
events() {
return {
'ok': action('ok'),
'cancel': action('cancel'),
'closed': action('closed'),
};
},
},
template: '<MkCropperDialog v-bind="props" v-on="events" />',
};
},
args: {
file: file(),
aspectRatio: NaN,
},
parameters: {
layout: 'centered',
msw: {
handlers: [
...commonHandlers,
http.get('/proxy/image.webp?url=https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true', async () => {
const image = await (await fetch('client-assets/fedi.jpg')).blob();
return new HttpResponse(image, {
headers: {
'Content-Type': 'image/jpeg',
},
});
}),
http.post('/api/drive/files/create', async ({ request }) => {
action('POST /api/drive/files/create')(await request.formData());
return HttpResponse.json(file());
}),
],
},
},
} satisfies StoryObj<typeof MkCropperDialog>;

View File

@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { emojiDetailed } from '../../.storybook/fakes.js';
import MkCustomEmojiDetailedDialog from './MkCustomEmojiDetailedDialog.vue';
export const Default = {
render(args) {
return {
components: {
MkCustomEmojiDetailedDialog,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
},
template: '<MkCustomEmojiDetailedDialog v-bind="props" />',
};
},
args: {
emoji: emojiDetailed(),
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkCustomEmojiDetailedDialog>;

View File

@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
import { StoryObj } from '@storybook/vue3';
import { action } from '@storybook/addon-actions';
import MkCwButton from './MkCwButton.vue';
export const Default = {
render(args) {
return {
components: {
MkCwButton,
},
data() {
return {
showContent: false,
};
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...this.args,
};
},
events() {
return {
'update:modelValue': action('update:modelValue'),
};
},
},
template: '<MkCwButton v-model="showContent" v-bind="props" v-on="events" />',
};
},
args: {
text: 'Some CW content',
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkCwButton>;

View File

@ -919,7 +919,7 @@ importers:
version: 8.0.9(bufferutil@4.0.7)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(utf-8-validate@6.0.3)(vite@5.2.11(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3))(vue@3.4.26(typescript@5.4.5))
'@testing-library/vue':
specifier: 8.0.3
version: 8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.25(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))
version: 8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))
'@types/escape-regexp':
specifier: 0.0.3
version: 0.0.3
@ -941,6 +941,9 @@ importers:
'@types/sanitize-html':
specifier: 2.11.0
version: 2.11.0
'@types/seedrandom':
specifier: 3.0.8
version: 3.0.8
'@types/throttle-debounce':
specifier: 5.0.2
version: 5.0.2
@ -1013,6 +1016,9 @@ importers:
react-dom:
specifier: 18.3.1
version: 18.3.1(react@18.3.1)
seedrandom:
specifier: 3.0.5
version: 3.0.5
start-server-and-test:
specifier: 2.0.3
version: 2.0.3
@ -4819,9 +4825,6 @@ packages:
'@vue/compiler-sfc@3.4.26':
resolution: {integrity: sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw==}
'@vue/compiler-ssr@3.4.25':
resolution: {integrity: sha512-H2ohvM/Pf6LelGxDBnfbbXFPyM4NE3hrw0e/EpwuSiYu8c819wx+SVGdJ65p/sFrYDd6OnSDxN1MB2mN07hRSQ==}
'@vue/compiler-ssr@3.4.26':
resolution: {integrity: sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ==}
@ -4845,11 +4848,6 @@ packages:
'@vue/runtime-dom@3.4.26':
resolution: {integrity: sha512-UftYA2hUXR2UOZD/Fc3IndZuCOOJgFxJsWOxDkhfVcwLbsfh2CdXE2tG4jWxBZuDAs9J9PzRTUFt1PgydEtItw==}
'@vue/server-renderer@3.4.25':
resolution: {integrity: sha512-8VTwq0Zcu3K4dWV0jOwIVINESE/gha3ifYCOKEhxOj6MEl5K5y8J8clQncTcDhKF+9U765nRw4UdUEXvrGhyVQ==}
peerDependencies:
vue: 3.4.25
'@vue/server-renderer@3.4.26':
resolution: {integrity: sha512-xoGAqSjYDPGAeRWxeoYwqJFD/gw7mpgzOvSxEmjWaFO2rE6qpbD1PC172YRpvKhrihkyHJkNDADFXTfCyVGhKw==}
peerDependencies:
@ -10875,6 +10873,9 @@ packages:
vue-component-type-helpers@2.0.16:
resolution: {integrity: sha512-qisL/iAfdO++7w+SsfYQJVPj6QKvxp4i1MMxvsNO41z/8zu3KuAw9LkhKUfP/kcOWGDxESp+pQObWppXusejCA==}
vue-component-type-helpers@2.0.19:
resolution: {integrity: sha512-cN3f1aTxxKo4lzNeQAkVopswuImUrb5Iurll9Gaw5cqpnbTAxtEMM1mgi6ou4X79OCyqYv1U1mzBHJkzmiK82w==}
vue-demi@0.14.7:
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
engines: {node: '>=12'}
@ -11661,7 +11662,7 @@ snapshots:
'@babel/traverse': 7.23.5
'@babel/types': 7.23.5
convert-source-map: 2.0.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@ -11681,7 +11682,7 @@ snapshots:
'@babel/traverse': 7.24.0
'@babel/types': 7.24.0
convert-source-map: 2.0.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
gensync: 1.0.0-beta.2
json5: 2.2.3
semver: 6.3.1
@ -11751,7 +11752,7 @@ snapshots:
'@babel/core': 7.24.0
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-plugin-utils': 7.22.5
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
lodash.debounce: 4.0.8
resolve: 1.22.8
transitivePeerDependencies:
@ -12522,7 +12523,7 @@ snapshots:
'@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.23.9
'@babel/types': 7.23.5
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@ -12537,7 +12538,7 @@ snapshots:
'@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.24.0
'@babel/types': 7.24.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
globals: 11.12.0
transitivePeerDependencies:
- supports-color
@ -12929,7 +12930,7 @@ snapshots:
'@eslint/eslintrc@2.1.4':
dependencies:
ajv: 6.12.6
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
espree: 9.6.1
globals: 13.19.0
ignore: 5.2.4
@ -13080,7 +13081,7 @@ snapshots:
'@humanwhocodes/config-array@0.11.13':
dependencies:
'@humanwhocodes/object-schema': 2.0.1
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@ -13088,7 +13089,7 @@ snapshots:
'@humanwhocodes/config-array@0.11.14':
dependencies:
'@humanwhocodes/object-schema': 2.0.2
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@ -14956,7 +14957,7 @@ snapshots:
ts-dedent: 2.2.0
type-fest: 2.19.0
vue: 3.4.26(typescript@5.4.5)
vue-component-type-helpers: 2.0.16
vue-component-type-helpers: 2.0.19
transitivePeerDependencies:
- encoding
- supports-color
@ -15217,11 +15218,11 @@ snapshots:
dependencies:
'@testing-library/dom': 9.3.4
'@testing-library/vue@8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.25(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))':
'@testing-library/vue@8.0.3(@vue/compiler-sfc@3.4.26)(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))':
dependencies:
'@babel/runtime': 7.23.4
'@testing-library/dom': 9.3.3
'@vue/test-utils': 2.4.1(@vue/server-renderer@3.4.25(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))
'@vue/test-utils': 2.4.1(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))
vue: 3.4.26(typescript@5.4.5)
optionalDependencies:
'@vue/compiler-sfc': 3.4.26
@ -15619,7 +15620,7 @@ snapshots:
'@typescript-eslint/type-utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3)
'@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.11.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.53.0
graphemer: 1.4.0
ignore: 5.2.4
@ -15639,7 +15640,7 @@ snapshots:
'@typescript-eslint/type-utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.1.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.2.4
@ -15659,7 +15660,7 @@ snapshots:
'@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.7.1
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
@ -15677,7 +15678,7 @@ snapshots:
'@typescript-eslint/types': 6.11.0
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.11.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.53.0
optionalDependencies:
typescript: 5.3.3
@ -15690,7 +15691,7 @@ snapshots:
'@typescript-eslint/types': 7.1.0
'@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 7.1.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
optionalDependencies:
typescript: 5.3.3
@ -15703,7 +15704,7 @@ snapshots:
'@typescript-eslint/types': 7.7.1
'@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.7.1
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
optionalDependencies:
typescript: 5.4.5
@ -15729,7 +15730,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 6.11.0(typescript@5.3.3)
'@typescript-eslint/utils': 6.11.0(eslint@8.53.0)(typescript@5.3.3)
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.53.0
ts-api-utils: 1.0.1(typescript@5.3.3)
optionalDependencies:
@ -15741,7 +15742,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 7.1.0(typescript@5.3.3)
'@typescript-eslint/utils': 7.1.0(eslint@8.57.0)(typescript@5.3.3)
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
ts-api-utils: 1.0.1(typescript@5.3.3)
optionalDependencies:
@ -15753,7 +15754,7 @@ snapshots:
dependencies:
'@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5)
'@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5)
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.4.5)
optionalDependencies:
@ -15771,7 +15772,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 6.11.0
'@typescript-eslint/visitor-keys': 6.11.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
globby: 11.1.0
is-glob: 4.0.3
semver: 7.5.4
@ -15785,7 +15786,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 7.1.0
'@typescript-eslint/visitor-keys': 7.1.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.3
@ -15800,7 +15801,7 @@ snapshots:
dependencies:
'@typescript-eslint/types': 7.7.1
'@typescript-eslint/visitor-keys': 7.7.1
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.4
@ -16012,12 +16013,6 @@ snapshots:
postcss: 8.4.38
source-map-js: 1.2.0
'@vue/compiler-ssr@3.4.25':
dependencies:
'@vue/compiler-dom': 3.4.25
'@vue/shared': 3.4.25
optional: true
'@vue/compiler-ssr@3.4.26':
dependencies:
'@vue/compiler-dom': 3.4.26
@ -16052,13 +16047,6 @@ snapshots:
'@vue/shared': 3.4.26
csstype: 3.1.3
'@vue/server-renderer@3.4.25(vue@3.4.26(typescript@5.4.5))':
dependencies:
'@vue/compiler-ssr': 3.4.25
'@vue/shared': 3.4.25
vue: 3.4.26(typescript@5.4.5)
optional: true
'@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5))':
dependencies:
'@vue/compiler-ssr': 3.4.26
@ -16071,13 +16059,13 @@ snapshots:
'@vue/shared@3.4.26': {}
'@vue/test-utils@2.4.1(@vue/server-renderer@3.4.25(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))':
'@vue/test-utils@2.4.1(@vue/server-renderer@3.4.26(vue@3.4.26(typescript@5.4.5)))(vue@3.4.26(typescript@5.4.5))':
dependencies:
js-beautify: 1.14.9
vue: 3.4.26(typescript@5.4.5)
vue-component-type-helpers: 1.8.4
optionalDependencies:
'@vue/server-renderer': 3.4.25(vue@3.4.26(typescript@5.4.5))
'@vue/server-renderer': 3.4.26(vue@3.4.26(typescript@5.4.5))
'@webgpu/types@0.1.30': {}
@ -16139,13 +16127,13 @@ snapshots:
agent-base@6.0.2:
dependencies:
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
agent-base@7.1.0:
dependencies:
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@ -16375,7 +16363,7 @@ snapshots:
dependencies:
'@fastify/error': 3.4.0
archy: 1.0.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
fastq: 1.17.1
transitivePeerDependencies:
- supports-color
@ -17483,7 +17471,7 @@ snapshots:
detect-port@1.5.1:
dependencies:
address: 1.2.2
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@ -17699,7 +17687,7 @@ snapshots:
esbuild-register@3.5.0(esbuild@0.20.2):
dependencies:
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
esbuild: 0.20.2
transitivePeerDependencies:
- supports-color
@ -17969,7 +17957,7 @@ snapshots:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
@ -18012,7 +18000,7 @@ snapshots:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
@ -18474,7 +18462,7 @@ snapshots:
follow-redirects@1.15.2(debug@4.3.4):
optionalDependencies:
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
for-each@0.3.3:
dependencies:
@ -18926,7 +18914,7 @@ snapshots:
http-proxy-agent@7.0.0:
dependencies:
agent-base: 7.1.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@ -18965,14 +18953,14 @@ snapshots:
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
https-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@ -19053,7 +19041,7 @@ snapshots:
dependencies:
'@ioredis/commands': 1.2.0
cluster-key-slot: 1.1.2
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
denque: 2.1.0
lodash.defaults: 4.2.0
lodash.isarguments: 3.1.0
@ -19306,7 +19294,7 @@ snapshots:
istanbul-lib-source-maps@4.0.1:
dependencies:
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
istanbul-lib-coverage: 3.2.2
source-map: 0.6.1
transitivePeerDependencies:
@ -20370,7 +20358,7 @@ snapshots:
micromark@4.0.0:
dependencies:
'@types/debug': 4.1.12
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
decode-named-character-reference: 1.0.2
devlop: 1.1.0
micromark-core-commonmark: 2.0.0
@ -22196,7 +22184,7 @@ snapshots:
dependencies:
'@hapi/hoek': 10.0.1
'@hapi/wreck': 18.0.1
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
joi: 17.11.0
transitivePeerDependencies:
- supports-color
@ -22294,7 +22282,7 @@ snapshots:
socks-proxy-agent@8.0.2:
dependencies:
agent-base: 7.1.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
socks: 2.7.1
transitivePeerDependencies:
- supports-color
@ -22391,7 +22379,7 @@ snapshots:
arg: 5.0.2
bluebird: 3.7.2
check-more-types: 2.24.0
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
execa: 5.1.1
lazy-ass: 1.6.0
ps-tree: 1.2.0
@ -22904,7 +22892,7 @@ snapshots:
chalk: 4.1.2
cli-highlight: 2.1.11
dayjs: 1.11.10
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
dotenv: 16.0.3
glob: 10.3.10
mkdirp: 2.1.6
@ -23114,7 +23102,7 @@ snapshots:
vite-node@0.34.6(@types/node@20.12.7)(sass@1.76.0)(terser@5.30.3):
dependencies:
cac: 6.7.14
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
mlly: 1.5.0
pathe: 1.1.2
picocolors: 1.0.0
@ -23163,7 +23151,7 @@ snapshots:
acorn-walk: 8.3.2
cac: 6.7.14
chai: 4.3.10
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
local-pkg: 0.4.3
magic-string: 0.30.7
pathe: 1.1.2
@ -23223,6 +23211,8 @@ snapshots:
vue-component-type-helpers@2.0.16: {}
vue-component-type-helpers@2.0.19: {}
vue-demi@0.14.7(vue@3.4.26(typescript@5.4.5)):
dependencies:
vue: 3.4.26(typescript@5.4.5)
@ -23244,7 +23234,7 @@ snapshots:
vue-eslint-parser@9.4.2(eslint@8.57.0):
dependencies:
debug: 4.3.4(supports-color@8.1.1)
debug: 4.3.4(supports-color@5.5.0)
eslint: 8.57.0
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3