Skip to content

Commit

Permalink
fix(ui): allow router to work on subdirs
Browse files Browse the repository at this point in the history
  • Loading branch information
itsjavi committed Sep 1, 2023
1 parent 744127d commit c0206d1
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 23 deletions.
1 change: 1 addition & 0 deletions packages/storylite/src/app/stores/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const builtinAddons: SLAddonsMap = new Map(
)

const defaultState: StoryLiteState = {
basePath: import.meta.env.BASE_URL,
canvas: {
element: null,
standalone: false,
Expand Down
1 change: 1 addition & 0 deletions packages/storylite/src/app/stores/global.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type StoryLiteCanvasState = {
export type StoryLiteParamValue = string | string[] | number | number[] | boolean | undefined | null

export type StoryLiteState = {
basePath: string
config: Required<SLAppComponentProps>
canvas: StoryLiteCanvasState
parameters: SLParameters
Expand Down
22 changes: 10 additions & 12 deletions packages/storylite/src/services/csf-api/navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SLNode, StoryModuleMap } from '@/types'
import { isTruthy } from '@/utility'

import { asCleanHash } from '../router/router.utils'
import { STORYLITE_BASE_PATH } from '../router'

export type SLNavigationNode = {
title: string
Expand All @@ -14,10 +14,6 @@ export type SLNavigationNode = {

type SLTopLevelNavigation = SLNavigationNode[]

export function getStoryUrlHash(storyId: string): string {
return `/#/stories/${asCleanHash(storyId)}`
}

export function getStoryUrl(
storyId: string | undefined,
options: { standalone?: boolean; target: 'top' | 'iframe' } = {
Expand All @@ -28,17 +24,19 @@ export function getStoryUrl(
const { standalone, target } = options
const isIframe = target === 'iframe'

const targetBasePath = isIframe ? '/canvas.html#' : '/#'
const targetHashBasePath = isIframe ? '/preview/' : '/'
const baseStr = `${targetBasePath}${targetHashBasePath}`.replace(/\/\//g, '/')
const targetBasePath = isIframe ? '/canvas.html#' : '#'
const targetHashBasePath = isIframe ? 'preview/' : ''
const baseStr = [STORYLITE_BASE_PATH, targetBasePath, targetHashBasePath]
.join('')
.replace(/\/\//g, '/')

let url = storyId === undefined ? baseStr : `${baseStr}stories/${storyId}`
let url = storyId === undefined ? baseStr : `${baseStr}/stories/${storyId}`

if (standalone) {
url += `/?standalone=true`
}

return url
return url.replace(/\/\//g, '/')
}

// TODO: support nested levels by splitting the title on `/`
Expand All @@ -50,7 +48,7 @@ export function getStoryNavigationTree(storyModuleMap: StoryModuleMap): SLTopLev
const topNode: SLNavigationNode = {
title: stories.default?.title || storiesFileId,
storyId: stories.default?.id || storiesFileId,
href: getStoryUrlHash(storiesFileId),
href: getStoryUrl(storiesFileId, { target: 'top', standalone: false }),
icon: stories.default?.navigation?.icon,
iconExpanded: stories.default?.navigation?.iconExpanded,
children: [],
Expand All @@ -64,7 +62,7 @@ export function getStoryNavigationTree(storyModuleMap: StoryModuleMap): SLTopLev
const childNode: SLNavigationNode = {
title: story.title || exportedName,
storyId: story.id,
href: getStoryUrlHash(story.id),
href: getStoryUrl(story.id, { target: 'top', standalone: false }),
icon: story.navigation?.icon,
iconExpanded: story.navigation?.iconExpanded,
children: [], // TODO: support nested levels in a future implementation
Expand Down
1 change: 1 addition & 0 deletions packages/storylite/src/services/router/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const STORYLITE_BASE_PATH = import.meta.env.BASE_URL
3 changes: 2 additions & 1 deletion packages/storylite/src/services/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './constants'
export * from './createStoryLiteRouter'
export * from './router.class'
export * from './router.component'
export * from './createStoryLiteRouter'
export * from './router.store'
export * from './router.types'
3 changes: 1 addition & 2 deletions packages/storylite/src/services/router/router.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react'

import { CurrentRoute, Route } from './router.types'
import {
asAbsoluteHash,
createPatternRegex,
getWindowHash,
parseHashbangPath,
Expand Down Expand Up @@ -79,7 +78,7 @@ export class Router implements Iterable<Route> {
}

navigate(path: string, query?: URLSearchParams | Record<string, string>, replace = false): void {
const absPath = asAbsoluteHash(path)
const absPath = path // asAbsoluteHash(path)
// const relPath = asRelativeHash(path)
const newUrl = new URL(absPath, window.location.origin)
newUrl.search = new URLSearchParams(query).toString()
Expand Down
4 changes: 2 additions & 2 deletions packages/storylite/src/services/router/router.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { HTMLAttributes, ReactNode } from 'react'

import { useRouterStore } from './router.store'
import { CurrentRoute } from './router.types'
import { asAbsoluteHash, parseWindowHash } from './router.utils'
import { parseWindowHash } from './router.utils'

export type RouteRendererProps = {
route?: CurrentRoute
Expand Down Expand Up @@ -42,7 +42,7 @@ export const Link = ({

return (
<a
href={asAbsoluteHash(to)}
href={to}
onClick={e => {
e.preventDefault()
navigate(to)
Expand Down
24 changes: 18 additions & 6 deletions packages/storylite/src/services/router/router.utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
export function cleanHashBang(path: string): string {
return path
const parts = path.split('#', 2)
if (parts.length === 1) {
return parts[0]
}
if (parts.length === 0) {
return ''
}

const hash = parts[1]

return hash
.replace(/(^#|^\/#)/, '')
.replace(/(^\/+|\/+$)/, '')
.replace(/\/+/g, '/')
Expand All @@ -11,15 +21,17 @@ export function parseHashbangPath(path?: string): [string, URLSearchParams] {
return ['', new URLSearchParams()]
}

if (!path.match(/^(\/?#)|([a-z]+\:)/)) {
path = '/#/' + path
let cleanPath = cleanHashBang(path)

if (!cleanPath.match(/^(\/?#)|([a-z]+\:)/)) {
cleanPath = '/#/' + cleanPath
}

if (path.startsWith('/') && !path.startsWith('/#')) {
path = '/#' + path
if (cleanPath.startsWith('#') && !cleanPath.startsWith('#/')) {
cleanPath = '#/' + cleanPath
}

const url = new URL(path, window.location.origin)
const url = new URL(cleanPath, window.location.origin)
const queryFromHash = url.hash.split('?')
if (queryFromHash.length > 1) {
url.search = queryFromHash[1]
Expand Down

0 comments on commit c0206d1

Please sign in to comment.