Skip to content

Commit

Permalink
Show more comprehensive details for storybook errors
Browse files Browse the repository at this point in the history
  • Loading branch information
vocksel committed Dec 19, 2024
1 parent 7185df8 commit dba0401
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 31 deletions.
79 changes: 79 additions & 0 deletions src/Common/CodeBlock.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
local React = require("@pkg/React")
local Sift = require("@pkg/Sift")

local SelectableTextLabel = require("@root/Forms/SelectableTextLabel")
local nextLayoutOrder = require("@root/Common/nextLayoutOrder")
local useTheme = require("@root/Common/useTheme")

local useMemo = React.useMemo

local function getLineNumbers(str: string): string
return Sift.List.reduce(str:split("\n"), function(accumulator, _item, index)
return if index == 1 then tostring(index) else `{accumulator}\n{index}`
end, "")
end

export type Props = {
source: string,
sourceColor: Color3?,
layoutOrder: number?,
}

local function StoryError(props: Props)
local theme = useTheme()

local sourceColor = useMemo(function()
return if props.sourceColor then props.sourceColor else theme.text
end, { props.sourceColor })

return React.createElement("Frame", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 0.5,
BorderSizePixel = 0,
BackgroundColor3 = theme.sidebar,
LayoutOrder = props.layoutOrder,
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
FillDirection = Enum.FillDirection.Horizontal,
Padding = theme.padding,
}),

BorderRadius = React.createElement("UICorner", {
CornerRadius = theme.corner,
}),

Padding = React.createElement("UIPadding", {
PaddingTop = theme.padding,
PaddingRight = theme.padding,
PaddingBottom = theme.padding,
PaddingLeft = theme.padding,
}),

LineNumbers = React.createElement("TextLabel", {
LayoutOrder = nextLayoutOrder(),
AutomaticSize = Enum.AutomaticSize.XY,
Text = getLineNumbers(props.source),
TextSize = theme.textSize,
LineHeight = 1,
BackgroundTransparency = 1,
Font = Enum.Font.RobotoMono,
TextColor3 = theme.textFaded,
TextXAlignment = Enum.TextXAlignment.Right,
}),

SourceCode = React.createElement(SelectableTextLabel, {
LayoutOrder = nextLayoutOrder(),
Size = UDim2.fromScale(1, 0),
AutomaticSize = Enum.AutomaticSize.Y,
Text = props.source,
TextColor3 = sourceColor,
TextSize = theme.textSize,
TextWrapped = false,
LineHeight = 1,
Font = Enum.Font.RobotoMono,
}),
})
end

return StoryError
6 changes: 3 additions & 3 deletions src/Navigation/Screen.luau
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ local NavigationContext = require("@root/Navigation/NavigationContext")
local NoStorySelected = require("@root/Storybook/NoStorySelected")
local SettingsView = require("@root/UserSettings/SettingsView")
local StoryCanvas = require("@root/Storybook/StoryCanvas")
local StoryError = require("@root/Storybook/StoryError")
local StorybookError = require("@root/Storybook/StorybookError")

local useMemo = React.useMemo

