Skip to content

Commit

Permalink
Re-add Storybook (#4841)
Browse files Browse the repository at this point in the history
* Re-add storybook

* Re-add storybook to ci_cd

* Use built storybook for CI

* Fix mobile searchbar clear button

* Update snapshots

* Try fixing pnpx cache access

* Fix type

* Fix value type

* Update the error string

* Add docs build

* Remove favicon replacement

* Add svg icon

* Update the lock file
  • Loading branch information
obulat authored Sep 10, 2024
1 parent 247bc69 commit aea8a33
Show file tree
Hide file tree
Showing 179 changed files with 6,625 additions and 3,147 deletions.
8 changes: 8 additions & 0 deletions .github/actions/build-docs/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ runs:
# Pass -W to fail CI if warnings exist
just documentation/build -W
- name: Build Storybook
shell: bash
run: |
just frontend/run storybook:build
cp frontend/src/public/favicon_storybook.svg frontend/storybook-static/favicon.svg
# Storybook will be available at `/storybook`
- name: Merge all docs
shell: bash
run: |
mv documentation/_build /tmp/docs
mv frontend/storybook-static /tmp/docs/storybook
4 changes: 4 additions & 0 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -796,11 +796,14 @@ jobs:
name:
- playwright_vr
- playwright_e2e
- storybook
include:
- name: playwright_vr
script: "test:playwright visual-regression -u"
- name: playwright_e2e
script: "test:playwright e2e"
- name: storybook
script: "test:storybook -u"

steps:
- name: Checkout repository
Expand Down Expand Up @@ -863,6 +866,7 @@ jobs:
name:
- playwright_vr
- playwright_e2e
- storybook

steps:
- name: Pass
Expand Down
1 change: 1 addition & 0 deletions docker/dev_env/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ RUN mkdir /pipx \
just \
jq \
which \
xdg-utils \
nodejs npm \
python3.12 python3.12-devel pipx \
libffi-devel \
Expand Down
15 changes: 8 additions & 7 deletions frontend/.storybook/decorators/with-rtl.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useI18n } from "#imports"

import { ref, watch, onMounted, reactive } from "vue"
import { ref, watch, onMounted, reactive, h } from "vue"

import { useEffect } from "@storybook/client-api"
import { useEffect } from "@storybook/preview-api"

const languageDirection = reactive({ value: "ltr" })

Expand All @@ -12,16 +12,17 @@ export const WithRTL = (story, context) => {
}, [context.globals.languageDirection])