Expand All @@ -29,8 +29,8 @@ local function Screen(props: Props)
storybook = props.storybook,
})
elseif props.unavailableStorybook then
return React.createElement(StoryError, {
err = `Failed to load {props.unavailableStorybook.storybook.name}\n\n{props.unavailableStorybook.problem}`,
return React.createElement(StorybookError, {
unavailableStorybook = props.unavailableStorybook,
})
else
return React.createElement(NoStorySelected)
Expand Down
32 changes: 4 additions & 28 deletions src/Storybook/StoryError.luau
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
local React = require("@pkg/React")
local Sift = require("@pkg/Sift")

local CodeBlock = require("@root/Common/CodeBlock")
local ScrollingFrame = require("@root/Common/ScrollingFrame")
local SelectableTextLabel = require("@root/Forms/SelectableTextLabel")
local useTheme = require("@root/Common/useTheme")

export type Props = {
Expand All @@ -13,10 +12,6 @@ export type Props = {
local function StoryError(props: Props)
local theme = useTheme()

local lineNumbers = Sift.List.reduce(props.err:split("\n"), function(accumulator, _item, index)
return if index == 1 then tostring(index) else `{accumulator}\n{index}`
end, "")

return React.createElement(ScrollingFrame, {
ScrollingDirection = Enum.ScrollingDirection.XY,
LayoutOrder = props.layoutOrder,
Expand All @@ -34,28 +29,9 @@ local function StoryError(props: Props)
PaddingLeft = theme.paddingSmall,
}),

LineNumbers = React.createElement("TextLabel", {
LayoutOrder = 1,
AutomaticSize = Enum.AutomaticSize.XY,
Text = lineNumbers,
TextSize = theme.textSize,
LineHeight = 1,
BackgroundTransparency = 1,
Font = Enum.Font.RobotoMono,
TextColor3 = theme.textFaded,
TextXAlignment = Enum.TextXAlignment.Right,
}),

ErrorMessage = React.createElement(SelectableTextLabel, {
LayoutOrder = 2,
Size = UDim2.fromScale(1, 0),
AutomaticSize = Enum.AutomaticSize.Y,
Text = props.err,
TextColor3 = theme.alert,
TextSize = theme.textSize,
TextWrapped = false,
LineHeight = 1,
Font = Enum.Font.RobotoMono,
CodeBlock = React.createElement(CodeBlock, {
source = props.err,
sourceColor = theme.alert,
}),
})
end
Expand Down
112 changes: 112 additions & 0 deletions src/Storybook/StorybookError.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
local React = require("@pkg/React")
local Sift = require("@pkg/Sift")
local Storyteller = require("@pkg/Storyteller")

local CodeBlock = require("@root/Common/CodeBlock")
local ScrollingFrame = require("@root/Common/ScrollingFrame")
local nextLayoutOrder = require("@root/Common/nextLayoutOrder")
local useTheme = require("@root/Common/useTheme")

type UnavailableStorybook = Storyteller.UnavailableStorybook

export type Props = {
unavailableStorybook: UnavailableStorybook,
layoutOrder: number?,
}

local function StoryError(props: Props)
local theme = useTheme()

local storybookSource = props.unavailableStorybook.storybook.source.Source

return React.createElement(ScrollingFrame, {
ScrollingDirection = Enum.ScrollingDirection.XY,
LayoutOrder = props.layoutOrder,
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
FillDirection = Enum.FillDirection.Vertical,
Padding = theme.paddingLarge,
}),

Padding = React.createElement("UIPadding", {
PaddingTop = theme.paddingLarge,
PaddingRight = theme.paddingLarge,
PaddingBottom = theme.paddingLarge,
PaddingLeft = theme.paddingLarge,
}),

MainText = React.createElement("TextLabel", {
LayoutOrder = nextLayoutOrder(),
Text = `Failed to load {props.unavailableStorybook.storybook.name}`,
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
Font = theme.font,
TextColor3 = theme.text,
TextSize = theme.textSize,
TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Center,
}),

Problem = React.createElement("Frame", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
LayoutOrder = nextLayoutOrder(),
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
FillDirection = Enum.FillDirection.Vertical,
Padding = theme.padding,
}),

Title = React.createElement("TextLabel", {
LayoutOrder = nextLayoutOrder(),
Text = "Error",
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
Font = theme.headerFont,
TextColor3 = theme.text,
TextSize = theme.headerTextSize,
TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Center,
}),

CodeBlock = React.createElement(CodeBlock, {
source = props.unavailableStorybook.problem,
sourceColor = theme.alert,
layoutOrder = nextLayoutOrder(),
}),
}),

StorybookSource = React.createElement("Frame", {
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
LayoutOrder = nextLayoutOrder(),
}, {
Layout = React.createElement("UIListLayout", {
SortOrder = Enum.SortOrder.LayoutOrder,
FillDirection = Enum.FillDirection.Vertical,
Padding = theme.padding,
}),

Title = React.createElement("TextLabel", {
LayoutOrder = nextLayoutOrder(),
Text = "Storybook Source",
AutomaticSize = Enum.AutomaticSize.XY,
BackgroundTransparency = 1,
Font = theme.headerFont,
TextColor3 = theme.text,
TextSize = theme.headerTextSize,
TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Center,
}),

CodeBlock = React.createElement(CodeBlock, {
source = storybookSource,
layoutOrder = nextLayoutOrder(),
}),
}),
})
end

return StoryError
32 changes: 32 additions & 0 deletions src/Storybook/StorybookError.story.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
local React = require("@pkg/React")
local Storyteller = require("@pkg/Storyteller")

local ContextProviders = require("@root/Common/ContextProviders")
local MockPlugin = require("@root/Testing/MockPlugin")
local StorybookError = require("@root/Storybook/StorybookError")

type UnavailableStorybook = Storyteller.UnavailableStorybook

return {
summary = "Component for displaying error messages to the user",
story = function()

local storybookModule = script.Parent.Parent["init.storybook"]
local unavailableStorybook: UnavailableStorybook = {
problem = "Something went wrong!",
storybook = {
name = storybookModule.Name,
source = storybookModule,
loader = {} :: any,
}
}

return React.createElement(ContextProviders, {
plugin = MockPlugin.new() :: ,
}, {
StorybookError = React.createElement(StorybookError, {
unavailableStorybook =unavailableStorybook
}),
})
end,
}

0 comments on commit dba0401

Please sign in to comment.