return {
template: `<div ref="element"><story /></div>`,
components: { story },
setup() {
const element = ref()
const { i18n } = useI18n({ useScope: "global" })
const i18n = useI18n({ useScope: "global" })

onMounted(() => {
watch(
languageDirection,
(direction) => {
i18n.localeProperties.dir = direction.value
async (direction) => {
await i18n.setLocale(direction.value === "rtl" ? "ar" : "en")

if (element.value) {
element.value.ownerDocument.documentElement.setAttribute(
"dir",
Expand All @@ -32,7 +33,7 @@ export const WithRTL = (story, context) => {
{ immediate: true }
)
})
return { element }
return () => h("div", { ref: element }, [h(story())])
},
}
}
20 changes: 13 additions & 7 deletions frontend/.storybook/decorators/with-screenshot-area.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { h } from "vue"

export const WithScreenshotArea = (story) => {
return {
template: `
<div
class="screenshot-area"
:style="{ display: 'inline-block', padding: '2rem' }"
>
<story />
</div>`,
components: { story },
setup() {
return () =>
h(
"div",
{
class: "screenshot-area",
style: "display: inline-block; padding: 2rem;",
},
[h(story())]
)
},
}
}
31 changes: 31 additions & 0 deletions frontend/.storybook/decorators/with-teleport-target.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { h, ref } from "vue"

import { useSearchStore } from "~/stores/search"

import VButton from "~/components/VButton.vue"

export const WithTeleportTarget = (story) => {
return {
components: { story },
setup() {
const isRendered = ref(false)
const renderStory = () => {
isRendered.value = true
}
// A workaround to make sure that the useStorage is initialized in the child story
useSearchStore().addRecentSearch("cat")
return () =>
h("div", null, [
isRendered.value
? h(story())
: h(
VButton,
{ variant: "filled-dark", size: "large", onClick: renderStory },
{ default: () => "Render Story" }
),
h("div"),
h("div", { id: "teleports" }),
])
},
}
}
5 changes: 2 additions & 3 deletions frontend/.storybook/decorators/with-ui-store.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { ref, onMounted } from "vue"
import { ref, onMounted, h } from "vue"

import { useLayout } from "~/composables/use-layout"

export const WithUiStore = (story) => {
return {
template: `<div ref="element"><story /></div>`,
components: { story },
setup() {
const element = ref()
const { updateBreakpoint } = useLayout()
onMounted(() => {
updateBreakpoint()
})
return { element }
return () => h("div", { ref: element }, [h(story())])
},
}
}
18 changes: 18 additions & 0 deletions frontend/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { StorybookConfig } from "@storybook-vue/nuxt"

const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: {
name: "@storybook-vue/nuxt",
options: {},
},
docs: {
autodocs: "tag",
},
}
export default config
47 changes: 47 additions & 0 deletions frontend/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { VIEWPORTS } from "~/constants/screens"

import { WithUiStore } from "~~/.storybook/decorators/with-ui-store"
import { WithRTL } from "~~/.storybook/decorators/with-rtl"

import type { Preview } from "@storybook/vue3"

const preview: Preview = {
decorators: [WithRTL, WithUiStore],
globalTypes: {
languageDirection: {
name: "RTL",
description: "Simulate an RTL language.",
table: {
defaultValue: { summary: "ltr" },
},
toolbar: {
icon: "globe",
items: [
{ value: "ltr", title: "LTR" },
{ value: "rtl", title: "RTL" },
],
},
},
},
parameters: {
backgrounds: {
default: "light",
values: [
{ name: "light", value: "#ffffff" },
{ name: "dark", value: "#0d0d0d" },
],
},
viewport: {
viewports: { ...VIEWPORTS },
},
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
},
}

export default preview
2 changes: 2 additions & 0 deletions frontend/Dockerfile.playwright
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ COPY package.json .

# Ensure the Playwright container's pnpm cache folder exists and is writable
RUN mkdir -p /.cache/node/corepack/ && chmod -R 777 /.cache/node/corepack/
# Ensure that the dlx cache folder exists and is writable
RUN mkdir -p /.cache/pnpm/dlx/ && chmod -R 777 /.cache/pnpm/dlx/

# Requires `packageManager` field to be present in `frontend/package.json`.
RUN corepack enable pnpm
Expand Down
1 change: 1 addition & 0 deletions frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export default defineNuxtConfig({
"@nuxtjs/i18n",
"@nuxtjs/tailwindcss",
"@nuxtjs/plausible",
"@nuxtjs/storybook",
"@nuxt/test-utils/module",
"@nuxtjs/sitemap",
"@nuxtjs/robots",
Expand Down
19 changes: 15 additions & 4 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
"start:playwright": "pnpm i18n:copy-test-locales && pnpm start",
"prod": "pnpm build && pnpm start",
"prod:playwright": "pnpm i18n:copy-test-locales && pnpm prod",
"storybook": "TEST=true storybook dev --port 54000",
"storybook:build": "pnpm i18n:copy-test-locales && NODE_OPTIONS=--openssl-legacy-provider nuxt storybook build",
"storybook:build-for-docs": "pnpm install & pnpm i18n:en && NODE_OPTIONS=--openssl-legacy-provider nuxt storybook build",
"prod:storybook": "pnpm i18n:copy-test-locales && pnpm storybook:build && pnpm storybook:start",
"storybook": "storybook dev --port 54000",
"storybook:build": "pnpm i18n:copy-test-locales && storybook build",
"storybook:start": "pnpx http-server storybook-static -p 54000 -s",
"talkback": "node ./test/proxy.js",
"prepare:nuxt": "pnpm i18n:en && npx nuxi prepare",
"test": "pnpm test:unit && pnpm test:playwright",
Expand Down Expand Up @@ -89,7 +90,9 @@
"@babel/parser": "^7.24.8",
"@nuxt/test-utils": "^3.14.1",
"@nuxtjs/i18n": "8.3.1",
"@nuxtjs/storybook": "npm:@nuxtjs/storybook@nightly",
"@playwright/test": "1.46.1",
"@storybook-vue/nuxt": "npm:@storybook-vue/nuxt@nightly",
"@testing-library/user-event": "^14.5.2",
"@testing-library/vue": "^8.1.0",
"@vitest/coverage-v8": "^2.0.5",
Expand All @@ -110,7 +113,15 @@
"vitest-dom": "^0.1.1",
"vue": "3.5.0",
"vue-router": "^4.4.0",
"vue-tsc": "2.1.4"
"vue-tsc": "2.1.4",
"storybook": "8.2.9",
"@storybook/vue3": "8.2.9",
"@storybook/addon-links": "8.2.9",
"@storybook/builder-vite": "8.2.9",
"@storybook/addon-essentials": "8.2.9",
"@storybook/addon-interactions": "8.2.9",
"@storybook/test": "8.2.9",
"@storybook/blocks": "8.2.9"
},
"browserslist": [
"> 1%",
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/components/VAudioThumbnail/VAudioThumbnail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ import { useSensitiveMedia } from "~/composables/use-sensitive-media"
const props = defineProps<{
/**
* The details of the audio whose artwork is to be shown. The properties
* `thumbnail`, `title` and `creator` are used.
* The details of the audio whose artwork is to be shown.
*/
audio: AudioDetail
audio: Pick<AudioDetail, "thumbnail" | "title" | "creator">
}>()
const { audio } = toRefs(props)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
import { Meta, type StoryObj } from "@storybook/vue3"
import { h } from "vue"

import { getAudioObj } from "~~/test/unit/fixtures/audio"

import { AudioDetail } from "~/types/media"

import VAudioThumbnail from "~/components/VAudioThumbnail/VAudioThumbnail.vue"

const Template = (args) => ({
template: `
<div class="w-30">
<VAudioThumbnail :audio="args.audio" v-bind="args"/>
</div>
`,
components: { VAudioThumbnail },
setup() {
return { args }
},
})
const sampleAudio = getAudioObj() as Pick<
AudioDetail,
"title" | "creator" | "thumbnail"
>

export default {
const meta = {
title: "Components/VAudioThumbnail",
components: VAudioThumbnail,
component: VAudioThumbnail,
} satisfies Meta<typeof VAudioThumbnail>

export default meta
type Story = StoryObj<typeof meta>

const Template: Story = {
render: (args) => ({
components: { VAudioThumbnail },
setup() {
return () =>
h("div", { class: "w-30" }, [h(VAudioThumbnail, { audio: args.audio })])
},
}),
args: { audio: sampleAudio },
}

export const Square = {
render: Template.bind({}),
...Template,
name: "Square",

args: {
Expand All @@ -32,7 +46,7 @@ export const Square = {
}

export const Portrait = {
render: Template.bind({}),
...Template,
name: "Portrait",

args: {
Expand All @@ -46,7 +60,7 @@ export const Portrait = {
}

export const Landscape = {
render: Template.bind({}),
...Template,
name: "Landscape",

args: {
Expand All @@ -60,7 +74,7 @@ export const Landscape = {
}

export const Fallback = {
render: Template.bind({}),
...Template,
name: "Fallback",

args: {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VAudioTrack/VAudioControl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const props = withDefaults(
* The parent audio layout currently in use. The connections are determined
* by the layout and the size of the button.
*/
layout: AudioLayout
layout?: AudioLayout
/**
* Whether the audio control button can be focused by using the `Tab` key
*/
Expand Down
Loading

0 comments on commit aea8a33

Please sign in to comment.